In python, statements are also objects from the statement class.
So far, we've only seen single line statements.
Next we will introduce block-statements which cannot be contained in a single line, but include segments that could be read as a single line.
Block-statements include:
=3
a=3
bif a==b:
print("Values are the same")
=0
a=3
bif a==b:
print("Values are the same")
=0
a=3
bif a==b:
print("Values are the same")
else:
print("Values are not the same");
=3
a=-3
bif a==b:
print("Values are the same")
elif a==(b*-1):
print("Values have the same magnitude")
else:
print("Values are not the same");
=0
a=8
bif a==b:
print("Values are the same")
elif a==(b*-1):
print("Values have the same magnitude")
elif a==0:
print("A is zero")
else:
print("Values are not the same");
=3
a=3
bif a==b:
print("Values are the same")
elif a==(b*-1):
print("this is a duplicate entry")
With Strings
='DNW'
nameif name=="DNW":
="David"
firistelif name="JKB":
="Justin"
firstelif name="MLW":
="Melanie"
firstelse:
='unknown' first
Script are not block-statements, rather file objects.
Working with block statements becomes tedious working solely in the REPL.
Working from scripts is perhaps preferable from here on out.
Open a new terminal
mkdir myPython
cd myPython touch myscript.py
python
In your editor of choice open the file you just created
def main():
print("my first script")
if __name__ == '__main__':
main()
python
Open a terminal
cd path/to/myscript.py
python myscript.py
python
Simplification:
Your script is an instance of "file class"
name is a special attribute of your script
Its value describes how the file is called
When run directly from a terminal, as a script, (like we did) it takes on the value main
*.py files can be used for other purposes
To ensure it runs the way we want, we always include the
if __name__== '___main___':
python
The body of our script gets put in the 'main()' function.
Try this:
if __name__ == '__main__':
#main()
print(__name__)
python
For loops iterate over collection or iterable types.
On each iteration, some variable takes on a value of the iterator (collection or iterable).
=[1,2,3]
Afor i in A:
print(i)
=["apple","pineapple","cherry"]
Afor i in A:
print(i)
If you would rather iterate over a sequence, use the range type.
=range(10) # numbers 1 through 9
myrangeprint(myrange)
class(myrange)
myrange.start()
for i in myrange:
print(i)
for i in myrange:
print(i+1)
=range(1,10) # numbers 2 through 9
myrangefor i in myrange:
print(i)
=range(1,10,2) # numbers 2 through 9, every other value
myrangefor i in myrange:
print(i)
The values of range are not generated until needed, thus very large ranges take up a negligible amount of data.
for i in range(10):
if (i==0):
pass
elif (i==10):
print("end")
elif (not i % 2==0) or (i==2):
print(str(i) + ": odd")
else:
print(str(i) + ": even")
def seq_even_or_odd(largest):
for i in range(largest+2):
if (i==0):
pass
elif (i==largest+1):
print("end")
elif (not i % 2==0) or (i==2):
print(str(i) + ": odd")
else:
print(str(i) + ": even")
10) seq_even_or_odd(
def my_sum(*args):
= 0
out for x in args:
+= x
out return out
1,2,3) my_sum(
def my_sum(**kwargs):
kwargs.values()=list(kwargs.values())
vals=list(kwargs.keys())
keysfor i in range(len(kwargs)):
print(vals[i])
print(keys[i])
=3) my_sum(abc
def my_w_comb(*args,**kwargs):
kwargs.values()=list(kwargs.values())
vals=list(kwargs.keys())
keys
=1
wSum=0
wProd
for i in range(len(kwargs)):
if keys[i] == "plus":
=vals[i]
wSumelif keys[i]=="prod":
=vals[i]
wProd=0;
resultfor i in range(len(args)):
=(wSum+args[i])*(wProd)
result
return result
1,2,3,4, plus=3,prod=2) my_w_comb(
def print_info(name, lang="python", version="3.7"):
print("Using function " + name + " with " + lang + " version " + version)
'my_w_comb')
print_info("fmincon","matlab","R2017") print_info(
def print_info(name, lang="python", version=None):
if not version:
print("Using function " + name + " with " + lang)
else:
print("Using function " + name + " with " + lang + " version " + version)
'my_w_comb')
print_info("fmincon","matlab","R2017") print_info(
A collection of file objects can be encapsulated together as a module.
Modules are features that can be added to python.
Modules can be further encapsulated by nesting as submodules.
A module or group of modules can encapsulated into a package object for easy distribution.
Popular modules find their way packages into an centralized online repository accessed via pip.
Anybody can create packages and submit their code to be included in the central pip repo.
Once a package is installed, they can be loaded into the REPL or script via the import command.
datetime is a module that comes pre-installed with python.
numpy is not
import datetime
print(datetime.date.today())
type(datetime)
import datetime as dt
print(dt.date.today())
type(dt.date)
dir(dt)
from datetime import date
print(date.today())
type(date.today)
from datetime import *
print(date.today())
print(timezone.utc)
from datetime import date as d
print(d.today())
type(d)
class experiment:
def __init__(self,name):
self.name=name
#-----------------------------------
def main():
=experiment("test")
aprint(a)
print(a.name)
#-----------------------------------
...
init is the name binding for the constructor method.
Reminder: constructor is called whenever an instance is created
All classes have constructors, but explicit creation is optional
dunder = double underlines
dunder attributes and methods are special in some way.
A=[1,2,3]
dir(A)
We can call on the constructor again by
__init__((2,3,4)) A.
But will only reconstruct if the type is mutable (which is true in this case).
'self' is a special binding that refers to the object itself.
A function's signature is the argument types that are relevant.
init as a function must determine which instance of init it must call.
This process is called dispatch.
In python the first argument "self" defines the signature.
Because only one argument defines signatures in python, python is called a single dispatch language
Calling
__init__("diffname") a.
is equivalent to
__init__(a,"diffname")
Although python has disabled this type of syntax to keep things clear.
Thus in python, when calling an object the first argument is implied by the object itself.
class experiment:
def __init__(self,name):
self.name=name
self.get_date()
def get_date(self):
self.date=date.today()
class experiment:
...
Class definitions should go into their own file
touch __init__.py # create package
touch myClasses.py # class definitions file
in init.py
import .myClasses.myClasses
move datetime import and class to new file
save both
try running
from myClasses import experiment as exp
change experiment to exp
In myScript.py
import sys
def main(name):
if not name:
=None
name=exp(name)
aprint(a.name)
if __name__ == '__main__':
if len(sys.argv) > 1:
1])
main(sys.argv[else:
main()
in terminal
python myScript.py Dave
in myClasses.py
from datetime import date
class subject:
def __init__(self,name=None,age=None,height=None,weight=None):
if type(age)==str:
=float(age)
age
if type(height)==str:
=float(height)
height
if type(weight)==str:
=float(weight)
weight
self.name=name
self.age=age
self.height=height
self.weight=weight
def get_bmi(self):
if not self.weight or not self.height:
return None
return self.weight/(self.height^2) * 703
class experiment:
def __init__(self,subject=None):
if subject == None:
'no subject defined')
error(self.subject=subject
self.get_date()
def get_date(self):
self.date=date.today()
in myScript.py
import sys
from myClasses import experiment as exp
from myClasses import subject as subj
def main(*argv):
=subj(*argv)
mysubj=exp(mysubj)
myexpprint(myexp.subject.name)
print(myexp.subject.get_bmi())
if __name__ == '__main__':
*sys.argv[1:]) main(
in Terminal
python myScript.py Dave 32 5.11 200
TODO
TODO
TODO