Try/Exception flow control - python-3.x

Codes:
def get_wordlen():
wordfamily_lst = []
while True:
try:
word_len = int(input('\nPlease enter length of the word you wish to guess: '))
input_File = open('dic.txt', 'r').read().split()
for word in input_File:
if len(word) == word_len:
wordfamily_lst.append(word)
else:
print("Sorry, there's no word of that length")
continue
except ValueError:
print('Please enter a numeric value for word length')
continue
return word_len, wordfamily_lst
wordlen, wordfamilylst = get_wordlen()
print(wordlen,wordfamilylst)
How can i modify my "else" statement to safeguard against user input of word length that the txt. file does not contain. Right now, my codes will display the print statement for EVERY word that doesn't match with the user input of word length.
I'd like just one print statement and loop back to the top of the while loop.
Please give me some suggestions.

You could modify your try block as:
word_len = int(input('\nPlease enter length of the word you wish to guess: '))
input_File = open('dic.txt', 'r').read().split()
wordfamily_lst = []
for word in input_File:
if len(word) == word_len:
wordfamily_lst.append(word)
if not wordfamily_lst:
print("Sorry, there's no word of that length")
continue
The for word in input_File: will execute for all words in the file
appending the word to wordfamily_lst only if the lengths match.
Since we are now assigning wordfamily_lst = [] inside the while
block, the if not wordfamily_lst: will make sure the error is
printed only if the input word is not present in the file.
On a related note, it would be a good idea to move the code to read the file outside the while True: block, read all the words in the file into a list once and compare the user input with this new list.
To summarize, this is what I mean:
def get_wordlen():
input_file_words = open('dic.txt', 'r').read().split()
while True:
try:
word_len = int(input('\nPlease enter length of the word you wish to guess: '))
wordfamily_lst = []
for word in input_file_words:
if len(word) == word_len:
wordfamily_lst.append(word)
if not wordfamily_lst:
print("Sorry, there's no word of that length")
continue
except ValueError:
print('Please enter a numeric value for word length')
continue
return word_len, wordfamily_lst
wordlen, wordfamilylst = get_wordlen()
print(wordlen,wordfamilylst)

Related

TypeError: method() takes 0 positional arguments but 1 was given

