Python is amazing.
For those who don’t already know, Python is a cross-platform high-level scripting language. It’s designed from the ground up to be extremely easy to use, with a “batteries included” philosophy – almost everything you need to do almost anything is included in the basic distribution.
The strong cross-platform support is another good feature of Python – it’s relatively easy to write a program in Python that “just works” across Linux, MacOS or Windows. Even more wonderful is the fact that the Python interpreter has been cross-compiled over to run on many embedded platforms, which means that all the power of Python is available for boards like the pcDuino, Raspberry Pi, and BeagleBone Black.
Ever since I started dabbling with Python four or five years ago, it’s become a part of my daily life in several ways. Here I’ll present a brief summary of two problems I’ve attacked with Python, to give you some idea of how useful it can be in real practice.
Caveat: I’m not going to claim any tremendous skill at writing Python code; I’m taking a calculated risk in exposing my amateurish code to the world to show people who don’t know much about Python just how easy it is to get some pretty great results. Also, please don’t let’s get into any flame wars about which language is better! I expect that if I’d heard of, say, Ruby before Python, this tutorial might be about Ruby instead.
A common electrical engineering problem is the creation of a resistor divider. If you’re not familiar, a resistor divider allows you to take a known voltage (say, 5V) and generate a reference voltage at a second, lower voltage (say, 3.3V).
Resistor dividers happen all the time. While the math behind a resistor divider is easy (trivial, even), getting values for the two resistors that match the resistors you have on hand (or even the resistors which are available for purchase) becomes more difficult. I think, given the context of this post, you can probably guess what’s coming.
Above is a screenshot of the command line (a GUI would be an unnecessary complication) output of my script. I asked for a 5V to 3.3V divider, using the values specified in SFE.txt (which is a file I created from our MRP system – using ANOTHER Python scrip t– of stocked SparkFun resistor values). The result is a list of five possible solutions, delivered in order from smallest nominal error to largest nominal error. It also gives the output impedance of the divider; that can be very important, depending on what you plan to use the divider for.
You can find the source for this in my personal GitHub account.
Another thing we run across is a desire to get fancy with our PCB designs. This can be for board shapes, silkscreen, logos, or whatever. EAGLE is pretty limited when it comes to editing shapes; you can have anything you want as long as it’s a straight line, ellipse, or section of an ellipse.
EAGLE, of course, has a powerful built-in scripting language (ULP) which is C-ish, but I have very little enthusiasm for learning new programming languages which aren’t portable. My solution to the problem was to learn about the SVG file format, as supported by Inkscape, and implement a
simple Python script that can pull shapes out of an SVG file and generate a script for EAGLE that will draw the shape in EAGLE.
Here’s the result. The script has its limitations: it only works on paths, it only works on ungrouped objects in the top layer, and it doesn’t deal well with negative space. Within those constraints, however, it does a pretty decent job.
It generates both filled polygons and lines; layer is determined by the red channel of the stroke, thickness by the weight of the line, and fill by, well, fill of the path object.
I’ve noticed that it behaves poorly on files imported from Illustrator, but on Inkscape native drawings, it works a treat! It’s available on my GitHub page as well, and the SVG file I used above is there, too, just to provide a known good.
I’ve done lots of other fun things with Python that I’m not going to share here: data scrapers from our MRP system, a bot that watches for comments on our website and alerts me to certain things, and a “You’ve Got Mail!” light. The massive number of libraries which are available for Python make it very easy to get working applications banged together in no time at all.
The last thing I want to mention for the complete newb is Python’s versioning. Right now, there are two different branches of Python – 3.x and 2.x. Code written to work in 2.x (all mine was written in 2.7.3) will generally not run without modification in 3.x, and vice versa. Most libraries out there are written with 2.x support in mind, and won’t work properly for 3.x.
This is a bit of a problem; officially, 2.x is deprecated, 2.7.x is the only pre-3.x version still being worked on, and only bug fixing is happening – no new features will be added. Practically, the community hasn’t really embraced 3.x, and much (most?) of the examples and libraries that turn up when you ask Google for help with Python are 2.x compatible only.
My advice? Download the latest version of 2.7 for your platform and stick with that. The documentation on the python.org website is first rate, and their tutorial is a great step-by-step introduction for people who can program, but don’t know Python yet.
One of the reasons I shared the two examples I did is because I know they could use some improvement. If you have an inclination, feel free to fork my repos and carry on improving them. At this point, they work well enough for me, most of the time, and I don’t have time to really push either of these programs ahead.