So, I'm trying to take information from bookfile.txt and display information from it. So far, I've opened the file. I'm having trouble getting each line as one object of arrayBooks.
I'd like to have arrayBooks[0]="Animal Farm,1945,152,George Orwell"
Then, I'm going to use book1 = arrayBooks[0].split(',') to split it to other information, such as:
book1[0]="Animal Farm"
book1[1]=1945
book1[2]=152
book1[3]="George Orwell"
So, when I want to find the shortest book, I can compare book1[2] to book2[2] and book3[2] to do so.
My main problem is getting the information in the array and usable. Anything I've tried doesn't seem to work and gives an error in the displayAll() function.
I'm using the displayAll() as a control because I feel if I can get the information to display, I will have it to use.
bookfile.txt:
Animal Farm,1945,152,George Orwell
To Kill A Mockingbird,1960,324,Harper Lee
Pride and Prejudice,1813,279,Jane Austen and Anna Quindlen
def main():
print("Welcome!")
displayBookMenu()
populateBooks()
displayAll(populateBooks())
def displayBookMenu:
print("\n1: Display All Books")
print("2: Display Shortest Book")
print("3: Display Longest Book")
print("3: Display Oldest Book")
print("4: Display Newest Book")
print("0: End")
choice = int(input("Choice: "))
if choice == 1:
displayAll()
elif choice == 2:
displayShortest()
elif choice == 3:
displayLongest()
elif choice == 4:
displayOldest()
elif choice == 5:
displayNewest()
elif choice == 0:
exit()
else:
print("Invalid Input")
def populateBooks():
fp = open("bookfile.txt", "r")
return fp.readlines()
def displayAll(arrayBooks):
print ("\nAll Books: \n")
#THIS IS WHERE I GET ERROR vvv
print arrayBooks[0]
def displayShortest():
def displayLongest():
def displayOldest():
def displayNewest():
main()
try this:
lines = [line.strip().split(',') for line in open("books.txt")]
Using list comprehesions you can read your file into a list named lines and convert each line from your files into a list of lists.
These are the results i got when i ran it:
`lines = [line.strip().split(',') for line in open("books.txt")]
print lines
print lines[2]
print lines [2][1]`
enter code here
[['Animal Farm', '1945', '152', 'George Orwell'], ['To Kill A Mockingbird', '1960', '324', 'Harper Lee'], ['Pride and Prejudice', '1813', '279', 'Jane Austen and Anna Quindlen']]
['Pride and Prejudice', '1813', '279', 'Jane Austen and Anna Quindlen']
1813
Now there are a number of edits. Here. Make sure you looks at them carefully:
`def displayBookMenu():
print("\n1: Display All Books")
print("2: Display Shortest Book")
print("3: Display Longest Book")
print("3: Display Oldest Book")
print("4: Display Newest Book")
print("0: End")
choice = int(input("Choice: "))
if choice == 1:
displayAll(populateBooks())
elif choice == 2:
displayShortest()
elif choice == 3:
displayLongest()
elif choice == 4:
displayOldest()
elif choice == 5:
displayNewest()
elif choice == 0:
exit()
else:
print("Invalid Input")
def populateBooks():
lines = [line.strip().split(',') for line in open("books.txt")]
return lines
def displayAll(arrayBooks):
print ("\nAll Books: \n")
#THIS IS WHERE I GET ERROR vvv
for books in arrayBooks:
for each_entry in books:
print each_entry,
print
def displayShortest():
pass
def displayLongest():
pass
def displayOldest():
pass
def displayNewest():
pass
def main():
print("Welcome!")
displayBookMenu()
populateBooks()
main()
Remove displayBooks(populateBooks()) and instead have it in you if choice ==1 statement.
First, you have an error in
def displayBookMenu: #needs ()
And you can't read ArrayBooks because it'a not a global (or nonlocal) variable. I think you have problems with variable scope. Check this: Python variable scope error
Related
I am working on a stupid yet funny practice program to improve my understanding of OOP in Python.
The program is meant to randomly generate some band names from a randomly selected adjective and another randomly selected noun - producing a lot of hilarious band names.
For the most part, the program works fine, but for some reason, there are some problems with the if-statements and the while loop in the menu(self)- method all the way down in the BandList class.
My hypothesis is that there is something wrong with the nesting of the else-if statements, or that the loop doesn't manage to advance the loop when I call on the self._generateBand() method in line 60 due to some technicality I'm not aware of. Either way, I'm not sure.
However, my question is:
Why does my loop stop at the line self._writeBand() and not continue executing the code that follows? (As shown below)
done = False
while done != True:
print("\n=============== BAND NAME GENEREATOR ==================")
start = input("\nDo you want to generate a list of bandnames? (y/n): ")
if start.lower() == "y":
self._generateBand()
self._writeBand() #The loop stops here for some reason and asks the same question over and over.
#The program won't execute this part of the code.
inp = ("\nDo you want to save these band names? (y/n): ")
if inp.lower() == "y":
outfile = input("What do you want to name the file?: ")
self._saveBand(f"{oufile}.txt")
If anyone can help me fix this, I would be super grateful.
In advance: Thank you for your help.
The complete program is pasted in below
import random
class Band:
def __init__(self, name):
self._Bandname = name
def __str__(self):
return f"{self._Bandname}"
def hentName(self):
return self._Bandname
class BandList:
def __init__(self):
self._BandList = []
def _readFile(self, filename1, filename2):
with open(filename1) as infile1, open(filename2) as infile2:
lineAdjective = infile1.read().splitlines()
lineNoun = infile2.read().splitlines()
adjective = random.choice(lineAdjective)
noun = random.choice(lineNoun)
return f"{adjective} {noun}"
def _saveBand(self, filename):
with open(filename, "w") as outfile:
for j, i in enumerate(self._BandList):
outfile.write(f"Nr: {j}\t-{i}\n")
def _generateBand(self):
num = int(input("\nHow many band names would you like to generate?: "))
for i in range(num):
bandname = f"The {self._readFile('adjective.txt', 'noun.txt')}s"
self._BandList.append(Band(name= bandname))
def _writeBand(self):
print("\n========= Genererte bandname =========")
for i in self._BandList:
print(i)
#print(i.hentName())
def _deleteBand(self):
self._BandList.clear()
def _writeGoodbyeMsg(self):
print("\n============ PROGRAM TERMINATING ================")
print("\t- thanks for using the program, goodbye!")
def menu(self):
done = False
while done != True:
print("\n=============== BAND NAME GENEREATOR ==================")
start = input("\nDo you want to generate a list of bandnames? (y/n): ")
if start.lower() == "y":
self._generateBand()
self._writeBand() #This is probably where the bug is...
inp = ("\nDo you want to save these band names? (y/n): ")
if inp.lower() == "y":
utfil = input("What do you want to name the file?: ")
self._saveBand(f"{utfil}.txt")
elif inp.lower() == "n":
self._deleteBand()
inp2 = input("Do you want to generate more band names? (y/n)?: ")
if inp2.lower() == "y":
self._generateBand()
elif inp2.lower() == "n":
done = True
self._writeGoodbyeMsg()
else:
print("Unknown command, please try again")
else:
self._writeGoodbyeMsg()
done = True
if __name__ == '__main__':
new = BandList()
new.menu()
You're missing an input call on your 2nd question for saving the band names. It should be:
inp = input("\nDo you want to save these band names? (y/n): ")
It does work. You just haven't given any values in self._BandList.
Its returning "BandList": null.
I need a help with a certain situation.
We have the following code:
import random
Genre = ["Power metal", "Melodic death metal", "Progressive metal", "Rock"]
Power_metal = ["Helloween", "Dragonforce", "Hammerfall"]
Melodic_death_metal = ["Kalmah", "Insomnium", "Ensiferum", "Wintersun"]
Progressive_metal = ["Dream theater", "Symphony X"]
Rock = ["Bon Jovi", "Nirvana"]
a = ["Pumpkins united", "Halloween"]
Helloween = set(a)
Music = input("\nSelect a music genre from available: %s:" % (Genre))
def bands(Music):
while True:
if Music == "Melodic death metal":
return (Melodic_death_metal)
elif Music == "Power metal":
return (Power_metal)
elif Music == "Progressive metal":
return (Progressive_metal)
elif Music == "Rock":
return (Rock)
else:
Music = input("\nYou entered the wrong name. Please, enter again: %s:" % (Genre))
Band = input("\nReffering to chosen genre, I have bands such as: %s. Choose a specific band and I'll suggest a random song:\n" % bands(Music))
def fate(Band):
while True:
if Band == "Helloween":
if len(Helloween) != 0:
print("Suggested song: ", Helloween.pop())
break
elif len(Helloween) == 0:
print("I don't have more songs to propose. Enjoy your music")
break
fate(Band)
while True:
next = input("\nWould you like me to suggest one more song from the band of your choice ? Answer yes or no:\n")
if next == "no":
print("Enjoy your music")
break
elif next == "yes":
fate(Band)
The problem is: when we get to the point where the program has no more songs to offer, it should print: "I don't have more songs to propose. Enjoy your music"and break. But instead of this, it goes all the way to the last loop and doesn't end until I type in the console no.
Can I make somehow the statement inside loop to end program even if I type in console yes?
Cause it will keep printing:
I don't have more songs to propose. Enjoy your music.
Would you like me to suggest one more song from the band of your choice ? Answer yes or no:
Thanks for the help.
I want to save the below code output to file.txt. The problem is that my code includes many functions.
In other words, I want my output in a text file, I'm using python but I posted as js, #python
import random
Generate_Number_CHOICE = 1
Average_Calculate_CHOICE = 2
Display_Grades_CHOICE = 3
Display_Failing_Marks_CHOICE = 4
QUIT_CHOICE = 5
def display_menu():
print(' MENU')
print('1) Enter Your Marks')
print('2) Get Your Average')
print('3) Display Your Grades')
print('4) Display Failin Marks')
print('5) Quit')
def generate_number():
numbers = random.sample(range(1 ,100),30)
print(numbers)
return numbers
def average_calculate(numbers):
total = sum(numbers)
average = total // 30
print('------------------------------------')
print('Your Average is:', average)
print(" ")
def display_grades(numbers):
for mark in(numbers):
if mark >= 90:
print('------------------------------------')
print('A+',mark)
elif mark >= 80:
print('------------------------------------')
print('B+',mark )
elif mark >= 70:
print('------------------------------------')
print('C+',mark)
elif mark >= 60:
print('------------------------------------')
print('D+',mark)
else:
print('------------------------------------')
print('F',mark)
return mark
return courses_Name
def display_failing(numbers):
for number in (numbers):
if number <= 59:
print('------------------------------------')
print("you Fail in",number)
print(" ")
def main():
infile = open('philosophers.txt', 'w')
choice = 0
while choice != QUIT_CHOICE:
display_menu()
choice = int(input('Enter your choice: '))
if choice == Generate_Number_CHOICE:
numbers = generate_number()
elif choice == Average_Calculate_CHOICE:
average_calculate(numbers)
elif choice == Display_Grades_CHOICE:
mark = display_grades(numbers)
elif choice == Display_Failing_Marks_CHOICE:
display_failing(numbers)
elif choice == QUIT_CHOICE:
print('Exiting the program...')
else:
print('Error: invalid selection.')
main()
You can just replace you print statements with infile.write('text goes here'), also don't forget to close your file after you're done with it using infile.close(). Alternately you can use a with statement.
with open('philosophers.txt', 'w') as infile:
infile.write('text')
and this will close the file without explicitly calling .close.
You can also print to a file
print('text', file=infile) #python 3
print >> infile, 'text' #python 2
You can open a file (as global variable) in the beginning of your main function and in all other functions use that file handle to write whatever you want in the file.But an even better solution is to pass that file handle to each function and use the handle to write to file. Either way, don't forget to close the file at the end of the main function.
I AM NEW TO PYTHON AND CODING IN GENERAL.
So I have a program with a menu that has multiple functions in it. individually each function works fine on its own, however when i put them together they would usually not fully execute and instead stop half way or wont work at all.
EXAMPLE- the function remove wont remove what i tell it to.
def show_coffee will only show the first description and weight only and nothing else.
What can i do to make the functions fully execute?
import os
def main():
choice =''
fun=[]
while choice != 4:
menu()
choice=getUserChoice()
if choice !=4:
fun=process_choice(choice,fun)
print(fun)
print("Goodby!")
def process_choice(choice,fun):
#fun=fun1
if choice == 0:
fun=add_coffee(fun)
elif choice == 1:
fun=show_coffee(fun)
elif choice == 2:
fun=search_coffee(fun)
elif choice == 3:
fun=modify_coffee(fun)
else:
print(choice,"is not a valid choice.")
return fun
def add_coffee(fun):
another= 'y'
coffee_file=open('coffee.txt', 'a')
Description={}
while another == 'y' or another == 'Y':
print('Enter the following coffee data:')
descr=input('Description: ')
qty= int(input('Quantity (in pounds): '))
coffee_file.write(descr + '\n')
coffee_file.write(str(qty) + '\n')
print("Do you want to add another record?")
another = input("Y=yes, anything else =no: ")
return fun
coffee_file.close()
print('Data append to coffee.txt.')
def show_coffee(fun2):
coffee_file=open ('coffee.txt', 'r')
descr=coffee_file.readline()
while descr != "":
qty= str(coffee_file.readline())
descr=descr.rstrip('\n')
print('Description:', descr)
print('Quantity:', qty)
descr= coffee_file.readline()
fun=fun2
return fun
coffee_file.close()
def search_coffee(fun3):
found=False
search =input('Enter a description to search for: ')
coffee_file=open('coffee.txt', 'r')
descr=coffee_file.readline()
while descr != '':
qty= float(coffee_file.readline())
descr = descr.rstrip('\n')
if descr== search:
print('Description:', descr)
print('Quantity:', qty)
found=True
descr=coffee_file.readline()
fun=fun3
return fun
coffee_file.close()
if not found:
print('That item was not found in the file.')
def modify_coffee(fun4):
found=False
search=input('Which coffee do you want to delete? ')
coffee_file=open('coffee.txt', 'r')
temp_file=open('temp.txt', 'w')
descr=coffee_file.readline()
while descr != '':
qty=float(coffee_file.readline())
descr=descr.rstrip('\n')
if descr !=search:
temp_file.write(descr + '\n')
temp_file.write(str(qty) + '\n')
else:
found=True
descr=coffee_file.readline()
fun=fun4
return fun
coffee_file.close()
temp_file.close()
os.remove('coffee.txt')
os.rename('temp.txt', 'coffee.txt')
if found:
print('The file has been update.')
else:
print('The item was not found in the file.')
def menu():
print('''
0. Add or Update an entry
1. Show an entry
2. Search
3. remove
4. Remove number
''')
def getUserChoice():
choice=-1
while choice <0 or choice > 3:
print("Please select 0-3: ",end='')
choice=int(input())
return choice
You are defining functions but this does not call a function. The standard way to do this in Python is use the if __name__=="__main__": statement at the bottom of a file. When the file is executed (instead of functions/classes being imported by another script) the code block within the scope of if __name__=="__main__": is executed.
Get comfortable with this, it's useful and clean :) Good read - What does if __name__ == "__main__": do?
So, for example...
At the bottom of your file...
if __name__=="__main__":
main()
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.