Lyft and Alphabet?

Various sources are reporting that Lyft may receive a significant investment from Alphabet. This would certainly be interesting in the autonomous vehicle space, since Lyft currently works with a variety of other autonomous vehicle companies (Alphabet owns Waymo, one such company). Forbes reports that they currently have five such partnerships. Lyft seems to value partnerships and collaboration, so it will be interesting to see what such a large investor does to the equation. I can imagine cancelling the other partnerships or even forming some sort of autonomous-platform consortium, where they settle on some standards for integration.

I’m also not convinced that Lyft would use the investment just to attract new drivers or enter new markets. Historically, automating a task and using technology eventually becomes more efficient than manual labor, and if Lyft is taking the long view, they would be better off investing the $1 billion into developing autonomous vehicle technology rather than burning cash to attract human drivers. Don’t compete head-to-head with Uber over market share for ride-hailing; rather tackle the big problem that will revolutionize the entire transportation industry.

iPhone X and facial recognition

With the release of the iPhone X comes a lot of analysis about the security of FaceID. I have a couple of more mundane usage questions, with the caveat being that I didn’t watch the whole keynote…

  • How does it handle facial accessories:
    • How does it work if I put on my sunglasses? Or readers?
    • What if I normally wear glasses, but get a new frame with a different shape?
    • What if I’m skiing or snowboarding (or pick your winter sport), and wearing my goggles / a ski mask / a scarf, but want to use my phone?
  • What if I get a new ear piercing or nose ring or something?
  • What happens during Halloween?
  • Does facial hair affect it? What if I grow a beard or goatee, or even just get some stubble? What will happen to Movember??

I think these questions are similar to the wrist tattoo interference problems with the original iWatch, where real-world corner cases were not tested before product release. It will be interesting to see what kinds of real-world challenges FaceID encounters or handles well.

Tornado and Django — serving static content

I recently inherited a project for CLIx, a Django app running off of a Tornado WSGI server. Everything seemed to run fine, until we started getting reports that video and audio files were not playing correctly. It turns out that the original app was using Django to serve static files — not quite recommended for production use. This worked fine for small files like .html and .vtt, but larger files would not stream (.mp4, .mp3). You could not seek videos, and pausing / waiting / playing again would cause the video to re-play from the beginning.

In the Chrome dev tools, we could see that only part of the files were loading, but nothing else. So I decided to make Tornado serve the static content … not a lot of documentation about doing this. Luckily the Tornado-Django example application gives us a hint:

wsgi_app = tornado.wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler())
tornado_app = tornado.web.Application([
('/hello-tornado', HelloHandler),
('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
])
server = tornado.httpserver.HTTPServer(tornado_app)

 

And a bunch of StackOverflow questions show how to configure Tornado URLs with the static URL handler:

handlers = [
  (r'/favicon.ico', tornado.web.StaticFileHandler, {'path': favicon_path}),
  (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path}), 
  (r'/', WebHandler)
]

Combining these two, you can make a Tornado WSGI server handle static files for a Django app!

