Python continue indentation in While loop - python

I am writing a program that has multiple options to modify a dictionary in python. The user has four options, and after completing an option I want the program to bring back the user to the main menu.
So far, every option works correctly except it doesn't bring the user back to the main menu, and instead loops for ever
user_input = int(input("Faites un choix..."))
liste_epicerie = {}
while True:
if user_input == 1:
print(liste_epicerie)
if liste_epicerie == {}:
print("La liste est vide")
continue
So this code should bring back the user to user_input, but instead prints "La liste est vide" for ever.
What am I doing wrong?

You have to actually read the user input again (inside the loop):
liste_epicerie = {}
while True:
user_input = int(input("Faites un choix..."))
if user_input == 1:
# ...
elif ...:
# ...
# under some condition
break
The variable user_input does not magically remember and repeat how its value came to be.

sum=0
count=0
while True:
n=input ("enter the value :")
if n=="exit":
break
try:
float(n)
except:
print ("enter the numeric value")
continue
sum=sum+n
count=count+1
print(sum,count,sum/count)

Related

Open an image when requested

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.

How to break between loop by creating a condition in python

lst = []
while True:
try:
arr = int(input("Enter number of elements: "))
if arr == "Quit":
break
except ValueError:
print("Invalid Input")
continue
else:
break
while True:
try:
for i in range(0, arr):
ele = int(input("Enter the elements:"))
lst.append(ele)
print(lst)
except ValueError:
print("Invalid Input")
continue
else:
break
How can I create a condition to exit the program at any point in the loop by specifically entering the conditioned term?
Like when it asks me to enter an element, but i want to break the program right at that point by entering
"Quit".
How to do that in this code?
(Learner)
Use sys.exit() to exit the program completely. Use break to exit the specific loop you're in (which you've used).
Other notes:
You're doing arr = int(input(...)) but you want to accept the input of "Quit" which is a string. So if the user enters "Quit", it raise ValueError and the loop continues. So check for "Quit" first and if it's not quit, then convert to int with the try-block
Same applies for the 2nd loop where you ask the user for the elements in the list
Btw, your second loop's while True loop should be inside the for-loop which gets each element.
lst = []
while True:
arr = input("Enter number of elements: ")
if arr == "Quit":
sys.exit() # will exit completely
try:
arr = int(arr) # check for int in the try-block, error raised here, if not int
break # can put break here instead of in else, any is okay
except ValueError:
print("Invalid Input")
# continue not needed here, since it loops infinitely by default
for i in range(0, arr):
while True:
ele = input("Enter the elements:")
if ele == "Quit":
sys.exit() # will exit completely
try:
ele = int(ele) # check for int in the try-block, error raised here, if not int
lst.append(ele)
break # breaks out of `while` loop, not `for` loop; good
except ValueError:
print("Invalid Input")
# continue not needed here, since it loops infinitely by default
print(lst) # print the full list after all the inputs
The pattern for your input is repeated:
Ask user for input
if input is "Quit", then exit completely
otherwise, convert the input to an int
So this can put into a function, which you call in both places:
def int_or_quit(msg):
"""`msg` is the message you want to show at input"""
while True:
item = input(msg)
if item == "Quit":
sys.quit() # will exit completely
try:
return int(item) # try converting to int and return
except ValueError:
print("Invalid Input")
# repeats by default
# use the function above in your two code blocks, which are now simplified:
lst = []
arr = int_or_quit("Enter number of elements: ")
# program exits before if user "Quit", next part won't execute
for i in range(0, arr):
ele = int_or_quit("Enter an element:")
lst.append(ele)
print(lst)
I can see that there're 2 blocks in your code snippet. I'd suggest organising them in distinct functions, where function name infers a function goal (instead of comments):
def get_list_size():...
def fill_list():...
Next thing to do is deciding about function's return values:
from typing import List, Optional
def get_list_size() -> Optional[int]:
"""
:returns: number of desired elements of list or None, if "Quit" was pressed
:raises: ValueError exception, if non integer value was pressed
"""
def fill_list(lst_size: int) -> List[int]:
"""
returns: filled list
throws: ValueError exception, if non integer value was pressed
"""
Here you can see, how Optional type hint is used to add condition logic into the program.
Lats thing to do is to fill your functions with lightweight code:
def get_list_size() -> Optional[int]:
"""
:returns: number of desired elements of list or None, if "Quit" was pressed
:raises: ValueError exception, if non integer value was pressed
"""
while True:
try:
input_value = input("Enter number of elements: ")
# Pay attention: you have to check string input_value, not int(input_value).
# Checking int(input_value) would raise exception before 'Quit' validation.
if input_value == "Quit":
return None
return int(input_value)
# Could be rewritten as trinary if
# return None if input_value == "Quit" else int(input_value)
except ValueError:
print("Invalid Input")
# continue <- Not needed here
def fill_list(lst_size: int) -> List[int]:
"""
returns: filled list
throws: ValueError exception, if non integer value was pressed
"""
lst = []
while len(lst) < lst_size:
try:
ele = int(input("Enter the elements:"))
lst.append(ele)
print(lst)
except ValueError:
print("Invalid Input")
return lst
Pay attention: in fill_list function you have to try/except each element, so while loop was moved outside.
Last thing to do is running these functions:
desired_list = []
desired_list_size = get_list_size()
if desired_list_size is not None:
desired_list = fill_list(desired_list_size)
def one():
message = ""
while message != "Quit":
message = input("Type in Order > ")
if message == "Run":
print("Run some Code")
message = input("What do u want to run ? > ")
if message == "Exel":
print("Runing Exel")
else:
pass
else:
pass
while True:
one()
Here you can pass in funktions that will run when you call it by its Name. If u write Quit it will start over again. It starts over again if you write something wrong. U could do an FailExeption for that if u want to.

