Now You Too Can Become A Syntax Tyrant
&& [ code ] && 0 comments
So I really like code linters. My coworkers know this. Actually, I got called a syntax Nazi today by a fellow developer. I’m OK with that. I believe in readability and consistency.
In my projects I make it impossible to make a git commit before the source code passes a flake8 check. How to perform this minor miracle you ask? With a simple git pre-commit hook:
myproject/.git/hooks/pre-commit
1 2 | |
When I commit, the hook executes. Since git knows a return of anything besides 0 means abort, it stops the commit from happening. Awesome.
Here is a terminal recording of it in action:
Don’t forget to make your pre-commit hook file executable!
Sane Django Development with Docker
&& [ code ] && 9 comments
Recently I started a new Django project, and this time I decided to go all in on Docker. No virtualenvs, no local databases - containers all the way.
There are about a million and ten articles about how to dockerize webapps by now. However, none of them seem to address one simple fact: we don’t simply want to dockerize our applications, we want to develop them too!
sane-django-docker
contains a sample django project webapp as well as the necessary
config files to run both a development and production server.
Checkout and Go®
One of my goals was to make the codebase development
first. One should be able to checkout the codebase and run at most two or three commands
to have a real development environment set up. This
means we should have a live-reloading Django development
server, debug mode on, and a postgresql database. I also can’t stand logic
in my settings.py files, so it is left as vanilla as possible. It
will import a local_settings.py file at the end, but besides that it is 100%
constants. No os.getenv() to be found.
To start the development server simply run:
docker-compose up
Django will complain about the postgres database not existing so we’ll create one:
docker exec sanedjangodocker_db_1 createdb -Upostgres webapp
Sweet Jane! We now have a Django development server running at http://localhost:8000 along with a postgresql database! Make a code
change and watch it reload. This is how code was meant to be written.
So what’s the secret sauce? A super simple Dockerfile and an equally simple docker-compose.yml file.
Deployment ain’t that much harder
So getitng a dev environment up and running is all well and good, but we are going to have to deploy our code at some point. Deployment takes a few additional steps, but then again deployment probably should.
Let’s take a look at what we have:
.
├── deploy
│ ├── docker-compose.yml
│ ├── local_settings.py
│ ├── nginx-app.conf
│ ├── supervisor-app.conf
│ ├── uwsgi.ini
│ └── uwsgi_params
├── docker-compose.yml
├── Dockerfile
├── Dockerfile.prod
├── manage.py
├── README.md
├── requirements.txt
└── webapp
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
The deploy/ directory contains all our server configuration files.
The directory also includes our local_settings.py which contains our
production config. It is included in .gitignore and should not be
included in source control!
Dockerfile.prod is our production dockerfile. It is based on Python:3.5,
installs nginx, uwsgi and supervisord, copies our config files and finally
runs manage.py collectstatic.
Let’s build an image from it:
docker build -f Dockerfile.prod -t webapp:latest .
That’s it! our production image is ready to go. To test it out locally first, we can run it:
cd deploy/ && docker-compose up
This should start our project in production mode, using the image we just built. Again, we need to initially create the database, and we should probably run migrations too:
docker exec sanedjangodocker_db_1 createdb -Upostgres webapp
docker exec sanedjangodocker_web_1 python3 manage.py migrate
Navigate to localhost:8700 and see your production-ready application
being served!
Where to go from here
There are probably a few things you want to tweak for a real project such as
the postgresql data volume in deploy/docker-compose.yml, and
your ALLOWED_HOSTS setting in local_settings.py.
Of course, the nginx, uwsgi and supervisord config files are pretty basic, and probably should be scrutinized before a real life deploy.
Conclusions
All in all, I’ve found this to be a pretty frictionless workflow. The one annoyance I have is that both dockerfiles have to be in the top level directory, due to how Docker sends the build context to the server. Besides that there isn’t much to complain about - I’ll probably use this as a base for my future projects.
Why I Still Prefer Unity: It's All About Real Estate
&& [ linux ] && 0 comments
I’ve been pretty good about not becoming a open source pundit. But today I feel like writing something useless.
My laptop’s ssd crapped out yesterday so I spent the day restoring backups and installing operating systems. I’ve been using Ubuntu for a few years now, so I thought it would be great to revisit Gnome and see how the 3.x development is coming along, maybe even switch back.
Nope.
There are many things I don’t like, but like many blog posts written before this one, I’m going to bitch and moan about a minute detail until the horse is well beyond dead.
Screen real estate. Gnome’s devs claim that Gnome Shell is minimalist and efficient, but I beg to differ. Here is an image comparing Gnome and Unity, using their default themes, and a terminal in the upper left hand corner of the screen:

The screenshots were taken using the same resolution. Gnome’s gluttons window decorations make me sick. They create a ton of wasted space, whereas Unity’s much thinner ones double as the menu bar. I can squeeze like, 2 more lines in the terminal using Unity!
What’s more, if I maximize, Unity integrates the entire window border into the top panel, freeing yet more space.
Sorry Gnome, but I’m still not impressed. The whole experience still feels like it’s designed for a tablet. For example, the “swipe up ^” animation on GDM is just plain offensive! No thanks, not for my laptop at least. Maybe I’ll run Gnome on an old smartphone.
Back to Unity, again.
The new Star Wars is Already Full of Fail
&& [ other ] && 3 comments
I was waiting in line at the supermarket this morning when I came across this cover of the June 2015 Vanity Fair:

Immediately something struck me as very, very wrong.
I know we all hope the new Star Wars will be good and make up for the complete travesty of episodes I, II and III. But I’m going to make a quick and uninformed judgment based solely on this magazine cover and say: no, no it won’t.
The problem my friends, is Chewbacca. Chewbacca does not casually pose for photographs. I mean just look at him! He’s got his arm up on a chair all relaxed and cool like he’s James Dean or something. He’s even got a disgusting smug smile on his face and his head is cocked to the side as if he’s waiting to complement you on your haircut. Terrible. Also, is his face airbrushed? What the hell!
This is the true Chewbacca:

