Recipe Finder, Python 3. Definition error when saving a recipe - python

Below is the code that I have the issue with. When it comes to saving a new recipe, it comes up with an error saying that 'dish' is not defined. 'dish' is the variable that holds the recipe name. To get to this stage, the name must have already been entered, and so I fail to see why the error should occur. I would be very grateful to here of any comments and tips, as i have hit the metaphorical 'brick wall.'
import sys
recipes = []
ingredients = []
quantities = []
menu = "What would you like to do? \n 1) Make a recipe \n 2) Load a recipe \n 3) Exit \n\
"
def save_recipe(recipe, file_name):
file = open(file_name, "w")
file.write(recipe)
file.close()
def decision_functions():
interface_choice = input(menu)
if (interface_choice == "1" or "Make a recipe"):
dish = input("What do you wish to make?: ")
ingredients_loop()
elif (interface_choice == "2" or "Load a recipe"):
decision = input("What recipe do you wish to load?: ")
decision += ".txt"
file = open(decision, "r")
recipe = (file.read())
serves = int(input("How many do you wish to serve?: "))
recipe = list(recipe)
elif (interface_choice == "3" or "Exit"):
print("Goodbye!")
sys.exit
else:
print("I don't understand. . . Please select one of the above numbered options. \n\
")
decision_functions
def ingredients_loop():
ingredient = input("Name an ingredient in the recipe. Type END when done: ")
if (ingredient == "end"):
def confirm_decision():
print(ingredients)
print(quantities)
confirmation = input("Is this all?: ")
if (confirmation == "yes"):
recipe = [ingredients, "\n\
" , quantities]
file_name = dish.replace(' ', '') + ".txt"
writerecipe(str(recipe), file_name)
print("Your recipe has been saved")
decision_functions()
elif (confirmation == "no"):
print("Preparing to allow more ingredients. . .")
ingredients_loop()
else:
print("I do not understand . . .")
confirm_decision()
confirm_decision()
else:
ingredient += ":"
ingredients.append (ingredient)
amount = int(input("How much of this ingredeint is required to serve one?: "))
units = (input("What unit is this measurement in?: "))
amts = amount, units
quantities.append (amts)
ingredients_loop()
decision_functions()

You are using dish inside the ingredients_loop Which is not accessible since you have declared inside the decision_functions
What you can do is either make dish as global or pass the dish to ingredients_loop
recipes = []
ingredients = []
quantities = []
dish =""
menu = "What would you like to do? \n 1) Make a recipe \n 2) Load a recipe \n 3) Exit \n\
"
specify dish as global

Related

I want to add tkinter to this code and will do that but i don't know where to place the tkinter variables?, they will eventually be in the while true

my code should be looking for search options and appending to a list that compares to the search, all im trying to figure out is how to get tkinter in the loop, because i dont know where to put things such as the if name == "main":
stuff
from tkinter import *
ideas = ["pooop", "pooop", "yaaah"]
describe = ["A software that provides poop images", "Fart noises", "kid on crack"]
window = Tk()
window.title("Exists?")
while True:
function = input("Append or Search: ").lower().strip()
if function == "append":
appending = input("What would you like to append enter keywords/possible names..... ")
ideas.append(appending)
appending2 = input("Describe what you would like to append, please do not enter blank values as that will make "
"your software harder to find ")
describe.append(appending2)
print(ideas.index(str(appending)))
print(describe.index(str(appending2)))
searcher = input("What would you like to search for, enter keywords/possible names")
if searcher in ideas:
print(ideas)
print("description: " + describe[ideas.index(searcher)])
print(searcher in ideas)
numberOfResults = str(ideas.count(searcher))
print("0 results found")
if searcher not in ideas:
print(ideas)
print(searcher in ideas)
of = str(len(ideas))
print("0 results found of " + of)
if function == "search":
searcher = input("What would you like to search for, enter keywords/possible names")
if searcher in ideas:
print(ideas)
print("description: " + describe[ideas.index(searcher)])
print(searcher in ideas)
numberOfResults = str(ideas.count(searcher))
print(numberOfResults + " results found")
if searcher not in ideas:
print(ideas)
print(searcher in ideas)
of = str(len(ideas))
print("0 results found of " + of)
if __name__ == "__main__":
window.mainloop()
Put the code in an infinite loop and exit when a word other than append or search is entered
ideas = ["pooop", "pooop", "yaaah"]
describe = ["A software that provides poop images", "Fart noises", "kid on crack"]
while True: # infinity loop
function = input("Append or Search: ").lower().strip()
if function == "append":
pass # ... you code instead
elif function == "search":
pass # ... you code instead
else: # other input
print("That's all!")
break # exit loop

