I am trying to create a program with a real estate agent in mind. In this program, I am trying to cover the aspects of a home to rent with all the basic parameters in mind. However I am having some errors.
class Apartment:
def __init__(self, aptNumber, address, bedrooms, baths):
self._aptNumber = aptNumber
self._address = address
self._bedrooms = int(bedrooms)
self._baths = float(baths)
def _securiyDep(self):
securityDeposit = 330(bedrooms)
def _rent(self):
rent = 250(bedrooms) + 150(bathrooms)+200
def _renter(self):
renter = "vacant"
def setSecDep(self, deposit):
self._deposit = 1000
def setRent(self, rentMoney):
self._rentMoney = 800
def setRenter(self, renter):
self._renter = "Vacant"
def getData(self, Data):
self._Data = Data
def isVacant(self, vacancy):
self._vacancy = "True" or "False"
def __repr__(self):
s = self._aptNumber+ " located at " + str(self._address) + " is rented at" + self._rent
s+= " and has a security deposit = " + self._deposit + " and is = " + self._vacancy
return s
# Test code for the Apartment Class
if __name__ == "__main__":
apts = []
apts.append(Apartment("10C", "107 E. Main", 3, 1.5))
apts.append(Apartment("14B", "109 E. Main", 4, 2))
apts.append(Apartment("13", "2207 W. Broadway", "5", "2.5"))
for apt in apts:
print(apt)
print()
apts[0].setRent("1245")
apts[0].setRenter("Rocky Quartzite")
apts[1].setSecDep("1000")
apts[1].setRenter("Millie Milton")
print(apts[0].getData())
print()
for apt in apts:
if not apt.isVacant():
print(apt)
print()
apts[0].setRenter("")
print(apts[0])
I am having the error
print(apts[0].getData())
<__main__.Apartment object at 0x0000000003124208>
TypeError: getData() missing 1 required positional argument: 'Data'
<__main__.Apartment object at 0x0000000003124240>
Can someone please help with the errors?
You call getData with no arguments on line 60: print(apts[0].getData()). In your definition it takes a parameter called Data.
You define getData to take two arguments, namely self which is a refernce to the instance you are operating on, and which is "automatically" supplied, and the second argument is Data
def getData(self, Data):
self._Data = Data
But when you call getData you don't supply the second argument Data
apts[0].getData()
Thus the interpreter tells you that 1 required argument is missing, which in your case is Data.
Since getData in your case actually sets the Data variable, it would be better to call it setData
If you want to retrive the Data variable the getter would have to looke something like this
def getData(self):
return self._Data
Related
I've tried many different things so it's a little all over the place, please help
I've been able to make the first class and then in a different file create some objects for it, but for this subclass I need to use user input and I just can't figure it out.
I have made it so the shift input has to be a 1 or 2 for a day or night shift, I just don't have the knowledge for this.
class Employee:
def __init__(self, name, id, dept, title):
self.__name = name
self.__id = id
self.__dept = dept
self.__title = title
def get_name(self):
return self.__name
def get_id(self):
return self.__id
def get_dept(self):
return self.__dept
def get_title(self):
return self.__title
def __str__(self):
result = ""
result += "Name: " + self.get_name() + "\tID Number: " + str(self.get_id()) + \
"\tDepartment: " + self.get_dept() + "\tJob Title:" + self.get_title()
return result
class ShiftEmployee(Employee):
def __init__(self, name, id, dept, title, shift, pay):
Employee.__init__(self, name, id, dept, title)
self.__shift = shift
self.__pay = pay
#classmethod
def inputs(self):
self.__name = input("Enter name: ")
self.__id = input("Enter ID number: ")
self.__dept = input("Enter department: ")
self.__title = input("Enter Jobe title: ")
self.__shift = input("Enter shift: ")
self.__pay = input("Enter hourly pay: ")
#set_shift(self, shift):
#self.__shift = shift
#def set_pay(self, pay):
#self.__pay = pay
def get_shift(self, shift):
if self.__shift == 1:
return "Day"
elif self.__shift == 0:
return "Night"
else:
return "Invalid entry"
def get_pay(self, pay):
return self.__pay
def __str__(self):
result = ""
#result += Employee.__str__(self)
result += "Name: " + self.get_name(ShiftEmployee) + "\tID Number: " + str(self.get_id(ShiftEmployee)) + \
"\tDepartment: " + self.get_dept(ShiftEmployee) + "\tJob Title:" + self.get_title(ShiftEmployee) + \
"\tShift: " + self.get_shift(ShiftEmployee) + "\tHourly Pay: " + str(self.get_pay(ShiftEmployee))
return result
shift_emp = ShiftEmployee
shift_emp.inputs()
print(shift_emp.__str__(ShiftEmployee))
Don't use a classmethod because
A class method is a method that’s shared among all objects.
Though python itself does not force this behavior, your use of self in the inputs definition indicates that you are not doing what you think. the parameter is traditionally named cls in #classmethod-annotated methods, because the object you're referring to inside the body is not an instance of the class, but the class object itself. This means if you have multiple ShiftEmployee objects, they're going to be writing their data to the same variables. This is not what you want to happen.
you are not instantiating a ShiftEmployee object with shift_emp = ShiftEmployee, but rather assigning the class to the variable shift_emp, which is not what you want to do. so if you remove the #classmethod annotation, I think what you want is
shift_emp = ShiftEmployee() # __init__ gets called when you use this constructor invocation
shift_emp.inputs()
print(shift_emp)
Your __str__ methods don't make a lot of sense. You are passing the class object to each getter, which doesn't seem like it's what you'd want to do. The class object defines the class, what you want are the instances of the class. It's an important, if initially confusing distinction. Posting the error you get would help, but here's what I would expect the methods to look like. I'm not using the getters, because this is internal access, but you can use them instead of directly referring to the state variables if you prefer.
# Employee
def __str__(self):
return f"Name: {self.__name} ID Number: {self.__id} Department: {self.__dept} Job Title: {self.__title}"
# ShiftEmployee
def __str__(self):
return super(ShiftEmployee, self).__str__() + f" Shift: {self.__shift} Hourly Pay: {self.__pay}"
So what's going on here? For one thing, we use format strings because they are easier to work with and exactly the thing you wanted. Then we're using the superclass (Employee) to provide the shared functionality, and using the descendent class to enrich with the ShiftEmployee-only data. I skipped the accessor methods because they're redundant when accessing "private" data from inside the class members. Note that this won't quite do what you expect, either, w.r.t. the shift value that gets printed -- it's going to print the int, not "Night" or "Day". This is where your accessor method comes into play, except that your accessor has an extraneous parameter, shift. So you'd have to remove that value.
Please use the following way to initialize the class and printing the class,
shift_emp = ShiftEmployee() # Added Parenthesis
shift_emp.inputs()
print(str(shift_emp)) # Pass class object to inbuilt str() method to get output from __str__() method from class
As of now I am wondering how to get inputs into a class.
class Contact:
def __init__(self, name = "",strengthPts = 0, power = ""):
self.name = name
self.power = power
self.strengthPts = strengthPts
def addStrengthPts(self, points):
self.strengthPts = self.strengthPts + points
def main():
namequestion = raw_input("put in a name")
time.sleep(1)
powerquestion = raw_input("What power would you like?")
newContact = Contact(namequestion , powerquestion)
print("The fabulous superhero, " + newContact.name)
time.sleep(1)
print(newContact.name + "'s superpower is " + newContact.power )
print(newContact.power)
main()
my output is
The fabulous superhero, test
test's superpower is
My main problem, (on the bottom of the output) is that the power's input is not relaying. I am not sure if this is a simple mistake with how I added it to my "newContact" or a problem with how inputs work with classes.
Your class' initializer is defined with three positional arguments (def __init__(self, name = "",strengthPts = 0, power = ""):). However, in this example you've passed two (newContact = Contact(namequestion , powerquestion)) which would mean that you're setting the value of powerquestion to your class instance's strengthPts instance variable. Since you've elected not to pass the power argument, it will use the default value of a blank string ("").
Either pass a value for the strengthPts positional variable, or use a named argument for power:
newContact = Contact(namequestion, power=powerquestion)
I am trying to add a method to update my acct_type, but I keep getting an error when trying to print out the new account.
class BankAccount(object):
def __init__(self, acct_holder, acct_type, balance = 0):
self.holder = acct_holder
self.type = acct_type
self.balance = balance
"""
Write a constructor for a bank account below.
The following attributes:
acct_holder will be a Person object
acct_type is a string
balance should be defaulted to 0 if not provided to the constructor, is an int
"""
pass
def changeAccountType(self, newType):
self.type = str(self.newType)
def __str__(self):
return str(self.holder) + self.type + str(self.balance)
account_1 = BankAccount('James','checking',45)
account_1.type.changeAccountType("dookieball_account")
print(account_1)
From your code above, I removed the ".type" from "account_1.type.changeAccountType..." and also removed "self." from "self.newType" in your changeaccount function. newType is not contained in self. Hope this help, it's my first attempt on here!
account_1.type.changeAccountType("dookieball_account")
needs to be
account_1.changeAccountType("dookieball_account")
When you use .type, you are getting the type of account_1, which is a string, and trying to call the changeAccountType function on it. Removing it instead calls the function on account_1.
Also, change
self.type = str(self.newType)
to
self.type = str(newType)
Because the newType is a parameter of that function, it is not yet under self.
I am struggling to make this simple code work. I've just started to learn OOP. I looked at other examples but none could point in the right direction. The error is
TypeError: SetStrength() missing 1 required positional argument: 'strength'
import random
class Character:
"""A game character that has strength and skill"""
#constructor
def __init__(self):
#set the attributes with an initial value
self._name = ''
self._strength = 0
self._skill = 0
def SetName(self, name):
self._name = name
def SetStrength(self, strength):
self._strength = calculateAttribute()
def SetSkill(self, skill):
self._skill = calculateAttribute()
def GetName(self):
return self._name
def GetStrength(self):
return self._strength
def GetSkill(self):
return self._skill
def report(self):
return{'name':self._name,'strength': self._strength, 'skill':self._skill}
def calculateAttribute():
return (random.randrange(1,13)//random.randrange(1, 5)) + 10
def main():
player1 = Character()
player1.SetName('James')
player1.SetStrength()
player1.SetSkill()
print(player1.report())
if __name__ == "__main__":
main()
That method is defined as def SetStrength(self, strength):. That means that, in addition to the self which is passed automatically, you need to provide an additional argument - in this case, the new strength value you'd like to set. It works very similarly to setName, which you call with an argument on the previous line.
That said, the code you're working with is Java/C++/etc. code translated into Python, which balloons the size of the code for no good reason.
You should remove the expected argument "strength" of your function "SetStrength". Same for "skill" and "SetSkill".
Try this:
def SetStrength(self):
self._strength = calculateAttribute()
def SetSkill(self):
self._skill = calculateAttribute()
Hi I'm making a program on python and I'm having trouble adding a global variable to my program so I'm just going to post my code and show you how I tried to do it.
So this is my class:
import globalvariables
class Bus :
def __init__(self, Number, Capacity, Destination, Seats):
self.Bus_Number = Number
self.Bus_Capacity = Capacity
self.Bus_Destination = Destination
self.Seats_taken = Seats
def Book(self):
self.Seats_taken = Seats + 1
def ShowBus(self):
return (str(self.Bus_Number) + ", " + str(self.Bus_Capacity) + ", " + str(self.Bus_Destination) + ", " + str(self.Seats_taken))
and this is my module for global variables
Seats = 0
and this is what I'm trying to run:
import Transport
import globalvariables
Big_Red = Transport.Bus(1, 50, "NYC", 0)
Big_Red.Book()
print(Big_Red.ShowBus())
I'm getting this error:
Traceback (most recent call last):
File "D:\Python\Assignment 3\Tester.py", line 5, in <module>
Big_Red.Book()
File "D:\Python\Assignment 3\Transport.py", line 14, in Book
self.Seats_taken = Seats + 1
NameError: global name 'Seats' is not defined
The variable Seats is local to __init__ function and can't be accessed outside of it.
So,
self.Seats_taken = Seats + 1
Should be :
self.Seats_taken = self.Seats_taken + 1
or :
self.Seats_taken += 1
Instead of using global variables inside class you should use class attributes:
class Bus :
seats = 50 #shared across all instances
def __init__(self):
#code
def Book(self):
self.Seats_taken = self.seats + 1
Globals should be avoided. In case you still want it to be :
def Book(self):
self.Seats_taken = globalvariables.Seats + 1
When you import globalvariables, you gain access to names qualified by the module name: globalvariables.Seats. To import Seats into the namespace of another module, use from globalvariables import Seats. (In desperate cases, you can import all names from a module: from globalvariables import *, but usually you don't want this.)
When you define a function, it has its own local namespace. It includes all function's arguments.
Seats = 100
def foo(Seats):
# returns the value of variable named Seats
# defined within "def foo", *not* defined by "Seats = 100"
return Seats
print foo(200) # prints 200
print foo() # fails because Seats are not set
To initialize a function parameter, use default value:
def foo(seats=0):
print foo() # prints 0
print foo(55) # prints 55
Also, global variables are evil. Global constants are good.
You want to use a global variable to track seats taken. You'll be much better off if you encapsulate it into a class that only allows reasonable access, does not allow to set the value arbitrarily, log access if needed, etc:
class SeatsDispenser(object):
def __init__(self, initial_count):
self.count = initial_count
def allocate(self, number_of_seats):
self.count -= number_of_seats
if self.count < 0:
raise ValueError("Overcommitted!")
def seats_left(self):
return self.number_of_seats
Naming your variables, classes, constants, and functions with the same Title Case is impractical. Usually variables are lower_case, functions are lowerCamelCase, classes are TitleCamelCase and constants are ALL_CAPS.
A reasonable piece of code would look like this:
import constants # modules are usually lower case
import transport
def Bus(object):
def __init__(self, number, capacity, seats=constants.SEATS):
self.number = number
self.capacity = capacity
self.seats = seats
big_red = Bus(constants.NYC_BUS_NUMBER, 50, 25)
default_blue = Bus(1, 20) # seats not passed, the default value is used
seats_dispenser = SeatsDispenser(100)
seats_dispenser.allocate(big_red.count)
seats_dispenser.allocate(default_blue.count)
print seats_dispenser.seats.left()