Real Python Learning Notes

Table of Contents

All courses below are on All notes taken and compiled by Aleks Ozolins.

Onboarding Course

Content Types on

Video Tutorials

  • Can be found under the "Learn Python" menu under "Python Tutorials"

Text Based Tutorials

  • Sometimes have downloadable guides you can keep
  • For code blocks you can strip out the REPL stuff with the button in the upper right

Interactive Quizzes

  • Woven into courses and text based tutorials
  • They will show up in the content via links or you can access directly via the Learn Python button.

Finding Things on

  • Can always use the search box in upper right
  • Searches return by relevance. Most relevant at the top.

Learning Paths

  • Kind of like playlists
  • A complete study plan
  • Walks you through all different types of content on a particular topic
  • Start with Introduction to Python Learning Path
  • A single path might take a few days to weeks

Browsing Tutorials By Topic

  • Topics will be tagged in a box in the upper right
  • You can browse courses by topic as well
  • Learn Python menu and click Browse Topics

Where to Start

  • Start with a learning path
  • I'm going to start with Introduction to Python

Your Python Gym

  • Real Python is a Gym for Python devs
  • There will always be new and up to date material
  • Click on the Real Python logo in the upper left and this will show the new media on the site.

The Real Python Slack Community

  • Private Slack Community (Click on Avatar and then Slack Community)
  • Say hi in the Introductions channel
  • There is a #coding-questions channel
  • If you don't know where to post, ask in #hangouts
  • Join #coffee-lottery channel - this is like donut chats.

Tutorial and Lesson Comments

  • You can comment on any tutorial or lesson
  • Take a look at these and feel free to join the conversation
  • You can include code snippets in your comments
  • Comments section supports markdown!

How to Learn Effectively

  • Combine videos, written tutorials, and quizzes
  • D a deep-dive on one topic once in a while

Make forward progress every day

  • Make Real Python a Habit

Review what you've learned

  • Interactive quizzes
  • Bookmark stuff you want to revisit

Teach Others

  • Give a workshop/presentation to your team / coworkers, etc.
  • Help out other Pythonistas in the community
  • Write your own blog post

Introduction to Python 3

  • Developed by Guido van Rossum
  • Interpreted (rather than a compiled) language

Installing Python


Using homebrew, install the following packages:

  • python
  • python-tk (this is for idle, executed with idle3)

pip should be included (pip3)

Arch Linux

Using Pacman, install the following packages:

  • python
  • python-pip (pip3)
  • tk (for idle executed with idle3)

Interacting with Python

Several ways to execute code

  • Using the REPL (Read-Eval-Print-Loop)
  • Running a script from the command line
  • Work within a Python IDE

Using the REPL

  • Start it by typing python3 at the command prompt.
  • In Linux or macOS you can exit the REPL by pressing ctrl+d

Running a script from the command line

  • A script file is not required to have a .py extension
  • Might look into setting up a desktop association so clicking file will run with the interpreter.

Interacting with Python through an IDE

Good things to have in an IDE

  • Syntax Highlighting
  • Context-sensitive help
  • Code-completion
  • Debugging

IDLE is a rudimentary IDE. It stands for Integrated Development and Learning Environment.

  • To start IDLE type idle3
  • IDLE provides syntax highlighting and context-sensitive help
  • You can start a new file in IDLE and run it with Run > Run Module

11 Beginner Tips for Learning Python

Code Every Day

  • Little and often is better than one large chunk once a week
  • Set a timetable
  • Be realistic about the time you have for this
  • Solve small problems as time allows

Write It Out

  • Write out notes helps you to retain information
  • Planning for programs with written notes can help make the solution clearer
  • Try working with paper and pencil once in a while

Go Interactive

  • Use the REPL.


Python methods are important. You can list out the methods available on a string a like this.

a = 'hello there'

Ignore the methods with double underscores

For instance, using the upper method:

a = 'hello there'


Let's see what methods are available to integers


Use The Help Command

From within the REPL display help for integers:


Get help on the print function:


Take Breaks

  • Pomodoro technique. Set a 25 minute timer to work and then break for 5 minutes. (you can adjust this)
  • Timetable breaks into your schedule
  • Sleep is important for memory formation
  • Fresh eyes spot 'obvious' errors

Become a Bug Bounty Hunter

  • Be methodical
  • Make use of print() to check work along the way
  • Make use of pdb (the python debugger)

pdb (the python debugger)

import random
import pdb
print ('Guess a number between 1 and 10')
number = random.randint(1, 10)
guess = int(input())
pdb.set_trace()                # pdb will take over from here
if guess == number:
    print(f'Correct - the number was {number}')
    print(f'Sorry, the number was {number}, not {guess}')

  • pdb commands
    • l list out the program and show what line you are on
    • You can type variable names directly to show their value and it will indicate whether it's a 'string' or an integer.
    • c continues the program

    You can move the trace command anywhere you'd like in the program.

Surround Yourself With Others Who Are Learning

  • Local events / meetups
  • Pycon (annual Mecca) - there are also local variants
  • Imposter Syndrome - don't let it bring you down


  • A great way to cement understanding
  • Set up your own programming blog (Field and answer questions from readers)

Pair Program

  • Switch between 'driver' and 'navigator' roles. Driver programs, navigator steers.
  • See how others solve problems and program in real time

Ask 'Good' Questions

  • Use Stack Overflow
  • (G) Give context
  • (O) Outline the things you have already tried to fix the issue
  • (O) Offer a best guess as to what the problem might be
  • (D) Demo what is happening. Include the code, error messages, etc

A lot of times, if you ask a "GOOD" question, the answer will reveal itself.

Build Something, Anything

  • What you build is less imporant than actually building it!
  • Gets you in the habit of starting and finishing a project
  • Learn as much as possible in practice and avoid glossing over difficult areas

Contribue To Open Source

  • Many thousands of Python-based open source projects
  • Take a look at them on GitHub at
  • Important for learning the appropriate etiquette
  • Contribute to documentation
  • Look for appropriate projects

Basic Data Types in Python


  • Integers
  • Floating-Point Numbers
  • Complex Numbers
  • Strings
  • Booleans
  • Built-in Functions


An integer is a:

  • Whole number
  • Any length allowed up to memory limit
  • Default is decimal (base 10)

You can set an integer to a variable like this:

a = 1
b = 10
print(a + b)


Defining a number from a binary value and then printing as base 10:

a = 0b101010111


Defining a number from an octal:

a = 0o454312


" hexidecimal:

a = 0xac4d


If a variable is defined as a string as in a = '12345'=, you'll need to convert it to an integer first to perform an integer operation (like arithmetic) on it.

Use int(a) to convert the value first.

You can inspect the type of any variable with the type() function:

a = 1000

<type 'int'>
  • to convert a value to binary use bin()
  • to concert a value to octal use oct()
  • to convert a value to hexadecimal use hex()

Floating-Point Numbers

  • Any number with a decimal point is a floating-point number
  • Division result will be a float
  • Can be defined using scientific notation (4x103 = 4000)

If you create a variable with a decimal point as in a = 4.2. the type will be float even if it is 4.0.

Again, the result of division will always be a float even if the answer could be an int.

a = 5
b = 10
c = b / a

<class 'float'>

Use the integer division operator // instead for integer division. (It rounds) … or leaves out the remainder.

You can make any number into a float with the float() function.

Using scientific notation will always result in a float:

a = 4e3


Sometimes floating point calculations do not work exactly as planned:

a = 0.2
b = 0.1
c = a + b


Complex Numbers

  • expressed in the form of ax + bj
  • Consist of 'real' and 'imaginary' part
  • j is the square root of -1
a = 2+3j

<class 'complex'>

Note: I don't really know what complex numbers are! I should figure this out!


  • A sequence of zero or more characters
  • Can be enclosed in single or double quotes
  • Formats raw and triple-quoted strings

Define a string

a = "hello world" or a = 'hello world'

These will always be printed with the single quote variant.

If your string includes a single quote, you need to surround it with double quotes as in "he's there". Vice-versa… String with double quotes inside will need to be defined with single quotes.

The type is <class 'str'>

Escape Sequences

If you need to have both single and double quotes inside a string, you'll need to use an escape character:

'He said "I wasn\'t at school today" to me'

The value of the variabe includes the escape character, but when printing the value, the escape character will not be shown.

\n is also an escape sequence meaning "new line".

a = 'This is line 1.\nThis is line 2.'

