Saturday, December 15, 2012

Yellow Curry with Chickpeas and Potatoes


A modified version of this recipe, to respect the people who will be eating my food tomorrow.
Makes 6-8 servings

Ingredients

  • 2 14-ounce can of coconut milk
  • 3 tablespoons yellow curry paste
  • 1 29 oz can chickpeas
  • 1 cup water
  • 2 medium potatoes
  • 1/4 large onion
  • 1 14-ounce can of baby corn
  • 1 teaspoon soy sauce
  • 1 teaspoon sugar
  • 1 lime

Instructions

  1. Slice the onion and baby corn into bite-sized pieces.
  2. Peel, cut, and parboil the potatoes for ~5 minutes. Set aside.
  3. Open one can of coconut milk and scoop the top thicker cream part into a pan.
  4. Heat this cream over medium heat until the oil just starts to separate from the milk.
  5. Then add the yellow curry paste and saute with the cream until it becomes fragrant.
  6. Then add the remaining 1 1/2 cans of the coconut milk and water and bring to a boil.
  7. Let cook until the consistency of the curry is what you prefer. You can use less water if you want a shorter cooking time.
  8. Add the potatoes, onions, and baby corn and cook until just done, but still firm.
  9. Mash 1/2 a potato and add to thicken.
  10. Adjust seasonings with soy sauce and sugar to taste.
  11. Garnish with thinly sliced kaffir lime leaves and red peppers. Serve with jasmine rice.

Wednesday, May 2, 2012

Logging to syslogd from Python


On Unix there is a syslog service that handles centralized logging. Using it for logging from your daemons has the advantage of putting control of the logging options in the hands of the system administrator, without involving you, the developer. If they want certain log rotations, or there is a preferred directory, or if the logs are sent over the network to a central logging server, it has nothing to do with you, as long as you are logging to syslog.

First off, you need a config file something like this:

[loggers]
keys=mysyslogger_l


[handlers]
keys=mysyslogger_h


[formatters]
keys=mysyslogger_f



[logger_mysyslogger_l]
level=NOTSET
handlers=mysyslogger_h
propagate=0

[handler_mysyslogger_h]
# Add this line to syslog.conf
# local1.*         /var/log/distributor.log
level=NOTSET
formatter=mysyslogger_f
class=handlers.SysLogHandler
args=('/dev/log', handlers.SysLogHandler.LOG_LOCAL1)

[formatter_mysyslogger_f]
format=%(message)s

Then, you'll need to read that config file with your Python program:

import logging
import logging.config

logging.config.fileConfig("logging.conf")
log = logging.getLogger("mysyslogger_l")
log.info("This an info message.")
log.error("This is an error message.")

Then you'll probably need to configure your syslog to write the messages somewhere. Add this line to /etc/syslog.conf and run /etc/init.d/syslog restart:

local1.*         /var/log/mysyslog_file.log

Sunday, March 4, 2012

Graphing Gaussian Curves in Octave

I've been working my way through Prof. Sebastian Thrun's second AI course,CS 373 Programming a Robotic Car that he is offering through the new company, Udacity. In week two he covers Kalman filters as a method of estimating location given uncertainty in sensor data and uncertainty in movement.

In an effort to get a better understanding of how the variables affect the shape of the Gaussian distribution that represents the probable state of the variables being modelled, I fired up Octave. Octave is math software that allows the user to do a large variety of things, but in my case I just wanted to use it to graph a Gaussian distribution and see the effect of changing the variables.

Thanks to this helpful, and to the point, post, it was reasonably straight forward to start graphing curves in two dimensions.

x = [1:0.1:6]
sigma = 5

mu = 10
fx = (1/sqrt(2*pi*sigma^2)*exp(-(x-mu).^2/(2*sigma^2)))
plot(x, fx)

This is enough to get started.

Wednesday, January 25, 2012

Gluten Free Bechamel Sauce

2 cansevaporated milk
8 tbspcorn starch
4 Cwater
2beaten eggs
1/2 Cshredded pecorino cheese
1 tbspbutter
1 tspsalt
1 pinchgrated nutmeg
  1. Bring water to a boil.
  2. Add 1 can evaporated milk.
  3. Add corn starch, whisk.
  4. Lower heat to medium.
  5. Add 2nd can of milk.
  6. Add butter.
  7. Whisk lightly until sauce thickens.
  8. Add eggs in slow stream, whisking quickly so they don't cook in chunks.
  9. Add nutmeg.
  10. Take off heat.
  11. Add cheese and mix thoroughly.

Thursday, June 30, 2011

Customizing the Python Interpreter

I was working with a friend on debugging an odd pickling issue. In order to really play with it, we started a Python interpreter and ran through the list of imports and sys.path.appends necessary to set up active database and memcache connections, as well as load the project code.

My friend mentioned that he had a python session on his desktop that he never dared to close, since the setup had been so much trouble.

Thinking that it would be great to have this more frequently, and more easily, I created a python file which gets loaded every time I start my python interpreter, pyprompt.py.


