Learn Python in 100 Python Session Log Lines: A Python Demo

Well, not exactly 100, but sort of ;) For a quick and dirty overlook to learn python from (valid) source code:

>>> myvar = 3
>>> myvar += 2 # no myvar++
>>> myvar -= 1
"""This is a multiline comment.
The following lines concatenate the two strings."""
>>> mystring = "Hello"
# Concatenate strings:
>>> mystring += " world."
>>> print mystring
Hello world.
# This swaps the variables in one line(!).
>> myvar, mystring = mystring, myvar
# List with number, list, tupel as elements:
>>> sample = [1, ["another", "list"], ("a", "tuple")]
# List with string, int, float as elements:
>>> mylist = ["List item 1", 2, 3.14]
# Change first element:
>>> mylist[0] = "List item 1 again"
# Dereference the last element (second last would be -2):
>>> mylist[-1] = 3.14
# Dictionary; known as hash in perl:
>>> mydict = {"Key 1": "Value 1", 2: 3, "pi": 3.14}
>>> mydict["pi"] = 3.15
# Tupel a.k.a. int array:
>>> mytuple = (1, 2, 3)
# Pointer to function len:
>>> myfunction = len
>>> print myfunction(mylist)
3
>>> mylist = ["List item 1", 2, 3.14]
# List ranges, called slicing. Range = [a, b):
>>> print mylist[:]
['List item 1', 2, 3.1400000000000001]
>>> print mylist[0:2]
['List item 1', 2]
>>> print mylist[-3:-1]
['List item 1', 2]
>>> print mylist[1:]
[2, 3.14]
>>> print "He said 'hello'."
He said 'hello'.
>>> print 'He said "hello".'
He said "hello".
>>> unicodestring =  u"This is a unicode string"
>>> strString = """This is
>>> a multiline
>>> string."""
""" %s get replaced with items from a given tuple | dict,
left to right (borrowed from printf()):"""
>>>print "Name: %s\nNumber: %s\nString: %s" % (myclass.name, 3, 3 * "-")
Name: Poromenos
Number: 3
String: ---
""" % is a string creation operator. Watch out for the
trailing s in "%(key)s", like printf's modifiers:"""
>>> print "This %(verb)s a %(noun)s." % {"noun": "test", "verb": "is"}
This is a test.
# If you prefer C syntax just define your own function
# ('*' means to wrap parameters up in a tuple and ',' adds no \n):
def printf(format, params): print format % params,
"""controling flow by if, for, while. Use if instead of case/switch.
Blocks are marked by indention!"""
rangelist = range(10)
>>> print rangelist
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in rangelist:
    # Check if number is one of
    # the numbers in the tuple.
    if number in (3, 4, 7, 9):
        # "Break" terminates a for without
        # executing the "else" clause.
        break
    else:
        # "Continue" starts the next iteration
        # of the loop. It's rather useless here,
        # as it's the last statement of the loop.
        continue
else:
    # The "else" clause is optional and is
    # executed only if the loop didn't "break".
    pass # Do nothing

if rangelist[1] == 2:
    print "The second item (lists are 0-based) is 2"
elif rangelist[1] == 3:
    print "The second item (lists are 0-based) is 3"
else:
    print "Dunno"
while rangelist[1] == 1:
    pass
# Declare functions with def; optional arguments have default value assigned:
def myfunction(arg1, arg2 = 100, arg3 = "test"):
    # multiple returns, i.e. multidimentional function.
    # '\' is line continuation character:
    return arg3, \
    arg2, arg1
>>>ret1, ret2, ret3 = myfunction("Argument 1", arg3 = "Named argument")
# notice = doing a multi-assignement here!
>>>print ret1, ret2, ret3
Named argument 100 Argument 1
# We can do easy value swapping:
>>>ret1, ret3 = ret3, ret1
>>>print ret1, ret3
Argument 1 Named argument
# Same as def f(x): return x + 1 but without a function's name:
functionvar = lambda x: x + 1
>>> print functionvar(1)
2
# Private vars and methods start by >= 2 underscores and
# <2 ones ppended (by convention only). __spam is
# replaced by _classname__spam literally.
# __init__() is the closest python gets to a constructor
# (instance already exists when it's called:
class MyClass:
    common = 10
    def __init__(self, n=3):
        self.myvariable = n
    def myfunction(self, arg1, arg2):
        return self.myvariable
