Python Training at Symantec - Chennai -- Day 1

March 27-31, 2017
Anand Chitipothu

These notes are available online at https://notes.pipal.in/2017/symantec

© Pipal Academy LLP

Home | Day 1 | Day 2 | Day 3 | Day 4 | Day 5

In [1]:
1 + 2
Out[1]:
3
In [2]:
print("hello world")
hello world
In [3]:
%%file hello.py
print("Hello world from Jupyter")
Overwriting hello.py
In [4]:
!python hello.py
Hello world from Jupyter

Datatypes

Let us look at various datatypes in Python.

Python has integers.

In [5]:
1 + 2
Out[5]:
3
In [6]:
2 ** 1000
Out[6]:
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

Python has floating point numbers.

In [7]:
1.2 + 2.3
Out[7]:
3.5

Python has strings.

In [8]:
"Hello world"
Out[8]:
'Hello world'

Strings can be enclosed either in double quotes or single quotes. Both exactly mean the same.

In [9]:
"Hello" + 'python'
Out[9]:
'Hellopython'
In [10]:
"Hello" * 5
Out[10]:
'HelloHelloHelloHelloHello'
In [11]:
print("Hello", "Python")
Hello Python

Q: Can we use comma in print function call? What is the difference between comma and plus?

In [12]:
"Hello" + "Python" # concatination
Out[12]:
'HelloPython'
In [13]:
print("Hello" + "Python") # one argument is passed to print
HelloPython
In [14]:
print("Hello", "Python")  # two arguments are passed to print function
Hello Python
In [15]:
print("Hello", 1, 2, 3) # pass a string and three numbers as args to print
Hello 1 2 3
In [16]:
# this will fail
print("Hello" + 1)
-------------------------
TypeErrorTraceback (most recent call last)
<ipython-input-16-16fb0dc3c38a> in <module>()
      1 # this will fail
----> 2 print("Hello" + 1)

TypeError: Can't convert 'int' object to str implicitly

Python supports usual escape characters in strings.

In [17]:
print("a\nb\nc")
a
b
c
In [18]:
print("a\tb\tc")
a	b	c

Python has support for multi-line strings too.

In [19]:
message = """This is multi-line string.
Second line.
Line number 3.
"""
In [20]:
message
Out[20]:
'This is multi-line string.\nSecond line.\nLine number 3.\n'
In [21]:
print(message)
This is multi-line string.
Second line.
Line number 3.

Multi-line strings are enclosed in three double quotes or three single quotes.

Python strings can handle any unicode characters.

In [40]:
print("\u0c05\u0c06\u0c07\u0c08")
అఆఇఈ
In [52]:
print("\u0b85\u0b86\u0b87\u0b88")
அஆஇஈ
In [53]:
name = "\u0b85\u0b86\u0b87\u0b88"
In [54]:
len(name)
Out[54]:
4

Python has a type called bytes for handling binary data.

In [48]:
x = b"hello"
In [49]:
type(x)
Out[49]:
bytes

Adding a prefix b before a literal string, makes it bytes.

In [50]:
x = b'\x12\xc4\x9b'

There are ways to convert bytes to strings and vice-versa. We'll look into that later.

Python has lists.

In [22]:
x = ["a", "b", "c"]
In [23]:
x
Out[23]:
['a', 'b', 'c']

The length of a list can be found using the len function.

In [24]:
len(x)
Out[24]:
3

The individual elements can be accessed using [].

In [25]:
x[0]
Out[25]:
'a'
In [26]:
x[1]
Out[26]:
'b'

Q: Is it possible to access multiple elements of a list at once?

In [27]:
print(x[0], x[1])
a b

Python has more advanced ways to slice and dice lists.

In [29]:
x[:2] # take first 2 elements
Out[29]:
['a', 'b']

We'll more about them later.

Python has another datatype called tuple for representing fixed-width records.

In [30]:
point = (3, 4)
In [31]:
print(point)
(3, 4)
In [32]:
point[0]
Out[32]:
3
In [33]:
point[1]
Out[33]:
4
In [34]:
x, y = point
In [35]:
print(x, y)
3 4
In [36]:
yellow = 255, 255, 0 # RGB
In [37]:
print(yellow)
(255, 255, 0)
In [38]:
r, g, b = yellow
print(r, g, b)
255 255 0

Python has dictionaries for representing name-value pairs.

In [55]:
person = {"name": "Alice", "email": "alice@example.com"}
In [56]:
print(person)
{'email': 'alice@example.com', 'name': 'Alice'}

Dictionary is an unordered collection. The order of elements is not guaranteed.

In [57]:
person["name"]
Out[57]:
'Alice'
In [58]:
person["email"]
Out[58]:
'alice@example.com'
In [59]:
student = {"name": "alice", "marks": {"science": 87, "maths": 48}}
In [60]:
student["marks"]
Out[60]:
{'maths': 48, 'science': 87}
In [61]:
student["marks"]["science"]
Out[61]:
87

Python has sets too.

In [62]:
x = {1, 3, 2, 3, 1}
In [63]:
x
Out[63]:
{1, 2, 3}

Q: Can we use values of any datatype as elements of a set?

Some data types like lists and dictionaries can't be used because they can be changed after adding a set.

In [66]:
red = (255, 0, 0)
blue = (0, 0, 255)
yellow = (255, 255, 0)

colors = {red, blue, yellow, blue, red}
print(colors)
{(255, 255, 0), (0, 0, 255), (255, 0, 0)}

set maintains unique elements.

Python has a boolean data type. It has two special values True and False.

In [64]:
True
Out[64]:
True
In [65]:
False
Out[65]:
False

Python has a special dataype to represent nothing. There is a special value None.

In [67]:
print(None)
None
In [68]:
x = None
In [69]:
print(x)
None
In [71]:
x # nothing will be printed because the interpreter ignores None values

If there is a function that does't return any value, then None is returned.

In [72]:
x = print("hello")
hello
In [74]:
print(x)
None

Variables

In [75]:
x = 4
In [76]:
x
Out[76]:
4
In [77]:
print(x*x)
16

Python doesn't have type declarations like in other languages.

In [78]:
x = "hello"
print(x)
hello

It is an error to use a variable that is not defined.

In [79]:
yy
-------------------------
NameErrorTraceback (most recent call last)
<ipython-input-79-c796c191140b> in <module>()
----> 1 yy

NameError: name 'yy' is not defined

Functions

Python has many built-in functions.

In [80]:
print("hello")
hello
In [81]:
print(1, 2, 3, 4)
1 2 3 4
In [82]:
len("hello")
Out[82]:
5

Python doesn't support operations on incompatible datatypes.

In [83]:
1 + "2"
-------------------------
TypeErrorTraceback (most recent call last)
<ipython-input-83-b88986c5ffd8> in <module>()
----> 1 1 + "2"

TypeError: unsupported operand type(s) for +: 'int' and 'str'
In [84]:
int("2")
Out[84]:
2
In [85]:
str(1)
Out[85]:
'1'
In [86]:
1 + int("2")
Out[86]:
3
In [87]:
str(1) + "2"
Out[87]:
'12'

Example: Counting the number of digits in a number

How to count number of digits in a number?

In [88]:
12345
Out[88]:
12345
In [89]:
2 ** 100
Out[89]:
1267650600228229401496703205376
In [91]:
2 ** 1000
Out[91]:
10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376
In [93]:
len(12345) # len doesn't work on numbers
-------------------------
TypeErrorTraceback (most recent call last)
<ipython-input-93-22b0721c99c3> in <module>()
----> 1 len(12345) # len doesn't work on numbers

TypeError: object of type 'int' has no len()
In [94]:
str(12345)
Out[94]:
'12345'
In [95]:
len(str(12345))
Out[95]:
5
In [96]:
len(str(2 ** 1000))
Out[96]:
302

