missing 1 required positional argument?

3.1k views Asked by At

I cant get what is wrong with this code? It keeps giving me an error. I do not wanna create a class. It keeps giving me the "missing 1 required positional argument 'choice' in the main function. Anyone have any suggestions? The script is supposed to be a menu with all functions connected to the main. I tried to do elif's, hopefully it helps. I probably need to use "self"

import socket
import uuid
import os
import re

HNAME=1
IP=2
MAC=3
ARP=4
ROUT=5
QUIT=6



def get_user_choice(choice):
    print("Network Toolkit Menu")
    print("_____________________________________")
    print("1. Display the Host Name")
    print("2. Display the IP Address")
    print("3. Display the MAC Address")
    print("4. Display the ARP Table")
    print("5. Display the Routing Table")
    print("6. Quit")
    print()
    
    choice = int(input("Enter your choice: "))
    print()
    return choice

def choicefun(choice):
   
    while choice > QUIT or choice < HNAME:
        
        choice = int(input("Please enter a valid number: "))
        print()
        
    return choice

def get_hostname(host):
    host=socket.gethostname()
    print("\n The host name is: ", host)
    #return host

def get_ipaddr(ipv4):
    ipv4=socket.gethostbyname()
    print("\n The IPv4 address of the system is: ", ipv4)
    #return ipv4

def get_mac(ele):
    print ("The MAC address is : ", end="") 
    print (':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff) 
    for ele in range(0,8*6,8)][::-1]))

def get_arp(line):
    print("ARP Table")
    with os.popen('arp -a') as f:
        data=f.read()
    for line in re.findall('([-.0-9]+)\s+([-0-9a-f]{17})\s+(\w+)',data):
        print(line)
    return line

def __pyroute2_get_host_by_ip(ip):
    print("Routing table\n: ")
    table=os.popen('route table')
    print(table)

def main(choice):
    counter=False
    while counter==False:
        get_user_choice()
        choicefun()
        if choice == 6:
            counter==True
        elif choice == 1:
            get_hostname()
        elif choice == 2:
            get_ipaddr()
        elif choice == 3:
           get_mac() 
        elif choice== 4:
            get_arp()
        elif choice == 5:
            __pyroute2_get_host_by_ip()

main()
5

There are 5 answers

0
bbnumber2 On BEST ANSWER

This occurs because you are calling the main function without the corresponding choice argument:

def main(choice):
    ...
main()

You either need to pass a choice argument or remove the choice parameter from the function. It seems like choice is mainly defined by get_user_choice(), in which case the code could read:

def main():
    counter=False
    while counter==False:
        choice = get_user_choice()
...

However, the get_user_choice function also has a choice parameter. Since this argument is overridden with choice = int(input("Enter your choice: ")) you likely want to define the function as:

def get_user_choice():
    ...
1
Riyas On
        get_user_choice(choice)

You missed to pass choice as arg

1
Jasar Orion On

this sould work:

import socket
import uuid
import os
import re

HNAME=1
IP=2
MAC=3
ARP=4
ROUT=5
QUIT=6



def get_user_choice():
    print("Network Toolkit Menu")
    print("_____________________________________")
    print("1. Display the Host Name")
    print("2. Display the IP Address")
    print("3. Display the MAC Address")
    print("4. Display the ARP Table")
    print("5. Display the Routing Table")
    print("6. Quit")
    print()
    
    choice = int(input("Enter your choice: "))
    
    return choice

def choicefun(choice):
   
    while choice > QUIT or choice < HNAME:
        
        choice = int(input("Please enter a valid number: "))
        print()
        
    return choice

def get_hostname(host):
    host=socket.gethostname()
    print("\n The host name is: ", host)
    #return host

def get_ipaddr(ipv4):
    ipv4=socket.gethostbyname()
    print("\n The IPv4 address of the system is: ", ipv4)
    #return ipv4

def get_mac(ele):
    print ("The MAC address is : ", end="") 
    print (':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff) 
    for ele in range(0,8*6,8)][::-1]))

def get_arp(line):
    print("ARP Table")
    with os.popen('arp -a') as f:
        data=f.read()
    for line in re.findall('([-.0-9]+)\s+([-0-9a-f]{17})\s+(\w+)',data):
        print(line)
    return line

def __pyroute2_get_host_by_ip(ip):
    print("Routing table\n: ")
    table=os.popen('route table')
    print(table)

def main():
    counter=False
    while counter==False:
        choice = get_user_choice()
        choicefun(choice)         
        if str(choice) == "6":            
            counter==True
        elif str(choice) == "1":
            get_hostname()
        elif str(choice) == "2":
            get_ipaddr()
        elif str(choice) == "3":
           get_mac() 
        elif str(choice)== "4":
            get_arp()
        elif str(choice) == "5":
            __pyroute2_get_host_by_ip()

main()

your problem is that you dont pass the required arguments to insinde the function.

0
Copperfield On

The problem is simple: you call your main function without arguments when you defined it a requiring it.

def main(choice):
    ...

main() #<-here

You need to either pass a value as your initial choice or remove it from the main definition

option 1 call it like for example

main(1)

option 2

def main():
    ...

But that will leave you with a second problem, in your main function, and that is you never assign or change to the choice variable here the value you get from get_user_choice so you will get a second error depending on how you fix the first problem, or get stuck in a infinite loop because the choice doesn't change

0
Fedeco On

I think you should re-evaluate your design :

def get_user_choice(choice):
print("Network Toolkit Menu")

choice is not set, therefore there is no use to pass a parameter that has not been created.
When You create a script like yours, Python that is a procedural and dynamic programming language (accept it even if there is a lot of debate on this), executes your code from the first row to the last. That would be in order

  1. get_user_choice
  2. choicefun
  3. get_hostname
  4. get_ipaddr
  5. get_mac
  6. get_arp
  7. __pyroute2_get_host_by_ip
  8. def main(choice):
  9. main(choice)

import socket
import uuid
import os
import re

HNAME=1
IP=2
MAC=3
ARP=4
ROUT=5
QUIT=6

def get_user_choice():
    print("Network Toolkit Menu")
    print("_____________________________________")
    print("1. Display the Host Name")
    print("2. Display the IP Address")
    print("3. Display the MAC Address")
    print("4. Display the ARP Table")
    print("5. Display the Routing Table")
    print("6. Quit")
    print()#???
    choice = int(input("Enter your choice: "))
    print("Your Choice is {0}".format(choice))
    return choice

def choicefun(choice):
    while choice > QUIT or choice < HNAME:
        choice = int(input("Please enter a valid number: "))
        print()#Wtf?
    return choice
def get_hostname(host):
    host=socket.gethostname()
    print("\n The host name is: ", host)
    #return host
def get_ipaddr(ipv4):
    ipv4=socket.gethostbyname()
    print("\n The IPv4 address of the system is: ", ipv4)
    #return ipv4
def get_mac(ele):
    print ("The MAC address is : ", end="")
    print (':'.join(['{:02x}'.format((uuid.getnode() >> ele) & 0xff)
                     for ele in range(0,8*6,8)][::-1]))
def get_arp(line):
    print("ARP Table")
    with os.popen('arp -a') as f:
        data=f.read()
    for line in re.findall('([-.0-9]+)\s+([-0-9a-f]{17})\s+(\w+)',data):
        print(line)
    return line
def __pyroute2_get_host_by_ip(ip):
    print("Routing table\n: ")
    table=os.popen('route table')
    print(table)
    
def main():
    counter=False
    #while !counter :
    while counter==False:
        choice = get_user_choice()
        choicefun(choice)#you forgot to pass choice parameter
        if choice == 6:
            counter==True
        elif choice == 1:
            get_hostname()
        elif choice == 2:
            get_ipaddr()
        elif choice == 3:
            get_mac()#you need to return something and save it in a variable
        elif choice== 4:
            get_arp()#same
        elif choice == 5:
            __pyroute2_get_host_by_ip(#??)#you need to pass the parameter ip

if __name__ == 'main':
   main()

I fixed a little bit : if you are starting and don't have too much experience, remember to write input,output and purpose of a function. Point 2, if you call a function that has "get" in the name of function, you must do variableOfReturn = getMyfunction(parameter1,paramater2...).
Point 3, check always about the declaration of function, if it requires a parameter you must pass it in two ways : using a variable that has been set or statically like choicefun(2).
There's no need to create a class, if you want to have a central function which calls other function like a menu,use if __name__ == '__main__' :

There are some serious lacks of essentials coding 101, stay careful, it's better that you try codechef or some other system.