better format than using try and except - python-3.x

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

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)

A permanent list change(Save python file)

I am a noob in python and i need help.I have made a phonebook where you can add the contacts.But the problem is that when i exit the program the changes to the list are not saved.I want the user to be able to make permanent changes to the list.I have seen posts about a file=open("something",'w') code to do this(I think) but i dont know where to insert this code and i dont really understand what it is.Could someone help me understand what this is about..Here is the full code:
name = ["ranga","hari"]
number = [9895497777,9]
book = {name[0]:number[0],name[1]:number[1]}
def search():
print("Contacts:")
for x in book:
print(x,':',book[x])
while 1:
count = 0
a = 0
ch1 = input("search: ")
try:
ch1 = int(ch1)
except ValueError:
while a < len(name):
result = name[a].find(ch1)
if result == -1:
a = a + 1
else:
print(name[a],number[a])
a = a + 1
count = count + 1
if count == 0:
print("Not available.Try again")
continue
else:
break
ch1 = str(ch1)
while a < len(number):
sumber = str(number[a])
result = sumber.find(ch1)
if result == -1:
a = a + 1
else:
print(name[a],number[a])
a = a + 1
count += 1
if count == 0:
print("Not available.try again")
continue
else:
break
def add():
print("What is the name of the contact you want to add?")
name1 = input()
name.append(name1)
while 1:
print("What is the number of this contact?")
number1 = input()
try:
number1 = int(number1)
except ValueError:
print("Please type a number..")
continue
number.append(number1)
book[name1] = number1
break
def remoe():
print("Reference:")
for x in book:
print(x,':',book[x])
while 1:
print("What is the name of the contact you want to remove?")
name2 = input()
if name2 in book:
increment = name.index(name2)
name.pop(increment)
number.pop(increment)
del book[name2]
break
else:
print("Not available.Please try again")
while 1:
print("Contacts:")
for x in book:
print(x, ':', book[x])
print("\nWhat do you want to do?\n1.Search for a person\n2.edit the phone book\n3.exit")
choice = input()
try:
choice = int(choice)
except ValueError:
print("Type 1,2 or 3")
continue
if choice == 1:
search()
elif choice == 2:
while 1:
print("Do you want to:\n1.Add a contact\n2.Remove a contact\n3.Go back to main menu")
ch2 = input()
if ch2 in['3']:
break
else:
try:
ch2 = int(ch2)
except ValueError:
print("Type 1 or 2..")
if ch2 == 1:
add()
elif ch2 == 2:
remoe()
elif choice == 3:
exit()
else:
print("Type 1,2 or 3")
I appreciate the help.
When you choose to add a contact, it does properly add the name and number to the list. But, that is it.
When you re-run the program, the list gets re-assigned due to the first 2 lines of your code:
name = ["ranga","hari"]
number = [9895497777,9]
So, you won't see the last changes.
This is where you should maintain a file which lives outside the scope of your code, rather than a list.
You can modify your add function like this:
def add():
print("What is the name of the contact you want to add?")
name1 = input()
#name.append(name1)
# Just add the name1 variable's value to the file
with open('contacts_list.txt', 'a+') as f:
f.write(name1 + '\n')
while 1:
print("What is the number of this contact?")
number1 = input()
try:
number1 = int(number1)
except ValueError:
print("Please type a number..")
continue
#number.append(number1)
# Similarly, append the number1 variable's value to file again.
with open('contacts_list.txt', 'w+') as f:
f.write(number1)
#book[name1] = number1
with open('contacts_list.txt', 'r') as f:
print(f.read())
break
Note: You would also need to change the other functions search and remove to read and write from the file. I've just given you a taste of how things are done. You need to modify your code and make it work.
Let me know if it helps.
I took your advice and made a new text file but i still did not know how to do it but after reading ur answers i understood and at last i came to this..
removelist = []
def search():
while 1:
search = str(input("Search: "))
if search not in["exit", "Exit"]:
with open('output.txt', 'r+') as f:
line = f.readline()
while line:
data = line.find(search)
if not data == -1:
print(line.rstrip('\n'))
line = f.readline()
else:
line = f.readline()
else:
break
f.close()
def add():
print("Type the name of the contact:")
name = input()
while 1:
print("Type the number of this contact:")
number = input()
try:
number = int(number)
except ValueError:
print("Please type a number")
continue
number = str(number)
with open('output.txt', 'a+') as f:
f.write('\n' + name +' ' + number)
break
def remoe(): #this is where the problem comes in
while 1:
remove = str(input("Remove: "))
with open('output.txt', 'r+') as f:
line = f.readline()
while line:
if not remove in["Remove", "remove"]:
removelist.clear()
data = line.find(remove)
if not data == -1:
removelist.append(line) #This saves all the lines coming from the search to a
print(removelist) #removelist which can be accessed when you type in remove
line = f.readline() #But the problem is that if there is a \n at the end of the
else: #string then the remove function does not work
line = f.readline()
else:
print(removelist)
with open('output.txt', 'r') as f:
d = f.readlines()
f.close()
with open('output.txt', 'w') as f:
for i in d:
if i not in removelist:
f.write(i)
f.truncate()
f.close()
break
while 1:
with open('output.txt', 'r') as f:
data = f.read()
print("Contacts:")
print(data)
print('''What do you want to do?
1.Search for a contact
2.Edit contacts
3.Exit''')
f.close()
choice = input()
if choice in["1"]:
search()
elif choice in["2"]:
while 1:
print('''What do you wanna do:
1.Add a contact
2.Remove a contact
3.Exit to main menu''')
ch1 = input()
if ch1 in["1"]:
add()
elif ch1 in["2"]:
remoe()
elif ch1 in["3"]:
break
else:
print("Please type 1,2 or 3")
elif choice in[3]:
print("Ok bye")
else:
print("Please type 1,2 or 3")
Now the problem seems to be the remove function..if i try to remove a line with \n at the end of it then it wont work while the opp. seems to work.Any guess what i am doing here?
And thanks for the help Mayank porwal
At the first you should know name = ["ranga","hari"], number = [9895497777,9] that you have defined are in the code and you can not change those value, and after exit() they will reset to default value.
you should use of file (for example .txt file) in this issue:
1. you must create a .txt file in your project (for example Contacts.txt)
2. and write your information in there (for example in first line: Kourosh +98938....)
3. at the first step in your program you must read Contact.txt and load it in a structure like a list or dictionary (for example
>>> with open('workfile') as f:
... read_data = f.read()
>>> f.closed
)
4.now you can edit, add, remove structure.
5.and finally you can write structure in the file, before exit()
for example:
>>> with open('workfile') as f:
... f.write(s)
>>> f.closed

