Updation of Old Python Code - python

Pretty noob question so please bear with me because I am new to Python. Below given code is about Ordinary Differential Equation generating automatic combinations of ODE. I tried to execute this code on Python 3.6.3 and on Spider(Pyton 3.6) but no outcomes. I spent many days to make it executable on new version of Python but I am unable to execute it because more errors are generating. So I copied the code as it was.
from scipy import*
from scipy.integrate import odeint
from operator import itemgetter
import matplotlib
matplotlib.use('Agg')
from matplotlib.ticker import FormatStrFormatter
from pylab import *
from itertools import product, islice
from numpy import zeros_like
from string import ascii_lowercase
import operator
import sys
t_range = arange(0.0, 20.0, 0.1)
# initial_condi = []
# VarList = []
# ParamsList = []
ops = "+-"
opsdict = { "+": operator.add, "-": operator.sub }
# if len(initial_condi)!=len(VarList):
# sys.exit('error: the number of initional conditions do not equal to the number of variables')
def odeFunc(Y, t, model, K):
return GenModel(Y, model, K)
def GenModel(Y, model, K):
# New array of floating-point zeros the size of Y
dydt = zeros_like(Y)
for i, derivative in enumerate(model):
for j, operator in enumerate(derivative):
# Sequentially compute dy/dt for each variable in Y
dydt[i] = opsdict[operator](dydt[i],K[j]*Y[j])
return dydt
# Returns a nicer-looking string for a derivative expression given the encoding
def derivString(vars, deriv):
result = ""
for i, v in enumerate(vars):
if i == 0 and deriv[i] == '+':
result += v
else:
result += deriv[i]+v
return result
# main
numvars = int(raw_input("Enter number of variables\n> "))
VarList = ascii_lowercase[:numvars]
nummodels = (2**numvars)**numvars
# begin looping
input = ""
while input != "quit":
print "\n%d possible models" % nummodels
input = raw_input("Enter model ID (zero-indexed) or 'quit'\n> ")
# Basic input filtering
if input == "quit":
continue
elif not input.isdigit():
print "Input must be a non-negative integer"
continue
ID = int(input)
if ID >= nummodels or ID < 0:
print "Invalid ID"
continue
# itertools.product creates a generator for all possible combinations of +-
derivatives = product(ops, repeat=numvars)
# We take the product again to generate all models
models = product(derivatives, repeat=numvars)
# islice takes the specified model
model = next(islice(models, ID, None))
# Display dy/dt for each variable
print "Model %d:" % ID
IDtitle = []
for i, variable in enumerate(VarList):
tempstring = "d%c/dt = %s" % (variable, derivString(VarList, model[i]))
IDtitle.append(tempstring)
print "\t" + tempstring
# User specifies the initial values of all variables.
# This process can be automated but this is to demonstrate that the progam
# accepts any input
init_cons = []
params = []
confirm = ""
while confirm not in ("y", "n"):
confirm = raw_input("Run this model? (y/n)\n> ")
if confirm == "n":
continue
print "\nEnter <initial value, parameter> pairs separated by ','"
for i, variable in enumerate(VarList):
iv_param = map(float, raw_input("> %c: " % variable).split(','))
init_cons.append(iv_param[0])
params.append(iv_param[1])
print "\nRunning ODEint...",
result = odeint(odeFunc, init_cons, t_range, args=(model,params))
print " done."
print "Plotting results...",
f = figure(ID)
title(", ".join(IDtitle))
for i, variable in enumerate(VarList):
plot(t_range, result[:,i], label=variable)
legend()
axhline(0, color='k')
savefig("model"+str(ID))
close(f)
print "done."
print " -- Bye --"

raw_input is now called input in Python3. You also had a variable called input, which may have caused confusion.
from scipy import *
from scipy.integrate import odeint
from operator import itemgetter
import matplotlib
matplotlib.use('Agg')
from matplotlib.ticker import FormatStrFormatter
from pylab import *
from itertools import product, islice
from numpy import zeros_like
from string import ascii_lowercase
import operator
import sys
t_range = arange(0.0, 20.0, 0.1)
# initial_condi = []
# VarList = []
# ParamsList = []
ops = "+-"
opsdict = { "+": operator.add, "-": operator.sub }
# if len(initial_condi)!=len(VarList):
# sys.exit('error: the number of initional conditions do not equal to the number of variables')
def odeFunc(Y, t, model, K):
return GenModel(Y, model, K)
def GenModel(Y, model, K):
# New array of floating-point zeros the size of Y
dydt = zeros_like(Y)
for i, derivative in enumerate(model):
for j, operator in enumerate(derivative):
# Sequentially compute dy/dt for each variable in Y
dydt[i] = opsdict[operator](dydt[i],K[j]*Y[j])
return dydt
# Returns a nicer-looking string for a derivative expression given the encoding
def derivString(vars, deriv):
result = ""
for i, v in enumerate(vars):
if i == 0 and deriv[i] == '+':
result += v
else:
result += deriv[i]+v
return result
# main
numvars = int(input("Enter number of variables\n> "))
VarList = ascii_lowercase[:numvars]
nummodels = (2**numvars)**numvars
# begin looping
input_ = ""
while input_ != "quit":
print("\n%d possible models" % nummodels)
input_ = input("Enter model ID (zero-indexed) or 'quit'\n> ")
# Basic input filtering
if input_ == "quit":
continue
elif not input_.isdigit():
print("Input must be a non-negative integer")
continue
ID = int(input_)
if ID >= nummodels or ID < 0:
print("Invalid ID")
continue
# itertools.product creates a generator for all possible combinations of +-
derivatives = product(ops, repeat=numvars)
# We take the product again to generate all models
models = product(derivatives, repeat=numvars)
# islice takes the specified model
model = next(islice(models, ID, None))
# Display dy/dt for each variable
print("Model %d:" % ID)
IDtitle = []
for i, variable in enumerate(VarList):
tempstring = "d%c/dt = %s" % (variable, derivString(VarList, model[i]))
IDtitle.append(tempstring)
print("\t" + tempstring)
# User specifies the initial values of all variables.
# This process can be automated but this is to demonstrate that the progam
# accepts any input
init_cons = []
params = []
confirm = ""
while confirm not in ("y", "n"):
confirm = input("Run this model? (y/n)\n> ")
if confirm == "n":
continue
print("\nEnter <initial value, parameter> pairs separated by ','")
for i, variable in enumerate(VarList):
iv_param = list(map(float, input("> %c: " % variable).split(',')))
init_cons.append(iv_param[0])
params.append(iv_param[1])
print("\nRunning ODEint...", end='')
result = odeint(odeFunc, init_cons, t_range, args=(model,params))
print(" done.")
print("Plotting results...", end='')
f = figure(ID)
title(", ".join(IDtitle))
for i, variable in enumerate(VarList):
plot(t_range, result[:,i], label=variable)
legend()
axhline(0, color='k')
savefig("model"+str(ID))
close(f)
print("done.")
print(" -- Bye --")

Related

Why does the encryption/decryption in my RSA code not work?

