I'm fairly new to Python, I'm learning it at school and I've been messing around with it at home, I'd like to learn it better for when GCSE's hit just to make it easier.
I'm having an issue with the code below:
def takeinfo():
print("To begin with, would you like to write your file clean? If you're making a new file, yes.")
choice=input()
if 'Y' or 'yes' or 'Yes' or 'YES' in choice:
print("What would you like to write in the file? \n")
information=input()
writeinfo()
else:
exit()
def writeinfo():
a=open('names.txt','wt')
a.write(information)
a.close()
takeinfo()
When I type 'Yes' to be taken to the writeinfo() definition, it doesn't write the information I'm asking it to because it's unassigned, even after typing something in the takeinfo() definition? Any help would be appreciated. I understand this is simple, but I've looked at other questions and I can't seem to find what's wrong with my code.
Thankyou.
def writeinfo():
a=open('names.txt','wt')
a.write(information)
a.close()
the "information" needs to be passed into the writeinfo function
should be:
def writeinfo(information):
a=open('names.txt','wt')
and above, when the function is called:
print("What would you like to write in the file? \n")
information=input()
writeinfo(information)
You will need to pass the argument on like this:
def takeinfo():
# same as before
information=input()
writeinfo(information)
# else stays the same
def writeinfo(information):
# rest remains the same...
takeinfo()
Or just change information into the global scope using global.
And a hint for you:
if 'Y' or 'yes' or 'Yes' or 'YES' in choice:
Wouldn't work as you would've expected. You can do some extensive learning to figure out why it will always be True even if the user inputted "No".
other answers show good functional style (pass information to the writeinfo() function)
for completeness' sake, you could also use global variables.
the problem you are facing is, that the line
information=input()
(in takeinfo()) will assign the input to a local variable, that shadows the global variables of the same name.
in order to force it to the global variable, you have to explicitely mark it as such, using the global keyword.
other problems
input vs raw_input
input() in python3 will just ask you to input some data.
however, in Python2 it will evaluate the user-data. on py2 you should therefore use raw_input() instead.
has the user selected 'yes'?
there's another problem with your evaluation of choice (whether to write to file or not).
the term 'Y' or 'yes' or 'Yes' or 'YES' in choice always evaluates to true, since it is really interpreted as ('Y') or ('yes') or ('Yes') or ('YES' in choice), and bool('Y') is True.
instead, you should use choice in ['Y', 'yes', 'Yes', 'YES'] to check whether choice is one of the items in the list.
you can further simplify this by normalizing the user answer (e.g. lower-casing it, removing trailing whitespace).
solution
try:
input = raw_input
except NameError:
# py3 doesn't know raw_input
pass
# global variable (ick!) with the data
information=""
def writeinfo():
a=open('names.txt','wt')
a.write(information)
a.close()
def takeinfo():
print("To begin with, would you like to write your file clean? If you're making a new file, yes.")
choice=input()
if choice.lower().strip() in ['y', 'yes']:
print("What would you like to write in the file? \n")
global information
information=input()
writeinfo()
else:
exit()
Related
I'm extremely new to Python and working on my first text-based game. In this game, I would like player to choose from a list of characters. In the course of the game, I would also like to give the player the ability to change the character (which ultimately affects the outcome of the game). I'm unable to understand what I need to do to ensure the new choice of character is saved appropriately. Below is a stripped down version of the code:
def identity_choice():
identity = input("""Your options are:
1. Ordinary Tourist
2. Chef
Please choose a number""")
if identity == "1":
print("You now look like a tourist!")
return identity
elif identity == "2":
print("You are now a chef")
return identity
else:
print("Sorry, I don't understand that.")
return identity_choice()
def action(identity):
if identity == "1":
print("You can't do what you need to as a tourist")
response = input("Would you like to change your disguise?")
if "y" in response:
identity_choice()
else:
print("You have chosen to retain your identity")
identity = identity_choice()
action(identity)
The variable "identity" is used only local to the function(s). If you need the variable global, just declare the variable outside all functions, and inside the functions you enter the line "global identity".
Short Answer
All you need to do is reassign the identity variable, if this is the way you are choosing to keep track of the players identity. For example:
if "y" in response:
identity = identity_choice()
After this you can return identity if you would like, or you may, as the other answer suggested, declare global identity inside the action function description. This way, the identity variable is shared throughout the entire script.
Longer Answer
Actually won't be that long, but this seems like a great place to learn some object oriented programming. You stated that you're just starting, so if it's too early, then don't bother just yet, you'll get there!
However, a nice way to set this up could be to instantiate users as an object of some class, such as user, and then this class could either have a second class identity which inherits from the user class. Or, the user class could simply have a variable called identity, which can be changed with a simple function. Here is a very brief and incomplete example:
class user:
def __init__(self):
pass # here you could call the choose identity function, or just
# initialize with some default identity
def choose_identity():
#the function you wrote above asking the user to choose their identity
Hope this helps a bit, I tried to keep it very simple
I don't exactly understand what you mean.
I assume that the problem is in the "action(identity)" function that the new identity is not saved in case the user chooses "y".
Change it into:
def action(identity):
if identity == "1":
print("You can't do what you need to as a tourist")
response = input("Would you like to change your disguise?")
if "y" in response:
return identity_choice()
else:
print("You have chosen to retain your identity")
return identity
Then, when you call action, do it like this:
identity = action(identity)
I am a newbie in Python programming and I would like to understand better the logic of programming. The code below is intended to create a function that assigns its parameters to a dictionary, prompt the user about an artist and a title name, call the function back passing the arguments (given by the user) to the parameters and print the function (the dictionary).
def make_album(artist, album_name):
entry = {'name' : artist, 'album' : album_name}
return entry
while True:
print("\nPlease, write your fav artist and title: ")
print("\nType 'q' to quit.")
band_name = input('Artist name: ')
if band_name == 'q':
break
title_name = input('Title name: ')
if title_name == 'q':
break
comp_entry = make_album(band_name, title_name)
print(comp_entry)
The code runs perfectly. But there are two points that I can not understand:
Why do I need the 'return entry' line? The function creates a dictionary and it is done. Why a return?
Why do I need to create a variable in the end, assign the result of the function and print it? There is already a variable (entry) addressed as the dictionary! I would like to just write instead:
make_album(band_name, title_name):
print(entry)
I know, the code will not run, but I would be very happy with some words explaining me the reason of why these 2 points.
entry is defined inside the function, so it cannot be accessed outside of it.
Check this article about closures
http://www.trytoprogram.com/python-programming/python-closures/
What you have to understand is the concept of scope in python. This article is a good place to start.
You can directly print the value this way too
print(make_album(band_name, title_name))
The variable comp_entry is used to store the value returned from the make_album function. So, if you want a function to return back a value on calling the function, provide a return statement
It will print None if no return is provided.
For my homework assignment, I'm trying to think of a way to check for user input without using the if statement.
This would be how the algorithm is implemented with an "if" statement
if userInput == "books":
printBooks()
else:
addBooks()
Is there a way to implement the same thing without using an if statement?
If you just do not want to see if in the code, this is the way to do:
func = {"book": printBooks}
func.get(userInput, addBooks)()
You put function as an object to a dict, retrieve it based on user input as the key, with a default fallback, then call the function.
And, yes, this is a bad approach in practice.
Don't ever see a need for this, but:
(addBooks, printBooks)[userInput == "books"]()
For python you can use like this
bookData = printBooks() if userInput == "books" else addBooks()
I am still working on the same encryption program before and I am currently stuck.
choice = ""
def program (str,my_fn):
global i
i=0
while i<len(str):
my_fn
i += 1
def encrypt(my_result):
message.append(ord(answer[i]))
while choice != "Exit":
choice = input("Do you want to Encrypt, Decrypt, or Exit?\n")
if choice == "Encrypt":
answer = input("What would you like to encrypt:\n")
message = []
program(answer,encrypt(message))
print (answer)
print (message)
So the first part of the program is simply asking the user if they wish to Encrypt, Decrypt, or Exit the program, this part works perfectly fine. However, my issue is with the functions. Function "program" is intended to serve as a repeater for the inner function for every single letter in the string. However, when I try to run the program, it continues to tell me that "i" isn't defined for the "encrypt" function and does nothing. I am certain I set "i" as a global variable so why isn't this working. In case you are wondering why I chose to make two functions, it is because I will later have to use function "program" multiple time and for this specific assignment I am required to use functions and abstractions. Thanks!
Add one line after your first line
choice = ""
i = 0
The keyword global means you declare an access to a global name.
Also, using a global variable is almost never a good idea. You may want to find another way to design your function.
The line program(answer,encrypt(message)) doesn't do what you want it to do. Rather than passing the function encrypt and its argument message to program (which can call it later), it calls the function immediately. It would pass the return value to program instead, but since encrypt(message) doesn't work without i defined, you get an exception instead.
There are a few ways you could fix this. By far the best approach is to not use global variables in your functions, and instead always pass the objects you care about as arguments or return values.
For instance, you could pass a function that encrypts a single letter to another function that repeatedly applies the first one to a string (this would be very much like the builtin map function):
def my_map(function, string):
result = []
for character in string:
result.append(function(character))
return result
def my_encryption_func(character):
return ord(character)
If you really want to stick with your current architecture, you could make it work by using functools.partial to bind the answer argument to your encrypt function, and then call the partial object in program:
from functools import partial
def program (str,my_fn):
global i
i=0
while i<len(str):
my_fn() # call the passed "function"
i += 1
def encrypt(my_result):
message.append(ord(answer[i]))
choice = ""
while choice != "Exit":
choice = input("Do you want to Encrypt, Decrypt, or Exit?\n")
if choice == "Encrypt":
answer = input("What would you like to encrypt:\n")
message = []
program(answer, partial(encrypt, message)) # pass a partial object here!
print (answer)
print (message)
I am very new to Python, as you can probably tell from the code. To begin, I am trying to have the user input their name and store that in a global variable that I can access all throughout my code...preferably named uName.
What's happening is during the loop cycle, it asks the user 'Is this your name?' after they input the first response. If I hit type anything but 'yes' or 'Yes', it will re-ask them to input the name. BUT, when they finally hit 'Yes', the program prints the very first name they entered.
Also, any tips on code structure or wording is helpful...
game.py
from decisions import *
import decisions
global globalname
globalname = ''
def gameEngine(uName):
looper = 0
while looper == 0:
print ('You said your name is, ') + uName + ('...')
clarifier = raw_input('Is that correct?\n')
if clarifier == 'yes' or clarifier == 'Yes':
namePrinter(answer)
else:
decisions.userDecisions(username)
def namePrinter(uName):
print uName
gameEngine(answer)
decisions.py
username = ''
def userDecisions(inputs):
response = raw_input("Please enter your name...\n>>> ")
return response
answer = userDecisions(username)
The specific issue that you are encountering is that you are first running the contents of decisions.py though the import statement in game.py. Through that, you have set the variable "answer" to be equal to the first name that the user inputs.
Then you are calling the gameEngine function in game.py, supplying the "answer" variable from decisions.py as the argument, which is stored in "uName". Upon the user entering another name the name is not stored anywhere and is thrown out with the following line.
decisions.userDecisions(username)
You can assign the return of that statement to a variable such as "uName", and that will get you closer to what you want to do.
uName = decisions.userDecisions(username)
The next issue is that when you are printing out the name, you are printing out the variable "answer" as opposed to "uName". This is what is mainly causing the issue of the first name always being printed out.
namePrinter(answer)
This could be resolved by passing in the "uName" variable instead.
namePrinter(uName)
Also if you want the final chosen name to be stored in the global variable you can assign the final user chosen name to the gloabl variable after the user confirms that the nameis correct.
globalname = uName
However, you may want to be careful about a few parts of the structure of your code.
First, you may want to try not to use global variables. Instead you should be passing around the name though the functions which use it. If you have other player information that you need to access often, you can create a Player class and object to store that information in a single object which can be passed around into functions as needed.
Second, as the userDecisions function does not use its arguement "inputs", you can remove that arguement, as it isn't used.
Third, you may want to be careful about running code through import statements alone. Generally when you are importing a source file, you should be importing the functions, and not rely upon imports to directly run code. For example you can remove the non-function lines of decisions.py and simply run the following in game.py instead.
gameEngine(decisions.userDecisions())
I reccomend that you look up some resources on functions and passing arguement in Python, as they might be able to explain the underlying concepts a bit better.
You have screwed up with the variables and their scope. Read more about them here.
To give you a perspective regarding the scope of variables concisely, look at this code snippet:
# This is a global variable
a = 0
if a == 0:
# This is still a global variable
b = 1
def my_function(c):
# this is a local variable
d = 3
print(c)
print(d)
# Now we call the function, passing the value 7 as the first and only parameter
my_function(7)
# a and b still exist
print(a)
print(b)
# c and d don't exist anymore -- these statements will give us name errors!
print(c)
print(d)
Regarding your code, you may want to have a look at these issues:
The answer variable is not accessible in the game.py module.
So is the case with username variable in the decisions.userDecisions(username) call.
The decisions.userDecisions(username) call in the gameEngine(uName) method is not storing the response to any variable and hence the response will be lost.
You are declaring global variable globalname but not assigning any value to it (of course other than '').
P.S.: I was tempted to do your homework for you, but then probably this is good enough information for you to learn more. ;)