Hi there. My name is Tamoghna Saha. For my bio, you can take a look at my LinkedIn profile or my GitHub account, but if you are wondering “who the hell is this guy in Harsha’s website?” , then I am (also) Harsha’s roomie! He told me to take up the initiative of writing articles on data science in his website. I am not a ‘writing’ kind of a guy but decided to give it a try. 😀

I have been working with Python for the past 2 years. There are lots of tutorials available online that covers Python, but sometimes it doesn’t cover the most crucial part which needs an answer – “Why do we need to use Python?”. “Is it worth learning it?”.

Since you have clicked this article, and reading till this point, I can assume that you are interested in Python or maybe you do know something about it but you need a quick recap. I am here to guide you not only with the syntax but also to tell some concepts, tips, and tricks associated with it.

I have embedded the notebook in the article at the end. If you find trouble going through the code snippets in this article, you can refer to the notebook. I will be doing the same for the upcoming articles.

Table of Content:

  • Numerical and Boolean Operations
  • Variable and Object
  • Data Type and Type Conversion
  • Importing Python Modules and standard libraries
  • Python Built-in Functions and keywords
  • String operations and formatting
  • Useful Pythonic Functions
  • User-Defined Function
  • Scope of a Variable
  • Additional Read

What is Python?

It is a general-purpose, high-level, interpreted, dynamic scripting language.

  • General-Purpose -> designed to be used for writing software in the widest variety of application domains
  • High-level -> designed to be more or less independent of a particular type of computer, human-readable friendly
  • Interpreted -> designed to execute instructions of a program directly, without previously compiling a program into machine-language instructions
  • Scripting -> languages which are interpreted rather than compiled

But, what is the difference between an interpreter and a compiler?

Currently, there are two versions of Python

Why do we need Python?

  • Simple syntax, readable, reusable and maintainable code
  • Multiple Programming Paradigms such as Object-oriented, structured, functional Paradigms and feature of automatic memory management
  • Compatible with Major Platforms and Systems, many open-source frameworks available which boostthe developer’s productivity
  • Robust Standard Library and supporting a wide range of external libraries
  • Easier to perform coding and testing simultaneously by adopting test-driven development (TDD) approach

That’s okay. But where do I use it?

Who uses Python anyway?

Cool. I guess we are good to go!

If your ground is muddy, can you build your dream house? So, let’s make the basics STRONG!

# This is how you comment a code in Python!
## Let’s start with the famous code.
>>> print(‘Hello World’)

Hello World
# a collection of 20 software principles that influences the design of Python Programming Language, of which 19 were written down
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

In order to get an understanding of these aphorisms, take a look at this link.

Numerical and Boolean Operations

## some basic mathematical operations , I am not showing. You do it. But see this.
>>> print(25/4) # floating point division
## to determine quotient and remainder
>>> print(25//4) # floor division
>>> print(25%4) # modulo operator
>>> x = 3
>>> x *= 3 # in-place operator
>>> print(x)
>>> y = “python”
>>> y += “3”
>>> print(y)

The tricky part for the above is this — in Python 2.7.X, it will return the base integer (6 in this case) in both floating point and floor division. So even if you are using Python 2.7.X, you can do this:

from __future__ import division

which causes Python 2.7.X to adopt the behavior of 3.7.X!
But what is this from stuff?
We will look into it. But let’s cover Boolean operations.

>>> from __future__ import division
>>> print(“Easy ones!\n — — — — -”)
>>> print(2 == 3)
>>> print(6 != 7)
>>> print(1 == True)
>>> print(2 == True)
>>> print(3 == False)
>>> print(9 is not “nine”) 
>>> print(5 > 3) 
>>> print(“ — — — — -”) 
>>> print(“Tricky ones!\n — — — — -”) 
>>> print(6 < 6.0) 
>>> print((3 * 0.1) == 0.3) 
>>> print((3 * 0.1) == (3/10))
Easy ones!
Tricky ones! 

Variables and Objects

    • Variables do not have a defined type at compile time.
  • Variables can reference any type of object!
  • The variable type can change in run-time.

Type checking is performed at run-time -> hence dynamic languages are slower than static languages.
Everything in Python is an Object!
object is the base type for every Python Object. Objects can be:

  • Mutable: value can be changed. [list, set, dictionaries]
  • Immutable: value is unchangeable. [number, string, frozenset, tuple]

Object mutability is defined by its type.
Objects Are Never Explicitly Destroyed! Allocation and deletion are done by the interpreter.
The most commonly used methods of constructing a multi-word variable name are the last three examples:

  • Camel Case: Second and subsequent words are capitalized, to make word boundaries easier to see. Example: numberOfCollegeGraduates
  • Pascal Case: Identical to Camel Case, except the first word is also capitalized. Example: NumberOfCollegeGraduates
  • Snake Case: Words are separated by underscores. Example: number_of_college_graduates
# the correct ways to declare variables 
>>> x = 123 # this is right
>>> my_variable = “is my variable, None of your variable” # even this is right
# definitely the wrong way to declare variables
>>> 1234_get_on_the_dance_floor = "really?" # this is wrong. see what error you will get

Data Type and Type Conversion

# data types
>>> print(type(“hello”))
>>> print(type(True))
>>> print(type(999.666))
>>> print(type((-1+0j)))
<class 'str'>
<class 'bool'>
<class 'float'>
<class 'complex'>
# type conversion
>>> print(float(6))
>>> print(str(99) + “ “ + str(type(str(99))))
>>> print(int(“3”) + int(“6”))
99 <class 'str'>

Importing Python Modules and standard libraries

Python is structured in Modules. From these modules, it is possible to extend the python interpreter capabilities.

## Importing standard and open-source external libraries to your programming environment

## There are several ways to import modules:
# 1. By directly import
>>> import math
# this is fine but avoid this sort of importing. Instead, try this:

# 2. By specifically importing its functions
>>> from math import sin, log
>>> print(sin(45))
>>> print(log(5))

# better not take the following approach
# 3. By importing everything
>>> from math import *
# if you still wish to use the entire library, you need to do it like this
>>> import math
>>> print(math.sin(45))

Some of the default modules in Python

  • sys -> System — specific parameters and functions.
  • io -> Core tools for working with streams.
  • os -> Miscellaneous operating system interfaces.
  • threading -> Higher — level threading interface.
  • multiprocess -> Process-based “threading“ interface.
  • socket -> Low — level networking interface.
  • asyncio -> Asynchronous I/O, event loop, coroutines, and tasks.
  • cmd -> Support for line-oriented command interpreters.
  • datetime -> Basic date and time types.
  • time -> Time access and conversions.
  • heapq -> Heap queue algorithm.
  • queue -> A synchronized queue class.
  • pathlib -> Object-oriented filesystem paths
  • math -> Mathematical functions
  • sqlite3 -> DB — API interface for SQLite3 Databases.

Python Built-in Functions and keywords

Built-in functions are core functions, provided by the Python Interpreter.

These functions are implemented in C and because of that, are capable of using and manipulating Python objects at memory level, with increased performance.

# just wrote these code to display the list properly in notebook

# built-in functions
>>> builtin_functions_list = dir(__builtins__)
>>> builtin_functions_data = np.array(builtin_functions_list)
>>> shape = ((len(builtin_functions_list)//4),4)
>>> print(tabulate(builtin_functions_data.reshape(shape), tablefmt='orgtbl'))
| ArithmeticError      | AssertionError         | AttributeError     | BaseException        
| BlockingIOError      | BrokenPipeError        | BufferError        | BytesWarning
| ChildProcessError    | ConnectionAbortedError | ConnectionError    | ConnectionRefusedError
| ConnectionResetError | DeprecationWarning     | EOFError           | Ellipsis             
| EnvironmentError     | Exception              | False              | FileExistsError
| FileNotFoundError    | FloatingPointError     | FutureWarning      | GeneratorExit        
| IOError              | ImportError            | ImportWarning      | IndentationError       
| IndexError           | InterruptedError       | IsADirectoryError  | KeyError
| KeyboardInterrupt    | LookupError            | MemoryError        | ModuleNotFoundError  
| NameError            | None                   | NotADirectoryError | NotImplemented         
| NotImplementedError  | OSError                | OverflowError      | PendingDeprecationWarning
| PermissionError      | ProcessLookupError     | RecursionError     | ReferenceError       
| ResourceWarning      | RuntimeError           | RuntimeWarning     | StopAsyncIteration     
| StopIteration        | SyntaxError            | SyntaxWarning      | SystemError               
| SystemExit           | TabError               | TimeoutError       | True                 
| TypeError            | UnboundLocalError      | UnicodeDecodeError | UnicodeEncodeError     
| UnicodeError         | UnicodeTranslateError  | UnicodeWarning     | UserWarning               
| ValueError           | Warning                | ZeroDivisionError  | __IPYTHON__          
| __build_class__      | __debug__              | __doc__            | __import__             
| __loader__           | __name__               | __package__        | __spec__                  
| abs                  | all                    | any                | ascii                
| bin                  | bool                   | bytearray          | bytes                  
| callable             | chr                    | classmethod        | compile                   
| complex              | copyright              | credits            | delattr              
| dict                 | dir                    | display            | divmod                 
| enumerate            | eval                   | exec               | filter                    
| float                | format                 | frozenset          | get_ipython          
| getattr              | globals                | hasattr            | hash                   
| help                 | hex                    | id                 | input                     
| int                  | isinstance             | issubclass         | iter                 
| len                  | license                | list               | locals                 
| map                  | max                    | memoryview         | min                       
| next                 | object                 | oct                | open                 
| ord                  | pow                    | print              | property               
| range                | repr                   | reversed           | round                     
| set                  | setattr                | slice              | sorted               
| staticmethod         | str                    | sum                | super                  
| tuple                | type                   | vars               | zip
### keywords
>>> keywords_list = keyword.kwlist
>>> keywords_data = np.array(keywords_list)
>>> shape = ((len(keywords_list)//3),3)
>>> print(tabulate(keywords_data.reshape(shape), tablefmt='orgtbl'))
| False | None   | True     |
| and   | as     | assert   |
| break | class  | continue |
| def   | del    | elif     |
| else  | except | finally  |
| for   | from   | global   |
| if    | import | in       |
| is    | lambda | nonlocal |
| not   | or     | pass     |
| raise | return | try      |
| while | with   | yield    |

String operations and formatting

## Concatenation
>>> str_var_1 = "concatenation"
>>> print("This is " + str_var_1 + " of string")
>>> print(3*"3")
>>> print("python"*3.7)
>>> print("This will not print")
This is concatenation of string
TypeError                                 Traceback (most recent call last)
<ipython-input-15-6eae2c361731> in <module>()
      6 print(3*"3")
----> 8 print("python"*3.7)
     10 print("This will not print")

TypeError: can't multiply sequence by non-int of type 'float'
## string formatting
# It provides a powerful way of embedding non-strings with strings

>>> py_ver = "We are using Python version {}.{}.x".format(3,6)
>>> print(py_ver)
>>> other_version = 2.7
>>> print(f"We could have also used Python {other_version}") # another way of performing string formatting
>>> print("{0}{1}{0}".format("abra ","cad"))
We are using Python version 3.6.x
We could have also used Python 2.7
abra cadabra
## user input
>>> data_input = input("Enter your ID: ")
>>> print("Employee having ID No: {} is late for office today.".format(data_input))
Enter your ID: 12345
Employee having ID No: 12345 is late for office today.

Useful Pythonic Functions

# strings
>>> print(",".join(["NASA","Google","Netflix","Yahoo"]))
>>> print("NASA,Google,Netflix,Yahoo".split(","))
>>> print("Python 2.7".replace("2.7","3.6"))
>>> print("There is more to it than meets the eye".startswith("There")) # also endswith is there
>>> print("python".upper())
['NASA', 'Google', 'Netflix', 'Yahoo']
Python 3.6
# numeric
>>> print(max(10,64,86,13,98))
>>> print(abs(-9))
>>> print(sum([2,4,6,8]))

User-Defined Function

Before going ahead, can you tell me the difference between a function and a method? Well, here is the answer.

In Python, functions are first-class objects which is an entity that can be
  • dynamically created, destroyed
  • can be stored in a variable
  • passed to a function as a parameter
  • returned as a value from a function

In C++, classes are not first class objects but instances of those classes are. In Python, both the classes and the objects are first class objects.

Create your own functions using def keyword.

UDF can either take or don’t take arguments. Technically, parameters are the variables in a function definition, and arguments are the values placed to the parameters when the function is called.

The name of the UDF should be lowercase.

NOTE: You must define functions before they are called, in the same way, you declare a variable before using them

>>> def udf_1(rqrdArg):

>>> def udf_2(optnlArg = None):
        print("OptionalArg: ", optnlArg)
>>> def udf_3(rqrdArg, optnlArg=None, *args, **kwargs): # *args = extra unnamed argument, **kwargs = extra named arguments
        print("RequiredArg: ", rqrdArg)
        print("OptionalArg: ", optnlArg)
        print("Remaining Non-keyworded args: ",args)
        print("Remaining keyworded args: ",kwargs)

>>> print("Calling UDF 1!")
>>> print("RequiredArg: ", udf_1(5.7))

>>> print("\nCalling UDF 2!")
>>> udf_2()
>>> udf_2(9)

>>> print("\nCalling UDF 3!")
>>> udf_3("Python","3.6",2,7,MSU_Python_Session=1)
Calling UDF 1!
RequiredArg:  17.1

Calling UDF 2!
OptionalArg:  None
OptionalArg:  9

Calling UDF 3!
RequiredArg:  Python
OptionalArg:  3.6
Remaining Non-keyworded args:  (2, 7)
Remaining keyworded args:  {'MSU_Python_Session': 1}
>>> def UDF_factorial(x):
        This is a recursive function performing factorial of a number
        x -> the number whose factorial is calculated
        if x == 1:
            return 1
            return x * UDF_factorial(x-1)
>>> print(UDF_factorial(5))

# how to check the function's docstring in notebook
>>> ?UDF_factorial # (and execute)

*args and **kwargs allow one to pass a variable-length argument list and keyworded, variable-length argument dictionary respectively to a function when one doesn’t know beforehand how many arguments can be passed to the function.

>>> def multiply(x,y):

>>> multiply(3,9)
>>> multiply(3,6,9)
TypeError Traceback (most recent call last)
<ipython-input-24-999cf6ad6adb> in <module>
4 multiply(3,9)
----> 5 multiply(3,6,9)

TypeError: multiply() takes 2 positional arguments but 3 were given

# resolving the above issue with *args
>>> def multiply(*args):
        x = 1
        for num in args:
            x *= num

>>> multiply(4, 5)
>>> multiply(10, 9)
>>> multiply(2, 3, 4)
>>> multiply(3, 5, 10, 6)

# likewise for **kwargs
>>> def print_kwargs(**kwargs):

>>> print_kwargs(kwargs_1="good stuffs", kwargs_2=2.7, kwargs_3=True)
{'kwargs_1': 'good stuffs', 'kwargs_2': 2.7, 'kwargs_3': True}

When ordering arguments within a function or function call, arguments need to occur in a particular order:

  1. Formal positional arguments
  2. *args
  3. Keyword arguments
  4. **kwargs

Scope of a variable

Not all variables are accessible from all parts of our program, and not all variables exist for the same amount of time.

A scope is a textual region of a Python program where a namespace is directly accessible. A namespace is a mapping from names (variables) to objects.

Basically, part of a program where a variable is accessible is its scope and the duration for which the variable exists its lifetime.

There are two types of variable scope:

  • Global: It is defined in the main body of a file, will be visible throughout the file, and also inside any file which imports that file.
  • Local: it is defined inside a function, limiting its availability inside that function. It is accessible from the point at which it is defined until the end of the function and exists for as long as the function is executing.

In Python 3, the third type of variable scope has been defined — nonlocal. It allows to assign variables in an outer, but non-global, scope.

# example showing global, local and nonlocal scopes
# global and local
>>> x = "global"
>>> def foo():
        print("x inside :", x)
>>> foo()
>>> print("x outside:", x)
x inside : global
x outside: global
>>> def outside():
        msg = "Outside!"
        def inside():
            msg = "Inside!"
>>> outside()

msg is declared in the outside function and assigned the value “Outside!”. Then, in the inside function, the value “Inside!” is assigned to it.

When we run outside, msg has the value “Inside!” in the inside function, but retains the old value in the outside function.

We see this behavior because Python hasn’t actually assigned the new value “Inside” to the existing msg variable, but has created a new variable called msg in the local scope of inside that shadows the name of the variable in the outer scope.

Preventing that behavior is where the nonlocal keyword comes in.

>>> def double_outside():
        msg = "Double Outside!"
        def outside():
            msg = "Outside!"
            def inside():
                nonlocal msg
                msg = "Inside!"
>>> double_outside()
Double Outside!

Now, by declaring nonlocal msg in the inside function, Python knows that when it sees an assignment to msg, it should assign to the variable from the immediate outer scope instead of declaring a new variable that shadows its name.

The usage of nonlocal is very similar to that of global, except that the former is used for variables in immediate outer function scopes and the latter is used for the variable in the global scope.

Additional Read

This is enough for the first part!

I hope you guys have liked this article. We will meet in the 2nd part of this series.

3 Replies to “Get started with Python | Notebook for Beginner’s level”

  1. Why Python is called Python? Absolutely nothing to do with the snakes! It was named after this comedy group called Monty Python. When Guido van Rossum began implementing Python, he was also reading the published scripts from “Monty Python’s Flying Circus”, a BBC comedy series from the 1970s. Van Rossum thought he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python.

Leave a Reply