Q: What are different operators used in Python?

Arthematic operations: 
    + 
    - 
    * 
    / (division)
    // (integer division)
    ** (power)
    % (remainder)

List and Dictionary operations:

    [] (indexing)

Gotchas with assignments

In [97]:
str = "hello"
print(str)
hello
In [106]:
str(1) + "2"
Out[106]:
'12'
In [107]:
str
Out[107]:
str

The only way out is to delete that variable.

In [108]:
del str
-------------------------
NameErrorTraceback (most recent call last)
<ipython-input-108-eefed57590b4> in <module>()
----> 1 del str

NameError: name 'str' is not defined
In [109]:
str
Out[109]:
str
In [104]:
str(1) + "2"
Out[104]:
'12'

Writing Custom Functions

In [110]:
def square(x):
    return x*x

print(square(3))
9

Please note that the indentation is very important in Python. The body of the function has to be indented, usually 4 spaces are used for indentation.

In [111]:
def square(x):
    y = x*x
    return y

print(square(3))
9

Problem: Write a function cube to compute cube of a number.

>>> cube(2)
8

Problem: Write a function count_digits that takes a number as argument and returns the number of digits it has.

>>> count_digits(12345)
5
>>> count_digits(2**1000)
302
In [120]:
def count_digits(number):
    return len(str(number))

print(count_digits(12345))
print(count_digits(2**1000))
5
302
In [121]:
# this doesn't work

def count_digits1(number):
    str(number)
    return len(number)

# right way
def count_digits2(number):
    x = str(number)
    return len(x)

Q: Can we write the two line the square function as a single line.

Python has expressions and statements. Expressions can be combined, not statements.

In [115]:
1 + 2 # expression
Out[115]:
3
In [114]:
4 * (1+2)
Out[114]:
12
In [117]:
x = 1 # statement
In [118]:
4 * (x=1) # error!
  File "<ipython-input-118-68c4d5c2db5b>", line 1
    4 * (x=1) # error!
          ^
SyntaxError: invalid syntax

However, you can write multiple statements in a single line by separeting them using semicolon.

In [119]:
def square(x):
    y = x*x; return y

print(square(3))
9

However, that is not a recommended practice.

Function are values too!

In [122]:
def square(x):
    return x*x
In [123]:
print(square(4))
16
In [125]:
print(square) # print the function it self
<function square at 0x11027e510>
In [126]:
print(square()) # call square without any arguments and print the result 
-------------------------
TypeErrorTraceback (most recent call last)
<ipython-input-126-abf8d7874bf7> in <module>()
----> 1 print(square()) # call square without any arguments and print the result

TypeError: square() missing 1 required positional argument: 'x'
In [127]:
f = square
In [128]:
f(4)
Out[128]:
16
In [129]:
print(f)
<function square at 0x11027e510>

Is there any practical use of this?

In [130]:
def square(x):
    return x*x

def sum_of_squares(x, y):
    return square(x) + square(y)

print(sum_of_squares(3, 4))
25
In [131]:
def cube(x):
    return x*x*x

def sum_of_cubes(x, y):
    return cube(x) + cube(y)

print(sum_of_cubes(3, 4))
91

Both sum_of_squares and sum_of_cubes are doing almost the same thing. Can we generalize these two functions into a single function?

In [132]:
def sumof(f, x, y):
    return f(x) + f(y)
In [133]:
sumof(square, 3, 4)
Out[133]:
25
In [134]:
sumof(cube, 3, 4)
Out[134]:
91
In [135]:
sumof(len, "Hello", "Python")
Out[135]:
11

Python even has some built-in functions that take functions as arguments.

In [136]:
max([2, 3])
Out[136]:
3
In [137]:
max(2, 3) # it even takes multiple arguments like this
Out[137]:
3
In [138]:
max(["one", "two", "three", "four", "five"])
Out[138]:
'two'

The comparison is based on dictionary ordering (comparing the characters).

How to find the longest element?