why does this python while loop not work in the program?

I'm trying to run the program in the following article:
https://blockgeeks.com/guides/python-blockchain-2/
I've copied all of the code into my Spyder IDE. When i run it there's a while loop which starts up asking the user to choose a number from the list of options it prints.
After selecting a number the program should perform the requested action. When i select it though it just loops back to the start of the while loop.
It appears to be ignoring the rest of the code in the while loop (the if statement part).
Confusingly if i take the parts of the code from the program which are used in the while loop and run them separately they work i.e if i run the below code and select the number 1 for my choice it will run the code in the if statement.
Why would the if statement run here but not in the main program?
#function 1:
def get_user_choice():
user_input = input("enter a number: ")
return user_input
#function 2:
def get_transaction_value():
tx_recipient = input('Enter the recipient of the transaction: ')
tx_amount = float(input('Enter your transaction amount '))
return tx_recipient, tx_amount
while True:
print("Choose an option")
print('Choose 1 for adding a new transaction')
print('Choose 2 for mining a new block')
print('Choose 3 for printing the blockchain')
print('Choose anything else if you want to quit')
user_choice = get_user_choice()
if user_choice == '1':
tx_data = get_transaction_value()
print(tx_data)
Update:
Sorry i realise i may not have been very clear what the problem is.
The above code is part of the code from the entire program and runs as expected in isolation from the main program.
The below code is the entire program from the article in the link. It includes all of the code in the program. If i run this main program the while loop doesn't use the if statement. It appears to just be breaking straight out of the loop after i select 1, 2 or 3 (any other number should break out of the loop anyway).
Here's a link for a screen shot showing what the console looks like after i have selected the number 1 for the option.
https://ibb.co/RNy2r0m
# Section 1
import hashlib
import json
reward = 10.0
genesis_block = {
'previous_hash': '',
'index': 0,
'transaction': [],
'nonce': 23
}
blockchain = [genesis_block]
open_transactions = []
owner = 'Blockgeeks'
def hash_block(block):
return hashlib.sha256(json.dumps(block).encode()).hexdigest()
# Section 2
def valid_proof(transactions, last_hash, nonce):
guess = (str(transactions) + str(last_hash) + str(nonce)).encode()
guess_hash = hashlib.sha256(guess).hexdigest()
print(guess_hash)
return guess_hash[0:2] == '00'
def pow():
last_block = blockchain[-1]
last_hash = hash_block(last_block)
nonce = 0
while not valid_proof(open_transactions, last_hash, nonce):
nonce += 1
return nonce
# Section 3
def get_last_value():
""" extracting the last element of the blockchain list """
return(blockchain[-1])
def add_value(recipient, sender=owner, amount=1.0):
transaction = {'sender': sender,
'recipient': recipient,
'amount': amount}
open_transactions.append(transaction)
# Section 4
def mine_block():
last_block = blockchain[-1]
hashed_block = hash_block(last_block)
nonce = pow()
reward_transaction = {
'sender': 'MINING',
'recipient': owner,
'amount': reward
}
open_transactions.append(reward_transaction)
block = {
'previous_hash': hashed_block,
'index': len(blockchain),
'transaction': open_transactions,
'nonce': nonce
}
blockchain.append(block)
# Section 5
def get_transaction_value():
tx_recipient = input('Enter the recipient of the transaction: ')
tx_amount = float(input('Enter your transaction amount '))
return tx_recipient, tx_amount
def get_user_choice():
user_input = input("Please give your choice here: ")
return user_input
# Section 6
def print_block():
for block in blockchain:
print("Here is your block")
print(block)
# Section 7
while True:
print("Choose an option")
print('Choose 1 for adding a new transaction')
print('Choose 2 for mining a new block')
print('Choose 3 for printing the blockchain')
print('Choose anything else if you want to quit')
user_choice = get_user_choice()
if user_choice == 1:
tx_data = get_transaction_value()
recipient, amount = tx_data
add_value(recipient, amount=amount)
print(open_transactions)
elif user_choice == 2:
mine_block()
elif user_choice == 3:
print_block()
else:
break
[1]: https://i.stack.imgur.com/FIrn7.png
When comparing values, Python takes a stronger route regarding data types than some other languages. That means no string in Python will equal a number.
Or in other terms "1" == 1 will be False.
That means you have to consider that in Python 3 you will receive a string from input() (not necessarily so in Python 2).
You can either compare this directly to another string:
user_choice = input()
if user_choice == "1":
print("You chose item 1")
Or you can convert it into a number first and compare it to a number:
user_choice = int(input())
if user_choice == 1:
print("You chose item 1")
Note that in the former case it might not be robust if the user enters extra spaces and in the latter case it will fail very loudly with an exception if the user doesn't enter an integer (or even nothing at all).
Both ways can be handled with extra code if necessary. In the former case, you can strip whitespace with user_input = input().strip() and in the latter case you can catch the exception with a try ... except ... block.
You have only handled the case for user_choice == '1'. If you enter anything other than 1, the program will return control to the beginning of the while loop.
I'll suggest you use a debugger to see what user_choice is before the if condition. If not, just use prints.
print("user_choice: {}, type: {}".format(user_choice, type(user_choice))

Python while loops never ends (on a numworks calculator) [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 3 years ago.
Just grabbed a calculator with python integrated (numworks).
I'm writing a python program wich includes a function to check if an input is a number (float).
When i type a proper float number everything goes right, but when an exception is catched here is the behavior:
the except block is run properly
then the while loops restarts, ask my imput again and enter an infite loops and freezes. No time for typing my input again.
I'm not familiar with Python, I'm pretty sure it's a simple syntax thing... But I didn't manage to work it out.
Help would be appreciated!
Here is the code:
# controle de saisie d'un nombre
def inputFloat(text):
ret = ''
while ret is not float:
try:
ret = float(input(text + " (nombre)"))
except ValueError:
print("saisie incorrecte.")
return ret
# test
def test():
print(inputFloat("saisir nombre"))
# affichage du menu
while True:
print("[1] test")
print("[0] quitter")
choix = input("Choisir une fonction:")
if choix == "0":
print("au revoir.")
break
elif choix == "1":
test()
Cheers
PS: infos about the environnement : the calculator uses MicroPython 1.9.4 (source https://www.numworks.com/resources/manual/python/)
Edit
here is the clean working version of the code with all suggestions from you guys.
Pushed it to the calc: works like a charm.
# controle de saisie d'un nombre
def inputFloat(text):
while True:
try:
return float(input(text + " (nombre)"))
except ValueError:
print("saisie incorrecte.")
continue
# test
def test():
print(inputFloat("saisir nombre"))
# affichage du menu
while True:
print("[1] test")
print("[0] quitter")
choix = input("Choisir une fonction:")
if choix == "0":
print("au revoir.")
break
elif choix == "1":
test()
break
I think the simplest way is the following:
def input_float():
while True:
try:
return float(input("Give us a number: "))
except:
print("This is not a number.")
You could also use a recursive version:
def input_float():
try:
return float(input("Give us a number: "))
except:
print("This is not a number.")
return input_float()

Personal archive tool, looking for suggestions on improving the code

i've written a tool in python where you enter a title, content, then tags, and the entry is then saved in a pickle file. it was mainly designed for copy-paste functionality (you spot a piece of code you like on the net, copy it, and paste it into the program), not really for handwritten content, though it does that with no problem.
i mainly did it because i'm always scanning through my pdf files, books, or the net for some coding example of solution that i'd already seen before, and it just seemed logical to have something where you could just put the content in, give it a title and tags, and just look it up whenever you needed to.
i realize there are sites online that handle this ex. http://snippets.dzone.com, but i'm not always online when i code. i also admit that i didn't really look to see if anyone had written a desktop app, the project seemed like a fun thing to do so here i am.
it wasn't designed with millions of entries in mind, so i just use a pickle file to serialize the data instead of one of the database APIs. the query is also very basic, only title and tags and no ranking based on the query.
there is an issue that i can't figure out, when you are at the list of entries there's a try, except clause where it tries to catch a valid index (integer). if you enter an inavlid integer, it will ask you to enter a valid one, but it doesn't seem to be able to assign it to the variable. if you enter a valid integer straightaway, there are no problems and the entry will display.
anyway let me know what you guys think. this is coded for python3.
main file:
#!usr/bin/python
from archive_functions import Entry, choices, print_choice, entry_query
import os
def main():
choice = ''
while choice != "5":
os.system('clear')
print("Mo's Archive, please select an option")
print('====================')
print('1. Enter an entry')
print('2. Lookup an entry')
print('3. Display all entries')
print('4. Delete an entry')
print('5. Quit')
print('====================')
choice = input(':')
if choice == "1":
entry = Entry()
entry.get_data()
entry.save_data()
elif choice == "2":
queryset = input('Enter title or tag query: ')
result = entry_query('entry.pickle', queryset)
if result:
print_choice(result, choices(result))
else:
os.system('clear')
print('No Match! Please try another query')
pause = input('\npress [Enter] to continue...')
elif choice == "3":
queryset = 'all'
result = entry_query('entry.pickle', queryset)
if result:
print_choice(result, choices(result))
elif choice == "4":
queryset = input('Enter title or tag query: ')
result = entry_query('entry.pickle', queryset)
if result:
entry = result[choices(result)]
entry.del_data()
else:
os.system('clear')
print('No Match! Please try another query')
pause = input('\npress [Enter] to continue...')
elif choice == "5":
break
else:
input('please enter a valid choice...')
main()
if __name__ == "__main__":
main()
archive_functions.py:
#!/bin/usr/python
import sys
import pickle
import os
import re
class Entry():
def get_data(self):
self.title = input('enter a title: ')
print('enter the code, press ctrl-d to end: ')
self.code = sys.stdin.readlines()
self.tags = input('enter tags: ')
def save_data(self):
with open('entry.pickle', 'ab') as f:
pickle.dump(self, f)
def del_data(self):
with open('entry.pickle', 'rb') as f:
data_list = []
while True:
try:
entry = pickle.load(f)
if self.title == entry.title:
continue
data_list.append(entry)
except:
break
with open('entry.pickle', 'wb') as f:
pass
with open('entry.pickle', 'ab') as f:
for data in data_list:
data.save_data()
def entry_query(file, queryset):
'''returns a list of objects matching the query'''
result = []
try:
with open(file, 'rb') as f:
entry = pickle.load(f)
os.system('clear')
if queryset == "all":
while True:
try:
result.append(entry)
entry = pickle.load(f)
except:
return result
break
while True:
try:
if re.search(queryset, entry.title) or re.search(queryset, entry.tags):
result.append(entry)
entry = pickle.load(f)
else:
entry = pickle.load(f)
except:
return result
break
except:
print('no entries in file, please enter an entry first')
pause = input('\nPress [Enter] to continue...')
def choices(list_result):
'''takes a list of objects and returns the index of the selected object'''
os.system('clear')
index = 0
for entry in list_result:
print('{}. {}'.format(index, entry.title))
index += 1
try:
choice = int(input('\nEnter choice: '))
return choice
except:
pause = input('\nplease enter a valid choice')
choices(list_result)
def print_choice(list_result, choice):
'''takes a list of objects and an index and displays the index of the list'''
os.system('clear')
print('===================')
print(list_result[choice].title)
print('===================')
for line in list_result[choice].code:
print(line, end="")
print('\n\n')
back_to_choices(list_result)
def back_to_choices(list_result):
print('1. Back to entry list')
print('2. Back to Main Menu')
choice = input(':')
if choice == "1":
print_choice(list_result, choices(list_result))
elif choice == "2":
pass
else:
print('\nplease enter a valid choice')
back_to_choices(list_result)
In the else, you call the main function again recursively. Instead, I'd do something like choice == "0", which will just cause the while loop to request another entry. This avoids a pointless recursion.

Categories