How to pull values from a nested dictionary with user input - python

Sorry if not too clear, creating a program to calculate a formula and using cataloged values for one variable which are stored in a nested dictionary. I want to have the user be able to pull values from the dict like so:
def get_value():
x = input("Material: ")
if x in materials:
y = input("Gauge: ")
if y in x:
return materials[x][y]
elif not (not (y is None) and not (y not in x)):
return 0
elif x not in materials or x is None:
return "Invalid Punch"
is there any specific way to do this that I'm messing up? Every time I try to run it I get a Nonetype, which I have set to replace with a default value of 0.
Dict for reference
materials = {"ss": {22: "", 21: "", 20: "0.431", 19: "", 18: ""
,17: "", 16: "", 15: "", 14: ""
,13: "", 12: "", 11: "", 10: "", 9: "", 8: ""}, }

Change your line: if y in x: to if y in materials[x]: you need to check if y is in the dict of x. y in x checks if y is part of x

You should use raw_input() instead of input().
input() will evaluate the input as python code, whereas raw_input() will return a string.
Also, as #DanielMesejo mentioned in their answer the condition y in x won't work as both will be strings. You should check y in materials[x].
def get_value():
x = raw_input("Material: ")
if x in materials:
y = int(raw_input("Gauge: "))
if y in materials[x]:
return materials[x][y]
elif not (not (y is None) and not (y not in materials[x])):
return 0
elif x not in materials or x is None:
return "Invalid Punch"
print(get_value())
Output:
0
This doesn't work because the gauge index is an int, not a string. raw_input return a string! So we need to type cast it:
def get_value():
x = raw_input("Material: ")
if x in materials:
y = int(raw_input("Gauge: ")) # Converting raw_input response to int
if y in materials[x]:
return materials[x][y]
elif not (not (y is None) and not (y not in materials[x])):
return 0
elif x not in materials or x is None:
return "Invalid Punch"
print(get_value())
Output:
0.431
Your expression on line #7 is more complicated than is necessary so I have made a simpler function for you:
def get_value():
material = raw_input("Material: ")
if not material or material not in materials:
return "Invalid Punch"
gauge = int(raw_input("Gauge: "))
if not gauge or gauge not in materials[material]:
return 0
return materials[material][gauge]
Usage:
> python input.py
Material: ss
Gauge: 20
0.431

Try this:
def get_value():
x = raw_input("Material: ")
if x in materials:
y = raw_input("Gauge: ")
if int(y) in materials[x]:
return materials[x][int(y)]
elif not (not (y is None) and not (y not in x)):
return 0
elif x not in materials or x is None:
return "Invalid Punch"
Your problem was the x in y they are both string you need to call if y in materials[x] also converted y to an int. Since input returns Strings in general.

Related

I want the program to loop every time the sensor detects anything in 15cm