This is line 1.
This is line 2.

Tab characters = \t

Escape Characters

  • \' - Single Quote
  • \" - Double Quote
  • \\ - Backslash
  • \n - Newline
  • \r - Carriage Return
  • \t - Tab
  • \b - Backspace
  • \f - Form Feed
  • \v - Vertical Tab
  • \onn - Character with octal value nn
  • \xnn - Character with hex value nn

Raw Strings

In a raw string, escape sequence characters are not interpreted.

You create them by prepending r to the value before the quotes.

a = "One Line\nTwo!"
b = r"One Line/nTwo!"

One Line
One Line/nTwo!

Might need to use these for regex.

Triple Quoted Strings

It's possible to put any type of quote inside without issue.

print("""This is 'a' "triple-quoted" string""")

This is 'a' "triple-quoted" string

Their main use is to allow strings which cover multiple lines:

print('''Hey, we're going to try multiple lines here...
by doing this...
and this...
and this...''')

Hey, we're going to try multiple lines here...
by doing this...
and this...
and this...

The most common use however, is providing doc strings for functions. When you use the function, the doc string will come up as a tool tup to tell you what the function does.

def my_function(value):
    """Takes a value and prints it to the screen."""
    print(f"{value} is a nice value")


hello is a nice value


A boolean is a variable which can take 2 values. In python False is equivalent to 0, True is equivalent to an non-zero number.

Objects have "truthiness" in Python and making use of this vcan make for more readable code.

a = True

<class 'bool'>

Objects can be evaluated using the bool function.

a = 1
b = 0



Equations can be evaluated and the result will be a boolean.

a = 5
print(a == 5)
b = 1
if b:                      # this is the same as saying, "if b is True..."
    print('b is true')
    print('b is false') 

