Python - class object return value - python

Beginner Pythonista here
Making a betting game as part of an OOP exercise.
made a Player class with a bet function:
# Player Class
class Player():
def __init__(self,name):
self.name = name
self.hand = []
self.chips = 0
def deposit(self,amount):
self.chips += int(amount)
print(f"{amount} chips deposited.\nTotal available funds: {self.chips}")
def bet(self):
amount = int(input("Place your bet: "))
if not amount > self.chips:
self.chips -= amount
print(f"You bet {amount}. New Balance: {self.chips}")
return amount
else:
print("You cannot bet above your chips")
I was under the impression that a method within a class acted as a function, but the "return amount" command returns "None/NoneType".
How can I return the integer value to add to assign to a variable?
Thanks in advance

Probably went through else statement, that does not return anything. Tried your code and it works as expected if you meet if criteria in bet function (one that has return)
a.chips = 100
a.bet()
Place your bet: >? 1
You bet 1. New Balance: 99
Out[8]: 1

Your code seems right except for the else condition. You should add to else condition in the method bet
return 0
or raise an error
raise ValueError('You cannot bet above your chips')
then you should handle it wherever you want to use it.

There is an indentation Error for me. The If statement in the bet method shouldnt be indented. After fixing that it works fine for me.
Creating an object from class Player:
test_player = Player("TestName")
Giving some deposit:
test_player.deposit(10)
10 chips deposited.
Total available funds: 10
And finally the betting:
test_player.bet()
Place your bet: >? 5
You bet 5. New Balance: 5
The last bet gives:
test_player.bet()
Place your bet: >? 6
You cannot bet above your chips

Related

Why are my classes not working properly? even though they work when only one class is active

so my classes won't recognize each other but when left to work alone they do work as seen in the consult printing at the bottom of the post. However the deposit and transfer are popping up the ram location, however, they do work fine when done separately just as shown in the consult action in the bottom part.
<function cashier.deposit at 0x0000023A9B656048>
import datetime
now = datetime.datetime.now()
class account:
owner = "name"
pin = "1823"
balance = 800
def __init__(self, transfer, withdraw, deposit, consult):
self.transfer = transfer
self.withdraw = withdraw
self.deposit = deposit
self.consult = consult
class cashier:
def __init__(self, withdraw, deposit, transfer, consult):
self.transfer = transfer
self.consult = consult
self.withdraw = withdraw
self.deposit = deposit
def deposit(self):
print("Please type pin to proceed")
if account.pin == 1823:
print("who would you like to send money to?")
else:
print("Invalid pin")
def transfer(self):
pass
def withdraw(self):
withdrawal = input("How much money do you want to withdraw? (there is a limit up to 10,000$ a day!)")
account.balance -= int(withdrawal)
if int(withdrawal) > 10000:
print("withdrawals cannot be larger than 10,000 a day!")
exit()
elif int(withdrawal) > account.balance:
print("your account does not have enough funds to complete your transaction")
else:
print("Transaction succesfull!\nPlease collect your money")
print('Today is', now)
print("Hello %s!\nWhat can I do for you today?" % account.owner)
action = input("Use commands such as withdraw, deposit, transfer or consult to continue!\n")
if action == "withdraw":
print(cashier.withdraw)
if action == "consult":
print("Your account's balance is %s $" % str(account.balance))
if action == "transfer":
print(cashier.transfer)
if action == "deposit":
print(cashier.deposit)
else:
print("Uknown command, exiting programm")
exit()
The various functions of cashier do not return anything, so the prints are just printing the string representation of the function. You could have the functions return a string like so:
class Cashier: # PEP8 calls for CamelCase here
def deposit(self):
pin = input("Please type pin to proceed")
if Account.pin == pin:
return "who would you like to send money to?"
else:
return "Invalid pin"
def transfer(self):
pass
def withdraw(self):
withdrawal = input("How much money do you want to withdraw? (there is a limit up to 10,000$ a day!)")
Account.balance -= int(withdrawal)
if int(withdrawal) > 10000:
return "withdrawals cannot be larger than 10,000 a day!"
elif int(withdrawal) > Account.balance:
return "your Account does not have enough funds to complete your transaction"
else:
return "Transaction successful!\nPlease collect your money"
Edit: I removed the initializer, as these weren't doing anything. You need to instantiate your cashier with cashier = Cashier(), then call the functions of Cashier with cashier.withdraw().
There's a fundamental misunderstanding on how classes work here (and OOP in general). You should read through the Python docs on building classes before you go any further.
To use your classes, you need to instantate them like this
Cashier = cashier()//I don't think you should ask for the transfer details while instantiating. But you can do that by adding the parameter in the bracket
Now you can use the functions on the Cashier variable like:-
Cashier.deposit(deposit_money)
I think if you don't want to instantiate and want a function which does not actually store data, you can use a static function but I don't think that is what you want to do

