nanotech example - v4.software-carpentry.org · sets and dictionaries nanotech example. how many...
Post on 24-Jul-2020
6 Views
Preview:
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