Questions about python inheritance and argument lists - python-2.7

First off I am getting this error
File "E:\New folder (7)\maingame.py", line 64, in play print self.introduction AttributeError: 'game' object has no attribute 'introduction'
I am not to sure as to what it means because I am pulling the self.introduction from the previous class..
I am also getting an
File "E:\New folder (7)\maingame.py", line 96, in <module>
game.play()
TypeError: play() takes exactly 2 arguments (1 given)
error, but can't for the life of me find what argument it is looking for, I simply want it to work.
from random import random
class place(object):
def __init__(self, title, description, events):
self.title = title
self.description = description
self.events = events
class event(object):
def __init__(self, probability, message, healthChange):
self.probability = probability
self.message = message
self.healthChange = healthChange
def process(self):
if random() < self.probability:
print self.message
return self.healthChange
return 0
class textadventure():
def __init__(self):
super(textadventure, self).__init__()
self.introduction = """
Welcome player, you are a lone traveler in space whom has set out to find glories beyond measure.
Unfortunately for you the dread pirate Roberts has attacked. You must defeat him.
"""
commandDeck = place('Command Deck', "You are now in the command center, here you can drive the ship and fire its weapons.",(
event(0.7, "The pirate ship fires at you! You take damage to your engines!", -10),
event(0.2, "One of the pirates manages to beam onto your ship! He shoots you before beaming away!",0),
))
engineRoom = place('Engine Room', "You are now in the main engine room here you can repair damage to the ship",(
event(0.7, "The pirate ship fires at you! You take damage to your engines!", -10),
))
restQuarters = place('Resting Quarters', "Here you can take a rest and heal your self",(
event(1.0, 'You are able to patch up your wounds and get back to the battle',0),
event(0.5, "The pirate ship fires at you! You take damage to your engines!", -10),
))
commandDeck.transitions = (engineRoom, restQuarters),
engineRoom.transitions = (commandDeck, restQuarters),
restQuarters.transitions = (commandDeck, engineRoom),
self.location = commandDeck
pirateHp = 50
class game(object, textadventure):
def __init__(self):
super(game, self).__init__()
self.health = 100
def location(self):
if self.location == commandDeck:
choice = raw_input('would you like to fire on the enemy ship?')
if choice == 'yes':
print 'You have hit the pirates!'
pirateHp -= 10
else: choice == 'no'
elif self.location == engineRoom:
choice = raw_input('Would you like to repair the engines?')
if choice == "yes":
event(1, "You repair what you can of the engines.", 10)
def __init__(self):
self.health = 100
def play(self, textadventure):
print textadventure.introduction
while True:
print (self.location.description)
for event in self.location.events:
self.health += event.process()
if self.health <= 0:
print ("Your ship has been destroyed!")
pause
exit(1)
print ('Your ships health is at %d percent' % self.health)
self._transition()
def _transition(self):
transitions = self.location.transitions
print ('you can go to: ')
for (index, transition) in enumerate(transitions):
print (index + 1, transition.title)
choice = int(raw_input('Choose one '))
if choice == 0:
exit(0)
else:
self.location = transitions[choice - 1]
def pirateShip(Object):
if pirateHp == 0:
print "You have defeated the pirates! Congradualations!"
pause
exit(1)
game = game()
game.play(game)

'game' object has no attribute 'introduction'
You should call the init of your super class when initializing game. In your current code, textadventure.init is never called which is why introduction is never added to textadventure.
Game should also not inherit from object (it does that through textadventure).
class game(textadventure):
def __init__(self):
super(game, self).__init__()
self.health = 100
def play(self):
print self.introduction
Should do the trick.
TypeError: play() takes exactly 2 arguments (1 given)
You never use your textadventure argument in play. Removing this should get things working.

Related

Increasing money when the dealer or player win the game

