I want to design a class named houses that holds the street address, asking price, number of bedrooms and number of bathrooms in the house. I would also like methods included to get and set values for each data field.
First time working with classes.
I got the class setup and I'm able to print the classes but I'm not sure how or which methods to use.
class houses:
def __init__(self, Adress, Askingprice, NumOfBedrooms, NumofBathroom):
self.Adress = Adress
self.Askingprice = Askingprice
self.NumOfBedrooms = NumOfBedrooms
self.NumofBathroom = NumofBathroom
def HouseDetails(self):
return "The house is at {} with a price of {} and has {} Bedroom/s and {} bathroom/s" \
.format(self.Adress, self.Askingprice, self.NumOfBedrooms, self.NumofBathroom)
house1 = houses("Almonaster_Avenue87", "R 500k", 1, 1)
house2 = houses("Audubon_Place33", "R 900k", 3, 3)
house3 = houses("Baronne_Street78", "R800k", 3, 2)
house4 = houses("Basin_Street55", "R700k", 2, 1)
house5 = houses("Bayou_Road11", "R 900", 4, 2)
house6 = houses("Bienville_Street78", "R700k", 2, 2)
house7 = houses("Bourbon_Street45", "R 800k", 4, 1)
house8 = houses("Broad_Street56", "R 900k", 5, 3)
print("\n",house1.HouseDetails())
Please Note
The "R" at asking price is my currency.
If you must have getter and setter methods, here's a succinct way to do it using Python's built-in property class. The create_property() utility function shown is a simplified version of recipe 9.21 in the 3rd edition of the Python Cookbook by Beazley & Jones (2013).
def create_property(name):
""" Utility to define repetitive property methods. """
storage_name = '_' + name
#property
def prop(self): # getter
return getattr(self, storage_name)
#prop.setter
def prop(self, value): # setter
return setattr(self, storage_name, value)
return prop
class House:
address = create_property('address')
asking_price = create_property('asking_price')
num_bedrooms = create_property('num_bedrooms')
num_bathrooms = create_property('num_bathrooms')
def __init__(self, address, asking_price, num_bedrooms, num_bathrooms):
self.address = address
self.asking_price = asking_price
self.num_bedrooms = num_bedrooms
self.num_bathrooms = num_bathrooms
def __str__(self):
return("The house is at {} with a price of {} and has "
"{} Bedroom/s and {} bathroom/s".format(self.address,
self.asking_price, self.num_bedrooms,
self.num_bathrooms))
house1 = House("Almonaster Avenue 87", "R 500k", 1, 1)
house2 = House("Audubon Place 33", "R 900k", 3, 3)
house3 = House("Baronne Street 78", "R 800k", 3, 2)
house4 = House("Basin Street 55", "R 700k", 2, 1)
house5 = House("Bayou Road1 1", "R 900", 4, 2)
house6 = House("Bienville Street 78", "R 700k", 2, 2)
house7 = House("Bourbon Street 45", "R 800k", 4, 1)
house8 = House("Broad Street 56", "R 900k", 5, 3)
print(house1)
Output:
The house is at Almonaster Avenue 87 with a price of R 500k and has 1 Bedroom/s and 1 bathroom/s
Related
I'm trying to make a simple 5v5 sport management, but I'm not sure how can I link players to teams, in order to make the overall rating of the team be the sum of the players rating / amount of players. Unfortunately my current code only returns where the object is ( <main.Player object at 0x000001CED897FCD0>) but not the player at all, so of course the overall is off
class Player:
totalPlayers = 0
def __init__(self,PName, PYearBorn, POvr, PNumber, PIndex):
self.PName = PName
self.PYearBorn = PYearBorn
self.POvr = POvr
self.PNumber = PNumber
self.PIndex = PIndex
Player.totalPlayers += 1
def getPlayer(self):
return self.PName, self.PYearBorn, self.POvr, self.PNumber, self.PIndex
'''
Player Name
Year Born
Player Overall
Player Number
Player Index'''
class HistoricPlayer(Player):
def __init__(self,PName, PlayerAge, POvr, PNumber, PIndex):
self.PlayerAge=PlayerAge
Player.__init__(self,PName, PlayerAge, POvr, PNumber, PIndex,)
class Franchise():
totalFranchises = 0
def __init__(self, FName, region, championships, yearCreated, rivals):
self.FName = FName
self.region = region
self.championships = championships
self.yearCreated = yearCreated
self.rivals = rivals
Franchise.totalFranchises += 1
class Team(Franchise):
totalTeams = 0
def __init__(self, TName, FName, amountofplayers, maxplayercapacity, region, championships, yearCreated, rivals, currentplayers):
Franchise.__init__(self, FName, region, championships, yearCreated, currentplayers)
self.currentplayers = currentplayers
self.overall = currentplayers[1].POvr/amountofplayers
self.rivals = rivals
self.TName = TName
self.amountofplayers = amountofplayers
self.maxplayercapacity = maxplayercapacity
self.currentplayers = currentplayers
Team.totalTeams+=1
def getTeam(self):
return self.TName, self.FName, self.amountofplayers, self.maxplayercapacity, self.region, self.championships, self.yearCreated, self.rivals, self.currentplayers
''' #Team Class Values
Team Name
Franchise Name
Overall
Amount of current players
Maximum player capacity
Team Region
Championships
Year of Creation
Rivals
Current Players
'''
P01=Player('Francis', 2000, 8, 69, 'p01')
P02=Player('Franton', 2000, 8, 69, 'p01')
P03=Player('Frank', 2000, 8, 69, 'p01')
P04=Player('Felitio', 2000, 8, 69, 'p01')
P05=Player('Fred', 2000, 8, 69, 'p01')
T01=Team('5 Friends', "The friends' club", 5, 6, "Hometown", 0, 2022, 'Rich', (P01, P02, P03, P04, P05))
print(T01.getTeam())
Any idea what should or can I do/what am I doing wrong?
I am trying to return the weighted average of the student's grades based on the last definition. I have the dictionaries defined, but think my attempt to pull the numbers out is incorrect.
def Average(lst):
return sum(lst) / len(lst)
# Driver Code
lst = [1,2,3,4,5]
average = Average(lst)
print("Average of the list =", average)
def get_weighted_average(student):
return average('homework')*0.10 + average('quizzes')*0.30 + average('tests')*.60
#driver code
students = [steve, alice, tyler]
print(get_weighted_average('steve'))
How to get a weighted average out of a dictionary of grades above?
What is the primary source of your data? Text? Anyway, it looks like you have something like this in mind.
Imperative approach
1 - Your "database"
students_marks = {
'steve':{
'homework':[1,2,3,4,5],
'quizzes' :[5,4,3,2,1],
'tests' :[0,0,0,0,0],
},
'alice':{
'homework':[5,4,3,2,1],
'quizzes' :[0,0,0,0,0],
'tests' :[1,2,3,4,5],
},
}
use case:
>>> students_marks['steve']
{'homework': [1, 2, 3, 4, 5], 'quizzes': [5, 4, 3, 2, 1], 'tests': [0, 0, 0, 0, 0]}
>>> students_marks['steve']['homework']
[1, 2, 3, 4, 5]
2 - The definition of average and get_weighted_average
def average(lst):
return sum(lst)/len(lst) # Python3
#return sum(lst)/float(len(lst)) # Python2
def get_weighted_average(student_name):
student_marks = students_marks[student_name]
return round(
average(student_marks['homework'])*.1
+ average(student_marks['quizzes'])*.3
+ average(student_marks['tests'])*.6
, 2)
use case:
>>> get_weighted_average('steve')
1.2
>>> get_weighted_average('alice')
2.1
or using list
>>> students_names = ['steve', 'alice']
>>> [get_weighted_average(name) for name in students_names]
[1.2, 2.1]
or using dict
>>> {name:get_weighted_average(name) for name in students_names}
{'steve': 1.2, 'alice': 2.1}
Object-Oriented (OO) approach
All this being shown, what you want to do would probably be better done by programming in an OO manner. A quick example
class Student(object):
homeworks_weight = .1
quizzes_weight = .3
tests_weight = .6
def __init__(self, name, homeworks_marks, quizzes_marks, tests_marks):
self.name = name
self.homeworks_marks = homeworks_marks
self.quizzes_marks = quizzes_marks
self.tests_marks = tests_marks
#staticmethod
def average(marks):
return sum(marks)/len(marks)
def get_gpa(self, rd=2):
return round(
self.average(self.homeworks_marks)*self.homeworks_weight
+ average(self.quizzes_marks)*self.quizzes_weight
+ average(self.tests_marks)*self.tests_weight
, rd)
use case:
>>> steve = Student(
name = 'Steve',
homeworks_marks = [1,2,3,4,5],
quizzes_marks = [5,4,3,2,1],
tests_marks = [0,0,0,0,0]
)
>>> steve.get_gpa()
1.2
>>> steve.homeworks_marks
[1, 2, 3, 4, 5]
Full code is at the end.
I've written a program that reads in data from a csv file. It creates a class of variable called "Facility". Each facility can have multiple water sources, so there is another class called "WaterSource" which appends a list of attributes for an individual water source to each Facility. If I call :
data['00312']
I get output:
Facility 00312 US Aggregates Inc IN
If I ask for data['00312'].records:
[ WaterSource 00312 WELL Willshire 80 683175 4511625,
WaterSource 00312 WELL Willshire 80 682550 4511750,
WaterSource 00312 INTAKE Willshire 1200 Unnamed Quarry 683225 4512075,
WaterSource 00312 INTAKE Willshire 1200 Unnamed Quarry 683225 4512050]
I need to create a report that iterates over every variable in the class and returns a list of Facilities that have multiple water sources. Thus the final output would a list of [RegNo, Facility Name, No. of WaterSources] such as:
[Facility 00312 US Aggregates Inc 4]
The issue I'm having is understanding how to iterate over the Facilities to count the records of the water sources appended to each Facilities object. I think I could add a method into the class somewhere, but I can't quite figure out where. I'm a python beginner, so please forgive me if this isn't quite the right vocabulary. I'm not even sure where to start, so any suggestions you could offer would be helpful.
class Facilities:
def __init__(self, regno, name, mwu): ##creates facility attributes
self.regno = regno
self.name = name
self.mwu = mwu
self.records = []
def add_record(self,record):
self.records.append(record)
def __repr__(self):
'''Makes a string representation'''
return 'Facility {0} {1} {2}'.format(self.regno, self.name, self.mwu)
class WaterSource(Facility):
'''holds info about the water source'''
def __init__(self, regno, source, quad, cap, body, utmE, utmN): ##creates water source attributes
self.regno = regno
self.source = source
self.quad = quad
self.cap = cap
self.body = body
self.utmE = utmE
self.utmN = utmN
self.records = []
def source_data(self):
regnos = []
sources = []
quads = []
caps = []
bodies = []
utmEs = []
utmNs = []
for record in self.records:
regnos.append(record.regno)
sources.append(record.source)
quads.append(record.quad)
caps.append(record.cap)
bodies.append(record.body)
utmEs.append(record.utmE)
utmNs.append(record.utmN)
return (regnos,sources,quads,caps,bodies,utmEs,utmNs)
def __repr__(self):
return ' WaterSource {0} {1} {2} {3} {4} {5} {6}'.format(self.regno, \
self.source, self.quad, self.cap, self.body, self.utmE, self.utmN)
def read_data(filename):
rv = {}
for r in csv.DictReader(open(filename, 'r', encoding='UTF-8')):
regno = r['RegNo']
if r['RegNo'] not in rv:
rv[regno] = Facilities(r['RegNo'],r['Facility'], r['MWU Code'])
rv[regno].add_record(WaterSource(regno, r['Source Code'], r['Quadrangle'], \
r['Capacity (GPM)'], r['Water Body Name'], r['UTM East'], r['UTM North']))
return rv
data = read_data('Fac-2013-2016.csv')
[Facility 00312 US Aggregates Inc 4]
The issue I'm having is understanding how to iterate over the
Facilities to count the records of the water sources appended to each
Facilities object.
From my understanding, simply add a method and return a count of the objects or straight up count the records using len unless there is something more to what you are asking for?
class Facilities:
def __init__(self, regno, name, mwu): ##creates facility attributes
self.regno = regno
self.name = name
self.mwu = mwu
self.records = []
def add_record(self,record):
self.records.append(record)
def __repr__(self):
'''Makes a string representation'''
return 'Facility {0} {1} {2} {3}'.format(self.regno, self.name, self.mwu , len(self.records))
All of your Facilities are stored as values in the dictionary data using the facility's RegNo for the keys. You can iterate over all the data using the dictionary items method. The length of each facility's records attribute is the number of water sources. You can build a format string to use the information you need.
for reg_no, facility in data.items():
no_of_sources = len(facility.records)
print(f'Facility {facility.regno} {facility.name} {no_of_sources}') #Python v3.6+
#print('Facility {} {} {}'.format(facility.regno, facility.name, no_of_sources)) #Python versions <3.6
What is the best solution to pivot/cross-tab tables in Python 3? Is there a built-in function that will do this? Ideally, I'm looking for a Python 3 solution that does not have external dependencies. For example, given a nested list:
nl = [["apples", 2 "New York"],
["peaches", 6, "New York"],
["apples", 6, "New York"],
["peaches", 1, "Vermont"]]
I would like to be able to rearrange rowed data and groupby fields:
apples peaches
New York 2 6
Vermont 6 1
The above is a trivial example, but is there a solution that would be easier than using itertools.groupby everytime a pivot is desired? Ideally, the solution would allow rowed data to be pivoted on any column. I was debating about using pandas, but it is an external library and only has limited Python 3 support.
Here is some simple code. Providing row/column/grand totals is left as an exercise for the reader.
class CrossTab(object):
def __init__(
self,
missing=0, # what to return for an empty cell.
# Alternatives: '', 0.0, None, 'NULL'
):
self.missing = missing
self.col_key_set = set()
self.cell_dict = {}
self.headings_OK = False
def add_item(self, row_key, col_key, value):
self.col_key_set.add(col_key)
try:
self.cell_dict[row_key][col_key] += value
except KeyError:
try:
self.cell_dict[row_key][col_key] = value
except KeyError:
self.cell_dict[row_key] = {col_key: value}
def _process_headings(self):
if self.headings_OK:
return
self.row_headings = list(sorted(self.cell_dict.keys()))
self.col_headings = list(sorted(self.col_key_set))
self.headings_OK = True
def get_col_headings(self):
self._process_headings()
return self.col_headings
def generate_row_info(self):
self._process_headings()
for row_key in self.row_headings:
row_dict = self.cell_dict[row_key]
row_vals = [
row_dict.get(col_key, self.missing)
for col_key in self.col_headings
]
yield row_key, row_vals
if __name__ == "__main__":
data = [["apples", 2, "New York"],
["peaches", 6, "New York"],
["apples", 6, "New York"],
["peaches", 1, "Vermont"]]
ctab = CrossTab(missing='uh-oh')
for s in data:
ctab.add_item(row_key=s[2], col_key=s[0], value=s[1])
print()
print('Column headings:', ctab.get_col_headings())
for row_heading, row_values in ctab.generate_row_info():
print(repr(row_heading), row_values)
Output:
Column headings: ['apples', 'peaches']
'New York' [8, 6]
'Vermont' ['uh-oh', 1]
See also this answer.
And this one, which I'd forgotten about.
itertools.groupby was exactly made for this problem. You will be hard-pressed to find something better, especially within the standard library.
This is a homework question, but as you can see I've written most of the code already. :) What I'm trying to have happen is that the Agent object inherits the methods from the Investor object, as the Agent object's methods are suppose to be basically the same. The only different is the constructors, Investor takes 6 parameters, Agent takes 7. You can see that the parameters are also basically the same.
Investor.load and Investor.report work, for the most part, as expected. The inherited methods in Agent do not. See below.
My main issues:
When I run report(o) on Investor, the output is slightly messed up. It has little paragraph symbols at the end of each line, rather than a carriage return. (I'm developing on linux)
When I run load and report on Agent, it does not populate my arrays (reports and data) as it should. Because of that, report prints nothing. How do I set up my class variables so that they work in the way I want them to?
Thanks!
Will re-add after turnin date.
Here is how the above code SHOULD function.
>>> from sys import stdout as o
>>> import datetime
>>> from hedgefunds import *
>>>
>>> i = Investor('Flintstone','Fred',datetime.date(1965,12,3),'male','Mr.')
>>>
>>> i
Investor('Flintstone', 'Fred', datetime.date(1965, 12, 3), 'male', 'Mr.', 1)
>>> repr(i)
"Investor('Flintstone', 'Fred', datetime.date(1965, 12, 3), 'male', 'Mr.', 1)"
>>> i.__repr__() # THIS CONTROLS PREVIOUS TWO LINES
"Investor('Flintstone', 'Fred', datetime.date(1965, 12, 3), 'male', 'Mr.', 1)"
>>> eval(repr(i)) # OBJECT CAN BE RECREATED FROM ITS REPR STRING
Investor('Flintstone', 'Fred', datetime.date(1965, 12, 3), 'male', 'Mr.', 1)
>>>
>>> i # NOTICE ONE ADDITIONAL BIT OF DATA WE DIDN'T SPECIFY?
Investor('Flintstone', 'Fred', datetime.date(1965, 12, 3), 'male', 'Mr.', 1)
>>> # THE '1' AT THE END IS THE RECORD ID rid. THE REPR STRING INCLUDES ALL DATA SO YOU SEE IT.
>>> # THE INVESTOR CLASS SHOULD ASSIGN A rid IF ONE IS NOT PASSED INTO THE CONSTRUTOR.
>>>
>>> print i
1, Mr. Fred Flintstone, 12/03/1965, male
>>> i.__str__() # THIS CONTROLS PREVIOUS LINE
'1, Mr. Fred Flintstone, 12/03/1965, male'
>>>
>>> # NOTE THE NAME IS NICELY PUT TOGETHER AND AND rid IS AT THE START
>>> # NOTE datetime.date(YYYY, MM, DD) BUT WE PRINT IN MM/DD/YYYY FORMAT
>>>
>>> # NOW LET'S LOOK AT OUR INVESTOR OBJECT'S ATTRIBUTES
>>> i.last_name
'Flintstone'
>>> i.first_name
'Fred'
>>> i.dob
datetime.date(1965, 12, 3)
>>> i.date_of_birth
'12/03/1965'
>>> i.gender
'male'
>>> i.title
'Mr.'
>>> i.name
'Mr. Fred Flintstone'
>>> i.rid
1
>>>
>>> # BUT WE'RE GONNA NEED SOMEHWERE TO STORE MULTIPLE INVESTOR OBJECTS
>>> # SO AS WELL AS CREATING INVESTOR OBJECTS, THE INVESTOR CLASS MUST ACT LIKE A RECORDSET
>>>
>>> Investor.report(o) # o WAS SET TO STDOUT AT THE TOP OF THIS TRACE BUT COULD BE ANY FILE
>>> Investor.add(i) # NO RECORDS SO LET'S ADD ONE
>>> Investor.report(o) # NOW WE HAVE SOMETHING TO REPORT
1, Mr. Fred Flintstone, 12/03/1965, male
>>>
>>> Investor.add(Investor('Flintstone','Wilma',datetime.date(1968,1,15),'female','Mrs.'))
>>> Investor.report(o)
1, Mr. Fred Flintstone, 12/03/1965, male
2, Mrs. Wilma Flintstone, 01/15/1968, female
>>>
>>> # WE COULD CONTINUE ADDING INVESTORS MANUALLY BUT SINCE WE'VE GOT A FILE FULL OF THEM....
>>> Investor.load('investors.csv')
>>> Investor.report(o)
1, Mr. Charles Creed, 12/05/1928, male
2, Miss Sheila Geller, 11/12/1962, female
3, Mr. Fred Kenobi, 07/13/1957, male
4, Miss Rachel Geller, 07/11/1968, female
5, Mr. Charles Rubble, 09/23/1940, male
6, Mrs. Leah Skywalker, 07/02/1929, female
7, Mr. Bill Balboa, 03/06/1988, male
8, Dr. Sheila Barkley, 08/26/1950, female
.
.
>>> # YOU SHOULD SEE 120 RECORDS (OUR TWO MANUALLY ADDED RECORDS ARE GONE)
>>>
>>>
>>>
>>> # AGENTS
>>>
>>> a = Agent(2.1,'Rubble','Barney',datetime.date(1966,4,20),'male','Mr.')
>>> a
Agent(2.1000000000000001, 'Rubble', 'Barney', datetime.date(1966, 4, 20), 'male', 'Mr.', 1)
>>> repr(a)
"Agent(2.1000000000000001, 'Rubble', 'Barney', datetime.date(1966, 4, 20), 'male', 'Mr.', 1)"
>>> eval(repr(a))
Agent(2.1000000000000001, 'Rubble', 'Barney', datetime.date(1966, 4, 20), 'male', 'Mr.', 1)
>>> print a
1, Mr. Barney Rubble, 04/20/1966, male, 2.1
>>> a.last_name
'Rubble'
>>> a.first_name
'Barney'
>>> a.dob
datetime.date(1966, 4, 20)
>>> a.date_of_birth
'04/20/1966'
>>> a.gender
'male'
>>> a.title
'Mr.'
>>> a.name
'Mr. Barney Rubble'
>>> a.rid
1
>>> a.commission
2.1000000000000001
>>> Agent.add(a)
>>> Agent.report(o)
1, Mr. Barney Rubble, 04/20/1966, male, 2.1
>>> Agent.load('agents.csv')
>>> Agent.report(o)
1, Mr. Barney Flintstone, 02/13/1933, male, 4.0
2, Miss Rachel Rubble, 11/21/1982, female, 2.5
3, Dr. Ted Geller, 03/14/1963, male, 8.0
4, Miss Phoebe Creed, 11/06/1959, female, 5.5
5, Mr. Luke Kenobi, 08/24/1945, male, 2.5
6, Dr. Megan Creed, 03/26/1957, female, 5.5
7, Mr. Ted Rubble, 09/14/1931, male, 3.5
8, Mrs. Monica Balboa, 05/07/1934, female, 1.5
There is a lot going on here, so I'll try to be brief.
class Investor(object):
reports = []
data = []
def __init__(self, LastName, FirstName, Date, Gender, Title, Rid=1):
# the following two lines define variables which only exist inside
# __init__, so they can basically be gotten rid of.
# reports = []
# data = []
# but they *don't need to be initialized*. Actually creating a new list
# in each constructor is *bad* unless you want one report per instance
# ... later, be sure to add "self" instead of adding to the local vars
self.add(self)
#classmethod
def report(self, o):
result = ""
for x in self.reports:
# Just use join, that's what you mean anyway.
result = ', '.join(x)
# \n should result in \n\n. I think you mean o.write(result)
o.write(result + "\n")
#classmethod
def load(self, f):
self.reports = []
self.data = []
file = open(f)
# why the extra readline?
file.readline()
list = []
while 1:
line = file.readline()
# you need to get rid of the trailing whitespace
items = line[:-1].split(", ")
if not line:
break
else:
# self, here, refers to the class, so you can use it as the
# constructor as well
# use the * to make a list into an argument list.
self(*items)
# No need to add it, the value is added at the end of __init__
# as things stand.
class Agent(Investor):
reports = []
data = []
def __init__(self, Commission, LastName, FirstName, \
Date, Gender, Title, Rid=1):
super(Agent, self).__init__(self, LastName, FirstName, Date, \
Gender, Title, Rid)
self.commission = Commission
def __str__(self):
# Be lazy! Use super!
return super(Agent,self).__str__() + ', ' + self.commission
# this was doing the same thing in the parent class.
# def __repr__(self):
# The classmethod methods are not needed unless you want to redefine
# behavior in a child class.
#classmethod
def add(self, i):
# If you do change something, though, make sure to use super
# here as well...
super(Agent, self).add(i)
I believe that should take care of most of your issues.
If you want to have the format Investor('Flintstone', 'Fred', datetime.date(1965, 12, 3), 'male', 'Mr.', 1), you'll need to include the __name__ and quote the properties:
def __repr__(self):
# notice the " and ' below.
return self.__name__ + "('" + str(self.rid) + "', '" + \
self.name + "', " + self.date_of_birth + ", '" + self.gender + "')"
In Agent you will need to use a sub-string to get what you need:
def __repr__(self):
# remove the Agent( so you can add the commission at the *front*
s = super(Agent,self).__str__()
return self.__name__ + "('" + self.commission + "'," + \
s[len(self.__name__ + 1):]