Having trouble calling the parent class method from child class - python

I've started trying to learn Python after working with Java for the past year and decided to work on a couple class projects I've done and to write them in Python. I am getting an AttributeError at line 102, stating my super object has no attribute 'area'.
I've looked through different posts of how it's done, and I can't seem to figure out why this isn't working correctly for me after following other solutions.
It's a simple program that takes in input from the user, parses it, then depending on the shape type, will call the methods of the appropriate object type, then calculates and prints it out. For example, an input would be "R 3/4 5-7", supposed to weigh 8.37, or "P 1/4 5-6 2-3", supposed to weigh 126.07.
import math
class Shipment:
_weight = 0
def weight(self):
return self._weight
def frac_in_feet(self, frac):
thick_frac = frac.replace('/', "")
print("number is: ", thick_frac)
numerator = int(thick_frac[0])
denominator = int(thick_frac[1])
fraction_of_an_inch = numerator / denominator
return self.in_feet(0, fraction_of_an_inch)
def feet_and_inches_in_feet(self, feet_and_inches):
a = feet_and_inches.replace('-', "")
print("number is: ", a)
feet = int(a[0])
inches = int(a[1])
return self.in_feet(feet, inches)
def in_feet(self, feet, inches):
inches /= 12
print(feet + inches)
return feet + inches
def get_value_in_feet(self, str):
i = str.find('/')
j = str.find('-')
if i == -1:
value = self.feet_and_inches_in_feet(str)
if j == -1:
value = self.frac_in_feet(str)
return value
def add_item(self, quantity, description):
desc_values = description.replace(" ", "")
values = []
shape_letter = desc_values[0]
i = 1
j = 4
for r in range(int(len(desc_values) / 3)):
print("r is: ", r)
values.append(self.get_value_in_feet(desc_values[i:j]))
i += 3
j += 3
if shape_letter == 'P':
if len(values) != 3:
raise ValueError("Plate needs three dimensions. ")
shape = Plate(values[0], values[1], values[2])
elif shape_letter == 'R':
if len(values) != 2:
raise ValueError("Rod needs two dimensions")
shape = Rod(values[0], values[1])
else:
raise ValueError("Shape letter ", shape_letter, " not recognized.")
self._weight += quantity * shape.weight()
return shape
class SteelShape:
_length = 0
_weight = 0
def length(self, length):
_length = length
def length(self):
return self._length
def weight(self, weight):
self._weight = weight
def weight(self):
return self._weight
class CalcShape(SteelShape):
_area = 0
def area(self, area):
self._area = area
def weight(self):
return self._area * self.length() * 489
class Rod(CalcShape):
def __init__(self, diameter, length):
radius = diameter / 2
super(CalcShape, self).area(math.pi * radius**2)
super(CalcShape, self).length
class Plate(CalcShape):
def __init__(self, thick, width, length):
super(CalcShape, self).area(thick * width)
super(SteelShape, self).length(length)
values = []
shipment = Shipment()
shape = SteelShape()
line = input("Enter shape and dimensions: ")
shape = shipment.add_item(1, line)
if isinstance(shape, Plate):
print("Plate weighs ", shape.weight())
elif isinstance(shape, Rod):
print("Rod weighs ", shape.weight())
print("Total shipment weight: ", shipment.weight())
# R 3/4 5-7: supposed to weigh 8.37
# P 1/4 5-6 2-3: supposed to weigh 126.07

I think replacing the super and instead using staticmethod is a better choice. See here:
https://stackoverflow.com/a/735978/10416716
Hope this helps.

Related

Student Info Program (adding onto) How to add two methods

We are adding onto code that we completed last week. Our instructor gave us direction (posted at bottom) and to me and my partner, they are not very descriptive. I'm not asking for an answer to the code, but just a different and more informative description or hints at how to start these additions.
import math
class Student:
def __init__(self, name, student_id, intended_major, grade):
self.name = name
self.student_id = student_id
self.intended_major = intended_major
self.grade = grade
self._exams = []
self._quizzes = []
self._projects = []
def get_name(self):
return self.name
def get_student_id(self):
return self.student_id
def get_major(self):
return self.intended_major
def set_quizzes(self, _quizzes):
self._quizzes = _quizzes[:]
def set_exams(self, _exams):
self._exams = _exams[:]
def set_projects(self, _projects):
self._projects = _projects[:]
def get_exams_mean(self):
return float((sum(self._exams)) / max(len(self._exams), 1))
def get_exams_median(self):
if len(self._exams) == 0:
return 0
lst = sorted(self._exams)
if len(lst) % 2 == 0:
n1 = lst[int(len(lst)/2)]
n2 = lst[int(len(lst)/2)-1]
return ( n1 + n2 ) / 2
else:
return lst[int(len(lst) / 2)]
def get_exams_std_dev(self):
if len(self._exams) == 0:
return 0
mean = sum(self._exams) / len(self._exams)
total = 0
for i in self._exams:
total += (i - mean)**2
return math.sqrt(total/len(self._exams))
def get_quizzes_mean(self):
return float((sum(self._quizzes)) / max(len(self._quizzes), 1))
def get_quizzes_median(self):
if len(self._quizzes) == 0:
return 0
lst = sorted(self._quizzes)
if len(lst) % 2 == 0:
n1 = lst[int(len(lst) / 2)]
n2 = lst[int(len(lst) / 2) -1]
return ( n1 + n2 ) / 2
else:
return lst[int(len(lst) / 2)]
def get_quizzes_std_dev(self):
if len(self._quizzes) == 0:
return 0
mean = sum(self._quizzes) / len(self._quizzes)
total = 0
for i in self._quizzes:
total += (i - mean) ** 2
return math.sqrt(total / len(self._quizzes))
def get_projects_mean(self):
return float((sum(self._projects)) / max(len(self._projects), 1))
def get_projects_median(self):
if len(self._projects) == 0:
return 0
lst = sorted(self._projects)
if len(lst) % 2 == 0:
n1 = lst[int(len(lst)/2)]
n2 = lst[int(len(lst)/2)-1]
return ( n1 + n2 ) / 2
else:
return lst[int(len(lst) / 2)]
def get_projects_std_dev(self):
if len(self._projects) == 0:
return 0
mean = sum(self._projects)/len(self._projects)
total = 0
for i in self._projects:
total += (i - mean)**2
return math.sqrt(total/len(self._projects))
def set_grade_calculation_type(self):
if True:
return 0
else:
pass
def set_quiz(self, grade, number):
pass
Add stubs for the following instance methods to your Student class:
set_grade_calculation_type:
The method takes a Boolean argument: True calculates missing grades as zero;
False skips missing grades in calculations
You will need to store this value in your class
Default to True if this method is not called
set_quiz:
takes two arguments: grade and number, which identifies the quiz
If the quiz list has less than number elements, then add missing quizzes as
None
Since this is computer science, we will start with quiz 0.
For example, let's say the student has two quiz grades in list for quizzes 0
and 1 =[90, 78], and we call student.set_quiz(89,4). We are missing quizzes 2
and 3, so our updated list will be [90, 78, None, None, 89]. In the future if
we call student.set_quiz(93,2) we would have [90, 78, 93, None, 89].
set_exam: analogous to set_quiz
set_project: analogous to set_quiz

Filling a Triangle in Python

I have a python program where the object is to have the user enter the length of the sides of a triangle, if they would like to fill it, and what color. I keep getting an attribute error pertaining to GeometricObject and fill.
After a few fixes I am stuck in the same area again (fill), this is the error I keep getting:
> Traceback (most recent call last): File "Desktop/one.py", line 81,
> in <module>
> main() File "Desktop/one.py", line 78, in main
> "Is filled? : ", triangle.ColorFill()) File "Desktop/one.py", line 21, in ColorFill
> return self.__filled AttributeError: 'Triangle' object has no attribute '_GeometricObject__filled'
I am not sure where to untangle this, any help would be welcomed. Below is my code:
12.1 The Triangle class
import math
#class for the GeometricObject, must be defined before Trianble. includes fill
class GeometricObject:
#if true the color will be green
def __init__(self, color =" ", filled = True):
self.__color = color
self__filled = filled
#getting the fill color and setting it to green fill
def getColor(self):
return self.__color
def setColor(self, color):
self.__color = color
def ColorFill(self):
return self.__filled
def setColorFill(self, filled):
self__filled = filled
#string that tells you if it is filled or not
def __st__(self):
return "Color is: " + (self.__color) \
+ "Fill: " + str(self.__filled)
#setting class for triangle and calling on geometric objects
class Triangle(GeometricObject):
def __init__(self, side1 = 1.0, side2 = 1.0, side3 = 1.0):
self.__side1 = side1
self.__side2 = side2
self.__side3 = side3
#calling GeometricObject, this is what triangle is bound to
GeometricObject.__init__(self)
#getting length of sides
def getLengthA(self):
return side1
def getLengthB(self):
return side2
def getLengthC(self):
return side3
#setting and getting perimeter
def setPerimeter(self):
self.perimeter = perimeter
def getPerimeter(self):
perimeter = self.__side1 + self.__side2 + self.__side3
return perimeter
#setting and getting area
def setArea(self):
self.area = area
def getArea(self):
s = (self.__side1 + self.__side2 + self.__side3) / 2
area = math.sqrt(s * ((s - self.__side1) * (s - self.__side2) * (s - self.__side3)))
return area
#printing string, sides
def toString(self):
return "Triangle: Side 1: " + (self.__side1)\
+ "Side 2: " + (self.__side2)\
+ "Side 3: " + (self.__side3)
def main():
#user enters sides of a triangle
side1, side2, side3 = eval(input("Enter the length of the Tiangle's sides (A, B, C): "))
triangle = Triangle(side1, side2, side3)
#user enters color
color = input("Enter a color: ")
triangle.setColor(color)
#user enter if filled
filled = eval(input("Enter 1 to fill with color \n Enter 0 for no fill: "))
ColorFill = (filled == 1)
triangle.setColorFill(ColorFill)
print("The area of the triangle is: " , triangle.getArea(), \
"The perimeter is: " , triangle.getPerimeter(), \
"The color is: ", triangle.getColor(), \
"Is filled? : ", triangle.ColorFill())
main()

