def _get_fields(self, s): start = s.find(MARKER) if start < 0: return (None, '') s = s[start + len(MARKER):] (price, s) = html_helper.find_in_between(s, '$', '<') price = int(float(price.replace(',', ''))) if price > MAX_PRICE: return (None, '') (link, s) = html_helper.find_in_between(s, LINK_START, '"') (title, s) = html_helper.find_in_between(s, '>', '<') (fee_text, s) = html_helper.find_in_between(s, FEE_START, '<') no_fee = 'no' in fee_text.lower() ending = s.find(LINE_END) end_listing = s[:ending] start = end_listing.rfind(' ') posting_date = end_listing[start:].strip() listing = Apartment(SOURCE, title, price, link) listing.set_has_fee(not no_fee) listing.set_posting_date(posting_date) return (listing, s)
def test_apartment_get_total_expenses(): water = 34 others = 3452 apart = Apartment(water=water, others=others) assert apart.get_total_expenses() == (water + others) heating = 245 apart.expenses["heating"] = heating assert apart.get_total_expenses() == (water + others + heating)
def test_apartment_is_expense_type(): assert Apartment.is_expense_type("gas") assert not Apartment.is_expense_type("gas1") assert not Apartment.is_expense_type("heating2") assert Apartment.is_expense_type("others") assert not Apartment.is_expense_type("other") assert not Apartment.is_expense_type([]) assert not Apartment.is_expense_type(23) assert not Apartment.is_expense_type(["gas"]) assert Apartment.is_expense_type("illuminating")
def filter_parse(self, command): """ Parses and validates the filter command Input: command - the user command Return: True on valid and False otherwise """ self.set_command(command) # filter by total amount greater than pattern_total_greater = self._regex_search(self._PATTERN_FILTER_GREATER_THAN_TOTAL) if pattern_total_greater: greater = pattern_total_greater.group(1) self._parsed_command = {"greater": greater, "type": None} return True # filter by only apartments having that type pattern_by_type = self._regex_search(self._PATTERN_FILTER_BY_TYPE) if pattern_by_type: expense_type = pattern_by_type.group(1) if not Apartment.is_expense_type(expense_type): UI.set_message(UI.get_error_types()) return False self._parsed_command = {"greater": None, "type": expense_type} return True UI.set_message(UI.get_error_filter()) return False
def sort_parse(self, command, reverse=False): """ Parses and validates the sort command Input: command - the user command reverse - the order of the sort Return: True on valid and False otherwise """ self.set_command(command) # simple sort no type use total expense pattern_sort = self._regex_search(self._PATTERN_SORT) if pattern_sort: self._parsed_command = {"type": None, "reverse": reverse} return True # use an expense type for the sort pattern_sort_by_type = self._regex_search(self._PATTERN_SORT_BY_TYPE) if pattern_sort_by_type: expense_type = pattern_sort_by_type.group(1) if not Apartment.is_expense_type(expense_type): UI.set_message(UI.get_error_types()) return False self._parsed_command = {"type": expense_type, "reverse": reverse} return True UI.set_message(UI.get_error_sort()) return False
def parse_listing(self, response): dl = {} for details in response.css('.object-kenmerken-body dl'): dts = details.css('dt::text').getall() dds = details.css('dd::text').getall() dl.update({d[0]: d[1] for d in zip(dts, dds)}) desc = ''.join( response.css( 'div.object-description-body::text').getall()).lower() yield Apartment( site=self.name, street=response.css('.object-header__title::text').get(), price=dl['Rent per month'], bedrooms=dl['Number of bedrooms'], surface=dl['Square meters'], url=response.url, available=fixdate(dl['Available from']), since=fixdate(dl['Offered since']), postcode=response.css( '.object-header__subtitle::text').get().replace( ' Amsterdam', ''), description=desc, )
def parse_listing(self, response): details = response.css('#details > dl') dts = details.css('dt::text').getall() dds = details.css('dd::text').getall() dl = { d[0]:d[1] for d in zip(dts, dds) } if dl['Offered since'] == '> 3 months': self.logger.info('Property more than 3 months old - SKIPPING') return under_contract = details.css('span.under-contract::text').get() if under_contract is not None: self.logger.info(f'Property taken: {under_contract} - SKIPPING') return desc = ''.join(response.css('#description p.text::text').getall()).lower() yield Apartment( site = self.name, street = dl['Street'], price = dl['Rent per month'], bedrooms = dl['Number of bedrooms'], surface = dl['Square meters'], url = response.url, available = fixdate(dl['Available from']), since = fixdate(dl['Offered since']), postcode = dl['Postal code'], description = desc, )
def _get_result(self, s): (latlong, s) = html_helper.find_in_between(s, "se:map:point='", "'") if latlong == None: return (None, s) (lat, long) = latlong.split(',') end = s.find("<div class='photo'>") has_no_fee = 'banner no_fee' in s[:end] s = s[end:] (url, s) = html_helper.find_in_between(s, 'href="', '"') url = BASE_URL + url (title, s) = html_helper.advance_and_find(s, '"details-title">', '"true">', '<') (price, s) = html_helper.advance_and_find(s, "'price'", '$', '<') price = int(float(price.replace(',', ''))) listing = Apartment(SOURCE, title, price, url) listing.set_location(float(lat), float(long)) listing.set_has_fee(not has_no_fee) start = s.find("class='first_detail_cell'") section_end = s.find('</div', start) end = s[:section_end].find('²') if end >= 0: section = s[:end] start = section.rfind('>') + 1 end = section.find(' ', start) listing.set_sqft(int(section[start:end].replace(',', ''))) return (listing, s)
def _format_data(self, fee, list): urls = [] listings = [] for item in list: if 'NumPosts' in item: urls.append(item['url']) continue bedrooms = int(float(item['Bedrooms'])) if bedrooms != 1 or 'studio' in item['PostingTitle'].lower(): continue apartment = Apartment( SOURCE, item['PostingTitle'], int(float(item['Ask'])), BASE_URL + item['PostingURL']) apartment.set_location(item['Latitude'], item['Longitude']) apartment.set_posting_timestamp(item['PostedDate']) apartment.set_has_fee(fee == Fees.FEE) listings.append(apartment) map(lambda listing: self._load_more_data(listing), listings) return (listings, urls)
def _find_listing(self, s): (url, s) = html_helper.advance_and_find(s, TITLE_PLACE_MARKER, 'href="', '"') (title, s) = html_helper.find_in_between(s, '>', '<') if url == None or title == None: return (None, s) title = html_helper.strip_tags(title) (price, s) = html_helper.advance_and_find(s, 'color-fg-green', '$', '<') price = int(float(price.strip().replace(',', ''))) (_, s) = html_helper.advance_and_find(s, '<td', '', '<div') (recency, s) = html_helper.advance_and_find(s, '"bold font-size-100"', '>', '</div') recency = html_helper.strip_tags(recency).lower() dt = self._understand_recency(recency, url) listing = Apartment(SOURCE, title, price, url) listing.set_posting_timestamp(dt.strftime('%s')) return (listing, s)
def get_current_apartments() -> List[Apartment]: current_apartments: List[Apartment] = [] with open("urls.txt", 'r') as file: temp_list = file.read().splitlines() for elem in temp_list: url = elem.split(",")[0].strip() price = elem.split(",")[1].strip() current_apartments.append(Apartment(url, price)) return current_apartments
def _insert_or_replace_apartment_parse(self, command, command_type): """ Protected parse method for insert and replace Input: command - the user command command_type - the command_type, can be insert or replace Return: True on valid and False otherwise Raises: Exception on invalid command_type """ self.set_command(command) # get the correct pattern if command_type is "insert": pattern = self._regex_search(self._PATTERN_INSERT) if not pattern: UI.set_message(UI.get_error("insert <amount>, <expense_type> at <apartment_id>")) return False elif command_type is "replace": pattern = self._regex_search(self._PATTERN_REPLACE) if not pattern: UI.set_message(UI.get_error("replace <amount>, <expense_type> at <apartment_id>")) return False else: raise Exception("command type is incorrect") # get the data amount = pattern.group(1) expense_type = pattern.group(2) apartment_id = pattern.group(3) # wrong type if not Apartment.is_expense_type(expense_type): UI.set_message(UI.get_error_types()) return False if command_type is "insert": # apartment does exist in the list if self.is_apartment(apartment_id): UI.set_message("Apartment " + apartment_id + " does exist in the list. " "Use this command to replace: replace " + amount + ", " + expense_type + " at " + apartment_id) return False elif command_type is "replace": # apartment does not exist in the list if not self.is_apartment(apartment_id): UI.set_message("Apartment " + apartment_id + " does not exist in the list. " "Use this command to add: insert " + amount + ", " + expense_type + " at " + apartment_id) return False # all good self._parsed_command = {"type": expense_type, "amount": amount, "id": apartment_id} return True
def main(): manhattan_studio_apt = Apartment(1, 16, 5500) atlanta_two_bedroom_apt = Apartment(2, 38, 4200) bangor_three_bedroom_apt = Apartment(3, 78, 2500) print(manhattan_studio_apt.more_expensive_than( atlanta_two_bedroom_apt)) # true print(bangor_three_bedroom_apt.more_expensive_than( atlanta_two_bedroom_apt)) # false
def prompt_init(): """ This method calls the parent methods prompt_init(), which asks user to initialize appropriate instances of classes Apartment and Purchase. :return: an instance which represents an apartment for purchasing - inherits from Apartment and Purchase. """ init = Apartment.prompt_init() init.update(Purchase.prompt_init()) return init
def loadApartments(self, file): apartment_data = open(file) for object in apartment_data: item = object.split(' ') apt_num = item[0] apt_bedrm = int(item[1]) apt_baths = int(item[2]) apt_rent = int(item[3]) apt_status = 'A' apt_status = apt_status.replace('\n','') self.apartments.append(Apartment(apt_num, apt_bedrm, apt_baths, apt_rent, apt_status)) apartment_data.close()
def from_dictionary(dictionary): """ Creates a new Apartment Object from a dictionary Input: dictionary - a dictionary compatible with Bloc Return: A new Bloc object """ new_dict = {} for apartment_id in dictionary: new_dict[apartment_id] = Apartment.from_dictionary(dictionary[apartment_id]) return Bloc(new_dict)
def get_apartments(url) -> List[Apartment]: r = requests.get(url) tree = html.fromstring(r.text) apartments = tree.xpath(".//div[contains(@class,'imaHover')]") apartments_list: List[Apartment] = [] for apartment in apartments: apartment_url: str = apartment.xpath( ".//div[@class='naslov']/a")[0].attrib.get("href") price: str = apartment.xpath( ".//div[@class='datum']/span[1]/text()[1]")[0].strip() apartments_list.append(Apartment(apartment_url, price)) return apartments_list
def prompt_init(): init = Apartment.prompt_init() init.update(Purchase.prompt_init()) return init #Sets the prompt to set de values #init = ApartmentPurchase.prompt_init() #print(init) #with the data setted, instance a object and sets # the data(**) by the constructor #apartment = ApartmentPurchase(**init) #print(Apartment.__dict__, '--->') #show data for a Purchase Apartment #apartment.display()
def to_dictionary(bloc_obj): """ Creates a dictionary from an Bloc object Input: bloc_obj - a object instance of Bloc Return: a new dictionary representing the object Raises: Exception on wrong object """ if isinstance(bloc_obj, Bloc): bloc_dict = bloc_obj.get() for apartment_id in bloc_dict: bloc_dict[apartment_id] = Apartment.to_dictionary(bloc_dict[apartment_id]) return bloc_dict raise Exception("bloc_obj is not of type Apartment")
def remove_apartment_parse(self, command): """ Parses and validates the remove command Input: command - the user command Return: True on valid and False otherwise """ self.set_command(command) # first case by apartment id pattern_remove_by_id = self._regex_search(self._PATTERN_REMOVE_BY_ID) if pattern_remove_by_id: apartment_id = pattern_remove_by_id.group(1) if not self.is_apartment(apartment_id): UI.set_message( "Apartment " + apartment_id + " does not exist in this list so all the expenses are by default 0") return False self._parsed_command = {"id": apartment_id} return True # second case remove from interval pattern_remove_by_interval = self._regex_search(self._PATTERN_REMOVE_BY_INTERVAL) if pattern_remove_by_interval: id_min = pattern_remove_by_interval.group(1) id_max = pattern_remove_by_interval.group(2) self._parsed_command = {"id_min": id_min, "id_max": id_max} return True # third case by type pattern_remove_by_type = self._regex_search(self._PATTERN_REMOVE_BY_TYPE) if pattern_remove_by_type: expense_type = pattern_remove_by_type.group(1) if not Apartment.is_expense_type(expense_type): UI.set_message(UI.get_error_types()) return False self._parsed_command = {"type": expense_type} return True UI.set_message(UI.get_error("remove <apartment_id> \n\tremove from 5 to 10 \n\tremove type")) return False
def list_by_type_parse(self, command): """ Parses and validates the list command Input: command - the user command Return: True on valid and False otherwise """ self.set_command(command) # list <type> pattern_type = self._regex_search(self._PATTERN_LIST_BY_TYPE) if pattern_type: expense_type = pattern_type.group(1) if not Apartment.is_expense_type(expense_type): UI.set_message(UI.get_error_types()) return False self._parsed_command = {"expense_type": expense_type} return True UI.set_message(UI.get_error("list <expense_type>")) return False
def stat_total_type_parse(self, command): """ Parses and validates the 'sum type' command Input: command - the user command Return: True on valid and False otherwise """ self.set_command(command) # sum <type> pattern_sum = self._regex_search(self._PATTERN_STAT_TOTAL_TYPE) if pattern_sum: expense_type = pattern_sum.group(1) if not Apartment.is_expense_type(expense_type): UI.set_message(UI.get_error_types()) return False self._parsed_command = {"expense_type": expense_type} return True UI.set_message(UI.get_error("sum <type>")) return False
# room1 = np.ones([5, 5]) # room2 = np.ones([10, 5]) # room3 = np.ones([5, 5]) # heatmap = np.append(outside, room1, axis=0) # heatmap = np.append(heatmap, room2, axis=1) # room3_temp = np.append(room3, outside, axis=0) # print(room3_temp) # heatmap = np.append(heatmap, room3_temp, axis=1) # # extent = [0, 3, 0, 2] # # plt.clf() # plt.imshow(heatmap, extent=extent, origin='upper') # plt.colorbar() # plt.title('Apartment heatmap') # plt.show() print('hej') # To create rooms dx = 1. / 3 r1 = RoomOne(20, dx) print('room1') r2 = RoomTwo(20, dx) print('room2') r3 = RoomThree(20, dx) print('room3') flat = Apartment(r1, r2, r3) print('apart') flat.plot_apartment()
if tenant.tenant_aptNum == aptNum: print('Tenant Name: ' + tenant.tenant_fName + ' ' + tenant.tenant_lName) if aptNum not in apt_num_list: print('This apartment does not exist.') if aptNum in avail_num_list: print('This apartment is available.') elif choice == 7: apt_num = int(input('Enter apartment number: ')) apt_bedrm = int(input('Enter number of bedrooms: ')) apt_baths = int(input('Enter number of bathrooms: ')) apt_rent = int(input('Enter apartment rent: ')) new_apartment = Apartment(apt_num, apt_bedrm, apt_baths, apt_rent, 'A') apartment_db.addApartment(new_apartment) elif choice == 8: total_apartments = apartment_db.getTotalApartments() available_apartments = len(apartment_db.getAvailApartments()) rented_apartments = len(apartment_db.getRentedApartments()) total_tenants = tenant_db.countTenants() print('Total Apartments: {}'.format(total_apartments)) print('Available Apartments: {}'.format(available_apartments)) print('Rented Apartments: {}'.format(rented_apartments)) print('Total Tenants: {}'.format(total_tenants)) done = True
def main(): """ Main-file where each task can be executed one at a time. Run main-file by typing “mpiexec -n 2 python main.py” """ # Defining mpi comm = MPI.COMM_WORLD rank = MPI.COMM_WORLD.Get_rank() # User gets to chose task task = None if rank == 0: input_not_ok = True while input_not_ok: task = input('Choose a task: ') if task == '1' or task == '2' or task == '3' or task == '4': task = int(task) print('You chose task : ' + str(task) + '\n') input_not_ok = False else: print('You must chose task 1, 2, 3' or 4) task = comm.bcast(task, root=0) # ---------------------------------------------------- Task 1 ----------------------------------------------------- # if task == 1: if rank == 0: # Mesh size dx = 1/3 # Create rooms r1 = RoomOne(10, dx) r2 = RoomTwo(20, dx) r3 = RoomThree(25, dx) # Print all matrices print('Matrix for room 1\n', r1.a) print('\n') print('Matrix for room 2\n', r2.a) print('\n') print('Matrix for room 3\n', r3.a) print('\n') # -------------------------------------------------- Task 2 & 3 --------------------------------------------------- # if task == 2 or task == 3: # Mesh size dx = 1/20 # Create rooms r1 = RoomOne(20, dx) r2 = RoomTwo(20, dx) r3 = RoomThree(20, dx) # Create apartment flat = Apartment(r1, r2, r3) # Solve heat equation problem flat.dirichlet_neumann() if rank == 0: # Calculate mean temperature u_mean = np.mean(np.concatenate((flat.r1.u, flat.r2.u, flat.r3.u))) print('Mean temperature: ' + str(u_mean)) # Plot apartment flat.plot_apartment() # ---------------------------------------------------- Task 4 ----------------------------------------------------- # # Optional assignment - try other initial temperatures if task == 4: # Create rooms r1 = RoomOne(temp_init=10, dx=1/30, temp_wall=15, temp_heater=30) r2 = RoomTwo(temp_init=20, dx=1/30, temp_wall=15, temp_heater=40, temp_window=-10) r3 = RoomThree(temp_init=25, dx=1/30, temp_wall=15, temp_heater=50) # Create apartment flat = Apartment(r1, r2, r3) # Solve heat equation problem flat.dirichlet_neumann() if rank == 0: # Calculate mean temperature u_mean = np.mean(np.concatenate((flat.r1.u, flat.r2.u, flat.r3.u))) print('Mean temperature: ' + str(u_mean)) # Plot apartment flat.plot_apartment()
from apartment import Apartment from penthouse import Penthouse from personal_home import PersonalHome from sales_manager import SalesManager from list_location_of_SIO import ListLocationOfSIO if __name__ == '__main__': my_sales_manager = SalesManager my_sales_manager.accommodationList.append(Apartment(2, 400, 40, 20, 100)) my_sales_manager.accommodationList.append(Apartment(1, 200, 80, 10, 500)) my_sales_manager.accommodationList.append( PersonalHome(8, 400, 50, 2000, 300)) my_sales_manager.accommodationList.append( PersonalHome(3, 350, 40, 200, 100)) my_sales_manager.accommodationList.append(Penthouse( 8, 200, 60, 1000, True)) my_sales_manager.accommodationList.append(Penthouse(9, 120, 50, 15, False)) my_sales_manager.accommodationList = my_sales_manager.\ find_accommodation_by_price(300, my_sales_manager.accommodationList) for accommodation in my_sales_manager.accommodationList: print(accommodation.__str__()) print('\n') my_sales_manager.accommodationList = my_sales_manager.\ find_by_distance(my_sales_manager.accommodationList , ListLocationOfSIO.school.value.latitude, 300) for accommodation in my_sales_manager.accommodationList: print(accommodation.__str__())
doorman = False building = Building(name=name, address=address, num_floors=num_floors, doorman=doorman) print "Thanks for adding building {0}".format(building) if response == "a": unit = raw_input("What is the unit number? ") rent = raw_input("What is the monthly rent? ") sqft = raw_input("How many sq feet are in the apartment? ") num_bedrooms = raw_input("How many bedrooms does it have? ") num_bathrooms = raw_input("How many bathrooms does it have? ") apartment = Apartment(unit=unit, rent=rent, sqft=sqft, num_bedrooms=num_bedrooms, num_bathrooms=num_bathrooms) try: building.apartments[unit] = apartment print "Thanks for adding unit {0} to building {1}".format( apartment.unit, building.name) except NameError: print "You have to add a building first" if response == "r": name = raw_input("What is the renter's name? ") age = raw_input("What is the renter's age? ") renter = Person(name=name, age=age) if not apartment.is_full(): apartment.renters.append(renter)
def prompt_init(): init = Apartment.prompt_init() init.update(Rental.prompt_init()) return init
from apartment import Apartment from sys import stdout as out result = False while result == False: out.write("How big is the apartment? (in meters): ") size = input() print('How much did it cost? (in euros)') cost = input() flat = Apartment(size, cost) result = flat.calculate() if result: print('Square meter cost is {}€'.format(result)) else: print("You didn't insert correct values, try again!") print('Do you want to calculate pricing of another apartment? (y/n)') answer = input() if answer == 'y' or answer == 'yes': result = False
def test_get_max_expenses_type(): apart = Apartment(water=100, gas=200) assert apart.get_max_expenses_type() == ["gas"] apart.expenses["water"] = 200 apart.expenses["others"] = 200 assert sorted(apart.get_max_expenses_type()) == sorted(["gas", "water", "others"]) apart.expenses["heating"] = 999 apart.expenses["illuminating"] = 23 assert apart.get_max_expenses_type() == ["heating"] apart = Apartment() assert apart.get_max_expenses_type() == [] apart.expenses["heating"] = -233 assert apart.get_max_expenses_type() == []
from praw.models import Message from apartment import Apartment from login import login from uuid import uuid4 import time NY = Apartment() if __name__ == "__main__": while True: try: r = login() print("[kramer=>main] looking for unread messages...\n") while True: # Look through all unread messages for message in r.inbox.unread(limit=None): # Ignore inbox objects that arent Messages if isinstance(message, Message): # If they mention 'invite' in the subject if "invite" in message.subject: print(f"\n===={message.author}====\n") print("[kramer=>main->Subject] " "Contains `invite`\n") # If the user already has an invite or not wasFound = NY.hey_buddy(message.author) # If they don't have an invite, # add em to the list & send invite
for row in readCSV: price = int(row[0]) squareFt = row[1] city = row[2] address = row[3] url = row[4] name = row[5] newSquareFt = 0 if squareFt == ' ': newSquareFt = 1 else: newSquareFt = int(squareFt) ApartmentList.append( Apartment(price, newSquareFt, city, address, url, name)) #sets the mins and maxes we just found and calculates the weighted number to sort the apartments for ap in ApartmentList: ap.calculateWeight() #dumb and bad insertion sort. however its so small doesn't matter for x in range(1, len(ApartmentList)): ap2 = ApartmentList[x] y = x - 1 while (y >= 0) and (ApartmentList[y].weightedNum > ap2.weightedNum): ApartmentList[y + 1] = ApartmentList[y] y = y - 1 ApartmentList[y + 1] = ap2 x = x + 1
def prompt_init(): init = Apartment.prompt_init() init.update(Purchase.prompt_init()) return init
price = price.text if more_info := get_web_elem(driver.find_element_by_tag_name, "section"): if more_info := get_web_elem(more_info.find_element_by_class_name, "wrapper_container"): more_info = more_info.text if seller := get_web_elem(driver.find_element_by_class_name, "seller"): seller = seller.text if butt := get_web_elem(driver.find_element_by_id, "lightbox_contact_seller_0"): butt.send_keys(Keys.ENTER) phone = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "phone_number")) ) if update := get_web_elem(driver.find_element_by_class_name, 'top', default="01/01/2000"): if update := get_web_elem(update.find_element_by_class_name, 'left', default="01/01/2000"): update = update.text apartments_set.add( Apartment(item, update, street, hood, lst[0].text, lst[1].text, lst[2].text, price, more_info, seller, phone.text)) driver.close() def start_crawling(url_list: typing.List, workers: int, apartments_set: typing.Set): """ creates threads according to number of WORKERS provided to program. sends threads to crawl the apartment web pages. :param url_list: list :param workers: int :param apartments_set :return: None """ with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor: for item in url_list: executor.submit(create_single_apartment, item, apartments_set)
num_floors = raw_input("How many floors are in the building? ") doorman = raw_input("Does the building have a doorman? (t/f)") if doorman == "t": doorman = True else: doorman = False building = Building(name=name, address=address, num_floors=num_floors, doorman=doorman) print "Thanks for adding building {0}".format(building) if response == "a": unit = raw_input("What is the unit number? ") rent = raw_input("What is the monthly rent? ") sqft = raw_input("How many sq feet are in the apartment? ") num_bedrooms = raw_input("How many bedrooms does it have? ") num_bathrooms = raw_input("How many bathrooms does it have? ") apartment = Apartment(unit=unit, rent=rent, sqft=sqft, num_bedrooms=num_bedrooms, num_bathrooms=num_bathrooms) try: building.apartments[unit] = apartment print "Thanks for adding unit {0} to building {1}".format(apartment.unit, building.name) except NameError: print "You have to add a building first" if response == "r": name = raw_input("What is the renter's name? ") age = raw_input("What is the renter's age? ") renter = Person(name=name, age=age) if not apartment.is_full(): apartment.renters.append(renter) print "Renter {0} added to apartment {1}".format(renter.name, apartment.unit) else: print "That apartment is already full"