Python saying 'int' object isn't callable

I got a small project for my course, I am to write a program that simulates a person's bank account.
I'll spare the talk, the code is down below, along with the commenting....
# -*- coding: utf-8 -*-
#This program starts by taking in a user input as shown in the While loop..
#the 2 Methods in the class, 1 is for depositing money and the second is for a withdrawal..
class Account:
newBal = 0
post_bal=0
def __init__(self, balance):
self.balance = balance
def deposit(self, deposit):
self.deposit = int(deposit)
#newBal is the variable that takes the new Balance
Account.newBal = self.balance + self.deposit
print("Your Balance is now {}".format(Account.newBal))
return Account.newBal
def withdraw(self, withdraw):
self.withdraw = int(withdraw)
if self.withdraw > Account.newBal:
return "Error, we have a hard time finding that kind of money..."
else:
print("Withdrawal Accepted, have fun with that dough!")
#post_bal is the variable that stores the balance with the withdrawal taken from it
Account.post_bal = Account.newBal - self.withdraw
return("Your Balance is now {}".format(Account.post_bal))
a = Account(balance=0)
while True:
input_1 = input("What would you like to do today? [1] Deposit, [2] Withdraw ")
if int(input_1) == 1:
print(a.deposit(input("How much would you like to deposit? ")))
elif int(input_1) == 2:
print(a.withdraw(input("How much would you like to withdraw? ")))
else:
print(" I'm not too sure I understand what you're saying...")
With this I've been able to run a full loop successfully, depositing and amount and then withdrawing another, with all the outputs being returned. However, once I get either action for the second time in the loop, I get the error call...
TypeError
Traceback (most recent call last)
<ipython-input-4-6a19e620e3d6> in <module>
33 print(a.deposit(input("How much would you like to deposit? ")))
34 elif int(input_1) == 2:
---> 35 print(a.withdraw(input("How much would you like to withdraw? ")))
36 else:
37 print(" I'm not too sure I understand what you're saying...")
TypeError: 'int' object is not callable
I'm not sure what I did wrong here...
You are changing the withdraw to an int here.
def withdraw(self, withdraw):
self.withdraw = int(withdraw)
Use a different name like
def withdraw(self, withdraw):
self.withdraw_value = int(withdraw)

Changing a local variable in multiple functions in Python?

background: I'm currently writing a text-based adventure and each enemy has a certain amount of turns you can attack it before it attacks back.
So to handle this the code sets an argument in the function for the fight dictating how many times you can attack.
def fight_sequence(rounds):
while rounds > 0:
attack = input()
if attack == magic:
magic("you teleport away to safety. Congratulations you have stayed alive through your journey and found a few souvenoirs. nice job!", 1, "you muster up all of your energy, chant the spell.... and nothing happens.Cthulu... seems unimpressed", 1, "")
elif attack == sword:
sword(1)
def magic(teleportmessage, teleportsuccess, firemessage, firefail, winmessage):
x = 0
while x == 0:
fightorflight = input("""you open the book to cast a spell
Do you want to try teleporting or use a fireball?""").lower()
if "teleport" in fightorflight:
if teleportsuccess = 1:
print(teleportmessage)
x = 1
else:
choice = input("You can't teleport out of this battle. Would you like to try a fireball?")
if choice == yes:
fightorflight = "fireball"
else:
x = 1
elif "fire" in fightorflight:
print(firemessage)
if firefail == 1:
choice = input("do you want to try to teleport instead?").lower()
if "yes" in choice:
fightorflight = "teleport"
else:
x = 1
else:
print(winmessage)
else:
print("Sorry not sure what you mean")
def sword(attacksuccess):
if attacksuccess == 1:
print("You pull out the sword and swing at the monster damaging it severely.")
else:
print("You pull out the sword and swing at the monster, but its immune to blunt objects.")
fight_sequence(3)
both magic() and sword() need to be able to decrease rounds by 1, originally i just did that before entering the magic or sword function. however some items to attack with allow you to attack more than once if you want so that won't work for them. Such as magic if they also choose to teleport. Is there a way to allow me to change the variable rounds while inside of another function?
I think using a return value might help but I'm not sure how to go about it
You can simply add a new argument to the magic function, and pass the 'rounds' variable through when you call it.
e.g.
def fight_sequence(rounds):
...
magic("some message", false, "fired", false, "you won", rounds)
def magic(teleportmessage, teleportsuccess, firemessage, firefail, winmessage, rounds):
Your passing through the variable (not just the value) so it will change in every context where rounds can be seen.
HTH.
I would recommend using classes to create this game rather than lots of functions, an example of a class in a hero game below.
class Hero:
def __init__(self):
self.health = 10
def eatApple(self):
self.health += 1
def takeDamage(self):
self.health -= 1
init function runs as class is initialized.
player = Hero()
print(player.health) # will print 10
player.takeDamage()
print(player.health) # will print 9
This way you can have global variables for you functions which can be changed in each function and is much more organised.