Turing automata in Python

class Tape(object):
blank_symbol = " "
def __init__(self,
tape_string = ""):
self.__tape = dict((enumerate(tape_string)))
# last line is equivalent to the following three lines:
#self.__tape = {}
#for i in range(len(tape_string)):
# self.__tape[i] = input[i]
def __str__(self):
s = ""
min_used_index = min(self.__tape.keys())
max_used_index = max(self.__tape.keys())
for i in range(min_used_index, max_used_index):
s += self.__tape[i]
return s
def __getitem__(self,index):
if index in self.__tape:
return self.__tape[index]
else:
return Tape.blank_symbol
def __setitem__(self, pos, char):
self.__tape[pos] = char
class TuringMachine(object):
def __init__(self,
tape = "",
blank_symbol = " ",
initial_state = "",
final_states = None,
transition_function = None):
self.__tape = Tape(tape)
self.__head_position = 0
self.__blank_symbol = blank_symbol
self.__current_state = initial_state
if transition_function == None:
self.__transition_function = {}
else:
self.__transition_function = transition_function
if final_states == None:
self.__final_states = set()
else:
self.__final_states = set(final_states)
def get_tape(self):
return str(self.__tape)
def step(self):
char_under_head = self.__tape[self.__head_position]
x = (self.__current_state, char_under_head)
if x in self.__transition_function:
y = self.__transition_function[x]
self.__tape[self.__head_position] = y[1]
if y[2] == "R":
self.__head_position += 1
elif y[2] == "L":
self.__head_position -= 1
self.__current_state = y[0]
def final(self):
if self.__current_state in self.__final_states:
return True
else:
return False
I am trying to implement Turing automata in Python. Can you tell me why this code doesn't work? e machine operates on an infinite[4] memory tape divided into discrete cells.[5] The machine positions its head over a cell and "reads" (scans)[6] the symbol there. Then, as per the symbol and its present place in a finite table[7] of user-specified instructions, the machine (i) writes a symbol (e.g., a digit or a letter from a finite alphabet) in the cell (some models allowing symbol erasure or no writing) then (ii) either moves the tape one cell left or right (some models allow no motion, some models move the head),[9] then (iii) (as determined by the observed symbol and the machine's place in the table) either proceeds to a subsequent instruction or halts the computation.
Before adding i to list, convert it to float by float(i).
for i in lines:
print(i)
if(i != " "):
if(a % 4 == 0 and a != 1):
second.append(float(i))
tuple(tmp)
first.append(tmp)
tmp = []
else:
tmp.append(float(i))
a+=1

Python - passing a class through a function resulting in error

