[SOLVED] Multiple values error when only one value was given

This is the place for queries that don't fit in any of the other categories.

[SOLVED] Multiple values error when only one value was given

Postby ZeeQyu » Sun Jul 07, 2013 1:28 pm

Hello.

I'm a python beginner, but a long-time casual coder.
I was attempting to improve my version of a number guessing game by making some of my code more reusable. I moved the get_int() function I had to a class, so you could specify the prompts given when you give a number that isn't accepted. I get this error when I attempt to prompt the user for a number.
Code: Select all
Traceback (most recent call last):
  File "C:\Users\MCMasta\projects\python\number_guessing_game.py", line 173, in <module>
    main()
  File "C:\Users\MCMasta\projects\python\number_guessing_game.py", line 135, in main
    first_prompt="What is the maximum number you want me to choose from?\nThe higher the maximum number, the harder the game is.\n0 to ? [A number, greater than 3]: ")
TypeError: get_int() got multiple values for keyword argument 'prompt'

The required code to get the same error in the python shell (IDLE) is the following class definition and the two lines I used to prompt the user.
Code: Select all
# Class definition:
class IntGetter(object):
   
    def __init__(self, too_low="That number is too low.\nPlease enter a number that is higher than or equal to {min}.",
                 too_high="That number is too high.\nPlease enter a number that is lower than or equal to {max}.",
                 not_number="That input can not be accepted as a number."):
        ''' Function for setting up an IntGetter object.
            Lets you change the prompts that are given when you use the get_int function.
            Use curly brackets with the keys min and max to have the minimum and maximum values
            specified in the get_int function call inserted into the prompt.
        '''
       
        self.not_number = not_number
        self.too_low = too_low
        self.too_high = too_high
       
    def get_int(prompt, min=0, max=0, first_prompt=''):
        ''' Gets an int from the user and returns that value.
            Will accept a number between min and max, including min and max. Will round floats down to nearest int.
            Will prompt the user with the prompt parameter. The first_prompt parameter will prompt that prompt the first time if non-null.
            Will complain and prompt the user to try again if the number is too high, too low or not a number.
        '''
        while True:
            if first_prompt:
                number = raw_input(first_prompt)
                first_prompt = ''
            else:
                number = raw_input(prompt)
           
            try:
                number = int(float(number))
            except:
                print "{not_number}\n".format(not_number=self.not_number, min=min, max=max)
            else:
                if min > number:
                    print "{too_low}\n".format(too_low=self.too_low, min=min, max=max)
                else:
                    # If max isn't greater than min, don't check maximum number.
                    if min >= max:
                        return number
                    else:
                        if max < number:
                            print "{too_high}\n".format(too_high=self.too_high, min=min, max=max)
                        else:
                            return number

Code: Select all
int_getter = IntGetter()
maximum = int_getter.get_int(prompt="Please enter a number for the maximum guessing number. [3-*]: ",
   min=4,
        first_prompt="What is the maximum number you want me to choose from?\nThe higher the maximum number, the harder the game is.\n0 to ? [A number, greater than 3]: ")

The error I get from running that code in the shell is the following:
Code: Select all
Traceback (most recent call last):
  File "<pyshell#9>", line 3, in <module>
    first_prompt="What is the maximum number you want me to choose from?\nThe higher the maximum number, the harder the game is.\n0 to ? [A number, greater than 3]: ")
TypeError: get_int() got multiple values for keyword argument 'prompt'

This code worked before I moved the get_int function into a class. As you can see, I only specify one prompt parameter, and yet it tells me I specify multiple values. Is there something I'm missing?

I am running Windows 7 and Python 2.7.5. I write the code in eclipse with PyDev.
The full code might not be useful, but I'll just put that here anyway, in case it is needed. Everything is in that code.
Code: Select all
from random import randint
import json
from datetime import datetime

