rulururu

post Python Trick: Check for Substring

December 26th, 2008

Filed under: Python — Kai @ 7:36 pm

Today I’d like to show you a quick hint that might be obvious, but it took me quite some time of Python programming to figure it out.

You probably know that you can test if a list, tuple, or dict contains an item by testing the expression “item in list” or “item not in list”. I never realized that this would work for strings as well.

I was always writing code like:

string = 'Hi there' # True example
string = 'Good bye' # False example
if string.find('Hi') != -1:
   print 'Success!'

It’s kinda ugly code but it didn’t mind at all since I found otu that it is completely equivalent to do “if substring in string”:

string = 'Hi there' # True example
string = 'Good bye' # False example
if 'Hi' in string:
   print 'Success!'

Much cleaner and simpler. Might be obvious to 99% of the population, but I wish I’d known about it sooner.

post Emulating “?:”

July 8th, 2008

Filed under: Python — Kai @ 6:36 pm

Python doesn’t know the trinary operator “?:” from C. However, it’s pretty easy to emulate:

x ? y : z    -->    [z, y][bool(x)]

(If you’re sure that x is already a boolean type (or an integer of value 0 or 1), you can omit the bool() function, of course.)

How does the trick work?
We simply create a small list constant, containing the two values to choose from, and use the boolean as an index into the list. “False” is equivalent to 0 and will select the first element, while “True” is equivalent to 1 and will select the second one.

Note that always all three operands will be evaluated, unlike the “?:” operator in C. If you need shortcut evaluation, use an if-else statement.

Actually, there’s another way to do it with shortcut evaluation, but it only works if y does not contain a boolean False equivalent:

x ? y : z    -->    bool(x) and y or z

post How Python can be fast

May 22nd, 2008

Filed under: Python — Kai @ 5:00 pm

I’ve been working with python for a sometime, I’m starting to understand why people like it so much. A bit part of it is that its just so damn simple. Its so easy to write code that works very quickly. The syntax is very elegant and easy to read. I’ve come to actually prefer the indent-based code grouping over most other language’s braces.

But one thing that has been plaguing me is how a dynamiclanguage could actually be faster than a static language like C++ or Java. I have faith in the theory, but its just that: faith. Until today, I didn’t have any real world examples. I needed something that you simply can’t do in a static language without bending over backwards. Conversely, I needed something that required the dynamicism of a language.

Always good examples for problems like that are searching or sorting issues.

What I particularly like is the “key” function that you can now pass to the sort method in Python 2.4. You can simply pass a method that retrieves the “key” to a sort. Then when the sort is performed, the keys are more or less cached, and a fast internal comparison can be used.

For example:

MyList = [(2,3,4), (5,3,4), (1,2,3)]
def get_key(v):
  return v[2]
 
MyList.sort(key=get_key)

Now compare this to a traditional language, which might allow you to pass in a sort callback:

int* MyList[] = [ [2,3,4], [5,3,4], [1,2,3] ]
 
int MyCompare(void* a, void* b) {
  key1 = ((int*)a)[2]
  key2 = ((int*)b)[2]
  return key1 - key2
}
 
qsort(MyList, MyCompare)

Type definitions aside, aside what we see here is that MyCompare is going to be called much more than get_key. In this simple case, obviously it doesn’t matter much, but if you’re sorting something big and retrieving/calculating the key is slow, you’re going to retrieve and calculate the key way more often in C than in Python.

The reason this works only in a dynamic language is that a dynamic comparison function (MyCompare) in C++ is still not as dynamic as the key-retrieval function. The key retrieval function is a function who takes an arbitrary object as a parameter and returns an arbitrary object. Then the sort routine needs to arbitrarily compare two objects. You just can’t do that in C without a whole lot of work.

post Colors for gcc in shell

January 11th, 2008

Filed under: Linux, Python — Kai @ 3:16 pm

I’ve always been annoyed by not having clearly marked errors (besides the word “error”) when using gcc/g++ from shell.

Now a simple python script helps me to notice every appearing error out of lots of unimportant lines of stuff (warnings e.g.).

highlight.py:

1
2
3
4
5
6
7
import sys
while 1:
input = sys.stdin.readline()
if len(input.lower().split("error")) > 1:
print chr(27) + '[91;1m' + input.strip() + chr(27) + '[0;0m'
else:
print input.strip()

Additionally I created a function and an alias in .bashrc which determines the behavior of the shell:

alias gcc_real=$(which gcc)
alias gcc='gcc_highlight'
function gcc_highlight()
{
gcc_real $@ 2>&1 | python ~/highlight.py
}
alias gpp_real=$(which g++)
#...and the same for g++
}

The usage of gcc_real is very important, otherwise gcc would call gcc and so on…perfect recursion. ;)
gcc errors are not reported over stdout but over stderr which means i had to use 2>&1 to forward them.

post Convert Xml to Sql

January 4th, 2008

Filed under: Database, Python — Kai @ 11:53 am

You need to convert an xml file to sql the simpliest way? I got a script for you that makes out of an xml file a clear sql dump for example to insert into a mysql database.

import sys
import xml.dom.minidom as minidom
 
#field list - same in SQL + XML
fields = "name, phone, adress"
tablename = "contacts" # table
recordset = "contact" 
 
def main(args):
    f = open(args[1])
    doc = minidom.parseString(f.read())
    f.close()
    for i in doc.getElementsByTagName(recordset):
        vars = []
        vals = []
        for j in fields.split(", "):
            for k in i.getElementsByTagName(j):
                if (k and k.firstChild):
                     vars.append(j)
                     vals.append(k.firstChild.nodeValue.replace("'", "\\'"))
        sqlstring = "INSERT INTO %s (%s) VALUES ('%s');" % (
                      tablename, ", ".join(vars), "', '".join(vals))
        print sqlstring.encode('utf-8')
 
if __name__ == "__main__":
    if len(sys.argv) < 1:
        print "Usage: %s <filename>.xml"
    else:
        main(sys.argv)

xml2sql.py (right-click Save as…)

Usage is:

xml2sql.py foo.xml

Of course you first have to change the rootnode name, subnodes and fields in the script.

ruldrurd
Powered by WordPress, Content and Design by Kai Bellmann
Entries (RSS) and Comments (RSS)