I have been programming a piece of code to try and carry through a class from one function to another (the code is also broken in other ways but those aren't the important ones). The major problem if you define a class in the enter function it then gives the error:
exec("""print({}.Show())""".format(x))
File "<string>", line 1, in <module>
NameError: name (whatever I have called the class title) is not defined
in the tr function.
import pickle
import traceback
import sys
classtitles = []
class Customer(object):
def __init__(self):
try:
self.load()
print(self.customer)
except:
None
def init2(self,customer_name,home_address,telephone_number):
self.customer = customer_name
self.address = home_address
self.phone = telephone_number
print(self.customer)
classtitles.append(self.customer)
def carpet_amounts(self, carpet_type, grippers_bool):
self.type = carpet_type
self.grippers = grippers_bool
def price(self, size, perimeter):
self.size = size
self.perimeter = perimeter
self.price = 0
if self.type == "First":
self.price = float(5.99) * self.size
if self.type == "Monarch":
self.price = float(7.99) * self.size
if self.type == "Royal":
self.price = int(60) * self.size
price_add = float(22.5) * self.size
if self.grippers == True:
price_add += self.perimeter * float(1.10)
hours = 0
while size >= 16:
hours += 1
size -= 16
self.hours = hours
price_add += hours * 65
self.price += price_add
def Show(self):
print("show")
if self.grippers == True:
grips = "with"
else:
grips = "without"
return ("the size is {}m^2 and with a {} undercarpet and {} grippers, totalling more than {} hours of work is {}".format(self.size,self.type,grips,self.hours,self.price))
def save(self):
"""save class as self.name.txt"""
file = open('ClassSave.txt','wb')
file.write(pickle.dumps(self.__dict__))
file.close()
def load(self):
"""try load self.name.txt"""
file = open('ClassSave.txt','r')
datapickle = file.read()
file.close()
self.__dict__ = pickle.loads(dataPickle)
def loadf():
f = open('classnames.txt','r')
mylist = f.read().splitlines()
for x in mylist:
exec("""{} = Customer()""".format(mylist[0]))
customs()
def customs():
try1 = input("Would you like to 1. Enter a new customer. 2. View all the customers. 3. Delete an old customer")
if try1 == '1':
enter()
elif try1 == 'q':
sys.exit()
else:
tr()
def enter():
name = input("What is thr customers name (no space i.e. 'JoeBloggs')? ")
address = input("What is their address")
phonenumber = str("What is their phone number")
exec("""{} = Customer()""".format(name))
exec("""{}.init2("{}","{}","{}")""".format(name,name,address,phonenumber))
print(classtitles)
carpet_type = input("What type of carpet would they like ('First','Monarch','Royal')? ")
grips = str(input("Would they like grips (1 = yes, 2 = no)? "))
if grips == '1':
grips = True
else:
grips = False
exec("""{}.carpet_amounts("{}",{})""".format(name,carpet_type,grips))
size = int(input("What is the m^2 size of their carpet? "))
perimeter = int(input("What is the m perimeter of their carpet? "))
exec("""{}.price({},{})""".format(name,size,perimeter))
exec("print({}.Show())".format(name))
file2 = open('classnames.txt','w')
for x in classtitles:
file2.write(x)
file2.close()
exec("{}.save()".format(name))
customs()
def tr():
x = input("name")
print(x)
exec("""print({}.Show())""".format(x))
customs()
loadf()

How can I get my user input to run from my class? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
bob = Turtle()
bob.shape("turtle")
class SimpleDraw(Turtle):
def __init__(Turtle):
bob = Turtle
def draw_square(bob, length):
'''This function draws a regular square'''
for i in range(4):
bob.forward(length)
bob.left(90)
def draw_polygon(bob, n, length):
'''This function draws a regular polygon'''
angle = 360.0 / n
for i in range(n):
bob.forward(length)
bob.left(angle)
def draw_circle (t, r):
circumference = 2 * math.pi * r
n = 50
length = circumference / n
polygon (t, n, length)
drawObj = SimpleDraw
drawObj.draw_polygon
drawObj.draw_circle
drawObj.draw_square
def testSimpleDraw():
number = raw_input('Please choose a draw option: \
1-draw square \
2-draw polygon \
3-draw circle \
0-to exit');
if number == 0:
exit()
else:
if number == 1:
drawObj.draw_square(bob, 5)
else:
if number == 2:
drawObj.draw_polygon(bob, 7, 70)
else:
if number == 3:
drawObj.draw_circle(50, 50)
if __name__ == '__main__':
testSimpleDraw()
drawObj = SimpleDraw needs to be changed to drawObj = SimpleDraw()
That's how you instantiate a class. You are assigning the SimpleDraw class to drawObj - drawObj is the same as SimpleDraw class not an instance of SimpleDraw in your code.
In this line:
drawObj = SimpleDraw
you assign the class SimpleDraw to the name drawObj. Instead, you should create an instance of the class to assign:
drawObj = SimpleDraw() # note parentheses
You don't need the __init__ in your SimpleDraw class; you inherit this from Turtle. It is conventional to call the first argument to instance methods self, rather than bob! For example:
def draw_square(self, length):
'''This function draws a regular square'''
for i in range(4):
self.forward(length)
self.left(90)
You will need to adjust your draw_circle method to correctly call the draw_polygon method:
def draw_circle(self, r, n=50):
circumference = 2 * math.pi * r
length = circumference / n
self.draw_polygon(n, length)
Note that you can use elif to simplify your code:
if number == 0:
...
elif number == 1:
...
I'm going to take a guess at what you're trying to do. First, lets rewrite this code and I'll explain the changes as we go along.
class SimpleDraw(Turtle):
# No __init__ need, calls __init__ of subclass implicitly
# So self refers to an instance of Turtle
# Since all your code essentially makes use of the same thing, lets create
# a generic base draw.
def draw_generic(self, angle, length, n):
for i in range(n):
self.forward(length)
self.left(angle)
def draw_square(self, length):
# Notice self instead of bob, this is how you refer to the instance
# of the class that has been created.
"""
This function draws a regular square.
"""
self.draw_generic(90, length, 4) # Note, self implicitly passed
def draw_polygon(self, n, length):
"""
This function draws a regular polygon
"""
angle = 360.0 / n
self.draw_generic(angle, length, n)
def draw_circle(self, t, r):
circumference = 2 * math.pi * r
n = 50
length = circumference / n
self.draw_polygon(t, n, length) # Note: draw_polygon instead of polygon
def test_simple_draw():
# Note the lowercase and underscores, this preferred by PEP 8
# http://stackoverflow.com/questions/8908760/should-i-use-camel-case-or-underscores-in-python
options = ["1 - draw square", "2 - draw polygon", "3 - draw circle", "0 -exit"]
msg = "Please choose a draw option:\n %s" % ("\n".join(options))
# Note that number is a string, so we have to try and coerce it to an int, and
# validate this as well.
number = None
while number is None:
try:
number = raw_input(msg)
number = int(number)
if 0 > number or 3 < number:
raise ValueError # Not a valid option
except ValueError: # If the coercion fails
print "%s is not a valid option. Please re-enter." % number
number = None # Set to None so we loop again
# Now we have the number, and it's actually a number.
# You make a lot of use of else, which can be replaced by elif, which is the
# like else but specifies a condition; a union of if and else
drawObj = SimpleDraw() # We create our object here, note braces for instantiation
if number == 0:
exit()
elif number == 1:
drawObj.draw_square(5)
elif number == 2:
drawObj.draw_polygon(7, 70)
else: # We can have confidence in this value because of our checks above
drawObj.draw_circle(50, 50)
if __name__ == "__main__":
test_simple_draw()
Now This code gets across the idea that you initially wanted, but makes use of the class inheritance that you were originally trying to use.
Further sources for reference:
Classes: http://docs.python.org/2/tutorial/classes.html
import math
import random
import turtle
class SimpleTurtle(turtle.Turtle):
# There is no need to override the default __init__
# Also, making the self argument 'bob' is just irritating -
# everyone expects to see 'self', why mess us up?
def draw_polygon(self, num_sides, side_length):
"""
Draw an n-sided regular polygon
"""
angle = 360. / num_sides
for side in range(num_sides):
self.forward(side_length)
self.left(angle)
def draw_square(self, side_length):
"""
Draw a square
"""
self.draw_polygon(4, side_length)
def draw_circle(self, radius, num_sides=60):
"""
Draw a circle
"""
angle = 360. / num_sides
side_length = 2. * radius * math.sin(math.radians(angle))
self.draw_polygon(num_sides, side_length)
def get_int(prompt, lo=None, hi=None):
while True:
try:
val = int(raw_input(prompt))
if (lo is None or lo <= val) and (hi is None or val <= hi):
return val
except ValueError:
pass
def do_menu(prompt, options):
print(prompt)
for i,opt in enumerate(options, 1):
print(" {:>2}: {}".format(i, opt))
return get_int("? ", 1, len(options)) - 1
def test_SimpleTurtle():
bob = SimpleTurtle(shape="turtle")
while True:
choice = do_menu("Please choose a draw option:", ["draw a square", "draw a polygon", "draw a circle", "quit"])
if choice == 0:
side_length = random.randint(10, 50)
bob.draw_square(side_length)
elif choice == 1:
sides = random.randint(5, 12)
side_length = random.randint(6, 30)
bob.draw_polygon(sides, side_length)
elif choice == 2:
radius = random.randint(8, 40)
bob.draw_circle(radius)
else:
break
if __name__ == '__main__':
test_SimpleTurtle()

Categories