Python code skips try/except clause

I am working on a class assignment in which I need to raise two exceptions.
First Exception: I am supposed to raise and handle an exception if a user's entry is less than 0 or greater than 100. The code should then ask the user for the digit again.
Second Exception: If a particular file is not found, the exception requests the file name and then search happens again.
In both cases, I cannot make the exception happen. In other words, if in the first exception, I enter a digit greater than 100 or less 0, the program continues and simply doesn't record anything for this entry. If I print the user's entry, I get "none" rather than the error message that the except clause should display. Likewise in the second exception, if the file is not found, the code simply stops executing rather than firing the exception.
I have tried manually raising an exception (as in this question/answer), but that creates a traceback which I do not want-- I just want the first exception to print the error message and call a function and the second to request input and call a function.
First exception:
def grade():
#input student's average grade
avgGrade = int(input("Enter average grade: "))
try:
if avgGrade > 0 and avgGrade < 100:
return avgGrade
except ValueError:
print("Grade must be numeric digit between 0 and 100")
grade()
Second exception:
def displayGrades(allStudents):
try:
#open file for input
grade_file = open(allStudents, "r")
#read file contents
fileContents = grade_file.read()
#display file contents
print(fileContents)
grade_file.close()
except IOError:
print("File not found.")
allStudents = input("Please enter correct file name: ")
displayGrades(allStudents)
Sounds like the exercise is to raise the exception and handle it. You really need a loop for continuation rather than recursion, e.g.:
def grade():
while True:
try:
avgGrade = int(input("Enter average grade: "))
if avgGrade < 0 or avgGrade > 100:
raise ValueError()
except ValueError:
print("Grade must be numeric digit between 0 and 100")
continue # Loop again
break # Exit loop
return avgGrade
But this is contrived for the purpose of the exception, as exceptions are not really needed in this case.
For your other example this is less contrived because the downstream function raises the exception, e.g.:
def displayGrades(allStudents):
while True:
try:
with open(allStudents, "r") as grade_file:
...
except IOError:
allStudents = input("Please enter correct file name: ")
continue
break
Though I would caution mixing arg passing and user input in the same function - usually the exception would be caught and handled where the user is originally providing the file name. So in this example, it would probably be the calling function.
For your first one, you have to raise it manually as python won't guess your logic and raise it for you.
def grade():
#input student's average grade
avgGrade = int(input("Enter average grade: "))
try:
if avgGrade > 0 and avgGrade < 100:
return avgGrade
else:
raise ValueError()
except ValueError:
print("Grade must be numeric digit between 0 and 100")
return grade()
For the second one, You have to return the value in the second call.
use return displayGrades(allStudents) instead of displayGrades(allStudents)
Try this:
def get_value(data_list, index):
return data_list[index]
# Sample list data
my_list = ['a', 'b', 'c']

Keep getting "ValueError: invalid literal for int() with base 10: '' error, despite it working throughout the program

For my programming class, we have to make a trivia program that has an independent point value for each question. To do this, I added the point as a line in the text file and have this line in the code:
points = int(next_line(the_file))
I also have:
if answer == correct:
print("\nRight!")
score += points
in order to add the points to the total score.
This works all throughout the program, adding the points on after the player gets each question correct. However, at the end of the program, AFTER displaying the final score, the program says that there is a value error:
ValueError: invalid literal for int() with base 10:
I'm not sure what the error is, due to the fact that it works throughout the entire program, all the way up until the end.
Any help would be greatly appreciated, thank you.
Here is the entire code:
import sys
choice = None
while choice != "0":
choice = input("""
WELCOME TO THE TRIVIA CHALLENGE. PLEASE SELECT AN EPISODE
0: Exit Game
1: Trivia 1
2: Trivia 2
Choice: """)
if choice == "0":
print("You have chose to exit the program. Your loss.")
sys.exit()
elif choice == "1":
fileChoice = "trivia1.txt"
elif choice == "2":
fileChoice = "trivia2.txt"
else:
print("You have entered an invalid option. You are being kicked off.")
sys.exit()
def open_file(file_name, mode):
"""Open a file."""
try:
the_file = open(file_name, mode)
except IOError as e:
print("Unable to open the file", file_name, "Ending program.\n", e)
input("\n\nPress the enter key to exit.")
sys.exit()
else:
return the_file
def next_line(the_file):
"""Return next line from the trivia file, formatted."""
line = the_file.readline()
line = line.replace("/", "\n")
return line
def next_block(the_file):
"""Return the next block of data from the trivia file."""
category = next_line(the_file)
question = next_line(the_file)
answers = []
for i in range(4):
answers.append(next_line(the_file))
correct = next_line(the_file)
if correct:
correct = correct[0]
explanation = next_line(the_file)
points = int(next_line(the_file))
return category, question, answers, correct, explanation, points
def welcome(title):
"""Welcome the player and get his/her name."""
print("\t\tWelcome to Trivia Challenge!\n")
print("\t\t", title, "\n")
def main():
trivia_file = open_file(fileChoice, "r")
title = next_line(trivia_file)
welcome(title)
score = 0
# get first block
category, question, answers, correct, explanation, points = next_block(trivia_file)
while category:
# ask a question
print(category)
print(question)
for i in range(4):
print("\t", i + 1, "-", answers[i])
# get answer
answer = input("What's your answer?: ")
# check answer
if answer == correct:
print("\nRight!")
score += points
else:
print("\nWrong.")
print(explanation)
print("Score:", score, "\n\n")
# get next block
category, question, answers, correct, explanation, points = next_block(trivia_file)
trivia_file.close()
print("That was the last question!")
print("Your final score is", score)
main()
input("\n\nPress the enter key to exit.")
Another problem I have is with the way I did the sys.exit(), since it also doesn't work.
You'll get this error when you have a blank line. If you look at the error message, its telling you what the problem is (although it may not be obvious):
ValueError: invalid literal for int() with base 10:
The blank after 10: is the clue, its actually a blank line in the file.
So, just check if there is a blank line:
points_line = next_line(the_file).strip()
if points_line:
points = int(points_line)
else:
print('Got a blank line when expecting points!')

Try/Exception flow control

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)

Resources