Created
July 3, 2019 21:50
-
-
Save FlintSable/38da25e09ae4939c2b678725d83bfda3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Contact: | |
| """ example that uses an inner (nested) class """ | |
| # class ("static") members and intended constants | |
| DEFAULT_NAME = "(no name assigned)" | |
| MIN_NAME_LEN = 2 | |
| MAX_NAME_LEN = 30 | |
| DEFAULT_PH_NUM = "0001112222" | |
| # initializer ("constructor") method ------------------------------- | |
| def __init__(self, | |
| the_name=DEFAULT_NAME, the_ph_num=DEFAULT_PH_NUM): | |
| # instance (attributes | |
| if not self.set_name(the_name): | |
| self.name = Contact.DEFAULT_NAME | |
| # since this calls Phone constructor, we need not test return val | |
| self.phone = self.Phone(the_ph_num) | |
| # mutator ("set") methods ------------------------------------------ | |
| def set_name(self, the_name): | |
| if type(the_name) != str \ | |
| or \ | |
| not (Contact.MIN_NAME_LEN <= len(the_name) <= Contact.MAX_NAME_LEN): | |
| return False | |
| # else | |
| self.name = the_name | |
| return True | |
| # sets the phone from client **string**, not from Phone object | |
| def set_phone(self, the_ph_str): | |
| if not self.phone.set_phone_num(the_ph_str): | |
| return False | |
| # else | |
| return True # if good param, mutator call already set | |
| # accessor ("get") methods ---------------------------------------- | |
| def get_name(self): | |
| return self.name | |
| # returns the phone **string**, which most clients would expect | |
| def get_phone(self): | |
| return self.phone.to_string() | |
| # returns the phone **object**, if client wants that level of detail | |
| def get_phone_object(self): | |
| return self.phone | |
| # BEGIN INNER CLASS Phone ------------------------------------------- | |
| class Phone: | |
| """ Phone is nested in Contact """ | |
| # class ("static") members and intended constants | |
| DEFAULT_NUM = "7778889999" | |
| VALID_NUM_LEN = 10 | |
| # initializer ("constructor") method -------------------------- | |
| def __init__(self, the_num=DEFAULT_NUM): | |
| # instance attributes | |
| if not self.set_phone_num(the_num): | |
| self.ph_num = Contact.DEFAULT_PH_NUM | |
| # mutator method -------------------------- | |
| def set_phone_num(self, the_ph_str): | |
| # first check that it's a string | |
| if type(the_ph_str) != str: | |
| return False | |
| # throw away non-numerics | |
| pure_number = self.extract_numeric_digits(the_ph_str) | |
| # check length | |
| if len(pure_number) != Contact.Phone.VALID_NUM_LEN: | |
| return False | |
| # else (passed all tests) | |
| self.ph_num = pure_number | |
| return True | |
| # accessor methods -------------------------- | |
| def get_phone_num(self): | |
| return self.ph_num | |
| def to_string(self): | |
| """ turn '1234567890' into '(123)456-7890' """ | |
| # build slowly for clarity -- could be done in one long statement | |
| ret_str = "(" | |
| ret_str += self.ph_num[0:3] | |
| ret_str += ")" | |
| ret_str += self.ph_num[3:6] | |
| ret_str += "-" | |
| ret_str += self.ph_num[6:10] | |
| return ret_str | |
| # helper for vetting Phone numbers -------------------------- | |
| @staticmethod | |
| def extract_numeric_digits(the_num): | |
| """ store only digits '213-555-1212' becomes '2135551212' | |
| returns None if non-string, else | |
| the string minus non-numerics """ | |
| if type(the_num) != str: | |
| return None | |
| # else | |
| the_length = len(the_num) | |
| number = "" | |
| for k in range(0, the_length): | |
| next_digit = the_num[k] | |
| if next_digit.isdigit(): | |
| number = number + next_digit | |
| return number | |
| # END INNER CLASS Phone ------------------------------------------- | |
| # client -------------------------------------------- | |
| # instantiate some Contacts with illegal and default phone nums #s ... | |
| con_1 = Contact("Harsha", "234") | |
| con_2 = Contact("Alfonso") | |
| print("Nested class objects instantiated directly from main -----:") | |
| bad_phone = Contact.Phone("bad bad number") | |
| default_phone = Contact.Phone() | |
| print(" Bad param gets Contact default: " + bad_phone.get_phone_num() | |
| + "\n No param gets Phone default: " + default_phone.get_phone_num()) | |
| # show the Contacts right after instantiation --------------------- | |
| print("\nBefore mutators -------------------:") | |
| print(("Contact #1:" | |
| + "\n name: {}" | |
| + "\n phone: {}"). | |
| format(con_1.get_name(), | |
| con_1.get_phone())) | |
| print(("Contact #2:" | |
| + "\n name: {}" | |
| + "\n phone: {}"). | |
| format(con_2.get_name(), | |
| con_2.get_phone())) | |
| # try to mutate some Contact objects, legally and illegally | |
| con_1.set_name("Stephen Hawking") # should work | |
| # ok to access either the Contact mutator or the Contact.Phone mutator | |
| con_1.set_phone("(605) 555-1212") # should work | |
| con_1.phone.set_phone_num("123-3333") # should fail - too short | |
| # contact #2 setters invoked (one good, one bad): | |
| con_2.set_name("waytoolong waytoolong waytoolong") # should fail | |
| con_2.phone.set_phone_num("123-456-7890") # should work | |
| # show the Contacts after mutator calls --------------------- | |
| print("\nAfter mutators -------------------:") | |
| print(("Contact #1:" | |
| + "\n name: {}" | |
| + "\n phone: {}"). | |
| format(con_1.get_name(), | |
| con_1.get_phone())) | |
| print(("Contact #2:" | |
| + "\n name: {}" | |
| + "\n phone: {}"). | |
| format(con_2.get_name(), | |
| con_2.get_phone())) | |
| # compare the two get_phone_xxx() accessors --------------------- | |
| show_me = con_1.get_phone() | |
| print("\nResult of get_phone(): ", show_me) | |
| show_me = con_1.get_phone_object() | |
| print("\nResult of get_phone_object(): ", show_me, | |
| "\n(that was ugly...)") | |
| print("(Better things to do with the returned object): \n", | |
| show_me.get_phone_num(), | |
| "\n or \n", | |
| show_me.to_string()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment