Check if Python list contains a specific element - python

I wrote a sample program to generate a hash code from input (it's not done yet so you don't see the part where it actually generates the hash):
import hashlib
def isInputValid(input, validInput=[]):
for i in validInput:
if validInput[i] == input: # error generated here
return True
pass
i = i + 1
return False
pass
sha1hash = hashlib.sha1()
choiceValidInputs = ["1", "2"]
print ("Welcome to hash generator!\n")
print ("[1] -- generate hash from input")
print ("[2] -- quit")
choice = input("\nWhat do you want to do? ")
if not isInputValid(choice, choiceValidInputs):
print ("Invalid option; try again")
choice = input("What do you want to do? ")
if choice == "1":
print ("\n[1] SHA1/SHA256")
print ("[2] SHA512")
hashType = input("\nWhat hash type do you want? ")
...
elif choice == "2":
print ("Goodbye!")
quit()
My Terminal window:
kali#kali:~$ python3 /home/bin/hashgenerator.py
Welcome to hash generator!
[1] -- generate hash from input
[2] -- quit
What do you want to do? 1
Traceback (most recent call last):
File "/home/bin/hashgenerator.py", line 19, in <module>
if isInputValid(choice, choiceInput)==False:
File "/home/bin/hashgenerator.py", line 5, in isInputValid
if validInput[i] == input:
TypeError: list indices must be integers or slices, not str
kali#kali:~$
I want to check if the input is present in choiceValidInputs. I actually don't really know how to work with lists etc. in Python.
Thanks for helping

you're looping through elements not indexes
If you want to use indexes:
def isInputValid(input, validInput=[]):
for i in range(len(validInput)):
if validInput[i] == input: # error generated here
return True
If you want to use elements you can do
def isInputValid(input, validInput=[]):
for i in validInput:
if i == input: # error generated here
return True
But you can do it more easily. And more correctly :)
def isInputValid(input, validInput=[]):
return input in validInput

for i in validInput:
if validInput[i] == input:
i here is not an index of an item in validInput, it is the item itself. What you want to do is:
for i in validInput:
if i == input:
Besides, you don't need pass and i = i+1 below. And I would suggest renaming variable input to something else to avoid confusion with input() function.

Related

Adding and saving to list in external json file

I'm very new to Python and I'm struggling when it comes to saving the data that the user has entered to a json file when quitting the application. Also every time I run my code all the data inside the json file is wiped. When I enter the input to save and exit I get this error code:
Traceback (most recent call last):
File "C:\Users\User\Downloads\sit_resources\sit_resources\sit_admin_application.py", line 86, in <module>
main_menu()
File "C:\Users\User\Downloads\sit_resources\sit_resources\sit_admin_application.py", line 23, in main_menu
save()
File "C:\Users\User\Downloads\sit_resources\sit_resources\sit_admin_application.py", line 82, in save
patients_file.write(finallist)
io.UnsupportedOperation: not writable
Here is my code below:
import json
patients_file = open("patients.json", "r")
loaded_patients = json.load(patients_file)
def main_menu():
'''Function docstring documentation here'''
print("\nSIT Data Entry Menu")
print("==========================")
print("1: Print Patients' List\n2: Add Patient\n3: Delete Patient\n4: Exit")
print("==========================")
input1 = input("Enter your menu selection:")
if input1 == "1":
patients_list()
elif input1 == "2":
add_patient()
elif input1 == "3":
remove_patient()
elif input1 == "4":
save()
else:
print ("Please enter a valid input")
main_menu()
def patients_list():
print("\nSIT current patients:\n")
loaded_patients.sort(key=str.casefold)
for number, item in enumerate(loaded_patients, start=1):
print(number, item)
print("\nTotal number of registered patients is", len(loaded_patients))
main_menu()
def add_patient():
newpatient = input("\nEnter new Patient -> Lastname Firstname:")
print ("Do the details you have entered look correct? y/n")
confirm = input()
if confirm == "y":
loaded_patients.append(newpatient)
print ("Patient successfully added to list")
main_menu()
elif confirm == "n":
print ("Patient import cancelled")
add_patient()
else:
print ("Please enter a valid input")
add_patient()
def remove_patient():
print ("Which of the following patients would you like to remove?")
loaded_patients.sort(key=str.casefold)
for number, item in enumerate(loaded_patients, start=1):
print(number, item)
try:
removepatient = int(input("\nEnter the number of the patient you would like to remove"))
print ("Does the patient number you have entered look correct? y/n")
delconfirm = input()
if delconfirm == "y":
try:
removepatient = (removepatient - 1)
loaded_patients.pop(removepatient)
print ("Patient was successfully removed from the list")
main_menu()
except IndexError:
print("Please enter a valid input")
remove_patient()
elif delconfirm == "n":
print ("Deletion cancelled")
remove_patient()
else:
print ("Please enter a valid input")
remove_patient()
except ValueError:
print ("Please enter a valid input")
remove_patient()
def save():
open("patients.json", "w")
finallist = json.dumps(loaded_patients)
patients_file.write(finallist)
print("Patient List successfully saved")
quit()
main_menu()
I store the json file in the same directory and all it contains is a list:
["Soreback Leigh", "Neckache Annette", "Sorefoot Jo", "Kaputknee Matt", "Brokentoe Susan", "Tornligament Alex"]
If anyone could help me out and let me know what I'm doing wrong or any simpler method I could use, it would be greatly appreciated.
Thanks
Your code has several issues, including the one you're asking about.
The main thing is the overall structure: your code keeps calling functions from functions, never really returning - that can work for a very long time, but in the end it will fail, and it's not the correct way to go about this.
Take for example your main_menu() - once an option is selected, you call the function matching it, and when the work there is done, you call main_menu() again. However, a better way to do the same:
def main_menu():
choice = ''
while choice != '4':
print('some options, 4 being "save and quit"')
if choice == 1:
patients_list()
...
# no if choice == 4: save() here, we'll save at the end
save()
This way, the menu will keep getting printed when you return to it, but every function that is executed, is allowed to return and then the loop restarts, unless option 4 was entered. And since you can allow the functions to return, no need to call main_menu() at the end of them.
Your save() function has some issues: it doesn't need quit() any more, but you also didn't do anything with the file you opened. A nice way to do this in Python is to use a 'context manager', which boils down to using with, like this:
def save():
with open("patients.json", "w") as patients_file:
finallist = json.dumps(loaded_patients)
patients_file.write(finallist)
That's assuming your loaded_patients always contains all the current patients of course. Given that's what it is for, you should consider just calling it patients.
Your file only contains a list, because a list is what you are creating in those functions and a list is a valid content for a json file. If you expected a dictionary, you should construct one in the rest of the code, but from your example it's unclear what exactly you would expect that dictionary to look like.
The conventional way to load and save json:
with open('patients.json', 'r') as f:
loaded_patients = json.load(f)
with open('patients.json', 'w') as f:
json.dump(loaded_patients, f)
You are trying to write to patients_file, which you opened in read-only mode.

Calculating average from user (through prompt input data) in a while loop until some condition in Python

