Python - Classes- Definition - python

I programmed a class aswell as a definition with the backthought the when you,
set everytime a value using class variable you can always recall the total amount by using the definition
class Hand():
def __init__(self, Hand=0):
self.Hand = Hand
def getHand(self, neue_Hand):
self.Hand = neue_Hand
def set_hand(self):
return self.Hand
c = Hand()
def Aufruf():
Total = 0
Total += c.getHand(0)
return Total
c.getHand(12)
Aufruf()
It changes the value each time, but doesn't accumulate it as it supposed to be.

You've mixed up the functionality in your getters and setters. The getter should return the variable and the setter should set the value.
class Hand():
def __init__(self,Hand=0):
self.Hand = Hand
def getHand(self):
return self.Hand
def set_hand(self, neue_Hand):
self.Hand = neue_Hand
def increment_hand(self, neue_Hand_incremenet):
self.Hand += neue_Hand_incremenet
c = Hand(10)
c.getHand()
>> 10
c.set_hand(20)
c.getHand()
>> 20
def Aufruf():
Total = 0
Total += c.getHand()
return Total
Aufruf()
>> 20
c.increment_hand(10)
Aufruf()
>> 30
Also as a side note:
If you look closely, you will realise your method Aufruf is actually an exact duplicate (logically) of the getHand() method. When you instantiate the variable total = 0 inside the method block of code, this value will ALWAYS be set to 0 when the method is called, meaning the value from c.getHand() will ALWAYS just be the value that's returned

Use method addition for changing value, and don't use capital letters or camelCase inside your class.
class Hand:
def __init__(self, 0):
self.hand = hand
def get_hand_bigger(self, addition):
self.hand += addition

Your class method getHand does not return any value, yet it is being called as such. Try this:
def getHand(self, neue_Hand):
self.Hand = neue_Hand
return self.Hand

Related

Class method uses an array not passed

So, I'm tring to program a variant of the knapsack problem but I'm really new to the use of Python and I stumbled on this.
I'm using Jupyter (Python 3)
class Gene(object):
def __init__(self, weight, price):
self.weight = weight
self.price = price
obj1 = Gene(10, 20)
obj2 = Gene(25, 5)
obj3 = Gene(5, 10)
genes = [obj1, obj2, obj3]
class Chromosomes(object):
def __init__(self, flagIndex_of_items_contained = []):
self.flagIndex_of_items_contained = flagIndex_of_items_contained
self.myWeight = self.Define_myWeight()
def Define_myWeight(self):
weight = 0
for index_flag in range(len(self.flagIndex_of_items_contained)):
if(self.flagIndex_of_items_contained[index_flag] == 1):
weight = weight + genes[index_flag].weight
return weight
chromosome1 = Chromosomes([1,0,1])
print("chromosome1 weight: ", chromosome1.myWeight)
Output
chromosome1 weight: 15
BUT
genes[index_flag].weight
How can this command work if i don't pass the array genes to the class?
The problem is that your variable genes lives on the same level as the classes, the module level. In the problematic line
weight = weight + genes[index_flag].weight
the interpreter simply sees that there is no local variable with the scope of the function Define_myWeight, hence it checks the global scope (module level). On this level genes exists and the interpreter can use it.
Besides that, issues because of which your code has been considered "badly written".
Use global variables only if they are absolutely necessary. Check some arbitrary tutorial on globals to understand this proposition.
You should never use a mutable object as default parameter. Lists are mutable objects in Python, that means they can be changed. Use immutable objects, like tuples, in such cases.
def func1(some_arg = []): # bad
def func1(some_arg = ()): # ok
Do not mix different format styles. Use either CamelCase or names_with_underscores. Check out the Python Style Guide for that.
Here is an idea to improve your code. Chromosomes are made up of different genes. The following code models this relation.
class Gene:
def __init__(self, weight, price):
self.weight = weight
self.price = price
class Chromosom:
def __init__(self):
self.genes = []
self.flag_idx = []
self.weight = 0
def add_gene(self, weight, price):
self.genes.append(Gene(weight, price))
def compute_weight(self, flags):
for i, flag in enumerate(flags):
if flag == 1:
self.weight += self.genes[i].weight
Usage:
ch = Chromosom()
ch.add_gene(10, 20)
ch.add_gene(25, 5)
ch.add_gene(5, 10)
ch.compute_weight((1, 0, 1))
print(ch.weight)

How can I automate the creation of instances of a class?

So in python 3 I am having trouble creating multiple instances of a class automatically. I am trying to make monopoly and here is the code sample that is giving me problems.
def numplayer():
numplayer = int(input('How many players would you like? (up to four)'))
while numplayer > 4 or numplayer < 1:
numplayer = int(input('How many players would you like? (up to
four)'))
for i in range(numplayer):
PlayerMoney.append(1500)
What I want to do is also add something that will create the number of players that numplayers equals to in the for i in range(numplayer) function. I have the player as a class but I don't want to manually create every single class for every player. If there is a solution to this, please do tell. Thanks!
EDIT: So I think this might be bad wording in the title but I'm trying to create multiple instances of a single class (the player).
Here is the code for the player class:
class Player:
def __init__(self, name, money, position):
self.name = name
self.money = money
self.position = position
def DiceRoll(self):
x = random.randint(1, 6)
y = random.randint(1, 6)
sum = x + y
return [sum, x, y]
def getName(self):
return sef.name
def getMoney(self):
return self.money
def getPosition(self):
return self.position
# Create Class
class Player:
def greating(self):
print 'Hello!'
# List to store instanses
l = []
for i in range(4):
l.append(Player())
# Call Instance #1 methods
l[0].greating()
Here we have a player class and 4 instances from this class stored in l list.
I would advise you structure your code as below. It's usually a good idea for your function to return something.
def setup():
n = int(input('How many players would you like? (up to 4)'))
names = [input('Give name #{0}'.format(i)) for i in range(1, n+1)]
return [Player(name, 1500, 0) for name in names]
players = setup()

Remove an object from a list of objects

I basically have 3 classes. Card, Deck, and Player. The Deck is a list of cards. I am trying to remove a card from the deck. But I am getting a ValueError saying that the card is not in the list. From my understanding, it is and I am passing the correct object through the removeCard function. I am not sure why I am getting a ValueError. So in short, the problem is that I need to remove an object (Card) from a list of Cards.
My issue is that when I try to remove a card from the deck I get an error like this:
ValueError: list.remove(x): x not in list
This is what I have so far:
Card class:
import random
class Card(object):
def __init__(self, number):
self.number = number
Deck class (the error is thrown here, in the removeCard function):
class Deck(object):
def __init__(self):
self.cards = []
for i in range(11):
for j in range(i):
self.cards.append(Card(i))
def addCard(self, card):
self.cards.append(card)
def removeCard(self, card):
self.cards.remove(card)
def showCards(self):
return ''.join((str(x.number) + " ") for x in self.cards)
Player class:
class Player(object):
def __init__(self, name, hand):
self.name = name
self.hand = hand
main function:
def main():
deck = Deck()
handA = [Card(6), Card(5), Card(3)]
handB = [Card(10), Card(6), Card(5)]
playerA = Player("A", handA)
playerB = Player("B", handB)
print("There are " + str(len(deck.cards)) + " cards in the deck.")
print("The deck contains " + deck.showCards())
for i in handA:
deck.removeCard(i)
print("Now the deck contains " + deck.showCards())
main()
When you call list.remove, the function searches for the item in the list, and deletes it if found. When searching, it needs to perform a comparison, comparing the search item to every other list item.
You're passing an object to remove. A user defined object. They do not behave the same way as, say, integers would, when performing comparisons.
For example, object1 == object2, where object* are objects of the Card class, by default are compared against their unique id values. Meanwhile, you want a comparison to be performed against the card number, and removal done accordingly.
Implement an __eq__ method in your class (python-3.x) -
class Card(object):
def __init__(self, number):
self.number = number
def __eq__(self, other):
return self.number == other.number
Now,
len(deck.cards)
55
for i in handA:
deck.removeCard(i)
len(deck.cards)
52
Works as expected. Note that in python-2.x, you'd implement __cmp__ instead.

Classes, objects and lists in python

so I'm trying to create a program but I still have difficulties with classes. The program (which isn't finished of course) will print a random number of Villages. Each village(second Class) will have a random number of Clans(the first Class). Anyway my problem is the Village class. How do I make sure to add the areas and family size into the Village class? How do I insert the counter from the Clan class to the Village class? As you can see when I've randomized a number of Clans the areas and family sizes should add up into the Village class. What should I do? What is wrong with my Village class?
class Clan:
counter = 0
def __init__(self):
r = random.randrange(20, 101)
self.area = r
s = random.randrange(1, 6)
self.familySize = s
Clan.counter += 1
self.counter = Clan.counter
def getArea(self):
return self.area
def getFamilySize(self):
return self.familySize
class Village:
counter = 0
def __init__(self):
self.clan_list = []
for i in range(random.randrange(3, 7)):
self.clan_list += [Clan()]
def getclan_list(self):
return self.clan_list
def getArea(self):
return self.area
def getPopulation(self):
pass
So, you want the village class to calculate how many families are in the village?
families = 0
for clan in self.clan_list
families += clan.getFamilySize()
Since the values of area and population are dependent on the clans in clan_list you should compute these values each time they are needed. The alternative is much more complicated -- having to control how clans are added and removed from the village and how the area and family size of a clan can be changed and having those changes reflected in the village.
Below is an example of how you might compute both village area and population. The first using a getter method, and the second using a more python-esque property.
import random
class Clan:
counter = 0
def __init__(self):
r = random.randrange(20, 101)
self.area = r
s = random.randrange(1, 6)
self.familySize = s
Clan.counter += 1
self.counter = Clan.counter
# removed getters
# Unless your getter or setter is doing something special,
# just access the attribute directly.
class Village:
def __init__(self):
self.clan_list = []
for i in range(random.randrange(3, 7)):
self.clan_list.append(Clan())
# for a village, area is a computed value, so use a getter
def getArea(self):
total_area = 0
for clan in self.clan_list:
total_area += clan.area
return total_area
# the prefered alternative to getters (and setters) are properties
# note that the function is named as if it was an attribute rather than function
#property
def population(self):
# use sum and generator rather than a for loop
return sum(clan.familySize for clan in self.clan_list)
# How to use a village instance
v = Village()
# get area
print("area:", v.getArea())
# get population
print("population:", v.population)
# note how population is accessed as if it was an attribute rather than called
# like a function

