Вы находитесь на странице: 1из 33

Introduction

Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. Its high-level built in data structures, combined with dynamic
typing and dynamic binding, make it very attractive for Rapid Application Development, as well as for use as a scripting or glue language to connect existing
components together. Python's simple, easy to learn syntax emphasizes readability and therefore reduces the cost of program maintenance. Python supports
modules and packages, which encourages program modularity and code reuse. The Python interpreter and the extensive standard library are available in source or
binary form without charge for all major platforms, and can be freely distributed.

Python is a great general-purpose programming language on its own, but with the help of a few popular libraries (numpy, scipy, matplotlib) it becomes a powerful
environment for scientific computing.

Python 3
Python 3 is regarded as the future of Python and is the version of the language that is currently in development. A major overhaul, Python 3 was released in late
2008 to address and amend intrinsic design flaws of previous versions of the language. The focus of Python 3 development was to clean up the codebase and
remove redundancy, making it clear that there was only one way to perform a given task.

Major modifications to Python 3.0 included changing the print statement into a built-in function, improve the way integers are divided, and providing more Unicode
support.

At first, Python 3 was slowly adopted due to the language not being backwards compatible with Python 2, requiring people to make a decision as to which version of
the language to use. Additionally, many package libraries were only available for Python 2, but as the development team behind Python 3 has reiterated that there is
an end of life for Python 2 support, more libraries have been ported to Python 3. The increased adoption of Python 3 can be shown by the number of Python
packages that now provide Python 3 support, which at the time of writing includes 339 of the 360 most popular Python packages.

Python 2.7
Following the 2008 release of Python 3.0, Python 2.7 was published on July 3, 2010 and planned as the last of the 2.x releases. The intention behind Python 2.7
was to make it easier for Python 2.x users to port features over to Python 3 by providing some measure of compatibility between the two. This compatibility support
included enhanced modules for version 2.7 like unittest to support test automation, argparse for parsing command-line options, and more convenient classes in
collections.

Because of Python 2.7’s unique position as a version in between the earlier iterations of Python 2 and Python 3.0, it has persisted as a very popular choice for
programmers due to its compatibility with many robust libraries. When we talk about Python 2 today, we are typically referring to the Python 2.7 release as that is
the most frequently used version.

Python 2.7, however, is considered to be a legacy language and its continued development, which today mostly consists of bug fixes, will cease completely in 2020.

Key Differences
While Python 2.7 and Python 3 share many similar capabilities, they should not be thought of as entirely interchangeable. Though you can write good code and
useful programs in either version, it is worth understanding that there will be some considerable differences in code syntax and handling.

Anaconda Python Distribution


Anaconda is an open-source package manager, environment manager, and distribution of the Python and R programming languages. It is commonly used for large-
scale data processing, scientific computing, and predictive analytics, serving data scientists, developers, business analysts, and those working in DevOps.

Anaconda offers a collection of over 720 open-source packages, and is available in both free and paid versions. The Anaconda distribution ships with the conda
command-line utility. You can learn more about Anaconda and conda by reading the Anaconda Documentation pages.
Why Anaconda?
User level install of the version of python you want
Able to install/update packages completely independent of system libraries or admin privileges
conda tool installs binary packages, rather than requiring compile resources like pip - again, handy if you have limited privileges for installing necessary
libraries.
More or less eliminates the headaches of trying to figure out which version/release of package X is compatible with which version/release of package Y, both of
which are required for the install of package Z
Comes either in full-meal-deal version, with numpy, scipy, PyQt, spyder IDE, etc. or in minimal / alacarte version (miniconda) where you can install what you
want, when you need it
No risk of messing up required system libraries