I'm currently coding a simplified RSA algorithm for a project at school but can't get it to work.
I've based the code off of the formulae c = m^e(mod N) and (c^d)mod N. The encryption function works to produce what looks like a feasible output but when I put it into the decryption function it either doesn't return the message correctly or gives me this error:
ValueError: chr() arg not in range(0x110000)
My code:
import random
import math
def is_prime(x):
for i in range(2,int(math.sqrt(x))+1):
if x % i == 0:
return False
break
return True
def gcd(a, b):
if (b == 0):
return a
else:
return gcd(b, a % b)
def generate_p_and_q(p,q):
p_and_q = []
p_and_q.append(p)
p_and_q.append(q)
return p_and_q
def generate_phi(p,q):
p_and_q = generate_p_and_q(p,q)
phi = (p_and_q[0] - 1)*(p_and_q[1] - 1)
return phi
def generate_N(p,q):
p_and_q = generate_p_and_q(p,q)
N = (p_and_q[0])*(p_and_q[1])
return N
def generate_e(p,q):
phi = generate_phi(p,q)
with open('First500Primes.txt') as f:
lines = f.read().splitlines()
for i in lines:
if int(i) > 1 and int(i)< phi:
if gcd(int(i), phi) == 1:
e = int(i)
break
return e
def encrypt_RSA():
encrypted = []
message = input("Enter a message to encrypt:")
message.lower()
with open('First500Primes.txt') as f:
lines = f.read().splitlines()
valid = False
choice = input("Do you want to: \nA: enter a key \nB: use a random key?\n")
if choice.lower() == 'a':
p = int(input("Enter a key - this must be a prime number between 0 and 500:"))
q = int(input("Enter a key - this must be a prime number between 0 and 500:\n"))
while valid != True:
valid = is_prime(p) and is_prime(q)
if valid == False:
print("Your numbers were not prime!")
p = int(input("Enter a key - this must be a prime number between 0 and 500:"))
q = int(input("Enter a key - this must be a prime number between 0 and 500:\n"))
else:
x = random.randint(0, 499)
y = random.randint(0, 499)
p = int(lines[x])
q = int(lines[y])
generate_p_and_q(p,q)
e = generate_e(p,q)
N = generate_N(p,q)
for char in message:
encrypted.append((ord(char) ** e) % N)
result = ''
for i in encrypted:
result = result + str(i)
print("encrypted message: " + result)
info = [encrypted, N, e]
return (info)
encrypt_RSA()
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def calculate_d(a,m):
g,x,y = egcd(a,m)
if g != 1:
return None
else:
return x%m
def calculate_phi(N):
with open('First500Primes.txt') as f:
lines = f.read().splitlines()
for num in lines:
if N%int(num) == 0:
p = int(num)
q = N/int(num)
phi = (p-1)*(q-1)
return int(phi)
def decrypt_RSA():
encrypted = encrypt_RSA()
encrypted_message, N, e = encrypted[0], encrypted[1], encrypted[2]
print(N)
phi = calculate_phi(N)
d = calculate_d(phi,e)
print("D: " + str(d))
message = []
encrypted_message = (encrypted[0])
for c in encrypted_message:
m = (c**d) % N
print(m)
message.append(chr(m))
print(message)
decrypt_RSA()
I need the code to firstly encrypt the message with the encrypt function then decrypt it with the decrypt function, so the encrypted and original message should be displayed.
Could someone tell me whats wrong with my code (since I'm still in school, it may need to be simplified), any additional feedback would be greatly appreciated.
After a bit of debugging, the problem is that the function calculate_d() does not seem to calculate the right number. It is solved when we invert the params of one of your function. Change this line
d = calculate_d(phi, e)
to this:
d = calculate_d(e, phi)
That got it working for me.
Also, since you asked for suggestions to improve your code, I made a few (a lot) improvements. Some ideas:
I replaced the parts that read the prime number file with a prime number generator, but that is just because I didn't have the file at hand. Choose whichever you like best.
Invoke the main functions inside a if __name__ == '__main__':. Read about it here.
I moved the input prompts outside of the encryption code. Implement those parts as needed (random or prompting user for input) and just pass the result to the function for encryption.
My version:
def generate_primes():
"""
Generate an infinite sequence of prime numbers.
Sieve of Eratosthenes
Code by David Eppstein, UC Irvine, 28 Feb 2002
http://code.activestate.com/recipes/117119/
https://stackoverflow.com/a/568618/9225671
"""
# Maps composites to primes witnessing their compositeness.
# This is memory efficient, as the sieve is not "run forward"
# indefinitely, but only as long as required by the current
# number being tested.
D = {}
# The running integer that's checked for primeness
q = 2
while True:
if q not in D:
# q is a new prime.
# Yield it and mark its first multiple that isn't
# already marked in previous iterations
yield q
D[q * q] = [q]
else:
# q is composite. D[q] is the list of primes that
# divide it. Since we've reached q, we no longer
# need it in the map, but we'll mark the next
# multiples of its witnesses to prepare for larger
# numbers
for p in D[q]:
D.setdefault(p + q, []).append(p)
del D[q]
q += 1
def choose_p_and_q():
p_i = random.randint(0, 100)
q_i = random.randint(0, 100)
p = 0
q = 0
for i, n in enumerate(generate_primes()):
if i <= p_i:
p = n
if i <= q_i:
q = n
if i > p_i and i > q_i:
break
return p, q
def generate_n(p, q):
return p * q
def generate_phi(p, q):
return (p - 1) * (q - 1)
def generate_e(phi):
e = None
for n in generate_primes():
if math.gcd(n, phi) == 1:
e = n
if n >= phi:
if e is None:
raise ValueError('no suitable prime number found; reached {}'.format(n))
# return the highest prime number found
return e
def find_p_and_q_from_n(n):
for i in generate_primes():
if n % i == 0:
p = i
q, remainder = divmod(n, p)
if remainder == 0:
return p, q
def egcd(a, b):
if a == 0:
return b, 0, 1
else:
g, y, x = egcd(b % a, a)
return g, x - (b // a) * y, y
def calculate_d(phi, e):
g, x, _ = egcd(phi, e)
if g == 1:
return x % e
raise ValueError('no modular multiplicative inverse found')
def encrypt_rsa(msg):
p, q = choose_p_and_q()
n = generate_n(p, q)
phi = generate_phi(p, q)
e = generate_e(phi)
print()
print('ENCRYPT')
print('p ', p)
print('q ', q)
print('n ', n)
print('phi ', phi)
print('e ', e)
encrypted_list = []
for char in msg:
m = (ord(char) ** e) % n
encrypted_list.append(m)
print('msg ', list(msg))
print('encrypted_list', encrypted_list)
return encrypted_list, n, e
def decrypt_rsa(encrypted_list, n, e):
p, q = find_p_and_q_from_n(n)
phi = generate_phi(p, q)
d = calculate_d(e, phi)
print()
print('DECRYPT')
print('p ', p)
print('q ', q)
print('n ', n)
print('phi ', phi)
print('e ', e)
print('d ', d)
decrypted_list = []
for elem in encrypted_list:
m = (elem**d) % n
decrypted_list.append(chr(m))
print('decrypted_list', decrypted_list)
if __name__ == '__main__':
msg = input('Enter a message to encrypt:').strip()
data = encrypt_rsa(msg)
decrypt_rsa(*data)

can anyone solve this raw input error and configure settings error in python?

I am beginner in python.I want to generate genetic algorithm source code in python.To be honest I downloaded this code from internet.I compiled this code in pycharm. It shows an error in MAIN FUNCTION AND RAW_INPUT IN CONFIGURE FUNCTION CONFIGURE SETTINGS can anyone please check the error in main function and check the raw input .I enclosed the code.Thanks in advance
from operator import itemgetter, attrgetter
import random
import sys
import os
import math
import re
# GLOBAL VARIABLES
genetic_code = {
'0000':'0',
'0001':'1',
'0010':'2',
'0011':'3',
'0100':'4',
'0101':'5',
'0110':'6',
'0111':'7',
'1000':'8',
'1001':'9',
'1010':'+',
'1011':'-',
'1100':'*',
'1101':'/'
}
solution_found = False
popN = 100 # n number of chromos per population
genesPerCh = 75
max_iterations = 1000
target = 1111.0
crossover_rate = 0.7
mutation_rate = 0.05
"""Generates random population of chromos"""
def generatePop ():
chromos, chromo = [], []
for eachChromo in range(popN):
chromo = []
for bit in range(genesPerCh * 4):
chromo.append(random.randint(0,1))
chromos.append(chromo)
return chromos
"""Takes a binary list (chromo) and returns a protein (mathematical expression in string)"""
def translate (chromo):
protein, chromo_string = '',''
need_int = True
a, b = 0, 4 # ie from point a to point b (start to stop point in string)
for bit in chromo:
chromo_string += str(bit)
for gene in range(genesPerCh):
if chromo_string[a:b] == '1111' or chromo_string[a:b] == '1110':
continue
elif chromo_string[a:b] != '1010' and chromo_string[a:b] != '1011' and chromo_string[a:b] != '1100' and chromo_string[a:b] != '1101':
if need_int == True:
protein += genetic_code[chromo_string[a:b]]
need_int = False
a += 4
b += 4
continue
else:
a += 4
b += 4
continue
else:
if need_int == False:
protein += genetic_code[chromo_string[a:b]]
need_int = True
a += 4
b += 4
continue
else:
a += 4
b += 4
continue
if len(protein) %2 == 0:
protein = protein[:-1]
return protein
"""Evaluates the mathematical expressions in number + operator blocks of two"""
def evaluate(protein):
a = 3
b = 5
output = -1
lenprotein = len(protein) # i imagine this is quicker than calling len everytime?
if lenprotein == 0:
output = 0
if lenprotein == 1:
output = int(protein)
if lenprotein >= 3:
try :
output = eval(protein[0:3])
except ZeroDivisionError:
output = 0
if lenprotein > 4:
while b != lenprotein+2:
try :
output = eval(str(output)+protein[a:b])
except ZeroDivisionError:
output = 0
a+=2
b+=2
return output
"""Calulates fitness as a fraction of the total fitness"""
def calcFitness (errors):
fitnessScores = []
totalError = sum(errors)
i = 0
# fitness scores are a fraction of the total error
for error in errors:
fitnessScores.append (float(errors[i])/float(totalError))
i += 1
return fitnessScores
def displayFit (error):
bestFitDisplay = 100
dashesN = int(error * bestFitDisplay)
dashes = ''
for j in range(bestFitDisplay-dashesN):
dashes+=' '
for i in range(dashesN):
dashes+='+'
return dashes
"""Takes a population of chromosomes and returns a list of tuples where each chromo is paired to its fitness scores and ranked accroding to its fitness"""
def rankPop (chromos):
proteins, outputs, errors = [], [], []
i = 1
# translate each chromo into mathematical expression (protein), evaluate the output of the expression,
# calculate the inverse error of the output
print ('%s: %s\t=%s \t%s %s' %('n'.rjust(5), 'PROTEIN'.rjust(30), 'OUTPUT'.rjust(10), 'INVERSE ERROR'.rjust(17), 'GRAPHICAL INVERSE ERROR'.rjust(105)))
for chromo in chromos:
protein = translate(chromo)
proteins.append(protein)
output = evaluate(protein)
outputs.append(output)
try:
error = 1/math.fabs(target-output)
except ZeroDivisionError:
global solution_found
solution_found = True
error = 0
print ('\nSOLUTION FOUND' )
print ('%s: %s \t=%s %s' %(str(i).rjust(5), protein.rjust(30), str(output).rjust(10), displayFit(1.3).rjust(130)))
break
else:
#error = 1/math.fabs(target-output)
errors.append(error)
print ('%s: %s \t=%s \t%s %s' %(str(i).rjust(5), protein.rjust(30), str(output).rjust(10), str(error).rjust(17), displayFit(error).rjust(105)))
i+=1
fitnessScores = calcFitness (errors) # calc fitness scores from the erros calculated
pairedPop = zip ( chromos, proteins, outputs, fitnessScores) # pair each chromo with its protein, ouput and fitness score
rankedPop = sorted ( pairedPop,key = itemgetter(-1), reverse = True ) # sort the paired pop by ascending fitness score
return rankedPop
""" taking a ranked population selects two of the fittest members using roulette method"""
def selectFittest (fitnessScores, rankedChromos):
while 1 == 1: # ensure that the chromosomes selected for breeding are have different indexes in the population
index1 = roulette (fitnessScores)
index2 = roulette (fitnessScores)
if index1 == index2:
continue
else:
break
ch1 = rankedChromos[index1] # select and return chromosomes for breeding
ch2 = rankedChromos[index2]
return ch1, ch2
"""Fitness scores are fractions, their sum = 1. Fitter chromosomes have a larger fraction. """
def roulette (fitnessScores):
index = 0
cumalativeFitness = 0.0
r = random.random()
for i in range(len(fitnessScores)): # for each chromosome's fitness score
cumalativeFitness += fitnessScores[i] # add each chromosome's fitness score to cumalative fitness
if cumalativeFitness > r: # in the event of cumalative fitness becoming greater than r, return index of that chromo
return i
def crossover (ch1, ch2):
# at a random chiasma
r = random.randint(0,genesPerCh*4)
return ch1[:r]+ch2[r:], ch2[:r]+ch1[r:]
def mutate (ch):
mutatedCh = []
for i in ch:
if random.random() < mutation_rate:
if i == 1:
mutatedCh.append(0)
else:
mutatedCh.append(1)
else:
mutatedCh.append(i)
#assert mutatedCh != ch
return mutatedCh
"""Using breed and mutate it generates two new chromos from the selected pair"""
def breed (ch1, ch2):
newCh1, newCh2 = [], []
if random.random() < crossover_rate: # rate dependent crossover of selected chromosomes
newCh1, newCh2 = crossover(ch1, ch2)
else:
newCh1, newCh2 = ch1, ch2
newnewCh1 = mutate (newCh1) # mutate crossovered chromos
newnewCh2 = mutate (newCh2)
return newnewCh1, newnewCh2
""" Taking a ranked population return a new population by breeding the ranked one"""
def iteratePop (rankedPop):
fitnessScores = [ item[-1] for item in rankedPop ] # extract fitness scores from ranked population
rankedChromos = [ item[0] for item in rankedPop ] # extract chromosomes from ranked population
newpop = []
newpop.extend(rankedChromos[:popN/15]) # known as elitism, conserve the best solutions to new population
while len(newpop) != popN:
ch1, ch2 = [], []
ch1, ch2 = selectFittest (fitnessScores, rankedChromos) # select two of the fittest chromos
ch1, ch2 = breed (ch1, ch2) # breed them to create two new chromosomes
newpop.append(ch1) # and append to new population
newpop.append(ch2)
return newpop
def configureSettings ():
configure = raw_input ('T - Enter Target Number \tD - Default settings: ')
match1 = re.search( 't',configure, re.IGNORECASE )
if match1:
global target
target = input('Target int: ' )
def main():
configureSettings ()
chromos = generatePop() #generate new population of random chromosomes
iterations = 0
while iterations != max_iterations and solution_found != True:
# take the pop of random chromos and rank them based on their fitness score/proximity to target output
rankedPop = rankPop(chromos)
print ('\nCurrent iterations:', iterations)
if solution_found != True:
# if solution is not found iterate a new population from previous ranked population
chromos = []
chromos = iteratePop(rankedPop)
iterations += 1
else:
break
if __name__ == "__main__":
main()
Probably you are using Python3, rather than Python2.
The function raw_input is for Python2.
In Python3, raw_input() was renamed to input()
From http://docs.python.org/dev/py3k/whatsnew/3.0.html
So, replace raw_input for input and give it a try.

Python: Failing to break out of while loop with "SyntaxError: 'break' outside loop"

I am developing a breadth-first-search algorithm for a factorization problem and am running into an interesting/confusing bug when attempting to break out of a while loop. If you run the code below, it will fail inside the "construct_path" method, stating :
File "main.py", line 96
break
SyntaxError: 'break' outside loop
but I am inside of a while loop! If anyone could give me some advice on this issue, I would really appreciate it. Thanks in advance.
from numpy import random
import itertools
import Queue
#Finding multiples, BFS problem
#Given input of list with unique integers 0 - 9 and n = range(0,1000000), calculate smallest multiple of n and unique combination of values in the list
#Example : Input : list = {0,1,2} , n = 3,
# output = 12
# Input : list = {0,1,2} , n = 50
# Output = 200
class Problem:
def __init__(self):
self.n = random.randint(0,10000000)
listSize = random.randint(1,9)
mainSet = set()
self.mainList = []
while True:
toAdd = random.randint(0,9)
if(toAdd not in self.mainList):
self.mainList.append(toAdd)
if(len(self.mainList) == listSize):
break
def get_start_state(self):
s = ''.join(map(str, self.mainList))
return int(s)
def is_goal(self, state):
return True
def get_sucessors(self):
print "Getting successors"
def breadth_first_search(problem):
# a FIFO open_set
open_set = Queue.Queue()
# an empty set to maintain visited nodes
closed_set = set()
# a dictionary to maintain meta information (used for path formation)
meta = dict() # key -> (parent state, action to reach child)
# initialize
start = problem.get_start_state()
meta[start] = (None, None)
open_set.put(start)
while not open_set.empty():
parent_state = open_set.get()
print "{} {}".format("parent_state is ", parent_state)
if problem.is_goal(parent_state):
return construct_path(parent_state, meta)
for (child_state, action) in problem.get_successors(parent_state):
if child_state in closed_set:
continue
if child_state not in open_set:
meta[child_state] = (parent_state, action)
open_set.put(child_state)
closed_set.add(parent_state)
#collect path to desired answer
def construct_path(state, meta):
action_list = list()
while True:
row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
return action_list.reverse()
x = Problem()
breadth_first_search(x)
Could be that you have a mix of tabs and spaces so that the break in line 96 looks like it is indented to be below action_list.append(action) but effectively it is below the while. That would explain the error at least.
It is just a guess. But it could be like this, using a visible tabwidth of 4 in the editor:
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
To the Python interpreter this looks like this (because it assumes a tabwidth of 8):
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
This is still valid but obviously means a different thing and would put your break outside of the while loop.

'str' object is not callable, functions as args

I'm trying to write a program as an exercise to calculate the integral value from a to b with one of 2 mathematical functions. My function integrate should have f as the mathematical function to integrate.
from math import *
def g(x):
return float(x) * float(x) + 3
def h(x):
return math.cos(float(x) * float(x))
def integrate(f, a, b, n):
H = (abs(float(a) - float(b)))/float(n)
ans = 0
xWaarde = a - H/2
print xWaarde
for k in range(1, n+1):
xWaarde = xWaarde + H
ans = ans + f(xWaarde) * H
return ans
print 'available functions:'
print 'g(x) = x^2+3'
while True:
print 'h(x) = cos(x^2)'
aIn = float(raw_input('integral from a = '))
bIn = float(raw_input('to b = '))
nIn = int(raw_input('Number of subintervals: '))
while True:
funcIn = raw_input('Which function do you want to use? (g or h): ')
if funcIn == 'g':
integrate(g,aIn,bIn,nIn)
break
elif funcIn == 'h':
integrate(h,aIn,bIn,nIn)
break
else:
print 'This function is not available'
print 'The definite integral is', integrate(funcIn, aIn, bIn, nIn)
doorg = raw_input('Do you want to continue? (y or n): ')
if doorg == 'n':
break
else:
print
The full Traceback is as follows:
Traceback (most recent call last):
File "C:/Users/Nick van Stijn/Desktop/Python/Assignment 3.1.py", line 38, in <module>
print 'The definite integral is', integrate(funcIn, aIn, bIn, nIn)
File "C:/Users/Nick van Stijn/Desktop/Python/Assignment 3.1.py", line 16, in integrate
ans = ans + f(xWaarde) * H
TypeError: 'str' object is not callable
EDIT: SOLVED
I made a mistake by calling a function at a time I didn't have to call it at all.
The problem is that you call integrate using the proper function, f or g, but then discard the result and instead call integrate again for the print, this time passing just the name of the function, funcIn.
Instead, you should just store the result in a variable, e.g., like this:
result = None
while result is None:
funcIn = raw_input('Which function do you want to use? (g or h): ')
if funcIn == 'g':
result = integrate(g,aIn,bIn,nIn)
elif funcIn == 'h':
result = integrate(h,aIn,bIn,nIn)
else:
print 'This function is not available'
print 'The definite integral is', result
Also, you could use a dict to map function names to actual functions, instead of using a possibly large number of if/elif/else:
functions = {'h': h, 'g': g}
while result is None:
funcIn = raw_input('Which function do you want to use? (g or h): ')
if funcIn in functions:
result = integrate(functions[funcIn],aIn,bIn,nIn)
else:
print 'This function is not available'
You are using the textual name of the function in the form of a string, rather than a reference to the function object itself. While there are hacky techniques to derive the function object from a string name, they can difficult to maintain and error-prone. Since in python functions are objects like any other (so called "first-class" objects) they are not really named, only references to functions have names.
This is a good example where a dictionary comes in handy, particularly if you wish to add more functions later. We can map a text key (what the user enters) to any python object, including a function:
from math import *
def g(x):
return float(x) * float(x) + 3
def h(x):
return math.cos(float(x) * float(x))
# Store references to the functions in a dictionary
# with the keys as the text name (the names need not match)
funcs = {'g': g, 'h': h} # <<<< ADDED
def integrate(f, a, b, n):
H = (abs(float(a) - float(b)))/float(n)
ans = 0
xWaarde = a - H/2
print xWaarde
for k in range(1, n+1):
xWaarde = xWaarde + H
ans = ans + f(xWaarde) * H
return ans
print 'available functions:'
print 'g(x) = x^2+3'
while True:
print 'h(x) = cos(x^2)'
aIn = float(raw_input('integral from a = '))
bIn = float(raw_input('to b = '))
nIn = int(raw_input('Number of subintervals: '))
while True:
funcIn = raw_input('Which function do you want to use? (g or h): ')
# THIS CODE CHANGED - note the simplification
# we just test for membership of the dictionary
if funcIn in funcs:
integrate(funcs[funcIn],aIn,bIn,nIn)
break
else:
print 'This function is not available'
# THIS CODE CHANGED (note first argument to integrate)
print 'The definite integral is', integrate(funcs[funcIn], aIn, bIn, nIn)
doorg = raw_input('Do you want to continue? (y or n): ')
if doorg == 'n':
break
else:
print

Getting the value of a variable from another function

I am unable to get the answer variable from the question function to check if the answer is indeed correct.
Following is what I have done so far:
import random
import operator
a = 0
ops = {
'+':operator.add,
'-':operator.sub
}
def generateQuestion():
x = random.randint(1, 10)
y = random.randint(1, 10)
op = random.choice(list(ops.keys()))
a = ops.get(op)(x,y)
print("What is {} {} {}?\n".format(x, op, y))
return a
def askQuestion():
guess = input("")
if guess == a:
print("Correct")
else:
print("Wrong, the answer is ", a)
generateQuestion()
askQuestion()
I cut out the in between stuff which is all working fine.
I'm aware I've set a = 0 at the top as well otherwise I got a was not defined error. However, I can't get the math from outside of the generateQuestion().
You can alleviate the need for the global by passing the answer value straight into askQuestion.
Don't forget to convert the return from input to an int, if you are running python 3. If using python 2 then you would not require the int conversion.
import random
import operator
ops = {
'+':operator.add,
'-':operator.sub
}
def generateQuestion():
x = random.randint(1, 10)
y = random.randint(1, 10)
op = random.choice(list(ops.keys()))
a = ops.get(op)(x,y)
print("What is {} {} {}?\n".format(x, op, y))
return a
def askQuestion(a):
guess = input("")
try:
if int(guess) == a:
print("Correct")
else:
print("Wrong, the answer is ", a)
except:
print('Did not input integer')
askQuestion(generateQuestion())
import random
import operator
ops = {
'+':operator.add,
'-':operator.sub
}
def generateQuestion():
x = random.randint(1, 10)
y = random.randint(1, 10)
op = random.choice(list(ops.keys()))
a = ops.get(op)(x,y)
print("What is {} {} {}?\n".format(x, op, y))
return a
def askQuestion(a):
guess = input("")
if guess == a:
print("Correct")
else:
print("Wrong, the answer is ", a)
variable = generateQuestion()
askQuestion(variable)
You have a scoping issue. Your variable a inside generateQuestion is not the same variable as a outside.
In order to fix this, you need to declare a as global inside generateQuestion.
import random
import operator
a = 0
ops = {
'+':operator.add,
'-':operator.sub
}
def generateQuestion():
x = random.randint(1, 10)
y = random.randint(1, 10)
op = random.choice(list(ops.keys()))
global a
a = ops.get(op)(x,y)
print("What is {} {} {}?\n".format(x, op, y))
return a
def askQuestion():
guess = input("")
if guess == a:
print("Correct")
else:
print("Wrong, the answer is ", a)
generateQuestion()
askQuestion()
Hav a look at this:
http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/tutorials/scope_resolution_legb_rule.ipynb

Categories

Resources