I am a beginner I am trying to add money if I wont to the money that I typed in the very start of the game if I won the money will be added to the input money that I had it adding but repeating its looping example I typed 500 then I won 200 price It will display 700 but if I won again and the price 300 it will show 800 and forgetting about what I won before
below is the code I will really appreciate your hep thank you
import random, sys
from random import shuffle
from _ast import Num
# define global variables for the cards
suits = ('Clubs', 'Spades', 'Hearts', 'Diamonds')
pip = ('Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King')
pipValues = {'Ace':11, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10, 'Jack':10, 'Queen':10, 'King':10}
playing = True
global score
score=0
class Card:
#When you create an instance of Card, you pass it a suit ("C", "D", "H", or "S") and a "pip" (2, 3, 4, 5, 6, 7, 8, 9, 10 J, Q, K, A).
#These values should be stored as instance variables for the new card object.
#I recommend you also have an instance variable "value" that stores the point value of the card.
#It should have an __str__ method that lets you print an individual card (such as "3S" for three of spades).
#Note that the __str__ method for Decks should take advantage of the __str__ method for Cards.
def __init__(self, suit, pip):
self.suit = suit
self.pip = pip
self.value = pipValues.get(pip)
def __str__(self):
return str(self.pip) + " of " + str(self.suit)
def __repr__(self):
return self.__str__()
class Player:
#When you create an instance of Player, it should have an instance variable "hand" that's set to an empty list,
#and an instance variable "handTotal" that's set to zero. These instance variables will be modified
#by Deck's "dealOne()" method.
#It should have an __str__ method that lets you print out a Player's hand.
def __init__(self, isDealer):
self.hand = []
self.isDealer = isDealer
self.name = "Dealer" if self.isDealer else "You"
self.other = "Dealer" if not self.isDealer else "You"
self.has = "has" if self.isDealer else "have"
def __str__(self):
return ", ".join(map(str, self.hand))
def __repr__(self):
return self.__str__()
def discardHand(self):
self.hand = []
#property
def handTotal(self):
while sum(card.value for card in self.hand) > 21 and \
any(card.pip == 'Ace' and card.value == 11 for card in self.hand):
for card in self.hand:
if card.pip == 'Ace' and card.value == 11:
card.value = 1
break
return sum(card.value for card in self.hand)
def blackjack(self):
print ("%s %s %s for a total of 21" %
(self.name, self.has, str(self)))
print ("%s %s a Blackjack! %s win%s!" %
(self.name, self.has, self.name, "s" if self.isDealer else ""))
print ("Thanks for playing. Come back again soon! ")
#chips=chips+(bet*500)
score+1
return message()
def bust(self):
print ("%s hold%s %s for a total of %s" %
(self.name, "s" if self.isDealer else "", str(self), str(self.handTotal)))
print ("%s Bust%s! %s Win%s!" %
(self.name, "s" if self.isDealer else "", self.other, "s" if not self.isDealer else ""))
print ("Thanks for Playing! Come Back Soon!")
# chips=chips-2
return message()
class Deck:
#When you create an instance of Deck, it should add 52 Card objects to an instance variable "cardList".
#It should have a shuffle() method that rearranges the cards in cardList. You can do this easily by importing the
#"random" package into Python, and using the random.shuffle() method. random.shuffle(myList) rearranges the
#elements of the list "myList" into a random order.
#It should have a dealOne() method that removes the first card from your deck's cardList, and appends it to the
#hand of a specified player.
#It should have an __str__ method that lets you print out the entire deck for debugging purposes.
freshDeck = []
for i in range(len(suits)):
for j in range(len(pip)):
freshDeck.append(Card(suits[i], pip[j]))
def __init__(self):
self.cardList = self.freshDeck[:]
def shuffle(self):
random. shuffle (self.cardList)
def dealOne(self, player):
if len(self.cardList) < 4:
print("Out of cards... shuffling a new deck...")
exit
#self.cardList = self.freshDeck[:]
#self.shuffle()
(player.hand).append(self.cardList[0])
del self.cardList[0]
#print(self.cardList)
shuffle(self.cardList)
return self.cardList
def __str__(self):
printString = ""
for i in range(len(self.cardList)):
if i % 13 == 0:
printString += "\n \t"
printString += str(self.cardList[i]) + " "
else:
printString += str(self.cardList[i]) + " "
printString += "\n"
return printString
def showHands(player, opponent):
print ('Dealer shows ' + str(opponent.hand[0]) + ' faceup')
print ('You show ' + str(player))
def turn(deck, player, other):
#First, check scores to see if either player has a blackjack:
if player.handTotal == 21:
return player.blackjack()
if other.handTotal == 21:
return other.blackjack()
#See if the dealer less 16
hitOrStand = 0
while hitOrStand != 2:
print (player.name + ' hold%s ' % ("s" if player.isDealer else "") + str(player) + ' for a total of ' + str(player.handTotal) + '\n')
if player.isDealer:
if player.handTotal < 16:
hitOrStand = 1
if player.handTotal >= other.handTotal:
hitOrStand = 2
else:
hitOrStand = input('Do you hit or stand? Enter "1" for hit and "2" for stand: ')
while hitOrStand != 1 and hitOrStand != 2:
try:
hitOrStand = int(hitOrStand)
break
except ValueError:
print ("Enter a valid integer \n")
hitOrStand = input('Do you hit hit or stand? Enter "1" for hit and "2" for stand: ')
print()
if hitOrStand == 1:
print('Card dealt: ' + str(deck.cardList[0]) + '\n')
deck.dealOne(player)
if player.handTotal == 21:
return player.blackjack()
if player.handTotal > 21:
return player.bust()
#if player.handTotal <16 :
#return player.bust()
if hitOrStand == 2:
if player.isDealer:
print ("Dealer stands at " + str(player.handTotal))
global price
price=bet*500*2
print (price )
print ("Dealer Wins!")
return message()
else:
print (player.name + ' stand at: ' + str(player.handTotal))
print()
print ("Now Dealer's Turn\n")
def message():
global playing
again = raw_input("Do you want to play again? (Y/N) : ")
if again.lower() == "n":
print("\n\n-------Thank you for playing!--------\n\n")
playing = False
return True
#who won
def betValidation():
global number
number=input("Enter amount: ")
number
if (number<5000):
print "Minimum amount is 5000!!! "
exit()
elif (number > 50000):
print "You Exceeding the Maximum Amount...."
exit()
elif (number==5000 , number<=50000):
if number%500==0:
print ""
else:
print "Invalid"
exit()
def main():
cardDeck = Deck()
global bet
bet1=betValidation()
while playing:
global chips
print "Score:",score
chips=number/500
print "You have", chips ,"chips!"
betchips=chips/2
global bet
bet=input("How much would you like to bet: ")
if(bet==0):
print "Invalid"
elif (bet>=betchips):
if bet%1==0:
player = Player(isDealer=False)
opponent = Player(isDealer=True)
player.discardHand()
opponent.discardHand()
#give each player 2 cards, alternating
cardDeck.dealOne(player)
cardDeck.dealOne(opponent)
cardDeck.dealOne(player)
cardDeck.dealOne(opponent)
#show 1 faceup card for each player
showHands(player,opponent)
#start playing
if turn(cardDeck,player, opponent):
continue
turn(cardDeck, opponent, player)
main()
I imagine your problem lies in the function blackjack() but you haven't posted that.