sgi_app = tornado.wsgi.WSGIContainer(DJANGO_WSGI_APP)
tornado_app = tornado.web.Application([
  (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': STATIC_URL}), 
  (r'/media/(.*)', tornado.web.StaticFileHandler, {'path': MEDIA_URL}), 
  (r'.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),
])
server = tornado.httpserver.HTTPServer(tornado_app)

Web.py and PyInstaller: issues with HTTPS on 32-bit Windows machines

I recently had a project where I had to bundle a Windows app, written in Python 2.7. I chose to use PyInstaller 3.2, since it was being used for other parts of our project as well.

The app had to be light-weight and compatible with older, 32-bit Windows machines, since it was going to be deployed on 10+ year old hardware in rural areas (running 32-bit Windows XP). The app basically provided a local, RESTful assessment engine, allowing students to interactively answer various types of questions (Multiple Choice, Fill-in-the-Blank, etc.) using the open source Open Embedded Assessments tool. To make it as light-weight as possible, I had decided to use the Web.py server.

While the app bundled fine on a 64-bit Windows 10 VM, I kept running into an error on a 32-bit Windows 10 VM:

    You must install pyOpenSSL to use HTTPS.

The app ran fine from the command prompt, and using a Python shell, I could import OpenSSL manually, so I was stumped. I finally dug into the PyInstaller warnings file and realized that Web.py was masking a common issue with _cffi_backend not being declared as a hidden import. Adding that to my spec file solved it, and I could cleanly build my app in 32-bit Windows.

I’m not entirely sure why the same spec file (without the _cffi_backend hidden import) worked fine in 64-bits, but that’s another mystery for another day.

React Native Flexbox confusion with custom components

For our Fly-by-Wire project, I’ve been learning and using React Native to build mobile applications. When trying to do a sidebar layout for a tablet view using nested custom components, I got stuck with Flexbox — no matter what I did, the flex option didn’t seem to have any effect in making my sidebar only take up a portion of the screen. You can see an example here.

I thought that ReactNative wrapped each component in an extra View or something (like how React wraps everything in a div). So I thought the components would render something like:


   
    
  
  
    
  

As you can probably guess, that is not how it works. The styles on the custom components’ (Sidebar and MainContent) View elements overrode anything I set on the custom components themselves (the sidebar and content classes). I was not expecting that, and I couldn’t find it clearly explained in the documentation. What I really wanted was something like this. Which would render (per my example above) as:


  
  

My lesson learned — with React Native, styles go on the “lowest” component in the tree, something to watch out for with nested custom components.

 

BYU’s Learning Platform Should Inspire Us All

Reflecting back on my recent trip to Utah for the Aspen Grove Winter Workshop (hosted by BYU), I was very impressed by their entire IT team (plus the location was just spectacular — at the base of Mt. Timpanagos, featured in the thumbnail image). One thing that stood out to me was their integration of a single learning outcome service into many core systems.

You can read about it more on their outcomes homepage. The system architect drew out a diagram of how the learning outcome service was being used, and it basically looked like a spider at the center of a web.

Diagram of consumer applications that use BYU's learning outcome service
Architecture diagram for BYU’s learning outcome service

The course catalog, student feedback system, accreditation reporting, and the LMS all drew upon this one service. At our university, every six years countless faculty and administrative staff spend hours to document each course, its learning outcomes, and how they map to accreditation standards. With a system like BYU’s (updated incrementally and in a central repository), they can publish their accreditation documents literally with a push of a button. I’m sure many other universities wish they could do the same…

Having an enterprise service like this also sets BYU up for exploring new learning methodologies, if they choose to do so. Things like competency-based learning, or improved student feedback & analytics, all become possible.

The Value of Models

It’s amazing how simple architectural decisions at the start of a software project can kill its long-term potential. One example we run into all the time is with learning outcomes and tagging content — simple enough, right?

Most learning platforms treat learning outcomes as simple text tags — let your instructors tag content with learning outcomes, so students know what they are expected to learn. Good pedagogy. And it’s a simple enough feature to implement, so it’s considered low-hanging fruit.

However, when you want to experiment with things like pathways and relationships between the outcomes, or adaptive assessments based on your knowledge, you run into trouble. Big trouble. You can’t easily link text tags once they are in your system…you could probably come up with complex database queries to get the results you want, but that early decision to model the outcomes as text tags now forces you to jump through hoops to do anything more complex and interesting.

Ideally, from the start you treat learning outcomes as their own entities, with their own relationships to each other and to content. So the initial complexity and planning pays off in the long-term, with less refactoring and more powerful models.

And yes, I am partially tooting my own horn. My group has been working on these types of models for the education domain, though way before my time. As outcomes-based learning becomes more prevalent, it’s amazing to see how the early work on OSIDs (from ~15 years ago) seems almost prescient. Check out EDUCAUSE’s vision for next generation learning platforms, and you can see the parallels.