nanotech example - v4.software-carpentry.org · sets and dictionaries nanotech example. how many...

Post on 24-Jul-2020

6 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Nanotech Example

Sets and Dictionaries

Nanotech Example

Copyright © Software Carpentry 2010

This work is licensed under the Creative Commons Attribution License

See http://software-carpentry.org/license.html for more information.

How many molecules of different kinds can we

make using the atoms in our warehouse?

Sets and Dictionaries Nanotech Example

How many molecules of different kinds can we

make using the atoms in our warehouse?

# Molecular formula file

helium : He 1

water : H 2 O 1

hydrogen : H 2

Sets and Dictionaries Nanotech Example

How many molecules of different kinds can we

make using the atoms in our warehouse?

# Molecular formula file

helium : He 1

water : H 2 O 1

hydrogen : H 2

# Atom inventory file

He 1

H 4

O 3

Sets and Dictionaries Nanotech Example

How many molecules of different kinds can we

make using the atoms in our warehouse?

# Molecular formula file

helium : He 1

water : H 2 O 1

hydrogen : H 2

# Atom inventory file

He 1

H 4

O 3

Now have all the tools we need

Sets and Dictionaries Nanotech Example

Now have all the tools we need

Natural to represent inventory as dictionary

Sets and Dictionaries Nanotech Example

Natural to represent inventory as dictionary

Keys: atomic symbols

Sets and Dictionaries Nanotech Example

Natural to represent inventory as dictionary

Keys: atomic symbols

Values: number of atoms availableValues: number of atoms available

Sets and Dictionaries Nanotech Example

Natural to represent inventory as dictionary

Keys: atomic symbols

Values: number of atoms availableValues: number of atoms available

'He'

'H'1

Sets and Dictionaries Nanotech Example

'O'

3

4

Represent individual molecules the same way

Sets and Dictionaries Nanotech Example

Represent individual molecules the same way

water

'O'

'H'

2

water

Sets and Dictionaries Nanotech Example

1

Store formulas as a dictionary of dictionaries

Sets and Dictionaries Nanotech Example

Store formulas as a dictionary of dictionaries

Keys: molecule names

Sets and Dictionaries Nanotech Example

Store formulas as a dictionary of dictionaries

Keys: molecule names

Values: dictionaries of formulasValues: dictionaries of formulas

Sets and Dictionaries Nanotech Example

Store formulas as a dictionary of dictionaries

Keys: molecule names

Values: dictionaries of formulasValues: dictionaries of formulas

'water'

'ammonia'

Sets and Dictionaries Nanotech Example

Number of molecules that can be made is:

minavailable[atom]

required[atom]min required[atom]

atom ∈ formula

Sets and Dictionaries Nanotech Example

Number of molecules that can be made is:

minavailable[atom]

required[atom]min required[atom]

atom ∈ formula

If atom not in available, its count is implicitly 0

Sets and Dictionaries Nanotech Example

Number of molecules that can be made is:

minavailable[atom]

required[atom]min required[atom]

atom ∈ formula

If atom not in available, its count is implicitly 0

Store results in yet another dictionary

Sets and Dictionaries Nanotech Example

Number of molecules that can be made is:

minavailable[atom]

required[atom]min required[atom]

atom ∈ formula

If atom not in available, its count is implicitly 0

Store results in yet another dictionary

Keys: molecule names

Sets and Dictionaries Nanotech Example

Keys: molecule names

Number of molecules that can be made is:

minavailable[atom]

required[atom]min required[atom]

atom ∈ formula

If atom not in available, its count is implicitly 0

Store results in yet another dictionary

Keys: molecule names

Sets and Dictionaries Nanotech Example

Keys: molecule names

Values: counts of how many can be made

'''Calculate how many molecules of each type can be made

with the atoms on hand.'''

importimportimportimport sys

ifififif __name__ == '__main__':ifififif __name__ == '__main__':

inventory = read_inventory(sys.argv[1])

formulas = read_formulas(sys.argv[2])

counts = calculate_counts(inventory, formulas)

show_counts(counts)

Sets and Dictionaries Nanotech Example

defdefdefdef read_inventory(filename):

'''Read inventory of available atoms.'''

result = {}

forforforfor line inininin read_lines(filename):

name, count = line.split(' ')name, count = line.split(' ')

result[name] = intintintint(count)

returnreturnreturnreturn result

Sets and Dictionaries Nanotech Example

defdefdefdef read_lines(filename):

'''Read lines from file, stripping out

blank lines and comments.'''

reader = openopenopenopen(filename, 'r')

lines = []lines = []

forforforfor line inininin reader:

line = line.split('#')[0].strip()

ifififif line:

lines.append(line)

