Skip to content

Commit

Permalink
tidy code
Browse files Browse the repository at this point in the history
  • Loading branch information
Mirko Dietrich committed Apr 6, 2010
1 parent 6b38c93 commit f7349e1
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 48 deletions.
8 changes: 4 additions & 4 deletions experiments/test_gui.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
sys.path.append("/home/raf/sound-evolution")
sys.path.append("/home/raf/sound-evolution")

from Tkinter import *
import sound_evolution as se
Expand All @@ -11,16 +11,16 @@
f.pack()

def callback():

i = se.instrument.Instrument.random(const_prob=0.7, max_children=4)
csd = se.csound_adapter.CSD()
csd.orchestra(i)
csd.score('i 1 0 2')
csd.play()

b = Button(f, command=callback)
b["text"] = "> Create Sound <"
b["text"] = "> Create Sound <"
b["background"] = "green"
b.pack(fill=BOTH, expand=0.8)
b.pack(fill=BOTH, expand=0.8)

root.mainloop()
50 changes: 22 additions & 28 deletions sound_evolution/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ def __to_instr(node, n, out_type):
@staticmethod
def __render(node, data, n, out_type):
"""render the code for a node"""

if out_type == "x":
out_type = random.choice(["a", "k"])

code = ""
var = "%s%d" % (out_type, n)
if node["code"]["type"] == "code":
Expand All @@ -69,9 +69,9 @@ def to_json(self):

def to_graph(self, filename='graph.jpg'):
"""Generates a jpg-file displaying the instrument tree."""

self.graph_filename = filename

if self.graph_filename.endswith('.jpg'):
dot_filename = self.graph_filename[:-4] + '.dot'
jpg_filename = self.graph_filename
Expand All @@ -83,7 +83,7 @@ def to_graph(self, filename='graph.jpg'):
graph.styleDefaultAppend("color","red")
graph.styleDefaultAppend("style", "filled")
graph.styleDefaultAppend("fontcolor", "white")

stack = []
new_parents = []
stack.append(self.instrument_tree)
Expand All @@ -93,12 +93,12 @@ def to_graph(self, filename='graph.jpg'):
if root:
sub_tree = stack.pop()
node = graph.newItem(sub_tree["code"]["symbol"])
root = False
root = False
else:
sub_tree = stack.pop()
node = new_parents.pop()
node = new_parents.pop()

if len(sub_tree["children"]) > 0:
if len(sub_tree["children"]) > 0:
for i, child in enumerate(sub_tree["children"]):

if child["code"]["name"] == "const":
Expand All @@ -113,14 +113,14 @@ def to_graph(self, filename='graph.jpg'):
child_node = graph.newItem(child["code"]["symbol"])
stack.append(child)
new_parents.append(child_node)

curr_link = graph.newLink(node, child_node)


if sub_tree["code"]["type"] == "code":
graph.propertyAppend(curr_link, "label", sub_tree["code"]["params"][i]["name"])
f = open(dot_filename,'w')

f = open(dot_filename,'w')
graph.dot(f)
f.close()
os.system('dot -Tjpg %(dot)s -o %(jpg)s' %{"dot": dot_filename, "jpg": jpg_filename})
Expand All @@ -142,7 +142,7 @@ def get_only_type(the_type, opcodes):
else:
types = [the_type]
return [op for op in opcodes if op["outtype"] in types]

def get_only_not_type(the_type, opcodes):
"""get only opcodes that don't have a certain type"""
return [op for op in opcodes if op["outtype"] != the_type]
Expand All @@ -152,7 +152,7 @@ def get_only_not_type(the_type, opcodes):

# select random root element (with a output)
if root_type and root_type == "t":
# TODO this 1 here has to be changed to a randint when we have more
# TODO this 1 here has to be changed to a randint when we have more
# than 1 table in the score
root = Instrument.__make_node(Instrument.__make_const_code("t", 1))
inst = Instrument(root)
Expand All @@ -170,7 +170,7 @@ def get_only_not_type(the_type, opcodes):

while todo:
tmp_tree = todo.popleft()

# if it is a math operator
if tmp_tree["code"]["type"] == "math":

Expand All @@ -190,7 +190,7 @@ def get_only_not_type(the_type, opcodes):
# if it is an opcode
else:
for param in tmp_tree["code"]["params"]:

# if param type is t alwys plug in a constant
if param["type"] == "t":
if param["max"] == param["min"]:
Expand Down Expand Up @@ -218,8 +218,7 @@ def get_only_not_type(the_type, opcodes):

inst = Instrument(root)
return inst



