Input validation and input processing - python

I'm having quite a hard time creating this program.
Basically the goal is to request user input 7 times, validate the user input based on the criteria of being >= 0 and a valid real number, create a list of that input, then process the input to output Total, max, min, and average.
MAX_HOURS=7
def get_string(prompt):
value=""
value=input(prompt)
return int(value)
def get_pints(pints):
counter = 0
while counter < MAX_HOURS:
pints[counter] = get_real("How many pints were donated? ")
counter = counter + 1
return counter
def valid_real(value):
while True:
try:
value=float(value)
if value >= 0:
return True
else:
print("Please enter a valid number greater than 0! ")
return False
except ValueError:
print("Please enter a valid number greater than 0! ")
return False, int(value)
def get_real(prompt)
value=""
value=input(prompt)
while not valid_real(value):
print(value, "is not a valid entry. Please enter a number greater than 0")
value=input(prompt)
return value
def get_total_pints(pints):
counter = 0
total_pints = 0.0
while counter < 7:
total_pints = total_pints + pints[MAX_HOURS]
counter = counter + 1
return total_pints
def get_min_pints(pints):
min_pints = pints[MAX_HOURS]
min_pints = 0
for i in range(7):
if i < min_pints:
min_pints = i
return min_pints
def get_max_pints(pints):
max_pints = pints
max_pints = 0
for i in range (MAX_HOURS):
if i > max_pints:
max_pints = i
return max_pints
def get_average_pints(total_pints):
average_pints = 0
average_pints=total_pints / MAX_HOURS
return average_pints
def full_program():
pints=[0 for i in range(MAX_HOURS)]
max_pints=[0 for i in range(MAX_HOURS)]
total_pints=[0 for i in range(MAX_HOURS)]
counter=0
pints=get_pints(pints)
total_pints = get_total_pints(pints)
print([pints])
print(int(total_pints))
full_program()
While I'm pretty sure my input validation loop is correct, it seems like the main issue is that I have a an int object that can't be subscripted. I've read other posts and tried some of the code that worked in those scenarios, but I can't get my program to run correctly.
I'm really struggling and at this point, any guidance in the right direction is appreciated.
EDIT: I sent some of the wrong code, I've been revising this code so much I got mixed up on what I meant to send.
Also:
Traceback (most recent call last):
File "C:/Users/User/Desktop/classwork 1125/lab5original.py", line 193, in <module>
full_program()
File "C:/Users/User/Desktop/classwork 1125/lab5original.py", line 182, in full_program
total_pints = get_total_pints(pints)
File "C:/Users/User/Desktop/classwork 1125/lab5original.py", line 97, in get_total_pints
total_pints = total_pints + pints[MAX_HOURS]
TypeError: 'int' object is not subscriptable

Related

Python program not working - simple mathematic function

cat Prog4CCM.py
numberArray = []
count = 0
#filename = input("Please enter the file name: ")
filename = "t.txt" # for testing purposes
file = open(filename, "r")
for each_line in file:
numberArray.append(each_line)
for i in numberArray:
print(i)
count = count + 1
def findMaxValue(numberArray, count):
maxval = numberArray[0]
for i in range(0, count):
if numberArray[i] > maxval:
maxval = numberArray[i]
return maxval
def findMinValue(numberArray, count):
minval = numberArray[0]
for i in range(0, count):
if numberArray[i] < minval:
minval = numberArray[i]
return minval
def findFirstOccurence(numberArray, vtf, count):
for i in range(0, count):
if numberArray[i] == vtf:
return i
break
i = i + 1
# Function calls start
print("The maxiumum value in the file is "+ str(findMaxValue(numberArray, count)))
print("The minimum value in the file is "+str(findMinValue(numberArray, count)))
vtf = input("Please insert the number you would like to find the first occurence of: ")
print("First occurence is at "+str(findFirstOccurence(numberArray, vtf, count)))
This is supposed to call a function (Find First Occurrence) and check for the first occurrence in my array.
It should return a proper value, but just returns "None". Why might this be?
The file reading, and max and min value all seem to work perfectly.
You forgot to add a return in the findFirstOccurence() function, in case the vtf response is not in the list and there is an error with adding one to the iterator and use break, the for loop will do that for you.
The correct code would look like this:
...
def findFirstOccurence(numberArray, vtf, count):
for i in range(0, count):
if numberArray[i] == vtf:
return i
# break # <==
# i = i + 1 # It's errors
return "Can't find =("
# Function calls start
print("The maxiumum value in the file is "+ str(findMaxValue(numberArray, count)))
print("The minimum value in the file is "+str(findMinValue(numberArray, count)))
vtf = input("Please insert the number you would like to find the first occurence of: ")
print("First occurence is at "+str(findFirstOccurence(numberArray, vtf, count)))
At a quick glance, the function findFirstOccurence miss return statement. If you want us to help you debug the code in detail, you may need to provide your test data, like t.txt