# Initiate:
>>> instance = MyClass()
>>> instance.myfunction(1, 2)
3
>>> instance2 = MyClass()
# variable 'common' is shared by all instances via their class:
>>> instance.common
10
>>> instance2.common
10
# Note how we use the class name instead of the instance:
>>> MyClass.common = 30
>>> instance.common
30
>>> instance2.common
30
# by explicitly declaring a value it becomes
# an instance variable (called data attribute):
>>> instance.common = 10
>>> instance.common
10
>>> instance2.common
30
>>> MyClass.common = 50
# This doesn't chance this:
>>> instance.common
10
# but this
>>> instance2.common
50
# This class inherits from MyClass which is just a special
# case for multiple inheritance as in
# class OtherClass(MyClass1, MyClass2, ..., MyClassN)
class OtherClass(MyClass):
    def __init__(self, arg1):
        self.myvariable = 3
        print arg1
>>> instance = OtherClass("hello")
hello
>>> instance.myfunction(1, 2)
3
# Add (instance) members 'on-the-fly':
>>> instance.test = 10
>>> instance.test
10
# this throws an error
>>> instance2.test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: MyClass instance has no attribute 'test'
def somefunction():
    try:
        # Division by zero raises an exception
        10 / 0
    except ZeroDivisionError:
        print "Oops, invalid."
    else:
        # Exception didn't occur, we're fine.
        pass
>>> fnExcept()
Oops, invalid.
# Import external libraries:
import random
# This will instead import the desired function only:
from random import randint
randomint = random.randint(1, 100)
>>> print randomint
42
# convert data structures to strings using prickle library.
import pickle
mylist = ["This", "is", 4, 13327]
# Open C:\binary.dat for writing. 'r' prevents backslash escaping:
myfile = file(r"C:\binary.dat", "w")
pickle.dump(mylist, myfile)
myfile.close()
#remove, i.e. free, variable. works on list items, too:
del mylist
myfile = file(r"C:\text.txt", "w")
myfile.write("This is a sample string")
myfile.close()
myfile = file(r"C:\text.txt")
>>> print myfile.read()
'This is a sample string'
myfile.close()
# Open the file for reading.
myfile = file(r"C:\binary.dat")
loadedlist = pickle.load(myfile)
myfile.close()
>>> print loadedlist
['This', 'is', 4, 13327]
# some hints:
# chain conditions (a must be 2):
1 < a < 3
# list comprehensions are powerfull:
>>> lst1 = [1, 2, 3]
>>> lst2 = [3, 4, 5]
>>> print [x * y for x in lst1 for y in lst2]
[3, 4, 5, 6, 8, 10, 9, 12, 15]
>>> print [x for x in lst1 if 4 > x > 1]
[2, 3]
# "any" returns true if any item in the list is true.
>>> any(i % 3 for i in [3, 3, 4, 4, 3])
True
# Check how many items have this property.
>>> sum(1 for i in [3, 3, 4, 4, 3] if i == 3)
3
>>> del lst1[0]
>>> print lst1
[2, 3]
# variables outside functions are global but need to be pointed out for writing:
number = 5
def myfunc():
    # This will print 5.
    print number
def anotherfunc():
    # This raises an exception because the variable has not
    # been assigned to before printing. Python knows that it a
    # value will be assigned to it later and creates a new, local
    # number instead of accessing the global one.
    print number
    number = 3
def yetanotherfunc():
    global number
    # This will correctly change the global.
    number = 3

As with any language, even natural ones, you need to practice it for a longer while to really get to know it. So what are you waiting for? Dive into Python, now! ;)

References and Further Reading:

Some clarification on Creative Commons (CC) and General Public Licence (GPL) issues

