04 May 2016

Top 10 #MetGala Outfits 2016

The Met Gala, an annual fundraiser for The Metropolitan Museum of Art's Costume Institute, has in recent years become quite the star-studded, can't-miss-it, fashion-event-to-watch of the season. This year's theme of dress was Manus X Machina, and while many on the red carpet opted for plain, metallic-looking ensembles, others rose to the occasion and (in some cases literally) let their light shine. Without further ado, my picks for the top 10 outfits at last night's Met Gala:

10. Kerry Washington wearing Marc Jacobs.

9. Rita Ora wearing Vera Wang.

8. Bella Hadid wearing Givenchy.

04 November 2015

Silent Push Notifications on Google Chrome

First, I would recommend you read (or skim) the Google Developers post on Push Notifications on Google Chrome. The following are a few excerpts that caught my eye:

You’ll notice that we show a notification even when there is an error. This is because if we don’t, Chrome will show it’s own generic notification.

See also:
When can I use push without showing notifications (i.e. silent background push)? 
There is no timeline for when this will be available yet, but there is an intent to implement background syncand while it’s not decided or spec’d, there is some discussion of enabling silent push with background sync.
And under the limitations section:
you have to show a notification when you receive a push message
At the time I first experimented with the Push API for Google Chrome, the first quote wasn't in the blog post, though the second two were. Being a naturally inquisitive creature, I wondered why you had to show a notifications, and more specifically, what were the consequences of not doing so. For a project I happened to be working on, I wanted to show push notifications when the site was in the background or closed, but obviously not when the user was browsing the website, as that would be annoying. So I experimented.

I set up the web project I was working on to receive push notifications using a service worker much like the examples in the post. One key difference; Instead of the following push event handler:

self.addEventListener('push', function(event) {  
  console.log('Received a push message', event);

  var title = 'Yay a message.';  
  var body = 'We have received a push message.';  
  var icon = '/images/icon-192x192.png';  
  var tag = 'simple-push-demo-notification-tag';

  event.waitUntil(  
    self.registration.showNotification(title, {  
      body: body,  
      icon: icon,  
      tag: tag  
    })  
  );  
});

I instead chose to try:

self.addEventListener('push', function(event) {  
  console.log('Received a push message', event);

  var title = 'Yay a message.';  
  var body = 'We have received a push message.';  
  var icon = '/images/icon-192x192.png';  
  var tag = 'simple-push-demo-notification-tag';

  //event.waitUntil(  
  //  self.registration.showNotification(title, {  
  //    body: body,  
  //    icon: icon,  
  //    tag: tag  
  //  })  
  //);  
});

I did this to test the consequences and see what would happen. As I more or less expected by this point, I saw some output in the console indicating I had received a push message, but I did see any notification pop up. Interesting...

I decided to test this further. I then modified the code to be the following:

self.addEventListener('push', function(event) {  
  console.log('Received a push message', event);

  var title = 'Yay a message.';  
  var body = 'We have received a push message.';  
  var icon = '/images/icon-192x192.png';  
  var tag = 'simple-push-demo-notification-tag';

  if(window.globalBoolean) {
    event.waitUntil(  
      self.registration.showNotification(title, {  
        body: body,  
        icon: icon,  
        tag: tag  
      })  
    ); 
  } 
});

In the JavaScript console of my webpage, I experimented with setting the value of window.globalBoolean to true or false. Much to my amazement, the code (which, mind you, is in a ServiceWorker.js file running in the background) picked up on it! It would show push notifications when I set the globalBoolean to true, and stop showing them once I set them to false. However, as a fascinating caveat, I found that once I refreshed the webpage, setting globalBoolean no longer had any effect on the service worker displaying notifications; it was simply stuck to whatever I set it to prior to refreshing. Weird!

By this point I was very invested. I decided to do a little research on how to communicate from my webpage to my service worker, and I discovered there's actually a pretty simple little protocol for doing so. I modified my service worker code one last time to:

self.addEventListener('push', function(event) {  
  console.log('Received a push message', event);

  var title = 'Yay a message.';  
  var body = 'We have received a push message.';  
  var icon = '/images/icon-192x192.png';  
  var tag = 'simple-push-demo-notification-tag';

  if(self.showNotifications) {
    event.waitUntil(  
      self.registration.showNotification(title, {  
        body: body,  
        icon: icon,  
        tag: tag  
      })  
    ); 
  } 
});

Additionally, I added the following to my service worker as well:

self.showNotifications = false; //default value

//listen for messages
self.addEventListener('message', function(event) {
  self.showNotifications = event.data === "true";
});

As you might imagine, this piece of code listens for a message event; when it receives a message, if the data contains the string "true", it sets self.showNotifications to true, otherwise it sets self.showNotifications to false. Not exactly the greatest code, but a good place to start experimenting.

To my front-end client, I added the following function:

function turnPushNotificationsOn() {
  if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
    // This wraps the message posting/response in a promise, which will resolve if the response doesn't
    // contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
    // controller.postMessage() and set up the onmessage handler independently of a promise, but this is
    // a convenient wrapper.
    return new Promise(function(resolve, reject) {
      var messageChannel = new MessageChannel();
      messageChannel.port1.onmessage = function(event) {
        if (event.data.error) {
          reject(event.data.error);
        } else {
          resolve(event.data);
        }
      };

      // This sends the message data as well as transferring messageChannel.port2 to the service worker.
      // The service worker can then use the transferred port to reply via postMessage(), which
      // will in turn trigger the onmessage handler on messageChannel.port1.
      // See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
      navigator.serviceWorker.controller.postMessage("true", [messageChannel.port2]);
    });
  }
}

I borrowed much of the above code from an example I found online for how to send messages to your service worker from your front end. I repurposed it specifically to send a "true" message to the service worker when turnPushNotificationsOn() was called.

Sure enough, I found that because I set self.showNotifications to false by default, notifications were arriving but not displaying. Once I called my new client function, self.showNotifications was set to true, and notifications would start displaying. This setting persisted until I turned it off again (using a function similar to turnPushNotificationsOn, but which I won't include here because duh), and the functions would even work across page refreshes. I had my solution!

Is this a bug? Maybe. Is it hacky? Yeah, kinda. But does it work? Up until Chrome 48, the answer is yes. There is no consequence to doing this as far as I've been able to tell on Chrome for Windows, Mac, or Android. In the example I showed, all I did was use this to control whether push notifications were shown or not. I needed this for a project because I did not want push notifications to display while the user was on the site. While not showing push notifications for active apps is a given behavior on mobile operating systems, the same cannot be said for the web (yet). Needless to say, if that were the case, I would not have had to come up with this solution. I was able to use the above solution in conjunction with some handy event listeners like "visibilitychange" and "beforeunload" to only turn push notifications on when the site was in the background or closed. 

Push Notifications on web are a very young technology, and I'm very interested in seeing where they go, even if their behavior isn't quite there yet. That said, I did very much enjoy piecing together my own solution, and I hope this is helpful for any of you working on similar projects.

08 September 2015

DIY: How to Build an Artist's Easel (For $20 or Less)


So you want a good, solid easel but don't want to spend $100-200. I recently found myself in this situation; a recent graduate between jobs, I was running low on cash but high on motivation to get my hands dirty and paint. I set out to buy supplies for painting, but I realized only when I was at the store that I was lacking a crucial element: an easel. I was shocked to see prices in the $100-200 range for anything remotely resembling a decent wooden easel, so, perhaps as a result of my computer science do-it-yourself mindset, I set out to build one from raw materials. Turns out it can be done for under $20! And if I did it, you can to.
Here's what you'll need:

20 May 2015

Bowdoin College: My Thoughts 4 Years Prior.

[Written 04/14/11, scheduled for posting 05/20/15]

I have officially made the decision to attend Bowdoin College this fall of 2011.
From the time I visited in November last year, I knew nothing would ever be the same. The beautiful landscape, tall pine groves & the peaceful setting made me fall in love. After considering several other options, including Baylor University and the University of Texas, I decided my best option lied far from my home state of Texas. This was partially due to financial reasons; due to the ongoing financial crisis in the state of Texas, both public & private universities have drastically reduced the aid they traditionally offer to students. Bowdoin, located in the beautiful state of Maine, offered my the best financial aid, promising to cover all of my demonstrated need. But my decision was certainly not made solely because of fiscal matters. No, far from it. I decided to go to Bowdoin College for personal reasons. For one, I wanted to get away: to experience new sights, new sounds, meet new people. In addition, many of the prospective students I made friends with during my visit were also going to Bowdoin, and I most certainly wished to join them. Lastly, several of my friends are going to (relatively) nearby colleges, including the Massachusetts Institute of Technology, Cornell University, & Columbia University. So, despite being so far from home, I would have some essence of familiarity at my new college. Indeed, I am sincerely happy with my decision to spend the next four years of my life at Bowdoin College, and I cannot wait until the fall semester. Every day the date gets closer and closer, & yet I feel farther and farther away. I cannot conceal my desire to alleviate this feeling, and be at my new home in Maine.

07 February 2015

Hacking Liberal Arts - The CBBhacks Story

[This story was originally posted on Medium]

Once upon a time, I attended MHacks. MHacks, held biannually in downtown Detroit, is one of the largest student hackathons in the United States. Together with a group of students I had never met before from diverse backgrounds, we worked to build a textbook exchange application running on Python/Django. When I got back to school the week after MHacks, I kept thinking about the sheer logistical nightmare hosting a hackathon must be. (Thanks to a great Medium series by the leaders behind MHacks, I did not have to wonder for too long). Bowdoin College — a small liberal arts college in Brunswick, Maine — is the place I call home during the academic year. Although I had an amazing weekend with really great people, I did not think students at a liberal arts college like Bowdoin would have much interest in this kind of experience.

In my spare time at Bowdoin, I lead a group known as the Information Technology Advisory Council (ITAC). We work directly with the College’s Chief Information Officer, and our mission is to enhance the student body’s experience at Bowdoin by simplifying outdated workflows with new tech. This past fall, one of our members brought up the idea of hosting a hackathon on campus. Though I remained a tad skeptical, I realized the only way to find out if the idea of a hackathon had any potential was by trying, and gauging student response. So we set off to begin organizing the first hackathon for liberal arts colleges, and the first student hackathon in Maine, CBBhacks. (CBB stands for Colby-Bates-Bowdoin, the primary colleges we expected attendees from).

 “I hope that students dive into this space and learn how to work across their ideas and skills to put together apps, websites, maker tech & other projects.” 
- Jack Gieseking, New Media & Data Visualization Specialist at Bowdoin 

Fortunately for us, Bowdoin College alumni are among the friendliest, most dedicated alums of any school. Though you might not expect it from a liberal arts college, we have amazing alums at places like Google, Hubspot, Okta, Mass Challenge, Raizlabs, L.L. Bean, and elsewhere. With their help, the support of Bowdoin’s own Student Activities office, and the assistance of the Bowdoin administration, we were able to establish a budget for the event and get word out about CBBhacks at the College and at other nearby schools like Colby, Bates, and others. Additionally, we were able to get in contact with several local Maine entrepreneurs, including Jason Cianchette, founder of Liquid Wireless, and Jess Knox, founder of several growth accelerating companies and Maine’s Startup and Create Week conference, both of whom were delighted to help us out with speaking and judging at the hackathon. We even had some awesome representatives from Code for America at the event.

 “If I were a college student, I’d be traveling to Bowdoin College this weekend to take part in [CBBhacks].” 
-Whit Richardson, Portland Press Herald 

Once people knew about the event, our biggest challenge was combating the stigma behind the word “hacking”. Though hackathons are now commonplace among many larger schools across the country, the word “hack” still sends the wrong message at schools like Bowdoin. Fielding questions like “what are you hacking into?”, “is this legal?”, and “Do I need to know how to code?” became daily rituals, despite our best efforts to advertise the event as one for technical and nontechnical entrepreneurs alike.

 “To hack means to build something quickly in a scrappy, innovative way without a lot of resources.” 
- Rebecca Goldfine, Bowdoin Daily Sun 

Our goal for the event had been set as a high bar: get 100–150 students to register for the event. By the day of the event, we had gotten 151 people to register. Of course, we did not for a moment foresee all of them attending — Attrition rates for events like hackathons are notoriously high, often upwards of 60%. When prompted for confirmation of their attendance from students, we only heard back from roughly half of them, and we knew to expect even fewer students than that. Still, despite being a relatively small event, we were proud of how many people we had gotten to sign up, as well as of the support and attention we were getting for the event. After all, this was the first hackathon at Bowdoin, and we hoped it would be just a starting point.

The event came and it was undeniably a success. We got students there from our target schools, professors, mentors, entrepreneurs, and people from different areas of the college who were all interested in showing their support for the first ever CBBhacks. Though the attendance was low even by our estimates, we were extremely pleased with everyone who did show up. There were plenty of computer science students, but we also had students from psychology, english, government, biology and math majors. Some students stayed up working the whole weekend, though most chose to sleep the first night and work the second. Our speakers discussed topics like entrepreneurship, founding companies, selling companies, being liberal arts students in highly competitive technical environments, and more. All in all, everyone there had a really good time and got to do something they had never done before they left.

When the awards came Sunday morning, everyone was excited to deliver their presentations to our panel of judges. We saw ideas like music-generating genetic algorithms, mom-and-pop hotel membership programs, Oculus VR game concepts and, amusingly, textbook exchange programs. We were able to give out really great prizes like Raspberry Pi kits, Drones, and Leap Motions that we hope will encourage our hackers to keep hacking in their spare time. The winning team was a group of Bowdoin and Bates students that received a set of Dell tablets courtesy of Major League Hacking, a scholarship to Top Gun Prep, an online entrepreneurship course, and the opportunity to pitch their idea at the Maine Startup and Create week.


At the end of the event, I asked all of our attendees to raise their hands if they had learned to code, learned a new programming language, or learned a new framework over the weekend. I was astonished and proud to see almost every hand in the room go up. In my opinion, that’s what hackathons are about. Learning. Growing. Teamwork. It is my hope that next year, this great group of students will return and share their experiences with their friends to get them hacking, too. Though we have lots of work to do in terms of getting liberal arts students more comfortable with “hacking”, we believe this was a fantastic first step and are now convinced that hacker/maker culture is an invaluable part of modern education that liberal arts students should not miss out on.

29 September 2014

Introducing TouchLocker

Ever snap a photo of sensitive information? 

Taken a selfie you'd rather others not see? 

Have a private photo you don't want immediately available? 

TouchLocker is an iOS 8 app targeted at devices featuring Apple's Touch ID (iPhone 5S, 6, 6 Plus). It makes use of the newly-available Touch ID SDK by securely guarding your photos behind your fingerprint.
With TouchLocker, any photos added to the app are instantly secured. You'll need to enter your fingerprint any time you wish to see these photos, or enter your backup password. This app makes it extremely simple to hide from plain sight that which you'd rather anyone handling your phone not come across.

Available today for $1.99 from the iOS App Store, TouchLocker lets you store any amount of photos you want. All of your data is secured to your device, too—your photos are never stored on any remote servers, and the app will never even use an internet connection. No photos leaked to the cloud here!

Download TouchLocker today!