thefekete.net

$> :(){ :|:& };:

Bash script to rename gEDA PCB gerber files to BatchPCB format

Just wrote a quick bash script to rename PCB gerber exported files to the BatchPCB naming rules.

It expects a list of files as arguments. PCB exports files with a ‘grb’ extension so the following should work just fine:

#!/bin/bash
$> gpcb2batchpcb *.grb

Read the rest of this entry »

Pseudo git diff with gEDA gschem in bash

Not really a diff, but you can switch between two (or more) schematics from different commits and see what changed. Here’s how…

The ingredients

First of all, you can open multiple files with gschem by listing them after the command:

#!/bin/bash
gschem FILE1 FILE2 ...

… and you can retrieve old versions of files with git-show:

#!/bin/bash
git show HEAD^:SOME_FILE
git show ab05831:SOME_FILE

For more info on how to specify a file, see the git-show man page.

Putting it together

Unfortunately, you can’t pipe schematics to gschem’s stdin (that I know of). Even if you could, we want to compare two schematics, so how would you pipe two files to stdin? It all seemed pretty tough to me until I found a post on stack overflow showing exactly how to handle it… Using process substitution, it becomes an easy problem:

#!/bin/bash
# See the last committed and current versions of a file
gschem <(git show HEAD:SOME_FILE) SOME_FILE
# See any two files in history
gschem <(git show OBJECT) <(git show OBJECT)

Bash script / function to append file names

In my previous post about appending file names, I made a one-off solution.

Here’s a bash function that you can throw in your .bashrc and use more easily:

#!/bin/bash

# Put this in your ~/.bashrc and use it like a script...
append_filename() {
    USAGE="append: Puts text between filename and extension"
    USAGE="$USAGE\nUsage: $0 APPENDAGE file1 file2 file3 ..."

    if [ "$#" == "0" ]; then
        echo -e "$USAGE"
        return 1  # exit kills shell this is called from
    fi

    # get appended string
    APPENDAGE=$1
    shift

    while (( "$#" )); do
        if [ -f "$1" ]; then  # don't rename directories
            mv "$1" "${1%.*}$APPENDAGE.${1##*.}"
        fi
        shift  # grab the next file in list
    done
}

Appending filenames, not extensions

I had a group of files that I needed to append a suffix to, but leave the extension intact. Basically, I needed to split the filename and extension, then put them back together with some filling in the middle…

This answer @ stack overflow shows how to split them, and then it’s pretty easy to put them back together:

#!/bin/bash
FILLER='-1'  # Whatever you want to append to the filename
for i in *
do
    mv $i "${i%.*}$FILLER.${i##*.}"
done

Two Simple Guitar Amps

Was messing around the last couple of days with my guitar, and got a little too close to the electronics bench…

I ended up with the following small amp circuits (I say small, but these things are louder than shit through a 1×12 cabinet):

Single LM386 1/2W Amp

Dual LM386 1W Amp

Here’s a pic of the bridged circuit on the breadboard:
Breadboarded Bridged LM386 Amp

Anyways, waiting for some JFETs in the mail so I can wire up some proper preamps.

These closely follow the the example circuits in the datasheet, but many thanks to runoffgroove.com for the great examples – particularly the little gem designs.

Splitting large files for a FAT32 removable drive or flash drive

If you got a file or group of files to put on a removable drive with a FAT32 file system – and any of them are over 4GB – then you need a way to make it smaller for transport. The easiest way is with split, cat and tar.

Read the rest of this entry »

Remove trailing whitespace from lines in Vim

Put this in your command mode and smoke it:

:s/ \+$//g

Match RAR archives

The Following can be used to find the first RAR file in a multi-volume archive. It will find *.part01.rar or *.rar depending on the naming convention in use.

.*[^p][^a][^r][^t]..\.rar$|.*part01\.rar$

If you need to find all the RAR files and SFV files (probably to delete them after extraction), the following will get them all.

.*\.r[0-9]{2}$|.*\.rar$|.*\.sfv$

Bash: Count Lines of Code in a Python Project

#!/bin/bash
find . -name '*.py' | xargs cat | sed '/^\s*#/d;/^\s*$/d' | wc -l

xargs converts find’s output to arguments, the sed RE drops comments and blank lines, and wc counts them lines. Thanks to these posts on stack overflow for some reference material.

Efficiently testing multiple model methods at once in Django

Update 2011-08-03

I have since ditched this idea because “Explicit is better than implicit” and “Readability counts.”

The method listed below is not very readable and very implicit in nature. Basically, if you handed this to someone (or you in 6 months), it wouldn’t be immediately obvious what is doing what. Which is not the reaction you want when tests are failing for some unknown reason.

I’ve settled on separate test methods for each model method/attribute. It’s a little more verbose, but very clear and easy to decipher.

I have left the original post to document my learning process, and to remind myself not to cross that fine line between clever and stupid.

/Update

I recently wrote some tests for a model that had many (eight) methods that calculated various values from the fields of the model. I needed to test the methods under many different conditions and found myself writing eight or so self.assertEqual(...) statements for each test condition. I was repeating myself and I didn’t like it.

To remedy the situation, I made a list of the methods I was calling over and over, and then wrote a simple function to iterate over the listed methods and assert that they returned equal to the values I passed the function. Below is a simplified example of how it worked:

# tests.py

from models import MyModel

class MyModelTest(TestCase):

    def test_methods(self):
        methods = ('method1', 'method2', 'method3')

        def assert_methods(obj, values):
            for m, v in zip(methods, values):
                ret = getattr(obj, m)()
                try:
                    self.assertEqual(ret, v)
                except AssertionError:
                    raise AssertionError('%s[%s].%s() returned %s expected %s'
                            % (obj.__class__.__name__, obj.pk, m, ret, v))

        # Create an object to test
        obj1 = MyModel.objects.create(...)
        # Assert that method1(), method2() and method3 return
        # 123, 'abc', and None respectively
        assert_methods(obj1, (123, 'abc', None))
        # Make some change to obj1
        obj1.somefield = 18
        obj1.save()
        # Assert the change on the methods
        assert_methods(obj1, (987, 'abc', False))

        # Create a different object
        obj2 = MyModel.objects.create(...)
        # Assert different return values for methods
        assert_methods(obj2, (456, 'efg', False))

The vital parts above are the methods list and assert_methods(). methods stores a list of strings naming the methods you want to call on your model instance. assert_methods() takes an object (the model instance) and a list of values to compare to the method’s returns.

The error handling prints out a more helpful message when assertion fails, including the model name, primary key, and method called along with the expected and actual values.

So basically, assert_methods() asserts that methods[0] = values[0], methods[1] = values[1] and methods[n] = values[n], etc.

Of course, this is limited to one type of assertion for all the methods, but it’s really useful when you gotta do the same thing a bunch of times. Anyways, hope this helps someone out there, if so let me know.