import math
class Point:
"""Represents a point in two-dimensional geometric coordinates"""
def __init__( self, x = 0, y = 0 ):
"""
initialize position of a new point, if the x and y coordinates
are not specified, the point defaults to the origin
"""
self.reset()
def move( self, x, y ):
"""moves the point to a new location in two-dimensional space"""
self.x = x
self.y = y
# reset simply moves the point to a specific position
def reset(self):
self.move( 0, 0 )
def calculate_distance( self, other_point ):
return math.sqrt( ( self.x - other_point.x ) ** 2 + ( self.y - other_point.y ) ** 2 )
The assert
function is a simple test tool and the program will fail if the statement is False.
point1 = Point()
point2 = Point()
point1.reset()
point2.move( 5, 0 )
print( point2.calculate_distance(point1) )
assert( point2.calculate_distance(point1) == point1.calculate_distance(point2) )
point1.move( 3, 4 )
print( point1.calculate_distance(point2) )
print( point1.calculate_distance(point1) )
5.0 4.47213595499958 0.0
Write your docstrings and they will appear in the help method.
help(Point)
Help on class Point in module __main__: class Point(builtins.object) | Represents a point in two-dimensional geometric coordinates | | Methods defined here: | | __init__(self, x=0, y=0) | initialize position of a new point, if the x and y coordinates | are not specified, the point defaults to the origin | | calculate_distance(self, other_point) | | move(self, x, y) | moves the point to a new location in two-dimensional space | | reset(self) | # reset simply moves the point to a specific position | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined)
Modules are nothing more than .py
files. As the project gets larger and larger, we may need a folder to hold all of the modules. A package is a collection of modules in a folder. The name of the package is the name of the folder. To tell python that that a folder is a package, we have to place a module name __init__.py
in the folder.
For example, to import the Products class
from the products.py module
in the ecommerce package (folder)
.
from ecommerce.products import Products
When working with related modules in a package you can use relative imports. For example, when working with the product.py
module and we want to work with the Database class
from database.py
module next to it ( in the same folder ). We can use a period up front during the import. And we can add multiple periods up front to move up the folder hierarchy.
# use it when working in the products.py
# from .database import Database
In our example, we had an ecommerce package
containing two modules named database.py
and products.py
. Suppose the database
module contains a db
variable that is accessed from a lot of places. It will be convenient if this could be imported as import ecommerce.db
instead of import ecommerce.database.db
.
To do this we can add the line from .database import db
in the __init__.py
module that serves as an indicator that the folder is a python package.
Every python module has a __name__
special variable that specifies the name of the module when it is imported, but when the module is executed directly within its own module, it is never imported and the __name__
special variable is set to the string __main__
. On the other hand, if the module is being imported the, __name__
of that module will be the module's name. It's useful to wrap all your scripts inside if __name__ == '__main__':
so you can easily import the module to be used by other code someday.
Reference: Youtube
if __name__ == '__main__':
print(1)
1
Class can be defined inside the function scope, in this case this class can't be accessed from anywhere outside the function, meaning that the class can't be imported.
def format_string( string, formatter = None ):
class DefaultFormatter(object):
def convert_to_title_case( self, string ):
# .title() returns a copy of the string in which
# first characters of all the words are capitalized.
return str(string).title()
if not formatter:
formatter = DefaultFormatter()
return formatter.convert_to_title_case(string)
hello_string = "hello world, how are you today?"
print( " input: " + hello_string )
print( "output: " + format_string(hello_string) )
input: hello world, how are you today? output: Hello World, How Are You Today?
In python, we don't enforce laws to do so, instead we prefix an attribute or method with an underscore _
, this suggests that this is an internal variable, think twice before accessing it directly. But there's nothing stopping them from doing so.
Another thing you can do is to prefix the attribute or method with double underscore __
. This will perform name mangling on it.
class SecretString(object):
def __init__( self, plain_string, pass_phrase ):
self.__plain_string = plain_string
self.__pass_phrase = pass_phrase
def decrypt( self, pass_phrase ):
if pass_phrase == self.__pass_phrase:
return self.__plain_string
else:
return ''
secret_string = SecretString("ACME: Top Secret", "antwerp")
print(secret_string.decrypt("antwerp"))
# print(secret_string.__plain_text) # this will return an error
ACME: Top Secret
# we can access the attribute with __ prefix by adding _<classname>
print(secret_string._SecretString__plain_string)
ACME: Top Secret
This shows that the method can still be called by outside objects if they REALLY want to do it, but it requires extra work since they have to do the name mangling themselves. Tis a strong indicator that the attribute or method should remain private. Although, many times, the using single underscore will already serve this purpose.
# for reloading the module
from importlib import reload
from notebook import Note
from notebook import Notebook
n = Notebook()
n.new_note("hello world")
n.new_note("hello again")
n.notes
[<notebook.Note at 0x1076a36d8>, <notebook.Note at 0x1076a3668>]
print( n.search("hello") )
n.modify_memo(1, "hi world")
print( n.notes[0].memo )
[<notebook.Note object at 0x1076a36d8>, <notebook.Note object at 0x1076a3668>] hi world
input
for interactive input.
# note the the type is returned in string, even if you've enter a integer
input( "Enter an option: " )
Enter an option: 2
'2'
# empty list will not print
notes1 = []
for note in notes1:
print(1)
# list will not print
notes2 = [ 1, 2, 3 ]
if not notes2:
print(2)