Feb 20-22, 2017
Anand Chitipothu
These notes are available online at http://bit.ly/intuit17
© Pipal Academy LLP
1 + 2
print("hello")
%%file hello.py
print("hello world")
!python hello.py
x = 3
print(x)
name = "Alice"
print("Hello", name)
In Python, variables don'y have a type. They are just placeholders which can hold any type of values.
x = "Python"
print("Hello", x)
In Python, anything starting with a # is considered a comment.
# this is a comment
x = 3
print(x*x)
x = x + 1 # incrementing x
Python has integers.
1 + 2
Python has floating point numbers.
1.2 + 2.3
Python has strings.
print("hello world")
Strings are enclosed either in double quotes or single quotes. Both mean the same.
"hello" + 'world'
"hello" * 3
print("=" * 40)
len("hello")
Python supports the usual escape codes.
x = "a\nb\nc"
print(x)
x = "a\tb\tc"
print(x)
Python supports multi-line strings too. They need to be enclosed in three double quotes or three single quotes.
text = """This is a multi-line string.
Line 2
Line 3
and the text may have "quotes" too.
"""
print(text)
text
Python strings can handle non-latin text as well.
print("\u0c85\u0c86\u0c87\u0c88")
kannada = "ಅಆಇಈ"
len(kannada)
Python has a special type called bytes to represent binary data.
x = b'hello'
type(x)
x = b'\x12\xc4\x70'
x
hex(ord('h'))
hex(ord('e'))
b'\x68\x65'
Python has lists.
x = ["a", "b", "c"]
x
x[0]
x[1]
len(x)
Q: Can a list of elements of different datatypes?
absolutely!
x = ["a", "b", 5, [3, 4]]
x[3]
x[3][0]
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix[2][2]
print(matrix[0][0], matrix[1][0], matrix[2][0])
column0 = [matrix[0][0], matrix[1][0], matrix[2][0]]
print(column0)
Python has another datatype called tuple for representing fixed-width records.
point = (2, 3)
print(point)
yellow = (255, 255, 0) # R G B
print(yellow)
r, g, b = yellow
print(r, g, b)
dark_yellow = (0.8 * r, 0.8 * g, 0.8 * b)
print(dark_yellow)
(1, 2)
1, 2
Python has dictionaries for representing name-value pairs.
person = {"name": "Alice", "email": "alice@example.com"}
person['name']
person['email']
Q: How to represent sets in python?
Python has a set datatype too.
x = {1, 2, 3, 2, 1}
x
Python has a boolean type. It has two special values True and False to represent truth and false.
True
False
Python has a special type called None to represent nothing.
x = None
print(x)
name = "Alice"
print("name")
name = Alice
print(name)
The above code failed because it was looking for a variable with name Alice, instead of text "Alice".
Python has many built-in functions.
print("hello")
print("hello", 1, 2, 3)
len("Hello")
len([1, 2, 3, 4])
Python doesn't support operations on incompatible datatypes.
5 + "2"
int("2")
str(2)
5 + int("2")
str(5) + "2"
How to count the number of digits in a number?
12345
2 ** 100
2 ** 1000
len(str(12345))
len(str(2**100))
len(str(2**1000))
def square(x):
return x*x
square(4)
def square(x):
y = x*x
return y
a = 23
a2 = square(a)
print("square of", a, "is", a2)
Problem: Write a function cube to compute cube of a number.
>>> cube(2)
8
>>> cube(3)
27
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
print vs. return¶def square1(x):
return x*x
def square2(x):
print(x*x)
print(square1(4))
square2(4)
1 + square1(4)
square1(square1(4))
The square2 function is not returning anything back. The result of that is not available for using in other computations.
So, we should try to make function return values.
There may be cases where you just want to print something. It is okay not to return anything in such cases.
def say_hello(name):
print("Hello", name)
say_hello("Python")
def square(x):
return x*x
print(square(4))
print(square)
f = square
f(4)
type(square)
type(f)
print(f)
Is there any practical value for this feature? Let us see an example.
def square(x):
return x*x
def sum_of_squares(x, y):
return square(x) + square(y)
print(sum_of_squares(3, 4))
def cube(x):
return x*x*x
def sum_of_cubes(x, y):
return cube(x) + cube(y)
print(sum_of_cubes(3, 4))
Both sum_of_squares and sum_of_cubes are doing almost the same thing. Can we generalize both of them into a single function?
def sumof(f, x, y):
return f(x) + f(y)
sumof(square, 3, 4)
sumof(cube, 3, 4)
sumof(len, "hello", "python")
This feature is so useful that even some built-in functions take functions as arguments.
max(3, 4)
It can even be called with a list of values.
max([3, 4])
max(["one", "two", "three", "four", "five"])
"python" > "perl"
"python" > "java"
"man" > "woman"
The string comparison uses the dictionary ordering.
How to find the longest word?
max(["one", "two", "three", "four", "five"], key=len)
min(["one", "two", "three", "four", "five"], key=len)
# records of students with name and marks
records = [
("A", 78),
("B", 96),
("C", 64)
]
Find the record with maximum marks.
def get_marks(record):
return record[1]
max(records, key=get_marks)
Methods are special kind of functions that work on an object.
x = "Hello"
x.upper()
x.lower()
"mathematics".count("mat")
"mathematics".replace("mat", "rat")
Problem Write a function count_zeros to count the number of zeros in the given number.
>>> count_zeros(0)
1
>>> count_zeros(100)
2
>>> count_zeros(2030405)
3
def count_zeros(n):
# FIX ME
return 0
print(count_zeros(0))
print(count_zeros(100))
print(count_zeros(2030405))
def count_zeros(n):
return str(n).count('0')
print(count_zeros(0))
print(count_zeros(100))
print(count_zeros(2030405))
Let us look at some more useful methods on strings.
sentence = "Anything that can go wrong, will go wrong"
sentence.split()
The split method splits on any whitespace by default.
Optionally, we can specify a delimiter.
sentence.split(",")
The join method does the reverse of split.
",".join(['one', 'two', 'three'])
"--".join(['one', 'two', 'three'])
Problem: Write a function count_words that takes a sentence as argument and returns the number of words it has.
>>> count_words("life is suffering")
3
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'
import time
print(time.asctime())
The import statement imports a module and allows us to call functions defined in that.
The import is also like an assignment.
time
t = time
print(t.asctime())
We can also import some functions defined in a module.
from time import asctime
print(asctime())
Let us look at some interesting modules in Python.
os module¶import os
# get the current working directory
os.getcwd()
# all files in the current directory
os.listdir(".")
Problem: Write a function count_files that takes path to a directory as argument and returns the number of files it has.
>>> count_files(".")
10
>>> count_files("/tmp")
15
def count_files(path):
files = os.listdir(path)
return len(files)
print(count_files("."))
print(count_files("/tmp"))
How to find the file size?
os.path.getsize("hello.py")
How to find the largest file in the current directory?
max(os.listdir("."), key=os.path.getsize)
help(os.path.getsize)
help("os.path.getsize")
If you are on unix, you can use command pydoc.
$ pydoc os.path.getsize
How to list all functions etc. defined in a module?
The built-in function dir returns all the variables defined in a module.
dir(time)
help("time.localtime")
import random
random.choice(["one", "two", "three", "four", "five"])
How to generate a random word from a sentence?
def random_word(sentence):
return random.choice(sentence.split())
random_word("one two three four five")
random_word("life is random")
random_word("the sooner you start to code, the longer it takes")
Let us try a fun program.
Write a function say_hello to say hello in a random language.
def say_hello(name):
prefix_options = ["Hello", "Namaskara", "Ola", "Namaskaram", "Lal Salam"]
prefix = random.choice(prefix_options)
print(prefix, name)
say_hello("Python")
say_hello("Python")
Can we improve the above function to have both a prefix and suffix, like shown below:
Namaskar Gopal Ji
Namaskaram Gopal Garu
Namaskara Gopal avure
Ram Ram Gopal Sahib
def say_hello(name):
prefix, suffix = get_random_greeting()
print(prefix, name, suffix)
def get_random_greeting():
# FIX ME
return "Namaskaram", "Garu"
say_hello("Gopal")
def say_hello(name):
prefix, suffix = get_random_greeting()
print(prefix, name, suffix)
def get_random_greeting():
options = [
("Namaskaram", "garu"),
("Namaskara", "avure"),
("Ram ram", "sahib"),
("Namaskar", "Ji")
]
return random.choice(options)
say_hello("Gopal")
The sys module keeps in the command-line arguments in a special variable argv.
%%file args.py
import sys
print(sys.argv)
!python args.py
!python args.py hello world
By convention, the first element in that list is always the program name.
!python args.py 1 2 3 4 5
Remember that the arguments are always strings.
Let us write a program to print the first command-line argument.
%%file echo.py
import sys
print(sys.argv[1])
!python echo.py hello
!python echo.py hello world
Problem: Write a program square.py that takes a number as command-line argument and prints its square.
$ python square.py 4
16
Problem: Write a program add.py that takes two numbers as command-line arguments and prints their sum.
$ python add.py 2 3
5
$ python add.py 5 4
9
%%file square.py
import sys
#print(sys.argv)
x = int(sys.argv[1])
print(x*x)
!python square.py 4
score = 47
score > 30
score < 50
name = "Alice"
name == "Alice"
name == "Alice" and score > 30
The in operator can be used to check if an element is part of another.
"hell" in "hello"
"yell" in "hello"
"yell" not in "hello"
"a" in ["a", "b", "c", "d"]
vowels = ["a", "e", "i", "o", "u"]
def is_vowel(c):
return c in vowels
is_vowel('a')
is_vowel('x')
Strings have other useful methods to check for prefix and suffix matching.
"hello".startswith("hell")
"hello".endswith("lo")
def is_python_file(filename):
return filename.endswith(".py")
is_python_file("hello.py")
is_python_file("hello.java")