If you ever where in the need to license your work — let be creative work what so ever — and the desire to do so with freedom in mind (as in “free speech” not in “free beer”) you must have been puzzled to peaces. Unless you happen to be equipped, besides your knowledge for the craft, with legal knowledge in that matter that is. I reckon most artists nor computer enthusiasts aren’t. At least, I’m not. So, an article on linux.com written by Nathan Willis came in very handy to at least give an introduction and some clarification to the issue of mixing those licenses. Say, you run a free operating system and want to integrate some desktop eyecandies, themes, icons, what-so-ever. If you don’t find that tricky already think about releasing something like a modification of the theme or a new program using some bits of an icon set or a new distro or some music mix using sounds from a theme, some video production with light effects from some application using a special theme … I guess you get the problem here.

Were you ever in the desperate need to know all primes below 1000?

In Python calculating primes can be done with a one-liner using functional programming concepts lambda function, map(), reduce() and filter():

# Primes <1000
print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,map(lambda x,y=y: y%x, range(2,int(pow(y,0.5)+1))),1), range(2, 1000)))

To try this out on a system with python installed in a terminal/console/… type python. In the command prompt showing up paste the line, hit enter and you’ll get:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]Update: Thanks to Matt and Mark the code snippet now can look much nicer:

# Primes <1000
print filter(None, map(lambda y: y*reduce(lambda x,y: x*y!=0, map(lambda x,y=y: y%x, range(2, int(pow(y, 0.5)+1))),1),range(2,1000)))

Update: Not quite as accurate (compare start of the sequence, 3 is missing) but much shorter using another formula and filter() and lambda techniques only:

filter(lambda x: x % 2 != 0 and x % 3 != 0, range(2, 1000))

[5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]

Some usefull resources for help coding in C

Essential and Handy Commands for the Text Editor vi (vim)

If for a key combination, something like nx, the n is missing one is assumed. E.g. to replace only a single character right under the cursor position in normal mode hit s followed by the replacement (can be more characters but only the first will be replaced). For most commands the optional number right before the command is somewhat a repeater to instruct how often the following should be executed.

Essentials

insert at cursor i
insert at start of line I
.. end of line A
leave insert mode <ESC>
replace next (n) char(s) incl. cursor ns
repeat last (n) command(s) n.
insert n new lines after this no
insert n new lines before this nO
delete next n lines with current ndd
delete until end of line D
paste from cursor onwards nP
past after cursor np

Search and Replace

  1. Change to normal (navigation) mode with <ESC>
  2. Search (Wraped around at end of file):
    Search STRING forward : / STRING.
    Search STRING backward: ? STRING.
  3. Repeat search: n
    Repeat search in opposite direction: N (SHIFT-n)
  4. Replace: Same as with sed, Replace OLD with NEW:
    First occurrence on current line: :s/OLD/NEW
    Globally (all) on current line: :s/OLD/NEW/g
    Between two lines #,#: :#,#s/OLD/NEW/g
    Every occurrence in file: :%s/OLD/NEW/g

References:

Tony Chen’s vi-manual
Felix Gers’s manual
vi reference on pages.de
RefCard on digilife.be (pdf)

Basics of MusicIP’s MusicDNS and MusicAnalysis

Deriving from musicbrainz the system MusicIP created finding similar music works, in short, in three steps:

  1. analyse the music audio signal (up to 10 min of a track) locally by MusicIP Mixer generating an id called PUID (closed source!)
  2. PUID is sent to MusicDNS, a web-service by MusicIP (closed source, too!) which does fuzzy matching
  3. Some magic happens that the Mixer calculates a playlist by. It would not be sufficient for the DNS (Music Digital Naming Service, don’t mistaken it with Domain Name System) server to just return a list of PUIDs since the server (hopefully!) doesn’t know about all other tracks I have in my library, i.e. that potentially could be used to generate playlists with.

PUIDs

PUID is a 128-bit Portable Unique IDentifier that represents the analysis result from MusicIP Mixer and therefore is not a music piece finger print identifying a song in some particular version. PUIDs are just the ids used in the proprietary fingerprinting system operated by MusicIP. They provide a lightweight PUID generator called genpuid that does 1. and 2. PUIDs can be used to map track information such as artist, title, etc. to a finger print. The id itself has no acoustic information.