This is the code:
def check_ultra():
global arduinoSerialData, y, i, x
while True:
if arduinoSerialData.inWaiting() > 1:
myData = arduinoSerialData.readline()
myData = str(myData)
myData = myData.replace("b'", '')
myData = myData.replace("\\r\\n'", str(0))
myData = myData.replace("\\r00.000", str(0))
myData = myData.replace("\\r00.000", str(0))
if "c" in myData:
myData = myData.replace("c", str(0))
if y == 1:
y = 3
if float(myData) > 15:
x = 0
return y, x
else:
if float(myData) < 15 and float(myData) > 1:
y = 1
x = 0
return y, x
elif "a" in myData:
myData = myData.replace("a", str(0))
if y == 2:
y = 3
if float(myData) > 15:
x = 0
return y, x
else:
if float(myData) < 15 and float(myData) > 1:
y = 2
x = 0
return y, x
else:
y = 0
return y
set_servo1_angle(0)
set_servo2_angle(90)
go_out_count = 0
m1 = 0
count = 3
y = 0
i = 0
x = 0
while y == None or y == 0 or x == 1:
# i = 0
# y = None
check_ultra()
if y == 1 and x == 0:
print("1")
sleep(2)
elif y == 2 and x == 0:
print('2')
sleep(2)
What this currently does is it prints 1 every time sensor 1 is blocked, but then it ends the code. I want to make it such that every time I block a sensor, it prints the corresponding print statement, no matter how many times I block the sensor. I have tried adding many variables to help but they didnt work. How do I make the loop keep repeating?
Your outer-most loop has the following condition: y==None or y==0 or x==1. The if statements in it are only going to print if all of those conditions are False. That means the loop is guaranteed to terminate on the first printout.
If you want the loop to keep going indefinitely, ignore everything and keep going. Replace the loop with
while True:
check_ultra()
...
On an unrelated note, try to avoid globals. They may have unpredictable side effects when you set them in long-forgotten places, and generally make the code harder to maintain. Use arguments and return values instead.
For example:
def check_ultra(arduinoSerialData, x, y):
while True:
if arduinoSerialData.inWaiting() > 1:
myData = arduinoSerialData.readline()
myData = str(myData)
myData = myData.replace("b'", '')
myData = myData.replace("\\r\\n'", str(0))
myData = myData.replace("\\r00.000", str(0))
myData = myData.replace("\\r00.000", str(0))
if "c" in myData:
myData = float(myData.replace("c", "0"))
if y == 1:
if myData > 15:
return 0, 3
return x, 3
elif 1 < myData < 15:
return 0, 1
return x, y
elif "a" in myData:
myData = float(myData.replace("a", "0"))
if y == 2:
if myData > 15:
return 0, 3
elif 1 < myData < 15:
return 0, 2
return x, y
else:
return x, 0
You would call it as
x, y = check_ultra(arduinoSerialData, x, y)
'break' statement ends the while loop, so try replacing it with 'pass', like this:
elif y == 2:
print('2')
pass

Issue with map function

Below is the hacker rank code and x is not being mapped to instance args.Can someone please provide me with a reason?https://www.hackerrank.com/challenges/python-lists/problem
if __name__ == '__main__':
N = int(input())
l=[]
for _ in range(N):
line = input().split()
cmd = line[0]
args= line[1:] # <=> here we have 0, 1 or 2 parameters, right?
"""if cmd!= "print":
cmd += "(" + ",".join(args)+")"""
#x = ",".join(map(str,args))
if len(args) == 2:
x, y = map(int, args)
if cmd == "insert":
l.insert(x, y)
elif len(args) == 1:
x = map(int,args)
if cmd == "remove":
l.remove(x)
elif cmd == "append":
l.append(x)
elif cmd == "sort":
l.sorted()
elif cmd == "pop":
l.pop()
elif cmd =="reverse":
l.reverse()
elif cmd == 'print':
print(l)
Your issue is with this line:
x = map(int,args)
This does not work like the line you have in a different branch of your code:
x, y = map(int, args)
The reason is that the first one binds the name x to the map call. It doesn't unpack the map object to get the single value it will yield. For that you'd need:
x, = map(int, args) # note the comma!
But if you know that you have only a single value in args, there's really no need to call map on it at all. Just use x = int(args[0]) instead.
You have couple of issues in your code.
By x = map(int,args) (line 16), x becomes a map object. To obtain integer from this map, first convert it into a list and then use indexing. x = list(map(int,args))[0] will solve your issue. Or you could simply use x = int(args[0]).
list has no sorted function, change l.sorted() to l.sort().

Building a simple operattion type calculator for two digits? stuck at error

print("Welcome to MusCalculator")
print("For adding two no type add")
print("for mutiplying type multiply")
print("for subtraction type subtract")
print("for dividing type divide")
def add_numbers(x, y):
if input == "addition":
addition = x + y
print addition
if input == "multiply":
multiply = x*y
print multiply
if input == "subtract":
if x > y:
sub = x - y
print sub
else:
sub = y - x
print sub
if input == "divide":
div = x / y
print div
else:
print("Use me if you know me")
x = input("First No.")
y = input("Second No.")
addition = x + y
c = input("Type Operation")
add_numbers(x, y)
the error is
Traceback (most recent call last):
File "C:\Users\Aafaq\workspace\python\project 1.py", line 34, in <module>
c = input("Type Operation")
File "C:\Program Files (x86)\eclipse\plugins\org.python.pydev_4.5.5.201603221110\pysrc\pydev_sitecustomize\sitecustomize.py", line 141, in input
return eval(raw_input(prompt))
File "<string>", line 1, in <module>
NameError: name 'addition' is not defined
There are some problems in your code. Some are mentioned below.
Addition variable is used in your main code, you might want to try different name or declare addition as a global variable.
under or above your print statements:
addition = 0
Also you are setting the received operation into variable name c, which is not referred anywhere, that should have been set to variable name input (which is a system define function name, you should not use that name to compare it with a string).
You are probably trying to do something like this:
operation = " "
addition = 0
def add_numbers(x, y):
if operation == "addition":
addition = x + y
print addition
if input == "multiply":
multiply = x*y
print multiply
if operation == "subtract":
if x > y:
sub = x - y
print sub
else:
sub = y - x
print sub
if operation == "divide":
div = x / y
print div
else:
print("Use me if you know me")
x = input("First No.")
y = input("Second No.")
addition = x + y
operation = input("Type Operation")
add_numbers(x, y)

Python: If condition appears to be met but isn't triggering