Creating a Class Attribute dependent on Another Attribute

I am currently working on a small RPG in Pygame to get used to object oriented coding.
When looking into how to auto-update a property I came across the following:
class P:
def __init__(self,x):
self.x = x
#property
def x(self):
return self.__x
#x.setter
def x(self, x):
if x < 0:
self.__x = 0
elif x > 1000:
self.__x = 1000
else:
self.__x = x
I tried applying it to my code but I get the following error:
File "weapons.py", line 13, in __init__
self.name = '{} {}'.format(ammo, self.raw_name)
TypeError: name() takes exactly 3 arguments (2 given)
I understand what the error is but I don't get how to solve it since I need both the raw_name and the ammo attributes to auto-update my Arrow instance's name.
My class is as such:
class Projectile(Item):
def __init__(self, name, value, image, x, y, speed, dmg, dmg_modif, ammo):
super(Projectile, self).__init__(name, value, image, x, y)
self.dest = (self.rect[0],self.rect[1])
self.speed = speed
self.dmg_modif = dmg_modif
self.dmg = dmg
self.orientation = 0
self.ammo = ammo
#property
def name(self):
return self.___name
#name.setter
def name(self, raw_name, ammo):
if '{} {}'.format(raw_name,ammo) != self.___name:
self.___name = '{} {}'.format(raw_name,ammo)
The child class which returns the error is:
class Arrow(Projectile):
def __init__(self, ammo): #name, value, image, x, y, dmg
self.raw_name = 'Arrows'
self.name = '{} {}'.format(ammo, self.raw_name)
self.value = 5
self.image = variables.quiver_img
self.speed = 4
self.dmg = 2
self.dmg_modif = 1
super(Arrow, self).__init__(self.name, self.value, self.image, 200, 150, self.speed, self.dmg, self.dmg_modif, ammo)
And the parent classes are, Item and MySprite:
class Item(MySprite):
def __init__(self, name, value, image, x, y):
# Call the parent class (Sprite) constructor
super(Item, self).__init__(image, x, y)
self.name = name
self.value = value
self.inv_pos = -1
and
class MySprite(pygame.sprite.Sprite):
def __init__(self,image,x,y):
# Call the parent class (Sprite) constructor
super(MySprite, self).__init__()
self.image = image
self.rect = self.image.get_rect().move(x, y) #initial placement
self.top_cp = (self.rect[0]+self.rect[2]/2,self.rect[1])
self.bot_cp = (self.top_cp[0],self.rect[1]+self.rect[3])
self.left_cp = (self.rect[0],self.rect[1]+self.rect[3]/2)
self.right_cp = (self.left_cp[0]+self.rect[2],self.left_cp[1])
self.center = self.rect.center
self.pos = self.rect.topleft
self.blit_order = 1
self.level = variables.current_level #Level(1)#level to which sprite belongs
Any help would be welcome !
Please provide a minimal example next time.
Your code looks a little complicated. OK, the first problem is that you can't pass multiple arguments to a setter. You can either pass a tuple or just use a traditional setter method def set_name(self, name, ammo):.
Another problem is that you use the ___name attribute before it has been set, for example in the second line of the Arrows __init__ method.
Private attributes should have one underscore not three (that's just a convention to warn other programmers). If you have two or more underscores than the name gets mangled.
Also, it looks to me like you change the name in the setter only if the new name is equal to the old name (kinda pointless ;)). What do you actually want to do there? Maybe you don't need properties at all.
Here's a fixed (minimal) version of your code:
import pygame
class MySprite(pygame.sprite.Sprite):
def __init__(self):
super(MySprite, self).__init__()
class Item(MySprite):
def __init__(self, name):
super(Item, self).__init__()
self.name = name
class Projectile(Item):
def __init__(self, name):
super(Projectile, self).__init__(name)
#property
def name(self):
return self._name
#name.setter
def name(self, name):
self._name = name + ' foo'
class Arrow(Projectile):
def __init__(self):
super(Arrow, self).__init__(name='Arrows')
arrow = Arrow()
print(arrow.name)
arrow.name = 'New name'
print(arrow.name)
So I eventually managed to solve my problem:
class Projectile(object):
def __init__(self, raw_name, ammo):
self.raw_name = raw_name
self.name = self.raw_name
self.ammo = ammo
#property
def ammo(self):
return self._ammo
#ammo.setter
def ammo(self, ammo):
self.name = str(ammo) + self.raw_name
self._ammo = ammo
class Arrow(Projectile):
def __init__(self):
self.raw_name = ' Arrows'
self.name = self.raw_name
super(Arrow, self).__init__(self.raw_name, ammo
= 10)
arrow = Arrow()
print arrow.ammo
print arrow.name
arrow.ammo = 15
print arrow.ammo
print arrow.name
gives:
>>>10
>>>10 Arrows
>>>15
>>>15 Arrows