Acoustic Fingerprinting

Refering, again, to musicbrainz’s wiki acoustic fingerprinting here is a different process using only 2 minutes of a track. This fingerprint than is send to a MusicDNS server which in turn matches it against stored fingerprints. If a close enough match is made a PUID is returned which unambiguously identifies the matching fingerprint (Also see a list of fingerprinting systems. There is also an scientific review of algorithms). This is necessary since source to generate PUIDs or submit new ones is closed source.

On the other hand wikipedia defines acoustic fingerprinting as follows:

An acoustic fingerprint is a unique code generated from an audio waveform. Depending upon the particular algorithm, acoustic fingerprints can be used to automatically categorize or identify an audio sample.

This definition is even quoted by MusicIP’s Open Fingerprint™ Architecture Whitepaper (page 3).

MusicDNS

The web-service mainly is to match a PUID to a given acoustic fingerprint and look up track metadata such as artist, title, album, year, etc. (aka tags) as done by the fingerprinting client library libofa which has been developed by Predixis Corporation (now MusicIP) during 2000-2005. Only the query code is public via the MusicDNS SDK; music analysis and PUID submitting routines are closed source!

Getting the Playlist

Up to now I couldn’t figure out or find sources how this is actually done by Music Mixer. I’ll keep you posted as I find out.

Other sources / Directions

Learning Learning: Neuroinformatics / Data Mining Link Collection

Since I’m currently studying for my next oral diploma exam on “introduction to neural information processing” (called Neuroinformatics and Data Mining) there are, of course, some Internet references of interest (mainly German):

Books I recommend:

Neural Netzworks - Raúl RojasRojas’ Theorie Neuronaler Netze A Classic: Raúl Rojas: “Theorie der neuronalen Netze.” First print published 1993 at Springer-Verlag, Berlin. ISBN: 3540563539 or it’s english version “Neural Networks” (Rojas says: “The English version is almost a new book”) ISBN: 3540605053. I only read the german version, so far. This I can recommend as it’s language is easily understandable which helps in the learning process. I gives a good overview over established neural modells without loosing details. It’s more on the theoretic side, though.

Neuronale Netze und Fuzzy-Systeme - NauckDetlef Nauck et all.: “Neuronale Netze und Fuzzy-Systeme.” Published at Vieweg 1993. ISBN: 3528052651. Even though it reads Fuzzy-Systems in the title about the first half of the book introduces artificial and biological neural methods in a quite practical manner. It gives many easy and basic examples helping to understand the principles, pros and cons of the many approaches.

Using fb2k’s Scripting Language In It’s Masstagger?!?

Well, what I’m trying to do I thought would be very simple: Add a new tag to each file that’s been added to fb2k’s media library holding the current system date and hence add a “added to library” tag. The tagz script to achieve this is not even the problem.

$if($meta(ADDED_TO_FOOBAR),,%cwb_systemdatetime%)

Or, what seams to be semantically equivalent but more readable (refer to tagz reference to understand the commands):

$if($not($meta(ADDED_TO_FOOBAR)),%cwb_systemdatetime%)

This even checks if the file has a tag already. Using the tagz parser in the preference dialog (Ctrl+P -> Display -> Title Formatting) confirms it’s working correctly when playing a song without a tag and one with the time stamp set.

The set-up is this:

  • with masstagger (right-click on song -> tagging -> manage scripts, if you haven’t changed the default context menu structure) add “Format value from other fields…“, select destination field name (ADDED_TO_FOOBAR) and use the stated script as formatting pattern. Hit Return and name your masstagger script and (important:) click the save button. Note: Using “Set value…” or the like will not work since it, despite intuitive guesses, does not evaluate tagz scripts but outputs it as a string.
  • in fb2k’s preferences dialog select Tools -> New File Tagger and from the drop-down list select Tagging/Scripts/your name (do this after extensive testing on single files with the file’s preferences box open!)

