I'm trying to do a silly little program that will let me open an image given a specific number.
import os
c1= os.startfile('Cat1.PNG')
c2= os.startfile('Cat2.PNG')
c3= os.startfile('Cat3.PNG')
catlist= [c1,c2,c3]
valid= False
def cats(valid):
while not valid:
try:
answer=int(input('Choose a number between 1 and 3'))
valid= True
except ValueError:
print("This is not a number")
if answer >=1 and answer <=3:
print(catlist[answer-1])
else:
print('Wrong value')
del (answer)
cats(valid)
return
cats(valid)
My problem is that my pictures just get all open when I start the program, while I want to open them when I choose a specific number.
The problem with your code is in the part where you assign the os.startfile() function to a variable.
When Python interpreter goes through your code, as soon as it hits the c1= os.startfile('Cat1.PNG') line of code, it executes the command and opens the files immediately.
import os
valid = True
def cats(valid):
while valid:
try:
x = int(input("Enter a number here: "))
valid = False
except ValueError:
print("This is not a number!")
if x == 1:
os.startfile('1.jpg')
elif x == 2:
os.startfile('2.jpg')
elif x == 3:
os.startfile('3.jpg')
else:
print("Wrong value")
valid = True
cats(valid)
There is probably a better and more efficient way to do it, but here is a solution I came up with.
Related
I wrote a python file in visual studio code with anaconda as the interpreter. I used pyinstaller to turn the file into an exe but when I try to open the exe a cmd window flashes open for a second and then closes. I don't know why it won't open. My program is supposed to read and print out specific data requested by the user from a HDF5 file and it does exactly that in visual studio code. I really just need a way to make it able to be run by someone on a different computer with python not installed.
Here is my entire code I know its probably bad because I don't have much python experience, but it works in visual studio code:
import numpy as np
import h5py
print ("Make sure to move the HDF file to the folder where this program is located.")
valid = "valid"
#gets the file name and checks if file exists
while valid == "valid":
filename = input("\nwhat is the name of the HDF file including the .hdf: ")
try:
with h5py.File(filename,"r") as hdf:
path = hdf.get("/Results/Unsteady/Output/Output Blocks/Base Output/Unsteady Time Series/2D Flow Areas/Flow Area")
break
except IOError:
print ("File not found")
#opens file
with h5py.File(filename,"r") as hdf:
#navigates to file location
path = hdf.get("/Results/Unsteady/Output/Output Blocks/Base Output/Unsteady Time Series/2D Flow Areas/Flow Area")
path_items = list(path.items())
#keeps running until user tells it to stop
run = "y"
while run == "y" or run == "Y" or run == "yes" or run == "Yes":
#user input
while valid == "valid":
choice = input("\nWhich file would you like to get data from? Depth, Face Shear stress, Face Velocity, or Water Surface: ")
choice = choice.lower()
if choice == "depth" or choice == "face shear stress" or choice == "face velocity" or choice == "water surface":
break
else:
print ("Invalid")
#checks the user input then converts the data set into a numpy array
if choice == "depth":
dataset = np.array(path.get("Depth"))
if choice == "face shear stress":
dataset = np.array(path.get("Face Shear Stress"))
if choice == "face velocity":
dataset = np.array(path.get("Face Velocity"))
if choice == "water surface":
dataset = np.array(path.get("Water Surface"))
#gets the shape/size of the dataset
shape = str(dataset.shape)
shape = shape.replace("(","")
shape = shape.replace(")","")
shape = shape.split(",")
timeAmount = shape[0]
pointAmount = shape[1]
timeAmount = int(timeAmount)
pointAmount = int(pointAmount)
timeAmount -= 1
pointAmount -= 1
print ("\nThis data set has",timeAmount,"time values and",pointAmount,"data values.")
#user input
while valid == "valid":
time = input("\nEnter a single time step: ")
try:
int(time)
break
except ValueError:
print ("Invalid")
time = int(time)
while valid == "valid":
minR = input("\nEnter the first (smaller) value in a range of cell locations: ")
try:
int(minR)
break
except ValueError:
print ("Invalid")
minR = int(minR)
while valid == "valid":
maxR = input("\nEnter the second (larger) value in a range of cell locations: ")
try:
int(maxR)
break
except ValueError:
print ("Invalid")
maxR = int(maxR)
#calculates all the numbers in the range between the two numbers
rangeL = []
while minR != maxR:
rangeL.append(minR)
minR += 1
rangeL.append(maxR)
#prints the value at each point
count = 0
for x in range(len(rangeL)):
tempN = rangeL[count]
tempV = dataset[time,rangeL[count]]
print (str(tempN) + "," + str(tempV))
count += 1
#asks the user if they want to get more data
run = input("\nWould you like to enter more parameters to get more/different data? (y/n): ")
if run == "y" or run == "Y" or run == "yes" or run == "Yes":
pass
else:
print ("Goodbye")
break
Probably because you have a code with just a few outputs. That means that the programm executes those lines really fast and eventually closes. Request for an input at the end of your code. That should make the program to stay open.
It worked for me. I used pyinstaller with command: pyinstaller -F file_name.py. It works. Doesn't close fast and asks for the input also.
Hi guys I was working on a shoppinglist-creator code but at the end I faced with a surprise.
My code:
import time
import math
import random
dict_of_lists={}
def addlist():
while True:
try:
listname=str(raw_input("=>Name of the list:\n"))
dict_of_lists[listname]={}
break
except ValueError:
print "=>Please enter a valid name.\n"
print "=>You added a new list named %s.\n" % (listname)
def printlists():
for lists in dict_of_lists:
return "-"+lists
def addproduct():
while True:
try:
reachlistname=input("=>Name of the list you want to add a product,Available lists are these:\n %s \nPlease enter one:\n" % (printlists()))
break
except ValueError:
print "=>Please enter a valid list name.\n"
while True:
try:
productname=raw_input("=>Name of the product:\n")
break
except ValueError:
print "=>Please enter a valid name.\n"
while True:
try:
productprice=input("=>Price of the product:\n")
if isinstance(float(productprice),float):
break
except ValueError:
print "=>Please enter a valid number.\n"
while True:
try:
productcount=input("=>Amount of the product:\n")
if isinstance(int(productcount),int):
break
except ValueError:
print "=>Please enter a valid number.\n"
dict_of_lists[reachlistname][productname]={"price":productprice,"count":productcount}
dict_of_lists[reachlistname]={productname:{"price":productprice,"count":productcount}}
allevents="1-Add a list"+" 2-Add a product to a list"
def eventtochoose():
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
if not isinstance(int(event),int):
print "\n=>Please enter a number.\n"
else:
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
while True:
print "%s" % ("\n"*100)
eventtochoose()
So, the problem is (I suggest you run the code) it says "=>What would you like to do? Here are the all things you can do:
1-Add a list 2-Add a product to a list
Please enter the number before the thing you want to do:" and when i put an answer it simply doesn't call the fucntion.
If I put 1 It should have called the fucntion addlist but I think it doesn't. There is nothing to explain I think just look at the code and find the problem if you want to help crocodiles. Thx
When you do int(event), that returns an int if possible, and raises a ValueError if not. So, testing the type of the result doesn't do you any good—if your code gets that far, the type has to be an int.
You already have code to handle the ValueError, so you don't need any other test for the same problem.
Meanwhile, you want to start the number that you got from int(event). That's the thing that can be == 1; the original string '1' will never be == 1.
So:
while True:
try:
event=raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
event = int(event)
if event==1:
addlist()
break
elif event==2:
addproduct()
break
except ValueError:
print "\n=>Please enter a valid input.\n "
You are not converting your input to an integer before comparing, so the comparisons are always false:
'1' == 1 # false
Try:
event = raw_input("=>What would you like to do? Here are the all things you can do:\n %s\nPlease enter the number before the thing you want to do:" % (allevents))
try:
event = int(event)
if event == 1:
addlist()
elif event == 2:
addproduct()
break
except ValueError:
print('Please enter a valid input')
Both functions use the same check(x) function and almost identical to each other, except the argument the second function have to take in order to use print.
Entering int as inputs showed no problem.
However, if alphabets were entered, the return result of enter_num() becomes NoneType, but this does not happen in enter_amount().
Where and how did it went wrong?
def check(x): #check if user input is integer
try:
int(x)
return True
except ValueError:
return False
def enter_num(): #get user input for lotto numbers
x = input("buy num:")
if check(x) == True: #check int
x = int(x)
return x
else:
print("Please enter integer")
enter_num()
def enter_amount(x): #get user amount of the lottos
print(x) ##if enter_num errored once, this will show None##
y = input("How many?")
if check(y) == True: #check int
y = int(y)
print("%s for %s copies" % (x,y))
return y
else:
print("Please enter integer")
enter_amount(x)
buy_num = enter_num()
amount = enter_amount(buy_num)
You never return the recursive result from enter_num():
def enter_num():
x = input("buy num:")
if check(x) == True:
x = int(x)
return x
else:
print("Please enter integer")
enter_num() # ignoring the return value
# so None is returned instead
The same applies to enter_amount(); it too ignores the recursive call.
You need to explicitly return the recursive call result, just like you would for any other expression:
def enter_num():
x = input("buy num:")
if check(x) == True:
x = int(x)
return x
else:
print("Please enter integer")
return enter_num() # ignoring the return value
Do the same for enter_amount(); change the last line to return enter_amount(x).
You really should not be using recursion however; all the user has to do is hold the ENTER key for a short amount of time for your code to end up breaking the recursion limit. See Asking the user for input until they give a valid response for better techniques; a while loop would be fine here.
There is also no need to test for == True; if already tests for truth:
if check(x):
I'd also inline the check test; no need to convert to int() twice if the string can be converted. The following won't run out of recursion depth, but just returns int(x) directly if x contained a convertible value, or prints an error message otherwise and loops right back to ask for the number again:
def enter_num():
while True:
x = input("buy num:")
try:
return int(x)
except ValueError:
print("Please enter integer")
I'm trying to make a multiple choice survey that allows the user to pick from options 1-x. How can I make it so that if the user enters any characters besides numbers, return something like "That's an invalid answer"
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
question = int(input('Out of these options\(1,2,3), which is your favourite?'))
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That\'s not an option!')
Your code would become:
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
while True:
try:
question = int(input('Out of these options\(1,2,3), which is your favourite?'))
break
except:
print("That's not a valid option!")
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That\'s not an option!')
The way this works is it makes a loop that will loop infinitely until only numbers are put in. So say I put '1', it would break the loop. But if I put 'Fooey!' the error that WOULD have been raised gets caught by the except statement, and it loops as it hasn't been broken.
The best way would be to use a helper function which can accept a variable type along with the message to take input.
def _input(message, input_type=str):
while True:
try:
return input_type (input(message))
except:pass
if __name__ == '__main__':
_input("Only accepting integer : ", int)
_input("Only accepting float : ", float)
_input("Accepting anything as string : ")
So when you want an integer , you can pass it that i only want integer, just in case you can accept floating number you pass the float as a parameter. It will make your code really slim so if you have to take input 10 times , you don't want to write try catch blocks ten times.
def func():
choice = "Wrong"
while choice.isdigit()==False :
choice = input("Enter a number: ")
if choice.isdigit()==False:
print("Wrongly entered: ")
else:
return int(choice)
One solution amongst others : use the type function or isinstance function to check if you have an ̀int or a float or some other type
>>> type(1)
<type 'int'>
>>> type(1.5)
<type 'float'>
>>> isinstance(1.5, int)
False
>>> isinstance(1.5, (int, float))
True
I would catch first the ValueError (not integer) exception and check if the answer is acceptable (within 1, 2, 3) or raise another ValueError exception
def survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
ans = 0
while not ans:
try:
ans = int(input('Out of these options\(1, 2, 3), which is your favourite?'))
if ans not in (1, 2, 3):
raise ValueError
except ValueError:
ans = 0
print("That's not an option!")
if ans == 1:
print('Nice!')
elif ans == 2:
print('Cool')
elif ans == 3:
print('Awesome!')
return None
I made a module for cases like this called restricted_input which checks the input in real time. Here, since you only need inputs from 1-3, this would do
from restricted_input import r_input
num = int(r_input("Out of these options\(1,2,3), which is your favourite? ", input_type="nothing", allow="123", maxlength=1))
It uses msvcrt.getch/termios to get non-blocking input, so it checks it in real time and allows only the specified characters.
Note: This will not work in IDLEs like Spyder, Jupyter etc.
You can use a module named PyInputPlus.
Installation:
pip install PyInputPlus
You can use this as
def Survey():
print('1) Blue')
print('2) Red')
print('3) Yellow')
question = int(input('Out of these options\(1,2,3), which is your favourite?'))
if question == 1:
print('Nice!')
elif question == 2:
print('Cool')
elif question == 3:
print('Awesome!')
else:
print('That\'s not an option!')
Can I combine these functions together to shorten my python code? I'm creating a quick program!
Here are the functions:
def try1():
try:
num1=input("Enter num 1: ")
return num1
except ValueError:
print("incorrect!")
return #value
def try2():
try:
num2=input("Enter num 2: ")
return num2
except ValueError:
print ("incorrect!")
return #value
def try3():
try:
num3=input("Enter num 3: ")
return num3
except ValueError:
print ("incorrect!")
return #value
def try4():
try:
num4=input("Enter num 4: ")
return num4
except ValueError:
print ("incorrect!")
return #value
Please post your suggestions and answers below.
As you can see from my reputations, I am a new programmer hoping to find kind people on Stackoverflow.
(This answer is based on the original revision of the question which is no longer accessible but showed a different problem, where the user is keep being asked until a valid number is entered. And the code showed some skill game system or something, so that’s why my questions are longer and more specific too.)
Something like this?
def getInt(name, target):
while True:
try:
return int(input('Please enter {0} for {1}: '.format(name, target)))
except ValueError:
print('Incorrect!')
strength0 = getInt('strength', 'character 1')
skill0 = getInt('skill', 'character 1')
strength1 = getInt('strength', 'character 2')
skill1 = getInt('skill', 'character 2')
In general, when you have multiple functions that approximately do the same thing, then yes, there is a lot potential to refactor it so you don’t repeat yourself. In this case, what was different is the question the user was being asked, so if we parameterize that, we are good to use just a single function to handle it all.
The function can be generalised to ask for the input of any number, for example:
def try_num(n):
num = int(input("Enter num {} : ".format(n)))
while num != n:
print ("incorrect!")
num = int(input("Enter num {} : ".format(n)))
return num
Use it like this:
try_num(10)
Enter num 10 : 9
incorrect!
Enter num 10 : 10
10
def safe_int(x):
try:
return int(x)
except ValueError:
return 0
[safe_int(raw_input("Number %d:"%i)) for i in range(4)]
I would create a validation method and simply pass in the strings.
def validate(question):
while True:
try:
print question,
input = raw_input()
if input.isdigit():
return int(input)
else:
print "Not a valid integer"