My question is that I was writing a program in Python 3 trying to think of a way to repeat a function from within a function, when on StackOverflow I found I can do this with the else statement:
def program():
var = (input('Pick A Car: BMW Or Nissian'))
if var == 'BMW':
print('You Picked BMW \n')
if var == 'Nissian':
print('You Picked Nissian \n')
else:
print('That's Not An Option')
program()
return
But I just do not understand how calling back a function from within a function can happen considering that the full function has not been defined yet? I appreciate the help if possible!
The function is defined. You define it right there. Assuming the indentation in your actual code is correct, your code should mostly work (you should use elif var == 'Nissian': instead of if var == 'Nissian').
Repeating a function within a function is called "recursion." There is a wealth of information about it online.
Related
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.
Error message reads, that number is not defined in line 5:
if number < int(6):
Using Qpython on android.
looper = True
def start() :
names = ["Mari", "Muri", "Kari"]
number = input("Whoms name to you want to know?")
number = int(number)
if number < int(6):
print(names[number])
else:
print("There arent that many members")
while looper :
start()
First of all, 6 is already an integer. There's no reason to type-cast it as one.
Next, you call start() after your if statement. Python reads code top-down, so the first thing it reads is your function definition, and then your if statement. Given that start() needs to be called for number to be defined, number represents nothing and cannot be compared to 6.
Well besides how you need to call the function before using the variable, you also have a simple issue of global and local variables.
Number is a local variable in the start() function and can only be used within it.
If you want to use the number variable outside the function, you can use the 'global' keyword in front of it, which should allow you to use it externally.
For example:
def func ():
global var
var = 10
func ()
print (var)
outputs 10
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()
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 have written a simple menu function that i want to call from my main_program() function. The code also includes a class called Writing which I'm trying to make an object of inside the main_program(). The reason for this is that I've heard that it's preferable to avoid global variables. However this doesn't work and I get the answer: NameError: name 'writing_obj' is not defined
When I create the object outside the main_program() everything works fine so I guess is that I have to return my object writing_obj from the main_function() somehow?
Here is the code I wrote:
class Writing:
def writing_something(self):
print("I'm learning Python ")
def menu():
while True:
val = int(input("1. Write a sentence 2. Quit "))
if val == 1:
writing_obj.writing_something()
elif val == 2:
print("The program shuts down. See ya! ")
break
else:
print("Sorry, I din't get that! ")
continue
def main_program():
writing_obj = Writing()
menu()
main_program()
writing_obj is defined within the main_program() function and is not declared to be global. I would suggest using function arguments:
...
def menu(writing_obj):
...
def main_program():
writing_obj = Writing()
menu(writing_obj)
You could instead put global writing at the beginning of the main_program() definition, but as you said, global variables are not recommended.