Showing posts with label nerds. Show all posts
Showing posts with label nerds. Show all posts

Saturday, May 23, 2015

Extracting Base64 Images from Google Keep Archives

I love Google Keep! It's a nice-looking note-taking app with more features than I ever use.

But once I made the mistake of staring a photo album in Keep. (If you don't know, you can add photos to a note either by taking a picture or finding on on 'disk.') To my chagrin I discovered that there's no way to get these photos out of Keep.

So I was super happy when I saw that Google Takeout now exports Google Keep files. "Great!" I thought, I'll just download my whole archive and grab those files. Again, much to my chagrin, I discovered that the photos were not in the Takeout archive as JPG files, but rather encoded as base64 strings inside the html page. So for example, I have a note called "Dogs" and all the photos are base64 encoded inside that "Dogs.html" note in the Takeout archive.

This is seriously annoying.

So, I wrote a Python script to get these images out. It's called the "Keep Photo Dump."

To use it you have to have Python installed. At the terminal, you would run:
./keep_photo_dump.py Dogs.html

and all the images in the file will be dumped as Dogs1.jpg, Dogs2.jpg, etc.

Hope this helps someone else.

Saturday, March 28, 2015

Ctrl-down/up in emacs in Mac Terminal

Finding the answer to this online pretty much drove me nuts. I'm sharing it here for you, future Internet user.

Here's the situation:
  • I use Emacs
  • I use Emacs in the Mac Terminal
  • \C-down was bound to forward-paragraph by default (and \C-up bound to backward-paragraph by default).
  • I wanted them to actually work, but they didn't.
Through some series of trickery I was able to figure out that the Mac terminal was sending the wrong escape sequences for cltr-up and down. Specifically, it wasn't sending anything at all, beyond just the down key. I fixed it with the following settings:
  1. From the terminal, go to "Preferences" "Settings" "Keyboard"
  2. Look for and modify, or add actions for ctrl-up and ctrl-down:
    1. ctrl-up = \033[1;5A
    2. ctrl-down = \033[1;5B

Friday, November 21, 2014

Email Response Time

Ever since I started a full time job, where I spend nearly all day answering work emails, it seems I am less and less interested in responding (or even reading) personal emails. At some point I realized Iwas being slow to respond, but I wanted to know, just exactly how slow.

So, I graphed it (numbers in days):

This data  comes from a Google App Script I wrote. Here's the source. Google App Script is great, it lets you write Javascript that has access to your Google Apps, like email, docs, etc. You can do stuff like send emails as a result of changes in your Docs, or in my case, run a script every day that reads your email and writes to a spreadsheet.

Here's how the script works, although there's definitely room for improvement. Every day it runs, it looks at my last 30 days of email, and for every email where I responded to someone else it adds up the delay between their email and my response. Additionally (and here's the kind of weird part that I think is creating the spikes in the above graph) I wanted to keep track of my outstanding responses and how long they were taking. My normal email workflow is that I keep things that I need to respond to in my inbox, so I decided to include for any email in my inbox, the time between the last email (as long as it wasn't from me) and the current date.

One final caveat was that, after 60 days I put a hard cutoff, since those are typically emails I just never respond to, and finally archive in shame.

So how does it look? For most (median) of my emails I respond in a few hours. But for the 99th%ile email, it is much worse, around 25 days, and even worse if you go back a month or so.

I definitely recommend Google Apps Script. It's easy, but super powerful because all of the useful data (i.e., yours) that the scripts have access to. I could even see it being a pretty good way to learn programming/JavaScript, since from day 1 you can do some pretty interesting things. 

Sunday, August 3, 2014

Announcing "Number 'N Date"

Hi folks!

Today I'm releasing the first version of Number 'N Date on Google Play. Number 'N Date is both a proof of concept and a useful Android application. It is a very simple way of adding a number and the current date to a Google Docs Spreadsheet. Take a look at the interface, it's pretty simple:

The basic idea is, you add a number and it, plus the current date, will show up as a row in the Google Docs Spreadsheet that you have chosen in the properties menu. I find it useful for keeping track of daily numbers like my weight, money I've spent, miles I've run, etc. But with the added benefit that the information is all in my own Google Docs Spreadsheets. So I've free to do whatever kind of processing I want to do on the data (plus not have to trust one more company with my information).


Number 'N Date is also open source! Which may be useful! You might not trust me, some Internet weirdo, not to squirrel away a copy of your data somewhere.

Actually the whole open source thing brings me to the second important feature; Number 'N Date is a proof of concept. Specifically, it's an end-to-end application that does something useful, gets authorization from accounts on an Android device, and reads and writes to Google Docs spreadsheets. Information on doing those latter two things together has been pretty hard to come by on the internet. I've written about reading Google Spreadsheets from an Android App before, but in a sort of limited way. This is a follow-on, an end-to-end example that shows everything together. 

I hope you find it useful, either as an app or as a code example. Please, send me feature requests, report bugs, ask me questions, etc. 

Known issues:
  • Spreadsheet must have 'number' and 'date' columns in the first row, or must be completely empty (so the app can add them). 


Sunday, October 13, 2013

Megabudget v0.1

I finished the very first, somewhat-useful version of the Megabudget Android App. To recap, Megabudget is an Android app that allows you to use your existing Google Docs spreadsheet as a budget, but add expenses on the go from your phone. It does the following:


  • Authenticates into your Google docs spreadsheet with your Android user account(s)
  • Reads months & categories from your budget spreadsheet
  • After you select a category & month, you can add a new expense, updating your spreadsheet
The project itself is meant to be extensible, so that if it seems useful to you, you can contribute an implementation of the BudgetAdapter in order to have it work with your own budget format. 

Here's the project again: https://code.google.com/p/nolacoaster/

And the last SVN commit log:
This is the first version of Megabudget that does something useful. It:
- populates the categories & months
- populates the total of the latest month
- you can select a category
- you can add an expense to that category

It has several notable problems
- no idea how it works when disconnected from the internet
- it is very slow, esp. at the beginning where it does multiple pulls from the
spreadsheet
- you can't select a month

Additionally it would be really nice to
- organize the categories by freq of use
- allow for offline expenses

Sunday, July 28, 2013

Reading Google Spreadsheets from an Android App

Well, I've done it. It took me two serious days of wading through the mess that is the gdata APIs (myths and outdated versions abound) and the OAuth2 APIs (same caveats apply) and I was finally able to read the list of my own personal spreadsheets in Google Docs, and print their names out from an Android application.

It was very important to me to be able to use Android's own build-in account mechanism, which took a fair bit of time to figure out, and then on top of that the build/class-path requirements for the Google Spreadsheets API is completely messed up.

But anyway, here's a short description of how I did it, notes, and the full code for the main activity.

1 - I am using a Nexus 4, so I set up my app to use the latest APIs possible (Android 4.2.2 on my system).

2 - The list of required JARs is crazy, and quite picky. Here's the screenshots of the ones I am using:

3 - I had to add the following permissions to my manifest file:

4 - And finally, here is the code itself to run the main activity. The basic application structure was just the one that is created by default when you create a new Android Application. The basic steps for listing the Spreadsheets I got from the Spreadsheets API Tutorial. I can't really remember where I learned the OAuth2.0 steps, but needless to say, I cobbled it together from several online sources.




Sunday, July 22, 2012

Project Fortress is Wrapping Up

I was interested to learn that Project Fortress, the programming language research project from Sun (now Oracle) was wrapping up:

https://blogs.oracle.com/projectfortress/entry/fortress_wrapping_up

I was an intern on Project Fortress during the summer of 2008. Fortress was an ambitious language project that attempted to incorporate a number of advanced and experimental features.

I'm sorry to see the language be wrapped up without a JVM or native code compiler, but I understand there were a number of technical challenges, many of which I encountered during the course of my internship. Best of luck to these folks on their future projects!

Sunday, February 26, 2012

Weddings with Awk, Latex and Google Docs

Hey guys, I'm getting married! Pretty sweet, right?

Like any good software developer, I am always trying to save myself boring work with scripts and tools. Sure it may end up taking more time, but it's more fun.

Anyway, I thought I'd share a little bit of our wedding workflow, since I think it has been pretty effective. It all starts off with a few Google docs. These documents are all shared, so both my fiance and I can update them at any point during the day. Those documents include a text file with ideas and tasks to be completed, along with a spreadsheet of the gifts we've received, who gave them and whether or not we'd sent them a thank-you. We don't want to forget anyone, nor forget what they gave!

But the most useful document has been a spreadsheet containing the guest list. In the row for each name we filled in their addresses as we received them along with a Y/N column indicating whether or not that person would have a 'plus one.' We were careful to put each piece of the address (street, city, state, ...) into its own column, which is helpful for the script I wrote later. We also had two Y/N columns indicating whether that person had been sent a save-the-date and an invitation.

Putting the addresses in a spreadsheet, as opposed to a Word document, is a great idea, because then it can be exported in CSV format, and I can write scripts over them. After exporting the guest list to CSV format, I wrote an Awk script that would go through the file and output a LaTeX file so that I could generate address labels. I used the "envlab" LaTeX package for generating the labels, and because I had saved each part of the address as its own column, it was easy to play around with alignments (e.g., "should the apartment number go on its own line or after the street?"). Also, I made the outputting of an address label conditional on the Y/N value in the column recording whether or not that person had already received an invitation. This was really useful, since we wanted to send out save-the-dates as soon as possible, even before we had addresses for everyone. So we could effectively run the script any time we wanted without having to worry about generating the same label twice. Finally, we printed the labels onto those standard Avery 5160 inkjet labels (or at least a compatible label). I happen to think that the clear labels look really good, and professional.

So that's it. Nothing particularly clever, but I kind of wanted to share my experiences. I think that overall we've saved a ton of time generating the labels this way. Certainly vs. writing them by hand, but even vs. using Word to create the labels.

Tuesday, June 7, 2011

Probabilistic, Modular and Scalable Inference of Typestate Specifications

Today I presented my paper, Probabilistic, Modular and Scalable Inference of Typestate Specifications at PLDI 2011. This paper was joint work with Aditya Nori from Microsoft Research India. This was the second time I worked on a research project with Aditya, and as before our collaboration was extremely fruitful.

This paper is all about specification inference. The tool that I worked on for my thesis, Plural, checks that objects in a program are used according to their protocols. While the tool was quite powerful, it required a number of pre and post-conditions to verify that the protocol was being used correctly.

Our tool, Anek, infers them automatically, and does so using probabilistic constraints. This allows us to use various forms of evidence, some of which may conflict, in determining a final specification.

Anywho, the paper and presentation are now available online. Enjoy!

Tuesday, May 25, 2010

I think this qualifies as a 'gotcha'

I was writing some Java code today. I'm writing a plug-in for Eclipse that will actually insert some Java annotations (e.g., @Override) into your code automatically.

Unfortunately, every time I ran my plug-in, the annotations were being inserted without the @ sign (e.g., Override). I couldn't figure out what was going on, looking at the code that generates the text:

String annotation_text = ...
StringBuilder sb = new StringBuilder('@');
sb.append(annotation_text);
sb.append(newline);

Finally, I hovered over the StringBuilder constructor to figure out which constructor I was calling. Low and behold, I'm calling this one:
java.lang.StringBuilder.StringBuilder(int capacity)

In other words, by using single quotes, I am specifying the character '@' which is then implicitly cast to an int. Hmm... This doesn't seem so bad at first, but there's an asymmetry in the API. If I use this constructor:
new StringBuilder("@");
I get the behavior I expect, a string builder initialized to the at sign.

Moreover, there are append methods that take a single character:
sb.append('@');
Adds the single at sign character to the stream. So, knowing about this method, and the string constructor of the StringBuilder, I naturally assumed there was a character constructor as well... NOT SO FAST BECKMAN.

Tuesday, May 11, 2010

Validating XML against a Schema

If you ever have to write XML, and you need that XML to validate against a schema (and by the way, if you ever had to do this, I'm so sorry...) it turns out that Visual Studio is a great environment for this. It will tell you where you're XML is wrong and more importantly WHY. So many of the online validators would just say you have a problem without giving you any suggestions on how to fix it.

For the record, I am using Visual Studio 2008 Professional.

Wednesday, April 21, 2010

Nearest Neighbor

Hey. Just learned about a cool data structure for computational geometry called, KD-Trees. Yes, it's sort of embarrassing that I've just now learned about them, but what can I say? I still think they are cool. Anyway, KD-Trees are like binary trees but for points in space. They make it really easy (well, fast) to do things like search for the nearest point in a set to some given point.

SO, I quickly hacked up a nearest neighbor application. It generates a bunch of random points, and then when you click highlights the nearest point in red. Yay.




Click here to download the JAR if you want to run it. It's on of those runnable Jars... remember those? Ah, Java... I tried to make it an Applet, but that process was even more ridiculous.

Tuesday, April 13, 2010

Proof of Soundness for a Typestate Checker with Locks

Right now I am working on (what I hope will be) the last major theoretical effort of my thesis. I need to do another proof. Way back when I wrote this paper for OOPSLA in 2008, I did a proof of soundness for my language, a language that used atomic blocks for mutual exclusion. Right now, I'm doing the same thing but for a language that uses synchronized blocks. In other words, a language that is more Java-like.

Proofs are pretty painful for me, and the last one I did was really complicated, so rather than merely update the old proof to add locks, I am actually rewriting and simplifying (I think?) a whole bunch of stuff.

One of the biggest questions for me is a question that is important whenever you are doing a proof for a language with references; how will I define a well-typed heap? A well-typed heap means a runtime heap that is consistent with the type-checking facts that were known statically. In my system, every thread is an expression, and each one has its own type-checking context. They all much be consistent with the heap. Furthermore, in anticipation of my proof of preservation (where I have to show that after a step, the heap will still be well-typed) I think that my definition of a well-typed heap will have to include the following condition:
At most one thread can know statically the exact state of an object.
In my last proof I had a similar condition, but it was really unweildy to work with. I wonder how I can simplify this desire?

We're Live @ Blogger

Hey folks,

As you may have noticed, my blog is now hosted at Blogger.com. This is why a.) you see a fancy new layout and b.) if you normally get here by typing www.blogface.org into your browser, it's no longer a silly URL redirect, but rather you actually see blogface.org in your browser's address bar. Nice. There are a few reasons I switched over to Blogger, but mainly I just wanted to try something new. If you ever have the joy/pain of switching from one blog software to another, I highly recommend you check out the google-blog-converters project. You can run it on there app engine or on your own PC, and it even logs into your blog and grabs all the comments if you want it to.

Couple of things to keep in mind:
  • If you want to follow over RSS, go to http://feed.blogface.org/
  • While comments were moved from the old blog, I guess you have pretty much lost your ability to edit your comment if you made one.
  • Lists should have three items.

Sunday, April 11, 2010

The Dissatisfactory Doily

The most recent incarnation of SIGBOVIK, the annual celebration of all that is computer science humor, occurred on April 1st. I didn't have much time to recap it earlier, but it went very well. With the exception of being just a tiny bit long, this may have been the best SIGBOVIK ever. If you're interested in a (free) electronic copy of the proceedings or a ($7) paper copy of the proceedings, go back and click those links!

But I mostly wanted to talk about my own paper, The Dissatisfactory Doily. The premise of the paper is this: You own a sports team. You are jealous of the Pittsburgh Steelers and their ability to sell $10 Terrible Towels. You's like to make your own, but you don't have a clever, alliterative name. Well look no further than the Dissatisfactory Doily, a random name generator for Terrible Towel knock-offs. It takes a list of adjectives (synonyms for terrible) and a list of nouns (cloth-related) and spits out your new product name. For a long list of examples, please see the paper, but some of my favorites are, The Wanton Wall-to-Wall Carpeting, The Abominable Afghan, and The Horrendous Hanky.

In further news, this was likely my last year as SIGBOVIK MC. It's been a lot of fun, but my jokes are getting stale. Time to pass the torch!

Monday, March 15, 2010

Technical Report: Polymorphic Access Permissions

I've recently been working on an approach to add parametric polymorphism to our Access Permissions methodology. Access Permissions is a fraction-based means of reasoning about program aliases statically. It turns out in certain cases, it's really nice to have parametric polymorphism over permission specifications, for many of the same reasons that it's useful to have traditional parametric polymorphism (e.g., Java generics).

Our paper on the subject was recently rejected from ECOOP, but I think there are still some neat ideas in here. We've posted the paper as a technical report, and work on the subject will continue. You can find the technical report on the ISR page.

In other news, I've also started keeping track of the movies I've watched, mostly due to a recent binge.

Friday, February 5, 2010

Question about function... optimization?

Computer science people, I am looking to be pointed in the right direction. I am looking for a solution to a problem, and I think the answer might lie in an area of Computer Science/Statistics/O.R. that I know very little about. Here's the deal:

I have two mathematical functions, f_1 and f_2. Both functions intersect with the Y axis at exactly two points (and basically what happens below the Y axis can be ignored). f_1 is fixed; it's input. But f_2 is defined in terms of two parameters that I can tweak. Here's what I am trying to answer:

How can I pick the two parameters of f_2 so that the area under f_2 is as large as possible and yet still contained entirely within the area under f_1? 

I have come up with sort of a brute-force algorithm that I think will solve the problem, but if there's a 'best' or well-known way to solve this class of problems I'd like to learn more about it. I have heard about topics like 'function optimization.' Is this relevant? Also, because what I am doing is sort of a surprise, I'd like to hide most of the details, but I can give more if that will help the quality of your responses.

Monday, November 9, 2009

OOPSLA Student Research Competition: Results

I guess I never mentioned this because of how hectic things were the last two weeks, but I did participate in the OOPSLA 2009 Student Research Competition. The first day, I presented my poster in an all-conference poster session. Owing to the excellent position of my poster (Yay for alphabetically-early last names!) I talked to a ton of people, thus giving me the necessary confidence for when the actual judges came to talk to me. 

That night, I had a message in my hotel room that I had passed on to the final round, meaning I needed to give a short presentation explaining my work. Of course I didn't have one, so I wrote one there in the conference. The results, were pretty good. I think I gave a good talk. My slides were fine. I definitely could have answered the questions better. 

Nonetheless, I won third place, which amazingly means I will receive a plaque and a small monetary prize. Tudo Dumitraş, another CMU student from a different research group, won first prize. 

Therefore, from this point forward, I shall refer to my thesis work as award-winning research.

Monday, October 12, 2009

BlogFace in the BlogSpot?

Hey folks. I have lately been thinking about moving this blog over to a different service, most likely Blogger. I wanted to see if anyone had any comments or suggestions. I know this will mean a few changes. Among other things, those of you who follow me as a friend on livejournal will no longer get my updates. Blogface.org, which now resolves to this blog would naturally be updated to resolve to my new blog. This could mean a change to those of you who subscribe to my livejournal RSS feed. I have thought about that. In order to future-proof yourself, you could change that subscription to instead point to feed.blogface.org, which as of today will always point to the current RSS feed.

The main reason I am contemplating a switch is flexibility. Livejournal just isn't that flexible. Its methods for creating blog entries can also be somewhat painful. I can't post cool gadgets like a Last.fm most-recently played songs widget. There are only a limited number of templates. I cannot install Google Analytics. Other things. 

So what do you think. Is this a bad idea? Would you be adversely affected?

Sunday, October 4, 2009

Technical Challenge: SML

Success! I finally got SMLNJ and the MLton optimizing compiler to work with Windows. I am very happy about this, as I had been trying for quite a while and ran into various annoying compilation and DLL problems. (Really mlton was the difficult one.) Here's how I did it.:
  • Download Sun's VirtualBox VM software.
  • Install Ubuntu.
  • Use apt-get to install smlnj and mlton.
Seriously. I really think this is the way to do it and I am perfectly happy to launch Linux every time I want to program, it's just so much easier in Linux land. I like cygwin generally, but I have found that if you want to install some software and there's not already a distribution for it, it can make your life miserable. Ubuntu, on the other hand, has like 9 million packages, and even includes obscure stuff like sml. Problem solved!