I wrote an input function python program,
But when run that code , IDE show that, "this function need to pass argument"
Even though ,I didn't declare any argument enter image description here
please help me how to solve this problem , Thank you in advance
list_number = list()
def input():
while True:
try:
number = input("Enter your number in to list = ")
if number == "Quit":
break
number = int(number)
list_number.append(number)
print(list_number)
except ValueError as e:
print(e)
def diagram():
display = ""
for i in list_number:
for j in range(i):
display = display +"#"
print(display)
display = ""
input()
diagram()
Several errors are noticed at glance:
mixture of namespace
You declared list_number as a global variable, but you cannot set value to it
directly insides a function. Instead, you can let the function return a value,
or use global statement to temporary allow a function to set a value to
a global variable temperary.
Read more on offical document, or search keyword python namespace for
relative articles.
name collision on builtin keyword
Some special word are reserved by python and could not be used as variable or
function name, input is amoung them.
BTW: The title of your question and example code layout is confusion! Follow the
tour to learn how to ask a better question and improve layout, so that people
can help you out.
Example code: though the test part has some bug I don't solved...
# remove: move it to a main progress for future design
# list_number = list()
# rename: input is a reserved name of builtins, pick another word
def myinput(*pargs):
if pargs:
for arg in pargs:
try:
yield int(arg)
except ValueError:
pass
else:
count = 0
while True:
# move out of `try` statement as it won't raise any exceptions
# imply lowercase for easier string comparison
userinput = input("Enter your number in to list: ").lower()
if userinput in ['quit', 'q']:
# for interactive, give user a response
print("Quit input procedure. Preparing Diagram...")
break
try:
number = int(userinput)
except ValueError:
# raise a error and the output will print to output by default
# there is no need to `print` an error
# and, for improve, you can raise a more specific message
# and continue your program
msg = "The program wants a number as input, please try again.\n"
msg += "Type `Quit` to exit input procedure."
print(msg)
continue
except KeyboardInterrupt:
msg = "You pressed Interrupt Keystroke, program exit."
print(msg)
return 0
# print a message and pass the value intercepted
count += 1
print("%d: number %d is added to queue." % (count, number))
yield number
def diagram(numbers):
# there is no need to iter a list by index
# and I am **not** sure what you want from your origin code
# if what you wnat is:
# join number with "#" sign
# then just use the builtins str.join method
# valid: is_list_like
if is_list_like(numbers):
numstr = map(str, numbers)
ret = "#".join(numstr)
else:
ret = "Nothing to export."
return ret
def is_list_like(obj):
"""fork from pandas.api.types.is_list_like,
search c_is_list_like as keyword"""
return (
# equiv: `isinstance(obj, abc.Iterable)`
hasattr(obj, "__iter__") and not isinstance(obj, type)
# we do not count strings/unicode/bytes as list-like
and not isinstance(obj, (str, bytes))
)
def main(*pargs):
# get a generator of user input
# if passed in values, accept parameter as user input for test
msgout = ""
if pargs:
# bug: test input not filtered by int() function
list_number = list(myinput(pargs))
print("Run builtin test module.")
else:
list_number = list(myinput())
count = len(list_number)
# process your input by whatever means you need
if count == 1:
msgout += "Received %d number from user input.\n" % count
else:
msgout += "Received %d numbers from user input.\n" % count
msgout += "The diagram is:\n%s" % diagram(list_number)
print(msgout)
def test():
"""simulate user input"""
userinputs = [
['a', 1, 5, 4, 9, 'q'],
[999, 'Quit'],
['q'],
]
for userinput in userinputs:
main(*userinput)
# test bug:
# 1. charactor is printed as output, too
if __name__ == "__main__":
# remove test() if you don't need it
test()
main()
Well I would change your function name from input to something else because you cannot have any function named anything from base python named in your function, This is probably the reason for your error.
Like the others said, input() is a builtin function in Python. Try this following code:
list_number = list()
def input_func():
while True:
try:
number = input("Enter your number in to list = ")
if number == "Quit":
break
number = int(number)
list_number.append(number)
print(list_number)
except ValueError as e:
print(e)
def diagram():
display = ""
for i in list_number:
for j in range(i):
display = display + "#"
print(display)
display = ""
input_func()
diagram()
Also, nice to note that try should be used more precisely only where the exception is expected to be thrown. You could rewrite input_func with that in mind, such as:
def input_func():
while True:
number = input("Enter your number in to list = ")
if number == "Quit":
break
try:
number = int(number)
except ValueError as e:
print(e)
else:
list_number.append(number)
print(list_number)

Code running despite no input being given (python)

When the user enters nothing, it is supposed to loop back and ask the question again. It performs correctly with every other type of input.
Here is the code:
string = ""
def str_analysis(string):
while True:
if string.isdigit():
if int(string) > 99:
print(str(string)+ " is a pretty big number!")
break
else:
print(str(string)+ " is a smaller number than expected")
break
elif string.isalpha():
print(string + " is an alphabetical character")
break
elif string == "":
print("")
else:
print(string + " is a surprise! It's neither all alpha nor all digit characters!")
break
print(str_analysis(input("Enter word or integer: ")))
There are a few things in your code that make no sense.
1:
print(str_analysis(input("Enter word or integer: ")))
You are trying to print the output of a function that has no return value
2:
It cant loop back and ask the question again, because the input is not taken inside of the function.
3:
If the string is empty you dont break the code but constantly print newlines.
Here is some code wich I think should do what you wanted:
def str_analasys():
while True:
string = input("Enter word or integer: ")
if string == '':
continue
elif string.isdigit():
if int(string) > 99:
print(str(string)+ " is a pretty big number!")
else:
print(str(string)+ " is a smaller number than expected")
elif string.isalpha():
print(string + " is an alphabetical character")
else:
print(string + " is a surprise! It's neither all alpha nor all digit characters!")
break
str_analasys()
This because when string is empty you are just printing an empty ""
elif string == "":
print("")
# break it here or take input again
# break or string = input()

Only show the last occurrence of a loop in Python

