<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>thefekete.net</title>
	<atom:link href="http://thefekete.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://thefekete.net</link>
	<description>$&#62; :(){ :&#124;:&#38; };:</description>
	<lastBuildDate>Mon, 12 Mar 2012 23:43:42 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Bash script to rename gEDA PCB gerber files to BatchPCB format</title>
		<link>http://thefekete.net/blog/bash-script-to-rename-geda-pcb-gerber-files-to-batchpcb-format/</link>
		<comments>http://thefekete.net/blog/bash-script-to-rename-geda-pcb-gerber-files-to-batchpcb-format/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 23:43:42 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[gEDA PCB]]></category>
		<category><![CDATA[BatchPCB]]></category>
		<category><![CDATA[gEDA]]></category>
		<category><![CDATA[pcb]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=530</guid>
		<description><![CDATA[Just wrote a quick bash script to rename PCB gerber exported files to the <a href="http://batchpcb.com/index.php/Faq#what_is_a_gerber">BatchPCB naming rules</a>.]]></description>
			<content:encoded><![CDATA[<p>Just wrote a quick bash script to rename PCB gerber exported files to the <a href="http://batchpcb.com/index.php/Faq#what_is_a_gerber">BatchPCB naming rules</a>.</p>
<p>It expects a list of files as arguments. PCB exports files with a &#8216;grb&#8217; extension so the following should work just fine:</p>
<pre><code>#!/bin/bash
$> gpcb2batchpcb *.grb</code></pre>
<p><span id="more-530"></span></p>
<p>Anyways, here&#8217;s the script:</p>
<pre><code>#!/bin/bash
USAGE="Usage: $0 file1 file2 .. fileN"
# gpcb2batchpcb - A script to rename pcb gerber files to BatchPCB rules
#
# NOTES: did not implement keepout or middle layers

if [ "$#" == "0" ]; then
    echo "$USAGE"
    exit 1
fi

while (( "$#" )); do
    if [ ! -f $1 ]; then
        echo "$1 is not a regular file, nothing to do."
    fi

    case "$1" in
        *front.gbr)
            # TopCopper
            echo "Found TopCopper Layer: $1"
            cp -v "$1" "${1%.front.gbr}.batchpcb.top"
            ;;
        *back.gbr)
            # BottomCopper
            echo "Found BottomCopper Layer: $1"
            cp -v "$1" "${1%.back.gbr}.batchpcb.bot"
            ;;
        *frontmask.gbr)
            # TopSolderMask
            echo "Found TopSolderMask Layer: $1"
            cp -v "$1" "${1%.frontmask.gbr}.batchpcb.tsm"
            ;;
        *backmask.gbr)
            # BottomSolderMask
            echo "Found BottomSolderMask Layer: $1"
            cp -v "$1" "${1%.backmask.gbr}.batchpcb.bsm"
            ;;
        *frontsilk.gbr)
            # TopSilk
            echo "Found TopSilk Layer: $1"
            cp -v "$1" "${1%.frontsilk.gbr}.batchpcb.slk"
            ;;
        *backsilk.gbr)
            # BottomSilk
            echo "Found BottomSilk Layer: $1"
            cp -v "$1" "${1%.backsilk.gbr}.batchpcb.bsk"
            ;;
        *plated-drill.cnc)
            # Drill
            echo "Found Drill Layer: $1"
            cp -v "$1" "${1%.plated-drill.cnc}.batchpcb.cnc"
            ;;
        *backpaste.gbr)
            # BottomStencil
            echo "Found BottomStencil Layer: $1"
            cp -v "$1" "${1%.backpaste.gbr}.batchpcb.gbp"
            ;;
        *frontpaste.gbr)
            # TopStencil
            echo "Found TopStencil Layer: $1"
            cp -v "$1" "${1%.frontpaste.gbr}.batchpcb.gtp"
            ;;
        *outline.gbr)
            # Outline
            echo "Found Outline Layer: $1"
            cp -v "$1" "${1%.outline.gbr}.batchpcb.outline"
            ;;
        *)
            echo "* Unknown file: $1"
    esac
    echo

    shift  # grab next argument