reader.close()

returnreturnreturnreturn lines

Sets and Dictionaries Nanotech Example

returnreturnreturnreturn lines

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):

Storing results

in dictionary

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):

For each

interesting

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

line in the

input file...

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):Separate the

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

Separate the

molecule name

and the formula

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):Separate the

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

Separate the

atoms and

their counts

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

Loop over pairs

of atoms and

counts

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

Store the count

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

as an integer

with the atomic

symbol as key

defdefdefdef read_formulas(filename):

'''Read molecular formulas from file.'''

result = {}

forforforfor line inininin read_lines(filename):

name, atoms = line.split(':')

name = name.strip()

atoms = atoms.strip().split(' ')

formula = {}

forforforfor i inininin rangerangerangerange(0, lenlenlenlen(atoms), 2):

formula[atoms[i]] = int(atoms[i+1])

And store the

Sets and Dictionaries Nanotech Example

formula[atoms[i]] = int(atoms[i+1])

result[name] = formula

returnreturnreturnreturn result

molecule in

the main

dictionary

defdefdefdef calculate_counts(inventory, formulas):

'''Calculate how many of each molecule

can be made with inventory.'''

counts = {}

forforforfor name inininin formulas:forforforfor name inininin formulas:

counts[name] = dict_divide(inventory,

formulas[name])

returnreturnreturnreturn counts

Sets and Dictionaries Nanotech Example

defdefdefdef calculate_counts(inventory, formulas):

'''Calculate how many of each molecule

can be made with inventory.'''

counts = {}

forforforfor name inininin formulas:forforforfor name inininin formulas:

counts[name] = dict_divide(inventory,

formulas[name])

returnreturnreturnreturn countsSub-dictionary holding

atom counts for a

Sets and Dictionaries Nanotech Example

particular molecule

defdefdefdef calculate_counts(inventory, formulas):

'''Calculate how many of each molecule

can be made with inventory.'''

counts = {}

forforforfor name inininin formulas:forforforfor name inininin formulas:

counts[name] = dict_divide(inventory,

formulas[name])

returnreturnreturnreturn counts

Big functions: nothing is obviously wrong

Sets and Dictionaries Nanotech Example

defdefdefdef calculate_counts(inventory, formulas):

'''Calculate how many of each molecule

can be made with inventory.'''

counts = {}

forforforfor name inininin formulas:forforforfor name inininin formulas:

counts[name] = dict_divide(inventory,

formulas[name])

returnreturnreturnreturn counts

Big functions: nothing is obviously wrong

Sets and Dictionaries Nanotech Example

Small functions: obviously, nothing is wrong

defdefdefdef dict_divide(inventory, molecule):

'''Calculate how much of a single molecule

can be made with inventory.'''

number = NoneNoneNoneNone

forforforfor atom inininin molecule:forforforfor atom inininin molecule:

required = molecule[atom]

available = inventory.get(atom, 0)

limit = available / required

ifififif (number isisisis None) orororor (limit < number):

number = limit

returnreturnreturnreturn number

Sets and Dictionaries Nanotech Example

returnreturnreturnreturn number

defdefdefdef dict_divide(inventory, molecule):

'''Calculate how much of a single molecule

can be made with inventory.'''

number = NoneNoneNoneNone

forforforfor atom inininin molecule:

Identical format:

keys are atoms,forforforfor atom inininin molecule:

required = molecule[atom]

available = inventory.get(atom, 0)

limit = available / required

ifififif (number isisisis None) orororor (limit < number):

number = limit

returnreturnreturnreturn number

keys are atoms,

values are counts

Sets and Dictionaries Nanotech Example

returnreturnreturnreturn number

defdefdefdef dict_divide(inventory, molecule):

'''Calculate how much of a single molecule

can be made with inventory.'''

number = NoneNoneNoneNone

forforforfor atom inininin molecule:forforforfor atom inininin molecule:

required = molecule[atom]

available = inventory.get(atom, 0)

limit = available / required

ifififif (number isisisis None) orororor (limit < number):

number = limit

returnreturnreturnreturn number

Common pattern: None

Sets and Dictionaries Nanotech Example

returnreturnreturnreturn numbermeans "uninitialized",

so initialize the first

time through the loop

defdefdefdef dict_divide(inventory, molecule):

'''Calculate how much of a single molecule

can be made with inventory.'''

number = NoneNoneNoneNone

forforforfor atom inininin molecule:forforforfor atom inininin molecule:

required = molecule[atom]

available = inventory.get(atom, 0)

limit = available / required

ifififif (number isisisis None) orororor (limit < number):

number = limit

returnreturnreturnreturn number

Common pattern:

Sets and Dictionaries Nanotech Example

