Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
The instructions and text in this tutorial (the "software") are licensed
under the zlib License.

(C) 2016-2018 Akuli
(C) 2016-2021 Akuli

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
Expand Down
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Python programming tutorial
# Python programming tutorial for beginners

This is a concise Python 3 programming tutorial for people who think
that reading is boring. I try to show everything with simple code
Expand All @@ -12,14 +12,8 @@ or very little programming experience. If you have programmed a lot in
the past using some other language you may want to read [the official
tutorial](https://docs.python.org/3/tutorial/) instead.

You can use Python 3.3 or any newer Python with this tutorial. **Don't
use Python 2.** If you write a Python 2 program now someone will need to
convert it to Python 3 later, so it's best to just write Python 3 to
begin with. Python 3 code will work just fine in Python 4, so you don't
need to worry about that. Python 2 also has horrible
[Unicode](http://www.unicode.org/standard/WhatIsUnicode.html) problems,
so it's difficult to write Python 2 code that works correctly with
non-English characters (like π and ♫).
You can use Python 3.5 or any newer Python with this tutorial. **Don't
use Python 2 because it's no longer supported.**

## List of contents

Expand Down Expand Up @@ -59,7 +53,7 @@ section. Most of the techniques explained here are great when you're
working on a large project, and your code would be really repetitive
without these things.

You can experient with these things freely, but please **don't use these
You can experiment with these things freely, but please **don't use these
techniques just because you know how to use them.** Prefer the simple
techniques from the Basics part instead when possible. Simple is better
than complex.
Expand Down Expand Up @@ -110,11 +104,8 @@ pull with git and run `make-html.py` again.

## Authors

I'm Akuli and I have written most of this tutorial, but these people
have helped me with it:
- [SpiritualForest](https://github.com/SpiritualForest): Lots of typing
error fixes.
- [theelous3](https://github.com/theelous3): Small improvements and fixes.
I'm Akuli and I have written most of this tutorial, but other people have helped me with it.
See [github's contributors page](https://github.com/Akuli/python-tutorial/graphs/contributors) for details.

***

Expand Down
67 changes: 12 additions & 55 deletions advanced/datatypes.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,68 +316,25 @@ TypeError: unsupported operand type(s) for +: 'dict' and 'dict'
>>>
```

Dictionaries have an `update` method that adds everything from another
dictionary into it. So we can merge dictionaries like this:
Usually it's easiest to do this:

```python
>>> merged = {}
>>> merged.update({'a': 1, 'b': 2})
>>> merged.update({'c': 3})
>>> merged
{'c': 3, 'b': 2, 'a': 1}
>>>
```

Or we can [write a function](../basics/defining-functions.md) like this:

```python
>>> def merge_dicts(dictlist):
... result = {}
... for dictionary in dictlist:
... result.update(dictionary)
... return result
...
>>> merge_dicts([{'a': 1, 'b': 2}, {'c': 3}])
{'c': 3, 'b': 2, 'a': 1}
>>>
>>> dict1 = {'a': 1, 'b': 2}
>>> dict2 = {'c': 3}
>>> {**dict1, **dict2}
{'a': 1, 'b': 2, 'c': 3}
```

Kind of like counting things, merging dictionaries is also a commonly
needed thing and there's a class just for it in the `collections`
module. It's called ChainMap:
Dictionaries also have an `update` method that adds everything from another
dictionary into it, and you can use that too. This was the most common way to
do it before Python supported `{**dict1, **dict2}`.

```python
>>> import collections
>>> merged = collections.ChainMap({'a': 1, 'b': 2}, {'c': 3})
>>> merged = {}
>>> merged.update({'a': 1, 'b': 2})
>>> merged.update({'c': 3})
>>> merged
ChainMap({'b': 2, 'a': 1}, {'c': 3})
>>>
```

Our `merged` is kind of like the Counter object we created earlier. It's
not a dictionary, but it behaves like a dictionary.

```python
>>> for key, value in merged.items():
... print(key, value)
...
c 3
b 2
a 1
>>> dict(merged)
{'c': 3, 'b': 2, 'a': 1}
>>>
```

Starting with Python 3.5 it's possible to merge dictionaries like this.
**Don't do this unless you are sure that no-one will need to run your
code on Python versions older than 3.5.**

```python
>>> first = {'a': 1, 'b': 2}
>>> second = {'c': 3, 'd': 4}
>>> {**first, **second}
{'d': 4, 'c': 3, 'a': 1, 'b': 2}
{'a': 1, 'b': 2, 'c': 3}
>>>
```

Expand Down
42 changes: 40 additions & 2 deletions basics/answers.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ isn't exactly like mine but it works just fine it's ok, and you can
print("Access denied.")
```

Again, this is not a good way to ask a real password from the user.
Again, this is not a good way to ask a real password from the user.

## Handy stuff: Strings

Expand Down Expand Up @@ -156,7 +156,15 @@ isn't exactly like mine but it works just fine it's ok, and you can
print(message, "!!!")
print(message, "!!!")
```

3. In the code below, `palindrome_input[::-1]` is the string `palindrome_input` reversed.
For example, if `palindrome_input` is `"hello"`, then `palindrome_input[::-1]` is `"olleh"`.
```python
palindrome_input = input("Enter a string: ")
if palindrome_input == palindrome_input[::-1]:
print("This string is a palindrome")
else:
print("This string is not a palindrome")
```
## Lists and tuples

1. Look carefully. The `namelist` is written in `()` instead of `[]`,
Expand Down Expand Up @@ -296,6 +304,36 @@ isn't exactly like mine but it works just fine it's ok, and you can
print(converted_numbers)
```

5. ``` python
row_count = int(input("Type the number of rows needed:"))
for column_count in range(1, row_count+1):
# Print numbers from 1 to column_count
for number in range(1, column_count+1):
print(number, end=" ")
print() # creates a new line for the next row
```
If the user enters 5, we want to do a row with 1 column, then 2 columns, and so on until 5 columns.
That would be `for column_count in range(1, 6)`, because the end of the range is excluded.
In general, we need to specify `row_count + 1` so that it actually ends at `row_count`.
The second loop is similar.

Usually `print(number)` puts a newline character at the end of the line, so that the next print goes to the next line.
To get all numbers on the same line, we use a space instead of a newline character,
but we still need `print()` to add a newline character once we have printed the entire row.



6. ```python
row_count=int(input("Type the number of rows needed:"))

for line_number in range(1, row_count+1):
for number in range(line_number, row_count+1):
print(number, end=' ')
print()
```
Just like in the previous exercise, if the user enters 5, the first `for` loop gives the line numbers `1, 2, 3, 4, 5`.<br>
For example, on line 2, we should print numbers from 2 to 5, as in `range(2, 6)`, or in general, `range(line_number, row_count+1)`.

## Trey Hunner: zip and enumerate

1. Read some lines with `input` into a list and then enumerate it.
Expand Down
142 changes: 137 additions & 5 deletions basics/docstrings.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ thing(stuff)
```

That sucked! We have no idea about what it does based on this. All we
know is that it takes a `thing` argument.
know is that it takes a `stuff` argument.

This is when documentation strings or docstrings come in. All we need to
do is to add a string to the beginning of our function and it will show
Expand Down Expand Up @@ -198,11 +198,143 @@ this thing out of it.
You might be wondering what `__weakref__` is. You don't need to care
about it, and I think it would be better if `help()` would hide it.

## Popular Docstring Formats

There are different styles for writing docstrings. If you are contributing to
another Python project, make sure to use the same style as rest of that project
is using.

If you are starting a new project, then you can use whichever style you
want, but don't "reinvent the wheel"; use an existing style instead instead of
making up your own. Here are some examples of popular docstring styles to choose
from:

### Sphinx Style

[Sphinx](https://www.sphinx-doc.org/en/master/) is the Python documentation tool
that [the official Python documentation](https://docs.python.org/3/) uses.
By default, sphinx expects you to write docstrings like this:

```python
class Vehicles:
"""
The Vehicles object contains lots of vehicles.
:param arg: The arg is used for ...
:type arg: str
:ivar arg: This is where we store arg
:vartype arg: str
"""

def __init__(self, arg):
self.arg = arg

def cars(self, distance, destination):
"""We can't travel a certain distance in vehicles without fuels, so here's the fuels

:param distance: The amount of distance traveled
:type amount: int
:param bool destinationReached: Should the fuels be refilled to cover required distance?
:raises: :class:`RuntimeError`: Out of fuel

:returns: A Car mileage
:rtype: Cars
"""
...
```

### Google Style

Google Style is meant to be easier to read and use without a tool like sphinx.
Sphinx can be configured to use that with
[sphinx.ext.napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html).

```python
class Vehicles:
"""
The Vehicles object contains lots of vehicles.

Args:
arg (str): The arg is used for...

Attributes:
arg (str): This is where we store arg.
"""

def __init__(self, arg):
self.arg = arg

def cars(self, distance, destination):
"""We can't travel distance in vehicles without fuels, so here is the fuels

Args:
distance (int): The amount of distance traveled
destination (bool): Should the fuels refilled to cover the distance?

Raises:
RuntimeError: Out of fuel

Returns:
cars: A car mileage
"""
...

```

### Numpy Style

[Numpy](https://numpy.org/) is a large and popular Python library,
and numpy developers have their own docstring style.

```python
class Vehicles:
"""
The Vehicles object contains lots of vehicles.

Parameters
----------
arg : str
The arg is used for ...
*args
The variable arguments are used for ...
**kwargs
The keyword arguments are used for ...

Attributes
----------
arg : str
This is where we store arg.
"""

def __init__(self, arg):
self.arg = arg

def cars(self, distance, destination):
"""We can't travel distance in vehicles without fuels, so here is the fuels

Parameters
----------
distance : int
The amount of distance traveled
destination : bool
Should the fuels refilled to cover the distance?

Raises
------
RuntimeError
Out of fuel

Returns
-------
cars
A car mileage
"""
pass
```

## When should we use docstrings?

Always use docstrings when writing code that other people will import.
The `help()` function is awesome, so it's important to make sure it's
actually helpful.
I recommend using docstrings when writing code that other people will import.
The `help()` function is awesome, so it's good to make sure it's actually helpful.

If your code is not meant to be imported, docstrings are usually a good
idea anyway. Other people reading your code will understand what it's
Expand All @@ -214,7 +346,7 @@ doing without having to read through all of the code.
- A `"""triple-quoted string"""` string in the beginning of a function,
class or file is a docstring. It shows up in `help()`.
- Docstrings are not comments.
- Usually it's a good idea to add docstrings everywhere
- Usually it's a good idea to add docstrings everywhere.

***

Expand Down
5 changes: 3 additions & 2 deletions basics/editor-setup.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# Setting up an editor for programming

An editor is a program that lets us write longer programs than we can
write on the `>>>` prompt. Then we can save the programs to files and
write on the `>>>` prompt. With an editor we can save the programs to files and
run them as many times as we want without writing them again.

When programmers say "editor" they don't mean programs like Microsoft
Word or LibreOffice/OpenOffice Writer. These programs are for writing
text documents, not for programming. **Programming editors don't support
things like bigger font sizes for titles or underlining bits of text**,
but instead they have features that are actually useful for programming,
like automatically displaying different things with different colors.
like automatically displaying different things with different colors,
but also highlighting mistakes in the code, and coloring syntax.

If you are on Windows or Mac OSX you have probably noticed that your
Python came with an editor called IDLE. We are not going to use it
Expand Down
Loading