setting an attribute at create retrieves None value - Python

So I have an Article class that models the articles in a store. When I create a new article, I want it to have an EAN 13 code. So I initialize the article with a 12 digits code and use the check_ean13() funtion to retrieve the control digit. It works but seems like in any moment, when the object is created, rewrite the ean13 attribute and replaces it for None. Any ideas?
Main
if __name__ == "__main__":
# create article
art1 = Article("123456789087", "Article 1", 145.6, 200.0)
print art1
print art1.get_ean13()
class Article
class Article:
def __init__(self, cod, art_name, cost, listprice):
self.ean13 = self.set_ean13(cod)
self.art_name = art_name
self.cost = cost
self.listprice = listprice
self.commission = None
self.promotion=[]
def get_ean13(self):
return self.ean13
def set_ean13(self,cod):
cd = self.check_ean13(cod)
ean13 = cod + str(cd)
self.ean13=ean13
def check_ean13(self, code):
checksum = 0
for i, digit in enumerate(reversed(code)):
checksum += int(digit) * 3 if (i % 2 == 0) else int(digit)
return (10 - (checksum % 10)) % 10
output:
None - Article 1 list price: 400.0
None
self.ean13 = self.set_ean13(cod)
set_ean13 doesn't return anything, so you're effectively doing self.ean13 = None here. Just call the method without assigning the result.
self.set_ean13(cod)

