[Tutor] Why does invalid syntax pop up?

Brian van den Broek bvande at po-box.mcgill.ca
Fri Jul 8 23:16:17 CEST 2005

Nathan Pinno said unto the world upon 08/07/2005 16:14:
>   Thanks, Danny and all.
>   Adjusted the code, here is the newest code and error:


>   def add_login_command(site,filename):
>       print "Add a login info card"
>       site = raw_input("Site: ")
>       id = raw_input("User ID: ")
>       passcard = raw_input("Password: ")
>       sitelist[site] = [id,passcard]


>   while menu_choice != "9":
>       menu_choice = raw_input("Choose an option: ")
>       if menu_choice == "1":
>           add_login_command()


>   Error Message:
>   Traceback (most recent call last):
>     File "D:\password.py", line 73, in ?
>       add_login_command()
>   TypeError: add_login_command() takes exactly 2 arguments (0 given)
>   How do I fix it so that it runs properly, and any other errors that have 
> to be fixed?

Hi Nathan,

(Having just finished this long email up, I see that Danny is quicker, 
terser, and more to the point than I am. But I hate to waste the 
effort, so I'm sending anyway. In case of conflict, go with what Danny 
said :-)

First, I mean what I am about to say as a constructive comment.

It seems like you have been getting an error message and then posting 
the error msg and entire generating code to the list. It is good you 
are giving the exact error msg now, but posting the entire code isn't 
really the best idea. It would be much better if you instead tried to 
post a smaller chunk of the code that still exhibits the behaviour 
you'd like help with. (My snips don't leave it running but that is the 
general idea.)

This is good for 2 reasons:

1) It makes it less time-consuming for those who want to help you,


2) It is a great way of helping yourself. Trimming things down is a 
valuable way for you to gain general understanding *and* will often 
result in your determining the answer to your own question.

No one on the list minds helping, that's what its for (and goodness 
knows, I'm grateful for the hours and hours of effort list members 
have put into helping me). But, the ultimate point is to learn to help 
yourself, right? :-)

So, to your particular problem:

Look at the code that remains above. The error msg is complaining that 
the function add_login_command takes 2 arguments and that it was 
called with none. And sure enough, if you look at your def block for 
the function:

def add_login_command(site,filename):
     # code goes here

and the block causing the error:

if menu_choice == "1":

you've called it with no arguments at all. Hence the poor Python 
interpreter is confused.

So, minimally, to fix it, you need to either pass arguments to the 
function call or to remove the arguments from the function definition. 
I'm not sure what your overall intent is, so it is hard to say.

I also wonder if you understand the role of the arguments in function 
definitions. Several functions you defined take site as one of their 
arguments, but do nothing with it other than rebind the name to the 
result of a raw_input() call.

In that case, it isn't clear why you should have the argument. Compare 

IDLE 1.1.1
 >>> def very_silly_print_function(the_argument):
  	the_argument = raw_input('What should I print?')
  	print the_argument

 >>> def slightly_less_silly_print_function_no_arg():
  	the_value = raw_input('What should I print?')
  	print the_value

 >>> def slightly_less_silly_print_function_arg(the_argument):
   	print the_argument

 >>> very_silly_print_function('This will not be printed')
What should I print?This will be printed instead
This will be printed instead
 >>> slightly_less_silly_print_function_no_arg()
What should I print?This will be printed
This will be printed
 >>> slightly_less_silly_print_function_arg('As will this')
As will this

So, your functions that take site in as an argument and only reference 
it by site = raw_input(some_prompt_here) are kind of like the 
very_silly_print_function above. But, it is a bit worse than that. The 
very_silly_print_function reassigns the name and then does something 
with it. You only reassign. Then, when your function ends, you drop 
the name on the floor :-)

Take a look at this:

 >>> def name_dropper():
  	name_inside_function = raw_input('What is your moniker?')

 >>> name_dropper()
What is your moniker?Brian
 >>> name_inside_function

Traceback (most recent call last):
   File "<pyshell#20>", line 1, in -toplevel-
NameError: name 'name_inside_function' is not defined

The name name_inside_function only exists (so to speak) inside the 
function. To make it meaningful in your top-level (i.e. not inside a 
function of class) code, you've got to bind it in the top-level:

 >>> name_inside_function = 'Misleadingly named string that exists at 
 >>> name_inside_function
'Misleadingly named string that exists at top-level'
 >>> name_dropper()
What is your moniker?Brian
 >>> name_inside_function
'Misleadingly named string that exists at top-level'

But now there are two names name_inside_function. One in your function 
scope, one in the top-level or global scope. To make the assignment to 
the name inside the function affect your top-level name, you've got to 
do something like:

 >>> def name_keeper():
  	name_inside_function = raw_input('What is your moniker?')
  	return name_inside_function

 >>> top_level_name = name_keeper()
What is your moniker?Brian
 >>> top_level_name

(There are other ways, but that's enough for now.)

I hope that there is some help in all that :-)  Best,

brian vdB

More information about the Tutor mailing list