done</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/bash-script-to-rename-geda-pcb-gerber-files-to-batchpcb-format/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pseudo git diff with gEDA gschem in bash</title>
		<link>http://thefekete.net/blog/pseudo-git-diff-with-geda-gschem/</link>
		<comments>http://thefekete.net/blog/pseudo-git-diff-with-geda-gschem/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 22:08:48 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[gschem]]></category>
		<category><![CDATA[diff]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=517</guid>
		<description><![CDATA[Not really a diff, but you can switch between two (or more) schematics from different commits and see what changed. Here&#8217;s how&#8230;
The ingredients
First of all, you can open multiple files with gschem by listing them after the command:
#!/bin/bash
gschem FILE1 FILE2 ...
&#8230; and you can retrieve old versions of files with git-show:
#!/bin/bash
git show HEAD^:SOME_FILE
git show ab05831:SOME_FILE
For [...]]]></description>
			<content:encoded><![CDATA[<p>Not really a diff, but you can switch between two (or more) schematics from different commits and see what changed. Here&#8217;s how&#8230;</p>
<h3>The ingredients</h3>
<p>First of all, you can open multiple files with <code>gschem</code> by listing them after the command:</p>
<pre><code>#!/bin/bash
gschem FILE1 FILE2 ...</code></pre>
<p>&#8230; and you can retrieve old versions of files with <code>git-show</code>:</p>
<pre><code>#!/bin/bash
git show HEAD^:SOME_FILE
git show ab05831:SOME_FILE</code></pre>
<p>For more info on how to specify a file, see the <a href="http://linux.die.net/man/1/git-show">git-show man page</a>.</p>
<h3>Putting it together</h3>
<p>Unfortunately, you can&#8217;t pipe schematics to gschem&#8217;s stdin (that I know of). Even if you could, we want to compare <em>two</em> schematics, so how would you pipe two files to stdin? It all seemed pretty tough to me until I found <a href="http://stackoverflow.com/questions/1569730/paste-without-temporary-files-in-unix">a post on stack overflow showing exactly how to handle it</a>&#8230; Using <a href="http://tldp.org/LDP/abs/html/process-sub.html">process substitution</a>, it becomes an easy problem:</p>
<pre><code>#!/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)</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/pseudo-git-diff-with-geda-gschem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash script / function to append file names</title>
		<link>http://thefekete.net/blog/bash-script-function-to-append-file-names/</link>
		<comments>http://thefekete.net/blog/bash-script-function-to-append-file-names/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 23:05:26 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[function]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=503</guid>
		<description><![CDATA[In my previous post about appending file names, I made a one-off solution.
Here&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="/blog/appending-filenames-not-extensions/">my previous post about appending file names</a>, I made a one-off solution.</p>
<p>Here&#8217;s a bash function that you can throw in your <code>.bashrc</code> and use more easily:</p>
<pre><code>#!/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
}</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/bash-script-function-to-append-file-names/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Appending filenames, not extensions</title>
		<link>http://thefekete.net/blog/appending-filenames-not-extensions/</link>
		<comments>http://thefekete.net/blog/appending-filenames-not-extensions/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 21:50:36 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[for-loop]]></category>
		<category><![CDATA[mv]]></category>
		<category><![CDATA[rename]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=493</guid>
		<description><![CDATA[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&#8230;
This answer @ stack overflow shows how to split them, and then it&#8217;s pretty easy to put [...]]]></description>
			<content:encoded><![CDATA[<p>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&#8230;</p>
<p><a href="http://stackoverflow.com/a/965072">This answer @ stack overflow</a> shows how to split them, and then it&#8217;s pretty easy to put them back together:</p>
<pre><code>#!/bin/bash
FILLER='-1'  # Whatever you want to append to the filename
for i in *
do
    mv $i "${i%.*}$FILLER.${i##*.}"
done</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/appending-filenames-not-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two Simple Guitar Amps</title>
		<link>http://thefekete.net/blog/two-simple-guitar-amps/</link>
		<comments>http://thefekete.net/blog/two-simple-guitar-amps/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 05:56:24 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[Guitar]]></category>
		<category><![CDATA[amp]]></category>
		<category><![CDATA[analog]]></category>
		<category><![CDATA[guitar]]></category>
		<category><![CDATA[lm386]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=471</guid>
		<description><![CDATA[Was messing around the last couple of days with <a href="/wp-content/uploads/2012/01/images_list_8_52_26357_1-e1326952260311.jpg">my guitar</a>, and got a little too close to the electronics bench...]]></description>
			<content:encoded><![CDATA[<p>Was messing around the last couple of days with <a href="/wp-content/uploads/2012/01/images_list_8_52_26357_1-e1326952260311.jpg" rel="lightbox[471]">my guitar</a>, and got a little too close to the electronics bench&#8230;</p>
<p>I ended up with the following small amp circuits (I say small, but these things are louder than shit through a 1&#215;12 cabinet):</p>
<p><a href="http://thefekete.net/wp-content/uploads/2012/01/lm386.amp_.gif" rel="lightbox[471]"><img src="http://thefekete.net/wp-content/uploads/2012/01/lm386.amp_-300x189.gif" alt="Single LM386 1/2W Amp" title="Single LM386 1/2W Amp" width="300" height="189" class="aligncenter size-medium wp-image-472" /></a></p>
<p><a href="http://thefekete.net/wp-content/uploads/2012/01/lm386.bridged.amp_.gif" rel="lightbox[471]"><img src="http://thefekete.net/wp-content/uploads/2012/01/lm386.bridged.amp_-300x239.gif" alt="Dual LM386 1W Amp" title="Dual LM386 1W Amp" width="300" height="239" class="aligncenter size-medium wp-image-474" /></a></p>
<p>Here&#8217;s a pic of the bridged circuit on the breadboard:<br />
<a href="http://thefekete.net/wp-content/uploads/2012/01/IMG_20120118_214910.jpg" rel="lightbox[471]"><img src="http://thefekete.net/wp-content/uploads/2012/01/IMG_20120118_214910-300x225.jpg" alt="Breadboarded Bridged LM386 Amp" title="Breadboarded Bridged LM386 Amp" width="300" height="225" class="aligncenter size-medium wp-image-490" /></a></p>
<p>Anyways, waiting for some JFETs in the mail so I can wire up some proper preamps.</p>
<p>These closely follow the the example circuits in the datasheet, but many thanks to <a href="http://www.runoffgroove.com">runoffgroove.com</a> for the great examples &ndash; particularly the <a href="http://www.runoffgroove.com/littlegem.html">little gem designs</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/two-simple-guitar-amps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Splitting large files for a FAT32 removable drive or flash drive</title>
		<link>http://thefekete.net/blog/splitting-large-files-for-a-fat32-removable-drive-or-flash-drive/</link>
		<comments>http://thefekete.net/blog/splitting-large-files-for-a-fat32-removable-drive-or-flash-drive/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 01:03:28 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[cat]]></category>
		<category><![CDATA[split]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=461</guid>
		<description><![CDATA[If you got a file or group of files to put on a removable drive with a FAT32 file system &#8211; and any of them are over 4GB &#8211; then you need a way to make it smaller for transport. The easiest way is with split, cat and tar.]]></description>
			<content:encoded><![CDATA[<p>If you got a file or group of files to put on a removable drive with a FAT32 file system &ndash; and any of them are over 4GB &ndash; then you need a way to make it smaller for transport. The easiest way is with split, cat and tar.</p>
<p><span id="more-461"></span></p>
<h3>One file</h3>
<p>For the simplest case of a single file, you can just split it:</p>
<pre><code>
#!/bin/bash
split --numeric-suffixes --bytes=4GB SRCFILE SRCFILE.split</code></pre>
<p>I like to use &#8211;numeric-suffixes so that the files end up like SRCFILE.split00, SRCFILE.split01, etc.</p>
<p>When you&#8217;re ready to extract on the other end:</p>
<pre><code>
#!/bin/bash
cat SRCFILE.split* > SRCFILE</code></pre>
<h3>Multiple files</h3>
<p>If you&#8217;ve got more than one file, you can do the following:</p>
<pre><code>
#!/bin/bash
tar -cvf - SRCDIR | split --numeric-suffixes --bytes=4GB - SRCDIR.tar.split
# You can also compress it, put a z in the tar command
tar -czvf - SRCDIR | split --numeric-suffixes --bytes=4GB - SRCDIR.tar.gz.split</code></pre>
<p>Then to extract the files:</p>
<pre><code>
#!/bin/bash
cat SRCDIR.tar.split* | tar -xvf -
# Or for the compressed one, put a z in the tar command
cat SRCDIR.tar.split* | tar -xzvf -</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/splitting-large-files-for-a-fat32-removable-drive-or-flash-drive/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remove trailing whitespace from lines in Vim</title>
		<link>http://thefekete.net/blog/remove-trailing-whitespace-from-lines-in-vim/</link>
		<comments>http://thefekete.net/blog/remove-trailing-whitespace-from-lines-in-vim/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 07:58:52 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[vim]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=456</guid>
		<description><![CDATA[Put this in your command mode and smoke it:
:s/ \+$//g
]]></description>
			<content:encoded><![CDATA[<p>Put this in your command mode and smoke it:</p>
<p><code>:s/ \+$//g</code></p>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/remove-trailing-whitespace-from-lines-in-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Match RAR archives</title>
		<link>http://thefekete.net/blog/match-rar-archives/</link>
		<comments>http://thefekete.net/blog/match-rar-archives/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 08:16:48 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[Regular Expressions]]></category>
		<category><![CDATA[egrep]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[sed]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=439</guid>
		<description><![CDATA[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$&#124;.*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}$&#124;.*\.rar$&#124;.*\.sfv$
]]></description>
			<content:encoded><![CDATA[<p>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>
<p><code>.*[^p][^a][^r][^t]..\.rar$|.*part01\.rar$</code></p>
<p>If you need to find all the RAR files and SFV files (probably to delete them after extraction), the following will get them all.</p>
<p><code>.*\.r[0-9]{2}$|.*\.rar$|.*\.sfv$</code></p>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/match-rar-archives/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bash: Count Lines of Code in a Python Project</title>
		<link>http://thefekete.net/blog/bash-count-lines-of-code-in-a-python-project/</link>
		<comments>http://thefekete.net/blog/bash-count-lines-of-code-in-a-python-project/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 19:11:41 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[bash]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=431</guid>
		<description><![CDATA[#!/bin/bash
find . -name '*.py' &#124; xargs cat &#124; sed '/^\s*#/d;/^\s*$/d' &#124; wc -l

xargs converts find&#8217;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.
]]></description>
			<content:encoded><![CDATA[<pre><code>#!/bin/bash
find . -name '*.py' | xargs cat | sed '/^\s*#/d;/^\s*$/d' | wc -l
</code></pre>
<p><code>xargs</code> converts <code>find</code>&#8217;s output to arguments, the <code>sed</code> RE drops comments and blank lines, and <code>wc</code> counts them lines. Thanks to <a href="http://stackoverflow.com/questions/114814/count-non-blank-lines-of-code-in-bash">these</a> <a href="http://stackoverflow.com/questions/864316/how-to-pipe-list-of-files-returned-by-find-command-to-cat-to-view-all-the-files">posts</a> on stack overflow for some reference material.</p>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/bash-count-lines-of-code-in-a-python-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efficiently testing multiple model methods at once in Django</title>
		<link>http://thefekete.net/blog/efficiently-testing-multiple-model-methods-at-once-in-django/</link>
		<comments>http://thefekete.net/blog/efficiently-testing-multiple-model-methods-at-once-in-django/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 22:08:05 +0000</pubDate>
		<dc:creator>thefekete</dc:creator>
				<category><![CDATA[django]]></category>
		<category><![CDATA[django-models]]></category>

		<guid isPermaLink="false">http://thefekete.net/?p=416</guid>
		<description><![CDATA[Update 2011-08-03
I have since ditched this idea because &#8220;Explicit is better than implicit&#8221; and &#8220;Readability counts.&#8221;
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&#8217;t be immediately obvious what is doing what. Which is not the reaction you [...]]]></description>
			<content:encoded><![CDATA[<h3>Update 2011-08-03</h3>
<p>I have since ditched this idea because &#8220;Explicit is better than implicit&#8221; and &#8220;Readability counts.&#8221;</p>
<p>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&#8217;t be immediately obvious what is doing what. Which is not the reaction you want when tests are failing for some unknown reason.</p>
<p>I&#8217;ve settled on separate test methods for each model method/attribute. It&#8217;s a little more verbose, but <i>very</i> clear and easy to decipher. </p>
<p>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.</p>
<h3>/Update</h3>
<p>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 <code>self.assertEqual(...)</code> statements for each test condition. I was repeating myself and I didn&#8217;t like it.</p>
<p>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 <code>assert</code> that they returned equal to the values I passed the function. Below is a simplified example of how it worked:</p>
<pre><code># 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))
</code></pre>
<p>The vital parts above are the methods list and assert_methods(). <code>methods</code> stores a list of strings naming the methods you want to call on your model instance. <code>assert_methods()</code> takes an object (the model instance) and a list of values to compare to the method&#8217;s returns.</p>
<p>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.</p>
<p>So basically, <code>assert_methods()</code> asserts that <code>methods[0]</code> = <code>values[0]</code>, <code>methods[1]</code> = <code>values[1]</code> and <code>methods[n]</code> = <code>values[n]</code>, etc.</p>
<p>Of course, this is limited to one type of assertion for all the methods, but it&#8217;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.</p>
]]></content:encoded>
			<wfw:commentRss>http://thefekete.net/blog/efficiently-testing-multiple-model-methods-at-once-in-django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