Why isn't my file writing method working?

import os
books = open(os.path.expanduser("~/Desktop/books.txt")).read()
b= books.split('\n')
del b[-1]
book={}
for i in b:
b1=i.split('\t')
book[b1[0]]=[b1[1],b1[2],b1[3]]
def all_book():
print "The Book List"
books = open(os.path.expanduser("~/Desktop/books.txt"))
print books.read()
def add_book():
print "Registering New Book"
books = open(os.path.expanduser("~/Desktop/books.txt"))
name = raw_input("Title: ")
author= raw_input("Author Name: ")
publisher =raw_input("Publisher: ")
n= int(b1[0])
n1 = n+1
newb= [str(n1), '\t', name, '\t', author,'\t', publisher]
books.writelines(newb) #Adding file to the list
newb = {}
newb[n1]=[name, author, publisher]
print 'A New Book Added!'
return newb
def del_book():
print "Deleting Books"
delnum = str(raw_input("Registered Number:"))
if delnum in book:
del book[delnum]
else:
print delnum, "Not Found"
def show_menu():
print '''
1) add new
2) all show
3) delete
4) search
5) Save/out
'''
menu_choice = raw_input('what --> ')
if menu_choice == '1':
add_book()
elif menu_choice == '2':
all_book()
elif menu_choice == '3':
del_book()
show_menu()
books = open(os.path.expanduser("~/Desktop/books.txt")).read()
Your error lies here. If you do not specify a file opening mode, Python will default to 'read' mode, meaning you cannot write to it.
The correct syntax for opening a file for writing is:
books = open('file', 'w')
This page has a table of file access modes down the page.
open() default open the file as read, and that's why you can't write your new book into the text file.

How do I access the array using the for loop in the while loop

I am working with an external file which has data in the form of:
-12345 CSEE 35000 Bart Simpson
-12346 CSEE 25000 Harry Potter
-12350 Economics 30000 Krusty The Clown
-13123 Economics 55000 David Cameron
With the first item being the ID, the second the subject, the third the salary, and the rest being the name of the person.
In part of my program I am trying to print the information of the people who have salaries between values submitted by the user. I have put all the data in a list called lecturers then I put all the salaries in a separate list called lecturers salary and tried to make them integers because at first I thought the reason the for loop wasn't working was because when trying to access them from the lectures loop I thought they might still be part of a string at this point.
I have already used a loop in my program to print all the people who teach a specific subject. This subject is submitted by the user. I tried to use a for loop again for the salaries but its not working.
print""
# To God be the Glory
lecturer = []
lecturer_salary = []
x = 0
a = " "
print ""
String = raw_input("Please enter the lecturers details: ")
print ""
def printFormat(String):
String = String.split()
lastname = String[-1]
firstnames = " ".join(String[3:-1])
name = ", ".join([lastname, firstnames])
ID_Subject = " ".join(String[0:2])
money = String[2]
print "%s,%s %s %s" % (lastname,firstnames,ID_Subject,money)
printFormat(String)
while x < len(lecturer):
lecturer_salary.append(int(lecturer [x][2]))
x = x + 1
print ""
try:
fname = input("Enter filename within " ": ")
with open(fname) as f:
for line in f:
data = line.split()
printFormat(line)
line = line.split()
lecturer.append(line)
except IOError as e :
print("Problem opening file")
print ""
print ""
answer = raw_input("Would you like to display the details of lectureers from a particular department please enter YES or NO: ")
if answer == "YES" :
print ""
department = raw_input("Please enter the department: ")
print ""
while x < len(lecturer) :
for line in lecturer:
if lecturer[x][1] == department:
a = lecturer[x]
a = ' '.join(a)
printFormat(a)
x = x + 1
**elif answer == "NO" :
print ""
answer2 = raw_input ("Would you like to know all the lecturers within a particular salary range: ")
print ""
if answer2 == "YES":
lower_bound = int(input("Please enter the lower bound of the salary range: "))
upper_bound = int(input("Please enter the upper bound of the salary range: "))
print ""
while x < len(lecturer) :
for line in lecturer_salary:
if lower_bound < lecturer_salary[x] < upper_bound :
print lecturer_salary[x]
x = x + 1**
else:
print ""
print "Please enter a valid input"
So, you have an array of lecturer and one of lecturer salary. the
for line in lecturer_salary:
is not needed - just the while followed by the if. Note that this will only print out the salary, not the lecturer details. Since x is the index to both arrays you can access lecturer[x] for the rest. In truth you don't need the lecturer_salary at all, just walk through lecturer and check:
while x < len(lecturer) :
if lower_bound < lecturer[x][2] < upper_bound :
a = lecturer[x]
a = ' '.join(a)
printFormat(a)
x = x + 1
For starters, you shouldn't name your variable with a capital letter like String or Id_Subject.
It is simpler to break code into functions and try using a dictionary or class to improve readability and extensibility.
Here is a minimal code using class:
lecturers = [] # To store Lecturer instances, which isn't necessary
class Lecturer():
def __init__(self, id, subject, salary, name):
self.id = id
self.subject = subject
self.salary = salary
self.name = name
def readfile(filename):
"""read each line in a file and yield a list of fields"""
with open(filename, "r") as f:
for line in f.readlines():
# return a list of fields
yield line.replace("\n", "").split()
def new_lecturer(detail):
"""Return a new lecturer instance from a list of fields"""
return Lecturer(detail[0],
detail[1],
detail[2],
{"firstname": detail[3],
"lastname": detail[4]
})
def print_lecturer_detail(lecturer):
"""Accept a lecturer instance and print out information"""
print "{0},{1} {2} {3}".format(lecturer.name["lastname"],
lecturer.name["firstname"],
lecturer.id,
lecturer.salary)
def main():
"""This is where all the main user interaction should be"""
fname = raw_input("Enter filename: ")
for lecturer in (readfile(fname)):
lecturers.append(new_lecturer(lecturer))
print ""
answer = raw_input("Would you like to display lecturers by department(Y/N)?: ")
if answer == "Y":
print ""
department = raw_input("Please enter the department: ")
print ""
for lecturer in lecturers:
if lecturer.subject == department:
print_lecturer_detail(lecturer)
elif answer == "N":
# implement salary code here
pass
if __name__ == '__main__':
main()
This may be an overkill now, but it's better than dealing with lists in a long run. You'll see that dealing with properties become much simpler. You may want to improve each function further and make it more modular and reusable.
#Paul Morrington has the straight answer on the while part.

PYTHON: How can I add +1 to a number in a file (txt.)

Okay so, I'm trying to make this little nifty auction program (for habbo if you've played it, but that's irrelevant.) Essentially, I have gotten pretty far with it, but my main goal is to be able to view Items (including their IDs for easy access) and to create new Items if I want.
Currently viewing items works fine, yet I'm struggling with the second goal, adding items.
I've used a bunch of different methods i've found on the internet, but none really seem to give the desired effect. I want to have a specific text document ("ID.txt") which simply starts at "0" and then each time my program is about to add an item, it adds 1 to that number in the file, so that I can call on it and give a brand new ID. So far each attempt I have it has done things like add [1] to the answer, instead of adding 1 itself.
import sys
import time
def choice1():
print("#####################################################")
print("Auction log opening")
dotDot = "..."
for char in dotDot:
sys.stdout.write(char)
time.sleep(0.5)
print("")
print("1 - Choose an item ID")
print("2 - Add an item")
print("3 - Return to start")
choices = input("Please make your choice. ")
if choices == "1" and "#1" and "one":
itemID = input("Enter item ID: ")
if itemID == "#0001":
aLog = open("auctionlist.txt")
lines = aLog.readlines()
print("#####################################################")
print("")
print(lines[0])
print(lines[1])
print(lines[2])
print(lines[3])
print("")
print("#####################################################")
elif itemID == "#0002":
aLog = open("auctionlist.txt")
lines = aLog.readlines()
print("#####################################################")
print("")
print(lines[4])
print(lines[5])
print(lines[6])
print(lines[7])
print("")
print("#####################################################")
elif choices == "2" and "#2" and "two":
## itemName = input("What's the item's name? ")
## itemBought = input("Item buy price? ")
## itemAvg = input("Item average? ")
## itemSell = input("Target sell price? ")
ID = open("ID.txt", "r+")
content = ID.readlines()
content[0] = content[0]+"1"
ID.write(str(content))
ID.close()
print("#####################################################")
print("Title: Auction House v0.1")
print("Author: Alasdair Cowie")
print("Date: 08/07/15")
print("#####################################################")
print("1 - Open the auction log.")
print("2 - Open the copy/paste log.")
print("3 - Exit the program")
oneTwoThree = input("Please make your choice. ")
if oneTwoThree == "1" and "one" and "#1" and "One":
choice1()
Open the file and read its contents:
with open(filePath) as idFile:
idString = idFile.read()
Convert the string to an int:
idNumber = int(idString)
Increase the number:
idNumber += 1
And write back that number:
with open(filePath, 'w') as idFile:
idFile.write('%d' % idNumber)
That's it.
You could use a replace method, and increment in your code,
you would search for i-1 and replace it with i or something similar.
print ("Text to search for:i-1")
textToSearch = input( "> " )
print ("Text to replace it with:i")
textToReplace = input( "> " )
print ("File to perform Search-Replace on:")
fileToSearch = input( "> " )
fileToSearch = 'D:\dummy1.txt'
tempFile = open( fileToSearch, 'r+' )
for line in fileinput.input( fileToSearch ):
if textToSearch in line :
print('Match Found')
else:
print('Match Not Found!!')
tempFile.write( line.replace( textToSearch, textToReplace ) )
tempFile.close()
input( '\n\n Press Enter to exit...' )

global name 'doc' is not defined, trouble withvcall from one function to annother

I'm having some trouble with a piece of code I'm currently writing.
With the following code I get the NameError: global name 'doc' is not defined.
def createHtml():
name = input("\nEnter the name for your HTML-page: ")
doc = open(name + ".html", 'w')
def createTitle():
print (t[0], file=doc) #<!DOCTYPE html>
print (t[1], file=doc) #<html>
print (t[2], file=doc) #<head>
title = input("Enter your title here: ")
print (" <title>",title,"</title>", file=doc)
print (t[3], file=doc) #</head>
I know it's because the doc is only defined in the createHtml-function. But how do I get it to work if I want the same doc to work when called in a different function? I cant leave it out of the createHtml-function because it will mess up my program since I have a menu which allows the user to choose from the different functions.
Like this:
while True:
menu = input("\nPress 1 to enter the file name for the HTML-page"
"\nPress 2 to enter title for the HTML-page"
"\nPress 3 to start entering code in body"
"\nPress 4 to exit\n")
if menu == "1":
createHtml()
elif menu == "2":
createTitle()
elif menu == "3":
createBody()
else:
print ("Good bye!")
break
doc.close()
And the doc is defined by the name variable in:
name = input("\nEnter the name for your HTML-page: ")
Is there anyway to get doc from the createHtml-function to my other functions?
What about wrapping the functions inside a class?
class HtmlBuilder(object):
def __init__(self):
self.doc = None
def createHtml(self):
name = input("\nEnter the name for your HTML-page: ")
self.doc = open(name + ".html", 'w')
def createTitle(self):
print (t[0], file=self.doc) #<!DOCTYPE html>
print (t[1], file=self.doc) #<html>
print (t[2], file=self.doc) #<head>
title = input("Enter your title here: ")
print (" <title>",title,"</title>", file=doc)
print (t[3], file=self.doc) #</head>
def Dispose(self):
self.doc.flush()
self.doc.close()
And just use it like this:
hb = HtmlBuilder()
while True:
menu = input("\nPress 1 to enter the file name for the HTML-page"
"\nPress 2 to enter title for the HTML-page"
"\nPress 3 to start entering code in body"
"\nPress 4 to exit\n")
if menu == "1":
hb.createHtml()
elif menu == "2":
hb.createTitle()
elif menu == "3":
hb.createBody()
else:
print ("Good bye!")
break
hb.Dispose()
At the end of the day, this is a perfect use case for Object Oriented Programming isn't it? After this, a lot of good improvements can be done.
For example:
Replace the print statements from the function to the outer code.
Make your methods testable.
Unit testing.
GOOD STUFF :D
Your function createHtml() function will need to return doc, which you can then pass to createTitle(). Something like this:
def createHtml():
name = input("\nEnter the name for your HTML-page: ")
doc = open(name + ".html", 'w')
return doc
So then in your while loop:
doc = createHtml()
and then you can pass it to the other functions:
createTitle(doc)
Note that it doesn't have to be called the same thing in each function.

Categories