Python: setting max for bank withdraw

I'm new to python and I am still trying to get the hang of it. I'm attempting to change the processing function in the following code so that the user can not withdraw more money then what the "bank" has on record, which is 500. I was hoping that someone could help. Would I enter an if statement for >500?
#Simple Bank Atm
def main():
PIN=7777;balance=500;pin=0;success=False
Pin=getInput(pin)
Pin,PIN,balance,success=processing(pin,PIN,balance,success)
Display(success,balance)
#Input Function
def getInput(pin):
pin=int(input(“Please enter your PIN:”))
return pin
#Processing Function
def processing(pin,PIN,balance,success):
if pin==PIN:
success=True
amt=float(input(“How much would you like to withdraw?”))
balance=balance-amt
return pin,PIN,balance,success
else:
success=false
return pin,PIN,balance,success
You can use an if condition to do this.
if amt <= balance: #Can't withdraw over your current balance
balance -= amt
else:
print("Error. Amount exceeds funds on record.")
Also, other things aside you're returning the same thing inside your if and else condition and if this is what you really want to return it's redundant to have it in both. You can just have it after your else statement at the same indentation level
def main():
PIN=7777;balance=500;pin=0;success=False
Pin=getInput(pin)
Pin,PIN,balance,success=processing(pin,PIN,balance,success)
Display(success,balance)
#Input Function
def getInput(pin):
pin=int(input("Please enter your PIN:"))
return pin
#Processing Function
def processing(pin,PIN,balance,success):
if pin==PIN:
success=True
amt=float(input("How much would you like to withdraw?"))
if balance<amt:
print("Amount to draw is greater than balance.")
return pin,PIN,balance,false
balance=balance-amt
return pin,PIN,balance,success
else:
success=false
return pin,PIN,balance,success
Yes. You should use an if statement - this should happen before they can withdrawal the amount (balance = balance - amt).
So you could do something like this:
if amt <= balance:
balance -= amt
return True
else:
# do not change balance and stop withdrawal
return False

Need help writing algorithm in Python/Sage