Installing on Windows
1. Download the Anaconda installer (https://www.continuum.io/downloads).
2. Optional: Verify data integrity with MD5 or SHA-256. More info on hashes
3. Double click the installer to launch.

NOTE: If you encounter any issues during installation, temporarily disable your anti-virus software during install, then re-enable it after the installation
concludes. If you have installed for all users, uninstall Anaconda and re-install it for your user only and try again.
4. Click Next.
5. Read the licensing terms and click I Agree.
6. Select an install for “Just Me” unless you’re installing for all users (which requires Windows Administrator privileges).
7. Select a destination folder to install Anaconda and click Next.

NOTE: Install Anaconda to a directory path that does not contain spaces or unicode characters.

NOTE: Do not install as Administrator unless admin privileges are required.


8. Choose whether to add Anaconda to your PATH environment variable. We recommend not adding Anaconda to the PATH environment variable, since this can
interfere with other software. Instead, use Anaconda software by opening Anaconda Navigator or the Anaconda Command Prompt from the Start Menu.
9. Choose whether to register Anaconda as your default Python 3.6. Unless you plan on installing and running multiple versions of Anaconda, or multiple versions
of Python, you should accept the default and leave this box checked.
10. Click Install. You can click Show Details if you want to see all the packages Anaconda is installing.
11. Click Next.
12. After a successful installation you will see the “Thanks for installing Anaconda” image:
13. You can leave the boxes checked “Learn more about Anaconda Cloud” and “Learn more about Anaconda Support” if you wish to read more about this cloud
package management service and Anaconda support. Click Finish.
14. After your install is complete, verify it by opening Anaconda Navigator, a program that is included with Anaconda. From your Windows Start menu, select the
shortcut Anaconda Navigator. If Navigator opens, you have successfully installed Anaconda.

Installing on macOS
1. Download the graphical macOS installer (https://www.continuum.io/downloads#macos) for your version of Python.
2. OPTIONAL: Verify data integrity with MD5 or SHA-256. For more information on hashes, see What about cryptographic hash verification?.
3. Double-click the .pkg file.
4. Answer the prompts on the Introduction, Read Me and License screens.
5. On the Destination Select screen, select Install for me only.

NOTE: If you get the error message “You cannot install Anaconda in this location,” reselect Install for me only.
6. On the Installation Type screen, you may choose to install in another location. The standard install puts Anaconda in your home user directory:
7. Click the Install button.
8. A successful installation displays the following screen:
Installing on Linux
1. In your browser, download the Anaconda installer for Linux.
2. Optional: Verify data integrity with MD5 or SHA-256. (For more information on hashes, see cryptographic hash validation.)

Run the following:

md5sum /path/filename OR:

sha256sum /path/filename
3. Verify results against the proper hash page to make sure the hashes match.
4. Enter the following to install Anaconda for Python 3.6:

bash ~/Downloads/Anaconda3-4.4.0-Linux-x86_64.sh OR

Enter the following to install Anaconda for Python 2.7:

bash ~/Downloads/Anaconda2-4.4.0-Linux-x86_64.sh NOTE: You should include the bash command regardless of whether you are using Bash shell.

NOTE: Replace actual download path and filename as necessary.

NOTE: Install Anaconda as a user unless root privileges are required.


5. The installer prompts “In order to continue the installation process, please review the license agreement.” Click Enter to view license terms.
6. Scroll to the bottom of the license terms and enter yes to agree to them.
7. The installer prompts you to click Enter to accept the default install location, press CTRL-C to cancel the installation, or specify an alternate installation
directory. If you accept the default install location, the installer displays 'PREFIX=/home/"user"/anaconda"2 or 3"' and continues the installation. It may
take a few minutes to complete.

The installer prompts “Do you wish the installer to prepend the Anaconda"2 or 3" install location to PATH in your /home/"user"/.bashrc ?” We recommend yes.

NOTE: If you enter “no”, you will need to manually specify the path to Anaconda when using Anaconda. To manually add the prepended path, edit file .bashrc to
add ~/anaconda"2 or 3"/bin to your path manually using:
8. export PATH="/home/"user"/anaconda"2 or 3"/bin:$PATH" Replace /home/"user"/anaconda"2 or 3" with the actual path.
9. The installer finishes and displays “Thank you for installing Anaconda"2 or 3"!”
10. Close and open your terminal window for the installation to take effect, or you can enter the command source ~/.bashrc.

Enter conda list. If the installation was successful, the terminal window should display a list of installed Anaconda packages.

NOTE: Power8 users: Navigate to your Anaconda directory and run this command:

conda install libgfortran

What are Jupyter notebook?

The notebook is a web application that allows you to combine explanatory text, math equations, code, and visualizations all in one easily sharable document.

Notebooks have quickly become an essential tool when working with data. You'll find them being used for data cleaning and exploration, visualization, machine
learning, and big data analysis. Typically you'd be doing this work in a terminal, either the normal Python shell or with IPython. Your visualizations would be in
separate windows, any documentation would be in separate documents, along with various scripts for functions and classes. However, with notebooks, all of these
are in one place and easily read together.

Notebooks are also rendered automatically on GitHub. It’s a great feature that lets you easily share your work. There is also http://nbviewer.jupyter.org/
(http://nbviewer.jupyter.org/) that renders the notebooks from your GitHub repo or from notebooks stored elsewhere.

How notebook works?


Jupyter notebooks grew out of the IPython project started by Fernando Perez. IPython is an interactive shell, similar to the normal Python shell but with great
features like syntax highlighting and code completion. Originally, notebooks worked by sending messages from the web app (the notebook you see in the browser)
to an IPython kernel (an IPython application running in the background). The kernel executed the code, then sent it back to the notebook. The current architecture is
similar.

The central point is the notebook server. You connect to the server through your browser and the notebook is rendered as a web app. Code you write in the web
app is sent through the server to the kernel. The kernel runs the code and sends it back to the server, then any output is rendered back in the browser. When you
save the notebook, it is written to the server as a JSON file with a .ipynb file extension.

The great part of this architecture is that the kernel doesn't need to run Python. Since the notebook and the kernel are separate, code in any language can be sent
between them. For example, two of the earlier non-Python kernels were for the R and Julia languages. With an R kernel, code written in R will be sent to the R
kernel where it is executed, exactly the same as Python code running on a Python kernel. IPython notebooks were renamed because notebooks became language
agnostic. The new name Jupyter comes from the combination of Julia, Python, and R.

Another benefit is that the server can be run anywhere and accessed via the internet. Typically you'll be running the server on your own machine where all your data
and notebook files are stored. But, you could also set up a server on a remote machine or cloud instance like Amazon's EC2. Then, you can access the notebooks
in your browser from anywhere in the world.

Installing Jupyter Notebook

By far the easiest way to install Jupyter is with Anaconda. Jupyter notebooks automatically come with the distribution. You'll be able to use notebooks from the
default environment.

To install Jupyter notebooks in a conda environment, use conda install jupyter notebook.

Launching the notebook server


To start a notebook server, enter jupyter notebook in your terminal or console. This will start the server in the directory you ran the command in. That means any
notebook files will be saved in that directory. Typically you'd want to start the server in the directory where your notebooks live. However, you can navigate through
your file system to where the notebooks are.

When you run the command (try it yourself!), the server home should open in your browser. By default, the notebook server runs at http://localhost:8888
(http://localhost:8888). If you aren't familiar with this, localhost means your computer and 8888 is the port the server is communicating on. As long as the server is
still running, you can always come back to it by going to http://localhost:8888 (http://localhost:8888) in your browser.

If you start another server, it'll try to use port 8888, but since it is occupied, the new server will run on port 8889. Then, you'd connect to it at http://localhost:8889
(http://localhost:8889). Every additional notebook server will increment the port number like this.

Fundamental types in Python

Integers
Integer literals are created by any number without a decimal or complex component.

In [1]: # This is a comment cell


# This is the second line comment

In [2]: # integers
x = 1
print(x)
y=5
print(y)
z="Sayan"
print(z)

1
5
Sayan
In [3]: #Implicit Printing
x

Out[3]: 1

Floats
Float literals can be created by adding a decimal component to a number.

In [4]: # No concept of declaring variable types in Python


x = 1.0
y = 5.7
print(y)
y=3
print(y)
y=5.6
print(x)
print(y)

5.7
3
1.0
5.6

Boolean
Boolean can be defined by typing True/False without quotes

In [5]: # Case Sensitive. True is different from TRUE. Dynamic Typing


b1 = True
print(b1)
b2 = False
b1 = 6
print(b1)

True
6

Strings
String literals can be defined with any of single quotes ('), double quotes (") or triple quotes (''' or """). All give the same result with two important differences.

If you quote with single quotes, you do not have to escape double quotes and vice-versa. If you quote with triple quotes, your string can span multiple lines.

In [6]: a="Sayan"
b=5
print(type(a))
print(type(b))

<class 'str'>
<class 'int'>

In [7]: # string
name1 = 'your name'
print(name1)
name2 = "He's coming to the party"
print(name2)
name3 = '''XNews quotes : "He's coming to the party"'''
print(name3)

your name
He's coming to the party
XNews quotes : "He's coming to the party"
In [8]: 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!

Determining variable type with type()


You can check what type of object is assigned to a variable using Python's built-in type() function. Common data types include:

int (for integer)


float
str (for string)
list
tuple
dict (for dictionary)
set
bool (for Boolean True/False)

Variables

Definining

A variable in Python is defined through assignment. There is no concept of declaring a variable outside of that assignment.

In [9]: a=10
a="Sayan"
a=5.6
a=True
print(a)

True

The names you use when creating these labels need to follow a few rules:

1. Names can not start with a number.


2. There can be no spaces in the name, use _ instead.
3. Can't use any of these symbols :'",<>/?|\()!@#$%^&*~-+
4. It's considered best practice (PEP8) that names are lowercase.
5. Avoid using the characters 'l' (lowercase letter el), 'O' (uppercase letter oh),
or 'I' (uppercase letter eye) as single character variable names.
6. Avoid using words that have special meaning in Python like "list" and "str"

Strong Typing

While Python allows you to be very flexible with your types, you must still be aware of what those types are. Certain operations will require certain types as
arguments.
In [10]: print(5+6)

11

In [11]: a=5
b=6
c=a+b
print(c)

11

In [12]: 6*7

Out[12]: 42

In [13]: #Concatenation
'Hello'+'World'

Out[13]: 'HelloWorld'

In [14]: 'Day ' + 1

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-643fe001d103> in <module>()
----> 1 'Day ' + 1

TypeError: must be str, not int

In [15]: #int(), #float, #bool()


print(type(1))
print(type(str(1)))

<class 'int'>
<class 'str'>

In [16]: #Typecasting
print('Day ' + str(1))

Day 1

Simple Expressions
In [17]: True and False

Out[17]: False

In [18]: True or False

Out[18]: True

In [19]: not True

Out[19]: False

In [20]: not False

Out[20]: True
In [22]: # Addition and subtraction
print(5 + 5)
print(5 - 5)

# Multiplication and division


print(3 * 5)
print(10 / 2)

# Exponentiation
print(4 ** 2)

# Modulo
print(18 % 7)

# How much is your $100 worth after 7 years?


print(100 * 1.1 ** 7)

10
0
15
5.0
16
4
194.87171000000012

if, elif, else Statements


if Statements in Python allows us to tell the computer to perform alternative actions based on a certain set of results.

Verbally, we can imagine we are telling the computer:

"Hey if this case happens, perform some action"

We can then expand the idea further with elif and else statements, which allow us to tell the computer:

"Hey if this case happens, perform some action. Else, if another case happens, perform some other action. Else, if none of the above cases happened, perform this
action."

Let's go ahead and look at the syntax format for if statements to get a better idea of this:

if case1:
perform action1
elif case2:
perform action2
else:
perform action3

In [ ]:

Each line of code in a certain block level must be indented equally and indented more than the surrounding scope. The standard (defined in PEP-8) is to use 4
spaces for each level of block indentation. Statements preceding blocks generally end with a colon (:).

Because there are no semi-colons or other end-of-line indicators in Python, breaking lines of code requires either a continuation character (\ as the last char) or for
the break to occur inside an unfinished structure (such as open parentheses).

Lists
The first container type that we will look at is the list. A list represents an ordered, mutable collection of objects. You can mix and match any type of object in a list,
add to it and remove from it at will.

Creating Empty Lists. To create an empty list, you can use empty square brackets or use the list() function with no arguments.

In [29]: marks_student = [10,20,30]


print(type(marks_student))

<class 'list'>

In [36]: marks_student[0]

Out[36]: 10
In [30]: l = []
l

Out[30]: []

In [31]: l = list()
l

Out[31]: []

In [33]: l = ['a', 'b', 'c']


l

Out[33]: ['a', 'b', 'c']

In [34]: #Zero Indexed


l[0]

Out[34]: 'a'

In [35]: l = ['a',6]
l

Out[35]: ['a', 6]

In [38]: # area variables (in square meters)


hall = 11.25
kit = 18.0
liv = 20.0
bed = 10.75
bath = 9.50

# Adapt list areas


areas = ["hallway", hall, "kitchen", kit, "living room", liv, "bedroom", bed, "bathroom", bath]

# Print areas
print(areas[2])
print(type(areas))

kitchen
<class 'list'>

In [40]: # area variables (in square meters)


hall = 11.25
kit = 18.0
liv = 20.0
bed = 10.75
bath = 9.50

# house information as list of lists


house = [["hallway", hall],
["kitchen", kit],
["living room", liv],
["bedroom", bed],
["bathroom", bath]]

# Print out house


print(house)

# Print out the type of house


print(type(house))

[['hallway', 11.25], ['kitchen', 18.0], ['living room', 20.0], ['bedroom', 10.75], ['bathroom', 9.5]]
<class 'list'>

In [41]: print(house[1])
print(type(house[1]))

['kitchen', 18.0]
<class 'list'>

In [42]: print(house[1][1])
print(type(house[1][1]))

18.0
<class 'float'>
A Python string is also a sequence of characters and can be treated as an iterable over those characters. Combined with the list() function, a new list of the
characters can easily be generated.

In [43]: list('abcdef')

Out[43]: ['a', 'b', 'c', 'd', 'e', 'f']

Adding. You can append to a list very easily (add to the end) or insert at an arbitrary index.

In [44]: l = []
l.append('b')
print(l)
l.append('c')
print(l)
l.insert(1, 56)
l
#Implicit Printing

['b']
['b', 'c']

Out[44]: ['b', 56, 'c']

String Basics

In Strings, the length of the string can be found out by using a function called len().

In [49]: a="Hello World"


len(a)

Out[49]: 11

String Indexing
We know strings are a sequence, which means Python can use indexes to call all the sequence parts. Let's learn how String Indexing works. • We use brackets []
after an object to call its index. • We should also note that indexing starts at 0 for Python. Now, Let's create a new object called s and the walk through a few
examples of indexing.

In [3]: demo = "Hello"


demo[1]

Out[3]: 'e'

In [50]: # Assign s as a string


s = 'Hello World'

In [51]: #Check
s

Out[51]: 'Hello World'

In [52]: # Print the object


print(s)

Hello World

Let's start indexing!

In [53]: # Show first element (in this case a letter)


s[0]

Out[53]: 'H'

In [54]: s[1]

Out[54]: 'e'
In [55]: s[2]

Out[55]: 'l'

We can use a : to perform slicing which grabs everything up to a designated point. For example:

In [60]: # Grab everything past the first term all the way to the length of s which is len(s)
s[1:]

Out[60]: 'ello World'

In [61]: # Note that there is no change to the original s


s

Out[61]: 'Hello World'

In [62]: # Grab everything UP TO the 2nd index


s[:3]

Out[62]: 'Hel'

Note the above slicing. Here we're telling Python to grab everything from 0 up to 3. It doesn't include the 3rd index. You'll notice this a lot in Python, where
statements and are usually in the context of "up to, but not including".

In [63]: #Everything
s[:]

Out[63]: 'Hello World'

We can also use negative indexing to go backwards.

In [64]: # Last letter (one index behind 0 so it loops back around)


s[-1]

Out[64]: 'd'

In [65]: # Grab everything but the last letter


s[:-1]

Out[65]: 'Hello Worl'

String Properties
Immutability is one the finest string property whichh is created once and the elements within it cannot be changed or replaced. For example:

In [66]: s

Out[66]: 'Hello World'

In [67]: # Let's try to change the first letter to 'x'


s[0] = 'x'

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-67-976942677f11> in <module>()
1 # Let's try to change the first letter to 'x'
----> 2 s[0] = 'x'

TypeError: 'str' object does not support item assignment

We can use the multiplication symbol to create repetition!

In [73]: 7*6

Out[73]: 42

In [74]: print('demo'*10)

demodemodemodemodemodemodemodemodemodemo
Print Formatting
Print Formatting ".format()" method is used to add formatted objects to the printed string statements.

Let's see an example to clearly understand the concept.

In [75]: print('Insert another string with curly brackets: {}'.format('The inserted string'))
print('My first name is {0}. Last name is {1}'.format('Sayan','Dey'))

Insert another string with curly brackets: The inserted string


My first name is Sayan. Last name is Dey

Indexing and Slicing


Indexing and slicing of lists works just like in Strings. Let's make a new list to remind ourselves of how this works:

In [76]: my_list = ['one','two','three',4,5]

In [77]: # Grab element at index 0


my_list[0]

Out[77]: 'one'

In [78]: # Grab index 1 and everything past it


my_list[1:]

Out[78]: ['two', 'three', 4, 5]

In [79]: # Grab everything UP TO index 3


my_list[:3]

Out[79]: ['one', 'two', 'three']

We can also use "+" to concatenate lists, just like we did for Strings.

In [80]: my_list + ['new item']

Out[80]: ['one', 'two', 'three', 4, 5, 'new item']

Note: This doesn't actually change the original list!

In [81]: my_list

Out[81]: ['one', 'two', 'three', 4, 5]

In this case, you have to reassign the list to make the permanent change.

In [82]: # Reassign
my_list = my_list + ['add new item permanently']

In [83]: my_list

Out[83]: ['one', 'two', 'three', 4, 5, 'add new item permanently']

In [84]: 'Zoo'*10

Out[84]: 'ZooZooZooZooZooZooZooZooZooZoo'

We can also use the * for a duplication method similar to strings:


In [86]: # Make the list double
my_list * 2

Out[86]: ['one',
'two',
'three',
4,
5,
'add new item permanently',
'one',
'two',
'three',
4,
5,
'add new item permanently']

In [98]: # Again doubling not permanent


my_list

Out[98]: ['one', 'two', 'three', 4, 5, 'add new item permanently']

In [99]: # Append
l=[1,2,3]
l.append('append me!')

In [100]: # Show
l

Out[100]: [1, 2, 3, 'append me!']

Use pop to "pop off" an item from the list. By default pop takes off the last index, but you can also specify which index to pop off. Let's see an example:

In [101]: # Pop off the 0 indexed item


l.pop(0)

Out[101]: 1

In [102]: # Show
l

Out[102]: [2, 3, 'append me!']

In [103]: # Assign the popped element, remember default popped index is -1


popped_item = l.pop()

In [104]: popped_item

Out[104]: 'append me!'

In [105]: # Show remaining list


l

Out[105]: [2, 3]

Note that lists indexing will return an error if there is no element at that index. For example:

In [106]: l[100]

---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-106-e2a0c2623844> in <module>()
----> 1 l[100]

IndexError: list index out of range

We can use the sort method and the reverse methods to also effect your lists:

In [107]: new_list = ['a','e','x','b','c']

In [108]: #Show
new_list

Out[108]: ['a', 'e', 'x', 'b', 'c']


In [109]: # Use reverse to reverse order (this is permanent!)
new_list.reverse()

In [110]: new_list

Out[110]: ['c', 'b', 'x', 'e', 'a']

In [111]: # Use sort to sort the list (in this case alphabetical order, but for numbers it will go ascending)
new_list.sort()

In [112]: new_list

Out[112]: ['a', 'b', 'c', 'e', 'x']

List Comprehensions

In [169]: # Build a list comprehension by deconstructing a for loop within a []


first_col = [row[0] for row in matrix]

In [170]: first_col

Out[170]: [1, 4, 7]

In [1]: l = [1,2,3]

In [2]: l.count(10)

Out[2]: 0

In [3]: l.count(2)

Out[3]: 1

In [4]: l.index(2)

Out[4]: 1

In [5]: l.index(12)

---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-5-da9218b18168> in <module>()
----> 1 l.index(12)

ValueError: 12 is not in list

In [7]: l

Out[7]: [1, 2, 3]

In [8]: # Place a letter at the index 2


l.insert(2,'inserted')

In [9]: l

Out[9]: [1, 2, 'inserted', 3]

In [10]: ele = l.pop()

In [11]: l

Out[11]: [1, 2, 'inserted']

In [12]: ele

Out[12]: 3

In [13]: l

Out[13]: [1, 2, 'inserted']

In [14]: l.remove('inserted')
In [15]: l
Out[15]: [1, 2]

In [16]: l = [1,2,3,4,3]

In [17]: l.remove(3)

In [18]: l

Out[18]: [1, 2, 4, 3]

In [198]: x = ["a", "b", "c", "d"]


print(x)
del(x[1])
print(x)

['a', 'b', 'c', 'd']


['a', 'c', 'd']

In [ ]:

Loops
In [113]: # Program to find the sum of all numbers stored in a list

# List of numbers
numbers = [6, 5, 3, 8, 4, 2, 5, 4,9]

# variable to store the sum


sum = 0

# iterate over the list


for val in numbers:
sum = sum+val
print("Printing")
print(sum)

# Output: The sum is 48


print("The sum is", sum)

Printing
6
Printing
11
Printing
14
Printing
22
Printing
26
Printing
28
Printing
33
Printing
37
Printing
46
The sum is 46

In [6]: # Program to add natural


# numbers upto
# sum = 1+2+3+...+n

sum = 0
i = 1

while i <= 10:


sum = sum + i
i = i+1 # update counter

# print the sum


print("The sum is", sum)

The sum is 55
In [1]: print(range(10))

range(0, 10)

In [2]: print(list(range(100)))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99]

In [3]: print(list(range(2, 8)))

[2, 3, 4, 5, 6, 7]

In [4]: print(list(range(2, 2000, 5)))

[2, 7, 12, 17, 22, 27, 32, 37, 42, 47, 52, 57, 62, 67, 72, 77, 82, 87, 92, 97, 102, 107, 112, 117, 122, 127, 132, 137,
142, 147, 152, 157, 162, 167, 172, 177, 182, 187, 192, 197, 202, 207, 212, 217, 222, 227, 232, 237, 242, 247, 252, 257,
262, 267, 272, 277, 282, 287, 292, 297, 302, 307, 312, 317, 322, 327, 332, 337, 342, 347, 352, 357, 362, 367, 372, 377,
382, 387, 392, 397, 402, 407, 412, 417, 422, 427, 432, 437, 442, 447, 452, 457, 462, 467, 472, 477, 482, 487, 492, 497,
502, 507, 512, 517, 522, 527, 532, 537, 542, 547, 552, 557, 562, 567, 572, 577, 582, 587, 592, 597, 602, 607, 612, 617,
622, 627, 632, 637, 642, 647, 652, 657, 662, 667, 672, 677, 682, 687, 692, 697, 702, 707, 712, 717, 722, 727, 732, 737,
742, 747, 752, 757, 762, 767, 772, 777, 782, 787, 792, 797, 802, 807, 812, 817, 822, 827, 832, 837, 842, 847, 852, 857,
862, 867, 872, 877, 882, 887, 892, 897, 902, 907, 912, 917, 922, 927, 932, 937, 942, 947, 952, 957, 962, 967, 972, 977,
982, 987, 992, 997, 1002, 1007, 1012, 1017, 1022, 1027, 1032, 1037, 1042, 1047, 1052, 1057, 1062, 1067, 1072, 1077, 108
2, 1087, 1092, 1097, 1102, 1107, 1112, 1117, 1122, 1127, 1132, 1137, 1142, 1147, 1152, 1157, 1162, 1167, 1172, 1177, 11
82, 1187, 1192, 1197, 1202, 1207, 1212, 1217, 1222, 1227, 1232, 1237, 1242, 1247, 1252, 1257, 1262, 1267, 1272, 1277, 1
282, 1287, 1292, 1297, 1302, 1307, 1312, 1317, 1322, 1327, 1332, 1337, 1342, 1347, 1352, 1357, 1362, 1367, 1372, 1377,
1382, 1387, 1392, 1397, 1402, 1407, 1412, 1417, 1422, 1427, 1432, 1437, 1442, 1447, 1452, 1457, 1462, 1467, 1472, 1477,
1482, 1487, 1492, 1497, 1502, 1507, 1512, 1517, 1522, 1527, 1532, 1537, 1542, 1547, 1552, 1557, 1562, 1567, 1572, 1577,
1582, 1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, 1632, 1637, 1642, 1647, 1652, 1657, 1662, 1667, 1672, 1677,
1682, 1687, 1692, 1697, 1702, 1707, 1712, 1717, 1722, 1727, 1732, 1737, 1742, 1747, 1752, 1757, 1762, 1767, 1772, 1777,
1782, 1787, 1792, 1797, 1802, 1807, 1812, 1817, 1822, 1827, 1832, 1837, 1842, 1847, 1852, 1857, 1862, 1867, 1872, 1877,
1882, 1887, 1892, 1897, 1902, 1907, 1912, 1917, 1922, 1927, 1932, 1937, 1942, 1947, 1952, 1957, 1962, 1967, 1972, 1977,
1982, 1987, 1992, 1997]

We can use the range() function in for loops to iterate through a sequence of numbers. It can be combined with the len() function to iterate though a sequence using
indexing. Here is an example.

In [5]: # Program to iterate through a list using indexing

genre = ['pop', 'rock', 'jazz','sapna']

# iterate over the list using index


for i in range(len(genre)):
print("I like", genre[i])

I like pop
I like rock
I like jazz
I like sapna

In [9]: print(len(genre))
print(list(range(len(genre))))

4
[0, 1, 2, 3]

In [10]: # Program to iterate through a list using indexing

genre = ['pop', 'rock', 'jazz','sapna']


l = [0,1,2,3]

# iterate over the list using index


for i in l:
print("I like", genre[i])

I like pop
I like rock
I like jazz
I like sapna

break and continue statement


In [11]: list("string")

Out[11]: ['s', 't', 'r', 'i', 'n', 'g']

In [13]: # Use of break statement inside loop

for val in "string":


if val == "i":
break
print(val)

print("The end")

s
t
r
The end

In [14]: # Program to show the use of continue statement inside loops

for val in "string":


if val == "i":
continue
print(val)

print("The end")

s
t
r
n
g
The end

Tuples
In Python, tuples are similar to lists but they are immutable i.e. they cannot be changed. You would use the tuples to present data that shouldn't be changed, such
as days of week or dates on a calendar.

In [32]: # Can create a tuple with mixed types


t = (1,2,3)

In [33]: # Check len just like a list


len(t)

Out[33]: 3

In [34]: # Can also mix object types


t = ('one',2)

# Show
t

Out[34]: ('one', 2)

In [35]: # Use indexing just like we did in lists


t[0]

Out[35]: 'one'

In [36]: # Slicing just like a list


t[-1]

Out[36]: 2

Basic Tuple Methods


Tuples have built-in methods, but not as many as lists do. Let's see two samples of tuple built-in methods:
In [37]: # Use .index to enter a value and return the index
t.index('one')

Out[37]: 0

In [38]: # Use .count to count the number of times a value appears


t.count('one')

Out[38]: 1

Immutability
As tuples are immutable, it can't be stressed enough and add more into it. To drive that point home:

In [39]: t[0]= 'change'

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-39-1257c0aa9edd> in <module>()
----> 1 t[0]= 'change'

TypeError: 'tuple' object does not support item assignment

Because tuple being immutable they can't grow. Once a tuple is made we can not add to it.

In [40]: t.append('nope')

---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-40-b75f5b09ac19> in <module>()
----> 1 t.append('nope')

AttributeError: 'tuple' object has no attribute 'append'

When to use Tuples


You may be wondering, "Why to bother using tuples when they have a few available methods?"

Tuples are not used often as lists in programming but are used when immutability is necessary. While you are passing around an object and if you need to make
sure that it does not get changed then tuple become your solution. It provides a convenient source of data integrity.

You should now be able to create and use tuples in your programming as well as have a complete understanding of their immutability.

In [41]: # areas list


areas = [11.25, 18.0, 20.0, 10.75, 9.50]

# Code the for loop


for index, area in enumerate(areas) :
print("room " + str(index) + ": " + str(area))

room 0: 11.25
room 1: 18.0
room 2: 20.0
room 3: 10.75
room 4: 9.5

Sets
Sets are an unordered collection of unique elements which can be constructed using the set() function.

Let's go ahead and create a set to see how it works.

In [42]: x = set()

In [43]: # We add to sets with the add() method


x.add(1)
In [44]: #Show
x

Out[44]: {1}

Note that the curly brackets do not indicate a dictionary! Using only keys, you can draw analogies as a set being a dictionary.

We know that a set has an only unique entry. Now, let us see what happens when we try to add something more that is already present in a set?

In [45]: # Add a different element


x.add(2)

In [46]: #Show
x

Out[46]: {1, 2}

In [47]: # Try to add the same element


x.add(1)

In [48]: #Show
x

Out[48]: {1, 2}

Notice, how it won't place another 1 there as a set is only concerned with unique elements! However, We can cast a list with multiple repeat elements to a set to get
the unique elements. For example:

In [49]: # Create a list with repeats


l = [1,1,2,2,3,4,5,6,1,1]

In [50]: # Cast as set to get unique values


a=set(l)
print(a)

{1, 2, 3, 4, 5, 6}

Dictionaries
In [15]: # Definition of countries and capital
countries = ['spain', 'france', 'germany', 'norway']
capitals = ['madrid', 'paris', 'berlin', 'oslo']

# Get index of 'germany': ind_ger


ind_ger = countries.index('germany')

# Use ind_ger to print out capital of Germany


print(capitals[ind_ger])

berlin

In [18]: # Definition of dictionary


europe = {'spain':'madrid', 'france':'paris', 'germany':'berlin', 'norway':'oslo' }

# Print out the keys in europe


print(type(europe))
print(europe.keys())
print(europe.values())

# Print out value that belongs to key 'norway'


print(europe['spain'])

<class 'dict'>
dict_keys(['spain', 'france', 'germany', 'norway'])
dict_values(['madrid', 'paris', 'berlin', 'oslo'])
madrid

Note that dictionaries are very flexible in the data types they can hold. For example:

In [35]: my_dict = {'key1':123,'key2':[12,23,33],'key3':['item0','item1','item2']}


In [36]: my_dict['key3']

Out[36]: ['item0', 'item1', 'item2']

In [37]: #Let's call items from the dictionary


type(my_dict['key3'])

Out[37]: list

In [38]: # Can call an index on that value


my_dict['key1'][0:2]

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-38-deb635d37c9c> in <module>()
1 # Can call an index on that value
----> 2 my_dict['key1'][0:2]

TypeError: 'int' object is not subscriptable

In [39]: #Can then even call methods on that value


my_dict['key3'][0].upper()

Out[39]: 'ITEM0'

We can effect the values of a key as well. For instance:

In [40]: my_dict['key1']

Out[40]: 123

In [41]: # Subtract 123 from the value


my_dict['key1'] = my_dict['key1'] - 123

In [42]: #Check
my_dict['key1']

Out[42]: 0

In [47]: # Set the object equal to itself minus 123


my_dict['key1'] =- 123
my_dict['key1']

Out[47]: -123

In [48]: # Dictionary of dictionaries


europe = { 'spain': { 'capital':'madrid', 'population':46.77 },
'france': { 'capital':'paris', 'population':66.03 },
'germany': { 'capital':'berlin', 'population':80.62 },
'norway': { 'capital':'oslo', 'population':5.084 } }

# Print out the capital of France


print(europe['france']['capital'])

# Create sub-dictionary data


data = { 'capital':'rome', 'population':59.83 }

# Add data to europe under key 'italy'


europe['italy'] = data

# Print europe
print(europe)

paris
{'spain': {'capital': 'madrid', 'population': 46.77}, 'france': {'capital': 'paris', 'population': 66.03}, 'germany':
{'capital': 'berlin', 'population': 80.62}, 'norway': {'capital': 'oslo', 'population': 5.084}, 'italy': {'capital': 'r
ome', 'population': 59.83}}

A few Dictionary Methods


There are a few methods we can call on a dictionary. Let's get a quick introduction to a few methods:
In [50]: # Create a typical dictionary
d = {'key1':1,'key2':2,'key3':3}

In [51]: # Method to return a list of all keys


d.keys()

Out[51]: dict_keys(['key1', 'key2', 'key3'])

In [52]: # Method to grab all values


d.values()

Out[52]: dict_values([1, 2, 3])

In [54]: #Tuples
(a,b)=(1,2)

In [55]: a

Out[55]: 1

In [56]: b

Out[56]: 2

In [57]: c= (1,2,3)
type(c)

Out[57]: tuple

In [59]: # Method to return tuples of all items


#List of Tuples
d.items()

Out[59]: dict_items([('key1', 1), ('key2', 2), ('key3', 3)])

In [60]: # Definition of dictionary


europe = {'spain':'madrid', 'france':'paris', 'germany':'bonn',
'norway':'oslo', 'italy':'rome', 'poland':'warsaw', 'australia':'vienna' }

# Iterate over europe


for key, value in europe.items() :
print("the capital of " + str(key) + " is " + str(value))

the capital of spain is madrid


the capital of france is paris
the capital of germany is bonn
the capital of norway is oslo
the capital of italy is rome
the capital of poland is warsaw
the capital of australia is vienna

Dictionary Comprehensions

In [73]: {x:x**2 for x in range(10)}

Out[73]: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

Functions
In [75]: def name_of_function(arg1,arg2):
'''
This is where the function's Document String (doc-string) goes
'''
# Do stuff here
#return desired result

You'll see the doc-string where you write the basic description of the function. Using iPython and iPython Notebooks, you'll be able to read these doc-strings by
pressing Shift+Tab after a function name. It is not mandatory to include docstrings with simple functions, but it is a good practice to put them as this will help the
programmers to easily understand the code you write
Example 1: A simple print 'hello' function

In [76]: def say_hello():


print('hello')

Call the function

In [77]: say_hello()

hello

Example 2: A simple greeting function


Let's write a function that greets people with their name.

In [78]: def greeting(name):


print('Hello %s' %name)

In [79]: greeting('Jose')

Hello Jose

Using return
Let's see some examples that use a return statement. Return allows a function to "return" a result that can then be stored as a variable, or used in whatever manner
a user wants.

Example 3: Addition function

In [80]: def add_num(num1,num2):


return num1+num2

In [81]: add_num(4,5)

Out[81]: 9

In [82]: # Can also save as variable due to return


result = add_num(4,5)

In [83]: print(result)

What happens if we input two strings?

In [84]: print(add_num('one','two'))

onetwo

In [85]: def is_prime(num):


'''
Naive method of checking for primes.
'''
for n in range(2,num):
if num % n == 0:
print('not prime')
break
else: # If never mod zero, then prime
print('prime')

In [86]: is_prime(16)

not prime
In [87]: help(max)

Help on built-in function max in module builtins:

max(...)
max(iterable, *[, default=obj, key=func]) -> value
max(arg1, arg2, *args, *[, key=func]) -> value

With a single iterable argument, return its biggest item. The


default keyword-only argument specifies an object to return if
the provided iterable is empty.
With two or more arguments, return the largest argument.

In [88]: ?max

In [89]: # Define shout_all with parameters word1 and word2


def shout_all(word1, word2):
"""Return a tuple of strings"""
# Concatenate word1 with '!!!': shout1
shout1 = word1 + '!!!'

# Concatenate word2 with '!!!': shout2


shout2 = word2 + '!!!'

# Construct a tuple with shout1 and shout2: shout_words


shout_words = (shout1, shout2)

# Return shout_words
return shout_words

# Pass 'congratulations' and 'you' to shout_all(): yell1, yell2


yell1, yell2 = shout_all('congratulations', 'you')

# Print yell1 and yell2


print(yell1)
print(yell2)

congratulations!!!
you!!!

In [90]: ## Scoping as searched is as follows


## Local then enclosing then global and finally the built-in scope

In [5]: # Create a string: team


team = "teen titans"

# Define change_team()
def change_team():
"""Change the value of the global variable team."""

# Use team in global scope


global team

# Change the value of team in global: team


team = "justice league"

# Print team
print(team)

# Call change_team()
change_team()

# Print team
print(team)

teen titans
justice league
In [92]: # Define three_shouts
def three_shouts(word1, word2, word3):
"""Returns a tuple of strings
concatenated with '!!!'."""

# Define inner
def inner(word):
"""Returns a string concatenated with '!!!'."""
return word + '!!!'

# Return a tuple of strings


return (inner(word1), inner(word2), inner(word3))

# Call three_shouts() and print


print(three_shouts('a', 'b', 'c'))

('a!!!', 'b!!!', 'c!!!')

In [93]: # Closure Concept in Computer Science


# Define echo
def echo(n):
"""Return the inner_echo function."""

# Define inner_echo
def inner_echo(word1):
"""Concatenate n copies of word1."""
echo_word = word1 * n
return echo_word

# Return inner_echo
return inner_echo

# Call echo: twice


twice = echo(2)

# Call echo: thrice


thrice = echo(3)

# Call twice() and thrice() then print


print(twice('hello'), thrice('hello'))

hellohello hellohellohello

In [94]: # Define echo_shout()


def echo_shout(word):
"""Change the value of a nonlocal variable"""

# Concatenate word with itself: echo_word


echo_word = word*2

#Print echo_word
print(echo_word)

# Define inner function shout()


def shout():
"""Alter a variable in the enclosing scope"""

#Use echo_word in nonlocal scope


nonlocal echo_word

#Change echo_word to echo_word concatenated with '!!!'


echo_word = echo_word + '!!!'

# Call function shout()


shout()

#Print echo_word
print(echo_word)

#Call function echo_shout() with argument 'hello'


echo_shout('hello')

hellohello
hellohello!!!
In [95]: # Define shout_echo
def shout_echo(word1, echo=1, intense=False):
"""Concatenate echo copies of word1 and three
exclamation marks at the end of the string."""

# Concatenate echo copies of word1 using *: echo_word


echo_word = word1 * echo

# Capitalize echo_word if intense is True


if intense is True:
# Capitalize and concatenate '!!!': echo_word_new
echo_word_new = echo_word.upper() + '!!!'
else:
# Concatenate '!!!' to echo_word: echo_word_new
echo_word_new = echo_word + '!!!'

# Return echo_word_new
return echo_word_new

# Call shout_echo() with "Hey", echo=5 and intense=True: with_big_echo


with_big_echo = shout_echo("Hey", echo=5, intense=True)

# Call shout_echo() with "Hey" and intense=True: big_no_echo


big_no_echo = shout_echo("Hey", intense=True)

# Print with_big_echo and big_no_echo


print(with_big_echo)
print(big_no_echo)

HEYHEYHEYHEYHEY!!!
HEY!!!

In [96]: # Define gibberish


def gibberish(*args):
"""Concatenate strings in *args together."""

# Initialize an empty string: hodgepodge


hodgepodge = ''

# Concatenate the strings in args


for word in args:
hodgepodge += word

# Return hodgepodge
return hodgepodge

# Call gibberish() with one string: one_word


one_word = gibberish("luke")

# Call gibberish() with five strings: many_words


many_words = gibberish("luke", "leia", "han", "obi", "darth")

# Print one_word and many_words


print(one_word)
print(many_words)

luke
lukeleiahanobidarth
In [97]: # Define report_status
def report_status(**kwargs):
"""Print out the status of a movie character."""

print("\nBEGIN: REPORT\n")

# Print a formatted status report


for key, value in kwargs.items():
print(key + ": " + value)

print("\nEND REPORT")

# First call to report_status()


report_status(name="luke", affiliation="jedi", status="missing")

# Second call to report_status()


report_status(name="anakin", affiliation="sith lord", status="deceased")

BEGIN: REPORT

name: luke
affiliation: jedi
status: missing

END REPORT

BEGIN: REPORT

name: anakin
affiliation: sith lord
status: deceased

END REPORT

Modules and Packages

Modules in Python are simply Python files with the .py extension, which implement a set of functions. Modules are imported from other modules using the import
command. Before you go ahead and import modules, check out the full list of built-in modules in the Python Standard library.

When a module is loaded into a running script for the first time, it is initialized by executing the code in the module once. If another module in your code imports the
same module again, it will not be loaded twice but once only - so local variables inside the module act as a "singleton" - they are initialized only once.

If we want to import module math, we simply import the module:

In [15]: # import the library


from math import ceil,pi

In [14]: # use it (ceiling rounding)


ceil(2.4)

Out[14]: 3

In [16]: pi

Out[16]: 3.141592653589793

In [5]: # Definition of radius


r = 0.43

# Import the math package


import math

# Calculate C
C = 2 * r * math.pi

# Calculate A
A = math.pi * r ** 2

# Build printout
print("Circumference: " + str(C))
print("Area: " + str(A))

Circumference: 2.701769682087222
Area: 0.5808804816487527
In [2]: # Definition of radius
r = 0.43
import numpy
# Import the math package
from math import pi

# Calculate C
C = 2 * r * pi

# Calculate A
A = pi * r ** 2

# Build printout
print("Circumference: " + str(C))
print("Area: " + str(A))

Circumference: 2.701769682087222
Area: 0.5808804816487527

Exploring built-in modules


While exploring modules in Python, two important functions come in handy - the dir and help functions. dir functions show which functions are implemented in each
module. Let us see the below example and understand better.

In [6]: print(dir(math))

['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'at
anh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor',
'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'l
og', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'tru
nc']

When we find the function in the module we want to use, we can read about it more using the help function, inside the Python interpreter:

In [103]: help(math.ceil)

Help on built-in function ceil in module math:

ceil(...)
ceil(x)

Return the ceiling of x as an Integral.


This is the smallest integer >= x.

Errors and Exception Handling


In this section, we will learn about Errors and Exception Handling in Python. You've might have definitely encountered errors by this point in the course. For
example:

In [104]: print('Hello)

File "<ipython-input-104-db8c9988558c>", line 1


print('Hello)
^
SyntaxError: EOL while scanning string literal
try and except
The basic terminology and syntax used to handle errors in Python is the try and except statements. The code which can cause an exception to occur is put in the
try block and the handling of the exception are the implemented in the except block of code. The syntax form is:

try:
You do your operations here...
...
except ExceptionI:
If there is ExceptionI, then execute this block.
except ExceptionII:
If there is ExceptionII, then execute this block.
...
else:
If there is no exception then execute this block.

Using just except, we can check for any exception: To understand better let's check out a sample code that opens and writes a file:

In [2]: ## except part will executed as n is not defined

## example 1
try:
if n > 5 :
print(nm)
except:
print('plz check the code')

plz check the code

In [3]: ## example 2

try:
print(x)
except:
print("An exception occurred")

An exception occurred

In [4]: ## example 3
try:
print(x)
except NameError:
print("Variable x is not defined")
except:
print("Something else went wrong")

Variable x is not defined

In [5]: ## example 4
try:
print("Hello")
except:
print("Something went wrong")
else:
print("Nothing went wrong")

Hello
Nothing went wrong
In [6]: ## example 5
## try and finally
try:
print(x)
except:
print("Something went wrong")
finally:
print("The 'try except' is finished")

Something went wrong


The 'try except' is finished

In [105]: try:
f = open('testfile','w')
f.write('Test write this')
except IOError:
# This will only check for an IOError exception and then execute this print statement
print("Error: Could not find file or read data")
else:
print("Content written successfully")
f.close()

Content written successfully

Now, let's see what happens when we don't have write permission? (opening only with 'r'):

In [106]: try:
f = open('testfile','r')
f.write('Test write this')
except IOError:
# This will only check for an IOError exception and then execute this print statement
print("Error: Could not find file or read data")
else:
print("Content written successfully")
f.close()

Error: Could not find file or read data

Notice, how we only printed a statement! The code still ran and we were able to continue doing actions and running code blocks. This is extremely useful when you
have to account for possible input errors in your code. You can be prepared for the error and keep running code, instead of your code just breaking as we saw
above.

We could have also just said except: if we weren't sure what exception would occur. For example:

In [107]: try:
f = open('testfile','r')
f.write('Test write this')
except:
# This will check for any exception and then execute this print statement
print("Error: Could not find file or read data")
else:
print("Content written successfully")
f.close()

Error: Could not find file or read data

Now, we don't actually need to memorize the list of exception types! Now what if we keep wanting to run code after the exception occurred? This is where finally
comes in.

finally
The finally: Block of code will always be run regardless if there was an exception in the try code block. The syntax is:

try:
Code block here
...
Due to any exception, this code may be skipped!
finally:
This code block would always be executed.

For example:
In [108]: try:
f = open("testfile", "w")
f.write("Test write statement")
finally:
print("Always execute finally code blocks")
Always execute finally code blocks

We can use this in conjunction with except. Let's see a new example that will take into account a user putting in the wrong input:

In [109]: def askint():


try:
val = int(input("Please enter an integer: "))
except:
print("Looks like you did not enter an integer!")

finally:
print("Finally, I executed!")
print(val)

In [110]: askint()

Please enter an integer: 2


Finally, I executed!
2

In [111]: askint()

Please enter an integer: 5


Finally, I executed!
5

Check how we got an error when trying to print val (because it was properly assigned). Let's find the right solution by asking the user and checking to make sure the
input type is an integer:

In [112]: def askint():


try:
val = int(input("Please enter an integer: "))
except:
print("Looks like you did not enter an integer!")
val = int(input("Try again-Please enter an integer: "))
finally:
print("Finally, I executed!")
print(val)

In [113]: askint()

Please enter an integer: 5


Finally, I executed!
5

Hmmm...that only did one check. How can we continually keep checking? We can use a while loop!

In [114]: def askint():


while True:
try:
val = int(input("Please enter an integer: "))
except:
print("Looks like you did not enter an integer!")
continue
else:
print('Yep thats an integer!')
break
finally:
print("Finally, I executed!")
print(val)

In [115]: askint()

Please enter an integer: 5


Yep thats an integer!
Finally, I executed!
In [116]: def square (x):
try:
if x<0:
raise ValueError('Value must not be negative. Square root of negative numbers is undefined')
return x**0.5
except TypeError :
print("x must be int or float")
except ValueError:
print("Error raised above")

In [117]: square(25)

Out[117]: 5.0

In [118]: square(25.0)

Out[118]: 5.0

In [119]: square("Hello")

x must be int or float

In [120]: square(-25)

Error raised above

Lambda Expressions, Map, and Filter


Now its time to quickly learn about two built in functions, filter and map. Once we learn about how these operate, we can learn about the lambda expression, which
will come in handy when you begin to develop your skills further!

map function
The map function allows you to "map" a function to an iterable object. That is to say you can quickly call the same function to every item in an iterable, such as a
list. For example:

In [1]: def square(num):


return num**2

In [2]: my_nums = [1,2,3,4,5]

In [5]: map(square,my_nums)

Out[5]: <map at 0x205baec21d0>

In [7]: # To get the results, either iterate through map()


# or just cast to a list
list(map(square,my_nums))

Out[7]: [1, 4, 9, 16, 25]

The functions can also be more complex

In [8]: def splicer(mystring):


if len(mystring) % 2 == 0:
return 'even'
else:
return mystring[0]

In [9]: mynames = ['John','Cindy','Sarah','Kelly','Mike']

In [10]: list(map(splicer,mynames))

Out[10]: ['even', 'C', 'S', 'K', 'even']


filter function
The filter function returns an iterator yielding those items of iterable for which function(item) is true. Meaning you need to filter by a function that returns either True
or False. Then passing that into filter (along with your iterable) and you will get back only the results that would return True when passed to the function.

In [12]: def check_even(num):


return num % 2 == 0

In [13]: nums = [0,1,2,3,4,5,6,7,8,9,10]

In [15]: filter(check_even,nums)

Out[15]: <filter at 0x205baed4710>

In [16]: list(filter(check_even,nums))

Out[16]: [0, 2, 4, 6, 8, 10]

lambda expression
One of Pythons most useful (and for beginners, confusing) tools is the lambda expression. lambda expressions allow us to create "anonymous" functions. This
basically means we can quickly make ad-hoc functions without needing to properly define a function using def.

Function objects returned by running lambda expressions work exactly the same as those created and assigned by defs. There is key difference that makes lambda
useful in specialized roles:

lambda's body is a single expression, not a block of statements.

The lambda's body is similar to what we would put in a def body's return statement. We simply type the result as an expression instead of explicitly returning it.
Because it is limited to an expression, a lambda is less general that a def. We can only squeeze design, to limit program nesting. lambda is designed for coding
simple functions, and def handles the larger tasks.

Lets slowly break down a lambda expression by deconstructing a function:

In [17]: def square(num):


result = num**2
return result

In [18]: square(2)

Out[18]: 4

We could simplify it:

In [19]: def square(num):


return num**2

In [20]: square(2)

Out[20]: 4

We could actually even write this all on one line.

In [21]: def square(num): return num**2

In [22]: square(2)

Out[22]: 4

This is the form a function that a lambda expression intends to replicate. A lambda expression can then be written as:

In [23]: lambda num: num ** 2

Out[23]: <function __main__.<lambda>>


In [25]: # You wouldn't usually assign a name to a lambda expression, this is just for demonstration!
square = lambda num: num **2

In [26]: square(2)

Out[26]: 4

So why would use this? Many function calls need a function passed in, such as map and filter. Often you only need to use the function you are passing in once, so
instead of formally defining it, you just use the lambda expression. Let's repeat some of the examples from above with a lambda expression

In [29]: list(map(lambda num: num ** 2, my_nums))

Out[29]: [1, 4, 9, 16, 25]

In [30]: list(filter(lambda n: n % 2 == 0,nums))

Out[30]: [0, 2, 4, 6, 8, 10]

Here are a few more examples, keep in mind the more comples a function is, the harder it is to translate into a lambda expression, meaning sometimes its just
easier (and often the only way) to create the def keyword function.

Lambda expression for grabbing the first character of a string:

In [31]: lambda s: s[0]

Out[31]: <function __main__.<lambda>>

Lambda expression for reversing a string:

In [32]: lambda s: s[::-1]

Out[32]: <function __main__.<lambda>>

You can even pass in multiple arguments into a lambda expression. Again, keep in mind that not every function can be translated into a lambda expression.

In [34]: lambda x,y : x + y

Out[34]: <function __main__.<lambda>>

You will find yourself using lambda expressions often with certain non-built-in libraries, for example the pandas library for data analysis works very well with lambda
expressions.

Вам также может понравиться