I don't understand how I am getting this error, can someone help:
import time
import os
import xlwt
from datetime import datetime
num = 0
def default():
global num
global model
global partnum
global serialnum
global countryorigin
time.sleep(1)
print ("Model: ")
model = input()
print ()
print ("Part number: ")
partnum = input()
print()
print ("Serial Number: ")
serialnum = input()
print ()
print ("Country of origin: ")
countryorigin = input()
print ("Thanks")
num = num+1
xlwt()
def xlwt():
print ("Do you want to write to excel?")
excel = input()
if excel == "y" or "yes":
excel()
else:
print ("Bye")
sys.exit()
def excel():
print ("Enter a spreadsheet name")
name = input()
wb = xlwt.Workbook()
ws = wb.add_sheet(name)
ws.write(0,0,"Model")
ws.write(0,1,"Part Number")
ws.write(0,2,"Serial Number")
ws.write(0,3,"Country Of Origin")
ws.write(num,0,model)
ws.write(num,1,partnum)
ws.write(num,2,serialnum)
ws.write(num,3,countryorigin)
ws.save(name)
def custom():
print()
def main():
print ("Welcome")
print ()
print ("The deafult catagories are: Model, Part Number, Serial Number,"
"country of origin")
time.sleep(1)
print()
dorc()
def dorc():
print ("Would you like to use the default or custom?")
dorc = input ()
if dorc == "default":
default()
elif dorc == "custom":
custom()
else:
print ("Invalid input")
dorc()
main()
When I execute this, I get an error str object is not callable.
You have both a function named excel() and a local variable named excel that you assigned a string to.
You can't do that and expect the function to still be available. The local name excel masks the global, so excel() tries to call the string result that input() returned.
Rename your variable:
print ("Do you want to write to excel?")
choice = input()
if choice in ("y", "yes"):
excel()
Note that I also corrected your variable test; excel == "y" or "yes" does not do what you think it does, programming language logic is not quite the same as English grammar rules. See Why does `a == b or c or d` always evaluate to True?
Next, you make the same mistake by using the name xlwt for both a module you import and a function:
import xlwt
# ...
def xlwt():
# ...
Both the module and the function are global names, and the name can only point to either the module you imported or the function you created, not both at the same time. Rename your function to something else, otherwise the following line will fail too:
wb = xlwt.Workbook()
because xlwt is bound to your function as that was defined later than the module import.
Related
I get this error when I run my code and reach the csv file part:
line 96, in fieldnames
self._fieldnames = next(self.reader)
io.UnsupportedOperation: read
My code:
import csv
username = ""
global enteruser
global username
def user():
age = input("What is your age:")
year = input("What is your year group?")
name = input("What is your name?")
username = name+age+year
return username
def username_validator():
with open('usernames.csv', 'ab') as file:
reader = csv.DictReader(file)
for row in reader:
print(row)
if enteruser or username == row["usernames"]: # if the username shall be on column 3 (-> index 2)
print ("is in file")
with open("user1.csv","ab") as quiz:
quizreader = csv.DictReader(quiz,delimiter=",")
for row in quizreader:
print(row["name"])
else:
print("doesnt work")
isuser = input("Do you have a username?")
if isuser == ("yes" or "Yes"):
enteruser = input("Enter username:")
username_validator()
elif isuser == ("no" or "No"):
user()
else:
None
print(username)
Not sure if this is what is causing your problem, but make sure to be careful with your use of global variables here. As your code stands now, it will always print an empty string at the last line, since you never update username globally. As a rule of thumb, try to avoid using global variables when possible, and instead pass those variables as arguments to the functions.
Unless you explicitly tell your functions to use global variables, it will default to creating local variables. So here:
def user():
age = input("What is your age:")
year = input("What is your year group?")
name = input("What is your name?")
username = name+age+year
return username
We are actually not doing anything to the global variable username, but rather simply creating a new local variable within the function which is returned. To update the global variable, either define it as global within the function (shown below):
def user():
global username
age = input("What is your age:")
year = input("What is your year group?")
name = input("What is your name?")
username = name+age+year
Alternatively, leave the function unchanged, and simply update the variable when you call the user() function, as follows:
elif isuser == ("no" or "No"):
username=user()
else:
None
print(username)
EDIT: Take a close look at your if statements, read the link posted in the comments under OP.
Your error is caused by your file opening / closing.
You're trying to read from a file not opened for it.
From the python built in functions open function open has a declaration like:
open(name[, mode[, buffering]])
Here the arguments you can use are r: reading, w: writing, a: appending r+: read/write, w+: read/write, and a+: append/write for the mode. To these a binary tag can be added to the end like r+b
For your code you'll want to change your open lines from
with open("user1.csv","ab") as quiz:
to
with open('user1.csv', 'a+b') as quiz:
So really all you need is that + to allow append and read
My task is to create a quiz for primary school children. The quiz bit works fine. But I must time how long the child takes and store their 'username' 'correctAnswers' and 'timeTaken' into a .txt file for the specific class the child is in. To do that I ask the child their class number and store their information into the file that was specifically made for that class.
The problems I in counter are:
The time isnt being rounded even though I have timeTaken = round(etime)in my code
raw_input not being defined (I have no idea how else to define it)
The message "Sorry, we can not save your data as the class you entered is not valid." comes up even when a valid class number has been entered.
Ive searched everywhere but with no luck. Any help at all would be greatly appreciated.
import time
import random
import math
def test():
num1=random.randint(1, 10)
num2=random.randint(1, num1)
ops = ['+','-','*']
operation = random.choice(ops)
num3=int(eval(str(num1) + operation + str(num2)))
print ("What is {} {} {}?".format(num1, operation, num2))
userAnswer= int(input("Your answer:"))
if userAnswer != num3:
print ("Incorrect. The right answer is {}".format(num3))
return False
else:
print("correct")
return True
username=input("What is your name?")
print ("Welcome {} to the Arithmetic quiz".format(username))
usersClass = input("Which class are you in? (1,2 or 3)")
raw_input("Press Enter to Start...")
start = time.time()
correctAnswers=0
for question_number in range(10):
if test():
correctAnswers +=1
print("{}: You got {} answers correct".format(username, correctAnswers))
end = time.time()
etime = end - start
timeTaken = round(etime)
print ("You completed the quiz in {} seconds".format(timeTaken))
if usersClass == 1:
with open("class1.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
elif usersClass == 2:
with open("class2.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
elif usersClass == 3:
with open("class3.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
else:
print("Sorry, we can not save your data as the class you entered is not valid.")
The return value of input is a str object:
>>> usersClass = input("Which class are you in? (1,2 or 3)")
Which class are you in? (1,2 or 3)3
>>> type(usersClass)
<class 'str'>
As a result, your subsequent checks against int objects will evaluate to False (ie, '3' != 3) resulting in what you are seeing.
The conditions of comparing which usersClass the user has selected would need to compare the same type to ensure equality. This means you could convert your return value of input to an int and continue to compare usersClass to an int which would satisfy your comparison as your code is written now,
usersClass = int(input("Which class are you in? (1,2 or 3)"))
or change the conditionals to compare usersClass to the str representation of 1, 2 and 3.
if usersClass == '1':
with open("class1.txt","a+") as f:
f.write("{}:Scored {} in {} seconds".format(username,correctAnswers,timeTaken))
...
As to the problem you are experiencing with raw_input using Python 3, it has been renamed to input: (taken from What's New in Python 3.0)
PEP 3111: raw_input() was renamed to input(). That is, the new input()
function reads a line from sys.stdin and returns it with the trailing
newline stripped. It raises EOFError if the input is terminated
prematurely. To get the old behavior of input(), use eval(input()).
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.
I keep getting the error message "global name 'user_input' not defined. new to python and to SO, hope you can help. Here's my code. Sorry if it's a mess. just starting out and teaching myself...
def menu():
'''list of options of unit types to have converted for the user
ex:
>>> _1)Length
_2)Tempurature
_3)Volume
'''
print('_1)Length\n' '_2)Temperature\n' '_3)Volume\n' '_4)Mass\n' '_5)Area\n'
'_6)Time\n' '_7)Speed\n' '_8)Digital Storage\n')
ask_user()
sub_menu(user_input)
def ask_user():
''' asks the user what units they would like converted
ex:
>>> what units do you need to convert? meter, feet
>>> 3.281
'''
user_input = input("Make a selection: ")
print ("you entered", user_input)
#conversion(user_input)
return user_input
def convert_meters_to_feet(num):
'''converts a user determined ammount of meters into feet
ex:
>>> convert_meters_to_feet(50)
>>> 164.042
'''
num_feet = num * 3.28084
print(num_feet)
def convert_fahrenheit_to_celsius(num):
'''converts a user determined temperature in fahrenheit to celsius
ex:
>>> convert_fahrenheit_to_celsius(60)
>>> 15.6
>>> convert_fahrenheit_to_celsius(32)
>>> 0
'''
degree_celsius = (num - 32) * (5/9)
print(round(degree_celsius, 2))
def sub_menu(num):
'''routes the user from the main menu to a sub menu based on
their first selection'''
if user_input == '1':
print('_1)Kilometers\n' '_2)Meters\n' '_3)Centimeters\n' '_4)Millimeters\n'
'_5)Mile\n' '_6)Yard\n' '_7)Foot\n' '_8)Inch\n' '_9)Nautical Mile\n')
ask = input('Make a selection (starting unit)')
return
if user_input == '2':
print('_1)Fahrenheit\n' '_2)Celsius\n' '_3)Kelvin\n')
ask = input('Make a selection (starting unit)')
return
When you do:
user_input = input("Make a selection: ")
Inside the ask_user() function, you can only access user_input inside that function. It is a local variable, contained only in that scope.
If you want to access it elsewhere, you can globalise it:
global user_input
user_input = input("Make a selection: ")
I think what you were trying was to return the output and then use it. You kind of got it, but instead of ask_user(), you have to put the returned data into a variable. So:
user_input = ask_user()
THere's no need to globalise the variable (as I showed above) if you use this method.
In your menu function, change the line that says ask_user() to user_input = ask_user().
I'm learning Python via book and internet. I'm trying to keep score of a game in a separate class. In order to test my idea, i've constructed a simple example. It looks too complicated for some reason. Is there a simpler/better/more Pythonic way to do this?
My code is as follows:
import os
class FOO():
def __init__(self):
pass
def account(self, begin, change):
end = float(begin) + float(change)
return (change, end)
class GAME():
def __init_(self):
pass
def play(self, end, game_start):
os.system("clear")
self.foo = FOO()
print "What is the delta?"
change = raw_input('> ')
if game_start == 0:
print "What is the start?"
begin = raw_input('> ')
else:
begin = end
change, end = self.foo.account(begin, change)
print "change = %r" % change
print "end = %r" % end
print "Hit enter to continue."
raw_input('> ')
self.play_again(end, game_start)
def play_again(self, end, game_start):
print "Would you like to play again?"
a = raw_input('> ')
if a == 'yes':
game_start = 1
self.play(end, game_start)
else:
print "no"
exit(0)
game = GAME()
game.play(0, 0)
Here's how I would format your code:
import os
class Game(object):
def play(self, end, game_start=None):
os.system("clear")
change = input('What is the delta? ')
# Shorthand for begin = game_start if game_start else end
begin = game_start or end
end = float(begin + change)
print "change = {}".format(change)
print "end = {}".format(end)
self.play_again(end, game_start)
def play_again(self, end, game_start):
raw_input('Hit enter to continue.')
if raw_input('Would you like to play again? ').lower() in ['yes', 'y']:
self.play(end, game_start)
else:
exit(0)
if __name__ == '__main__':
game = Game()
game.play(0, 0)
And a few tips:
I wouldn't create a new class that contains only code to perform one specific task. If the class doesn't take arguments or doesn't simplify your code, don't create it. Your Game class is an exception, however, as you would probably add more code to it.
In Python, classes are written in CamelCase. Global constants are usually written in UPPERCASE.
raw_input() returns a string. input() returns the string evaluated into a Python object.
I asked the question a better way and got what I was looking for here:
python: how do I call a function without changing an argument?