b is true
  • An empty list b = [] is False
  • An empty dictionary b = {} is also False
  • This however is true (it's not empty) b = [0]

Built-In Functions

Composite Data Types

  • List
    • Lists are defined as a = [1, 2, 3, 4, 5]
    • Lists are 0 indexed meaning the first result is represented by 0.
    • You can also use negative indexing to get a value from the back of the list.
    a = [1, 2, 3, 4, 5, 6]
    • You can also use slicing to include a range:
    a = [1, 2, 3, 4, 5]
    [2, 3]

    Note above that what was printed is in between the indexes given. The value of position 3 was not included.

    You can change a specific value in a list with a[2] = 6

  • Tuple
    • A tuple is similar to a list but is defined using parens instead: a = (1, 2, 3, 4, 5)
    • Similarly, it is 0 indexed like lists.

    You cannot reassign values when using a tuple:

    a = (1, 2, 3, 4, 5)
    a[2] = 6   # This will not work and will result in the error 'tuple' object does not support item assigmnent

    Therefore, tuples are immutable.

  • Set

    Sets are similar to lists but can only contain unique values:

    a = [1, 2, 3, 3, 3, 3, 4, 5]
    b = set(a)
    [1, 2, 3, 3, 3, 3, 4, 5]
    {1, 2, 3, 4, 5}

    You can create a list from a set so you can act upon it in the normal way:

    a = [1, 2, 3, 3, 3, 3, 4, 5]
    b = set(a)
    c = list(b)
    [1, 2, 3, 3, 3, 3, 4, 5]      # this is a list
    {1, 2, 3, 4, 5}               # this is a set
    [1, 2, 3, 4, 5]               # this is a list again
  • Dict or Dictionary
    • Best thought of as a lookup table which allows you to store values in it with key/value pairs
    a = dict()                 # an empty dictionary is created
    # Key value pairs are assigned
    a['name'] = 'Aleks'
    a['age'] = '41'
    print(a)                   # print the entire contents of the dict
    print(a['age'])            # print only the value of 'age'
    print(a.get('country'))    # You can use the get method and it won't throw an error if a key isn'r present
    {'name': 'Aleks', 'age': '41'}

    In this case, both keys are strings, while the value for 'name' is a string and the value for 'age' is an int.


  • abs

    The absolute value function basically takes the sign away from the number.

    a = 5
    b = -5
  • Modulo

    Modulo gives the remainder:

    a = 15 % 4
  • divmod

    Divmod will show us how many times a number goes into another, and the remainder as well:

    a = divmod(15, 4)
    (3, 3)
  • max

    Max will provide the maximum of an iterable:

    print(max(1, 2, 3, 4, 5))
  • min

    Min will provide the minimum of an iterable.

  • pow

    Can take 2 arguments or 3. When given 3, the third has something to do with the modulo.

    print(pow(3, 2))
  • round

    Rounds a number to the nearest integer.


    Note that 4.5 is rounded down. Int will always just take the decimal away - Not the same as rounding.

  • sum

    Sums the iterables which are passed.

    print(sum([1, 2, 3, 4, 5]))
    print(sum([1, 2, 3, 4, 5], 10))     # In this case, an optional "start value" was provided

Type Conversion

  • ascii

    Shows the ascii equiv of a string:

    print(ascii('はい'))     # In this case, unicode characters were used, so escape characters are shiws with the ascii equiv.
  • chr

    Returns a unicode string of one character with ordinal. You can look up these values on an ascii able. There are 128 values in the ascii alphabet. Chr also works for unicode characters.


    Note: - Ascii codes are the same as unicode below 128.

  • ord

    Will give you the ascii or unicode code for a character:

  • type

    Will give the type of the object like string, int, float, bool, list, etc.

Iterables and Iterators

These are functions you can use with iterables and iterators.

  • len
    a = [1, 4, 6, 3, 5, 2]
  • any and all

    Returns a boolean showing if any of the values were true of all of the values were true.

    a = [True, True, True]
    b = [True, False, True]
    c = [False, False, False]
  • reversed

    Gives an iterator object that represents the reverse of the object you're working with.

    a = [1, 4, 3, 4, 2, 5, 4, 3]
    <list_reverseiterator object at 0x7f9857363f70>
    [3, 4, 5, 2, 4, 3, 4, 1]

    Note that we had to use the list function here to actually see the values. You won't always have to do this in your code because Python will often deal with the iterator.

  • sorted

    Produces a sorted list

    a = [4, 2, 6, 1, 2, 9, 3]
    [1, 2, 2, 3, 4, 6, 9]
  • range

    Gives us the range:

    • If a single number is provided, it will give the range between 0 and that number. The number itself will not be included.
    • If two numbers are provided, it will give the range between those numbers.
    • If a third argument is provided, it will use that as the stride.
    print(list(range(10, 50, 5)))
    [10, 15, 20, 25, 30, 35, 40, 45]
  • enumerate

    Displays a counter in a loop (I think):

    players = ['Mike','Bob','Sarah','Charlie','Jo']
    for count, player in enumerate(players):
        print(count, player)
    0 Mike
    1 Bob
    2 Sarah
    3 Charlie
    4 Jo

    So, with enumerate, we don't have to increment a counter each time a loop is run.

  • zip
    countries = ['France','Tanzania','Cabada']
    continents = ['Europe','Africa','North America']
    merged = []
    for i in range(len(countries)):
        merged.append((countries[i], continents[i]))
    # There's a much simpler way to do this using zip:
    merged_2 = zip(countries, continents)
    [('France', 'Europe'), ('Tanzania', 'Africa'), ('Cabada', 'North America')]
    [('France', 'Europe'), ('Tanzania', 'Africa'), ('Cabada', 'North America')]
  • iter and next

    It's possible to create an iterator using any iterable. next is a method which pops the next value off that iterator until it's exhausted.

    a = iter([1, 2, 3, 4, 5, 6])

    If I were to have run next again, you'd get a StopIteration exception.


  • print
    • end defaults to the new line character \n

    In the code below, we're changing end to a space instead so each number is not printed on a new line. We add another print statement at the end just to get the prompt back to the next line.

    for i in range(100):
        print(i, end=' ')
    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 
  • open

    Here, we open a file and write to it:

    file = open('test.txt, 'w')    # opens test.txt in write mode
    file.write('Hello World!\n')

    Here, we read from a file:

    file = open('test.txt'. 'r')     # opens test.txt in read mode
    print(file.readlines())          # print contents of file as list

Variables, References and Scope

  • dir
    • Allows you to see all of the attributes and methods that any Python has.
    • Allows you to see what you can do with any object basically.
    a = 'hello'
    ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

    The double underscores are dunder methods. We won't have to worry about them for now.

  • vars and globals

    So below, we've set the value of variables, defined a function which re-defines those variables, and then we're printing directly, and via the function to illustrate the difference between global and local scopes.

    a = 1
    b = 'global'
    c = 'another global'
    def function():
        a = 2
        b = 'local'
        print(a, b)
        print(vars()) # prints all the variables available within the scope in a dict.
        print(c) # prints the value of c from the global scope since it can't find it from the local scope.
    print(a, b)
    print(a ,b)
    1 global
    2 local
    {'a': 2, 'b': 'local'}
    another global
    1 global

    print(globals()) will give the list of global vars within any scope.


  • exec
    • Allows you to execute any Python code.
    import os     # gives you access to info about the computer/os
    job = input('Tell me a task to do: ')

    The program above will prompt you for input and allow you to execute any Python command.

    The problem here is that, because we've imported the os module, you can run any code on the computer and fry it - os.system('rm -rf *.*')

  • eval
    • Allows you to evaluate the value of a Python function.
    calc = input('Give me some maths to do: ')
    print(eval(calc))     # work out calc, and then give me the value of it.

    Again, if you've imported os, you'll have access to the system in this case.

    Using print(eval(calc, {})) instead, means no named functions will be accepted and the exploit above won't be available.

    You can specify a function explicitly to allow, print(eval(calc, {'pow': pow})) for intance.

  • hash
    • One way function that gives a summary of the function it has been passed.

    The hash of any int will be the value of that int


    The story is somewhat different for text:

    print(hash('Hello World'))

    If you have two pieces of text that are somewhat similar, you'll be able to tell them apart better by comparing the hashes instead.

    You can compare an entire book that differs in one character easily using hashes.

Variables in Python: Overview

Variable Assignment

Standard Variable Assignment

  • n = 300 That's it. That's a variable assignment in Python
  • You can change a variable on the fly.
  • Can change a variable that was an int to a string - no problem.

Chained Variable Assignment

  • n = m = x = y = 400
  • Now, all of those variable names point to the value 400
  • Multiple Assignment
    • a, b = 300, 400
    • Use commas to separate
  • Variable Types
    • int, string, etc.
    • You can check the type with type(n)
    • Variables are simply references to objects. Everything in Python is an object.

Object References

  • Everything is an Object
    • When you create a string, it's an object
    • A function is also an object
  • Variables are References
    • When you assign a value to a varibale, you're giving a reference to an object.
  • Orphaned Objects

    When all the references to an object have been changed or reassigned, the object becomes an orphaned object.

    Python does what is called Garbage Collection in this case. The orphaned object is flushed from memory.

Object Identity

Object Value vs. Object Identity

  • The value of a variable is what you get when you print it to the screen.
  • To get an object's identity, run id on it.
n = 300


The last result here tells us where in memory this object lives.

n = 300
m = 300

If you evaluate the above in the REPL, you'll get different ids even though the objects have the same integer value.

id(n) == ~id(m) is False

Small Integer Caching

a = 30
b = 30
print(a == b)
print(id(a) == id(b))

Why is this happening? We just learned that the ids for 2 objects, even if they have the same value would be different.

This happens with small integers - anything between -5 and 256.

When the object is a small integer, in any Python session, those objects are already pre-created so they exist in a single place in memory.

Variable Names

Naming Conventions

  • Variable names can be any length
  • Upper and lowercase characters; case sensitive
  • The normal convention is that UPPERCASE variables should refer to constants: things that don't change.
  • The normal convention for standard variables is to use underscores and lowercase characters. This is snake_case
  • You can use digits, but not at the beginning. video3 = 'yes' is ok.
  • You can use unicode characters in python3. voilà = "France" is ok.


Reserved Keywords

These are words that you can't use as variable names in Python.

  • We of course can't use an integer or name starting with an integer.
  • We can't use certain keywords for a variable name such as for
  • help("keywords") will return a list of these keywords we can't use.

You can also import the keyword module and return the list:

import keyword
print(keyword.kwlist)              # list out all keywords
print(keyword.iskeyword("Horse"))   # Check if Horse is a keyword

['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', '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']


Operators and Expressions in Python

Date: 2024-02-03 Sat 09:55

Emacs 29.3 (Org mode 9.6.15)