Introduction - The Basics of Python
Contents
Introduction - The Basics of Python¶
Python is a general purpose programming language that supports rapid development of scripts and applications.
Python’s main advantages:
Open Source software, supported by Python Software Foundation
Available on all major platforms (ie. Windows, Linux and MacOS)
It is a general-purpose programming language, designed for readability
Supports multiple programming paradigms (‘functional’, ‘object oriented’)
Very large community with a rich ecosystem of third-party packages
Interpreter¶
Python is an interpreted language* which can be used in two ways:
“Interactive” Mode: It functions like an “advanced calculator”, executing one command at a time:
user:host:~$ python
Python 3.5.1 (default, Oct 23 2015, 18:05:06)
[GCC 4.8.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 + 2
4
>>> print("Hello World")
Hello World
“Scripting” Mode: Executing a series of “commands” saved in text file, usually with a
.py
extension after the name of your file:
user:host:~$ python my_script.py
Hello World
Using interactive Python in Jupyter-style notebooks¶
A convenient and powerful way to use interactive-mode Python is via a Jupyter Notebook, or similar browser-based interface.
This particularly lends itself to data analysis since the notebook records a history of commands and shows output and graphs immediately in the browser.
There are several ways you can run a Jupyter(-style) notebook - locally installed on your computer or hosted as a service on the web. Today we will use a Jupyter notebook service provided by Google: https://colab.research.google.com (Colaboratory).
Jupyter-style notebooks: a quick tour¶
Go to https://colab.research.google.com and login with your Google account.
Select NEW NOTEBOOK → NEW PYTHON 3 NOTEBOOK - a new notebook will be created.
Type some Python code in the top cell, eg:
print("Hello Jupyter !")
Shift-Enter to run the contents of the cell
You can add new cells.
Insert → Insert Code Cell
NOTE: When the text on the left hand of the cell is: In [*]
(with an asterisk rather than a number), the cell is still running. It’s usually best to wait until one cell has finished running before running the next.
Let’s begin writing some code in our notebook.
print("Hello Jupyter !")
Hello Jupyter !
In Jupyter/Collaboratory, just typing the name of a variable in the cell prints its representation:
message = "Hello again !"
message
'Hello again !'
# A 'hash' symbol denotes a comment
# This is a comment. Anything after the 'hash' symbol on the line is ignored by the Python interpreter
print("No comment") # comment
No comment
Variables and data types¶
Integers, floats, strings¶
a = 5
a
5
type(a)
int
Adding a decimal point creates a float
b = 5.0
b
5.0
type(b)
float
int
and float
are collectively called ‘numeric’ types
(There are also other numeric types like hex
for hexidemical and complex
for complex numbers)
Challenge - Types¶
What is the type of the variable letters
defined below ?
letters = "ABACBS"
A)
int
B)
str
C)
float
D)
text
Write some code the outputs the type - paste your answer into the Etherpad.
Solution¶
Option B - str
.
letters = "ABACBS"
type(letters)
str
Strings¶
some_words = "Python3 strings are Unicode (UTF-8) ❤❤❤ 😸 蛇"
some_words
'Python3 strings are Unicode (UTF-8) ❤❤❤ 😸 蛇'
type(some_words)
str
The variable some_words
is of type str
, short for “string”. Strings hold
sequences of characters, which can be letters, numbers, punctuation
or more exotic forms of text (even emoji!).
Operators¶
We can perform mathematical calculations in Python using the basic operators:
+
-
*
/
%
**
2 + 2 # Addition
4
6 * 7 # Multiplication
42
2 ** 16 # Power
65536
13 % 5 # Modulo
3
# int + int = int
a = 5
a + 1
6
# float + int = float
b = 5.0
b + 1
6.0
a + b
10.0
some_words = "I'm a string"
a = 6
a + some_words
Outputs:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-781eba7cf148> in <module>()
1 some_words = "I'm a string"
2 a = 6
----> 3 a + some_words
TypeError: unsupported operand type(s) for +: 'int' and 'str'
str(a) + " " + some_words
'5 Python3 strings are Unicode (UTF-8) ❤❤❤ 😸 蛇'
# Shorthand: operators with assignment
a += 1
a
# Equivalent to:
# a = a + 1
6
Boolean operations¶
We can also use comparison and logic operators:
<, >, ==, !=, <=, >=
and statements of identity such as
and, or, not
. The data type returned by this is
called a boolean.
3 > 4
False
True and True
True
True or False
True
Lists and sequence types¶
Lists¶
numbers = [2, 4, 6, 8, 10]
numbers
[2, 4, 6, 8, 10]
# `len` get the length of a list
len(numbers)
5
# Lists can contain multiple data types, including other lists
mixed_list = ["asdf", 2, 3.142, numbers, ['a','b','c']]
mixed_list
['asdf', 2, 3.142, [2, 4, 6, 8, 10], ['a', 'b', 'c']]
You can retrieve items from a list by their index. In Python, the first item has an index of 0 (zero).
numbers[0]
2
numbers[3]
8
You can also assign a new value to any position in the list.
numbers[3] = numbers[3] * 100
numbers
[2, 4, 6, 800, 10]
You can append items to the end of the list.
numbers.append(12)
numbers
[2, 4, 6, 800, 10, 12]
You can add multiple items to the end of a list with extend
.
numbers.extend([14, 16, 18])
numbers
[2, 4, 6, 800, 10, 12, 14, 16, 18]
Loops¶
A for loop can be used to access the elements in a list or other Python data structure one at a time. We will learn about loops in other lesson.
for num in numbers:
print(num)
2
4
6
800
10
12
14
16
18
Indentation is very important in Python. Note that the second line in the example above is indented, indicating the code that is the body of the loop.
To find out what methods are available for an object, we can use the built-in help
command:
help(numbers)
Help on list object:
class list(object)
| list(iterable=(), /)
|
| Built-in mutable sequence.
|
| If no argument is given, the constructor creates a new empty list.
| The argument must be an iterable if specified.
|
| Methods defined here:
|
| __add__(self, value, /)
| Return self+value.
|
| __contains__(self, key, /)
| Return key in self.
|
| __delitem__(self, key, /)
| Delete self[key].
|
| __eq__(self, value, /)
| Return self==value.
|
| __ge__(self, value, /)
| Return self>=value.
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __getitem__(...)
| x.__getitem__(y) <==> x[y]
|
| __gt__(self, value, /)
| Return self>value.
|
| __iadd__(self, value, /)
| Implement self+=value.
|
| __imul__(self, value, /)
| Implement self*=value.
|
| __init__(self, /, *args, **kwargs)
| Initialize self. See help(type(self)) for accurate signature.
|
| __iter__(self, /)
| Implement iter(self).
|
| __le__(self, value, /)
| Return self<=value.
|
| __len__(self, /)
| Return len(self).
|
| __lt__(self, value, /)
| Return self<value.
|
| __mul__(self, value, /)
| Return self*value.
|
| __ne__(self, value, /)
| Return self!=value.
|
| __repr__(self, /)
| Return repr(self).
|
| __reversed__(self, /)
| Return a reverse iterator over the list.
|
| __rmul__(self, value, /)
| Return value*self.
|
| __setitem__(self, key, value, /)
| Set self[key] to value.
|
| __sizeof__(self, /)
| Return the size of the list in memory, in bytes.
|
| append(self, object, /)
| Append object to the end of the list.
|
| clear(self, /)
| Remove all items from list.
|
| copy(self, /)
| Return a shallow copy of the list.
|
| count(self, value, /)
| Return number of occurrences of value.
|
| extend(self, iterable, /)
| Extend list by appending elements from the iterable.
|
| index(self, value, start=0, stop=9223372036854775807, /)
| Return first index of value.
|
| Raises ValueError if the value is not present.
|
| insert(self, index, object, /)
| Insert object before index.
|
| pop(self, index=-1, /)
| Remove and return item at index (default last).
|
| Raises IndexError if list is empty or index is out of range.
|
| remove(self, value, /)
| Remove first occurrence of value.
|
| Raises ValueError if the value is not present.
|
| reverse(self, /)
| Reverse *IN PLACE*.
|
| sort(self, /, *, key=None, reverse=False)
| Sort the list in ascending order and return None.
|
| The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
| order of two equal elements is maintained).
|
| If a key function is given, apply it once to each list item and sort them,
| ascending or descending, according to their function values.
|
| The reverse flag can be set to sort in descending order.
|
| ----------------------------------------------------------------------
| Static methods defined here:
|
| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| ----------------------------------------------------------------------
| Data and other attributes defined here:
|
| __hash__ = None
Tuples¶
A tuple is similar to a list in that it’s an ordered sequence of elements.
However, tuples can not be changed once created (they are “immutable”). Tuples
are created by placing comma-separated values inside parentheses ()
.
tuples_are_immutable = ("bar", 100, 200, "foo")
tuples_are_immutable
('bar', 100, 200, 'foo')
tuples_are_immutable[1]
100
tuples_are_immutable[1] = 666
Outputs:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-39-c91965b0815a> in <module>()
----> 1 tuples_are_immutable[1] = 666
TypeError: 'tuple' object does not support item assignment
Dictionaries¶
Dictionaries are a container that store key-value pairs. They are unordered.
Other programming languages might call this a ‘hash’, ‘hashtable’ or ‘hashmap’.
pairs = {'Apple': 1, 'Orange': 2, 'Pear': 4}
pairs
{'Apple': 1, 'Orange': 2, 'Pear': 4}
pairs['Orange']
2
pairs['Orange'] = 16
pairs
{'Apple': 1, 'Orange': 16, 'Pear': 4}
The items
method returns a sequence of the key-value pairs as tuples.
values
returns a sequence of just the values.
keys
returns a sequence of just the keys.
In Python 3, the .items()
, .values()
and .keys()
methods return a ‘dictionary view’ object that behaves like a list or tuple in for loops but doesn’t support indexing. ‘Dictionary views’ stay in sync even when the dictionary changes.
You can turn them into a normal list or tuple with the list()
or tuple()
functions.
pairs.items()
# list(pairs.items())
dict_items([('Apple', 1), ('Orange', 16), ('Pear', 4)])
pairs.values()
# list(pairs.values())
dict_values([1, 16, 4])
pairs.keys()
# list(pairs.keys())
dict_keys(['Apple', 'Orange', 'Pear'])
len(pairs)
3
dict_of_dicts = {'first': {1:2, 2: 4, 4: 8, 8: 16}, 'second': {'a': 2.2, 'b': 4.4}}
dict_of_dicts
{'first': {1: 2, 2: 4, 4: 8, 8: 16}, 'second': {'a': 2.2, 'b': 4.4}}
Challenge - Dictionaries¶
Given the dictionary:
jam_ratings = {'Plum': 6, 'Apricot': 2, 'Strawberry': 8}
How would you change the value associated with the key Apricot
to 9
.
A) jam_ratings = {'apricot': 9}
B) jam_ratings[9] = 'Apricot'
C) jam_ratings['Apricot'] = 9
D) jam_ratings[2] = 'Apricot'
Solution - Dictionaries¶
The correct answer is C.
A assigns the name jam_ratings
to a new dictionary with only the key apricot
- not only are the other jam ratings now missing, but strings used as dictionary keys are case sensitive - apricot
is not the same key as Apricot
.
B mixes up the value and the key. Assigning to a dictionary uses the form: dictionary[key] = value
.
C is correct. Bonus - another way to do this would be jam_ratings.update({'Apricot': 9})
or even jam_ratings.update(Apricot=9)
.
D mixes up the value and the key (and doesn’t actually include the new value to be assigned, 9
, anywhere). 2
is the original value, Apricot
is the key. Assigning to a dictionary uses the form: dictionary[key] = value
.