I have written the following code which is working fine for me and I want to write the same code in a function (i.e., def function_name()) - which I have tried below as well but that's not a good approach and it's poorly written). So, how can I fix the code and how can I put input in an argument of my function name upon invoking/calling argument so that I can get my ultimate answer.
# Normal code:
from statistics import mean
lst = list()
while True:
user_int = input("Enter a number: ")
if user_int == "done":
break
try:
float_user_int = float(user_int)
except:
print("Bad input. Enter a valid number")
continue
lst.append(float_user_int)
print(mean(lst))
# Function Method I have tried which is working fine but it's poorly written and not yielding correct output. Rather, I am getting an error i.e., NameError: name 'float_user_input' is not defined. How can I write user_input integer numbers in an argument of my function name?
def avg_list(float_user_input):
from statistics import mean # import statistics
lst = list()
while True:
user_int = input("Enter a number: ")
if user_int == "done":
break
try:
float_user_int = float(user_int)
except:
print("Bad input. Enter a valid number")
continue # quit()
lst.append(float_user_int)
return(mean(lst)) # statistics.mean()
print(avg_list(float_user_input))
# This is the one I tried and it seems to be working with function but I don't think this code is perfect because I have done nothing in it except copy pasting the entire code under def function statement. How can I put user input number in an argument of function name?
def avg_list():
from statistics import mean # import statistics
lst = list()
while True:
user_int = input("Enter a number: ")
if user_int == "done":
break
try:
float_user_int = float(user_int)
except:
print("Bad input. Enter a valid number")
continue # quit()
lst.append(float_user_int)
return(mean(lst)) # statistics.mean()
print(avg_list())
Your help would be highly appreciated! Thanks.
Remove float_user_input from function declaration and function call
I think you want a function which takes input list from user such as get_input_list and calculate the mean as below:
from statistics import mean # import statistics
def avg_list(input_list):
return(mean(input_list))
def get_input_list():
# Take user input here
lst = list()
while True:
user_int = input("Enter a number: ")
if user_int == "done":
break
try:
float_user_int = float(user_int)
except:
print("Bad input. Enter a valid number")
continue
lst.append(float_user_int)
return lst
# call function
print(avg_list(get_input_list()))

ValueError: invalid literal for int() in my program and if statement inside a except

I have a program that takes input and adds it to a list and spits out the average of said list. I want to make it so you can type MENU and it will stop the programy() and let you either exit or restart the programy(). Everything works fine until you type MENU (all caps). Thank you everyone! :) Still new to python.
from functools import reduce
def programy():
running = True
print("I output the average of a list that you add files to.")
listy = []
while running == True:
def listaverage(givenlist):
print(sum(listy) / len(listy))
currentnum = input("Please type a number to add to the list: ")
try:
val = int(currentnum)
except ValueError:
if str(currentnum) == "MENU":
running = False
else:
print("Not a number!")
continue
listy.append(int(currentnum))
listaverage(listy)
answer = input("Please type either: EXIT or RESTART")
if str(answer) == "RESTART":
running = True
if answer == "EXIT":
exit
programy()
Traceback (most recent call last):
File "C:\Users\hullb\OneDrive\Desktop\average_via_input.py", line 34, in <module>
programy()
File "C:\Users\hullb\OneDrive\Desktop\average_via_input.py", line 24, in programy
listy.append(int(currentnum))
ValueError: invalid literal for int() with base 10: 'MENU
if str(currentnum) == "MENU":
running = False
sets the while condition to false and stops the next iteration from running, but the current one hasn't ended yet, so in int(currentnum) you are trying to convert "MENU" to int.
Use isdigit() instead to check the value
if currentnum.isdigit():
listy.append(int(currentnum))
listaverage(listy)
else:
if str(currentnum) == "MENU":
running = False
else:
print("Not a number!")
The error is simple, you're taking a string as an input,
say if for exiting the loop i.e. MENU, and in line
listy.append(int(currentnum))
you're typecasting that to an integer. That's why you're getting the above error.
Without changing much of code, you only need to shift few lines to get that done.
Just move
listy.append(int(currentnum))
listaverage(listy)
under the try block, where if it is a number you do as required.
Also define the function listaverage(listy) outside the main program, unless you want it acting as a generator.

Python 3.x input variable

I want to get user input of a code that has to be 11 numbers long and must not contain any characters. Otherwise the question to enter will be repeated.
code=input("Please enter your code ")
while len((code)) !=11: #here should be something to nullify strings inout :)
code = input("Please enter your code and in numbers only ")
There is definitely a better solution for this, just can't think of any.
This might be what you're after
def validate(s):
for char in s: #iterate through string
if not char.isdigit(): # checks if character is not a number
return False # if it's not a number then return False
return True # if the string passes with no issues return True
def enter_code():
while True: #Will keep running until break is reached
code = input("Please enter your code: ") #get user input
# if the length of input and it passes the validate then print 'Your code is valid'
if len(code) == 11 and validate(code):
print('Your code is valid')
break #break out of loop if valid
# if code fails test then print 'Your code is invalid' and return to start of while loop
print('Your code is invalid')
if __name__ == '__main__':
enter_code()