Chewbacca is bigfoot in space: a vicious hairy beast who will rip off every one of your appendages for accidentally touching his bowcaster. There were very few scenes in the original Star Wars when he wasn’t actively trying to damage someone or something, much less acting calm and collected.
If you need any more proof that Hollywood is a mere impersonation of what it once was, destroying everything good that it had once accomplished, look no further. They are killing Star Wars - again.
Upgrading Wheezy to Jessie: Nginx and PHP5-fpm
&& [ code ] && 1 comments
I just upgraded this VPS from Debian Wheezy to Jessie. The upgrade went pretty flawless, excpet some minor issues with postgres and the new bad systemd smell.
However, if you are running NGINX + PHP5-fpm, you may want to read the news that gets displayed during the upgrade:
nginx shipped a modified `fastcgi_params`, which declared `SCRIPT_FILENAME`
fastcgi_param. This line has now been removed. From now on we are also
shipping fastcgi.conf from the upstream repository, which includes a sane
`SCRIPT_FILENAME` parameter value.
So, if you are using fastcgi_params, you can try switching to fastcgi.conf
or manually set the relevant params.
After the upgrade, I was getting blank responses from nginx for all php scripts. No errors in nginx or fpm logs. After re-reading the news above, the following fix worked for me:
In /etc/nginx/sites-available/* change
include fastcgi_params
to
include fastcgi.conf
Hope this helps anyone in need.
100 Observations Logged on AstroChallenge!
&& [ featured, astrochallenge, astronomy, code ] && 0 comments

I created AstroChallenge to scratch my own itch: to have a place to keep an observation journal for astronomy and to share it with the rest of the community. In that I believe I’ve succeeded, check out my profile and journal.
Since then the word has gotten out and other astronomers have been logging their own observations. Now, only 2 weeks after making AstroChallenge public, over 100 observations have been logged! I want to thank everyone who has helped me make AstroChallenge awesome by providing great feedback and ideas.
It’s been a fun project so far and I look forward to seeing where it goes from here. Most of all, I wish everyone clear skies! Keep looking up.
Feynman on "Computer Disease"
&& [ other ] && 0 comments

The following is a excerpt from the book I am currently reading by Richard Feynman, Surely You Must be Joking, Mr. Feynman! that I found amusing.
Well, Mr. Frankel, who started this program, began to suffer from the computer disease that anybody who works with computers now knows about. It’s a very serious disease and it interferes completely with the work. The trouble with computers is you play with them. They are so wonderful. You have these switches–if it’s an even number you do this, if it’s an odd number you do that–and pretty soon you can do more and more elaborate things if you are clever enough, on one machine.
After a while the whole system broke down. Frankel wasn’t paying any attention; he wasn’t supervising anybody. The system was going very, very slowly–while he was sitting in a room figuring out how to make one tabulator automatically print arc-tangent X, and then it would start and it would print columns and then bitsi, bitsi, bitsi and calculate the arc-tangent automatically by integrating as it went along and make a whole table in one operation.
Absolutely useless. We had tables of arc-tangents. But if you’ve ever worked with computers, you understand the disease–the delight in being able to see how much you can do. But he got the disease for the first time, the poor fellow who invented the thing.
Still suffering to this day!
Reviving fchart to Create Beautiful Astronomical Finder Charts
&& [ astronomy, code, astrochallenge ] && 0 comments
I’ve spent a good deal of time in the last few days searching for a good library to draw star charts (finder charts) that I could use to integrate with AstroChallenge. While there are plenty of utilities to create star maps, they mostly consist of desktop software or websites that are not open source.

Eventually I found fchart which resembled was I was looking for. A set of python scripts with minimal dependencies that would output star maps! This I could use.
I extracted the package downloaded from Michiel Brentjens’ website and hit go… nothing. Then I realized the file’s last modified date: 2005. Uh-oh. It depended on numarray, a package long ago replaced by numpy.
But the source was clean, so I decided to see if I couldn’t upgrade it to work in numpy and python2.7. Indeed, after a few find/replaces and some method renaming, the code ran! However, there was another problem. The tyc2.bin file from fchart website seemed to be corrupt - I couldn’t get any stars to draw. So I headed over to http://cdsarc.u-strasbg.fr/viz-bin/Cat?I/259 and grabbed a fresh copy of the tyco2 star database, concatenated the archives and created a new tyc2.bin file using the tyc2_to_binary script.
Now everything appears to be working. The image above is an example of a chart generated for the Andromeda Galaxy. I emailed Michiel to let him know about my modifications and that I’ve hosted the code on github. The repo also contains the new tyc2.bin file that contains the star catalog - so the installation should run out of the box without issues.
This is a great example of why open source software works. Not only can the software be useful to a wider audience now, but I plan on adding my own improvements and functionality.
GraniteMaps: Soquel Demonstaion Forest/Nisene Marks released!
&& [ granitemaps, code, cartography ] && 0 comments

After much ado, the latest map from GraniteMaps is now available. This map covers 2 distinct areas; The first is Soquel Demonstration Forest, well known in the mountain biking community as having miles of challenging, technical singletrack. The other is the Forest of Nisene Marks which shares a ridge with Demo and provides trail users of all types some of the most pristine redwood forest trails available in California.
This new map is much improved over the last version for Santa Cruz by having a brand new base layer. This is a custom topographic map I designed myself (detailed in this post) which combines OpenStreetMap and SRTM data to create a concise, easy to read map. I hope you enjoy it.
Thanks everyone for your kind words and support! The reception I received for the Santa Cruz map was fantastic, far exceeding anything I could have imagined while creating it!
Using Django and PyEphem to Determine the Location of White Fuzzies
&& [ AstroChallenge, astronomy, code ] && 0 comments
I’ve been working on new project recently called AstroChallenge. While the details of what exactly AstroChallenge is will have to come later, rest assured, it has to do with Astronomy.

One of the bits of information I’m interested in is whether a particular celestial object is visible in the sky or not. Given an observer’s latitude, longitude and elevation and an object’s right ascension and declination it becomes a straightforward calculation.
However, there are libraries written by smarter people than I and it would be a good idea to use them. So instead if spending my time carefully coding maths, I can simply:
$pip install pyephem
and
import ephem
into my project.
Now the work is done for me. Isn’t the modern age great?
PyEphem is a great python library for performing calculations on all sorts of celestial objects including planets, moons, comets, asteroids, stars and deep space objects. Once you input your observation date, time and location some of the interesting functions you can run include:
-
Next transit
-
Altitude, Azimuth
-
Distance from Earth, Sun, other bodies
-
Current Constellation
-
Phase, day, month and year
And so on. When you set up an observer, you can even supply dates in the path so you can, for example, find the positions of the moons of Jupiter on February 15, 1564.
Since AstroChallenge is a webapp written in Django we have data models for things like deep space objects on which we can place handy methods to get information from pyephem:
(fields truncated for readability) {{< highlight python >}} class DeepSpaceObject(models.Model): ra_hours = models.IntegerField() ra_minutes = models.FloatField() dec_sign = models.CharField(max_length=1, choices=((‘+’, ‘+’), (‘-‘, ‘-‘)), default=”+”) dec_deg = models.IntegerField() dec_min = models.FloatField()
@property
def fixed_body(self):
""" Return a FixedBody object which PyEphem uses to perform calculations """
object = ephem.FixedBody()
object._ra = "{0}:{1}".format(self.ra_hours, self.ra_minutes)
object._dec = "{0}{1}:{2}".format(self.dec_sign, self.dec_deg, self.dec_min)
return object
def observation_info(self, observer):
""" Given an observer, perform the calculations we are interested in and return them as a dictionary """
p_object = self.fixed_body
p_object.compute(observer)
up = True if ephem.degrees(p_object.alt) > 0 else False
return {
'alt': str(p_object.alt),
'az': str(p_object.az),
'up': up,
'neverup': p_object.neverup,
'rise': timezone.make_aware(observer.next_rising(p_object).datetime(), pytz.UTC) if p_object.rise_time else None,
'set': timezone.make_aware(observer.next_setting(p_object).datetime(), pytz.UTC) if p_object.set_time else None
}
{{< / highlight >}}
Some things to note:
-
An object is “visible” if it’s Altitude is greater than 0, meaning it is above the horizon. If it still light out, or you live in a light polluted area, you’re probably still out of luck, though,
-
PyEphem’s
Observer.next_rising/settingmethods may returnNone, that means an object either never rises (as can be determined usingBody.neverup) or never sets.
The Observer data can be provided using a simple method on a UserProfile model:
{{< highlight python >}} class UserProfile(models.Model): user = models.OneToOneField(User, editable=False) timezone = TimeZoneField(default=”UTC”) lat = models.FloatField(“latitude”, default=0.0) lng = models.FloatField(“longitude”, default=0.0) elevation = models.IntegerField(default=0)
@property
def observer(self):
observer = ephem.Observer()
observer.lat, observer.lon, observer.elevation = str(self.lat), str(self.lng), self.elevation
return observer
@property
def sunset(self):
sun = ephem.Sun()
sun.compute(self.observer)
return timezone.make_aware(self.observer.next_setting(sun).datetime(), pytz.UTC)
{{< / highlight >}}
Notice the observer property just returns an observer, so we can now supply it in our views to a Celestial object and get the information we need. Another
handy property, sunset uses the observer property to compute the time at
which the sun will be setting for this user. PyEphem rocks.

