Difference between revisions of "Code:for patterns"

From Predictive Chemistry
Jump to: navigation, search
(Created page with "Here are some example codes that write essentially the same instruction over and over. Let's see how to abstract these patterns out using variables. Try and work the problems...")
 
m (Solutions)
 
Line 61: Line 61:
 
out = fmt
 
out = fmt
 
n = 0
 
n = 0
for i in ["A1", "A2", "A3", "B1", "B2", "B3", "C1", "C2", "C3"]:
+
for i in ["A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3", "C3"]:
 
out = out.replace(i, vals[n])
 
out = out.replace(i, vals[n])
 
n = n + 1
 
n = n + 1
Line 79: Line 79:
 
fed = fed[:] # copy fed
 
fed = fed[:] # copy fed
 
for i in range(n):
 
for i in range(n):
pos = (start + n) % 12 # use mod to get an index in the circular
+
pos = (start + i) % 12 # use mod to get an index in the circular
 
# range 0, 1, 2, 3, ..., 10, 11, 0, 1, 2
 
# range 0, 1, 2, 3, ..., 10, 11, 0, 1, 2
if i < 6: # positions 0, 1, ..., 5 are ABC
+
if pos < 6: # positions 0, 1, ..., 5 are ABC
ABC[i] = ABC[i] + 1
+
ABC[pos] = ABC[pos] + 1
 
else: # positions 6, 7, ..., 11 map to fed 5, 4, ..., 0
 
else: # positions 6, 7, ..., 11 map to fed 5, 4, ..., 0
fed[5-(i-6)] = fed[5-(i-6)] + 1
+
fed[5-(pos-6)] = fed[5-(pos-6)] + 1
 
return ABC, fed, pos
 
return ABC, fed, pos
   
Line 98: Line 98:
 
x = [1] # start with a `seed' value
 
x = [1] # start with a `seed' value
 
for i in range(5): # generate 5 numbers
 
for i in range(5): # generate 5 numbers
x.append(x[i]*61 % 900)
+
x.append(x[i]*62 % 900)
 
</source>
 
</source>

Latest revision as of 15:05, 25 January 2016

Here are some example codes that write essentially the same instruction over and over. Let's see how to abstract these patterns out using variables. Try and work the problems before flipping over to the solutions section.

Problems

<source lang="python">

  1. Replace text in a formula.
  2. A B C

vals = ["1", "", "2", # 1

       "",  "", "3", # 2
       "",  "", "" ] # 3

out = "A1 + C1 * C2" out = out.replace("A1", vals[0]) out = out.replace("A2", vals[3]) out = out.replace("A3", vals[6])

out = out.replace("B1", vals[1]) out = out.replace("B2", vals[4]) out = out.replace("B3", vals[7])

out = out.replace("C1", vals[2]) out = out.replace("C2", vals[5]) out = out.replace("C3", vals[8])

  1. Increment items in a list.

fed[5] = fed[5] + 1 fed[4] = fed[4] + 1 fed[3] = fed[3] + 1

  1. Append a line to a string.

if n >= 1:

   out = out + "%f %f %f\n"%(a[0][0], a[0][1], a[0][2])

if n >= 2:

   out = out + "%f %f %f\n"%(a[1][0], a[1][1], a[1][2])

if n >= 3:

   out = out + "%f %f %f\n"%(a[2][0], a[2][1], a[2][2])

if n >= 4:

   out = out + "%f %f %f\n"%(a[3][0], a[3][1], a[3][2])
  1. Iterate the linear congruential random number generator.

i = len(x)-1 x.append(x[i]*61 % 900) i = len(x)-1 x.append(x[i]*61 % 900) i = len(x)-1 x.append(x[i]*61 % 900) i = len(x)-1 x.append(x[i]*61 % 900) i = len(x)-1 x.append(x[i]*61 % 900) </source>

First, assume the loop control variable is "i", and try and write each one of these as a loop body that uses the variable "i" to make the pattern. Next, add the "for i in (...):" syntax on top by figuring out how many times / what values of "i" the loop should run.

Solutions

<source lang="python">

  1. Replace text in a formula.
  2. A B C

def substitute_str(fmt, vals): # substitute_str : str -> [str] -> str

   out = fmt
   n = 0
   for i in ["A1", "B1", "C1", "A2", "B2", "C2", "A3", "B3", "C3"]:
       out = out.replace(i, vals[n])
       n = n + 1
   return out

print substitute_str("A1 + C1*C2", vals)

  1. Increment items in a list.

def sow_list_6(fed, n): # sow_list : [int] -> int -> [int]

   out = fed[:] # copy all elements of fed by slicing all of them
   for i in range(n):
       out[5-i] = out[5-i] + 1
   return out
  1. Increment items in a list (advanced).

def sow_list(ABC, fed, start, n): # [int] -> [int] -> int -> int -> ([int], [int], int)

   ABC = ABC[:] # copy ABC
   fed = fed[:] # copy fed
   for i in range(n):
       pos = (start + i) % 12 # use mod to get an index in the circular
                                       # range 0, 1, 2, 3, ..., 10, 11, 0, 1, 2
       if pos < 6: # positions 0, 1, ..., 5 are ABC
           ABC[pos] = ABC[pos] + 1
       else: # positions 6, 7, ..., 11 map to fed 5, 4, ..., 0
           fed[5-(pos-6)] = fed[5-(pos-6)] + 1
   return ABC, fed, pos
  1. Append a line to a string.

def print_atoms(a): # print_atoms : float -> str

   out = "Atomic coordinates (in Angstrom)\n"
   for i in range(len(a)): # loop over all items in a
       if len(a) > i: # This test is no longer needed.  Do you see why?
           out = out + "%f %f %f\n"%(a[i][0], a[i][1], a[i][2])
   return out
  1. Iterate the linear congruential "random" number generator.

x = [1] # start with a `seed' value for i in range(5): # generate 5 numbers

   x.append(x[i]*62 % 900)

</source>