While practicing OOP with inheritance in my second class I have problems adding my parameters, as you can see I have: (self, name, tred, PM, PM2, ra, ra2). But when run the program it tells me that I can not multiply Nonetype, I print them to see what's wrong and i get that some of the parameters are incorrect.
The first class works fine (Atomic_d), I just need to understand how does it work the variables in the second class: Molecular_d
How can I fix this?
This is the complete code picture
import math
class Atomic_d():
def __init__(self,name="",red="",PM=None,ra=None):
self.name = name
self.red = red
self.PM = PM
self.ra = ra
def density(self):
redes = {"BCC":2,"FCC":4,"HCP":6}
self.red = self.red.upper()
nred = redes.get(self.red)
nav = round(6.022*(10**23),3)
if nred == 2:
a = (4*(self.ra))/((3)**0.5)
elif nred == 4:
a = (4*(self.ra))/((2)**0.5)
else:
per = round(12 * self.ra,3)
hipoc = round((2*self.ra)**2,3)
basec = round(self.ra**2,3)
apo = round(math.sqrt(hipoc - basec),3)
a = round((per * apo / 2),3)
if nred == 2 or nred == 4:
vol = a**3
elif nred == 6:
vol = round(a * 3.266 * self.ra,3)
density = round((((nred*self.PM)/(nav*vol))*10**21),3)
return "{} : {} g/cc".format(self.name,density)
class Molecular_d(Atomic_d):
def __init__(self,name="",tred="",PM=None,ra=None,PM2=None,ra2=None):
super().__init__(name,PM,ra)
self.PM2 = PM2
self.ra2 = ra2
self.tred = tred
def density(self):
tredes = {"NACL":8}
self.tred = self.tred.upper()
nred = tredes.get(self.tred)
nav = round(6.022*(10**23),3)
if nred == 8:
l = round(((2*self.ra)*(2*self.ra2)),3)
vol = l**3
density = ((8*(self.PM + self.PM2))/(nav*vol))
return "{}: {} g/cc".format(self.name,density)
This is the error that happens when I try to debug
I print every variable to see what is the problem
print("Hi I'm name",self.name)
print("Hi I'm ra",self.ra)
print("Hi I'm ra2",self.ra2)
print("Hi I'm PM",self.PM)
print("Hi I'm PM2",self.PM2)
Hi I'm name Ox de magnesio
Hi I'm ra None
Hi I'm ra2 0.14
Hi I'm PM 16.0
Hi I'm PM2 0.072
Traceback:
TypeError Traceback (most recent call last)
<ipython-input-21-bb7a69690a34> in <module>
1 magnesium_ox = Molecular_d("Ox de magnesio","NaCl",24.31,16.0,0.072,0.14)
2
----> 3 magnesium_ox.density()
<ipython-input-19-064f60b8cfce> in density(self)
52
53 if nred == 8:
---> 54 l = round(((2*self.ra)*(2*self.ra2)),3)
55 vol = l**3
56
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
When you make the call to super()_init(), you leave out the red argument. Python assumes that the three arguments you are passing are name, red, and pa, even though that's seems not to be what you intended.
When you don't attach parameter= to an argument, Python assumes you are giving them from left to right. You need to write:
super().__init__(name=name, PM=PM, ra=ra)
You need to be using keyword arguments if you are not going to put them same order as the class. Try changing the Molecular_d to this below:
class Molecular_d(Atomic_d):
def __init__(self,name="",tred="",PM=None,ra=None,PM2=None,ra2=None):
super().__init__(name=name,PM=PM,ra=ra)
self.PM2 = PM2
self.ra2 = ra2
self.tred = tred
def density(self):
tredes = {"NACL":8}
self.tred = self.tred.upper()
nred = tredes.get(self.tred)
nav = round(6.022*(10**23),3)
if nred == 8:
l = round(((2*self.ra)*(2*self.ra2)),3)
vol = l**3
else:
vol = 10
density = ((8*(self.PM + self.PM2))/(nav*vol))
return "{}: {} g/cc".format(self.name,density)
mag = Molecular_d(name="a", tred="as", PM=1.1, ra=0.2, PM2=2.3, ra2=40.1)
result = mag.density()
print(result)
<< 'a: 4.5167718365991366e-24 g/cc'
I added in a default value of vol, because i'm not sure
You have that:
class Atomic_d():
def __init__(self,name="",red="",PM=None,ra=None):
But, initialization is:
class Molecular_d(Atomic_d):
def __init__(self,name="",tred="",PM=None,ra=None,PM2=None,ra2=None):
super().__init__(name,PM,ra)
it:
super().__init__(name,PM,ra)
goes to:
def __init__(self,name="",red="",PM=None,ra=None):
as
__init__(self,name=name,red=PM,PM=ra,ra=None):
So, ra param was not initialised.
Related
class FoodItem:
def __init__(self, item_name, amount_fat, amount_carbs, amount_protein, num_servings):
self.item_name = "None"
self.amount_fat = 0.0
self.amount_carbs = 0.0
self.amount_protein = 0.0
self.num_servings = 0.0
def get_calories(self, num_servings):
# Calorie formula
calories = ((self.fat * 9) + (self.carbs * 4) + (self.protein * 4)) * num_servings;
return calories
def print_info(self):
print('Nutritional information per serving of {}:'.format(self.name))
print(' Fat: {:.2f} g'.format(self.fat))
print(' Carbohydrates: {:.2f} g'.format(self.carbs))
print(' Protein: {:.2f} g'.format(self.protein))
if __name__ == "__main__":
food_item1 = FoodItem()
item_name = input()
amount_fat = float(input())
amount_carbs = float(input())
amount_protein = float(input())
food_item2 = FoodItem(item_name, amount_fat, amount_carbs, amount_protein)
num_servings = float(input())
food_item1.print_info()
print('Number of calories for {:.2f} serving(s): {:.2f}'.format(num_servings,
food_item1.get_calories(num_servings)))
print()
food_item2.print_info()
print('Number of calories for {:.2f} serving(s): {:.2f}'.format(num_servings,
food_item2.get_calories(num_servings)))
Results in the error:
Traceback (most recent call last):
File "main.py", line 22, in <module>
food_item1 = FoodItem()
TypeError: __init__() missing 5 required positional arguments: 'item_name', 'amount_fat', 'amount_carbs', 'amount_protein', and 'num_servings'
I'm not spotting an obvious error, but I'm new to initializing classes. The error seems to say that I'm missing arguments within the original init, but considering they were initialized to 0/'none' values, I don't understand that.
Perhaps someone can catch the error?
You have to initialize your class with ALL the arguments: item_name, amount_fat, amount_carbs, amount_protein and num_servings.
# here, you have to provide the arguments
food_item1 = FoodItem()
...
# and here, you are missing the 'num_servings' argument
food_item2 = FoodItem(item_name, amount_fat, amount_carbs, amount_protein)
Just in case, you can provide default values to an argument like so:
# here, the argument will default to '0' if you do not provide a value.
class Example:
def __init__(self, argument=0):
self.argument = argument
example = Example()
print(example.argument)
>>> 0
Your code is not saying what to match for example self.amount_fat with which argument you are talking about.
You should write:
self.amount_fat = amount_fat
And then announce was self.amount_fat is, otherwise your program will not know where to read.
def __init__(self, item_name, amount_fat, amount_carbs, amount_protein, num_servings):
self.item_name = item_name
self.amount_fat = amount_fat
self.amount_carbs = amount_carbs
self.amount_protein = amount_protein
self.num_servings = num_servings
You can then add what you coded initially.
This is an offensively simple question and I feel bad for even asking it, so some extent. I've been banging my head against the wall on this one for two days now.
I'm trying do to an object oriented program that takes the lines of a csv and turns each line of that CSV into a variable that I can use down the road. I want to somehow (I can't figure out how) get each line of that CSV into a class. I know this might not even be the best way to do this but I'm constrained to solve the problem in this way for other reasons.
I don't know enough Python to even know how to look up a solution to this and I need to know how to do this for a project I'm working on.
Here is the code I am basing this off:
import argparse
from collections import defaultdict
import csv
class Actor(object):
"""An actor with bounded rationality.
The methods on this class such as u_success, u_failure, eu_challenge are
meant to be calculated from the actor's perspective, which in practice
means that the actor's risk aversion is always used, including to calculate
utilities for other actors.
I don't understand why an actor would assume that other actors share the
same risk aversion, or how this implies that it is from the given actor's
point of view, but as far as I can tell this is faithful to BDM's original
formulation as well as Scholz's replication.
"""
def __init__(self, name, c, s, x, model, r=1.0):
self.name = name
self.c = c # capabilities, float between 0 and 1
self.s = s # salience, float between 0 and 1
self.x = x # number representing position on an issue
self.model = model
self.r = r # risk aversion, float between .5 and 2
def __str__(self):
return self.__repr__()
def __repr__(self):
return '%s(x=%s,c=%s,s=%s,r=%.2f)' % (
self.name, self.x, self.c, self.s, self.r)
def compare(self, x_j, x_k, risk=None):
"""Difference in utility to `self` between positions x_j and x_k."""
risk = risk or self.r
position_range = self.model.position_range
x_k_distance = (abs(self.x - x_k) / position_range) ** risk
x_j_distance = (abs(self.x - x_j) / position_range) ** risk
return self.c * self.s * (x_k_distance - x_j_distance)
def u_success(self, actor, x_j):
"""Utility to `actor` successfully challenging position x_j."""
position_range = self.model.position_range
val = 0.5 - 0.5 * abs(actor.x - x_j) / position_range
return 2 - 4 * val ** self.r
def u_failure(self, actor, x_j):
"""Utility to `actor` of failing in challenge position x_j."""
position_range = self.model.position_range
val = 0.5 + 0.5 * abs(actor.x - x_j) / position_range
return 2 - 4 * val ** self.r
def u_status_quo(self):
"""Utility to `self` of the status quo."""
return 2 - 4 * (0.5 ** self.r)
def eu_challenge(self, actor_i, actor_j):
"""Expected utility to `actor_i' of `actor_i` challenging `actor_j`.
This is calculated from the perspective of actor `self`, which in
practice means that `self.r` is used for risk aversion.
"""
prob_success = self.model.probability(actor_i.x, actor_j.x)
u_success = self.u_success(actor_i, actor_j.x)
u_failure = self.u_failure(actor_i, actor_j.x)
u_status_quo = self.u_status_quo()
eu_resist = actor_j.s * (
prob_success * u_success + (1 - prob_success) * u_failure)
eu_not_resist = (1 - actor_j.s) * u_success
eu_status_quo = self.model.q * u_status_quo
return eu_resist + eu_not_resist - eu_status_quo
def danger_level(self):
"""The amount of danger the actor is in from holding its policy position.
The smaller this number is, the more secure the actor is, in that it
expects fewer challenges to its position from other actors.
"""
return sum(self.eu_challenge(other_actor, self) for other_actor
in self.model.actors if other_actor != self)
def risk_acceptance(self):
"""Actor's risk acceptance, based on its current policy position.
I have two comments:
- It seems to me that BDM's intent was that in order to calculate
risk acceptance, one would need to compare an actor's danger level
across different policy positions that the actor could hold. Instead,
Scholz compares the actor's danger level to the danger level of all
other actors. This comparison doesn't seem relevant, given that other
actors will have danger levels not possible for the given actor
because of differences in salience and capability.
- Even (what I assume to be) BDM's original intention is an odd way to
calculate risk acceptance, given that the actor's policy position may
have been coerced, rather than having been chosen by the actor based
on its security preferences.
"""
# Alternative calculation, which I think is more faithful to
# BDM's original intent.
# orig_position = self.x
# possible_dangers = []
# for position in self.model.positions():
# self.x = position
# possible_dangers.append(self.danger_level())
# self.x = orig_position
# max_danger = max(possible_dangers)
# min_danger = min(possible_dangers)
# return ((2 * self.danger_level() - max_danger - min_danger) /
# (max_danger - min_danger))
danger_levels = [actor.danger_level() for actor in self.model.actors]
max_danger = max(danger_levels)
min_danger = min(danger_levels)
return ((2 * self.danger_level() - max_danger - min_danger) /
(max_danger - min_danger))
def risk_aversion(self):
risk = self.risk_acceptance()
return (1 - risk / 3.0) / (1 + risk / 3.0)
def best_offer(self):
offers = defaultdict(list)
for other_actor in self.model.actors:
if self.x == other_actor.x:
continue
offer = Offer.from_actors(self, other_actor)
if offer:
offers[offer.offer_type].append(offer)
best_offer = None
best_offer_key = lambda offer: abs(self.x - offer.position)
# This is faithful to Scholz' original code, but it appears to be a
# mistake, since Scholz' paper and BDM clearly state that each actor
# chooses the offer that requires him to change position the
# least. Instead, Scholz included a special case for compromises which
# results in some bizarre behavior, particularly in Round 4 when
# Belgium compromises with Netherlands to an extreme position rather
# than with France.
def compromise_best_offer_key(offer):
top = (abs(offer.eu) * offer.actor.x +
abs(offer.other_eu) * offer.other_actor.x)
return top / (abs(offer.eu) + abs(offer.other_eu))
if offers['confrontation']:
best_offer = min(offers['confrontation'], key=best_offer_key)
elif offers['compromise']:
best_offer = min(offers['compromise'],
key=compromise_best_offer_key)
elif offers['capitulation']:
best_offer = min(offers['capitulation'], key=best_offer_key)
return best_offer
class Offer(object):
CONFRONTATION = 'confrontation'
COMPROMISE = 'compromise'
CAPITULATION = 'capitulation'
OFFER_TYPES = (
CONFRONTATION,
COMPROMISE,
CAPITULATION,
)
def __init__(self, actor, other_actor, offer_type, eu, other_eu, position):
if offer_type not in self.OFFER_TYPES:
raise ValueError('offer_type "%s" not in %s'
% (offer_type, self.OFFER_TYPES))
self.actor = actor # actor receiving the offer
self.other_actor = other_actor # actor proposing the offer
self.offer_type = offer_type
self.eu = eu
self.other_eu = other_eu
self.position = position
#classmethod
def from_actors(cls, actor, other_actor):
eu_ij = actor.eu_challenge(actor, other_actor)
eu_ji = actor.eu_challenge(other_actor, actor)
if eu_ji > eu_ij > 0:
offer_type = cls.CONFRONTATION
position = other_actor.x
elif eu_ji > 0 > eu_ij and eu_ji > abs(eu_ij):
offer_type = cls.COMPROMISE
concession = (other_actor.x - actor.x) * abs(eu_ij / eu_ji)
position = actor.x + concession
elif eu_ji > 0 > eu_ij and eu_ji < abs(eu_ji):
offer_type = cls.CAPITULATION
position = other_actor.x
else:
return None
return cls(actor, other_actor, offer_type, eu_ij, eu_ji, position)
def __str__(self):
return self.__repr__()
def __repr__(self):
type_to_fmt = {
self.CONFRONTATION: '%s loses confrontation to %s',
self.COMPROMISE: '%s compromises with %s',
self.CAPITULATION: '%s capitulates to %s',
}
fmt = type_to_fmt[self.offer_type] + "\n\t%s vs %s\n\tnew_pos = %s"
return fmt % (self.actor.name, self.other_actor.name, self.eu,
self.other_eu, self.position)
class BDMScholzModel(object):
"""An expected utility model for political forecasting."""
def __init__(self, data, q=1.0):
self.actors = [
Actor(name=item['Actor'],
c=float(item['Capability']),
s=float(item['Salience']),
x=float(item['Position']),
model=self)
for item in data]
self.name_to_actor = {actor.name: actor for actor in self.actors}
self.q = q
positions = self.positions()
self.position_range = max(positions) - min(positions)
#classmethod
def from_csv_path(cls, csv_path):
return cls(csv.DictReader(open(csv_path, 'rU')))
def actor_by_name(self, name):
return self.name_to_actor.get(name)
def __getitem__(self, key):
return self.name_to_actor.get(key)
def positions(self):
return list({actor.x for actor in self.actors})
def median_position(self):
positions = self.positions()
median = positions[0]
for position in positions[1:]:
votes = sum(actor.compare(position, median, risk=1.0)
for actor in self.actors)
if votes > 0:
median = position
return median
def mean_position(self):
return (sum(actor.c * actor.s * actor.x for actor in self.actors) /
sum(actor.c * actor.s for actor in self.actors))
def probability(self, x_i, x_j):
if x_i == x_j:
return 0.0
# `sum_all_votes` below is faithful to Scholz' code, but I think it is
# quite contrary to BDM's intent. Instead, we should have.
# denominator = sum(actor.compare(x_i, x_j) for actor in self.actors)
# This would make sure that prob(x_i, x_j) + prob(x_j, x_i) == 1.
# However, because of the odd way that salience values are used as
# the probability that an actor will resist a proposal, this results in
# the actors almost always confronting each other.
# My theory is that Scholz got around the confrontation problem by
# introducing this large denominator, causing extremely small
# probability values. This prevents actors from confronting each other
# constantly, but the result is comical, in that the challenging actor
# always has a vanishingly small chance of winning a conflict, yet the
# challenged actor often gives up without a fight because of low
# salience.
sum_all_votes = sum(abs(actor.compare(a1.x, a2.x))
for actor in self.actors
for a1 in self.actors
for a2 in self.actors)
return (sum(max(0, actor.compare(x_i, x_j)) for actor in self.actors) /
sum_all_votes)
def update_risk_aversions(self):
for actor in self.actors:
actor.r = 1.0
actor_to_risk_aversion = [(actor, actor.risk_aversion())
for actor in self.actors]
for actor, risk_aversion in actor_to_risk_aversion:
actor.r = risk_aversion
def update_positions(self):
actor_to_best_offer = [(actor, actor.best_offer())
for actor in self.actors]
for actor, best_offer in actor_to_best_offer:
if best_offer:
print best_offer
actor.x = best_offer.position
def run_model(self, num_rounds=1):
print 'Median position: %s' % self.median_position()
print 'Mean position: %s' % self.mean_position()
for round_ in range(1, num_rounds + 1):
print ''
print 'ROUND %d' % round_
self.update_risk_aversions()
self.update_positions()
print ''
print 'Median position: %s' % self.median_position()
print 'Mean position: %s' % self.mean_position()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'csv_path',
help='path to csv with input data')
parser.add_argument(
'num_rounds',
help='number of rounds of simulation to run',
type=int)
args = parser.parse_args()
model = BDMScholzModel.from_csv_path(args.csv_path)
model.run_model(num_rounds=args.num_rounds)
Yeah, that's a lot of code, but reading the code, and then running it, I can see what's going on.
You're probably getting this error:
% python2 so.py sample.csv 1
Traceback (most recent call last):
File "so.py", line 336, in <module>
model = BDMScholzModel.from_csv_path(args.csv_path)
File "so.py", line 241, in from_csv_path
return cls(csv.DictReader(open(csv_path, 'rU')))
File "so.py", line 233, in __init__
for item in data]
KeyError: 'Actor'
And you're getting that error because just creating a DictReader doesn't actually read the data, that's still a set of steps you have to explicitly carry out. Here's the minimal example from the Python2 docs for DictReader:
import csv
with open('names.csv') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['first_name'], row['last_name'])
In your case, you want to pass a list of dicts to your BDMScholzModel constructor, and in its __init__() method turn those individual dicts into Actors.
So, your from_csv_path() classmethod needs to look more like that example, with these changes:
create an empty list before creating the reader, data = []
inside the row-in-reader loop, just append each row to data, data.append(row) (DictReader handles the field/key names for you)
after the whole with-open block, finally call your BDMScholzModel initializer w/your data, return cls(data)
I did all that. Then sketched up this sample CSV:
sample.csv
Actor,Capability,Salience,Position
foo,1,1,1
bar,2,2,2
baz,3,3,3
I also added a debug-print statement just before the cls(data) call at the end of my new from_csv_path() classmethod:
print 'debug data: %s\n' % data
return cls(data)
And running:
python2 so.py sample.csv 1
got me:
debug data: [
{'Capability': '1', 'Position': '1', 'Salience': '1', 'Actor': 'foo'},
{'Capability': '2', 'Position': '2', 'Salience': '2', 'Actor': 'bar'},
{'Capability': '3', 'Position': '3', 'Salience': '3', 'Actor': 'baz'}
]
Median position: 3.0
Mean position: 2.57142857143
ROUND 1
Median position: 3.0
Mean position: 2.57142857143
Here's my complete from_csv_path() method:
#classmethod
def from_csv_path(cls, csv_path):
data = []
with open(csv_path) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
data.append(row)
print 'debug data: %s\n' % data
return cls(data)
Tcard.attack(self.players[self.opponent])
AttributeError: 'int' object has no attribute 'attack'
This is the error I get from calling attack().
Tcard = self.players[self.turn].returnCard()
Tcard.attack(self.players[self.opponent])
For some odd reason when Tcard.attack() calls with the parameters self.players[self.opponent], the list returns an int ranther than a Player object. Can someone please explain why it is returning an int rather than an object?
Here is the code for the whole file:
class Game():
def __init__(self):
self.players = []
self.turn = 0
self.opponent = 1
def prepare_game(self):
AI_1 = AI("AI_1", 1000)
AI_1.generate_inventory()
AI_2 = AI("AI_2", 1000)
AI_2.generate_inventory()
self.players.append(AI_1)
self.players.append(AI_2)
def start(self):
p1 = self.players[self.turn]
p2 = self.players[self.opponent]
Tcard = self.players[self.turn].returnCard()
print "Battle time"
print "%s attacked %s" % (p1.Name, p2.Name)
Tcard.attack(self.players[self.opponent])
#switch
if self.turn == 0:
self.turn = 1
self.opponent = 0
self.start()
else:
self.turn = 0
self.opponent = 1
self.start()
Here is where the function returnCard is at:
class AI():
def __init__(self, Name, Health):
self.Name = Name
self.Health = Health
self.inventory = []
def generate_inventory(self):
#Generate 6 Cards and 3 Power-ups
#rand_powerups = random.randint(min(len(powerup)), max(len(powerup)))
rand_cards = random.randint(0, 4)
#self.inventory.append(rand_powerups)
while len(self.inventory) != 4:
self.inventory.append(rand_cards)
if len(self.inventory) == 4:
break
def returnCard(self):
return self.inventory[random.randrange(0, 4)]
def returnCard(self):
return self.inventory[random.randrange(0, 4)]
returnCard returns a random item of self.inventory.
And self.inventory is filled by generate_inventory which does this:
# generate a random *INT*
rand_cards = random.randint(0, 4)
while len(self.inventory) != 4:
# append that *INT*
self.inventory.append(rand_cards)
# (note that this keeps adding the same number over and over)
So, of course, returnCard will return an int here:
Tcard = self.players[self.turn].returnCard()
So when you try to call attack you try to call it on an int:
Tcard.attack(self.players[self.opponent])
self.inventory = [] # a list
rand_cards = random.randint(0, 4)
self.inventory.append(rand_cards) # you add ints to the list
# you return an int
return self.inventory[random.randrange(0, 4)]
# you set Tcard equal to an int returned from ^^
Tcard = self.players[self.turn].returnCard()
On another note you should use range to add the random ints and keep calling randint or you will just get the same number added to your list:
def generate_inventory(self):
for _ in range(4):
self.inventory.append(random.randint(0, 4))
If you want to use the methods in your class, create an instance. I could give you an example but I have no idea where attack comes from.
First of all, Tcard becomes a variable due to this line:
Tcard = self.players[self.turn].returnCard()
By assigning Tcard the result of .returnCard() which will always be an integer since you made returnCard() to return an integer with:
return self.inventory[random.randrange(0, 4)]
So since an integer can't have any attributes, that will be an error. Thus the raised error saying that an int has no attribute.
Second, Tcard is not even a function. Only functions can have attributes thus adding more to the error. You need to create a function for Tcard to be able to work. Add something like:
class Tcard:
def attack():
#Do something
I dont know why i get this error and it's really annoying... anyone see the problem?
I get this error:
line 66, in <module>
ting.movefigure(ting, "up", 20)
AttributeError: 'int' object has no attribute 'movefigure'
Here is my code:
from tkinter import * import time
def movefigure(self, direction, ammount):
x = 0
y = 0
ammount2 = 0
if direction == "up":
print("Direction = " + ammount)
y = ammount
elif direction == "down":
print("Direction = " + ammount)
ammount2 = ammount - (ammount * 2)
y = ammount2
elif direction == "right" + ammount:
print("Direction = " + ammount)
x = ammount
elif direction == "left":
print("Direction = " + ammount)
ammount2 = ammount - (ammount * 2)
y = ammount2
canvas.move(self, x, y)
root = Tk()
root.title('Canvas')
tingx = 100
tingy = 100
tingxMove = 1
tingyMove = 1
canvas = Canvas(root, width=400, height=400)
ting = canvas.create_rectangle(205, 10, tingx, tingy, tags="Ting", outline='black', fill='gray50')
canvas.pack()
ting.movefigure(ting, "up", 20)
root.mainloop()
You're mixing up functions and methods.
A method is a function defined in a class; it takes a self argument, and you call it on an instance of that class. Like this:
class Spam(object):
def __init__(self, eggs):
self.eggs = eggs
def method(self, beans):
return self.eggs + beans
spam = Spam(20)
print(spam.method(10))
This will print out 30.
But your movefigure is not a method of any class, it's just a regular function. That means it doesn't take a self parameter, and you don't call it with dot syntax. (Of course there's nothing stopping you from calling any parameter self if you want, just like there's nothing stopping you from writing a function called print_with_color that erases a file named /kernel, but it's not a good idea…)
So, you wanted to do this:
def movefigure(rect, direction, ammount):
# all of your existing code, but using rect instead of self
movefigure(ting, "up", 20)
I'm working with Inheritance in python but i'm getting an error i don't know how to fix, 'finalStore' object has no attribute 'marone'. I get this when i try create an object.
from ClassFile import studStore
class finalStore (studStore):
grandAve = 0
numStu = 0
def __init__(self, name, marone, martwo, marthree, marfour, corone, cortwo, corthree, corfour):
studStore.__init__(self, name, marone, martwo, marthree, marfour)
self.corone = corone
self.cortwo = cortwo
self.corthree = corthree
self.corfour = corfour
finalStore.numStu += 1
self.holder = finalStore.numStu
self.average = (marone + martwo + marthree + marfour)/4
finalStore.grandAve += self.average
self.storit = finalStore.grandAve
My initializing for the child class
class studStore:
def __init__(self, name, marone, martwo, marthree, marfour):
self.newname = name
self.Ave = 0
self.marone = marone
self.martwo = martwo
self.marthree = marthree
self.marfour = marfour
And the initializing for the parent class. My main line is just a loop where i create multiple objects for but it errors on this line:
listIn.append(finalStore(name, gradeone, gradetwo, gradethree, gradefour, courseOne, courseTwo, courseThree, courseFour))
I'm not sure what the error is but I have a similar program that works, I'm just not using the from * import *
I'm outputting it like this
for i in range (0,len(listIn)):
print(str(listIn[i].returnName()).ljust(20," "), end = " ")
print(str(listIn[i].returnOne()).ljust(20, " "))
print(str(listIn[i].returnTwo()).ljust(20, " "))
print(str(listIn[i].returnThree()).ljust(20, " "))
print(str(listIn[i].returnFour()).ljust(20, " "))
Your call to the super class's init function is incorrect. Here is how you should do it:
class finalStore(studStore):
def __init__(self, name, ...):
super(finalStore, self).__init__(name, marone, ...)