returnreturnreturnreturn numberstored value or default

defdefdefdef dict_divide(inventory, molecule):

'''Calculate how much of a single molecule

can be made with inventory.'''

number = NoneNoneNoneNone

forforforfor atom inininin molecule:forforforfor atom inininin molecule:

required = molecule[atom]

available = inventory.get(atom, 0)

limit = available / required

ifififif (number isisisis None) orororor (limit < number):

number = limit

returnreturnreturnreturn numberCommon pattern:

Sets and Dictionaries Nanotech Example

returnreturnreturnreturn number

find minimum of

calculated values

defdefdefdef show_counts(counts):

'''Show how many of each molecule can be made.'''

counts = invert_dict(counts)

forforforfor key inininin sortedsortedsortedsorted(counts.keys(), reverse=TrueTrueTrueTrue):

forforforfor name inininin sortedsortedsortedsorted(counts[key]):forforforfor name inininin sortedsortedsortedsorted(counts[key]):

printprintprintprint key, name

Sets and Dictionaries Nanotech Example

defdefdefdef show_counts(counts):

'''Show how many of each molecule can be made.'''

counts = invert_dict(counts)

forforforfor key inininin sortedsortedsortedsorted(counts.keys(), reverse=TrueTrueTrueTrue):

forforforfor name inininin sortedsortedsortedsorted(counts[key]):forforforfor name inininin sortedsortedsortedsorted(counts[key]):

printprintprintprint key, name

Reverse to get

Sets and Dictionaries Nanotech Example

greatest first

defdefdefdef invert_dict(src):

'''Invert a dictionary, returning value->set{key}.'''

dst = {}

forforforfor key inininin src:

value = src[key]value = src[key]

ifififif value notnotnotnot inininin dst:

dst[value] = set()set()set()set()

dst[value].add(key)

returnreturnreturnreturn dst

Sets and Dictionaries Nanotech Example

defdefdefdef invert_dict(src):

'''Invert a dictionary, returning value->set{key}.'''

dst = {}

forforforfor key inininin src:

value = src[key]value = src[key]

ifififif value notnotnotnot inininin dst:

dst[value] = set()set()set()set()

dst[value].add(key)

returnreturnreturnreturn dst

Common pattern:

Sets and Dictionaries Nanotech Example

make sure there's a

collection, then add

defdefdefdef show_counts(counts):

'''Show how many of each molecule can be made.'''

counts = invert_dict(counts)

forforforfor key inininin sortedsortedsortedsorted(counts.keys(), reverse=TrueTrueTrueTrue):

ifififif key > 0:ifififif key > 0:

forforforfor name inininin sortedsortedsortedsorted(counts[key]):

printprintprintprint key, name

Go back and only

Sets and Dictionaries Nanotech Example

show molecules that

can actually be made

# inventory-00.txt # formulas-01.txt

helium : He 1

No output, which is correct.

Sets and Dictionaries Nanotech Example

# inventory-01.txt

He 1

# formulas-01.txt

helium : He 1

1 helium

Sets and Dictionaries Nanotech Example

# inventory-02.txt

He 1

H 4

# formulas-01.txt

helium : He 1

1 helium

Sets and Dictionaries Nanotech Example

# inventory-02.txt

He 1

H 4

# formulas-02.txt

helium : He 1

water : H 2 O 1

1 helium

Sets and Dictionaries Nanotech Example

# inventory-02.txt

He 1

H 4

# formulas-03.txt

helium : He 1

water : H 2 O 1

hydrogen : H 2

2 hydrogen

1 helium

hydrogen : H 2

Sets and Dictionaries Nanotech Example

# inventory-03.txt

He 1

H 4

O 3

# formulas-03.txt

helium : He 1

water : H 2 O 1

hydrogen : H 2

2 hydrogen

2 water

1 helium

hydrogen : H 2

Sets and Dictionaries Nanotech Example

# inventory-03.txt

He 1

H 4

O 3

# formulas-03.txt

helium : He 1

water : H 2 O 1

hydrogen : H 2

2 hydrogen

2 water

1 helium

hydrogen : H 2

Sets and Dictionaries Nanotech Example

Looks good...

# inventory-03.txt

He 1

H 4

O 3

# formulas-03.txt

helium : He 1

water : H 2 O 1

hydrogen : H 2

2 hydrogen

2 water

1 helium

hydrogen : H 2

Sets and Dictionaries Nanotech Example

Looks good...

Code is much simpler than it would be using

lists of pairs

June 2010

created by

Greg Wilson

June 2010

Copyright © Software Carpentry 2010

This work is licensed under the Creative Commons Attribution License

See http://software-carpentry.org/license.html for more information.

top related