5.1 KiB
5.1 KiB
Concepts of phone-number
Example implementation:
From the current example.py:
import re
class PhoneNumber:
def __init__(self, number):
self.number = self._clean(number)
self.area_code = self.number[:3]
self.exchange_code = self.number[3:6]
self.subscriber_number = self.number[-4:]
def pretty(self):
return "({}) {}-{}".format(
self.area_code, self.exchange_code, self.subscriber_number
)
def _clean(self, number):
return self._normalize(re.sub(r"[^\d]", "", number))
def _normalize(self, number):
if len(number) == 10 or len(number) == 11 and number.startswith("1"):
valid = number[-10] in "23456789" and number[-7] in "23456789"
else:
valid = False
if valid:
return number[-10:]
else:
raise ValueError("{} is not a valid phone number".format(number))
Concepts
- [Class][class]: classes are defined with the
class <ClassName>:syntax - [Dunder Methods][dunder-methods]: User defined classes can (and generally do) overload the
__init__method, whose first argument isself, because the result of__init__is a class instance. - [Inheritance][inheritance]: The default
__str___method is inherited fromObject, which every class in Python inherits from. (See: inheritance) - [Methods][methods]: classes can have instance methods which are called from an instance of the class (as opposed to class methods, called from the Class itself). The first parameter of an instance method is always
self, which is provided when calling from the instance (i.e. the programmer does not need to pass it as an argument explicitly). Static methods are methods called from the class itself, and are not connected to an instance of the class. They have access to class attributes (those defined on the class, not connected to theself), and do not require an instance of the class to exist. Classes can also define apropertyby using the@propertydecorator (not shown here); apropertycan be "lazily evaluated" to avoid unneeded computation - [Non-Public Methods][non-public-methods]: Methods or attributes (including those of an imported module) prefixed with an underscore,
_, are conventionally treated as "non-public" methods. Python does not support data privacy in the way a language like Java does. Instead convention dictates that methods and attributes that are not prefixed with a single underscore can be expected to remain stable along with semver, i.e. a public method will be backwards compatible with minor version updates, and can change with major version updates. Generally, importing non-public functions or using non-public methods is discouraged, though Python will not explicitly stop the programmer from doing so. - [Implied Argument][implied-argument]: within the class definition, methods and properties can be accessed via the
self.notation - [Inheritance][inheritance]: a "subclass" will inherit all methods, attributes from it's parent class, and can then override methods as needed. Overriding means the logic in the parent class is not used. The
superbuiltin function (not shown here) exists to allow the programmer to defer logic up the inheritance chain to the parent class when needed. - [Standard Library][standard-library]: the
remodule is an example of the Python stdlib (standard library), or included code libraries and tools that are frequently used in Python - [Import][import]: to use the module, the
importsyntax can be used - [Iterables][iterables]: characters in a string are iterables and are subject to index and slice access as described below
- [Immutable][immutable]: strings are immutable, and so cannot have values assigned; new strings can be created, however
- [String Formatting][string-formatting]:
str.formatcan be used to format a string - [Membership Testing][membership-testing]: the
inkeyword, as in"s" in "string, allows the user to check membership in the longer string - [String Methods][string-methods]: strings (and other types) have built in instance methods - in this case,
"string".startswith("s")which are called from the instance of the string itself - [Indexing][indexing]: for iterables, individual items can be accessed with
stringname[x]notation. Negative numbers start to count backwards - [Slicing][slicing]: a slice within an iterable, i.e. the slice of items from
<iterable>[x]to<iterable>[y], can be accessed via<iterable>[x:y]notation; a third parameter allows "skipping" byz, i.e.stringname[x:y:z] - [Regular Expressions][regular-expressions]: regular expressions is a language of sorts that can detect substrings and extract groups from a string, as well as replace them with something else
- [Conditionals][conditionals]:
if ... elseandelifallow a programmer to switch code branches depending on some condition - [Boolean Logic][boolean-logic]: the
orandandkeywords are used - [Raise][raise]: an appropriate Exceptions must be raised with the
raisekeyword