Using logic in your update methods

I'm working on a little game with some fellow students and I'm wanting some guidance on how to handle the problem...
With my code what it boils down to is I want to call into use the Boss_Shoot Class where the Boss class update() starts printing "should be shooting" .. the print statement statements seen through out are nothing more then a "placeholder of sorts...
As always Thanks so much!
class Boss(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("sprites/boss.png")
self.rect = self.image.get_rect()
self.dx = 1
self.dy = 1
self.shoot= True
def update(self):
if self.rect.centerx >= 600:
self.rect.centerx -= self.dx
elif self.rect.centerx <= 600:
print "should be shooting"
self.rect.centery -= self.dy
self.checkBounds()
def checkBounds(self):
if self.rect.top <= 0:
self.dy *= -1
print
if self.rect.bottom >= 500:
self.dy *= -1
class Boss_Shoot(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((20, 20))
self.image.fill((255, 0, 0))
self.rect = self.image.get_rect()
self.rect.center = (320, 240)
self.dy =2
def update(self):
if self.shoot == True:
print "shooting"
for i in range(100):
print "wtf man"
self.rect.x = random.randrange(1000, 3000)
self.rect.y = random. randrange(10, 490)
self.rect.x -= 5
self.rect.y +=self.dy
You need a way your actors (or Sprites, or whatever you call your "entities") can communicate with the global state of your game.
You didn't show all your code, so I assume everything is in one file.
Somewhere in your code, you probably have a list of all actors (and if you don't, you should create one). Let's assume it's defined as:
actors = []
Maybe you use a single list, maybe you want to use pygame's Group class.
I further assume you call the update() method on all actors in your mainloop, like:
for a in actors:
a.update()
(or, if you use pygame's Group class, something like mygroup.update()).
Now, in the update() method of Boss, just create a new instance of Boss_Shoot, and add it to the list of actors, like:
def update(self):
if self.rect.centerx >= 600:
self.rect.centerx -= self.dx
elif self.rect.centerx <= 600:
actors.append(Boss_Shoot())
You probably want to pass the position of Boss to the Boss_Shoot constructor so the bullet (or whatever) doesn't randomly appear on the screen (if you want to).
I prefer encapsulating the gamestate into a seperate dict or class, and pass that down to each actor so each actor can register/unregister itself from the world, something like:
class State(object):
def __init__(self):
self._actors = []
def register(self, actor):
self._actors.append(actor)
def unregister(self, actor):
self._actors.remove(actor)
def update(self):
for a in self._actors:
a.update()
...
class Boss(pygame.sprite.Sprite):
def __init__(self, state):
self.state = state
self.state.register(self)
...
def update(self):
if self.rect.centerx >= 600:
self.rect.centerx -= self.dx
elif self.rect.centerx <= 600:
self.state.register(Boss_Shoot(self.state))
class Boss_Shoot(pygame.sprite.Sprite):
def __init__(self, state):
self.state = state
self.state.register(self)
...
while True:
state.update()
state.draw(screen)
...
You'll get the idea.

Issue with an exception from a class, how to get it to return the main-script?

I'm having an issue with an exception in my class. I want it to return to my main-script if that's even possible, or any solution which will avoid any crashing of my program. I'll show you the code.
Here's the main script:
from requestnew import requestNew
def chooseCountry():
countryc = input("Enter which country your city is in(in english): ")
rq.countrychoice.append(countryc)
def chooseCity():
cityc = cityc = input("Enter the name of the city: ")
rq.citychoice.append(cityc)
def makeForecast():
try:
for day in rq.data['forecast']['simpleforecast']['forecastday']:
print ("Country: ", rq.countrychoice[-1], "City: ", rq.citychoice[-1])
print (day['date']['weekday'] + ":")
print ("Conditions: ", day['conditions'])
print ("High: ", day['high']['celsius'] + "C", '\n' "Low: ", day['low']['celsius'] + "C", '\n')
except Exception as e:
print ("\nHave you typed in the correct country and city?\nBecause we got a" ,'"',e,'"', "error\nplease try again!")
return menu
if __name__ == '__main__':
"""Introducion"""
print ("\nThis program lets you see a weather forecast for your choosen city.")
rq = requestNew()
while True:
try:
print("\nWhen you have typed in country and city, press 3 in the menu to see the weather forecast for your choice.\n")
menu = int(input("\nPress 1 for country\nPress 2 for city\nPress 3 to see forecast\nPress 4 to exit\n"))
if menu == 1:
chooseCountry()
elif menu == 2:
chooseCity()
elif menu == 3:
rq.forecastRequest()
makeForecast()
elif menu == 4:
print ("\nThank you for using my application, farewell!")
break
elif menu >= 5:
print ("\nYou pressed the wrong number, please try again!")
except ValueError as e:
print ("\nOps! We got a ValueError, info:", e, "\nplease try again!")
continue
And here is my class code:
import requests
import json
class requestNew:
def __init__(self):
self.countrychoice = []
self.citychoice = []
def countryChoice(self):
self.countrychoice = []
def cityChoice(self):
self.citychoice = []
def forecastRequest(self):
try:
r = requests.get("http://api.wunderground.com/api/0def10027afaebb7/forecast/q/" + self.countrychoice[-1] + "/" + self.citychoice[-1] + ".json")
self.data = r.json()
except #?
As you can see above I use an exception in the def forecastRequest(self):. The problem is I don't know which exception and how to return it correctly to avoid any program crashes.
If you look at my main-script you can see that I have while True: to loop everything from the menu.
Everything in the program works correctly except if I press 3; elif menu == 3: without choosen both country from def chooseCountry(): or city from def chooseCity():.
This is because I'm using a list in my class and then print it in the def forecastRequest(self): like this; countrychoice[-1] to get the last appended list-item from input. And when I press 3 in the menu without choosing country or city, the list will be empty.
My question is, is there any way to let the except #? in def forecastRequest(self): to return the user to the menu in my main-script? Or is there any other way to avoid the program of crashing if the list is empty when I try to make the request?
Sorry for my english, and sorry if my explaining is messy, I've tried my best for it to be relatively easy to understand as possible.
If you want control to return to the main loop, catch the exception in the main loop:
elif menu == 3:
try:
rq.forecastRequest()
except IndexError:
# self.countrychoice[-1] will raise an IndexError if self.countrychoice is empty
# handle error
else:
makeForecast()