Continuous results from a single function call

I am extremely new to Python, and to programming in general, so I decided to write some basic code to help me learn the ins and outs of it. I decided to try making a database editor, and have developed the following code:
name = []
rank = []
age = []
cmd = input("Please enter a command: ")
def recall(item): #Prints all of the information for an individual when given his/her name
if item in name:
index = name.index(item) #Finds the position of the given name
print(name[index] + ", " + rank[index] + ", " + age[index]) #prints the element of every list with the position of the name used as input
else:
print("Invalid input. Please enter a valid input.")
def operation(cmd):
while cmd != "end":
if cmd == "recall":
print(name)
item = input("Please enter an input: ")
recall(item)
elif cmd == "add":
new_name = input("Please enter a new name: ")
name.append(new_name)
new_rank = input("Please enter a new rank: ")
rank.append(new_rank)
new_age = input("Please input new age: ")
age.append(new_age)
recall(new_name)
else:
print("Please input a valid command.")
else:
input("Press enter to quit.")
operation(cmd)
I want to be able to call operation(cmd), and from it be able to call as many functions/perform as many actions as I want. Unfortunately, it just infinitely prints one of the outcomes instead of letting me put in multiple commands.
How can I change this function so that I can call operation(cmd) once, and call the other functions repeatedly? Or is there a better way to go about doing this? Please keep in mind I am a beginner and just trying to learn, not a developer.
Take a look at your code:
while cmd != "end":
if cmd == "recall":
If you call operation with anything than "end", "recall" or "add", the condition within while is True, the next if is also True, but the subsequent ifs are false. Therefore, the function executes the following block
else:
print("Please input a valid command.")
and the while loop continues to its next lap. Since cmd hasn't changed, the same process continues over and over again.
You have not put anything in your code to show where operator_1, operator_2, and operator_3 come from, though you have hinted that operator_3 comes from the commandline.
You need to have some code to get the next value for "operator_3". This might be from a list of parameters to function_3, in which case you would get:
def function_3(operator_3):
for loopvariable in operator_3:
if loopvariable == some_value_1:
#(and so forth, then:)
function_3(["this","that","something","something else"])
Or, you might get it from input (by default, the keyboard):
def function_3():
read_from_keyboard=raw_input("First command:")
while (read_from_keyboard != "end"):
if read_from_keyboard == some_value_1:
#(and so forth, then at the end of your while loop, read the next line)
read_from_keyboard = raw_input("Next command:")
The problem is you only check operator_3 once in function_3, the second time you ask the user for an operator, you don't store its value, which is why its only running with one condition.
def function_3(operator_3):
while operator_3 != "end":
if operator_3 == some_value_1
function_1(operator_1)
elif operator_3 == some_value_2
function_2
else:
print("Enter valid operator.") # Here, the value of the input is lost
The logic you are trying to implement is the following:
Ask the user for some input.
Call function_3 with this input.
If the input is not end, run either function_1 or function_2.
Start again from step 1
However, you are missing #4 above, where you are trying to restart the loop again.
To fix this, make sure you store the value entered by the user when you prompt them for an operator. To do that, use the input function if you are using Python3, or raw_input if you are using Python2. These functions prompt the user for some input and then return that input to your program:
def function_3(operator_3):
while operator_3 != 'end':
if operator_3 == some_value_1:
function_1(operator_3)
elif operator_3 == some_value_2:
function_2(operator_3)
else:
operator_3 = input('Enter valid operator: ')
operator_3 = input('Enter operator or "end" to quit: ')
looks like you are trying to get input from the user, but you never implemented it in function_3...
def function_3(from_user):
while (from_user != "end"):
from_user = raw_input("enter a command: ")
if from_user == some_value_1:
# etc...

Categories

Resources