Programming in Python

  • High level & Interpreted
  • Powerful
  • Open source
  • Super easy to learn
  • Easy to read, write and maintain 
  • Modules for almost everything

Why Python?

>>> print("Hello World!")
Hello world!
>>>
>>> def hello_world():
...     print("Hello World!")
...
>>> hello_world()
Hello World!

Python's Runtime execution model

Byte code compilation

 

  • source code -> bytecode
  • bytecode: lower-level, platform-independent
  • Speed benefits
  • Stored in .pyc files

PVM: Python Virtual Machine

  • Runtime engine of python
  • Just runs the bytecode
  • All these details are invisible
  • We simply write code and run

Basic examples

 

Python Interpreter

REPL

$ python3
Python 3.6.0 (default, Dec 24 2016, 08:01:42)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

Demo time

Type these into the interpreter

  • 2+2
  • 2*2
  • 5/2
  • 5//2
  • _
  • _*2
  • 2**10
  • x = 5
  • y = 10
  • print(x*y)
  • x = "Now a string"
  • print(x)
  • type(x)
  • x + y

Python files in action

#!/usr/bin/python3

def hello():
  print("Hello world")

hello()
$ ./test.py
$ chmod u+x test.py
$ python3 test.py

create test.py

Significant whitespace

  • Leading whitespace is significant
  • Used to separate blocks of code instead of braces
  • Removes the unnecessary clutter of braces
  • Convention is use 4 spaces to indent code
  • Never mix tabs and spaces
>>> for i in range(5):
...     x = i * 10
...     print(x)
...
0
10
20
30
40

Python code in muzi-scanner

Python Standard library

  • Text processing,  Mathematical modules
  • File handling, OS interfacing 
  • Internet protocols
  • Can implement complex tasks without 3rd party libraries
  • Detailed documentation:
  • Google: "Python3 standard library"
>>> import module_name
>>>
>>> module_name.method()
>>> 
>>> from module import function

Various types of imports

  • `import math`
  • `from math import factorial`
  • `from math import factorial as fac`

Variables and data types

  • Python is dynamically typed
  • Types are not explicitly specified
  • Python keeps track of data types internally
  • Integers
  • Can be arbitrarily large
  • Floats
  • 64 bit floating point numbers
>>> a = 10
>>> type(a)
<class 'int'>
>>> b = 15.5
>>> type(b)
<class 'float'>
>>> c = int(b)
>>> type(c)
<class 'int'>
>>> print(c)
15
  • Boolean
  • True
  • False
>>> type(True)
<class 'bool'>

>>> True
True

>>> False
False

>>> bool(True)
True

>>> bool(None)
False

>>> bool(13123)
True

Only `None`, `False`, 0 and empty collections evaluate to `False`

None type

  • NoneType type
  • Used to represent absence of value
>> a = None
>> a is None
True

Relational operators

  • ==                        value equality
  • !=
  • >=
  • <= 
  • >
  • <
>>> 5 > 10
False
>>> 5 > 1
True
>>> 5 >= 5
True
>>> 5 != 5
False

Collections

  • str
  • bytes
  • list
  • dict

Strings

  • sequence of unicode code points
  • Major difference between python2 & 3
  • Default encoding is utf-8
  • Immutable
"This is a string"

'This is also a string'

"You can't handle mah swag"

'You can\'t handle mah swag'
# Multi line strings delimited by 3 quotes

>>>"""This is a multi-
... -line string"""


>>> print('Try to print \n this string')
Try to print
 this string

>>> print("try to print \\n this string")
try to print \n this string

# If you get tired used raw strings

>>> print(r'C:\path\to\directory')
C:\path\to\directory

More on strings

>>> s = '  hello'
>>> r = 'world!'
>>> r.capitalize()
>>> s + r
>>> l = s + r
>>> l
>>> l.split()
>>> l.split('w')
>>> l.lstrip()
>>> l.rstrip()
>>> l.strip()
>>> l.strip('!')

String methods

Try: `help(str)`

This lists all the methods supported by str.

>>> a = 'hello world!     '
>>> a.capitalize().strip().strip('!')

Methods can be chained

bytes 

  • immutable sequences of bytes
  • Files, Network connections
  • Data going in/out of programs 
>>> b'Some bytes'
b'Some bytes'

Text

Encoding Decoding 

>>> swag = "ϟÐϟℒα♭s"

>>> swag.encode('utf-8')
b'\xcf\x9f\xc3\x90\xcf\x9f\xe2\x84\x92\xce\xb1\xe2\x99\xads'

>>> bytes = swag.encode('utf-8')

>>> bytes.decode('utf-8')
'ϟÐϟℒα♭s'

Lists

  • Mutable sequences of objects
  • Everything in python is an object
  • Workhorse of python data structures
  • Zero based index
>>> [1, 2, 3, 4]

List examples

ProTip: To see the attrs/methods available for an object

run `dir(obj)` in the interpreter

>>> [1,2,3]
[1,2,3]

>>> a = ["palai", "mangal", "nightfury"]

>>> a[1]
mangal

>>> a[1] = 7

>>> a
["palai", "mangal", "nightfury"]

>>> a.append("kd")

>>> a[-1]
kd

List examples