How to call method of other object in Python?

I am new in python, and I have small problem, I have two classes, and it wrotes this : set_gyro_angle() takes exactly 1 argument (2 given) how can I call set_gyro_angle() method from Machine method?
class Gyro(object):
"""gyroskop senzor"""
def __init__(self,gyro_start_angle = 0):
self.gyro_angle = 0
def get_gyro_angle():
return self.gyro_angle
def set_gyro_angle(angle):
self.gyro_angle = angle
return 0
class Maschine(object):
def __init__(self, state = "normal",length = 10,width = 15):
self.length = length
self.width = width
self.gyro = Gyro()
def setPoint(self,alpha):
self.gyro.set_gyro_angle(alpha)
return 0
Main:
maschine = Maschine()
maschine.setPoint()
If you want to create an instance method, you need to add an extra argument that will be a pointer to your instance. Usually it's self:
class Gyro(object):
"""gyroskop senzor"""
def __init__(self,gyro_start_angle = 0):
self.gyro_angle = 0
def get_gyro_angle(self):
return self.gyro_angle
def set_gyro_angle(self, angle):
self.gyro_angle = angle
return 0
And i think you want setPoint to be like this:
def setPoint(self, alpha):
self.gyro.set_gyro_angle(alpha)
All of your instance methods should have another parameter, self, before the others; this is the instance itself, and is passed automatically:
def set_gyro_angle(self, angle):
Alternatively, skip the setter:
self.gyro.gyro_angle = alpha
Machine.gyro.set_gyro_angle(45)
However you need to fix your code by adding the self parameter as the first parameter of your class methods.

Categories

Resources