Real Python Learning Notes
Table of Contents
- Onboarding Course
- Introduction to Python 3
- Installing Python
- Interacting with Python
- 11 Beginner Tips for Learning Python
- Basic Data Types in Python
- Variables in Python: Overview
- Operators and Expressions in Python
All courses below are on https://realpython.com. All notes taken and compiled by Aleks Ozolins.
Onboarding Course
Content Types on realpython.com
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 realpython.com
- 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
macOS
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.
Methods
Python methods are important. You can list out the methods available on a string a
like this.
a = 'hello there' print(dir(a))
Ignore the methods with double underscores
For instance, using the upper
method:
a = 'hello there' print(a.upper())
HELLO THERE
Let's see what methods are available to integers
print(dir(int))
Use The Help Command
From within the REPL display help for integers:
help(int)
Get help on the print
function:
help(print)
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}') else: print(f'Sorry, the number was {number}, not {guess}')
Surround Yourself With Others Who Are Learning
- Local events / meetups
- http://www.pythonistacafe.com
- Pycon (annual Mecca) - there are also local variants
- Imposter Syndrome - don't let it bring you down
Teach
- 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 http://www.github.com/topics/python
- Important for learning the appropriate etiquette
- Contribute to documentation
- Look for appropriate projects
Basic Data Types in Python
Overview
- Integers
- Floating-Point Numbers
- Complex Numbers
- Strings
- Booleans
- Built-in Functions
Integers
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) print(a + b)
1 11
Defining a number from a binary value and then printing as base 10:
a = 0b101010111 print(a)
343
Defining a number from an octal:
a = 0o454312 print(a)
153802
" hexidecimal:
a = 0xac4d print(a)
44109
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 print(type(a))
<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 print(c) print(type(c))
2.0 <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 print(a)
4000.0
Sometimes floating point calculations do not work exactly as planned:
a = 0.2 b = 0.1 c = a + b print(c)
0.30000000000000004
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 print(a) print(type(a))
(2+3j) <class 'complex'>
Note: I don't really know what complex numbers are! I should figure this out!
Strings
- 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.' print(a)
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!" print(a) print(b)
One Line Two! 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") return my_function('hello')
hello is a nice value
Booleans
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 print(type(a))
<class 'bool'>
Objects can be evaluated using the bool
function.
a = 1 print(bool(a)) b = 0 print(bool(b))
True False
Truthiness
Equations can be evaluated and the result will be a boolean.
a = 5 print(a == 5)
True
b = 1 if b: # this is the same as saying, "if b is True..." print('b is true') else: 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] print(a[0]) print(a[-1])
1 6
- You can also use slicing to include a range:
a = [1, 2, 3, 4, 5] print(a[1:3])
[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
- Lists are defined as
- 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.
- A tuple is similar to a list but is defined using parens instead:
- Set
Sets are similar to lists but can only contain unique values:
a = [1, 2, 3, 3, 3, 3, 4, 5] b = set(a) print(a) print(b)
[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) print(a) print(b) c = list(b) print(c)
[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'} 41 None
In this case, both keys are strings, while the value for 'name' is a string and the value for 'age' is an int.
Math
- abs
The absolute value function basically takes the sign away from the number.
a = 5 b = -5 print(abs(a)) print(abs(b))
5 5
- Modulo
Modulo gives the remainder:
a = 15 % 4 print(a)
3
- divmod
Divmod will show us how many times a number goes into another, and the remainder as well:
a = divmod(15, 4) print(a)
(3, 3)
- max
Max will provide the maximum of an iterable:
print(max(1, 2, 3, 4, 5))
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))
9
- round
Rounds a number to the nearest integer.
print(round(4.6)) print(int(4.6))
5 4
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
15 25
Type Conversion
- ascii
Shows the ascii equiv of a string:
print(ascii('hello')) print(ascii('はい')) # In this case, unicode characters were used, so escape characters are shiws with the ascii equiv.
'hello' '\u306f\u3044'
- 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.
print(chr(97)) print(chr(34)) print(chr(0x06a4))
a " ڤ
Note: - Ascii codes are the same as unicode below 128.
- ord
Will give you the ascii or unicode code for a character:
print(ord('a'))
97
- 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] print(len(a))
6
- any and all
Returns a boolean showing if
any
of the values were true ofall
of the values were true.a = [True, True, True] b = [True, False, True] c = [False, False, False] print(any(a)) print(any(b)) print(any(c)) print(all(a)) print(all(b)) print(all(c))
True True False True 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] print(reversed(a)) print(list(reversed(a)))
<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] print(sorted(a))
[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])) print(merged) # There's a much simpler way to do this using zip: merged_2 = zip(countries, continents) print(list(merged_2))
[('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]) print(next(a)) print(next(a)) print(next(a)) print(next(a)) print(next(a)) print(next(a))
1 2 3 4 5 6
If I were to have run
next
again, you'd get aStopIteration
exception.
Input/Output
- 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=' ') print()
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') file.close()
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 file.close()
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' print(dir(a))
['__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
andlocal
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) function() 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.
Misc
- 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: ') exec(job)
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 anyint
will be the value of thatint
print(hash(123))
123
The story is somewhat different for text:
print(hash('Hello World'))
1465864162751722754
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
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 print(n) print(id(n))
300 140396967598928
The last result here tells us where in memory this object lives.
n = 300 m = 300 print(id(n)) print(id(m))
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))
True True
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.
PEP-8
- Python Enhancement Proposal #8
- https://peps.python.org/pep-0008/
- This is the latest style guide for Python
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() 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'] False