Monday, March 31, 2014

Washing machine hoses

When our home inspector went through he mentioned to me that I should replace the existing rubber hoses on the washing machine with steel-reinforced ones. I wondered if washing machine hoses were specially prone to fail, perhaps something to do with the intermittent nature of the load (if you look at the hoses when the washing machine runs, they jerk as the machine draws water in phases). I also began to wonder if dishwasher hoses suffered from the same problem.

A quick search brought up two documents, one from a community association underwriter - which I assume insures people with rental properties. The other document I found was from an insurance association serving hotels and inns. The first one claims that steel-reinforced hoses are no better than rubber hoses since the hoses are damaged at the connection. The other one suggests that steel-reinforced hoses may be better than regular rubber hoses but all hoses should be replaced every five years or so.

I could not find reasons why these hoses were more susceptible to rupturing and why the dish washer water connection does not suffer from the same maintenance issue.


execfile and imported modules

I was given to believe that Python's execfile statement simply executed all the commands in a file and continued on its way. This is not entirely true, at least in Python 2.7: imported modules seem not to be handled by the execfile statement, which seems to be rather odd to me.

import numpy


def gen(n=100):
  return numpy.arange(n)

This code does what you expect when you import it as a module:

In [1]: import test

In [2]: test.gen(10)
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

And when you run it as a script to incorporate it into your workspace:

In [3]: run test

In [4]: gen(10)
Out[4]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

However, when you use execfile to run the script you run into a snag:


In [5]: pars = {}; execfile('test.py', {}, pars); pars['gen'](10)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-b06061c74d2b> in <module>()
----> 1 pars = {}; execfile('test.py', {}, pars); pars['gen'](10)
/Users/kghose/Code/Mitty/Test/test.py in gen(n)
      3 
      4 def gen(n=100):
----> 5   return numpy.arange(n)
NameError: global name 'numpy' is not defined

Whaaaaa?

If, instead, you use the fascinating standard Python imp module, you get:


In [7]: import imp; mod = imp.load_source('test','./test.py', open('test.py','r'))
In [8]: mod
Out[8]: <module 'test' from './test.pyc'>
In [9]: mod.gen(10)
Out[9]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Things run as they should.

Tuesday, March 25, 2014

Parameter files in Python for Python programs

I often write and use Python programs that require input parameters to tell them what to do. When there are a few parameters I usually pass them through the command line (my current favorite framework for command line argument parsing is the amazing docopt module). When there are many parameters, however, command line arguments can get cumbersome.

In the past I have looked to configuration markup languages (YAML comes to mind) and have also used microsoft excel format files (using the excellent xlrd package). Using proprietary formats makes my stomach upset, but there are no good solutions for the odf counterparts.

Recently I have started to experiment with storing parameter files in python and reading them into my code.

__import__(filename) works and puts the parameters into a separate name space, so you can access them as filename.x, filename.y etc. However, the file needs to be in the module search path, and it feels a bit of a misuse.

A better solution, I find, is to use execfile to read the parameter file into the code. There are no path restrictions, execfile IS meant to execute code (so no misuse there) and the variables from the Python file are loaded into a separate dictionary so they are contained and do not spill all over your code.

#Main file
pars = {}
execfile('params.py', {}, pars)

With params.py looking like

a = 43
b = 'a string'
c = {'d': 23}

We get:

pars --> {'a': 43, 'b': 'a string', 'c': {'d': 23}}

We can put in comments in the file and structure however we need which I find very convenient.

execfile has disappeared in Python 3 but you can use

with open(filename) as f:
    exec(compile(f.read(), filename, "exec"))

UPDATE: However, see a funny issue with execfile here.

Monday, March 24, 2014

git subtree split

Problem: You have a git hub repository with code in several folders. You want to move one of the sub folders into its own separate repository (for example, it was experimental code you were working on, which you now want to spin off into its own life)

Solution: Use git subtree split as detailed here (look for the answer that says The Easy Way™)

Wednesday, March 19, 2014

Another reason to love PyCharm

The latest version of PyCharm can run the pep8.py tool on your code to flag coding style violations on the fly. I thought this was cool, but it can be annoying sometimes. This is because pep8 consists of coding guidelines and some of them are a matter of taste. My personal quirk is that I like to use 2 spaces for indents instead of 4. 

When I turn on PyCharm’s pep8 checking all my code gets underlined because I’m using two spaces for indents. However, I discovered that under Preferences->Inspections->PEP 8 Coding style violation and there is a properties list labelled “Ignore” where you can type in pep8 violations to be ignored.

UPDATE: From this very informative post here and a response from one of PyCharm's programmers there: Go to the error, click on the light bulb icon and then select 'Ignore errors like this'. This will automatically add a proper exception to this list. For those interested the list of error codes is here.

I typed in ‘indentation’ and was delighted to note that this made those annoying flags disappear (This should not have worked). Also, you can change the severity of the violation flag - I changed it from warning to typo, which is less visually distracting.

Thursday, March 13, 2014

Ghost in the wiring

The kitchen has an old Nutone vent hood. The fan didn't spin as fast as it should and the fan blades looked rusty so I decided to replace the motor and blades. I found a replacement motor off Amazon (of all places) and found a metal fan of the exact same design off ebay. I dismantled the vent fan assembly and replaced the motor and fan and tested it and everything worked fine.

A few days later I switched the vent fan on and it did not work. Neither did the hood light. I puzzled over this, wondered if I'd blown a fuse, checked all the fuses - all were intact. I could not figure anything out. I decided that the wiring inside the hood was old and had come apart from my fiddling with it.

A few days later I idly switched the fan on - and it worked! Now I was sure there was loose wiring somewhere.

Then a few days later again I tried the fan, and it did not work. I banged the hood I banged under the fan trying to see if I could jar the loose wiring in place but nothing worked. I left the kitchen disappointed, trying to decide how best to tackle this. I started to think of replacing the entire vent hood.

After a while I came back and switched off the over sink light. There was a sudden rattling sound. I jumped. I was confused for a moment. I was pretty sure I had turned off the over sink light and not hit the disposal button (they are located symmetrically on either side of the sink) but it sure sounded like the disposal. I flipped the switch again. The rattling sound stopped and the sink light came on.

I flipped the switch again. The light went off and the rattling - which I now properly identified as the vent hood fan, which I had messed with and unseated so it was brushing the hood roof (because of all my banging) - started again. It took me a while to stop laughing.

Somebody had gone to great lengths to wire the kitchen light with a single pole double throw switch with the other circuit serving the vent hood. I'm so glad I had accidentally left the vent fan on, otherwise I would have NEVER figure this one out.

Tuesday, March 11, 2014

Docopt notes

I raved previously about docopt. Docopt can be finicky about how you write the docstring. Here are some tips:

No empty line between "Usage:" and the first usage pattern.

Usage:
      <---- Don't do this
mutate snp [-r <REF>] [-p <SNP>]

No empty lines between usage patterns

Usage:
mutate snp [-r <REF>] [-p <SNP>]
      <---- Don't do this

mutate cnv [-r <REF>] [-p <SNP>]