In [139]:
max(["one", "two", "three", "four", "five"], key=len)
Out[139]:
'three'

tell max to use the function len when comparing.

In [141]:
def mylen(x):
    print("mylen", x)
    return len(x)

max(["one", "two", "three", "four", "five"], key=mylen)
mylen one
mylen two
mylen three
mylen four
mylen five
Out[141]:
'three'

Methods

Methods are special type of functions that work on an object.

In [142]:
x = "Hello"
In [143]:
x.upper()
Out[143]:
'HELLO'
In [144]:
y = "Python"
y.upper()
Out[144]:
'PYTHON'
In [145]:
x.lower()
Out[145]:
'hello'
In [146]:
"mathematics".count("mat")
Out[146]:
2
In [147]:
"mathematics".replace("mat", "rat")
Out[147]:
'ratheratics'

Q: Is there a way to list all available methods on an object.

In [148]:
dir("hello")
Out[148]:
['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__getnewargs__',
 '__gt__',
 '__hash__',
 '__init__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mod__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__rmod__',
 '__rmul__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'capitalize',
 'casefold',
 'center',
 'count',
 'encode',
 'endswith',
 'expandtabs',
 'find',
 'format',
 'format_map',
 'index',
 'isalnum',
 'isalpha',
 'isdecimal',
 'isdigit',
 'isidentifier',
 'islower',
 'isnumeric',
 'isprintable',
 'isspace',
 'istitle',
 'isupper',
 'join',
 'ljust',
 'lower',
 'lstrip',
 'maketrans',
 'partition',
 'replace',
 'rfind',
 'rindex',
 'rjust',
 'rpartition',
 'rsplit',
 'rstrip',
 'split',
 'splitlines',
 'startswith',
 'strip',
 'swapcase',
 'title',
 'translate',
 'upper',
 'zfill']

The dir function gives all attributes of an object. They can be simple values, need not be methods.

You can also look at help using the the help function.

help(str)
...

Problem: Write a function count_zeros to count the number of zeros in a number.

>>> count_zeros(1003)
2
In [152]:
def count_zeros(number):
    return str(number).count("0")
In [153]:
count_zeros(1003)
Out[153]:
2

Q: sibi - my solution is not working.

In [154]:
# sibi's code
def count_zeros(x):
    str.count(sub, start= 0,end=len(x))
    return x
x(100)
-------------------------
TypeErrorTraceback (most recent call last)
<ipython-input-154-9d62d2bf6d5e> in <module>()
      3     str.count(sub, start= 0,end=len(x))
      4     return x
----> 5 x(100)
      6 

TypeError: 'str' object is not callable

What is x here?

In [162]:
# sibi's code
def count_zeros(x):
    str.count(str(x), "0")
    return x
count_zeros(100)
Out[162]:
100
In [163]:
# sibi's code
def count_zeros(x):
    y = str.count(str(x), "0")
    return y
count_zeros(100)
Out[163]:
2

A better approach would be to call count as a method.

In [164]:
# sibi's code
def count_zeros(x):
    y = str(x).count("0")
    return y
count_zeros(100)
Out[164]:
2

Let us look at more useful methods on strings.

In [165]:
sentence = "anything that can go wrong, will go wrong"
In [166]:
sentence.split()
Out[166]:
['anything', 'that', 'can', 'go', 'wrong,', 'will', 'go', 'wrong']

The split function splits a string on any whitespace.

Optionally, we can specify a delimiter.

In [167]:
sentence.split(",")
Out[167]:
['anything that can go wrong', ' will go wrong']

The reverse is done using the join method.

In [168]:
"-".join(["a", "b", "c"])
Out[168]:
'a-b-c'

Problem: Write a function count_words that takes a sentence as argument and returns the number of words in it.

>>> count_words("one two three")
3

Bonus Problem: Write a function longest_word that takes a sentence as argument and returns the longest word from it.

>>> longest_word("one two three four five")
'three'
In [ ]: