Features of Python

  • Dynamic typing :
    keeps track of the kinds of objects your program uses when it runs; it doesn’t require complicated type and size declarations in your code.
    Python is dynamically typed, a model that keeps track of types for you automatically instead of requiring declaration code, but it is also strongly typed, a constraint that means you can perform on an object only operations that are valid for its type.
  • Automatic memory management:
    automatically allocates objects and reclaims (“garbage collects”) them when they are no longer used
  • Library utilities and Third-party utilities

Why Python is used by developers?

Readability : Python code is designed to be readable, and hence reusable and maintainable
Portability : Most Python programs run unchanged on all major computer platforms like Linux and Windows.
Component Integration : Python code can invoke C and C++ libraries, can be called from C and C++ programs. Can interact over networks with interfaces like SOAP, XML-RPC, and CORBA.
Multi paradigm : It’s Object-Oriented and Functional and Procedural language.

Why not to use Python?

Only significant downside to Python is its ‘execution speed’, it may not always be as fast as that of fully compiled and lower-level languages such as C and C++. In short, the standard implementations of Python today compile (i.e., translate) source code statements to an intermediate format known as byte code and then interpret the byte code. Byte code provides portability, as it is a platform-independent format. However, because Python is not normally compiled all the way down to binary machine code (e.g., instructions for an Intel chip), some programs will run more slowly in Python than in a fully compiled language like C.

How python runs a program

source.py –> byte_code.pyc –> Python Virtual Machine

A program is first compiled to byte-code and then routes to virtual-machine.

  • Byte code compilation :
    A program is compiled to format known as byte code. Python byte code is not binary machine code. Byte code is a Python-specific representation.
    Compilation is simply a translation step, and byte code is a lower-level, platform-independent representation of source code
    This byte code translation is performed to speed execution—byte code can be run much more quickly than the original source code statements.
    It will store the byte code of your programs (files that are imported in another file) in files that end with a .pyc extension (“.pyc” means compiled “.py” source)
    These .pyc files cane be scene alongside the source files. Although modern version of python saves its .pyc byte code files in a subdirectory named __pycache__ located in the directory where your source files reside, and in files whose names identify the Python version that created them (e.g., script.cpython-33.pyc) to prevent different Python versions installed on the same computer from overwriting each other’s saved byte code.
    The flow is as follows :
    Source changes: Python automatically checks the last-modified timestamps of source and byte code files to know when it must recompile—if you edit and resave your source code, byte code is automatically re-created the next time your program is run.
    Python versions: Imports also check to see if the file must be recompiled because it was created by a different Python version
  • Python virtual machine
    The PVM is the runtime engine of Python
    the PVM is just a big code loop that iterates through your byte code instructions, one by one, to carry out their operations.
    PVM has to interpret the byte code, and byte code instructions require more work than CPU instructions. This is why some Python code may not run as fast as C or C++ code
    There is no initial compile-time phase at all, and everything happens as the program is running. This even includes operations such as the creation of functions and classes and the linkage of modules. Such events occur before execution in more static languages, but happen as programs execute in Python.

Modules in python

In simple terms, every file of Python source code whose name ends in a .py extension is a module.
Other files can access the items a module defines by importing that module
The items inside the module such as functions, classes, variables are called attributes.
Each module file is a package of variables, that is, a namespace
Each module is a self-contained namespace
One module file cannot see the names defined in another file unless it explicitly imports that other file. Because of this, modules serve to minimize name collisions in your code.

Debugging python

Run as python -i filename.py to start as interactive session and debug variable values.

Python Syntax Notes

List Comprehensions

1
2
3
4
L = [1,2,3,4,5]
[x+10 for x in L]

a new list containing x + 10, for every x in L.

List comprehension are
List comprehensions might run much faster than manual for loop statements (often roughly twice as fast) because their iterations are performed at C language speed inside the interpreter, rather than with manual Python code.

name == ‘main

When a Python file (module) is run directly, the special variable “name“ is set to “main
Therefore, it’s common to have the boilerplate if name ==… shown above to call a main() function when the module is run directly, but not when the module is imported by some other module.

len()

len() can tell length of string, list, tuple, dictionary

repr()

Return a string containing a printable representation of an object.

functions

The def keyword defines the function with its parameters within parentheses and its code indented.
The first line of a function can be a documentation string (“docstring”) that describes what the function does. A docstring is triple quotes “””

methods

A method is like a function, but it runs “on” an object.

variable names

Prefer underscore_based naming
As python doesnt have strong type system, it is better to name variables to denote what type it is. e.g name if it is string, names if it is list

help() dir()

dir() shows the attributes of an object. e.g all the functions and variables of a module
help() shows the help documentation

operators

+-*/ works usual way on integers. // is for integer division.

strings

String literals can be enclosed by either double or single quotes, though single quotes are more commonly used.
Backslash escapes work the usual way within both single and double quoted literals
A single quoted string can have double quote and vice versa.
String can span over multiple lines, provided there is backslash at end of line.

Strings in python are IMMUTABLE. New strings are created to store computed values.
Characters in strings can be accessed with [] syntax, exception is raised for out of bound index.
str() function converts number/float to string

  • concatenates a string and returns new string
    r’hi\t hello’ treats the string as raw. no special treatment for backslash.
    u’hello hi’ treats the string in unicode format

s.find(), s.replace(), s.split(), s.join()
s.isalpha(), s.isdigit(), s.isspace()

s.slice[i:j] doesnt include jth character
s.slice[:] here i defaults to 0, j defaults to length of string
s.slice[i:-1] here -1 is the last character

if statement

Any value can be used as an if-test. The “zero” values all count as false: None, 0, empty string, empty list, empty dictionary.
boolean operators are ‘and’ ‘or’
if else
if elif
if i in list

list

List literals are written within square brackets [ ]. Lists work similarly to strings – use the len() function and square brackets [ ] to access data, with the first element at index 0

for-in

for i in list:
statements

Dictionary

dict = {‘key’: ‘value’}
Strings, numbers, and tuples work as keys, and any type can be a value.
strings and tuples work cleanly as keys since they are immutable.

  • dict[‘foo’] looks up the value under the key ‘foo’
  • Looking up a value which is not in the dict throws a KeyError
  • use “in” to check if the key is in the dict
  • use dict.get(key) which returns the value or None if the key is not present
  • get(key, not-found) allows you to specify what value to return in the not-found case

dict.keys() and dict.values() returns lists of keys and values

del

del operator does deletions

files

  • open() function opens and returns a file handle that can be used to read or write a file
  • for in - reads one line at a time. Reading one line at a time has the nice quality that not all the file needs to fit in memory at one time
  • f.readlines() method reads the whole file into memory and returns its contents as a list of its lines.
  • The f.read() method reads the whole file into a single string, which can be a handy way to deal with the text all at once
  • f.write(string) method is the easiest way to write data to an open output file
    The “codecs” module provides support for reading a unicode file.

Exercise Incremental Development

  • Building a Python program, don’t write the whole thing in one step.
  • Divide it into milestones. Write the code to get to that milestone, and just print your data structures at that point, and then you can do a sys.exit(0)
  • Being able to look at the printout of your variables at one state can help you think about how you need to transform those variables to get to the next state.

Extra Notes


String

Strings are immutable but Passed by reference

S[i] # returns c
S[i:j] # returns substring
S.find(c) # returns index or -1


List

L is mutable. Passed by reference.
L.append(v)
v in L # returns boolean
L.index(v) # returns i. error if v not present in L
L.pop()