Now each time a file is added to fb2k’s lib this script is run on it. BUT: It doesn’t do what it’s supposed to! What ends up in the files tags is

  1. a ‘?’ for those with no time stamp
  2. deleting the existing field when value = ‘?’

That’s when I noticed the two scripts are not equivalent: The first add an empty string to the requested field if present where the later does simply nothing in that case because there is no else branch. But still, even the later does not do the desired job.

Then I came up with this script:

$if($not($meta_test(ADDED_TO_FOOBAR)),%cwb_systemdatetime%,$meta(ADDED_TO_FOOBAR))

But once again, the only effort is frustration but not the desired time stamp. After all it leaves existing fields untouched.

I could work around this issue with the “Stamp current Time and Date…” bit but since after reinstalling my OS and using fb2k before my music files partly are stamped already. Sidenote: Probably because of this the field name should rather be something like “ADDED_TO_LIBRARY”. Though moving on…

A working workaround I figured out is to

  1. add a “Stamp current Time and Date…”,
  2. use the following script
  3. $if($not($meta_test(ADDED_TO_FOOBAR)),$meta(TIMESTAMP),$meta(ADDED_TO_FOOBAR))
  4. add “Remove Field…” with selected “TIMESTAMP” field.

So that leaves me with speculating about a bug in either the masstagger or in foo_cwb_hooks. By the way, the time stamping option might be in foo_masstag_addons. You might want to include this masstagger script from a file.

Audiophile’s Techno Thoughts — Playlist Generators

There are some thoughts I’d like to a. document but b. share, too. They are about — no, not about Techno music! — programming issues, or just ideas I would find useful if they where already realized. Maybe they are and only I don’t know about it jet. But also, I might be the one realizing them… let’s see.

Well, one thing that came to my mind by playing around with the MusicIP Mixer: Wasn’t it cool to have a free library like thing laying around that could easily be user by a software music player (or even extended to video, i.e. media player) to generate playlists similar to the MusicIP Mixer? To be more precise the features I’m thinking about are:

  • generate playlists by user selected music title from library, that is giving back a list of songs from the user’s music library that have similar mood, tempo, harmony, …
  • start playing tracks from the lib. The user can skip or pin it. Either one “pin” (as in MusicIP Mixer) is enough to start generating the list or maybe even keep on with more appropriate music (closer in the above terms). That’s especially useful for those audiophiles that just cannot remember artists or track names (like me). But also it’s faster in terms of I don’t have to sit down first and think about what I’d like to here right now but rather can just find out what I’d wanted to listen to in the first place.

To brake it down, the key note here is to have two methods generating playlists that are end-user orientated. You may ask: “Well, what the hack is so special about it? You mentioned MusicIP Mixer yourself, that does exactly that!” No, it does not. MusicIP Mixer, as fare as I know, is closed source. But more importantly the list generates are encapsulated within the Mixer software and cannot (again, as far as I know) be used by other software that MusicIP Mixer itself (I’ll digg in to find out when time permits). The generators that is; one can have the generated lists send to one’s music player of choice, easily. Which is fair dinkum.

An example: As of now I chose foobar2k to be my favorite music player as it is very customizable and produces good enough sound for my HiFi (gapless playback, replaygain, multiple format support, “tabbed playlisting“, has plugin API to name a few features and components). I runs more or less 24/7. Through the foo_playlist_tree I wrote a query which gives me 10h of random music, not yet listened to or not for more than two weeks. Of course there are also queries by audio format, … just by any combination of normal audio file tags plus more. But still if I might just want say 40 min of jogging music… mmh, that I could manage by all means, plus also the hassle of time consuming transfer to your portable player if your on the run… Not a good example. OK, imagine sitting on the couch with your fb2k (keyboard remote control configured, of course) ready to blast your ears away but you just can think of what so listen to. Even with my iPAQ running Minibar2k this would not really what ease my relaxed mood. Getting it? Comments, as always, appreciated!

Blogged with Flock

Tags: , ,

Follow

Get every new post delivered to your Inbox.