I know this seems like it should be very simple, but at this point I'm at my wit's end trying to figure this out. I've coded up a calculator in python, but for some reason the ending if-else statement is only firing the else segment.
import sys
import re
#setting values
x = 0
n = '+'
y = 0
#valid input flag
valid = True
#continue operations flag
run = True
again = "k"
#addition function
def add(x, y):
return x + y
#subtraction function
def subtract(x, y):
return x - y
#multiplication function
def multiply(x, y):
return x * y
#division function
def divide(x, y):
return x / y
#continuation loop
while run == True:
#Prompt for and accept input
equation = raw_input("Please insert a function in the form of 'operand' 'operator' 'operand' (x + y): ")
equation.strip()
#Divide input into 3 parts by spaces
pieces = re.split('\s+', equation)
#set part 1 = x as float
x = pieces[0]
try:
x = float(x)
except:
print "x must be a number"
valid = False
#set part 2 = operator
if valid == True:
try:
n = pieces[1]
except:
print "Please use valid formating (x [] y)."
valid = False
#set part 3 = y as float
if valid == True:
y = pieces[2]
try:
y = float(y)
except:
print "y must be a number"
valid = False
#If input is valid, do requested calculations
while valid == True:
if n == '+' :
print equation + " =", add(x,y)
elif n == '-' :
print equation, " =", subtract(x,y)
elif n == '*' :
print equation, "*", y, " =", multiply(x,y)
elif n == '/' :
if y == 0:
print "You cannot divide by zero."
else:
print equation, " =", divide(x,y)
else:
print "Please use an appropriate operator ( + - * / )."
#play again
again = raw_input("Play again? ")
print again
if again == ("yes", "y", "YES", "Yes","yes"):
run = True
print "yes'd"
else:
print "no'd"
run = False
When I run this code, I get two different problems:
If I enter a valid input (ie: 2 + 2), then my output is
"2 + 2 = 4.0"
"2 + 2 = 4.0"
"2 + 2 = 4.0"
repeating forever.
If I enter an invalid input, I get the "Play again? " Prompt, but
no matter what I enter, the else statement fires.
(for instance, in the case that I enter "yes" into "Play again? ", it will print:
"yes" (<-- this is from "print again" line )
"no'd" (<-- this is from "else: print "no'd" )
I dont know how to solve either of these problems at this point, so any help would be greatly appreciated.
Edit: Thank you everyone, I wish I could check mark all of you for helping me understand different things about what I did wrong.
In while valid == True:, you never change the value of valid, so it's always True and the loop is infinite. I don't see why it's even a loop - change it to if like the blocks above it and it will behave as expected.
Also, in if again == ("yes", "y", "YES", "Yes","yes"):, change == to in and it will behave as expected.
Perhaps you should replace this code:
while valid == True:
if n == '+' :
print equation + " =", add(x,y)
elif n == '-' :
print equation, " =", subtract(x,y)
elif n == '*' :
print equation, "*", y, " =", multiply(x,y)
elif n == '/' :
if y == 0:
print "You cannot divide by zero."
else:
print equation, " =", divide(x,y)
else:
print "Please use an appropriate operator ( + - * / )."
With this...
if valid:
Or...
while valid == True:
# Insert your previous code here.
break
You could also just simply set valid to false at the bottom of your loop too. That would work.
I think valid is constantly true in this case. You have also written while valid is true, which means it will keep iterating over the loop until valid is equalled to false. It appears that within this block of code in the while loop, valid isn't switched to false.
while valid == True: should probably be if valid == True
and for your second problem:
if again == ("yes", "y", "YES", "Yes","yes"): should probably be:
again = again.lower();
if again == "yes" or again == "y":
Your answer is looping because of
while valid == True:
Replace the loop with the if statement
You get "no'd" because of
if again == ("yes", "y", "YES", "Yes", "yes"):
Here you are equating string with a tuple, instead of checking whether the string is contained within a tuple. Try this instead:
if again in ("yes", "y", "YES", "Yes""):

Python simple project not quite working

# program to test truth tables v2
import time
import sys
x = 0
while x == 0:
x = str(raw_input("Please enter True or False..."))
x = x[0].upper()+ x[1:]
if x == "True":
x = True
elif x == "False":
x = False
else:
print 'invalid input!'
x = 0 # very difficult but this works now!
print x
y = 0
while y == 0:
y = str(raw_input("Please enter True or False again..."))
y = y[0].upper()+ y[1:]
if y == "True":
y = True
elif y == "False":
y = False
else:
print 'invalid input!'
y = 0
problem = 0
while problem == 0:
problem = input("Please enter number: \n1 for AND, 2 for OR, 3 for NAND, 4 for NOR...")
if problem == 1:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1.0)
print x, "AND", y, "is", x and y
elif problem == 2:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "OR", y, "is", x or y
elif problem == 3:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "NAND", y, "is", not(x and y) # not working for false/false or false/true
elif problem == 4:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(0.5)
print x, "NOR", y, "is", not(x or y) # not working for false/false
else:
print 'invalid input'
problem = 0
I thought this project worked then once I had tested all the combos, I found that there is a problem with the elif in the first while loop. See the comments in the last section. Any help gratefully received
The problem in your first while loop is that 0 == False. Toss that in the interpreter and see.
Here's my guess. You need to turn your booleans into strings. For example, in the first while loop, you set x equal to True and False instead of "True" and "False." Because Python sees booleans True and False as 1 and 0, respectively, your while loop variables (x and y) remain equal to zero in the case of False. It's likely causing you to repeat whenever the user inputs False
Try it and see. Let me know. And whatever you do, keep practicing!! You'll get it.
EDIT: Yep that was the problem. Here's your working code.
import time
import sys
x = 0
while x == 0:
x = str(raw_input("Please enter True or False..."))
#x = x[0].upper()+ x[1:]
print "THIS IS X: {}".format(x)
if x == "True":
x = "True"
elif x == "False":
x = "False"
else:
print 'invalid input!'
x = 0 # very difficult but this works now!
print x
y = 0
while y == 0:
y = str(raw_input("Please enter True or False again..."))
y = y[0].upper()+ y[1:]
if y == "True":
y = "True"
elif y == "False":
y = "False"
else:
print 'invalid input!'
y = 0
problem = 0
while problem == 0:
problem = input("Please enter number: \n1 for AND, 2 for OR, 3 for NAND, 4 for NOR...")
if problem == 1:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1.0)
print x, "AND", y, "is", x and y
elif problem == 2:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "OR", y, "is", x or y
elif problem == 3:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(1)
print x, "NAND", y, "is", not(x and y) # not working for false/false or false/true
elif problem == 4:
print "I'm thinking.."
time.sleep(2.5)
print "the answer is..."
time.sleep(0.5)
print x, "NOR", y, "is", not(x or y) # not working for false/false
else:
print 'invalid input'
problem = 0
The other posters have it right -- Python sees 0 and False as the same thing, at least truth-wise. We humans know that they are not the same thing type-wise, of course, and you can force Python to tell the difference by using "is" instead of "==", so the line should become...
while y is 0: # <-- change that line there
y = str(raw_input("Please enter True or False again..."))
y = y[0].upper()+ y[1:]
This is a "strict comparison" that compares both the value (which Python thinks are the same) and type (False is a Boolean, 0 is a Number)

Categories

Resources