Python not accepting function variable - python

Whenever I run the code, python comes up with the error message:
Traceback (most recent call last):
File ""/Users/jim/Desktop/Python/TextWindow.py", line 7, in module
Read(name)
NameError: name 'name' is not defined
def Writeline(string):
print(string)
def Read(name):
name = input()
Read(name)
Writeline(name)

I am assuming that you want Read to read in a string that you will then pass to Writeline. In that case, Read has to return a value. Python strings are immutable, so you have to return the string you read to access it outside the function:
def Writeline(string):
print(string)
def Read():
return input()
name = Read()
Writeline(name)
Edit
Keep in mind that input() does different things in Pythons 2 and 3. In Python 3, it does what you appear to want. In Python 2 raw_input() is the function that reads in input. input() will attempt to evaluate anything you type as a line of Python code.

First, go through the link that #Erica provided as a comment.
There's a few things going wrong here.
You haven't actually defined the variable "name" on a scope that is able to be used.
You are passing in name to function Read(), when you probably don't want to pass in any variable to begin with.
I think you want raw_input(), not input() (This only applies to python 2.x, as I did not see the 3.x tag)
What you need to do is assign the variable "name" to be the return of the Read() function.
Such as the following:
def WriteLine(s):
print(s)
def Read():
r = raw_input()
return r
name = Read()
WriteLine(name)

Related

Create dynamic function in python?

I got NameError for calling test_gobject, but the funny thing is I never called this function name. I called test_gobjectpy()
Can you explain it to me why Python decide to call the wrong function name (see error output)
Maybe it has some problems because I have a string with the same name as function?!
file name test_dyn_fun.py
second_path = ['test_gobject.py', 'st1.py', 'test_show_desktop.py', 'download_img.py', 'test_dump.py']
print("second_path", second_path)
print()
for i in second_path:
#func = create_dyn_func(i)
tmp = i.replace(".", "") #rm dot for function name
print("tmp =", tmp)
exec(f"def {tmp}(): print({i})")
print()
print(dir(test_gobjectpy))
print()
print(locals())
test_gobjectpy()
Error output:
Traceback (most recent call last):
File "/home/manta/Coding/test_dyn_fun.py", line 13, in <module>
test_gobjectpy()
File "<string>", line 1, in test_gobjectpy
NameError: name 'test_gobject' is not defined
In your loop you create functions, the first one created is effectively created like this:
i = 'test_gobject.py'
tmp = 'test_gobjectpy'
exec(f"def {tmp}(): print({i})")
So, it's as if you ran:
exec("def test_gobjectpy(): print(test_gobject.py)")
For Python to print test_gobject.py, it tries to access an object called test_gobject and its attribute .py.
That's what is causing the error. The fact that test_gobject.py looks like a filename to you doesn't matter, it's just names of variables to Python, the way you wrote it.
What would you expect to happen if you called this function?
def test_gobjectpy():
print(test_gobject.py)
More in general, as a beginning programmer, it's generally best to stay away from stuff like exec() and eval(). It's very common for new Python programmers to think they need this, or that it somehow solves a problem they have, but it's generally the worst solution to the problem and rarely actually a good solution at all. (not never, just rarely)

Using functions in a dictionary for a menu

I am trying to create a simple menu by utilizing a dictionary instead of a series of if, elif statements. My problem is the functions being called when I declare them as the definition within the dictionary. Also I'm running into an error when trying to call on the dictionary.
I know that I'm missing something with the declaration. It doesn't matter what I put in the definition, if it's executable code then it executes when declared instead of when I call on it.
As far as the problem with calling on the dictionary I'm totally lost, from everything I've read I believe I'm doing it correctly. I've included an overly simplified version of what I'm trying to do that replicates the problems I'm having.
def hello():
print("Hello")
def goodbye():
print("Goodbye")
options = { '1' : hello(),
'2' : goodbye()}
chosen = '1'
options[chosen]()
This is what I get when the above is executed.
Hello
Goodbye
Traceback (most recent call last):
File "main.py", line 12, in <module>
options[chosen]()
TypeError: 'NoneType' object is not callable
And I should just see this.
Hello
Simply remove the parentheses from the functions in the dictionary. Leaving them there causes the functions to be called when the dictionary is declared.
Furthermore you get an error because the values you put into the dictionary are the return values of the functions, i.e., None, and calling None() gets you nowhere ;-)
Just assign the function name as the values in the dictionary
def hello():
print("Hello")
def goodbye():
print("Goodbye")
options = {'1': hello,
'2': goodbye}
chosen = '1'
options[chosen]()

