python classes adding numbers - python

I need to write a class, Numbers, with methods addNumbers and currentSum, that prints the current sum. Eg.:
numbers = Numbers()
numbers.addNumber(3)
numbers.addNumber(2)
print numbers.currentSum()
should print 5
I have made a class:
class Numbers:
def __init__(self, numbers):
self.numbers=addNumbers
return numbers.currentSum()
Numbers=Numbers()
A hint, anyone?

class Numbers:
def __init__(self):
self.__sum=0
def addNumber(self, number):
self.__sum += number
def currentSum(self):
return self.__sum

Hints:
You need to implement the currentSum() method
You also need to implement the addNumber() method
addNumber() will need to keep track of numbers across method calls. Use a list.
More reading on methods: What is a "method" in Python?

class Numbers(object):
def __init__(self):
self.sum = 0
def addNumber(self, n):
self.sum += n
def currentSum(self):
return self.sum

Related

Referencing other objects of same class in a method of a class in Python

I am new to programming and learning Python. Right now I am trying to figure out howto write a value to another object of the same class inside of a method definition inside the class. I mean something like this:
class myClass:
def __init__(self, attribute, lst = True):
self.attribute = attribute
if lst is True:
self.lst = []
def add_amount(self, amount):
self.lst.append(dict(Amount = amount))
def total:
self.total = []
for each in self.lst:
self.total.append(each.get("Amount"))
self.total = sum(self.total)
#def transfer(self, amount, attribute):
#here I would like to be able to add
#a value (for example self.total) to
#the lst [] of a different instance of
#this class
firstInstance = myClass("First")
secondInstance = myClass("Second")
firstInstance.add_amount(10)
firstInstance.add_amount(20)
##firstInstance.transfer(15, "Second")
#How can I write the transfer
#function so that it will add
#the value of the first argument
#to the empty list of the instance
#object with the attribute "Second"
#(in this case secondInstance)?
How do I have to program that? I hope I explained my problem in an understandable way, hope you guys can help me! Thanks in advance! :)
Kind regards
You would have to pass the secondInstance as an argument to your transfer function. You could potentially do something like this:
class myClass:
def __init__(self, attribute, lst = True):
self.attribute = attribute
if lst is True:
self.lst = []
def add_amount(self, amount):
self.lst.append(dict(Amount = amount))
def subract_amount(self, amount):
# TODO
pass
def total:
self.total = []
for each in self.lst:
self.total.append(each.get("Amount"))
self.total = sum(self.total)
def transfer(self, amount, other):
self.subtract_amount(amount)
other.add_amount(amount)
firstInstance = myClass("First")
secondInstance = myClass("Second")
firstInstance.add_amount(10)
firstInstance.add_amount(20)
firstInstance.transfer(15, secondInstance)

not all attributes defined in __init__?

I've seen the following code.
class Primes:
def __init__(self, max):
self.max = max
self.number = 1
def __iter__(self):
return self
def __next__(self):
self.number += 1
if self.number >= self.max:
raise StopIteration
elif check_prime(self.number):
return self.number
else:
return self.__next__()
In the dunder init function, we set self.number=1, without having included earlier the attribute number. What's the meaning of it?
This code, only means that self.number is not customizable and will always values 1 when creating an instance of Primes. This is used when the class need an attribute, which will be used along its state and methods, but it's value should always be the same when instanciating the object
def __init__(self, max):
self.max = max
self.number = 1

How to determine if a class was instantiated by a method in another class?

def _check_value(number):
if not 0 <= number <= 10:
raise ValueError
return number
class A:
def __init__(self, number):
self.number = _check_value(number)
class B:
def __init__(self):
self.factor = 2
def my_algorithm(self, number):
number = _check_value(number)
number += 1 * self.factor
return A(number)
The above example is a simplified version of my code. Class A can be instantiated directly or by the method my_algorithm() in class B. I need to check the number value in both cases. My problem is that when I instantiated class A using the method in class B, there will be a double checking for number value.
My question is how to know that class A was instantiated using the method in class B in order to avoid double checking? Or is there any better solution?
I am not 100% following your question on instances, but I reckon you don't have to check the value twice? Could try ... except be of help here?
def _check_value(number):
if not 0 <= number <= 10:
raise ValueError
return number
class A:
def __init__(self, number):
self.number = _check_value(number)
class B:
def __init__(self):
self.factor = 2
def my_algorithm(self, number):
try:
return A(number + 1 * self.factor)
except ValueError: # not a very descriptive error, but nbd
print("Provided value is out of bounds")
I ended up with following code to avoid double checking:
def _check_value(number):
if not 0 <= number <= 10:
raise ValueError
return number
class A:
def __init__(self, number, check=True):
if check:
self.number = _check_value(number)
else:
self.number = number
class B:
def __init__(self):
self.factor = 2
def my_algorithm(self, number):
number = _check_value(number)
number += 1 * self.factor
return A(number, check=False)

Repeat class method in Python

I would like to repeat a class method several times (26 to be exact) so that I can split a deck of cards to two separate decks. I tried [:26] and [26:] (obviously for lists only) in addition to d1=Deck() then deck1 = d1.deal()*26 and they both did not work. I just learned how to create Classes.
Desired output is deck1=["""26 random cards"""] and deck2=["""26 random cards"""].
Relevant code:
import random
suits = ['H','C','S','D']
ranks = ['A']+list(map(str,range(2,10)))+['X','J','Q','K']
values = [14]+list(range(2,14))
class Card:
def __init__(self,suit,rank):
self.suit=suit
self.rank=rank
self.value=values[ranks.index(self.rank)]
def __str__(self):
return "*------*\n|{0}{1} |\n| |\n| {0}{1}|\n*------*".format(self.rank,self.suit)
def __gt__(self,other):
return self.value > other.value
def __lt__(self,other):
return self.value < other.value
def __eq__(self,other):
return self.value == other.value
class Deck:
"""This class is for creating deck"""
def __init__(self):
self.deck=[]
for suit in suits:
for rank in ranks:
self.deck.append(Card(suit,rank))
self.shuffle()
def __str__ (self):
tmp=''
for card in self.deck:
tmp+=str(card)+'\n'
return tmp
def shuffle(self):
random.shuffle(self.deck)
def deal(self):
return self.deck.pop()
So the order of operations is going to execute your function once, then repeat the result 26 times. You probably want something more like:
deck1 = [d1.deal() for _ in range(26)]
Whenever you want to repeat an action a certain number of times, use a for loop.
d2 = []
for i in range(26):
d2.append(d1.deal())
There's no way for your code at the moment to create an empty deck. Maybe you should have a __init__ that creates an empty deck and then a separate method to make a full deck? Just a thought.

How should my __lt__ code look like if I want .sort() to work on my list of classes

I have created a carddeck and every player is assigned a hand. I would like the players to be able to arrange their hand with the lowest value first and then print out this hand. I would like to think this can be done with .sort() but atm I'm getting a message
TypeError: unorderable types: NumberedCard() < NumberedCard()
I got a tip from the net that if I defined how .sort() is to work through a correct def __lt__(self, other): then I wouldn't be having this problem. So help me programmers figure this one out. Every card is defined by value and suit.
My code looks like this:
import random
suitlist=["Hearts","Spades","Clubs","Diamonds"]
class NumberedCard():
def __init__(self,value,suit):
self.value=value
self.suit=suit
def __str__(self):
return '%s of %s' %(self.value,suitlist[self.suit])
class JackCard():
def __init__(self,suit):
self.suit=suit
self.value=11
def __str__(self):
return 'Jack of %s' %(suitlist[self.suit])
class QueenCard():
def __init__(self,suit):
self.suit=suit
self.value=12
def __str__(self):
return 'Queen of %s' %(suitlist[self.suit])
class KingCard():
def __init__(self,suit):
self.suit=suit
self.value=13
def __str__(self):
return 'King of %s' %(suitlist[self.suit])
class AceCard():
def __init__(self,suit):
self.suit=suit
self.value=14
def __str__(self):
return 'Ace of %s' %(suitlist[self.suit])
class StandardDeck():
"""A class that creates a deck of 52 different cards, that also gives options to do matching operations with them"""
def __init__(self):
self.deck = []
for suit in range(4):
for value in range(2,11):
card = NumberedCard(value,suit)
self.deck.append(card)
self.deck.append(JackCard(suit))
self.deck.append(QueenCard(suit))
self.deck.append(KingCard(suit))
self.deck.append(AceCard(suit))
#for k in range(52):
# print(self.deck[k])
def shuffle(self):
"""Shake n' bake with the cards."""
random.shuffle(self.deck)
def take_card(self):
return self.deck.pop()
def deal_cards(self, hand,num):
for i in range(num):
hand.add_card(self.take_card())
class Hand:
"""A class to do the usual poker things during the game. Ie pick up cards, drop cards etc."""
def __init__(self):
self.hand = []
def __str__(self):
Handen=""
for card in self.hand:
Handen+=str(card) + "\n"
return Handen
def add_card(self,card):
self.hand.append(card)
def sort_cards(self):
self.hand.sort()
####Testing the program
deck=StandardDeck()
deck.shuffle()
hand=Hand()
hand.add_card(deck.take_card())
hand.add_card(deck.take_card())
print(hand)
hand.sort_cards() # <---- This is the part not working
So how is it done and where should it be put?
The best way to salvage this would be to create a class Card which would have a value and the __lt__ or __gt__ and a __eq__ defined method. And then proliferate those method by having all the other cards inherit from that parent class.
The proposed methods could be as simple as just compairing values of value which is an int and python knows how to do it himself.
Something like this:
>>> class Card(object):
def __init__(self, value):
self.value = value
def __lt__(self, other):
if other.value > self.value:
return True
return False
>>> class Ace(Card):
def __init__(self, value):
super().__init__(value)
>>> class NumCard(Card):
def __init(self, value):
super().__init__(value)
>>> jack = Ace(12)
>>> n = NumCard(7)
>>> jack > n
True
>>> n > jack
False
If you only want to sort the list in self.hand why not just use the key argument for sort to create a function to return the value to sort on?
self.hand.sort(key=lambda x: x.value)
This link should provide some info on sorting techniques

Categories

Resources