Tuesday, January 12, 2016

Displaying python output with GeekTool

Living in Michigan, we are often hit with snow storms that cause us conditions to be too dangerous for driving to school.  These 'snowdays' are great, and every morning when the possibility of a snowday is present, I will often find myself checking our local news website to see if our schools name appears.  This often involves refreshing the website every few minutes (or even seconds! #fingercrossed) during the crucial minutes before I need to take a shower and get in the car or get back into bed.

So the other day when I was doing some web-scraping programming, the idea occurred to me to automate this process, so that I don't have to keep pressing refresh.  So I wrote a little python program that opened up the website, searched the html code for Kent county schools, and outputted the results.  This was the hard part, and one I'm not prepared to fully explain today.

Once I got the program printing what I wanted, I opened up GeekTool.  GeekTool is a mac program that allows you to display words, bits of code, website data, computer data, images, etc. on the background of your desktop.  You'll have to see for yourself various things it can do.

Anyhow, creating a shell geeklet with the following code will cause that python program to run and its output to show up on the computers desktop:
python ~/Documents/script/
In this case, was the name of the program I created -- but you could put the name of any python program there. Then one of the options you can set in GeekTool is how often this program refreshes itself, so I set mine for 60sec. The results:
For a half-hour this morning I sat and read the Bible, sipping coffee, and every 60secs or so looked up and watched as the list populated itself and grew automatically.  And, since you're reading this, eventually I did see my school's name pop up.  Unfortunately, the coffee had done its work and I couldn't fall back asleep.

By the way, the picture of the radar was also self refreshing -- every 300 seconds (5 minutes) GeekTools would fetch the image url, download the image and update my background.  

Apart from being able to be lazier than normal on a snowday morning, I will say there was an additional benefit to all this work.  By fetching it this way, I actually found out about my snowday 2 minutes faster than I would have otherwise (we receive text messages from remind), and my background was always a few schools ahead of the website the normal way through a browser and many schools ahead of perusing the website through their mobile app.

Next steps are to get my computer to check for my school, and automatically turn my alarm on/off based on whether the name shows up....    

Accessing Python Functions in Quicksilver

Over the last two years, I have been programming a lot with Python.  I have developed a lot of functions to do various mathematical tasks. For instance, I have a function that takes a number and spits out a list of its factors:
factors(30) = [1, 2, 3, 5, 6, 10, 15, 30]

And I have another that gives me the prime factorization of a number:
primefactorization(400) = [2, 2, 2, 2, 5, 5]

These have been very helpful as I have created other programs, and as I have participated in the EulerProject -- a set of mathematical challenges that typically require the user to create a program that helps solve them.  As I try to complete more and more challenges, my collection of useful functions grows and grows.

Recently, I have tried to find a way to access these functions more quickly.  Previously, I would have to find them in the correct program file, open it up, tweak it a little bit to call the function with the specifics of what I was looking for, and then run the program.  Annoyingly many steps, in my opinion, and usually hard enough to deter me from using my own work and find an answer another way, or give up entirely.

However, I found a way to use Quicksilver to access these functions, inspired by a friends QuicksilverPythonTodoList program. He uses Quicksilver, as I do, to easily find and open programs and files on the mac, to move and copy files, to create qr codes, to search google, and many other things.  And he uses it to call up a python program and add items to a todo list by a simple keyboard command.  By pressing Cmd-Space, period, typing his todo item, pressing tab, and enter, quicksilver automatically opens up the correct python program, enters in the correct input, the python script runs which updates a text file, which is automatically saved and displayed on his background via GeekTool. All in the background, instantly (practically), at the press of a few simple buttons.  I wanted that too, for my mathematical functions.

So I gathered all my functions into one python module which I called and reading Brian's post on adding custom actions to quicksilver I set out to enable this for myself.  It took three steps, which I'll outline for you if you're interested yourselves:

Step 0: Install quicksilver and learn how to use the period to enter text entry mode
  1. Create a python module that has any desired functions all in one place.  Take note of the file name and path as you will need it later. Mine was ~/Documents/script/
  2. Use terminal to access that file and call up a function.  I had to use a -c switch with python to access my functions.  Something like:
        python -c "import euler; print euler.factors(30)"
    This is essentially a two-line program that imports my list of functions, and calls one of them specifically.  
  3. Write an applescript file that calls this terminal command.  In order for quicksilver to recognize it, you'll need to save this applescript file in ~/Library/Application Support/QuickSilver/Actions and then restart QS.  I created an applescript named DoMath.
    using terms from application 'Quicksilver' on process text theText set results to do shel script 'cd ~/Documents/script; python -c "import euler; print euler." & theText & "'" return results end process text end using terms from
Now I can access my files by the following keystrokes:
cmd space, period, type my functions name, tab, type domath, enter.

Having a heavy interest in cryptography, I also took many of the functions I wrote to encipher and decipher messages and set it up to be done the same way.  So now:
cmd space, period, CaesarShift("hello world") tab encoder instantly produces Khoor zruog.  

I have one improvement I'd like to do -- but not sure how to quite yet.  I'd like to be able to have it save the results to the clipboard automatically.  I'm sure that's possible with an additional tweak of the DoMath and Encoder applescripts -- but that's a learning project for another day.
Related Posts Plugin for WordPress, Blogger...