Ask user for function name and then print .__doc__, isn't working

I am trying to make a script in Python, that when executed, asks the user for a function name and prints the function .__doc__
For example:
>>> print abs.__doc__
abs(number) -> number
Return the absolute value of the argument.
The problem is, it doesn't work with raw_input. The following is my code and what happens when it gets executed.
Code:
f = raw_input("Your function: ")
print f.__doc__
Execution:
Your function: abs
str(object='') -> string
Return a nice string representation of the object.
If the argument is a string, the return value is the same object.
What am I doing wrong?
Well you ask to print the __doc__ of f and f is in this case something like 'abs'. So you call 'abs'.__doc__ which is the __doc__ of a string.
Now you can however query for a builtin function with:
func = getattr(__builtins__,f)
print func.__doc__
this will however only work for builtin functions. You can also look for globals() or locals() which are dictionaries storing the global and local variables respectively.
As others have said, your problem is trying to use the string reply from raw_input() as a function object. You could get the function object by calling getattr(), but you need to known which module it is in. OK, so you could go through the global namespace looking for it, but there is a much simpler solution, just use pydoc:
f = raw_input("Your function: ")
help(f)
In this case, abs is a method that you're querying the __doc__ on. The raw_input is converting the input value to a string, so what you're really executing the __doc__ on is a string.
You get the same results if you do this:
z = ''
print z.__doc__

How do I call a function from the same file as I would if using getattr?

In my program I have 25 different functions named "task1", "task2", "task3", etc...
At the moment I can call on these functions from a separate file and do them in the shell:
import examplefilename
tasknum = str(input("Which task would you like to see? "))
task = "task" + tasknum
methodToCall = getattr(examplefilename, task)
result = methodToCall()
What I have done will only call from a different file though so how do I do a function in this manner from the same file?
If my understanding is correct, the functions are defined in the same file and you need user input to invoke them, just use globals instead of getattr.
That is, replace the getattr with:
methodToCall = globals()[task] # it isn't a method, though
keeping the rest as-is.
As also noted in a comment, wrapping input with str is superfluous here, input already returns a string.

Error Encountered using ".format"

This is the code I have so far
def Save_Scores():
global score
score=str(score)
file=open("Class{}.txt",'a').format(group)
file.write("\n")
file.write ("Name: "+name+"\n")
file.write("Score: "+score+"/10\n")
file.close()
quiz()
However I encounter this error when the function is ran
line 42, in Save_Scores
file=open("Class{}.txt",'a').format(group)
AttributeError: '_io.TextIOWrapper' object has no attribute 'format'
str.format() is a method on string objects, but you are trying to call it on a file. Apply it to the string you want to pass to the open() call:
file = open("Class{}.txt".format(group), 'a')
Other best practices you can apply here:
Rather than use score as a global, make it an argument to your function, then pass it in when you call the function.
You also use name and group as globals, these should be arguments here too.
Make use of the with statement to have Python close the file for you.
You can use string formatting on the data you write to the file too, rather than use concatenation.
With those changes your function would look like this:
def Save_Scores(group, name, score):
with open("Class{}.txt".format(group), 'a') as file:
file.write("\nName: {}\nScore: {}/10\n".format(name, score))

Categories

Resources