I have a program which is meant to show where the last group of letters 'ing' are within a word for example if the user inputted 'sing' it would output '2'. However when I have a word like 'singing' it outputs '2' and '5'. Whereas I want it to only display the '5':
userinput = input('Enter a word: ')
ING = 0
while ING < len(userinput):
ING = userinput.find('ing', ING)
if ING == (-1):
print('-1')
break
print('ing found at', ING+1)
ING += 3
userinput = input('Enter a word: ')
x = userinput.rfind('ing')+1
if x != 0:
print(x)
rfind is a method which searches the last occurence.

Python writing to new lines

I'm trying to get this code to ask for the user's details then save them to a .txt file with commas separating the strings. I need to write to a new line every time I run the code but adding "/n" onto the end of the strings but it gives me all the user's data on the same line. any help?
print ("enter your name, age, and year group and password")
while True:
reg_name = input("Name:"))
reg_pass = input ("Password:")
reg_age = input ("age:")
reg_group = input ("Year Group")
print ("Is this infomation correct?")
print ("Name:",reg_name)
print ("password:",reg_pass)
print ("Age:",reg_age)
print ("Year Group:", reg_group)
reg_correct = input ("[Y/N]").lower()
if reg_correct == "y":
reg_user = reg_name[0:3]+reg_age
reg_write = open("D:\\Computer science\\Computing test\\logindata.txt","a")
reg_write.write (reg_user+","+reg_name+","+reg_pass+","+reg_age+","+reg_group+"/n")
print ("Your username is:",reg_user)
reg_write.close()
break
elif reg_correct == "n":
print ("Please Re-enter your infomation")
else:
Print ("Invalid input! Please try again...!")
I think that you may want \n instead of /n. It is the actual newline character. Otherwise, it would be adding "/n" between each statement in the file. \n creates a newline.
print ("enter your name, age, and year group and password")
while True:
reg_name = input("Name:"))
reg_pass = input ("Password:")
reg_age = input ("age:")
reg_group = input ("Year Group")
print ("Is this infomation correct?")
print ("Name:",reg_name)
print ("password:",reg_pass)
print ("Age:",reg_age)
print ("Year Group:", reg_group)
reg_correct = input ("[Y/N]").lower()
if reg_correct == "y":
reg_user = reg_name[0:3]+reg_age
reg_write = open("D:\\Computer science\\Computing test\\logindata.txt","a")
reg_write.write (reg_user+","+reg_name+","+reg_pass+","+reg_age+","+reg_group+"\n")
print ("Your username is:",reg_user) # ^^^
reg_write.close()
break
elif reg_correct == "n":
print ("Please Re-enter your infomation")
else:
Print ("Invalid input! Please try again...!")
Different way :
You can also avoid escape character by using writelines() method .
reg_write.writelines (reg_user+","+reg_name+","+reg_pass+","+reg_age+","+reg_group)
You can use the print function to write your information to a file. By using the pathlib module, you can easily run some error checking to help verify your file is accessible. With Python's recent addition of format strings, printing out variables can be very easy to accomplish.
#! /usr/bin/env python3
import pathlib
def main():
while True:
username = input('Username: ')
password = input('Password: ')
year_age = input('Age: ')
grouping = input('Group: ')
print('Is this information correct?')
print(f'Username: {username}\n'
f'Password: {password}\n'
f'Age: {year_age}\n'
f'Group: {grouping}')
# noinspection PyUnresolvedReferences
answer = input('Yes or no? ').casefold()
if 'yes'.startswith(answer):
path = pathlib.Path('login_data.csv')
if path.exists() and not path.is_file():
print('Your information cannot be saved.')
else:
with path.open('at') as file:
# noinspection PyTypeChecker
print(
username, password, year_age, grouping,
sep=',', file=file
)
break
elif 'no'.startswith(answer):
print('Please enter your information so that it is correct.')
else:
print('I did not understand your answer. Please try again.')
if __name__ == '__main__':
main()

better format than using try and except

