#/usr/lib/python/site-packages/triangle.py
divisor_count_to_find = 500
def triangle_number(n):
return n*(n+1)/2
def divisors(tn):
counter = 0
n_sqrt = int(pow(tn, 0.5))
for i in range(1, n_sqrt + 1):
if tn%i == 0:
counter += 2
if n_sqrt * n_sqrt == tn:
counter -= 1
return counter
def start():
start_number = 1
div_numbers = 0
while (div_numbers < divisor_count_to_find):
tn = triangle_number(start_number)
div_numbers = divisors(tn)
start_number += 1
print(div_numbers)
print(tn)
if __name__ == '__main__':
start()
# Most common, clean way to do it. Prevents collisions.
import triangle
triangle.method # Call method
There are other methods as well. We can give our modules aliases
# Same as above except we gave triangle an alias
import triangle as tri
tri.method
We can also import specific modules without throwing them into a namespace.
from triangle import divisor_count_to_find, triangle_number
print divisor_count_to_find # output 500
triangle_number(5)
We can take the previous example a step further and implement aliases. This will allow us to change the names up to prevent collisons.
from triangle import divisor_count_to_find as dcf, triangle_number as tn
print dcf # output 500
tn(5)
Lastly, we can also import an entire module without a namespace. The * tells Python to import all modules without a namespace. This is a dangerous method and should only be used if you are sure there will not be collisions.
from triangle import *
/ # Top directory
math_stuff/ # Package
__init__.py # special file
fib.py # fib module
triangle.py # triangle module
Calculator.py # calculator class module
more_math_stuff/ # additional package
__init__.py
other_modules.py
So let's take the package below and walk through an import.
/ # Top directory
math_stuff/ # Package
__init__.py # special file
fib.py # fib module
triangle.py # triangle module
Calculator.py # calculator class module
more_math_stuff/ # additional package
__init__.py
other_modules.py # import and run this file (module)
There are two ways we can go about this:
import more_math_stuff.other_modules
more_math_stuff.other_modules.do_something()
OR
from more_math_stuff import other_modules as om
om.do_something()
# dir() Returns list of names in current local scope or with argument,
# attempts to return a list of valid attributes for object
>>> print dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> import(struct)
>>> print dir()
['__builtins__', '__doc__', '__name__', '__package__', 'struct']
>>> print dir(struct)
['Struct', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_clearcache', 'calcsize', 'error', 'pack', 'pack_into', 'unpack', 'unpack_from']
# help() Invokes built-in help system
print help(struct)
# Try it
print help()
# Try it
Reserved words of the language, and cannot be used as ordinary identifiers. Do not use any of these for any naming. They must be spelled exactly as written here:
and del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try
To verify that a string is a keyword you can use keyword.iskeyword; to get the list of reserved keywords you can use keyword.kwlist:
>>> import keyword
>>> keyword.iskeyword('break')
True
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def',
'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import',
'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try',
'while', 'with', 'yield']
# This is the class
class Person:
"""Stage 1 of Person Class
We will expand on this."""
firstName = "James"
lastName = "Bond"
birthday = "08/21/1800"
age = "200"
email = "[email protected]"
def f(self):
return "This is the Person class"
# This is the instantiation of class Person as object x
x = Person()
# This is using object x
print x.f()
print "This person's name is: {} {}".format(x.firstName, x.lastName)
# We can also do this...
print Person.firstName
>>> class someClass:
... x = 100
...
>>> someClass.x
100
>>> someInstance = someClass()
>>> someInstance.x
100
>>> someClass.x = 400
>>> someInstance.x
400
>>> someInstance.x = 1000
>>> someInstance.x
1000
>>> someClass.x = 0
>>> someInstance.x
1000
>>> class someClass:
... ex1 = 0
... ex2 = 0
...
... def f(self, val):
... ex1 = val
... self.ex2 = val
...
>>> # the class has been created. We also created a method.
... # the method attempts to change ex1 and self.ex2 to val
...
>>> someInstance = someClass()
>>> someInstance.ex1
0
>>> someInstance.ex2
0
>>> someInstance.f(100)
>>> someInstance.ex1
0
>>> someInstance.ex2
100
Now that we have a general understanding of self, let's create a __init__() method.
We can do something as simple as:
class X:
def __init__(self):
self.i = "yay"
# Invalid
print X.i # We will get an error, i is not a class variable
# Valid
a = X()
print a.i # Output will be 'yay'
This prevents us from being able to change data across all classes. But we have even more flexibility than that in Python, we can also pass additional arguments to __init__() via on object instantiation.
def __init__(self, firstName, lastName):
self.firstName = firstName
self.lastName = lastName
# Once we go to create the object
x = Person("James", "Bond")
Now that we have learned how to utilize __init__()... let's update our example.
# This is the class
class Person:
"""Stage 2 of Person Class
We will expand on this."""
def __init__(self, firstName, lastName, birthday, age, email):
self.firstName = firstName
self.lastName = lastName
self.birthday = birthday
self.age = age
self.email = email
def printDetails(self):
print "First Name: {}".format(self.firstName)
print "First Name: {}".format(self.lastName)
print "First Name: {}".format(self.birthday)
print "First Name: {}".format(self.age)
print "First Name: {}".format(self.email)
# This is the instantiation of class Person as object x
x = Person("James", "Bond", "08/21/1800", 200, "[email protected]")
x.printDetails()
class Example:
def __init__(self, age = 0):
self._age = age
# getter method
def get_age(self):
return self._age
# setter method
def set_age(self, x):
self._age = x
a = Example()
# setting the age using setter
a.set_age(57)
# retrieving age using getter
print(a.get_age())
print(a._age)
Output:
57
57
Python exceptions allow you to attempt code that may result in an error and execute additional functionality on said error.
try:
<statements%gt;
except: <name%gt;:
<statements%gt;
except: <name%gt; as <data%gt;:
<statements%gt;
else:
<statements%gt;
try:
<statements%gt;
finally:
<statements%gt;
"""
Checks a certain range of numbers to see if they can divide into a user specified num
"""
# Program main, runs at start of program
def launch():
num = input('What number would you like to check?')
amount = input('How many numbers do you want to check?')
if isInt(num) == False or isInt(amount) == False:
print("You must enter an integer")
launch()
elif int(amount) < 0 or int(num) < 0:
print("You must enter a number greater than 0")
launch()
else:
divisible_by(int(num), int(amount))
# Checks num divisible numbers up to amount or itself
def divisible_by(num, amount):
i = 1.0
while (num / i >= 1 and amount > 0):
if num % i == 0:
print('{} is divisible by {}'.format(int(num), int(i)))
amount -= 1
i += 1
# EXCEPTION HANDLING
def isInt(x):
try:
int(x) ###
return True
except ValueError:
return False
launch()
class CustomError(Exception):
def _init_(self, msg):
self.msg = msg
def _str_(self):
return "your error is {}".format(self.msg)
def doStuff(danger):
if danger == True:
raise CustomError("Whoa don't do that!")
print("Success") #What happens here?
try:
doStuff(True)
except CustomError as stuff:
print(stuff)
Programming typified by a data-centered (as opposed to a function-centered) approach to program design.
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than
right
now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
—Tim Peters
a.x means fetch the x attribute from the 'a' object.
A value passed to a function (or method) when calling the function. There are two types of arguments:
complex(real=3, imag=5)
complex(**{'real': 3, 'imag': 5})
complex(3, 5)
complex(*(3, 5))
Class
Class Variable
class TestClass:
i = 10
print TestClass.i
Constructors
Deconstructor
Function/Method Overloading
def someFunc(x, y, z = None):
if z is None:
# Set a default for z or don't use it
else:
# Set and use all three
someFunc(1,2)
someFunc(1,2,3)
Generator
Immutable
Inheritance
Instance Variable
class NameClass:
def __init__(self, name):
self.name = name
dis_class = NameClass('your_name')
print dis_class.name
#OUTPUT:
'dis_name'
Object
Method
Self
Polymorphism
len("hello") # returns 5 as result
len([1,2,3,4,45,345,23,42]) # returns 8 as result
Polymorphism Exaple:
class Square:
side = 5
def calculate_area(self):
return self.side * self.side
class Triangle:
base = 5
height = 4
def calculate_area(self):
return 0.5 * self.base * self.height
sq = Square()
tri = Triangle()
print("Area of square: ", sq.calculate_area())
print("Area of triangle: ", tri.calculate_area())
Area of square: 25
Area of triangle: 10.0
Special Method