Error in finding if an imei number in valid in python (TypeError: not all arguments converted during string formatting)

I am making a python script that lets you entire an imei number then checks if it is valid, I keep getting an error
Traceback (most recent call last):
File "program.py", line 28, in
if isValidEMEI(n):
File "program.py", line 19, in isValidEMEI
d = (int)(n % 10)
TypeError: not all arguments converted during string formatting
the code is
def sumDig( n ):
a = 0
while n > 0:
a = a + n % 10
n = int(n / 10)
return a
def isValidEMEI(n):
s = str(n)
l = len(s)
if l != 15:
return False
d = 0
sum = 0
for i in range(15, 0, -1):
d = (int)(n % 10)
if i % 2 == 0:
d = 2 * d
sum = sum + sumDig(d)
n = n / 10
return (sum % 10 == 0)
n = input("Enter number")
if isValidEMEI(n):
print("Valid IMEI Code")
else:
print("Invalid IMEI Code")
I have not really being sure what to try and do but I have looked up the error and nothing helpful/stuff I know to to interpret is showing up.
I am new to learning python so this will probalbly have a very simple sulution
I will update this with a "shortest replication of this error"
Thank you so much all help is welcome, this is for a challange I set myself so I am very determind to finish it
I have fixed it, replace n = input("enter number") with n = int(input("Enter number"))

How can I make it so that the program loops until the conditions are met?

I was trying to make it so that my program will keep asking the user to input a certain value and if the user doesn't it keeps asking until they do.
I tried to use "while" instead of "if" but I know I'm probably missing something, somewhere.
def terrain(surface):
surface = raw_input("What surface will you be driving on? ")
if surface == "ice":
u = raw_input("what is the velocity of the car in meters per second? ")
u = int(u)
if u < 0:
u = raw_input("Velocity must be greater than 0")
return
if u == 0:
u = raw_input("Velocty must be a number greater than zero")
return
a = raw_input("How quickly is the vehicle decelerating? ")
a = int(a)
if a > 0:
print ("Deceleration cannot be a positive integer")
return
else:
s1 = u**2
s2 = 2*.08*9.8
s = s1/s2
print "This is how far the vehicle will travel on ice: "
print ("The vehicle will travel %i meters before coming to a complete stop" % (s))
terrain("ice")
The problem is you are using return after checking the condition which causes the function to return None you have to use break instead of return with while loop instead of if to achieve this. A better way to validate and get data is below
class ValidationError(Exception):
pass
def validate_and_get_data_count(x):
if int(x) < 0:
raise ValidationError("Cannot be less than 0")
return int(x)
def validate_and_get_data_name(x):
if len(x) < 8:
raise ValidationError("Length of name cannot be less than 8 chars")
elif len(x) > 10:
raise ValidationError("Length of name cannot be greater than 10 chars")
return x
validators = {
"count": validate_and_get_data_count,
"name": validate_and_get_data_name
}
data = {}
params = [
("count","Please enter a count: "),
("name","Please enter a name: "),
]
for param in params:
while True:
x = input(param[1])
try:
data[param[0]] = validators[param[0]](x)
break
except ValidationError as e:
print(e)
print(data)
What the above code does is for every param in params list it runs a while loop checking for every validation condition defined in its validator if valid it breaks the while loop and proceeds to next param and repeats the same process again

TypeError: 'int' object is not subscriptable (nested functions)

So, whenever I call a function that calls another function I get this TypeError and I don't know why because it doesn't happen when I call first function. Here's the code:
def codeChar(c,key):
k = ord(c) + key
if key > 26:
key = key % 26
if 91 <= k <= 96:
k = k - 26
elif 123 <= k:
k = k - 26
c = chr(k)
return c
def codeBlock(word,key):
i = 0
result = ""
while i < len(word):
k = int(key[i])
result = result + codeChar(word[i],k)
i = i + 1
return result
def isletter(h):
i = ord(h)
if 65 <= i <= 90:
return True
elif 97 <= i <= 122:
return True
else:
return False
def codeString(string,key):
i = 0
result = ""
while i < len(string):
k = int(key[i])
if isletter(string[i]) == True:
result = result + codeBlock(string[i],k)
i = i + 1
else:
i = i + 1
return result
print(codeString(input("Enter a sentence to be coded: "),input("Enter an 8 digit key: ")))
The error code received when I run it is this:
Enter a sentence to be coded: Hello world
Enter your student number: 16061226
Traceback (most recent call last):
File "E:\cw.1\cw.1.py", line 89, in <module>
print(codeString(input("Enter a sentence to be coded: "),input("Enter your student number: ")))
File "E:\cw.1\cw.1.py", line 82, in codeString
result = result + codeBlock(string[i],k)
File "E:\cw.1\cw.1.py", line 39, in codeBlock
k = key[i]
TypeError: 'int' object is not subscriptable
Thanks in advance!
When you pass k to codeBlock on line 36, it's an integer, rather than the string that your function is expecting. Perhaps you intended to use key here instead?
It has nothing to do with calling a function from another function. When you call codeBlock from within codeString, you pass it a parameter k, which is an integer. On the other side, with key in the codeBlock function, you try to index into that integer by doing int(key[i]), hence the typeError.

python script for Mastermind solving stops unexpectedly (also gives error after increasing range)

I've tried to adapt one of the given scripts here:
How to solve the "Mastermind" guessing game?
When i'm trying to get results for:
digits = 4
variables = 10
times_until = 100
...I'm not having any problem. But when i try to increase 'variables' to 12 program stops after progressing a little.
Also i have another issue that if i change 'times_until' to 500 program gives me error like below:
Traceback (most recent call last):
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 72, in <module>
rungame(hidden_code, strategy_allrand)
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 58, in rungame
restart_game()
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 37, in restart_game
rungame(hidden_code, strategy_allrand)
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 58, in rungame
restart_game()
...
...
restart_game()
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 37, in restart_game
rungame(hidden_code, strategy_allrand)
File "/Users/ivalaostiapytriel/Dropbox/MastermindSolver.py", line 50, in rungame
print ("That's it. After %d tries, I won." % (i+1,))
File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/idlelib/PyShell.py", line 1347, in write
return self.shell.write(s, self.tags)
RuntimeError: maximum recursion depth exceeded while calling a Python object
>>>
Note that I'm NOT knowledgeable -even slightly- about python. Just had a lecture at back university about it, but not any other experience. Just need to adapt it for a project and retrieve some results from this.
Here is the code I've adapted down below. I would be glad if anyone mention where I am doing wrong to cause these errors.
import random
#from itertools import izip, imap
try:
# Python 2
from itertools import izip
from itertools import imap
except ImportError:
# Python 3
izip = zip
imap = map
digits = 4
variables = 10
times_until = 500
maxtries = 25
times_done = 0
average_cal = 0
fmt = '%0' + str(digits) + 'd'
searchspace = tuple([tuple(map(int,fmt % i)) for i in range(0,variables**digits)])
def compare(a, b, imap=imap, sum=sum, izip=izip, min=min):
count1 = [0] * variables
count2 = [0] * variables
strikes = 0
for dig1, dig2 in izip(a,b):
if dig1 == dig2:
strikes += 1
count1[dig1] += 1
count2[dig2] += 1
balls = sum(imap(min, count1, count2)) - strikes
return (strikes, balls)
def restart_game():
hidden_code = random.choice(searchspace)
rungame(hidden_code, strategy_allrand)
def rungame(target, strategy, verbose=True):#, maxtries=):
possibles = list(searchspace)
for i in range(maxtries):
g = strategy(i, possibles)
#if verbose:
#print ("Out of %7d possibilities. I'll guess %r" % (len(possibles), g),)
score = compare(g, target)
#if verbose:
#print (' ---> ', score)
if score[0] == digits:
if verbose:
print ("That's it. After %d tries, I won." % (i+1,))
global times_done
times_done += 1
global average_cal
average_cal += (i+1)
if times_done <= times_until:
restart_game()
else:
print ("That's it. Average %f " % (average_cal/times_until,))
break
possibles = [n for n in possibles if compare(g, n) == score]
return i+1
def strategy_allrand(i, possibles):
return random.choice(possibles)
if __name__ == '__main__':
hidden_code = random.choice(searchspace)
rungame(hidden_code, strategy_allrand)
As I understand it from your code, you call function rungame from function restart_game, and if
if times_done <= times_until:
you call restart_game from rungame. Therefore, if times_until variable exceed certain value you get maximum recursion depth exceeded error.
You get a sequence of nested calls of the form
rungame(...)
restart_game(...)
rungame(...)
restart_game(...)
...
To increase the maximum recursion depth you could use sys.setrecursionlimit function. But a far better solution would be to rewrite your code in such a way
to get rid of recursion.

Categories