I am currently making a program that allows me to search for files in a user specified directory. But am having some trouble condensing down my try and except statements. My current code is as follows:
if os.path.exists(file_path)!= True:
print('\n******* Path does not exist. *******\n')
else:
while True:
aa = '''\nWhich search characteristics would you like to use? \n 1. Search by name: N \n 2. Search by extension: E \n 3. Search by size: S
\n Please enter your choice: '''
answer = input(aa).strip()
if answer not in 'NnEeSs' or answer=='':
print('\n***** Invalid choice. *****')
elif answer in 'Nn':
while True:
try:
name = input ('\nEnter file name: ')
rr = search_by_name(name, file_path)
if not rr:
print('\n***** File not found *****\n')
else:
break
except WindowsError:
print('\n***** Oops! Access denied.*****\n')
continue
elif answer in 'Ee':
while True:
try:
ending = input ('\nEnter the file extension: ')
rr = search_by_extention(ending, file_path)
if not rr:
print('\n***** No File(s) found *****\n')
else:
break
except WindowsError:
print('\n***** Oops! Access denied. *****\n')
continue
elif answer in 'Ss':
while True:
try:
size = int(input('\nPlease enter file size: '))
rr = search_by_size(size, file_path)
if not rr:
print('\n***** No file(s) found *****\n')
else:
break
except ValueError:
print('\n***** Enter an numeric value. *****\n')
continue
except WindowsError:
print('\n***** Oops! Access denied. *****\n')
continue
In each of these cases or overall, is there a better condensed way to write the above code? Each of the search functions return a list containing the result of the code.
I have a couple of suggestions:
1. Improve indenting.
At the top of your file you have:
if os.path.exists(file_path)!= True:
print('\n******* Path does not exist. *******\n')
else:
The else statement has to have the same indentation value as the original if.
2. Remove newlines
As you are concerned about taking space up, just remove all the newlines. I would not suggest this because your code can become confusing to read, but if you are a stickler about space, go ahead. I can count 11 newlines, so if you remove those, you've removed 1⁄5th of your file.
3. Be pythonic
If you care about the lines your code is taking up, try to be as pythonic about each line as possible, for future review/editing. Instead of if x in 'Ss': to check if x is an s or S, just do if x.lower() == 's':
4. Format try... except
Your try... except's encompass most of your code. Try to only limit them to the line that may raise the error. Here's an example:
try:
var = int(raw_input())
x = float(var)/100.0
if x == 1:
print 'YAY'
else:
print 'BOO!'
for k in range(1, x):
print 'this has looped %d times' %(k)
except ValueError:
print 'Your input is not in a number format!'
In this code, we want to make sure that the input is a number. However, that can only be checked by the first line, and everything else is rubbish. So just surround the first line, and leave the rest untouched.
Note:
Do not remove necessary components from your try... except's, or some arbitrary error may be raised.
5. Shrink your while loops
Instead of doing the following code:
while True:
try:
size = int(input('\nPlease enter file size: '))
rr = search_by_size(size, file_path)
if not rr:
print('\n***** No file(s) found *****\n')
else:
break
except ValueError:
print('\n***** Enter an numeric value. *****\n')
continue
You can do
size = input('\nPlease enter file size: ')
while size.isdigit() == False or not rr = search_by_size(size, file_path):
size = input('\nPlease enter file size: ')
Your edited code: Original: 59 lines; Edited: 33 lines:
if os.path.exists(file_path)!= True:
print('\n******* Path does not exist. *******\n')
else:
while True:
aa = '''\nWhich search characteristics would you like to use? \n 1. Search by name: N \n 2. Search by extension: E \n 3. Search by size: S
\n Please enter your choice: '''
answer = input(aa).strip()
if answer not in 'NnEeSs' or answer=='':
print('\n***** Invalid choice. *****')
elif answer.lower() == 'n':
name = input ('\nEnter file name: ')
try:
while not search_by_name(name, file_path):
name = input ('\nEnter file name: ')
except WindowsError:
print('\n***** Oops! Access denied.*****\n')
continue
elif answer .lower() == 'e':
ending = input ('\nEnter the file extension: ')
try:
while not search_by_extention(ending, file_path):
ending = input ('\nEnter the file extension: ')
except WindowsError:
print('\n***** Oops! Access denied. *****\n')
continue
elif answer.lower() == 's':
size = input('\nPlease enter file size: ')
try:
while size.isdigit() == False or not search_by_size(size, file_path):
size = input('\nPlease enter file size: ')
except WindowsError:
print('\n***** Oops! Access denied. *****\n')
continue

Resources