TheGeek
TheGeek

Reputation: 11

Python subroutine returning NonType

So I have created this fruit machine in python and when I call the variable to check the results of the machine the subroutine returns a non type error

I have tried to force the returned variable into a float (what I need it to be ) a couple ways but no luck I am not sure what else to try: I have looked on a multitude of websites and asked friends for help but with no luck; I have tried to rewrite how the function is called but no change; how the return functions return the winnings variable but noting has changed. I have copied the code below.

import random
money = 1.00
finish = False


print (" You have £", money)

def prizecheck(tocheck,winnings):
    if wheel1 == tocheck:
        if wheel2 == tocheck:
            if wheel3 == tocheck:
                if tocheck == "Skull":
                    winnings = 0
                    return winnings
                    print ("The house wins, All money lost")
                elif tocheck == "Cherry" or tocheck == "Lemon" or tocheck == "Orange" or tocheck == "Star":
                    print ("You win £1")
                    winnings = winnings + 1
                    return winnings
                elif tocheck == "Bell":
                    print ("You win £5")
                    winnings = winnings + 5
                    return winnings
            else:
                if tocheck == "Skull":
                    winnings = winnings - 1.00
                    return winnings
                elif tocheck == "Cherry" or tocheck == "Lemon" or tocheck == "Orange" or tocheck == "Star" or tocheck == "Bell":
                    print ("You win 50p")
                    winnings = winnings + 0.50
                    return winnings
        elif wheel3 == tocheck:
            if tocheck == "Skull":
                print ("The house wins, you lost £1")
                winnings = winnings - 1.00
                return winnings
            elif tocheck == "Cherry" or tocheck == "Lemon" or tocheck == "Orange" or tocheck == "Star" or tocheck == "Bell":
                print ("You win 50p")
                winnings = winnings + 0.50
                return winnings
    elif wheel2 == tocheck:
        if wheel3 == tocheck:
            if tocheck == "Skull":
                print ("The house wins, you lost £1")
                winnings = winnings - 1.00
                return winnings
            elif tocheck == "Cherry" or tocheck == "Lemon" or tocheck == "Orange" or tocheck == "Star" or tocheck == "Bell":
                print ("You win 50p")
                winnings = winnings + 0.50
                return winnings
            
def spin():
    picture = random.randint(1,6)
    if picture == 1:
        wheel = "Cherry"
    elif picture == 2:
        wheel = "Bell"
    elif picture == 3:
        wheel = "Lemon"
    elif picture == 4:
        wheel = "Orange"
    elif picture == 5:
        wheel = "Star"
    else:
        wheel = "Skull"
    return wheel

    


while money >= 0.2 and finish != True:
    money = money - 0.2
    wheel1 = spin()
    wheel2 = spin()
    wheel3 = spin()
    print(wheel1,"|",wheel2,"|",wheel3)
    
    change = prizecheck("Skull",money)
    change = prizecheck("Cherry",money)
    change = prizecheck("Bell",money)
    change = prizecheck("Lemon",money)
    change = prizecheck("Orange",money)
    change = prizecheck("Star",money)
    
    money = change
    
    print("You have £",money)
    
    endcheck = input("Spin again (1), or quit(2)?")
    if endcheck == "2":
        finish = True
    
    if money < 0.20:
        print("Sorry You have ran out of money")



Any help would be appreciated

Upvotes: 1

Views: 66

Answers (3)

JonSG
JonSG

Reputation: 13177

It might be easier to think about how to determine winnings by looking at the count of the most frequent wheel value. For example, I believe all these produce the same "win" right?

["Cherry", "Cherry", "Lemon"]
["Cherry", "Lemon", "Cherry"]
["Lemon", "Cherry", "Cherry"]

If we find the count of the most frequent item found, in all cases we get: ("Cherry", 2) making it easier to check and process.

I propose:

def prize_check(wheels, bet_amount):
    ## ---------------------
    ## find the details of the most common item
    ## ---------------------
    most_common_value, most_common_count = collections.Counter(wheels).most_common(1)[0]
    ## ---------------------

    ## ---------------------
    ## All items different
    ## ---------------------
    if most_common_count == 1:
        return bet_amount  # a guess by me at what to return here
    ## ---------------------

    ## ---------------------
    ## Two of the items are the same
    ## ---------------------
    if most_common_count == 2:
        if most_common_value == "Skull":
            return bet_amount - 1.0
        return bet_amount + 0.5
    ## ---------------------

    ## ---------------------
    ## All three the same
    ## ---------------------
    if most_common_value == "Skull":
        return 0

    if most_common_value == "Bell":
        return bet_amount + 5.0

    return bet_amount + 1.0
    ## ---------------------

Then rather than calling prizecheck() multiple times, we call this new method once and pass in the wheel values and the bet.

money = prize_check([wheel1, wheel2, wheel3], money)

Upvotes: 2

Ada
Ada

Reputation: 1913

I think this should work:

import random

money = 1.00
finish = False

print("You have £", money)


def prizecheck(tocheck, money):
    winnings = 0  # Initialize winnings to 0
    if wheel1 == tocheck and wheel2 == tocheck and wheel3 == tocheck:
        if tocheck == "Skull":
            print("The house wins, All money lost")
        elif tocheck in ["Cherry", "Lemon", "Orange", "Star"]:
            print("You win £1")
            winnings = 1
        elif tocheck == "Bell":
            print("You win £5")
            winnings = 5
    elif (wheel1 == tocheck) + (wheel2 == tocheck) + (wheel3 == tocheck) == 2:
        if tocheck == "Skull":
            print("The house wins, you lost £1")
            winnings = -1
        elif tocheck in ["Cherry", "Lemon", "Orange", "Star", "Bell"]:
            print("You win 50p")
            winnings = 0.5
    return money + winnings


def spin():
    picture = random.randint(1, 6)
    if picture == 1:
        wheel = "Cherry"
    elif picture == 2:
        wheel = "Bell"
    elif picture == 3:
        wheel = "Lemon"
    elif picture == 4:
        wheel = "Orange"
    elif picture == 5:
        wheel = "Star"
    else:
        wheel = "Skull"
    return wheel

while money >= 0.2 and not finish:
    money -= 0.2
    wheel1 = spin()
    wheel2 = spin()
    wheel3 = spin()
    print(wheel1, "|", wheel2, "|", wheel3)

    money = prizecheck("Skull", money)
    money = prizecheck("Cherry", money)
    money = prizecheck("Bell", money)
    money = prizecheck("Lemon", money)
    money = prizecheck("Orange", money)
    money = prizecheck("Star", money)

    print("You have £", money)

    endcheck = input("Spin again (1), or quit(2)?")
    if endcheck == "2":
        finish = True

    if money < 0.20:
        print("Sorry, you have run out of money")
  • Any print statements after return statements will not be executed, so I moved those
  • I also simplified your if statements, less nesting makes it less confusing
  • You were overwriting change each time you call prizecheck for different fruits. This means that only the last fruit's result will be stored in change. You need to accumulate the changes for all fruits and then update money accordingly
  • In the prizecheck function you are using a variable named winnings defined outside the function. This causes a problem where you are not updating the money variable correctly. You need to pass money to the function and return the updated value

Upvotes: 1

mijiturka
mijiturka

Reputation: 494

Your logic gets to the end of prizecheck() without returning anything, setting change to None when you do change = prizecheck(...).

Try to put a debug statement there and see when this happens.

Try to print the value of change every time you change it so you can see the pattern.

Get in the habit to always return something at the end of functions you expect a return value from.

Python is not a statically typed language so you can't force a value to be a float. If you could (in another language), you'd have to specify the return type of the function, and get a compiler error in the process. You can provide a type hint to check for mistakes like this, but a Python variable can always be set to None.

Upvotes: 1

Related Questions