class IntGetter(object):
   
    def __init__(self, too_low="That number is too low.\nPlease enter a number that is higher than or equal to {min}.",
                 too_high="That number is too high.\nPlease enter a number that is lower than or equal to {max}.",
                 not_number="That input can not be accepted as a number."):
        ''' Function for setting up an IntGetter object.
            Lets you change the prompts that are given when you use the get_int function.
            Use curly brackets with the keys min and max to have the minimum and maximum values
            specified in the get_int function call inserted into the prompt.
        '''
       
        self.not_number = not_number
        self.too_low = too_low
        self.too_high = too_high
       
    def get_int(prompt, min=0, max=0, first_prompt=''):
        ''' Gets an int from the user and returns that value.
            Will accept a number between min and max, including min and max. Will round floats down to nearest int.
            Will prompt the user with the prompt parameter. The first_prompt parameter will prompt that prompt the first time if non-null.
            Will complain and prompt the user to try again if the number is too high, too low or not a number.
        '''
        while True:
            if first_prompt:
                number = raw_input(first_prompt)
                first_prompt = ''
            else:
                number = raw_input(prompt)
           
            try:
                number = int(float(number))
            except:
                print "{not_number}\n".format(not_number=self.not_number, min=min, max=max)
            else:
                if min > number:
                    print "{too_low}\n".format(too_low=self.too_low, min=min, max=max)
                else:
                    # If max isn't greater than min, don't check maximum number.
                    if min >= max:
                        return number
                    else:
                        if max < number:
                            print "{too_high}\n".format(too_high=self.too_high, min=min, max=max)
                        else:
                            return number

def fill_time_template(time_template, datetime_object, force_double_digit = 0):
    ''' Fills in a time template with the correct numbers from a datetime object, allowing pretty time formatting.
        The time template must be a string with the following curly bracket keys:
        Y, M, D, H, Min, S
        Forces double-digit formatting on every number except for year if force_double_digit is non-null.
    '''
   
    Y = str(datetime_object.year)
    if force_double_digit:
        M = double_digit(datetime_object.month)
        D = double_digit(datetime_object.day)
        H = double_digit(datetime_object.hour)
        Min = double_digit(datetime_object.minute)
        S = double_digit(datetime_object.second)
    else:
        M = str(date_object.month)
        D = str(datetime_object.day)
        H = str(datetime_object.hour)
        Min = str(datetime_object.minute)
        S = str(datetime_object.second)
       
    return time_template.format(Y=Y, M=M, D=D, H=H, Min=Min, S=S)
       
def double_digit(number):
    ''' Makes sure a number is double-digit.
        If the number is single-digit, add a
        zero in front and return it as a string.
    '''
    if len(str(number)) == 1:
        return "0" + str(number)
    else:
        return str(number)

def get_json_file(filename):
    ''' Opens, loads and returns the specified JSON file if it exists and returns an empty dictionary if it doesn't.
    '''
    try:
        f = open(filename)
        log = json.load(f)
        f.close()
    except:
        log =  {}
    return log

def save_log(filename, name, maximum, tries, target, guesses, times_guessed, start_time):
    ''' Gets the existing log from a file if it exists,
        adds an entry to the JSON dictionary with the current time as the key
        and a dictionary containing the various specified values and saves it to the same file.
       
        filename should be a path
        name should be a string.
        maximum, tries, target and times_guessed should be integers.
        start_time should be a datetime object.
        guesses should be a list with lists containing the guessed number
        and a string containing either "high", "low" or "correct".
    '''
    log = get_json_file(filename)
    now = datetime.now()
    time_template = "{Y}-{M}-{D} {H}:{Min}:{S}"
    key = fill_time_template(time_template, now, 1)
    start_time = fill_time_template(time_template, start_time, 1)
    print "DEBUG", key
    log[key] = {"name": name,
                "max": maximum,
                "tries": tries,
                "target": target,
                "guesses": guesses,
                "times_guessed": times_guessed,
                "start_time": start_time}
    f = open(filename, "w")
    json.dump(log, f, indent=2)
    f.close()
                   
def main():
    ''' Number guessing game. Lets you choose the range of numbers to be guessed and the number of attempts
        you have to guess the number at the start of every game.
        Saves the name of the player and various details about the game to a file.
    '''
   
    print "Welcome to the number guessing game!"
    int_getter = IntGetter()
    while True:
        name = raw_input("What is your name? ")
        maximum = int_getter.get_int(prompt="Please enter a number for the maximum guessing number. [3-*]: ",
                                     min=4,
                                     first_prompt="What is the maximum number you want me to choose from?\nThe higher the maximum number, the harder the game is.\n0 to ? [A number, greater than 3]: ")
        tries = int_getter.get_int(first_prompt="How many turns do you want to guess the number? [0 for unlimited, 1-*]: ", prompt="How many turns? [0, 1-*]: ")
   
        guess_number = 1
        target_number = randint(0, maximum)
        guesses = []
        print "I am thinking of a number..."
        start_time = datetime.now()
        # Start of game
        while True:
            if guess_number > tries and tries:
                print "\nYou are out of tries. The number was {}.\nYou lose.\n".format(target_number)
                break
            if tries and tries == guess_number:
                print "\nGuess #{}: LAST TRY! Choose wisely!".format(guess_number)
            else:
                print "\nGuess #{}:".format(guess_number)
            guess_number = guess_number + 1
            guessed_number = int_getter.get_int("What is your guess? [0-{}]: ".format(maximum), min=0, max=maximum)
           
            if guessed_number == target_number:
                print "\nYou found the number! The number was {}! Congratulations!".format(target_number)
                guesses.append([guessed_number, "correct"])
                break
            elif guessed_number > target_number:
                print "That number is too HIGH. Try again!"
                guesses.append([guessed_number, "high"])
            else:
                print "That number is too LOW. Try again!"
                guesses.append([guessed_number, "low"])
       
        save_log(filename="number_guessing_game.json", name=name, maximum=maximum, tries=tries, target=target_number, guesses=guesses, times_guessed=guess_number-1, start_time=start_time)
        again = int_getter.get_int("Play again? [1 for yes, 0 for no]: ", 0, 1, "Do you want to play again? [Type 1 for yes or 0 for no]: ")
        print
        if not again:
            break
       
if __name__ == "__main__":
    main()


Sincerely,

ZeeQyu
Last edited by ZeeQyu on Sun Jul 07, 2013 6:30 pm, edited 1 time in total.
ZeeQyu
 
Posts: 2
Joined: Sun Jul 07, 2013 12:36 pm

Re: Multiple values error when only one value was given

Postby Yoriz » Sun Jul 07, 2013 1:44 pm

Hi, welcome to the forum, nice first post with plenty of information :D
Because
Code: Select all
def get_int(prompt, min=0, max=0, first_prompt=''):
is a method its should have self as the first argument

change it to
Code: Select all
def get_int(self, prompt, min=0, max=0, first_prompt=''):

and i think the problem will go away
New Users, Read This
Join the #python-forum IRC channel on irc.freenode.net!
Spam topic disapproval technician
Windows7, Python 2.7.4., WxPython 2.9.5.0., some Python 3.3
User avatar
Yoriz
 
Posts: 837
Joined: Fri Feb 08, 2013 1:35 am
Location: UK

Re: Multiple values error when only one value was given

Postby ZeeQyu » Sun Jul 07, 2013 3:20 pm

Thanks a lot, I'm actually happy that the mistake I did was so stupid and simple. I forget that methods and functions are different, coming from Java where there are no functions outside of classes.
Quick reply, good solution. I think I'll be coming back here again. :)

ZeeQyu
ZeeQyu
 
Posts: 2
Joined: Sun Jul 07, 2013 12:36 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 5 guests