>>> a = ["palai", "mangal", "nightfury"]

>>> a.pop()
nightfury

>>> a
["palai", "mangal"]

>>> a.pop(0)

>>> a.remove("mangal")

>>> list("SDSLabs")

dict (Dictionary)

  • Mutable key value pairs
  • keys have to be unique and hashable
>>> date = { 'day': 6,
...          'month': 'March',
...          'year': 2017 }

>>> date['day']
6

>>> date
{'day': 6, 'month': 'March', 'year': 2017}

>>> date['day'] = 7

>>> date
{'day': 7, 'month': 'March', 'year': 2017}

>>> date.keys()
dict_keys(['day', 'month', 'year'])

>>> date.values()
dict_values([7, 'March', 2017])

Control Flow Structures

  • Terminated by a colon : 

If - Else

# Else is optional

if expression:  # expression is converted to bool as if by bool() operator
    print("It is true!")

b = 40

if b>50:
    print("B is greater than 50")
else:
    print("B is less than or equal to 50")

# Multiple if-else

if b>50:
    print("B is greater than 50")
elif b<20:
    print("B is less than 20")
else:
    print("B is between 20 and 50")

While


while expression:  # expression is converted to bool as if by bool() operator
    print("Infinite loop")

# break out by Ctrl + C

b = 40

while b!=0:
    print(b)
    b = b - 10

while True:
    num = Input("Enter a number:")
    if num%7 == 0:
        break
    else:
        continue
  • break statement breaks out of innermost loop

For loop

>>> for item in iterable:
        ..... body ....


>>> SDSLabs = { 'palai': 'pro',
              'mangal': 'panda'}

>>> for member in SDSLabs:
        print("{} is {}".format(member, SDSLabs[member]))
palai is pro
mangal is panda

Python methods

# return is Optional
def myFunc(x):
    x = x * 5
    print(x)

# Use return

def myFunc(x):
    x = x * 5
    return x

# Can return multiple values :)

def myFunc(x,y):
    return x*x, y*y


# default args

def myFunc(x = 5):
    return x*5

*args and **kwargs

>>> def myFunc(*args):
        for arg in args:
            print('this is our arg: {}'.format(arg))
>>> myFunc(10)
>>> myFunc(10, 'lol', 'yolo')

For sending arbitrary number of arguments

To send named args, use **kwargs (gets passed as a dict)

>>> def myFunc(**kwargs):
        print(kwargs)
>>> myFunc(day = 6, month = 'March')
  • named arguments have to always be passed after unnamed args

Modules

  • Reusable self contained pieces code.
  • Modularity is a good software practise.
  • Collections of related functions are placed in the same file which can be imported as a module

Creating a module

  • create  a script missiles.py
def launch_missiles():
    print("Missiles launched!")

print("Lets see if we can import this")
  • Now open python3 interpreter and run `import missiles`

Importing properly

  • What if we want to import the module without executing the print statement
  • Use python runtime attribute __name__
  • __name__ is set to '__main__' when script is executed directly
  • When imported __name__ evaluates to the module's name 

Importing properly

def launch_missiles():
    print("Missiles launched!")

   
if __name__ == '__main__':
    print("Lets see if we can import this")

Documenting our module

""" This is the module doc string"""

def launch_missiles():
    """ This is the function doc string. Explain briefly
    
    Args:
         None
    Returns:
         None
    """

    print("Missiles launched!")

   
if __name__ == '__main__':
    # This is just a comment
    print("Lets see if we can import this")

Python classes

  • Classes are same as in other OO languages
  • Encapsulating data and functions
  • By convention class names are CamelCase

Defining classes

"""This is our sample class"""

class MyClass:
    def test(self):
        return('this is only a test')

    def test2(self):
        print(self.test)
  • Each method that is to be called on a class object or has to be called from a class instance has to accept 'self' as an argument.
  • 'self' is similar to 'this' in java

__init__

"""This is our sample class"""

class MyClass:
    def __init__(self):
        self.__myName = 'gautham'

    def test(self):
        print('this is only a test')
        return self.__myName
>>> my_class = MyClass()

>>> my_class.test()

More __init__

"""This is our sample class"""

class MyClass:
    def __init__(self, name = 'gautham'):
        self.__myName = name

    def test(self):
        print('this is only a test')
        return self.__myName
>>> my_class = MyClass('xz0r')

>>> my_class.test()

>>> my_class2 = MyClass()

Exception handling

  • Unhandled exceptions terminate the program
  • Raise an exception to interrupt normal flow
  • Handle the exception to resume control
  • Exception objects contain information about the event

Try - except 

""" Module for demonstrating exceptions"""

def convert(s):
    """Convert to integer"""
    x = int(s)
    return x
>>> import test

>>> print(test.convert("5"))

>>> print(test.convert("TryMe"))

Try - except 

""" Module for demonstrating exceptions"""

def convert(s):
    """Convert to integer"""
    try:
        x = int(s)
        print("Conversion succeeded")
    except ValueError:
        print("Conversion Failed")
        x = -1
    return x
>>> import test

>>> print(test.convert("5"))

>>> print(test.convert("TryMe"))

Further steps

  • File handling
  • Inheritance, mixins 
  • Virtual environments
  • Pip