I'm a complete novice to python and sage so I need some help and clarification on the steps all the way through. This is a question concerning game theory.
First I will describe the algorithm and then I will propose a solution the best I can.
The algorithm:
I want to start the program with a random variable from 1-100. This
variable will be defined 'S'. I also want to define a set of variables
'C' which can be deducted from S every turn, this set is {1,2,3,4,5,6}
(in other words the user and computer can deduct 1, 2, 3, 4, 5 or 6
from S. If variable S is divisible by 7 (e.g. 21), then print: "I
lose". If not, the game can begin.
Let's say that the random variable turns out to be 20. The player is
now prompted to enter a number within the range of C. When the player
has entered the number, I want the program to deduct that number from
S, so if the player enters 4 (a legal move), S is then 20-4=16. The
computer then calculates mod(S,7) and finds out that modulo 16,7 is 2
so it deducts 2 from S, in other words, 16-2=14.
If the player enters a number which results in S being divisible by 7, such as 6 (20-6=14) then the computer simply deducts 1 and attempts to get to such a number again next round.
The game continues until the computer eventually wins as the player is
eventually placed at 7 and has to deduct a number which the computer
can finish with (user deducts 6, computer deducts the last one and
wins). Print: "I win".
So like I said, I have literally no experience in python and sage so I can only go by my (limited) java experience:
I would attempt to establish a variable S with some 'ran' element (no idea what it's called in python). I would then attempt something like:
if S%7=0 then print "I lose"
else
prompt "Pick a number between 1 and 6, those included".
Declare user input as variable U.
Do S-U=S
Now do S-S%7=S
Now I want the program to realize when S=7 and then print: "You lose". If you can help me go all the way, though, that would be great.
import random
def playgame():
s = random.randint(1,100) #grabs a random integer between 1 and 100
POSS = range(1,7) #range ignores the last number, so this is [1,2,3,4,5,6]
if not s % 7: #if s%7 != 0
print("I lose")
return #exit the function
while s > 0: #while s is still positive
choice = 0 #set choice to 0 (this may as well have been "foo",
# I just needed it to not be in POSS)
while choice not in POSS: #until the user picks a valid number
choice = int(input("Select a number between 1 and 6: ")) #prompt for input
s -= choice #subtract choice from s, then set the difference to s
print("You subtracted {}, leaving {}".format(choice,s)) #print for the user
comp_choice = s%7 #the computer's choice is always s%7
s -= comp_choice #subtract the comp's choice from s, then set the diff to s
print("I subtracted {}, leaving {}".format(comp_choice,s)) #print for user
print("I win!") #since we know computer will always win, I don't have to do a check
playgame() #run the function
Here's a vastly more complicated function that does essentially the exact same thing ;-)
class Entity(object):
"""Base class that should not be instantiated on its own -- only
exists to be inherited from. Use Player() and Computer() instead"""
def __init__(self,name=None):
if name is None:
name = input("What's your name? ")
self.name = name
self.myturn = False
def __str__(self):
# this magic function means calling str(self) returns str(self.name)
# included so I can do print(player)
return self.name
def makemove(self,choice):
"""finds the global s and subtracts a given choice from it,
printing the choice and the result to the user."""
global s
s -= choice
print("{} chooses {}, leaving {}".format(self,choice,s))
return choice
def activate(self):
self.myturn = True
return self
def deactivate(self):
"""does exactly self.myturn = False"""
self.myturn = False
class Player(Entity):
"""A player-controlled Entity"""
def getchoice(self):
"""Prompts the user for a choice, ensuring it's between 1 and 6, then
calls Entity's makemove() with that as an argument"""
choice = None
while choice not in range(1,7):
choice = int(input("Pick a number between 1 and 6: "))
return super().makemove(choice)
class Computer(Entity):
def __init__(self):
super().__init__(name="Computer Player")
#overrides to ensure every Computer object has the name Computer Player
def getchoice(self):
"""grabs a number for the computer, and makes its move"""
global s
choice = s%7
if choice == 0: #edge case where computer goes first on an s where s%7==0
choice = random.randint(1,6)
return super().makemove(choice)
class Game(object):
"""Class defining an instance of the Game
FUNCTIONS:
Game.start() <-- use this to start the game"""
def __init__(self,playerArray=[]):
"""defines s as a global, ensures the players array is built
correctly, and gives s a random int value between 1-100"""
global s
if type(playerArray) is Player:
playerArray = [playerArray]
while len(playerArray) < 2:
playerArray.append(Computer())
self.players = playerArray
s = random.randint(1,100)
def start(self):
"""Let's play!"""
global s
print ("""
====================================
THE GAME BEGINS NOW!!!
We will begin with a value of: {:3}
====================================""".format(s).lstrip())
turn = random.randint(1,len(self.players))-1
while True:
try:active_player = self.players[turn].activate()
except IndexError: print(turn)
choice = active_player.getchoice()
if s <= 0: break
active_player.deactivate() # is active_player.myturn = False
turn += 1
if turn == len(self.players): turn = 0 #wrap the list
for player in self.players:
#this will execute the turn s becomes zero
if player.myturn:
winner = player
break
print("Winner: {}".format(winner))
import random
game = Game()
game.start()
S=random.randint(1,100) #will pick a random number
user_input = int(raw_input("Enter a number:")) #will get an integer from the user
#subtraction and modulo work just like in any other language ...
if(condition):
do_something() #is the format for if statements
does that cover all your questions? or did I miss some?

Categories