import sys
import os

def getProjectDir(d=os.getcwd()):
projects = os.path.join(os.environ['HOME'], "projects")
if os.path.dirname(d) in ['/home', '/']:
return None
elif projects == os.path.dirname(d):
if os.path.exists(os.path.join(d, "src/pylons/proj")):
return d
else:
return None
else:
return getProjectDir(os.path.dirname(d))

pd = getProjectDir()
if pd:
print
print "Detected %s project. Setting up database." %(os.path.basename(pd))
print
sys.path.append(os.path.join(pd, "src/pylons/proj"))
import proj
from proj.lib.helpers import setup_db
factory = setup_db()
dbcon = factory.getConnection()


Now I want this file to run every time the python interpreter is started.


export PYTHONSTARTUP="/home/jsimpson/bin/pyprompt.py"


So, what happens is, when the python interpreter starts, it checks the PYTHONSTARTUP variable for a python file to run. That executes the getProjectDir() function, which tests if my current working directory is in a project. (Our workflow includes many branches of the main project.) If I am in a project, it will import the files from that project and setup my interpreter, ready for some interactive work.

Readline Interactions

I previously posted on how Emacs keys work for interaction on many different shells, bash, python, ruby, mysql, etc.

Recently I was trying to improve my python interaction experience when I stumbled across this:

http://www.linuxselfhelp.com/gnu/bash/html_chapter/bashref_8.html

This details some interesting key bindings in bash, as well as how to change the key bindings.

Thursday, May 5, 2011

Custom Tab Complete and Bash Functions

Everyone with even a little experience in Unix has their own special aliases. Maybe you have:

alias wcd="cd ~/workspace"

to take you to the directory where you have your projects. Maybe you have some really sophisticated aliases that change your bash configuration and path when you hit a certain directory.

One of the challenges I found when I moved off of csh to bash was csh aliases had parameters, so you could make niffty aliases that had some value in the middle:

alias fi 'find . -name \!:1 -exec vim {} \;'

(The first alias I ever used, from my friend William Hui). Using this alias, if you run:

fi mycode.c

It will search through the directory tree to find mycode.c and open it in vim. Bash doesn't seem to give you the same level of control over alias parameters. However, recently I've learned that you can create a bash function, and it will run like a command on the command line.

Since fi is a reserved word that closes an if statement in bash, we'll switch from fi to fim. Then create this in a file (functions.sh):

fim() {
test ! -z "$1" && find . -name $1 -exec vim {} \;
}

and source the file in your current environment:

source functions.sh

then this works in bash:

fim mycode.c

Since you are now using a bash function instead of an alias, you can squeeze any amount of bash code you want in there, format it nicely, even (possibly) comment it. Aliases can get pretty crazy sometimes but a bash function should be fairly readable.

So, that's cool, flexible bash functions instead of aliases. Which brings me to my next trick. Everyone loves tab completion. Okay, that may be a fairly sweeping statement, but watching people use the Unix command line, I think I can safely say most people love tab completion.

With newer versions of bash, you can build your own custom tab completion. Lets say you have a directory where you do a lot of your work, and you often want to go there to some project.

wcd() {
cd ~/workspace
}

That's cool, anywhere you are
wcd
takes you there. However, now that it's a bash function, it's really straight forward to augment it a little:

wcd() {
cd ~/workspace/$1
}

That's cool too. Now, assuming your working directory looks like this:

[jsimpson@jsimpson-lnx1 workspace]$ ls
bookcatalog/ mashup/ mywebsite/ out.html

you can:

wcd bookcatalog

and anywhere you are will take you to ~/workspace/bookcatalog. However, if your workspace looks like mine, it has many projects, some of which haven't been worked on in months or years. Sometimes I need a little help to remember where I'm going. Wouldn't a custom tab complete be great?

wcd() {
cd ~/workspace/$1
}

_wcd() {
local cur opts
cur="${COMP_WORDS[COMP_CWORD]}"
opts=$(cd ~/workspace ; ls -d */. | sed 's|/./||')
COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
}
complete -F _wcd wcd

The first function we've seen before. Once you press enter on the command line, this is the function that will do the work of changing you to a new directory.

Last line first, complete is a utility that registers a function (-F for function) to be run every time you tab when wcd is the first command on the command line.

_wcd is the function that computes your list of possible completions.

local - sets up some local variables.

cur - gets the last element of the COMP_WORDS array, which is a special bash variable that holds the array of parameters to the command line you are pressing tab on.

opts - this line gets a string of space delimited words that are possible completions, something that will look like this "dir1 dir2 dir3".

COMPREPLY - this is a special bash variable that is an array of all the possible completions. So, if you are here:

wcd m

When you hit tab, the function will run and evaluate like this:

cur="m"
opts="bookcatalog mashup mywebsite"
COMPREPLY=(mashup mywebsite)

and on the command line you will see this:

[jsimpson@jsimpson-lnx1 workspace]$ wcd m
mashup mywebsite


Debian Administrator's Introduction to Bash Completion