def mutate(self):
"""Mutate an instrument."""
flat = Instrument.__traverse(self.instrument_tree)
Expand All @@ -241,27 +240,26 @@ def ficken(self, other):
candidates = [cand for cand in flatother if cand["code"]["outtype"] == crosstype]
winner2 = random.randint(0,len(candidates)-1)
flatself[winner]["code"] = candidates[winner2]["code"]
flatself[winner]["children"] = candidates[winner2]["children"]
flatself[winner]["children"] = candidates[winner2]["children"]
if other.to_json() != self.to_json():
return
raise Exception("ficken was not successfull")
raise Exception("ficken was not successfull")

@staticmethod
def __traverse(node):
flat = []
flat = []
for child in node["children"]:
if child["code"]["type"] == "const":
flat.append(child)
else:
flat.extend(Instrument.__traverse(child))
flat.append(node)
return flat
return flat

def fitness(self):
"""Score of the instrument."""
return


@staticmethod
def __make_node(code):
"""Make a node with no children."""
Expand All @@ -272,18 +270,14 @@ def __make_const_code(outtype, val):
"""make a new constant"""
return {"name": "const", "type": "const", "outtype": outtype, "value": str(val)}



Individual.register(Instrument)


if __name__ == '__main__':

i = Instrument.random(const_prob=0.7, max_children=4)
csd = csound_adapter.CSD()
csd.orchestra(i)
csd.score('i 1 0 2')
csd.play()
print i.to_json()
print i.to_instr()

2 changes: 1 addition & 1 deletion tests/csound_adapter_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os, re
import nose.tools

import sound_evolution as se

def setUp():
Expand Down
29 changes: 14 additions & 15 deletions tests/instrument_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,23 @@ def setUp():
os.path.join(os.path.dirname(__file__),
"fixtures", "even_more_complex.json")).read()


def test_create_empty():
"""Should create an empty instrument."""
i = se.instrument.Instrument()
assert(type(i) == se.instrument.Instrument)
assert type(i) == se.instrument.Instrument

def test_create_from_json():
"""Should create an instrument from JSON."""
global valid_json
i = se.instrument.Instrument(simple_json)
assert(type(i) == se.instrument.Instrument)
assert type(i) == se.instrument.Instrument

@nose.tools.raises(ValueError)
def test_create_from_json_fails():
"""Shouldn't create an instrument from invalid JSON."""
global invalid_json
i = se.instrument.Instrument(invalid_json)
assert(type(i)!=se.instrument.Instrument)
assert type(i) != se.instrument.Instrument

def test_create_rand_instr_default():
"""Should create a random instrument with default params."""
Expand All @@ -66,15 +65,15 @@ def test_create_to_json():
"""The JSON we create is in valid JSON format"""
global simple_json
i = se.instrument.Instrument(simple_json)
assert ('{"root": {}}' == i.to_json())
assert '{"root": {}}' == i.to_json()

def test_mutation():
"""The mutation produces something different from the original thing"""
global complex_json
i = se.instrument.Instrument(complex_json)
old_json = i.to_json()
i.mutate()
assert (old_json != i.to_json)
assert old_json != i.to_json

def test_ficken():
"""The crossover of two instruments creates a new instrument not equal to either of the originals"""
Expand All @@ -83,30 +82,30 @@ def test_ficken():
j = se.instrument.Instrument(complex_json)
j1 = se.instrument.Instrument(complex_json)
j.ficken(i)
assert (j1.to_json() != j.to_json()) & (i.to_json() != j.to_json())
assert(type(j) == se.instrument.Instrument)
assert(type(i) == se.instrument.Instrument)
assert j1.to_json() != j.to_json()
assert i.to_json() != j.to_json()
assert type(j) == se.instrument.Instrument
assert type(i) == se.instrument.Instrument

def test_to_instr():
"""test if a simple instrument produces the valid csound code that we wrote by hand"""
global complex_json, complex_orc
i = se.instrument.Instrument(complex_json)
assert(i.to_instr() == complex_orc)

assert i.to_instr() == complex_orc

def test_population():
"""Should create a Population object containing a list of instruments with length == size"""
size = 3
params = {"const_prob": 0.7, "max_children": 4}
pop = se.genetics.Population(size, se.instrument.Instrument, params)
assert(type(pop) == se.genetics.Population)
assert(type(pop.individuals[1]) == se.instrument.Instrument)
assert(len(pop.individuals) == size)
assert type(pop) == se.genetics.Population
assert type(pop.individuals[1]) == se.instrument.Instrument
assert len(pop.individuals) == size

def test_next_generation():
"""The next generation should be member of class Population"""
size = 3
params = {"const_prob": 0.7, "max_children": 4}
pop = se.genetics.Population(size, se.instrument.Instrument, params)
pop_2 = pop.next_generation()
assert(type(pop_2) == se.genetics.Population)
assert type(pop_2) == se.genetics.Population

0 comments on commit f7349e1

Please sign in to comment.