├── .github └── workflows │ └── build_deploy.yml ├── .gitignore ├── Makefile ├── README.md ├── _static ├── academis.png ├── custom.css ├── favicon.ico └── header-alt.jpg ├── appendix ├── LanguageBasics_Exercises.odp └── LanguageBasics_Exercises_v1.1.pdf ├── challenges ├── anagrams.rst ├── baby_name_generator.rst ├── birthdays.rst ├── checker.rst ├── count_words.py ├── count_words.rst ├── ctree.rst ├── dragon_egg.png ├── fibonacci.rst ├── fizzbuzz.rst ├── gcd.rst ├── minesweeper.rst ├── misty_mountains.rst ├── moby_dick.txt ├── mountains.csv ├── mountains.jpg ├── palindrome.rst ├── querprodukt.rst ├── quiz.rst ├── roman.rst ├── sierpinski.rst ├── spiral.rst ├── spiral1.svg ├── spiral2.svg ├── text_adventure.rst └── tictac.rst ├── conf.py ├── cover.jpg ├── cover.svg ├── data ├── bigbang.txt └── bigbang_numbers.txt ├── debugging ├── README.rst ├── questions.json └── twenty_questions.py ├── first_steps ├── ada.jpg ├── babynames.rst ├── bill.rst ├── builtin_functions.rst ├── calculator.png ├── cypher.rst ├── dictionaries.rst ├── dicts.png ├── enigma.jpg ├── for.rst ├── guess_the_number.rst ├── hello.rst ├── indexing.png ├── indexing.rst ├── indexing.svg ├── installing_python.rst ├── list_funcs1.png ├── list_funcs2.png ├── lists.png ├── nested_lists.rst ├── python_shell.rst ├── receipts.jpg ├── rock_paper_scissors.rst ├── rock_paper_scissors.svg ├── slideshow.png ├── slideshow.rst ├── spyder.png ├── squares.jpg ├── statistics.rst ├── strings.png ├── ten_images.zip └── type_conversions.rst ├── images ├── baby.png ├── big_bang_facts.png ├── files.png ├── functions.png ├── ipo.png ├── list.png ├── math.png ├── mobydick_count.png ├── os.png ├── sierpinski.png └── while.png ├── index.rst ├── learning_goals.md ├── links.md ├── refactoring ├── connect_four.py ├── connect_four_clean.py └── refactoring.rst ├── reference ├── basics.rst ├── builtin_functions.rst ├── data_types.rst ├── datatypes.png ├── dictionaries.rst ├── for_loops.rst ├── functions.rst ├── if.rst ├── images │ ├── cover.jpg │ ├── cover.png │ ├── indexing.png │ └── python3_reference_cover.svg ├── indexing.rst ├── input.rst ├── ipython_shell.rst ├── lists.rst ├── numbers.rst ├── operators.rst ├── os.rst ├── print.rst ├── reading_files.rst ├── run_from_terminal.rst ├── string_formatting.rst ├── strings.rst ├── tuples.rst ├── type_conversions.rst ├── while.rst └── writing_files.rst ├── requirements.txt └── solutions ├── anagrams.py ├── checker.py ├── comprehensions.py ├── create_numpy_arrays.py ├── create_numpy_matrices.py ├── format_strings.py ├── sierpinski.py ├── string_basics.py └── string_comprehensions.py /.github/workflows/build_deploy.yml: -------------------------------------------------------------------------------- 1 | 2 | name: deploy python basics 3 | 4 | on: 5 | push: 6 | branches: [ master ] 7 | 8 | jobs: 9 | 10 | build: 11 | name: sphinx build 12 | runs-on: ubuntu-latest 13 | steps: 14 | 15 | - name: checkout repo 16 | uses: actions/checkout@v1 17 | 18 | - name: build static html 19 | run: | 20 | python -m pip install --upgrade pip 21 | pip install -r requirements.txt 22 | make html 23 | 24 | - name: copy to academis server 25 | uses: appleboy/scp-action@master 26 | with: 27 | host: ${{ secrets.ACADEMIS_HOST }} 28 | username: ${{ secrets.ACADEMIS_USERNAME }} 29 | port: 22 30 | key: ${{ secrets.SSH_PRIVATE_KEY }} 31 | source: build/html/* 32 | target: /www/academis/python_basics 33 | rm: true 34 | strip_components: 2 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _book/* 2 | de/_book/* 3 | de/node_modules/* 4 | names.zip 5 | 6 | de/challenges/movie/mencoder.exe 7 | Gemfile.lock 8 | _site/* 9 | build/ 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Python Exercises for Beginners 3 | 4 | This is a tutorial for novice programmers. You are the learner I had in mind when writing these exercises if: 5 | 6 | * you have no programming experience at all 7 | * you have some experience with a different programming language like R, MATLAB or C. 8 | * you would like to teach Python to others 9 | 10 | Pick an exercise and start programming! 11 | 12 | There is a live site on [www.academis.eu/python_basics/](http://www.academis.eu/python_basics/) 13 | 14 | 15 | ## License 16 | 17 | © 2023 Dr. Kristian Rother (krother@academis.eu) 18 | 19 | with contributions by Allegra Via, Kaja Milanowska, Anna Philips, @ShalokShalom and @devSython. 20 | 21 | Distributed under the conditions of the Creative Commons Attribution Share-alike License 4.0 22 | 23 | Sources of this document can be found on [https://github.com/krother/Python3_Basics_Tutorial](https://github.com/krother/Python3_Basics_Tutorial) 24 | 25 | ## Acknowledgements 26 | 27 | I would like to thank the following people for inspiring exchange on training and Python that this tutorial has benefited from: Pedro Fernandes, Tomasz Puton, Edward Jenkins, Bernard Szlachta, Robert Lehmann and Magdalena Rother 28 | -------------------------------------------------------------------------------- /_static/academis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/_static/academis.png -------------------------------------------------------------------------------- /_static/custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --main-font: Lato; 3 | --secondary-color: #3C6F1F; 4 | --icon-frame-color: #80b940; 5 | --icon-body-color: #b3d789; 6 | --hover-color: #1b4403; 7 | --link-color:#3C6F1F; 8 | --footer-link-color: #efefef; 9 | --line-color: rgba(0, 128, 0, 0.298); 10 | --main-text-color: #000000; 11 | } 12 | 13 | /******************* VARIABLES END *******************/ 14 | 15 | 16 | /************************************** NEW CODE **************************************/ 17 | 18 | html { 19 | height: 100%; 20 | width: 100%; 21 | scroll-behavior: smooth; 22 | -webkit-box-sizing: border-box; 23 | -moz-box-sizing: border-box; 24 | box-sizing: border-box; 25 | } 26 | body { 27 | height: 100%; 28 | width: 100%; 29 | overflow-x: hidden; 30 | color: var(--main-text-color); 31 | font-family: var(--main-font); 32 | font-size: 1.4rem; 33 | background: url(header-alt.jpg) no-repeat; 34 | padding-top: 5em; 35 | } 36 | 37 | div.body { 38 | background: none; 39 | background-color: #00000000; 40 | } 41 | 42 | div.body h1 { 43 | font-size: 200%; 44 | } 45 | div.body h2 { 46 | font-size: 170%; 47 | } 48 | -------------------------------------------------------------------------------- /_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/_static/favicon.ico -------------------------------------------------------------------------------- /_static/header-alt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/_static/header-alt.jpg -------------------------------------------------------------------------------- /appendix/LanguageBasics_Exercises.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/appendix/LanguageBasics_Exercises.odp -------------------------------------------------------------------------------- /appendix/LanguageBasics_Exercises_v1.1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/appendix/LanguageBasics_Exercises_v1.1.pdf -------------------------------------------------------------------------------- /challenges/anagrams.rst: -------------------------------------------------------------------------------- 1 | Anagrams 2 | ======== 3 | 4 | **🎯 Check whether two words are anagrams of each other.** 5 | 6 | For example, the string: 7 | 8 | :: 9 | 10 | players 11 | 12 | has the anagram (permutations of characters): 13 | 14 | :: 15 | 16 | parsley 17 | 18 | Write a function `anagram()` that satisfies the following checks: 19 | 20 | .. code:: python3 21 | 22 | assert anagram("players", "parsley") is True 23 | assert anagram("hello", "world") is False 24 | 25 | Hints 26 | ----- 27 | 28 | - consider sorting the characters 29 | - consider the `set()` data type 30 | - consider `collections.Counter` 31 | - look up the function `itertools.permutations()`. 32 | 33 | Extra challenges 34 | ---------------- 35 | 36 | - Look for anagrams in the `SOWPODS word list `__ . 37 | - Implement an algorithm to generate all possible anagrams. Inform yourself about **dynamic programming**. 38 | - what is the time complexity of your implementation? 39 | 40 | *Translated with* `www.DeepL.com `__ 41 | -------------------------------------------------------------------------------- /challenges/baby_name_generator.rst: -------------------------------------------------------------------------------- 1 | Baby Name Generator 2 | =================== 3 | 4 | **🎯 Write a baby name generator for undecided parents.** 5 | 6 | Use the function ``random.choice()`` from the `random 7 | module `__. 8 | 9 | Look up the documentation if necessary. 10 | 11 | Extra Challenges: 12 | ----------------- 13 | 14 | - The program randomly outputs a name from a predefined list. 15 | - The program randomly outputs a name from the `US civil 16 | register `__ 17 | - The user can select either a boy’s or girl’s name 18 | - The program creates 10 suggestions 19 | 20 | *Translated with* `www.DeepL.com `__ 21 | -------------------------------------------------------------------------------- /challenges/birthdays.rst: -------------------------------------------------------------------------------- 1 | Birthday Problem 2 | ================ 3 | 4 | **🎯 Calculate probabilities** 5 | 6 | You’re attending a party with N guests. 7 | Calculate how likely it is that at least two of them will have a birthday on the same day. 8 | 9 | Hints 10 | ----- 11 | 12 | - there are at least two people at the party 13 | - assume that birthdays occur on all days of the year with the same probability. 14 | - ignore leap years 15 | 16 | Questions 17 | --------- 18 | 19 | - How many people have to be there for a >50% or >90% chance? 20 | - What is the probability that there are two or more pairs? 21 | - consider when the assumption that all days have the same probability 22 | makes sense 23 | 24 | *Translated with* `www.DeepL.com `__ 25 | -------------------------------------------------------------------------------- /challenges/checker.rst: -------------------------------------------------------------------------------- 1 | Checkerboard 2 | ============ 3 | 4 | **🎯 Write a program that outputs a chess board with 8 \* 8 squares:** 5 | 6 | :: 7 | 8 | #_#_#_#_ 9 | _#_#_#_# 10 | #_#_#_#_ 11 | _#_#_#_# 12 | #_#_#_#_ 13 | _#_#_#_# 14 | #_#_#_#_ 15 | 16 | Extra Challenges 17 | ---------------- 18 | 19 | - use a single ``print()`` statement 20 | - the characters ``#`` and ``_`` occur only once in the program 21 | - do not use the assignment operator ``=`` 22 | 23 | *Translated with* `www.DeepL.com `__ 24 | -------------------------------------------------------------------------------- /challenges/count_words.py: -------------------------------------------------------------------------------- 1 | 2 | import re 3 | 4 | # read the file 5 | mobydick = open('moby_dick.txt').read() 6 | 7 | # remove crap 8 | mobydick = mobydick.lower() 9 | mobydick = re.sub('[\*\.\!\"\;\?,\d]','',mobydick) 10 | mobydick = re.sub("[\-\(\)\']",' ',mobydick) 11 | 12 | # chop it into a list of words. 13 | words = mobydick.split() 14 | 15 | out = "Moby Dick contains %8i words."%(len(words)) 16 | 17 | # count the words in a dictionary 18 | count = {} 19 | for w in words: 20 | count.setdefault(w,0) 21 | count[w] += 1 22 | 23 | # get a list of sorted word counts 24 | result = [] 25 | for w in count: 26 | result.append( (count[w],w) ) 27 | result.sort() 28 | result.reverse() 29 | 30 | for count,word in result: 31 | out += "%5i\t%s\n"%(count,word) 32 | open('words.txt','w').write(out) 33 | 34 | 35 | -------------------------------------------------------------------------------- /challenges/count_words.rst: -------------------------------------------------------------------------------- 1 | Count Words 2 | =========== 3 | 4 | In this challenge you can learn: 5 | -------------------------------- 6 | 7 | ==== ================================== 8 | area topic 9 | ==== ================================== 10 | 🔀 use a counter variable 11 | 💡 read a text file 12 | 💡 split strings 13 | ⚙ use comparison operators 14 | 🔧 define absolute and relative paths 15 | 🐞 check file names 16 | ==== ================================== 17 | 18 | The Challenge 19 | ------------- 20 | 21 | The book *“Moby Dick”* by Herman Melville describes an epic battle of a 22 | gloomy captain against his personal nemesis, the white whale. Who of 23 | them is mentioned in the book more often? 24 | 25 | .. figure:: ../images/mobydick_count.png 26 | :alt: Moby Dick word count 27 | 28 | Write a program that counts how often each word occurs in the book. 29 | Determine how often the words ``captain`` and ``whale`` occur. You will 30 | need different data structures for counting words and for sorting them. 31 | 32 | When you know whether ``whale`` or ``captain`` occurs more often, you 33 | have mastered this challenge. 34 | 35 | The Data 36 | -------- 37 | 38 | You can find the full text for Herman Melville's “Moby Dick” in the text 39 | file :download:`moby_dick.txt` and on 40 | `www.gutenberg.org `__. 41 | 42 | Hints 43 | ----- 44 | 45 | Hint 1: What output do you expect? 46 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 47 | 48 | How should the output of the program look like? Write down a few sample lines of output . 49 | 50 | 51 | .. hint:: 52 | 53 | Output example 54 | 55 | :: 56 | 57 | 2307 is 58 | 228 through 59 | 5 tobacco 60 | 61 | 62 | Hint 2: Find a program structure 63 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 | Which steps should the program execute, and in which order? Draw a small flowchart. 65 | 66 | .. hint:: 67 | 68 | Program structure 69 | 70 | * Read the file. 71 | * Split it into words. 72 | * Count each word. 73 | * Sort the words by counts. 74 | * Output the words and counts 75 | 76 | 77 | Hint 3: Finding the right data type 78 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 | 80 | Which data type in Python is suited well to count things? 81 | Which operations on this data type will be necessary to 82 | 83 | * initialize the data type? 84 | * count a word? 85 | * Processing text data 86 | 87 | .. hint:: 88 | 89 | Dictionaries can be used to count things. 90 | 91 | .. code:: python3 92 | 93 | counter = {} 94 | counter.setdefault('fish', 0) 95 | counter['fish'] += 1 96 | 97 | 98 | Hint 4: Functions 99 | ~~~~~~~~~~~~~~~~~ 100 | Which Python functions can be used to 101 | 102 | * Read a text file? 103 | * Separate a string into words? 104 | 105 | .. hint:: 106 | 107 | Reading a text file: 108 | 109 | .. code:: python3 110 | 111 | text = open(filename).read() 112 | 113 | chopping up a string: 114 | 115 | .. code:: python3 116 | 117 | list = string.split() 118 | 119 | 120 | Hint 5: Sorting 121 | ~~~~~~~~~~~~~~~ 122 | 123 | Which data type in Python can be used to sort things? 124 | How would you want to represent words and counts in this data structure? 125 | 126 | .. hint:: 127 | 128 | In Python, lists can be sorted. 129 | Lists can contain tuples, e.g. 130 | 131 | .. code:: python3 132 | 133 | my_list = [ (12, 34), (56, 78) ] 134 | my_list.sort() 135 | 136 | 137 | Hint 6: Sorting by word counts 138 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | 140 | How does Python sort integers, strings, tuples, and other lists? 141 | 142 | 143 | .. hint:: 144 | 145 | Sorting by word count, not words: 146 | Try to sort on the command line these lists: 147 | 148 | :: 149 | 150 | [ ( "aaa", 100), ( "bbb", 20) ] 151 | 152 | and 153 | 154 | :: 155 | 156 | [ ( 100, "aaa"), ( 20, "bbb") ] 157 | 158 | Hint 7: Did it work? 159 | ~~~~~~~~~~~~~~~~~~~~ 160 | Where would you expect words like 'is', 'the', 'sea', and 'cerebellum' to occur? 161 | Check whether the output of the program corresponds to your expectations. 162 | Does 'captain' or 'whale' occur more often in the text? 163 | 164 | .. hint:: 165 | 166 | The first five places should be taken by of (6614), and (6433), a (4726), to (4625), and in (4173). 167 | You have to check yourself whether 'whale' or 'captain' is first. 168 | 169 | 170 | Hint 8: Special characters 171 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 172 | Special and uppercase characters may be a problem when separating words. 173 | How can you remove all special characters before starting counting? 174 | 175 | .. hint:: 176 | 177 | Special characters can be removed by the str.replace() function – or more comfortably using the re module. 178 | 179 | -------------------------------------------------------------------------------- /challenges/ctree.rst: -------------------------------------------------------------------------------- 1 | Star Tree 2 | ========= 3 | 4 | **🎯 Write a program that outputs the following image:** 5 | 6 | :: 7 | 8 | * 9 | *** 10 | ***** 11 | ******* 12 | ********* 13 | *********** 14 | 15 | .. hint:: 16 | 17 | You don't need to come up with an elegant solution right aways. 18 | For your first implementation, a straightforward solution is good enough. 19 | -------------------------------------------------------------------------------- /challenges/dragon_egg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/challenges/dragon_egg.png -------------------------------------------------------------------------------- /challenges/fibonacci.rst: -------------------------------------------------------------------------------- 1 | Fibonacci Numbers 2 | ================= 3 | 4 | **🎯 Write a program that produces numbers from the Fibonacci series.** 5 | 6 | In the Fibonacci series, each number is the sum of the two preceding 7 | ones. The first numbers of the series are: 8 | 9 | :: 10 | 11 | 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 12 | 13 | Hints 14 | ----- 15 | 16 | - it is possible to implement the solution as a recursive function or 17 | without recursion. 18 | 19 | Extra Challenge 20 | --------------- 21 | 22 | - do not use the assignment operator (``=``) 23 | -------------------------------------------------------------------------------- /challenges/fizzbuzz.rst: -------------------------------------------------------------------------------- 1 | Fizz-Buzz-Test 2 | ============== 3 | 4 | **🎯 Write a program that runs through the numbers from 1 to 100:** 5 | 6 | - If the number is divisible by 3, the program outputs *“Fizz”*. 7 | - If the number is divisible by 5, the program outputs *“Buzz”*. 8 | - If the number is divisible by 3 and 5, the program outputs 9 | *“FizzBuzz”*. 10 | - otherwise the number is printed 11 | 12 | Note 13 | ---- 14 | 15 | The **Fizz Buzz Test** has often been used in coding interviews. 16 | 17 | *Translated with* `www.DeepL.com `__ 18 | -------------------------------------------------------------------------------- /challenges/gcd.rst: -------------------------------------------------------------------------------- 1 | Greatest Common Denominator 2 | =========================== 3 | 4 | **🎯 Implement the** `Euclidean 5 | Algorithm `__ **to 6 | determine the greatest common denominator of two integers.** 7 | 8 | Pseudocode 9 | ---------- 10 | 11 | 1. you have two integer numbers a and b 12 | 2. copy the value of b 13 | 3. set b to the modulo of a and b 14 | 4. set a to the copy of b 15 | 5. if b is not zero, go back to step 2. 16 | 6. a is the greatest common denominator of a and b 17 | 18 | Tests 19 | ----- 20 | 21 | Use the following code to test your function: 22 | 23 | .. code:: python3 24 | 25 | assert gcd(6, 3) == 3 26 | assert gcd(12, 8) == 4 27 | assert gcd(42, 12) == 6 28 | 29 | 30 | *Translated with* `www.DeepL.com `__ 31 | -------------------------------------------------------------------------------- /challenges/minesweeper.rst: -------------------------------------------------------------------------------- 1 | Minesweeper 2 | =========== 3 | 4 | **🎯 Write a program that fills a Minesweeper field with the number of 5 | adjacent mines.** 6 | 7 | The input: 8 | 9 | :: 10 | 11 | .....*.. 12 | .*...... 13 | ......*. 14 | ..**.... 15 | ..*...*. 16 | .......* 17 | 18 | produces: 19 | 20 | :: 21 | 22 | 11101*10 23 | 1*100111 24 | 023211*1 25 | 02**1222 26 | 02*311*2 27 | 0111012* 28 | 29 | Hints 30 | ----- 31 | 32 | - First select a suitable data structure 33 | - Write a test for the program before you implement it 34 | - Write a function that counts the mines around a single field 35 | 36 | *Translated with* `www.DeepL.com `__ 37 | -------------------------------------------------------------------------------- /challenges/misty_mountains.rst: -------------------------------------------------------------------------------- 1 | Misty Mountains 2 | =============== 3 | 4 | .. image:: mountains.jpg 5 | 6 | Photo by `Rohit Tandon on unsplash.com `__ 7 | 8 | **🎯 Find the highest peak.** 9 | 10 | You are looking for the dwarven cities. 11 | They are under the highest mountains, of course. 12 | As you scan the horizon, you can clearly see the elevation of each mountain: 13 | 14 | :: 15 | 16 | 310 17 | 464 18 | 618 19 | 772 20 | 926 21 | 1080 22 | ... 23 | 24 | A peak is any elevation with two lower numbers before and after it. 25 | Every peak hosts one of the dwarven cities. You find the elevations in 26 | :download:`mountains.csv`. 27 | 28 | * find the highest peak 29 | * find all seven peaks 30 | 31 | Extra challenge 32 | --------------- 33 | 34 | Plot the elevations of the mountains as a line plot. 35 | -------------------------------------------------------------------------------- /challenges/mountains.csv: -------------------------------------------------------------------------------- 1 | 310 2 | 464 3 | 618 4 | 772 5 | 926 6 | 1080 7 | 1234 8 | 1388 9 | 1542 10 | 1696 11 | 1850 12 | 1807 13 | 1764 14 | 1721 15 | 1678 16 | 1635 17 | 1592 18 | 1549 19 | 1506 20 | 1463 21 | 1420 22 | 1371 23 | 1322 24 | 1273 25 | 1224 26 | 1175 27 | 1126 28 | 1077 29 | 1028 30 | 979 31 | 930 32 | 981 33 | 1032 34 | 1083 35 | 1134 36 | 1185 37 | 1236 38 | 1287 39 | 1338 40 | 1389 41 | 1440 42 | 1372 43 | 1304 44 | 1236 45 | 1168 46 | 1100 47 | 1032 48 | 964 49 | 896 50 | 828 51 | 760 52 | 800 53 | 840 54 | 880 55 | 920 56 | 960 57 | 1000 58 | 1040 59 | 1080 60 | 1120 61 | 1160 62 | 1147 63 | 1134 64 | 1121 65 | 1108 66 | 1095 67 | 1082 68 | 1069 69 | 1056 70 | 1043 71 | 1030 72 | 1094 73 | 1158 74 | 1222 75 | 1286 76 | 1350 77 | 1414 78 | 1478 79 | 1542 80 | 1606 81 | 1670 82 | 1575 83 | 1480 84 | 1385 85 | 1290 86 | 1195 87 | 1100 88 | 1005 89 | 910 90 | 815 91 | 720 92 | 790 93 | 860 94 | 930 95 | 1000 96 | 1070 97 | 1140 98 | 1210 99 | 1280 100 | 1350 101 | 1420 102 | 1475 103 | 1530 104 | 1585 105 | 1640 106 | 1695 107 | 1750 108 | 1805 109 | 1860 110 | 1915 111 | 1970 112 | 1929 113 | 1888 114 | 1847 115 | 1806 116 | 1765 117 | 1724 118 | 1683 119 | 1642 120 | 1601 121 | 1560 122 | 1502 123 | 1444 124 | 1386 125 | 1328 126 | 1270 127 | 1212 128 | 1154 129 | 1096 130 | 1038 131 | 980 132 | 1008 133 | 1036 134 | 1064 135 | 1092 136 | 1120 137 | 1148 138 | 1176 139 | 1204 140 | 1232 141 | 1260 142 | 1174 143 | 1088 144 | 1002 145 | 916 146 | 830 147 | 744 148 | 658 149 | 572 150 | 486 151 | 400 152 | 447 153 | 494 154 | 541 155 | 588 156 | 635 157 | 682 158 | 729 159 | 776 160 | 823 161 | 870 162 | 887 163 | 904 164 | 921 165 | 938 166 | 955 167 | 972 168 | 989 169 | 1006 170 | 1023 171 | 1040 172 | 1120 173 | 1200 174 | 1280 175 | 1360 176 | 1440 177 | 1520 178 | 1600 179 | 1680 180 | 1760 181 | 1840 182 | 1812 183 | 1784 184 | 1756 185 | 1728 186 | 1700 187 | 1672 188 | 1644 189 | 1616 190 | 1588 191 | 1560 192 | 1429 193 | 1298 194 | 1167 195 | 1036 196 | 905 197 | 774 198 | 643 199 | 512 200 | 381 201 | -------------------------------------------------------------------------------- /challenges/mountains.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/challenges/mountains.jpg -------------------------------------------------------------------------------- /challenges/palindrome.rst: -------------------------------------------------------------------------------- 1 | Palindrome 2 | ========== 3 | 4 | **🎯 Write a function that checks whether a string is a palindrome:** 5 | 6 | .. code:: python3 7 | 8 | def is_palindrome(s): 9 | ... 10 | 11 | Tests 12 | ----- 13 | 14 | Test your function with this code: 15 | 16 | .. code:: python3 17 | 18 | assert is_palindrome('Abba') 19 | assert is_palindrome('kayak') 20 | assert is_palindrome('Rats live on no evil star') 21 | assert not is_palindrome('abc') 22 | assert not is_palindrome('Hello world') 23 | 24 | Hints 25 | ----- 26 | 27 | - remove whitespace 28 | - ignore punctuation marks 29 | - ignore upper/lower case 30 | - you find more `palindromes on 31 | Wikipedia `__. 32 | 33 | *Translated with* `www.DeepL.com `__ 34 | -------------------------------------------------------------------------------- /challenges/querprodukt.rst: -------------------------------------------------------------------------------- 1 | Multiplicative Digital Root 2 | =========================== 3 | 4 | **🎯 Calculate the multiplicative digital root of a number.** 5 | 6 | The multiplicative digital root is the product of all digits. 7 | 8 | ====== === 9 | number MDR 10 | ====== === 11 | 7 7 12 | 23 6 13 | 111 1 14 | 100 0 15 | 333 27 16 | ====== === 17 | 18 | Hints 19 | ----- 20 | 21 | - Which data type is suitable for addressing the digits individually? 22 | - Because of the commutative law, it doesn’t matter in which order you 23 | multiply the numbers. 24 | 25 | Extra Challenge 26 | --------------- 27 | 28 | - for an advanced challenge, look up the ``functools.reduce`` function 29 | and solve the problem with it. 30 | 31 | *Translated with* `www.DeepL.com `__ 32 | -------------------------------------------------------------------------------- /challenges/quiz.rst: -------------------------------------------------------------------------------- 1 | Quiz 2 | ==== 3 | 4 | **🎯 Write a Multiple-Choice-Quiz.** 5 | 6 | The player gets questions with four choices. Depending on the input, the 7 | program outputs **CORRECT** or **WRONG**. 8 | 9 | Sample output: 10 | ~~~~~~~~~~~~~~ 11 | 12 | :: 13 | 14 | Question 1: 15 | 16 | Who are the burglars trying to rob Duck McScrooge? 17 | 18 | a) Blues Brothers 19 | b) Bagel Brothers 20 | c) Beagle Brothers 21 | d) Soul Brothers 22 | 23 | Enter your answer: c 24 | CORRECT 25 | 26 | Question 2: 27 | 28 | What is the top speed of a swallow? 29 | 30 | a) 50 km/h 31 | b) 70 km/h 32 | c) 120 km/h 33 | d) a European or Asian one? 34 | 35 | Enter your answer: 36 | ... 37 | -------------------------------------------------------------------------------- /challenges/roman.rst: -------------------------------------------------------------------------------- 1 | Roman Numbers 2 | ============= 3 | 4 | **🎯 Write a function ``roman2arabic()``, that translates a Roman into an 5 | Arabic number.** 6 | 7 | Tests 8 | ----- 9 | 10 | The following code helps you to check the results: 11 | 12 | .. code:: python3 13 | 14 | def test_roman(self): 15 | assert roman2arabic("I") == 1 16 | assert roman2arabic("XI") == 11 17 | assert roman2arabic("IX") == 9 18 | assert roman2arabic("CLI") == 151 19 | assert roman2arabic("XCIII") == 93 20 | assert roman2arabic("CCXCIV") == 294 21 | assert roman2arabic("MCM") == 1900 22 | assert roman2arabic("MI") == 1001 23 | 24 | Hints 25 | ----- 26 | 27 | - You only have to consider numbers from 1-5000 28 | - Which data structure is suitable for looking up the numerical values 29 | of Roman numerals? 30 | 31 | Extra Challenge 32 | --------------- 33 | 34 | - Write a function that converts Arabic to Roman numerals. 35 | 36 | *Translated with* `www.DeepL.com `__ 37 | -------------------------------------------------------------------------------- /challenges/sierpinski.rst: -------------------------------------------------------------------------------- 1 | Sierpinski Triangle 2 | =================== 3 | 4 | **🎯 Construct a Sierpinski Triangle with a Cellular Automaton.** 5 | 6 | .. figure:: ../images/sierpinski.png 7 | 8 | Consider the following rules: 9 | 10 | .. code:: python3 11 | 12 | rules = { 13 | ' ': ' ', 14 | ' #': '#', 15 | ' # ': '#', 16 | ' ##': ' ', 17 | '# ': '#', 18 | '# #': ' ', 19 | '## ': ' ', 20 | '###': ' ', 21 | } 22 | 23 | Now when you start with a string consisting of a single hash flanked by spaces: 24 | 25 | :: 26 | 27 | # 28 | 29 | The rules define how the next line looks like. 30 | For the new line you look up character triplets from the original string. 31 | The three triplets `" #", " # ", "# "` involving the original hash result in a new hash each. 32 | So the second line is: 33 | 34 | :: 35 | 36 | ### 37 | 38 | If you propagate that line once again, the triplets with two hashes reult in a space: 39 | 40 | :: 41 | 42 | # # 43 | 44 | If you propagate once again, the first four lines look like: 45 | 46 | :: 47 | 48 | # 49 | ### 50 | # # 51 | ### ### 52 | 53 | Write a program that propagates the following line 32 times: 54 | 55 | .. code:: python3 56 | 57 | line = " " * 32 + "#" + " " * 32 58 | 59 | Add an empty space at the beginning and end of each new line so that the line length stays the same. 60 | 61 | .. hint:: 62 | 63 | Experiment with the rule set defined by the dictionary by changing its values. 64 | 65 | What you can practise in this coding challenge 66 | ---------------------------------------------- 67 | 68 | - loops 69 | - string operations 70 | - looking up things in dictionaries 71 | 72 | .. seealso:: 73 | 74 | `Sierpinski Triangle on Wikipedia `__ -------------------------------------------------------------------------------- /challenges/spiral.rst: -------------------------------------------------------------------------------- 1 | Spiral 2 | ====== 3 | 4 | **Write a program, that draws a spiral:** 5 | 6 | .. figure:: spiral1.svg 7 | :alt: spiral 8 | 9 | When your program draws a spiral with at least 3 loops, you have 10 | mastered this challenge. 11 | 12 | What you can practise in this coding challenge 13 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | 15 | - loops 16 | - The **turtle** module in Python 17 | 18 | Hints 19 | ~~~~~ 20 | 21 | - It is sufficient to draw the spiral as a series of short lines 22 | - Where is it easier to start (inside or outside)? 23 | - Both the Python modules ``Pillow`` and ``turtle`` are up to the task 24 | 25 | Getting started 26 | ~~~~~~~~~~~~~~~ 27 | 28 | If you have no idea where to start, try the following Python script: 29 | 30 | .. code:: python3 31 | 32 | from turtle import forward, left 33 | 34 | forward(50) 35 | left(90) 36 | forward(50) 37 | 38 | Extra Challenge 39 | ~~~~~~~~~~~~~~~ 40 | 41 | - the line width grows thicker from the inside to the outside 42 | - there is a color gradient along the spiral 43 | - draw the **Fibonacci spiral** instead 44 | 45 | .. figure:: spiral2.svg 46 | :alt: Spiral with width and color 47 | -------------------------------------------------------------------------------- /challenges/spiral1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /challenges/text_adventure.rst: -------------------------------------------------------------------------------- 1 | Quest for the Dragon Egg 2 | ======================== 3 | 4 | **🎯 Implement a text adventure.** 5 | 6 | |image0| 7 | 8 | 9 | The Story 10 | --------- 11 | 12 | Far, far away, in an hardly accessible landscape, the mystic dragon egg 13 | lies hidden.. Will you find the egg and awaken the life within? 14 | 15 | - the dragon egg can be found on a lonely clearing 16 | - to awaken the egg, you need a magic spell 17 | - the spell is only known to a mage 18 | - the mage lives in a tower behind the forest 19 | - in the forest lives a bear that doesn’t let anyone pass 20 | - the bear, however, loves honey. Fortunately there is a beekeeper nearby. 21 | 22 | .. hint:: 23 | 24 | I admit this is not the greatest plot ever written. 25 | If you have a better one, program it! 26 | 27 | Requirements 28 | ------------ 29 | 30 | Write a game in which you can travel around between multiple rooms 31 | (clearing, tower, forest etc.). 32 | 33 | - the world consists of at least four ‘rooms’ 34 | - every room has a description 35 | - you enter the room to which you want to go on the keyboard 36 | - when you find the egg, the game ends with a final message 37 | 38 | The game is entirely text-based. 39 | 40 | Example Output 41 | -------------- 42 | 43 | :: 44 | 45 | Find the Dragon Egg 46 | =================== 47 | 48 | You are in your home town, 49 | a little trading spot on the desert border. 50 | 51 | There are paths leading to: desert, forest 52 | 53 | Where do you want to go? desert 54 | 55 | 56 | You are in the desert. The sun is burning. 57 | 58 | There are paths leading to: home, clearing, forest 59 | 60 | Where do you want to go? clearing 61 | 62 | 63 | On a hidden clearing you discover the dragon egg. 64 | 65 | Your quest has been successful! 66 | 67 | Step by Step 68 | ------------ 69 | 70 | Step 1: Create a project folder 71 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 72 | 73 | - Create a new folder for this project 74 | - Create a Python file ``adventure.py`` 75 | - Open the file in an editor 76 | 77 | Step 2: The Basic Structure 78 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 79 | 80 | Make the program produce a welcoming message. You could use an output 81 | with multiple lines: 82 | 83 | .. code:: python3 84 | 85 | print(""" 86 | Find the Dragon Egg 87 | =================== 88 | 89 | Your quest starts. 90 | """) 91 | 92 | At the end, the program congratulates the player to success: 93 | 94 | .. code:: python3 95 | 96 | print(""" 97 | On a hidden clearing you discover the dragon egg. 98 | 99 | Your quest has been successful! 100 | """) 101 | 102 | During the project, you will insert more code between these two 103 | instructions. 104 | 105 | **Execute the program and make sure it works.** 106 | 107 | Step 3: The Main Loop 108 | ~~~~~~~~~~~~~~~~~~~~~ 109 | 110 | The most important structural element of most games is the **main 111 | loop**. In each round of the loop you can enter a command. The game 112 | should end once you reach the final destination. 113 | 114 | At the beginning it is unknown how many instructions the player will 115 | enter. Therefore the number of loops is unknown. In such situations a 116 | **conditional loop** with ``while`` is a good choice. 117 | 118 | First you need to define a variable that contains the current location. 119 | In Python you can use the name of the room as a string: 120 | 121 | .. code:: python3 122 | 123 | room = "hometown" 124 | 125 | As soon as you reach the room *“clearing”*, the game ends. You can check 126 | that in the condition of the ``while`` loop: 127 | 128 | .. code:: python3 129 | 130 | while room != "clearing": 131 | print(f"You are in {room}") 132 | room = input("Where would you like to go? ") 133 | 134 | **Execute the program and make sure you can finish the game.** 135 | 136 | Step 4: Rooms 137 | ~~~~~~~~~~~~~ 138 | 139 | Your game does not have any rooms yet, so it is hard to tell where you 140 | are. 141 | 142 | Write interesting descriptions of the rooms and print them by adding 143 | ``if`` instructions like the following to the main loop: 144 | 145 | .. code:: python3 146 | 147 | if room == "hometown": 148 | print(""" 149 | You are in your home town. 150 | A small trading spot at the desert border. 151 | """) 152 | 153 | You can replace the ``print()`` statement from the previous step with 154 | the ``if`` statement. 155 | 156 | **Execute the program and make sure it works.** 157 | 158 | Step 5: Data Structure 159 | ~~~~~~~~~~~~~~~~~~~~~~ 160 | 161 | Checking every room with a separate ``if`` statement is feasible if you 162 | have 4 rooms. But imagine your game has 100 or more rooms – the program 163 | would become quite messy. 164 | 165 | A better alternative is to **structure the room data**. We will use a 166 | **dictionary** that contains descriptions of all rooms: 167 | 168 | .. code:: python3 169 | 170 | descriptions = { 171 | "hometown": """You are in your home town...""", 172 | "desert": """...""", 173 | } 174 | 175 | Define this dictionary at the beginning of the program. Now you can 176 | replace all ``if`` statements by a single request to the dictionary. The 177 | **key** is the ``room`` variable. 178 | 179 | Add these commands to the ``while`` loop: 180 | 181 | .. code:: python3 182 | 183 | print(descriptions[room]) 184 | 185 | and remove the ``if`` statements from step 4. 186 | 187 | **Execute the program and make sure it works.** 188 | 189 | Step 6: Checks 190 | ~~~~~~~~~~~~~~ 191 | 192 | At the moment the program is not checking whether a room you entered 193 | really exists. If you enter a wrong room (or make a typo), the program 194 | stops with an error message. 195 | 196 | Let’s check the input to prevent that. 197 | 198 | The following code matches the users input with the keys of the 199 | dictionary ``descriptions``: 200 | 201 | .. code:: python3 202 | 203 | target = input("Where do you want to go? ") 204 | if target in descriptions: 205 | room = target 206 | else: 207 | print("Stop! There is no such place.") 208 | 209 | Find out where in the program these lines need to be inserted. 210 | 211 | **Execute the program and make sure it works.** 212 | 213 | Step 7: Paths 214 | ~~~~~~~~~~~~~ 215 | 216 | Until now you could teleport from one room to any other. That makes the 217 | game a bit boring. 218 | 219 | - First, it is not clear which rooms you can go to. 220 | - Second, you could enter “clearing”, and the game ends right away. 221 | 222 | The game would be a lot more interesting if only some rooms were 223 | connected. For that, we need a second dictionary that contains the 224 | connections. Each entry points from one starting room to one or more 225 | targets: 226 | 227 | .. code:: python3 228 | 229 | paths = { 230 | "hometown": ["beekeeper", "forest"], 231 | "forest": ["hometown", "deser"], 232 | ... 233 | } 234 | 235 | You need two entries to create paths in both directions. If you leave 236 | one of them away, you also could create *one-way-streets*. 237 | 238 | The paths for the current room could be displayed with the following 239 | line: 240 | 241 | .. code:: python3 242 | 243 | print(paths[room]) 244 | 245 | or somewhat more nicely with: 246 | 247 | .. code:: python3 248 | 249 | print(", ".join(paths[room])) 250 | 251 | If you would like to extend the plausibility check, so that only the 252 | current paths are accessible, you need the following line: 253 | 254 | .. code:: python3 255 | 256 | if target in paths[room]: 257 | ... 258 | 259 | **Execute the program and make sure it works.** 260 | 261 | Step 8: Puzzles 262 | ~~~~~~~~~~~~~~~ 263 | 264 | An interesting adventure should also contain a few puzzles. Here is how 265 | a puzzle could look like: 266 | 267 | :: 268 | 269 | Where would you like to go? forest 270 | 271 | There is a BEAR in the forest!!! You run away. 272 | 273 | ... 274 | 275 | Where would you like to go? beekeeper 276 | 277 | You buy a pot of honey at the beekeeper. 278 | 279 | ... 280 | 281 | Where would you like to go? forest 282 | 283 | You leave the honeypot to the bear and carefully sneak through. 284 | 285 | How to implement such a puzzle? 286 | 287 | First you need a **state variable** that you define before the main 288 | loop, e.g.: 289 | 290 | .. code:: python3 291 | 292 | honey = False 293 | 294 | Second, you need to check in the main loop whether the state should 295 | change, and then change it, e.g.: 296 | 297 | .. code:: python3 298 | 299 | if room == "beekeeper" and not honey: 300 | print("You buy a pot of honey at the beekeeper.") 301 | honey = True 302 | 303 | Finally you need to check the state variable in the main loop to allow 304 | actions or prevent them: 305 | 306 | .. code:: python3 307 | 308 | if target == "forest": 309 | if honey: 310 | print("You leave the honeypot to the bear and carefully sneak through.") 311 | honey = False # you can use the honey only once 312 | else: 313 | print("There is a BEAR in the forest!!! You run away.") 314 | target = room # player stays in the same place 315 | 316 | Final Remarks 317 | ~~~~~~~~~~~~~ 318 | 319 | It is not easy to place all statements in the right order. A good idea 320 | is to run the program after each modification and to see what happens. 321 | 322 | For sure you have many ideas what to include in your adventure. 323 | 324 | .. |image0| image:: dragon_egg.png 325 | 326 | -------------------------------------------------------------------------------- /challenges/tictac.rst: -------------------------------------------------------------------------------- 1 | Tic-Tac-Toe 2 | =========== 3 | 4 | **🎯 Find out which player won.** 5 | 6 | You are given a Tic-Tac-Toe playing field as a nested list: 7 | 8 | :: 9 | 10 | ttt = [['X', 'O', 'X'], 11 | ['.', 'X', 'O'], 12 | ['X', 'O', 'O']] 13 | 14 | Write a program that determines which player has three symbols in a row 15 | (or whether it is a draw). 16 | 17 | Hints 18 | ----- 19 | 20 | - Examine rows, columns and diagonals separately at first. 21 | - It gets a little easier when you leave out the inner brackets. 22 | - Test the code with several game situations. 23 | 24 | *Translated with* `www.DeepL.com `__ 25 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # For the full list of built-in configuration values, see the documentation: 4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 5 | 6 | # -- Project information ----------------------------------------------------- 7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 8 | 9 | project = 'Teaching Programming' 10 | copyright = '2023, Kristian Rother' 11 | author = 'Kristian Rother' 12 | release = '1.0' 13 | 14 | # -- General configuration --------------------------------------------------- 15 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 16 | 17 | extensions = [ 18 | 'sphinx_design', 19 | 'sphinx_copybutton', 20 | 'sphinx.ext.todo', 21 | 'myst_parser', 22 | ] 23 | 24 | templates_path = ['_templates'] 25 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'learning_goals.md', 'README.md'] 26 | 27 | language = 'ls' 28 | 29 | # -- Options for HTML output ------------------------------------------------- 30 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 31 | 32 | html_theme = 'alabaster' 33 | html_theme_path = ['themes'] 34 | html_static_path = ['_static'] 35 | #html_logo = "_static/banner_wide.svg" 36 | html_favicon = "_static/favicon.ico" 37 | 38 | html_sidebars = { 39 | '**': [ 40 | 'about.html', 41 | 'localtoc.html', 42 | 'searchbox.html', 43 | ] 44 | } 45 | html_theme_options = { 46 | 'logo': 'academis.png', 47 | 'github_user': 'krother', 48 | 'github_repo': 'Python3_Basics_Tutorial', 49 | 'show_relbar_top' : True, 50 | 'show_relbar_bottom' : True, 51 | } 52 | -------------------------------------------------------------------------------- /cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/cover.jpg -------------------------------------------------------------------------------- /data/bigbang.txt: -------------------------------------------------------------------------------- 1 | Emily,F,12562 2 | Amy,F,2178 3 | Penny,F,342 4 | Bernadette,F,129 5 | Leonard,M,384 6 | Howard,M,208 7 | Sheldon,M,164 8 | Stuart,M,82 9 | Raj,M,41 10 | -------------------------------------------------------------------------------- /data/bigbang_numbers.txt: -------------------------------------------------------------------------------- 1 | 12562 2 | 2178 3 | 342 4 | 129 5 | 384 6 | 208 7 | 164 8 | 82 9 | 41 -------------------------------------------------------------------------------- /debugging/README.rst: -------------------------------------------------------------------------------- 1 | 2 | Twenty Questions 3 | ================ 4 | 5 | In this chapter you will: 6 | ------------------------- 7 | 8 | ==== ============================================== 9 | area topic 10 | ==== ============================================== 11 | 🚀 get the question-answer game to work 12 | 💡 load a JSON file 13 | 🔧 work with a minimal input file 14 | 🐞 check code for errors 15 | 🐞 read error messages 16 | 🐞 add diagnostic print statements 17 | ==== ============================================== 18 | 19 | Exercise 1: Execute the program 20 | ------------------------------- 21 | 22 | Below you find the code for the game **twenty questions**. 23 | In the game, you think of an animal. 24 | The computer tries to guess it using only yes/no questions. 25 | 26 | To get started: 27 | 28 | - download the code :download:`twenty_questions.py` 29 | - download the questions in :download:`questions.json` 30 | - place both in the same folder 31 | - execute the program 32 | 33 | What happens? 34 | 35 | Here is the complete code: 36 | 37 | .. literalinclude:: twenty_questions.py 38 | 39 | Exercise 2: Read the code 40 | ------------------------- 41 | 42 | The easiest type of bugs are **Syntax Errors**. 43 | A Syntax Error generally means that the code is not understandable 44 | for the Python interpreter, so it refuses to execute any of it. 45 | 46 | This type of bug is the easiest to fix. 47 | Actually, your editor should find all Syntax Errors for you. 48 | 49 | Find and fix them. 50 | 51 | 52 | Exercise 3: Read error messages 53 | ------------------------------- 54 | 55 | Once you fixed all Syntax Errors, Python starts executing code. 56 | The next type of bug are errors that occur *while the program runs*. 57 | These are called **Exceptions at Runtime**. 58 | The program terminates, and you see an error message – so you know there is a bug. 59 | 60 | What can you learn about an errors from reading the error messages? 61 | Try to fix the errors as good as you can. 62 | 63 | .. hint:: 64 | 65 | A good practice when debugging Python code is to read error messages *from the bottom*. 66 | 67 | Exercise 4: Diagnostic prints 68 | ----------------------------- 69 | 70 | Many bugs do not produce an error message. 71 | To Python everything looks fine. 72 | But you notice that the program is not doing what it should. 73 | This category, **Semantic Errors** is harder to identify, 74 | because you need to find out *that* something goes wrong and then *what* exactly goees wrong. 75 | 76 | With a semantic error, you might want to add extra ``print`` statements to your program 77 | so that you can learn what is happening. 78 | Such a *diagnostic print* could be as simple as: 79 | 80 | .. code:: python3 81 | 82 | print("reached AAA") 83 | 84 | or display the contents of a variable: 85 | 86 | .. code:: python3 87 | 88 | print(finished) 89 | 90 | Inspect the next bug using an extra ``print``. 91 | Remove the ``print`` if it helps you to fix the bug. 92 | 93 | Exercise 5: Minimal input 94 | ------------------------- 95 | 96 | If your program works with lots of data, debugging is more difficult. 97 | One problem with the game is that the JSON file ``questions.json`` 98 | contains a couple of thousand questions. 99 | 100 | Let's use a simpler one. 101 | 102 | Create a file ``mini_questions.json`` and use it instead by changing the file name in the program. 103 | It should contain the following minimalistic data: 104 | 105 | :: 106 | 107 | { 108 | "text": "is it a Python?", 109 | "yes": { 110 | "text": "it is a Python!" 111 | }, 112 | "no": { 113 | "text": "it is some other animal." 114 | } 115 | } 116 | 117 | If you get the game to work with this data, 118 | switch back to the bigger file. 119 | 120 | **Good luck!** 121 | 122 | Reflection Questions 123 | -------------------- 124 | 125 | * what types of errors do you know? 126 | * what techniques for finding bugs do you know? 127 | * why do programmers create bugs? 128 | 129 | 130 | .. seealso:: 131 | 132 | - `Kristians Debugging Tutorial at PyData 2017 `__ 133 | - Data from: `github.com/knkeniston/TwentyQuestions `__ 134 | -------------------------------------------------------------------------------- /debugging/twenty_questions.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | 4 | def is_answer(node): 5 | """leaf nodes have only a 'text' attribute""" 6 | return len(node) == 1 7 | 8 | 9 | f = open('quetions.json') 10 | node = json.load() 11 | 12 | finished = "False" 13 | 14 | while not finished 15 | print(node['text'] 16 | 17 | if is_answer_node(node): 18 | finished = True 19 | else: 20 | answer == input() 21 | if answer.upper() in ['yes', 'y']: 22 | node = node['no'] 23 | else: 24 | node = node['yes'] 25 | -------------------------------------------------------------------------------- /first_steps/ada.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/ada.jpg -------------------------------------------------------------------------------- /first_steps/babynames.rst: -------------------------------------------------------------------------------- 1 | Baby Names 2 | ========== 3 | 4 | In this chapter you will: 5 | ------------------------- 6 | 7 | ======= ==================================== 8 | area topic 9 | ======= ==================================== 10 | 🚀 analyze birth statistics 11 | 💡 use the ``open`` function to read and write files 12 | 💡 use the ``os`` module to loop through a directory 13 | 🔀 parse comma-separated files 14 | 🐞 fix FileNotFound errors 15 | ======= ==================================== 16 | 17 | The dataset of U.S. baby names 18 | ------------------------------ 19 | 20 | .. figure:: ../images/baby.png 21 | :alt: Babynames 22 | 23 | For this chapter, you will need to download a data set of baby 24 | names. The authorities of the United States have recorded the first 25 | names of all people born as U.S. citizens since 1880. The dataset is 26 | publicly available on `www.ssa.gov/oact/babynames/limits.html `__. 27 | 28 | Download the shorter archive of baby names (not grouped by states). 29 | 30 | .. note:: 31 | 32 | For the protection of privacy only names used 33 | at least 5 times appear in the data. 34 | 35 | 36 | Exercise 1: Read a file 37 | ----------------------- 38 | 39 | Unzip the downloaded archive and place the folder next to your Python program. 40 | Read one of the files by inserting ``line``, ``line``, ``open`` and 41 | ``print`` into the gaps. 42 | 43 | .. code:: python3 44 | 45 | for ___ in ___(r"names/yob2022.txt"): 46 | if "Maria" in ___: 47 | ___(line) 48 | 49 | .. hint:: 50 | 51 | Depending on your editor, you may need to insert the complete path to 52 | the file insted of ``names/``. 53 | On Windows, the ``r`` is important to have Python correctly interpret 54 | backslashes as separators. 55 | 56 | Exercise 2: Distinct names 57 | -------------------------- 58 | 59 | How many different *girls names* were there in 2022? 60 | 61 | **Sort** the following code lines and **indent them correctly**: 62 | 63 | .. code:: python3 64 | 65 | girls = 0 66 | if "B" in line: 67 | print(girls) 68 | if ",F," in line: 69 | for line in open(r"names/yob2022.txt"): 70 | girls += 1 71 | 72 | Exercise 3 73 | ---------- 74 | 75 | Extend the program from the previous exercise such that boys and girls 76 | names are counted separately. 77 | 78 | 79 | Exercise 4: Frequent names 80 | -------------------------- 81 | 82 | The following program collects names in a list that occur at least 10000 83 | times. Unfortunately, the program contains **four errors**. Find and fix 84 | these. 85 | 86 | .. code:: python3 87 | 88 | frequent = [] 89 | 90 | for line in open(r"names/yob2022.txt"): 91 | columns = line.strip().split(",") 92 | name = colums[1] 93 | if int(columns[3]) >= 10000 94 | frequent.append(name) 95 | 96 | print(frequent) 97 | 98 | 99 | Exercise 5: Total babies 100 | ------------------------ 101 | 102 | Write a program that calculates the total number of babies for the year 103 | 2022 and writes it to the screen. Compare that number with the year 1922. 104 | 105 | 106 | Exercise 6: Read and write 107 | -------------------------- 108 | 109 | Form pairs of Python commands and their meanings. 110 | 111 | .. figure:: ../images/files.png 112 | :alt: file exercise 113 | 114 | 115 | Exercise 7: Write a file 116 | ------------------------ 117 | 118 | Execute the following program. Explain what happens. 119 | 120 | .. code:: python3 121 | 122 | names = ["Ada", "Bob", "Charlie", "Dorothy"] 123 | 124 | with open(r"names.txt", "w") as f: 125 | for name in names: 126 | f.write(name + "\n") 127 | 128 | .. hint:: 129 | 130 | What happens if you remove the ``\n`` from the program? 131 | 132 | 133 | Exercise 8: f-Strings 134 | --------------------- 135 | 136 | Try the following commands in a Python shell: 137 | 138 | .. code:: python3 139 | 140 | name = "Ada" 141 | number = 42 142 | pi = 3.14159 143 | 144 | print(f"{name}") 145 | print(f"{name:>10}") 146 | print(f"{number:5d}") 147 | print(f"{number:05d}") 148 | print(f"{pi:4.1f}") 149 | print(f"{pi:6.3f}") 150 | print(f"name: {name} number: {number} pi: {pi:6.3f}") 151 | 152 | 153 | Exercise 9: Directories 154 | ----------------------- 155 | 156 | To process bigger amounts of data, you will need to work on more than 157 | one file. Sometimes you don’t know all the files in advance. 158 | The ``os`` module is quite useful for working with many files and directories. 159 | 160 | Fill in the gaps: 161 | 162 | .. figure:: ../images/os.png 163 | :alt: os exercise 164 | 165 | Exercise 10 166 | ----------- 167 | 168 | Explain the following code: 169 | 170 | .. code:: python3 171 | 172 | import os 173 | 174 | for dirname in os.listdir(r"names/"): 175 | print(dirname) 176 | 177 | 178 | Recap: Read and write text files 179 | -------------------------------- 180 | 181 | Insert working code into the blanks: 182 | 183 | :: 184 | 185 | # 1. Create a list with the numbers 1..7 186 | ... 187 | 188 | # 2. Convert the numbers to a string 189 | ... 190 | 191 | # 3. Open a file for writing 192 | ... 193 | 194 | # 4. Write the numbers to the file 195 | ... 196 | 197 | # 5. Open the file for reading 198 | ... 199 | 200 | # 6. Read all numbers in a list 201 | ... 202 | 203 | # 7. Sum up the numbers 204 | ... 205 | 206 | 207 | Reflection Questions 208 | -------------------- 209 | 210 | - How do you know that a file path in a program is wrong? 211 | - What do you need to check if a file path in a program is wrong? 212 | - How to print all file names in a folder? 213 | -------------------------------------------------------------------------------- /first_steps/bill.rst: -------------------------------------------------------------------------------- 1 | Receipts 2 | ======== 3 | 4 | .. image:: receipts.jpg 5 | 6 | Photo by `Carli Jeen on unsplash.com `__ 7 | 8 | 9 | In this chapter you will: 10 | ------------------------- 11 | 12 | ======= ==================================== 13 | area topic 14 | ======= ==================================== 15 | 🚀 sum up numbers from shopping bills 16 | ⚙ loop over a list 17 | 💡 use the ``append`` method of the ``list`` data type 18 | 🔀 transform a list into a new one 19 | 🐞 fix value errors 20 | ======= ==================================== 21 | 22 | 23 | Exercise 1 24 | ---------- 25 | 26 | To process larger amounts of data, we cannot invent a new variable name 27 | for every number. 28 | Instead, we can store multiple number in a **list**. 29 | 30 | The program below sums up items on a list. 31 | Complete the code by inserting ``costs``, ``for``, ``item``, ``total`` 32 | 33 | .. code:: python 34 | 35 | costs = [8, 5, 20, 12, 1] 36 | total = 0 37 | ___ item in ___: 38 | ___ += ___ 39 | print(total) 40 | 41 | 42 | Exercise 2: List methods 43 | ------------------------ 44 | 45 | Find out what each expression does to the list in the center. 46 | 47 | .. figure:: lists.png 48 | :alt: list exercise 49 | 50 | 51 | Exercise 3: Add an extra item 52 | ----------------------------- 53 | 54 | You have an extra item you need to take into account: 55 | 56 | .. code:: python3 57 | 58 | costs = [8, 5, 20, 12, 1] 59 | extra = 4 60 | 61 | Use a list method from exercise 2 to add the extra item to the list. 62 | Then calculate the sum. 63 | 64 | 65 | Exercise 4: Concatenate 66 | ----------------------- 67 | 68 | Explain the difference between the following expressions: 69 | 70 | :: 71 | 72 | [1, 2 + 3, 4] 73 | 74 | [1, 2] + [3, 4] 75 | 76 | ["1", "2" + "3", "4"] 77 | 78 | ["1, 2" + "3, 4"] 79 | 80 | "[1, 2" + "3, 4]" 81 | 82 | 83 | 84 | Exercise 5: Puzzle 85 | ------------------ 86 | 87 | Use the expressions to modify the list as indicated. Use each expression 88 | once. 89 | 90 | .. figure:: list_funcs2.png 91 | :alt: list funcs exercise2 92 | 93 | 94 | Exercise 6: List transformation 95 | ------------------------------- 96 | 97 | Sometimes it is useful to create a new list from an existing one. 98 | This is called **transforming** a list. 99 | Order the lines in the following program: 100 | 101 | .. code:: python3 102 | 103 | print(total) 104 | costs = ["8", "5", "20", "12", "1"] 105 | numbers.append(int(item)) 106 | for item in costs: 107 | total = sum(numbers) 108 | numbers = [] 109 | 110 | 111 | Exercise 7: Receipt assistant 112 | ----------------------------- 113 | 114 | Write a program that sums up shopping bills. 115 | The user enters amounts, one number at a time. 116 | If they enter nothing (an empty string), 117 | the program calculates the total value of the items entered. 118 | 119 | The output of the program could look like this: 120 | 121 | :: 122 | 123 | Please enter the costs on your bills, one number at a time: 124 | 13 125 | 8 126 | 5 127 | 21 128 | 129 | The total cost of your bills is 47 130 | 131 | 132 | .. hint:: 133 | 134 | You will need a ``while`` loop for entering the numbers. 135 | 136 | 137 | Reflection Questions 138 | -------------------- 139 | 140 | - How can you create a list? 141 | - How can you add an item to a list? 142 | - How can you run a for loop over a list? 143 | -------------------------------------------------------------------------------- /first_steps/builtin_functions.rst: -------------------------------------------------------------------------------- 1 | Substitution Cipher 2 | =================== 3 | 4 | In this chapter you learn: 5 | -------------------------- 6 | 7 | ==== ============================================== 8 | area topic 9 | ==== ============================================== 10 | 🚀 encrypt text with a substitution cipher 11 | ⚙ convert strings to lists and back 12 | ⚙ use a random seed 13 | 💡 use the ``random`` module 14 | 💡 use the ``string`` module 15 | 💡 use the ``zip`` function 16 | 🔀 use the ``dict(zip())`` pattern 17 | 🐞 fix IndexErrors 18 | ==== ============================================== 19 | 20 | Exercise 1: Random string 21 | ------------------------- 22 | 23 | The following code creates a random chiffre that we will use for encryption. 24 | Insert ``alphabet``, ``chars``, ``join`` and ``random`` into the code: 25 | 26 | .. code:: python3 27 | 28 | import random 29 | 30 | alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 31 | 32 | ___ = list(___) 33 | ___.shuffle(chars) 34 | chiffre = "".___(chars) 35 | print(chiffre) 36 | 37 | Run the program a couple of times. 38 | 39 | 40 | Exercise 2: Random seed 41 | ----------------------- 42 | 43 | Add the following line after the import: 44 | 45 | .. code:: python3 46 | 47 | random.seed(77) 48 | 49 | Run the program a couple of times. 50 | What changes? 51 | 52 | Also try running the program with different numbers. 53 | 54 | 55 | Exercise 3: Chiffre indices 56 | --------------------------- 57 | 58 | Output each character from the chiffre and its index 59 | Simplify the following code using the function ``enumerate()``: 60 | 61 | .. code:: python3 62 | 63 | i = 0 64 | for char in chiffre: 65 | print(i, char) 66 | i += 1 67 | 68 | 69 | Exercise 4: Lookup dictionary 70 | ----------------------------- 71 | 72 | Create a dictionary that maps unencrypted to encrypted characters: 73 | 74 | .. code:: python3 75 | 76 | lookup = {} 77 | i = 0 78 | while i < len(alphabet): 79 | char = alphabet[i] 80 | lookup[char] = chiffre[i] 81 | i += 1 82 | print(lookup) 83 | 84 | Execute the program slowly on paper to make sure you understand the index operations. 85 | 86 | Exercise 5: Zip 87 | --------------- 88 | 89 | Use the following code to make the program above simpler: 90 | 91 | .. code:: python3 92 | 93 | for char, chif in zip(alphabet, chiffre) 94 | print(char, chif) 95 | 96 | Once you understand what happens, also try: 97 | 98 | .. code:: python3 99 | 100 | lookup = dict(zip(alphabet, chiffer)) 101 | 102 | 103 | Exercise 6: Encrypt 104 | ------------------- 105 | 106 | Use the lookup dictionary to encrypt a message. 107 | Use the following lines as a starting point: 108 | 109 | .. code:: python3 110 | 111 | message = ... 112 | result = "" 113 | 114 | for char in message: 115 | result += ... 116 | - 117 | Exercise 7: Debugging 118 | --------------------- 119 | 120 | What happens when you enter lowercase letters or special characters in the message? 121 | 122 | Try the expression: 123 | 124 | .. code:: python3 125 | 126 | print(lookup.get(";", "X")) 127 | 128 | Fix the problem. 129 | 130 | 131 | Exercise 7: Decrypt 132 | ------------------- 133 | 134 | Decrypt a message when all you know is the encrypted message and the random seed. 135 | 136 | 137 | Reflection Questions 138 | -------------------- 139 | 140 | - what does the ``enumerate()`` function do? 141 | - what does the ``zip()`` function do? 142 | - is a substitution cipher rather safe or unsafe? 143 | - what is **symmetric encryption**? 144 | 145 | .. seealso:: 146 | 147 | **Further Reading** 148 | 149 | - `Kerckhoffs Principle `__ -------------------------------------------------------------------------------- /first_steps/calculator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/calculator.png -------------------------------------------------------------------------------- /first_steps/cypher.rst: -------------------------------------------------------------------------------- 1 | Cesar Cipher 2 | ============ 3 | 4 | .. image:: enigma.jpg 5 | 6 | Photo by `Christian Lendl on unsplash.com `__ 7 | 8 | In this chapter you will: 9 | ------------------------- 10 | 11 | ======= ==================================== 12 | area topic 13 | ======= ==================================== 14 | 🚀 encrypt and decrypt text 15 | ⚙ index the positions of a string 16 | ⚙ loop over a string 17 | 💡 use the ``find`` method of the ``string`` data type 18 | 🔀 build a longer string by concatenation 19 | 🔀 use the same index for two strings 20 | 🐞 fix index errors 21 | ======= ==================================== 22 | 23 | 24 | Exercise 1: Cesar Cipher 25 | ------------------------ 26 | 27 | Execute the following code calculating a **Cesar Cipher**: 28 | 29 | .. code:: python3 30 | 31 | plain = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " 32 | encrypted = "DEFGHIJKLMNOPQRSTUVWXYZABC " 33 | 34 | for i in range(26): 35 | print(plain[i], " -> ", encrypted[i]) 36 | 37 | Explain what the code does. 38 | 39 | 40 | Exercise 2: String methods 41 | -------------------------- 42 | 43 | Find out what the expressions do to the string in the middle. 44 | 45 | .. figure:: strings.png 46 | 47 | Exercise 3: Loop over a string 48 | ------------------------------ 49 | 50 | The following program should print the position in the alphabet of every character. 51 | Complete program by inserting ``char``, ``message``, ``plain`` and ``position``: 52 | 53 | .. code:: python3 54 | 55 | plain = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " 56 | message = "MY SECRET MESSAGE" 57 | 58 | for char in ___: 59 | position = ___.find(___) 60 | print(char, "is in position", ___) 61 | 62 | Why is the space at the end of ``plain`` important? 63 | 64 | Exercise 4: String concatenation 65 | -------------------------------- 66 | 67 | Explain the following code: 68 | 69 | .. code:: python3 70 | 71 | encrypted = "DEFGHIJKLMNOPQRSTUVWXYZABC " 72 | 73 | s = "" 74 | s += encrypted[4] 75 | s += encrypted[1] 76 | s += encrypted[8] 77 | s += encrypted[8] 78 | s += encrypted[11] 79 | print(s) 80 | 81 | Exercise 5: Encryption 82 | ---------------------- 83 | 84 | Write a program that: 85 | 86 | 1. defines a plain and encrypted alphabet as 26-character strings 87 | 2. reads a message from the keyboard 88 | 3. defines an empty result string 89 | 4. goes through each character of the message 90 | 5. finds the position in the plain text alphabet 91 | 6. looks up that position in the encrypted alphabet 92 | 7. adds the encrypted character to the result string 93 | 8. when all characters have been processed, output the result 94 | 95 | .. hint:: 96 | 97 | After each step, you should be able to run the program 98 | and see what it already does. 99 | 100 | Exercise 6 101 | ---------- 102 | 103 | Explain why the following code does the same as in exercise 1: 104 | 105 | .. code:: python3 106 | 107 | plain = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 108 | for i in range(26): 109 | print(plain[i], " -> ", plain[(i + 3) % 26]) 110 | 111 | Can you use it to make your encryption program shorter? 112 | 113 | .. hint:: 114 | 115 | If you are not sure what happens, print the value of ``i`` inside the loop. 116 | 117 | Exercise 7 118 | ---------- 119 | 120 | Also write a program for **decryption**. 121 | 122 | .. hint:: 123 | 124 | How could you make sure that the input string is in upper case? 125 | 126 | Reflection questions 127 | -------------------- 128 | 129 | - what happens when a string is followed by square brackets? 130 | - describe two ways to loop over the characters of a string? 131 | - what does the ``str.find()`` method do? 132 | - how can you add characters to a string? 133 | -------------------------------------------------------------------------------- /first_steps/dictionaries.rst: -------------------------------------------------------------------------------- 1 | Look up Prices 2 | ============== 3 | 4 | In this chapter you will: 5 | ------------------------- 6 | 7 | ======= ==================================== 8 | area topic 9 | ======= ==================================== 10 | 🚀 write a better receipt assistant 11 | ⚙ define a dictionary 12 | ⚙ look up values of a dictionary 13 | 🔀 iterate through a list of dictionary keys 14 | 🔀 use lists as dictionary values 15 | 🐞 fix errors in dictionary definitions 16 | 🐞 fix index errors 17 | ======= ==================================== 18 | 19 | Exercise 1: Look up 20 | ------------------- 21 | 22 | Consider we would like to look up shopping prices. 23 | In this chapter, we will use a **dictionary**, 24 | a data structure that is good for looking up items. 25 | 26 | Execute the following code: 27 | 28 | .. code:: python3 29 | 30 | prices = { 31 | "apple": 0.50, 32 | "banana": 1.00, 33 | "orange": 1.50, 34 | "cherries": 3.00, 35 | } 36 | print(prices["banana"]) 37 | 38 | How does the dictionary differ from a list? 39 | 40 | 41 | Exercise 2: Explore 42 | ------------------- 43 | 44 | Find out what each of the expressions does to the dictionary in the center. 45 | 46 | .. figure:: dicts.png 47 | :alt: dict exercise 48 | 49 | 50 | Exercise 3: Look up 51 | ------------------- 52 | 53 | Now consider having the list of items in ``fruit``. 54 | You would like to calculate the total price. 55 | For that, the list and dictionary need to work together. 56 | 57 | Sort the lines and indent them properly: 58 | 59 | print(total) 60 | total += prices[item] 61 | bought = ["banana", "banana", "cherries", "apple", "apple", "banana"] 62 | for item in bought: 63 | total = 0 64 | prices = { 65 | "apple": 0.50, 66 | "banana": 1.00, 67 | "orange": 1.50, 68 | "cherries": 3.00, 69 | } 70 | 71 | Exercise 4: Receipt assitant 2.0 72 | -------------------------------- 73 | 74 | Improve the receipt assistant from the previous chapter 75 | so that it uses a dictionary of prices. 76 | 77 | 78 | Exercise 5: Traveler 79 | -------------------- 80 | 81 | The following program allows you to travel from one city to the next. 82 | Unfortunately, it contains **five bugs**. Find and fix them. 83 | 84 | .. code:: python3 85 | 86 | cities = { 87 | "New York": ["Tokyo", "Delhi", "London"], 88 | "Poznan": ["London", "Berlin"], 89 | "London": ["New York", "Poznan"] 90 | "Berlin": ["Tokyo", "Poznan"], 91 | "Tokyo": ["New York" "Berlin"], 92 | "Delhi": ["Katmandu"] 93 | } 94 | 95 | location = "Berlin" 96 | print "\nYour task: fly to Katmandu\n" 97 | 98 | while location in cities and location == 'Katmandu': 99 | print(f"You are in {location}") 100 | 101 | print("There are flights to ", cities["location"]) 102 | location = input("Where would you like to travel?") 103 | 104 | print("You have reached your destination") 105 | 106 | 107 | Exercise 6: Zip 108 | --------------- 109 | 110 | Simplify the following code using the function ``zip()``: 111 | 112 | .. code:: python3 113 | 114 | fruits = ["apple", "banana", "orange", "cherries"] 115 | prices = [0.5, 1.0, 1.5, 3.0] 116 | 117 | table = [] 118 | i = 0 119 | while i < len(fruits): 120 | row = (fruits[i], prices[i]) 121 | table.append(row) 122 | i += 1 123 | print(table) 124 | 125 | Try the expression: 126 | 127 | .. code:: python3 128 | 129 | for a, b in zip(fruits, prices): 130 | ... 131 | 132 | 133 | Reflection Questions 134 | -------------------- 135 | 136 | - How can you create a dictionary? 137 | - What data types can you use as keys of a dictionary? 138 | - What data types can you use as values of a dictionary? 139 | - How can you modify values in a dictionary? 140 | - Is it possible to run a for loop over a dictionary? 141 | -------------------------------------------------------------------------------- /first_steps/dicts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/dicts.png -------------------------------------------------------------------------------- /first_steps/enigma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/enigma.jpg -------------------------------------------------------------------------------- /first_steps/for.rst: -------------------------------------------------------------------------------- 1 | Square Numbers 2 | ============== 3 | 4 | |image0| 5 | 6 | `Image by travelnow.or.crylater on 7 | Unsplash `__ 8 | 9 | In this chapter you will: 10 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 11 | 12 | ==== ============================= 13 | area topic 14 | ==== ============================= 15 | 🚀 calculate square numbers 16 | ⚙ use ``for`` loops 17 | ⚙ indent instructions 18 | 💡 use the ``range()`` function 19 | 💡 use the ``time`` module 20 | 🐞 recognize bugs at runtime 21 | ==== ============================= 22 | 23 | 24 | Exercise 1: Pat your own shoulder 25 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 | 27 | Execute the following program. What happens? 28 | 29 | .. code:: python3 30 | 31 | import time 32 | 33 | for i in range(5): 34 | print("You are great at programming!") 35 | time.sleep(5) 36 | 37 | 38 | Exercise 2: Counting 39 | ~~~~~~~~~~~~~~~~~~~~ 40 | 41 | Execute the following two lines: 42 | 43 | .. code:: python3 44 | 45 | for number in range(1, 7): 46 | print(number) 47 | 48 | Make the code print the numbers from 1 to 20. 49 | 50 | 51 | Exercise 3: Prints 52 | ~~~~~~~~~~~~~~~~~~ 53 | 54 | Explain why the ``for``-loop is better than this code sniplet: 55 | 56 | .. code:: python3 57 | 58 | print(1) 59 | print(2) 60 | print(3) 61 | print(4) 62 | print(5) 63 | print(6) 64 | print(7) 65 | 66 | 67 | Exercise 4: Indentation 68 | ~~~~~~~~~~~~~~~~~~~~~~~ 69 | 70 | Explain the difference between the following two programs: 71 | 72 | .. code:: python3 73 | 74 | x = 1 75 | for i in range(10): 76 | x = x * 2 77 | print(x) 78 | 79 | and 80 | 81 | .. code:: python3 82 | 83 | x = 1 84 | for i in range(10): 85 | x = x * 2 86 | print(x) 87 | 88 | 89 | Exercise 5: Squares 90 | ~~~~~~~~~~~~~~~~~~~ 91 | 92 | Implement a ``for`` loop that produces the following output: 93 | 94 | :: 95 | 96 | 1 97 | 4 98 | 9 99 | 16 100 | 25 101 | 36 102 | 49 103 | 104 | 105 | Exercise 6: More loops 106 | ~~~~~~~~~~~~~~~~~~~~~~ 107 | 108 | Execute the following loops one by one. 109 | 110 | .. code:: python3 111 | 112 | for char in "ABCD": 113 | print(char) 114 | 115 | for i in range(10): 116 | print(i) 117 | 118 | for number in [4, 9, 16, 25]: 119 | print(number) 120 | 121 | for x, y in [(1,2), (3,4), (5,6)]: 122 | print(x, y) 123 | 124 | rabbits = 10 125 | for i in range(9): 126 | rabbits = rabbits + rabbits // 5 127 | print(rabbits) 128 | 129 | .. |image0| image:: squares.jpg 130 | 131 | -------------------------------------------------------------------------------- /first_steps/guess_the_number.rst: -------------------------------------------------------------------------------- 1 | Guess the Number 2 | ================ 3 | 4 | In this chapter you will: 5 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 6 | 7 | ==== ============================================== 8 | area topic 9 | ==== ============================================== 10 | 🚀 write a number guessing game 11 | 💡 use the *string* data type 12 | ⚙ implement a conditional loop 13 | 🔧 enter Python commands 14 | 🐞 debug endless loops 15 | ==== ============================================== 16 | 17 | 18 | Exercise 1: Conditional Loops 19 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 20 | 21 | In this chapter, you will need a new command to influence the 22 | order in which instructions are executed: the conditional loop or 23 | ``while`` loop. 24 | 25 | Match the expressions so that the ``while`` loops run the designated 26 | number of times. 27 | 28 | .. figure:: ../images/while.png 29 | :alt: while exercise 30 | 31 | while exercise 32 | 33 | -------------- 34 | 35 | Exercise 2 36 | ~~~~~~~~~~ 37 | 38 | Which of these ``while`` commands are correct? 39 | 40 | .. code:: python3 41 | 42 | while a = 1: 43 | 44 | while b == 1 45 | 46 | while a + 7: 47 | 48 | while len(c) > 10: 49 | 50 | while a and (b-2 == c): 51 | 52 | while s.find('c') >= 0: 53 | 54 | -------------- 55 | 56 | Exercise 3 57 | ~~~~~~~~~~ 58 | 59 | Which statements are correct? 60 | 61 | - ``while`` is also called a conditional loop 62 | - The expression after ``while`` may contain function calls 63 | - It is possible to ``while`` loops that run forever 64 | - The colon after ``while`` may be omitted 65 | - The code block after ``while`` is executed at least once 66 | 67 | -------------- 68 | 69 | Exercise 4: Search 70 | ~~~~~~~~~~~~~~~~~~ 71 | 72 | The following ``for`` loop searches for ``33`` in the data. Modify the 73 | code, so that it uses a ``while`` loop instead. 74 | 75 | .. code:: python3 76 | 77 | data = [5, 7, 33, 12, 4, 3, 18] 78 | 79 | found = False 80 | for n in data: 81 | if n == 33: 82 | found = True 83 | 84 | print("The value 33 has been found: {}".format(found)) 85 | 86 | -------------- 87 | 88 | Exercise 5 89 | ~~~~~~~~~~ 90 | 91 | The following ``while`` loop counts numbers higher than 10. Change the 92 | code so that it uses a ``for`` loop instead. 93 | 94 | .. code:: python3 95 | 96 | data = [4, 7, 11, 1, 3, 15] 97 | 98 | i = 0 99 | high = 0 100 | while i < len(data): 101 | if data[i] > 10: 102 | high += 1 103 | i += 1 104 | 105 | print(f"There are {high} values higher than 10") 106 | 107 | -------------- 108 | 109 | Exercise 6 110 | ~~~~~~~~~~ 111 | 112 | Which of the following ``while`` loops will finish? 113 | 114 | Exercise 6.1 115 | ^^^^^^^^^^^^ 116 | 117 | .. code:: python3 118 | 119 | count = 0 120 | while count > 0: 121 | print count 122 | count += 1 123 | 124 | Exercise 6.2 125 | ^^^^^^^^^^^^ 126 | 127 | .. code:: python3 128 | 129 | text = "a" 130 | while "z" not in text: 131 | text += "a" 132 | 133 | Exercise 6.3 134 | ^^^^^^^^^^^^ 135 | 136 | .. code:: python3 137 | 138 | a = 7 139 | b = 135 140 | while a != b: 141 | a += (a - b) / 10.0 142 | b -= (a - b) / 10.0 143 | 144 | Exercise 6.4 145 | ^^^^^^^^^^^^ 146 | 147 | .. code:: python3 148 | 149 | n = 0 150 | while n * 5 != n ** 2: 151 | n += 2 152 | 153 | Exercise 6.5 154 | ^^^^^^^^^^^^ 155 | 156 | .. code:: python3 157 | 158 | data = [1, 2, 7, 8] 159 | while data[-1] > 2: 160 | data.pop() 161 | 162 | Exercise 6.6 163 | ^^^^^^^^^^^^ 164 | 165 | .. code:: python3 166 | 167 | data = [2, 3, 15] 168 | while data[0] < 100: 169 | data = data[1:] 170 | 171 | ---- 172 | 173 | Exercise 7: Implement the game 174 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 175 | 176 | In the **Guess the Number** game, the player tries to guess a number that the computer has generated. 177 | 178 | 1. The program randomly *“rolls”* a number between 1 and 100. 179 | 2. **Do not** output the number. 180 | 3. The player enters a number. 181 | 4. The program says whether the number was too big or too small. 182 | 5. Repeat steps 3-5 until the correct number was guessed. 183 | 184 | Example output: 185 | ~~~~~~~~~~~~~~~ 186 | 187 | :: 188 | 189 | I have memorized a number. 190 | Try to guess it! 191 | 192 | Please enter a number (1-100): 33 193 | My number is lower. 194 | 195 | Please enter a number (1-100): 22 196 | My number is lower. 197 | 198 | Please enter a number (1-100): 11 199 | My number is higher. 200 | 201 | Please enter a number (1-100): 17 202 | My number is lower. 203 | 204 | Please enter a number (1-100): 14 205 | My number is lower. 206 | 207 | Please enter a number (1-100): 13 208 | You found it! 209 | -------------------------------------------------------------------------------- /first_steps/hello.rst: -------------------------------------------------------------------------------- 1 | Hello World 2 | =========== 3 | 4 | In this chapter you will: 5 | ------------------------- 6 | 7 | ==== ============================================== 8 | area topic 9 | ==== ============================================== 10 | 🚀 write a Hello World program in Python 11 | 💡 use the *string* data type 12 | 💡 call the functions ``print()`` and ``input()`` 13 | ⚙ store text in a string variable 14 | 🔧 enter Python commands 15 | 🔧 modify Python commands 16 | 🐞 find SyntaxErrors 17 | ==== ============================================== 18 | 19 | 20 | Exercise 1: Your first Program 21 | ------------------------------ 22 | 23 | Create a new file in the **editor window** and enter the following 24 | instructions: 25 | 26 | .. code:: python3 27 | 28 | name = input("What is your name? ") 29 | print("Hello", name) 30 | 31 | Execute the program by pressing the **“Execute”** button or pressing 32 | **F5** in Spyder. What happens? 33 | 34 | 35 | Exercise 2: Break the program 36 | ----------------------------- 37 | 38 | When programming, it is inevitable that you make mistakes. Errors can be 39 | simple typos or complicated errors in the logical structure. One of the 40 | most important skills in programming is to find the cause of a bug in a 41 | program and fix it. You can practice this by intentionally breaking the 42 | program and seeing what happens. 43 | 44 | Try the following programs with errors one by one and try to understand 45 | the error message: 46 | 47 | .. code:: python3 48 | 49 | name = input("What is your name? ") 50 | pront("Hello", name) 51 | 52 | name = input("What is your name? " 53 | print("Hello", name) 54 | 55 | name = input("What is your name? ") 56 | print(Hello , name) 57 | 58 | x = input("What is your name? ") 59 | print("Hello", x) 60 | 61 | How can you find out what is going on? 62 | 63 | 64 | Exercise 3: input 65 | ----------------- 66 | 67 | Which of the following ``input`` commands work? Try them one by one. 68 | 69 | .. code:: python3 70 | 71 | name input("enter your name: ") 72 | 73 | name = input("enter a number: ") 74 | 75 | name = input(enter your name) 76 | 77 | name = input() 78 | 79 | 80 | Exercise 4: print 81 | ----------------- 82 | 83 | Which of the following ``print`` commands work? Try them one by one. 84 | 85 | .. code:: python3 86 | 87 | print "Hello" 88 | 89 | print("Hello", name, name) 90 | 91 | print("Hello" + name) 92 | 93 | print("Hello name") 94 | 95 | print(name) 96 | 97 | 98 | Exercise 5: Variable names 99 | -------------------------- 100 | 101 | Try which of the following names of Python variables can be used: 102 | 103 | .. code:: python3 104 | 105 | YODA = 'jedi' 106 | 107 | darth vader = 'sith' 108 | 109 | luke99 = 'jedi' = 'sith' 110 | 111 | 2000imperator = 'sith' 112 | 113 | obi_wan_kenobi = 'jedi' 114 | 115 | darth.maul = 'sith' 116 | 117 | 118 | Exercise 6: Three little bugs 119 | ----------------------------- 120 | 121 | The following program should output a song by Bob Marley. 122 | It contains three bugs. 123 | Copy the code into your editor. 124 | Then find and fix the bugs. 125 | 126 | .. code:: python3 127 | 128 | part1 = "Don't worry about a thing" 129 | part2 = "Cause every little thing" 130 | part3 = gonna be all right 131 | 132 | text = "part1 + part2 + part3" 133 | print(text 134 | 135 | 136 | Exercise 7 137 | ---------- 138 | 139 | Write a program that asks for your first and last name and outputs both. 140 | 141 | 142 | Reflection questions 143 | -------------------- 144 | 145 | * What is a function in Python? 146 | * How can you recognize a function? 147 | * What can you put inside the brackets of the `print()` function? 148 | * What are legal/illegal variable names? 149 | * What can you do if your program does not work? 150 | -------------------------------------------------------------------------------- /first_steps/indexing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/indexing.png -------------------------------------------------------------------------------- /first_steps/indexing.rst: -------------------------------------------------------------------------------- 1 | 2 | Block Cipher 3 | ============ 4 | 5 | In this chapter you will: 6 | ------------------------- 7 | 8 | ======= ==================================== 9 | area topic 10 | ======= ==================================== 11 | 🚀 implement a transposition cipher 12 | ⚙ slice lists and strings 13 | 💡 use the ``join`` method of the ``string`` data type 14 | 🔀 use a loop variable for indexing 15 | 🔀 use indexing to re-arrange a list 16 | ======= ==================================== 17 | 18 | 19 | Indexing and Slicing 20 | -------------------- 21 | 22 | Strings and lists are both ordered sequences of elements. 23 | In both, you can address elements by their position. 24 | However, Python is counting differently than humans: 25 | 26 | .. figure:: indexing.png 27 | :alt: Indexing 28 | 29 | 30 | Exercise 1: Indexing lists 31 | -------------------------- 32 | 33 | What do the following expressions result in? 34 | 35 | .. code:: python3 36 | 37 | numbers = [1, 4, 9, 16, 25, 36] 38 | 39 | numbers[4] 40 | movies[0] 41 | movies[-1] 42 | numbers[-3] 43 | 44 | 45 | Exercise 2: Slicing strings 46 | --------------------------- 47 | 48 | What do the following commands result in? 49 | 50 | name = "hello world" 51 | 52 | name[5:] 53 | name[5:10] 54 | name[:10:2] 55 | numbers[2:-2] 56 | numbers[::2] 57 | 58 | Exercise 3: Ranges 59 | ------------------ 60 | 61 | Use ``list(range())`` to create the following lists: 62 | 63 | .. code:: python3 64 | 65 | [4, 7, 9, 12, 15] 66 | 67 | [10, 20, 30, 40, 50, 60] 68 | 69 | [33, 32, 31, 30] 70 | 71 | 72 | Exercise 4: Decypher 73 | -------------------- 74 | 75 | The following text contains an encrypted word: 76 | 77 | .. code:: python3 78 | 79 | name = "CSAIPRALKAINACZEYLVOST" 80 | 81 | Print every second character, starting with the 2nds. 82 | 83 | 84 | Exercise 5: Slicing puzzle 85 | -------------------------- 86 | 87 | Use the expressions to modify the list as indicated. Use each expression 88 | once. 89 | 90 | .. figure:: list_funcs1.png 91 | :alt: list funcs exercise1 92 | 93 | 94 | Exercise 6: Blocks 95 | ------------------ 96 | 97 | The following code is creating the first two blocks for a `transposition cipher `__ . 98 | Complete the code by creating the other two blocks as well. 99 | 100 | .. code:: python3 101 | 102 | message = "MEETINGATDAWNATTHEBRIDGE" 103 | 104 | block1 = message[0::4] 105 | block2 = message[1::4] 106 | ___ 107 | ___ 108 | encrypted = block1 + block2 + block3 + block4 109 | 110 | 111 | Exercise 7: Transposition Cipher 112 | -------------------------------- 113 | 114 | Complete the program that encrypts a text using a transposition cipher: 115 | 116 | .. code:: python3 117 | 118 | message = input("enter the text to encrypt: ") 119 | encrypted = "" 120 | for start in range(4): 121 | ___ 122 | 123 | Exercise 8: Decrypt 124 | ------------------- 125 | 126 | Write a program to decrypt an encrypted message again. 127 | 128 | 129 | Exercise 9: Encryption Key 130 | -------------------------- 131 | 132 | Use an encryption key like ``2031`` that specifies a new order for the blocks. 133 | Implement the following: 134 | 135 | 1. create an empty list 136 | 2. create the blocks as above and add them to the list 137 | 3. go through each position of the encryption key 138 | 4. select the block with the index given by the digit from the key (convert it to int) 139 | 5. add the block to the result string 140 | 141 | 142 | Reflection questions 143 | -------------------- 144 | 145 | - what is indexing? 146 | - what do the three numbers in *slicing* do? 147 | - what do you think about the transposition cipher. Is it secure? 148 | - how could you decrypt a transposition cipher without the key? -------------------------------------------------------------------------------- /first_steps/installing_python.rst: -------------------------------------------------------------------------------- 1 | Installing Python 2 | ================= 3 | 4 | In this chapter you will: 5 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 6 | 7 | ==== ============================================== 8 | area topic 9 | ==== ============================================== 10 | 🔧 install the Anaconda Python distribution 11 | 🔧 launch the Spyder editor 12 | ==== ============================================== 13 | 14 | 15 | The first step into programming is to get Python installed on your 16 | computer. You will need two programs: **Python** itself and an 17 | **editor** to write code. A convenient way to install both in one go is 18 | **Anaconda**, a Python distribution with many pre-installed packages. 19 | Download it from `www.anaconda.com `__ and 20 | follow the instructions. 21 | 22 | After installing, launch the **Spyder** editor from the **Anaconda 23 | Navigator**. It should look like this: 24 | 25 | |image0| 26 | 27 | Troubleshooting 28 | ~~~~~~~~~~~~~~~ 29 | 30 | Generally, you can use any text editor to write Python code. Besides 31 | Spyder, I recommend **Visual Studio Code** and **PyCharm**, although 32 | both are not that easy to configure. 33 | 34 | If you prefer to use the standard Python installation, you find it on 35 | `www.python.org `__. 36 | In that case, install spyder using the Python package manager ``pip``. 37 | Type: 38 | 39 | :: 40 | 41 | pip install spyder 42 | 43 | Reflection Questions 44 | ~~~~~~~~~~~~~~~~~~~~ 45 | 46 | - Which text editors are installed on your system? 47 | - Which Python version are you running? 48 | - Name some advantages/disadvantages of the Python language 49 | 50 | .. |image0| image:: spyder.png 51 | 52 | -------------------------------------------------------------------------------- /first_steps/list_funcs1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/list_funcs1.png -------------------------------------------------------------------------------- /first_steps/list_funcs2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/list_funcs2.png -------------------------------------------------------------------------------- /first_steps/lists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/lists.png -------------------------------------------------------------------------------- /first_steps/nested_lists.rst: -------------------------------------------------------------------------------- 1 | Nested Lists 2 | ============ 3 | 4 | In this chapter you learn: 5 | -------------------------- 6 | 7 | ==== ============================================== 8 | area topic 9 | ==== ============================================== 10 | ⚙ define a list inside a list 11 | ⚙ index a nested list 12 | 🔀 loop over a nested list 13 | 🔀 create a nested list with a nested loop 14 | ==== ============================================== 15 | 16 | Data frequently occurs in the form of tables. To process tables in 17 | Python, we can put lists in other lists. These are called **nested lists**: 18 | 19 | .. code:: python3 20 | 21 | table = [ 22 | ["Emma", 20799], 23 | ["Olivia", 19674], 24 | ["Sophia", 18490], 25 | ["Isabella", 16950], 26 | ["Ava", 15586], 27 | ["Mia", 13442], 28 | ["Emily", 12562], 29 | ] 30 | 31 | Generally, for nested lists, the same rules apply as for single lists. 32 | E.g. for the third row: 33 | 34 | .. code:: python3 35 | 36 | print(table[2]) 37 | 38 | To access a single element, you need two pairs of square brackets. 39 | E.g. for the second column of the third row: 40 | 41 | .. code:: python3 42 | 43 | print(table[2][1]) 44 | 45 | In this chapter we will create and process nested lists. 46 | 47 | 48 | Exercise 1 49 | ---------- 50 | 51 | Write all rows of the above table to the screen with a ``for`` loop. 52 | 53 | Complete the code: 54 | 55 | .. code:: python3 56 | 57 | for ... in table: 58 | print(...): 59 | 60 | 61 | Exercise 2 62 | ---------- 63 | 64 | Now modify the loop to output only the names. 65 | 66 | 67 | Exercise 3 68 | ---------- 69 | 70 | Write each individual *cell* of the table to the screen with a nested ``for`` loop. 71 | 72 | Complete the code: 73 | 74 | .. code:: python3 75 | 76 | for row in ...: 77 | ... cell in row: 78 | print(...) 79 | 80 | 81 | Exercise 4 82 | ---------- 83 | 84 | Create an empty table of 10 x 10 cells and fill them with numbers from 1 85 | to 100. 86 | 87 | Sort the lines and indent the code properly: 88 | 89 | .. code:: python3 90 | 91 | for x in range(10): 92 | for y in range(10): 93 | number = 1 94 | number += 1 95 | print(table) 96 | row = [] 97 | row.append(number) 98 | table.append(row) 99 | table = [] 100 | -------------------------------------------------------------------------------- /first_steps/python_shell.rst: -------------------------------------------------------------------------------- 1 | Python as a Calculator 2 | ====================== 3 | 4 | |image0| 5 | 6 | `photograph by Charles Deluvio on 7 | Unsplash `__ 8 | 9 | 10 | In this chapter you will: 11 | ------------------------- 12 | 13 | ==== ================================ 14 | area topic 15 | ==== ================================ 16 | 🚀 use Python as a pocket calculator 17 | 💡 use the data type *integer* 18 | ⚙ use arithmetical operators (+-\*/) 19 | ⚙ store numbers in a variable 20 | ⚙ change the contents of a variable 21 | 🔧 use the Variable Explorer 22 | ==== ================================ 23 | 24 | 25 | Arithmetics 26 | ----------- 27 | 28 | In this chapter we will use the Python console as a pocket calculator. 29 | In Spyder you should see the following prompt (in the bottom right 30 | window): 31 | 32 | :: 33 | 34 | In [1]: 35 | 36 | If you see a different number than 1 it is still the right place. 37 | 38 | 39 | Exercise 1: Basic Arithmetics 40 | ----------------------------- 41 | 42 | Execute a few calculations in Python. Insert the missing symbols into 43 | the gaps: 44 | 45 | :: 46 | 47 | In [1]: 1 + ___ 48 | Out[1]: 3 49 | 50 | In [2]: 12 ___ 8 51 | Out[2]: 4 52 | 53 | In [3]: ___ * 5 54 | Out[3]: 20 55 | 56 | In [4]: 21 / 7 57 | Out[4]: ___ 58 | 59 | In [5]: ___ ** 2 60 | Out[5]: 81 61 | 62 | Enter the commands into the console and see what happens. 63 | 64 | .. hint:: 65 | 66 | Do not enter the first part (``In [1]`` etc.). It appears automatically. 67 | 68 | 69 | Exercise 2: Division 70 | -------------------- 71 | 72 | What is the difference between the following instructions? 73 | 74 | .. code:: python3 75 | 76 | 10 / 4 77 | 10.0 / 4 78 | 10 // 4 79 | 10 * 0.25 80 | 81 | Enter them in the console and examine the result. 82 | 83 | 84 | Exercise 3: Operators 85 | --------------------- 86 | 87 | Which operations result in 8? 88 | 89 | .. code:: python3 90 | 91 | 4 - -4 92 | 65 // 8 93 | 17 % 9 94 | 64 ** 0.5 95 | 96 | Enter the instructions and examine the result. 97 | 98 | 99 | Exercise 4: Variables 100 | --------------------- 101 | 102 | For saving numbers and results of calculations for later, you can store 103 | them in **variables**. 104 | 105 | Fill the gaps: 106 | 107 | :: 108 | 109 | In [1]: rabbits = 25 110 | In [2]: cats = 7 111 | In [3]: raccoons = 5 112 | In [4]: rabbits 113 | Out[4]: ___ 114 | In [5]: cats + 1 115 | Out[5]: ___ 116 | In [6]: 3 * raccoons 117 | Out[6]: ___ 118 | 119 | 120 | Exercise 5: Modify Variables 121 | ---------------------------- 122 | 123 | The first instruction modifies the value of a variable from exercise 4. 124 | Insert values and variables so that the result is correct: 125 | 126 | :: 127 | 128 | In [7]: rabbits = rabbits + 1 129 | In [8]: rabbits 130 | Out[8]: ___ 131 | 132 | In [9]: animals = ___ + ___ + ___ 133 | In [10]: animals 134 | Out[10]: 38 135 | 136 | .. hint:: 137 | 138 | In the **Variable Explorer** in Spyder (top right) you can inspect 139 | the content of each variable. 140 | 141 | 142 | Exercise 6: Vaiable Assignments 143 | ------------------------------- 144 | 145 | Which variable assignmments are correct? Enter the code and execute it 146 | to see if it works. 147 | 148 | .. code:: python3 149 | 150 | a = 1 * 2 151 | 2 = 1 + 1 152 | 5 + 6 = y 153 | seven = 3 * 4 154 | 155 | 156 | Exercise 7: Rabbit Multiplication 157 | --------------------------------- 158 | 159 | In April you have 10 rabbits: 160 | 161 | .. code:: text 162 | 163 | rabbits = 10 164 | 165 | The rabbits constantly multiply. Every month, their number grows by 166 | **20%**. Therefore, you will have 12 rabbits in May. 167 | 168 | **How many rabbits will you have in December?** 169 | 170 | .. hint:: 171 | 172 | - assume that rabbits never die 173 | - it is ok to calculate with fractions of rabbits 174 | - it is ok to repeat the same lines multiple times for each month 175 | 176 | .. |image0| image:: calculator.png 177 | 178 | 179 | Reflection Questions 180 | -------------------- 181 | 182 | * Which arithmetic operators exist in Python? 183 | * What is a variable? 184 | * What does the `=` operator do? 185 | * How can you swap the values of two variables? 186 | -------------------------------------------------------------------------------- /first_steps/receipts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/receipts.jpg -------------------------------------------------------------------------------- /first_steps/rock_paper_scissors.rst: -------------------------------------------------------------------------------- 1 | Rock-Paper-Scissors 2 | =================== 3 | 4 | |image0| 5 | 6 | `image by Enzoklop, CC BY-SA 7 | 3.0 `__ 8 | 9 | 10 | In this chapter you will: 11 | ------------------------- 12 | 13 | ======= ==================================== 14 | area topic 15 | ======= ==================================== 16 | 🚀 write a *rock-paper-scissors* game 17 | ⚙ use the conditional statement ``if`` 18 | ⚙ use comparison operators 19 | 💡 use the data type ``bool`` 20 | 🔀 use a state variable 21 | 🐞 recognize indentation errors 22 | ======= ==================================== 23 | 24 | An important structural element in program is *making decisions*. 25 | In Python, the instruction ``if`` 26 | decides which instruction to execute next. 27 | 28 | 29 | Exercise 1: Decision 30 | -------------------- 31 | 32 | With the instruction ``if``, you can make a decision inside your program. 33 | Test the following program with different inputs: 34 | 35 | .. code:: python3 36 | 37 | player = input("Please enter R, P or S (for [R]ock, [P]aper and [S]cissors) ") 38 | computer = "P" 39 | 40 | if player == computer: 41 | print("it's a draw") 42 | 43 | 44 | Exercise 2: Alternative decisions 45 | --------------------------------- 46 | 47 | Insert the words ``elif``, ``else`` and ``if`` into the gaps in the code 48 | so that it runs: 49 | 50 | .. code:: python3 51 | 52 | import random 53 | 54 | player = input("Please enter R, P or S (for [R]ock, [P]aper and [S]cissors) ") 55 | computer = random.choice('RPS') 56 | 57 | ___ player == 'R' and computer == 'P': 58 | print("Computer wins") 59 | ___ player == 'R' and computer == 'S': 60 | print("Player wins") 61 | ___: 62 | print("it's a draw") 63 | 64 | 65 | Exercise 3: Paper 66 | ----------------- 67 | 68 | Extend the program, so that it also works if the player chooses *paper*. 69 | 70 | 71 | Exercise 4: Debugging 72 | --------------------- 73 | 74 | Fix one bug in each ``if``-statement: 75 | 76 | .. code:: python3 77 | 78 | elif player.upper() not in 'RPS': 79 | print('Invalid input. Please enter R,P or S.') 80 | 81 | elif player == computer 82 | print('You chose the same as I did') 83 | 84 | if player = 'S': 85 | print('You chose "scissors".') 86 | 87 | else: 88 | print('You chose something else than "scissors"') 89 | 90 | 91 | Exercise 5: Expressions 92 | ----------------------- 93 | 94 | Which comparisons in the following ``if`` statements result in ``True``: 95 | 96 | .. code:: python3 97 | 98 | a = 3 99 | b = 4 100 | c = 7 101 | 102 | if a + b < c: 103 | print(True) 104 | 105 | if a + b == 5 + 2: 106 | print(True) 107 | 108 | if a * b == 12 and b * c == 28: 109 | print(True) 110 | 111 | if a + b * c >= 28: 112 | print(True) 113 | 114 | if a + b == "7": 115 | print(True) 116 | 117 | 118 | Exercise 6: State variables 119 | --------------------------- 120 | 121 | The following program saves the result of a comparison 122 | in a variable of the data type ``bool``. 123 | Complete the code: 124 | 125 | .. code:: python3 126 | 127 | player_wins = ( 128 | (player == "R" and computer == "S") or 129 | (player == "P" and ___) or 130 | (___) 131 | ) 132 | 133 | if player_wins: 134 | print('You won!') 135 | 136 | 137 | Exercise 7: Nested if statements 138 | -------------------------------- 139 | 140 | Complete the program, so that it covers all possible situations: 141 | 142 | .. code:: python3 143 | 144 | winner = 'draw' 145 | 146 | if player == "S": 147 | if computer == "P": 148 | winner = "player" 149 | elif computer == "T": 150 | winner = "computer" 151 | 152 | elif player == "P": 153 | ___ 154 | 155 | print("The winner is:", winner) 156 | 157 | .. hint:: 158 | 159 | A *nested if* is an if inside another if block. 160 | 161 | 162 | Exercise 8: Rock-Paper-Scissors 163 | ------------------------------- 164 | 165 | Complete the Rock-Paper-Scissors game. 166 | 167 | Optional goals: 168 | ~~~~~~~~~~~~~~~ 169 | 170 | - take draws into account as a possibility 171 | - inputs should be valid in upper and lower case 172 | - use a single ``if..elif..else`` block 173 | - extend the game by `lizard and Spock `__ 174 | - use ``bool`` variables, so that only one or two ``if`` statements 175 | without ``elif`` or ``else``) remain 176 | 177 | Reflection Questions 178 | -------------------- 179 | 180 | * in which order do the parts of an ``if`` statement have to be? 181 | * which parts of an ``if`` statement are optional? 182 | * what is indentation? 183 | * which *comparison operators* do you know so far? 184 | 185 | 186 | .. |image0| image:: rock_paper_scissors.svg 187 | -------------------------------------------------------------------------------- /first_steps/slideshow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/slideshow.png -------------------------------------------------------------------------------- /first_steps/slideshow.rst: -------------------------------------------------------------------------------- 1 | Slideshow 2 | ========= 3 | 4 | .. figure:: slideshow.png 5 | :alt: Example output 6 | 7 | In this chapter you will: 8 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 9 | 10 | ==== =============================== 11 | area topic 12 | ==== =============================== 13 | 🚀 implement a small slideshow 14 | 💡 load and display images 15 | 💡 resize images 16 | ⚙ import the PIL module 17 | ⚙ write file names and file paths 18 | ⚙ iterate over a list 19 | ⚙ index a list 20 | 🔀 use a counter variable 21 | 🐞 fix wrong file paths 22 | ==== =============================== 23 | 24 | 25 | Exercise 1: Display an image 26 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 | 28 | Use the **Pillow** library to display images in Spyder: 29 | 30 | - download the :download:`zipfile with 10 images `. 31 | - unzip the file 32 | - copy the image ``"rainbow.jpg"`` into your folder with Python 33 | programs. 34 | 35 | Create a new program file with the following instructions: 36 | 37 | .. code:: python3 38 | 39 | from PIL import Image 40 | from IPython.display import display 41 | 42 | pic = Image.open('rainbow.jpg') 43 | display(pic) 44 | 45 | Save the program in the same folder as the image and execute it. In 46 | Spyder, you should see the image in the **Python Console** at the bottom 47 | right. 48 | 49 | If you see an error message, the image is probably stored somewhere 50 | else. Please check that it is in the same folder in which you saved the 51 | Python code. 52 | 53 | If you don’t see anything (e.g. because you are using a different 54 | editor), replace the ``display()`` command by: 55 | 56 | .. code:: python3 57 | 58 | pic.show() 59 | 60 | -------------- 61 | 62 | Exercise 2: Paths 63 | ~~~~~~~~~~~~~~~~~ 64 | 65 | Next, we will read an image from a different folder. 66 | 67 | Move the entire ordner with 10 images into your folder with Python 68 | programs. 69 | 70 | Define a variable that contains the name of the folder (also called a 71 | *“path”*): 72 | 73 | .. code:: python3 74 | 75 | from PIL import Image 76 | from IPython.display import display 77 | 78 | path = 'images/' 79 | pic = Image.open(path + 'flower.jpg') 80 | display(pic) 81 | 82 | The *forward slash* is very important to separate names of folders and 83 | files from each other. Python is very picky about whether you use a 84 | forward slah (``/``) or backslash (``\``). 85 | 86 | If you see an error message, it is likely that the images are probably 87 | somewhere else (the image folder and your program are in different 88 | folders). 89 | 90 | -------------- 91 | 92 | Exercise 3: Multiple images 93 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 94 | 95 | Create a list with names of images: 96 | 97 | .. code:: python3 98 | 99 | images = ['rainbow.jpg', 'flower.jpg', 'pebbles.jpg'] 100 | for filename in images: 101 | pic = Image.open(path + filename) 102 | display(pic) 103 | 104 | Add the following instruction to the program: 105 | 106 | :: 107 | 108 | input('press for the next image') 109 | 110 | Where do you need to insert the command to see the next image? 111 | 112 | -------------- 113 | 114 | Exercise 4: Number the images 115 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 116 | 117 | Now every picture should get a number. For that we use a **counter 118 | variable**. 119 | 120 | The counter increases by one in every round of the ``for`` loop, so that 121 | it contains the number of the current image all the time. 122 | 123 | Add the following instructions to the program from the previous 124 | exercise. Find out which line needs to go where: 125 | 126 | .. code:: python3 127 | 128 | print(title) 129 | i = i + 1 130 | i = 0 131 | title = f"Image No. {i}" 132 | 133 | If everything is done correctly, you should see a caption with the right 134 | number below each image, e.g.: 135 | 136 | :: 137 | 138 | Image No. 1 139 | 140 | -------------- 141 | 142 | Exercise 5: Captions 143 | ~~~~~~~~~~~~~~~~~~~~ 144 | 145 | Prepare a list of image captions e.g.: 146 | 147 | .. code:: python3 148 | 149 | captions = [ 150 | 'oil reflections by Daniel Olah', 151 | 'white flower by Annie Spratt', 152 | 'pebbles by John Salzarulo' 153 | ] 154 | 155 | We would like to print one caption at a time. We will use **indexing** 156 | for that. Check what output the following instructions produce: 157 | 158 | .. code:: python3 159 | 160 | print(captions[0]) 161 | 162 | print(captions[2]) 163 | 164 | Insert the variable ``i`` from the previous exercise into the square 165 | bracket to output the right caption for an image, e.g.: 166 | 167 | :: 168 | 169 | Image No. 1 170 | oil reflections by Daniel Olah 171 | 172 | -------------- 173 | 174 | Exercise 6: Manipulating images 175 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 176 | 177 | The **Pillow** library can do a lot more! Try the following instructions 178 | one by one to find out what they do: 179 | 180 | .. code:: python3 181 | 182 | x, y = pic.size 183 | print(x, y) 184 | 185 | b = pic.resize((500, 500)) 186 | display(b) 187 | 188 | b = pic.rotate(45) 189 | display(b) 190 | 191 | b = pic.crop((100, 100, 300, 300)) 192 | display(b) 193 | 194 | pic.save('neues_bild.png') 195 | 196 | There is a very, very detailed documentation of Pillow on 197 | `pillow.readthedocs.io `__. 198 | 199 | -------------- 200 | 201 | Exercise 7: Your own images 202 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 203 | 204 | Use your own images and label them. 205 | 206 | To suppress the last input, you could modify the ``input()``-command: 207 | 208 | .. code:: python3 209 | 210 | if i < len(images): 211 | input('next image') 212 | 213 | Present your slide show. 214 | 215 | **Tip:** *If you want to present larger images, use the mouse to drag 216 | the border of the output window in Spyder and make it bigger.* 217 | 218 | -------------- 219 | 220 | Image sources 221 | ------------- 222 | 223 | The following images were taken from 224 | `unsplash.com `__: 225 | 226 | - Bubbles by Marko Blažević on Unsplash 227 | - Coffee by Nathan Dumlao on Unsplash 228 | - Ivy by asoggetti on Unsplash 229 | - Orange by Vino Li on Unsplash 230 | - Rainbow paint by Daniel Olah on Unsplash 231 | - Pebbles by John Salzarulo on Unsplash 232 | - Waterfall by Ben Guerin on Unsplash 233 | - Clouds by Zbynek Burival on Unsplash 234 | - White flower by Annie Spratt on Unsplash 235 | - Puddle by Erik Mclean on Unsplash 236 | -------------------------------------------------------------------------------- /first_steps/spyder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/spyder.png -------------------------------------------------------------------------------- /first_steps/squares.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/squares.jpg -------------------------------------------------------------------------------- /first_steps/statistics.rst: -------------------------------------------------------------------------------- 1 | Statistics 2 | ========== 3 | 4 | Writing all instructions into a single sequence creates programs that 5 | are hard to debug. Here, you learn to break the code down into smaller 6 | units: **functions**. 7 | 8 | In this chapter you learn: 9 | -------------------------- 10 | 11 | ==== ============================================== 12 | area topic 13 | ==== ============================================== 14 | 🚀 calculate statistics 15 | ⚙ implement a function 16 | ⚙ call a function you defined 17 | 💡 use the ``math`` module 18 | 💡 use the ``sum`` function 19 | 🔀 use a recursive function 20 | ==== ============================================== 21 | 22 | 23 | Exercise 1: Sum up 24 | ------------------ 25 | 26 | Write a function that calculates a sum from a list of numers. Insert 27 | into the gaps: ``numbers``, ``data``, ``def``, ``return``, 28 | ``calc_sum',``\ +=\` 29 | 30 | .. code:: python3 31 | 32 | ____ calc_sum(data): 33 | total = 0 34 | for n in ____: 35 | total ____ n 36 | ____ total 37 | 38 | numbers = [12562, 2178, 342, 129, 384, 208, 164, 82, 41] 39 | s = ____(____) 40 | print(s) 41 | 42 | 43 | Exercise 2: Mean 44 | ---------------- 45 | 46 | Write a function that calculates the arithmetic mean from the following numbers: 47 | 48 | .. code:: python3 49 | 50 | def mean(data): 51 | ... 52 | 53 | numbers = [12562, 2178, 342, 129, 384, 208, 164, 82, 41] 54 | 55 | ... 56 | 57 | Don't forget about the ``return`` statement. 58 | 59 | 60 | Exercise 3: Shortcut 61 | -------------------- 62 | 63 | Simplify the mean function using the function ``sum()``. 64 | 65 | Use your own or the builtin ``sum()`` function. 66 | 67 | 68 | Exercise 4: Standard Deviation 69 | ------------------------------ 70 | 71 | The following program calculates the standard deviation from a list of 72 | numbers. You would like to generalize the code, so that it can be used 73 | with other data sets. Wrap the code for the calculation – but not the 74 | data – in a function. 75 | 76 | .. code:: python3 77 | 78 | import math 79 | 80 | data = [12562, 2178, 342, 129, 384, 208, 164, 82, 41] 81 | 82 | avg = mean(data) 83 | 84 | stdsum = 0.0 85 | for n in data: 86 | stdsum += (n - avg) ** 2 87 | variance = stdsum / len(data) 88 | stdev = math.sqrt(variance) 89 | 90 | print(f"Standard Deviation: {stdev:8.2f}") 91 | 92 | 93 | Exercise 5: Optional Parameters 94 | ------------------------------- 95 | 96 | Explain the program: 97 | 98 | .. code:: python3 99 | 100 | def add(a=2, b=2): 101 | return a + b 102 | 103 | print(add(3, 3)) 104 | print(add(3)) 105 | print(add()) 106 | print(add(b=4)) 107 | 108 | 109 | Exercise 6: Recursion 110 | --------------------- 111 | 112 | Explain the code: 113 | 114 | .. code:: python3 115 | 116 | def factorial(n): 117 | """Calculates the factorial of the given number.""" 118 | if n > 1: 119 | return n * factorial(n - 1) 120 | else: 121 | return 1 122 | 123 | 124 | x = int(input('Please enter a number: ')) 125 | y = factorial(x) 126 | print (f"The result is:\n{x}! = {y}}") 127 | 128 | 129 | Reflection Questions 130 | -------------------- 131 | 132 | - Why is it useful to write functions? 133 | - What do you need to write in a function definition? 134 | - How do you call a function? 135 | - What does the ``return`` statement do? 136 | -------------------------------------------------------------------------------- /first_steps/strings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/strings.png -------------------------------------------------------------------------------- /first_steps/ten_images.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/first_steps/ten_images.zip -------------------------------------------------------------------------------- /first_steps/type_conversions.rst: -------------------------------------------------------------------------------- 1 | Ada Lovelace 2 | ============ 3 | 4 | .. figure:: ada.jpg 5 | :alt: Ada Lovelace 6 | 7 | `Ada Lovelace, image by Alfred Edward Chalon - public 8 | domain `__ 9 | 10 | **Ada Lovelace** was the first human to write a computer program. 11 | This was quite an achievement, given that Ada had to imagine a computer first! 12 | 13 | 14 | In this chapter you will: 15 | ------------------------- 16 | 17 | ==== ================================= 18 | area topic 19 | ==== ================================= 20 | 🚀 calculate the age of Ada Lovelace 21 | ⚙ distinguish data types 22 | 💡 use the data type ``float`` 23 | 💡 convert data types 24 | 🐞 recognize bugs at runtime 25 | ==== ================================= 26 | 27 | 28 | Exercise 1: Ada Lovelace 29 | ------------------------ 30 | 31 | Insert the following pieces into the gaps, so that all instructions are 32 | executed correctly: ``age``, ``int(age)``, ``name``, ``str(born)``, 33 | ``1815`` 34 | 35 | .. code:: python3 36 | 37 | name = "Ada Lovelace" 38 | born = ... 39 | ... = "37" 40 | 41 | text = ... + " was born in the year " + ... + "." 42 | year = born + ... 43 | print(text) 44 | print(year) 45 | 46 | .. hint:: 47 | 48 | Python contains many functions for **type conversion**. 49 | With the functions ``int()``, ``float()`` and ``str()`` you can convert 50 | numbers and strings into each other. 51 | 52 | 53 | Exercise 2: Nine plus nine 54 | -------------------------- 55 | 56 | Insert ``int()`` or ``str()`` into the instructions, 57 | so that all of them run without an error. 58 | 59 | .. code:: python3 60 | 61 | 9 + 9 62 | 9 + "9" 63 | "9" + "9" 64 | 9 * "9" 65 | 66 | 67 | Exercise 3: Output 68 | ------------------ 69 | 70 | Which ``print`` statements work? 71 | 72 | .. code:: python3 73 | 74 | print("9" + "9") 75 | print "nine" 76 | print(str(9) + "nine") 77 | print(9 + 9) 78 | print(9 + int("9")) 79 | print(nine) 80 | print(float("9") + int(9.0)) 81 | 82 | 83 | Exercise 4: Debugging 84 | --------------------- 85 | 86 | The following code should calculate the age of Ada in a year entered by 87 | the user. It contains three bugs. Find and fix them. 88 | 89 | .. code:: python3 90 | 91 | year_of_birth = 1815 92 | year = input('Which year is it? ') 93 | age = year_of_birth - year 94 | 95 | print("Today, Ada Lovelace would be " + age + " years old.") 96 | 97 | 98 | Exercise 5: Age Calculator 99 | -------------------------- 100 | 101 | Write a program where you can enter the year in which you were born. 102 | The program should calculate your age on January 1st of this year. 103 | 104 | Use the following code to calculate the current year: 105 | 106 | .. code:: python3 107 | 108 | import time 109 | 110 | time.time() // (365 * 24 * 60 * 60) + 1970 111 | 112 | .. hint:: 113 | 114 | ``time`` is a Python module. It contains useful functions. 115 | 116 | ``time.time()`` is a function in that module. 117 | It returns the number of seconds since January 1st, 1970 118 | (called the Unix Epoch, the 0 AD of computers). 119 | 120 | 121 | Reflection Questions 122 | -------------------- 123 | 124 | * which variable types have you seen so far? 125 | * what does a type conversion function do? 126 | * what is a ``TypeError``? 127 | -------------------------------------------------------------------------------- /images/baby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/baby.png -------------------------------------------------------------------------------- /images/big_bang_facts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/big_bang_facts.png -------------------------------------------------------------------------------- /images/files.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/files.png -------------------------------------------------------------------------------- /images/functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/functions.png -------------------------------------------------------------------------------- /images/ipo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/ipo.png -------------------------------------------------------------------------------- /images/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/list.png -------------------------------------------------------------------------------- /images/math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/math.png -------------------------------------------------------------------------------- /images/mobydick_count.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/mobydick_count.png -------------------------------------------------------------------------------- /images/os.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/os.png -------------------------------------------------------------------------------- /images/sierpinski.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/sierpinski.png -------------------------------------------------------------------------------- /images/while.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/images/while.png -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | Python Exercises for Beginners 2 | ============================== 3 | 4 | Here you find exercises for people new to Python. 5 | I wrote them for teachers looking for material 6 | and people learning Python by themselves. 7 | 8 | The goal of the exercises is to enable you to write 9 | Python programs up to 200 lines. 10 | The exercises cover six areas: 11 | 12 | =============================== =================================== 13 | area description 14 | =============================== =================================== 15 | 🚀 **applications** programs that do fun stuff 16 | 💡 **functions and data types** useful Python objects 17 | ⚙ **syntax** grammar rules and keywords 18 | 🔀 **patterns** useful expressions and idioms 19 | 🔧 **tools** things that make programming easier 20 | 🐞 **debugging** discover and fix broken code 21 | =============================== =================================== 22 | 23 | 24 | First Steps 25 | ----------- 26 | 27 | .. toctree:: 28 | :maxdepth: 1 29 | 30 | first_steps/installing_python.rst 31 | first_steps/python_shell.rst 32 | first_steps/hello.rst 33 | first_steps/type_conversions.rst 34 | first_steps/rock_paper_scissors.rst 35 | first_steps/for.rst 36 | first_steps/guess_the_number.rst 37 | first_steps/cypher.rst 38 | first_steps/bill.rst 39 | first_steps/dictionaries.md 40 | first_steps/indexing.rst 41 | first_steps/nested_lists.rst 42 | first_steps/builtin_functions.rst 43 | first_steps/slideshow.rst 44 | first_steps/babynames.rst 45 | first_steps/statistics.rst 46 | debugging/README.rst 47 | refactoring/refactoring.rst 48 | challenges/text_adventure.rst 49 | 50 | -------------- 51 | 52 | Coding Challenges 53 | ----------------- 54 | 55 | .. toctree:: 56 | :maxdepth: 1 57 | 58 | challenges/ctree.rst 59 | challenges/fizzbuzz.rst 60 | challenges/quiz.rst 61 | challenges/checker.rst 62 | challenges/baby_name_generator.rst 63 | challenges/palindrome.rst 64 | challenges/anagrams.rst 65 | challenges/tictac.rst 66 | challenges/minesweeper.rst 67 | challenges/gcd.rst 68 | challenges/fibonacci.rst 69 | challenges/querprodukt.rst 70 | challenges/birthdays.rst 71 | challenges/misty_mountains.rst 72 | challenges/sierpinski.rst 73 | challenges/count_words.rst 74 | challenges/spiral.rst 75 | 76 | -------------- 77 | 78 | Reference 79 | --------- 80 | 81 | Examples of common Python commands 82 | 83 | .. toctree:: 84 | :maxdepth: 1 85 | 86 | reference/ipython_shell.rst 87 | reference/run_from_terminal.rst 88 | reference/basics.rst 89 | reference/data_types.rst 90 | reference/numbers.rst 91 | reference/strings.rst 92 | reference/tuples.rst 93 | reference/lists.rst 94 | reference/dictionaries.rst 95 | reference/type_conversions.rst 96 | reference/indexing.rst 97 | reference/print.rst 98 | reference/string_formatting.rst 99 | reference/input.rst 100 | reference/reading_files.rst 101 | reference/writing_files.rst 102 | reference/os.rst 103 | reference/if.rst 104 | reference/for_loops.rst 105 | reference/while.rst 106 | reference/builtin_functions.rst 107 | reference/functions.rst 108 | 109 | 110 | Appendix 111 | -------- 112 | 113 | .. toctree:: 114 | :maxdepth: 1 115 | 116 | links.md 117 | 118 | -------------- 119 | 120 | .. topic:: Acknowledgements 121 | 122 | I would like to thank the following people for inspiring exchange on 123 | training and Python that this tutorial has benefited from: Pedro 124 | Fernandes, Tomasz Puton, 125 | Edward Jenkins, Bernard Szlachta, Robert Lehmann, 126 | and Magdalena Rother 127 | 128 | 129 | .. topic:: License 130 | 131 | © 2023 Dr. Kristian Rother 132 | 133 | with contributions by Allegra Via, Kaja Milanowska, Anna Philips, 134 | @ShalokShalom and @devSython. 135 | 136 | Usable under the conditions of the Creative Commons Attribution Share-alike License 4.0 (CC-BY-SA 4.0). 137 | See `creativecommons.org `__ for details 138 | 139 | Sources of this document can be found on 140 | https://github.com/krother/Python3_Basics_Tutorial 141 | -------------------------------------------------------------------------------- /learning_goals.md: -------------------------------------------------------------------------------- 1 | ## 1 First Steps 2 | 3 | * Data types: int(), float(), str(), list() 4 | * Builtins: print(), input(), range(), len() 5 | * keywords: if, for 6 | * operators: +-*/ =>< and or 7 | 8 | ### 1.1 Installation 9 | 10 | * install Anaconda 11 | * start Spyder 12 | * create a `.py` file 13 | * use keyboard shortcuts 14 | * know where the official Python documentation is 15 | 16 | ### 1.2 Hello World 17 | 18 | * read data from the keyboard 19 | * store a string in a variable 20 | * print the contents of a variable 21 | * comment your code 22 | 23 | ### 1.3 Python as a calculator 24 | 25 | * use the arithmetical operators (`+ - * / ** // %`) 26 | * distinguish integer and float numbers 27 | * convert integers, floats and strings 28 | * use functions from the `math` module 29 | * look up functions from the `math` module 30 | * calculate absolute and rounded values 31 | 32 | ### 1.4 Lists 33 | 34 | * store data in a list 35 | * create data with `range()` 36 | * examine the length of a list 37 | * sort and slice lists 38 | * draw a bar plot 39 | 40 | ### 1.5 Loops 41 | 42 | * iterate over lists and ranges using a for loop 43 | * indent a code block 44 | * distinguish iterables and loop variables 45 | * count the current iteration using a variable 46 | * collect results of a calculation in a list 47 | 48 | ### 1.6 Conditions 49 | 50 | * write `if..elif..else` statements 51 | * count items in a list by a condition 52 | * filter a list by a condition 53 | * combine comparison operators with boolean logic 54 | * modify every second entry of a list 55 | * enumerate operators you can use in comparisons 56 | 57 | ### 1.7 Debugging 58 | 59 | * code, run, debug and repeat 60 | * recognize and fix SyntaxErrors 61 | * recognize and fix IndentationErrors 62 | * recognize and fix runtime Exceptions 63 | * execute code partially and inspect the result 64 | * look up the documentation of functions 65 | -------------------------------------------------------------------------------- /links.md: -------------------------------------------------------------------------------- 1 | 2 | # Recommended books and websites 3 | 4 | ## Online Tutorials and Books 5 | 6 | * [Python for Everybody](https://www.freecodecamp.org/learn/scientific-computing-with-python/python-for-everybody/) - video course with exercises by **Dr. Chuck** 7 | * [W3 Schools Python Tutorial](https://www.w3schools.com/python/default.asp) - Lightweight course with exercises 8 | * [How to think like a Computer Scientist](http://www.greenteapress.com/thinkpython/) - a very systematic, scientific tutorial by **Allen B. Downey** 9 | * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com/) - by **Al Sweigart** 10 | * [Python 101](http://python101.pythonlibrary.org/) - by **Michael Driscoll** 11 | * [Dive into Python 3](https://diveinto.org/python3/table-of-contents.html) - Tutorial for experienced programmers - by **Mark Pilgrim** 12 | * [www.codewars.com](http://www.codewars.com/) – small online coding tasks 13 | 14 | ---- 15 | 16 | ## Official Python Documentation 17 | 18 | * Main documentation and tutorial](http://www.python.org/doc) 19 | * Python Library Reference covering the language basics: [https://docs.python.org/3/library/index.html](https://docs.python.org/3/library/index.html) 20 | * Global Module Index – description of standard modules: 21 | [https://docs.python.org/3/py-modindex.html](https://docs.python.org/3/py-modindex.html) 22 | -------------------------------------------------------------------------------- /refactoring/connect_four.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | # create empty game board 4 | board = [ 5 | [".", ".", ".", ".", ".", ".", "."], 6 | [".", ".", ".", ".", ".", ".", "."], 7 | [".", ".", ".", ".", ".", ".", "."], 8 | [".", ".", ".", ".", ".", ".", "."], 9 | [".", ".", ".", ".", ".", ".", "."], 10 | ] 11 | 12 | while True: 13 | 14 | # print the game board 15 | print() 16 | print("1 2 3 4 5 6 7") 17 | for row in board: 18 | line = "" 19 | for cell in row: 20 | line += cell + " " 21 | print(line) 22 | print() 23 | 24 | # first player moves 25 | x = input("enter a column (1-7) ") 26 | x = int(x) 27 | 28 | # find empty cell closest to bottom 29 | if board[0][x - 1] == ".": 30 | y = 0 31 | if board[1][x - 1] == ".": 32 | y = 1 33 | if board[2][x - 1] == ".": 34 | y = 2 35 | if board[3][x - 1] == ".": 36 | y = 3 37 | if board[4][x - 1] == ".": 38 | y = 4 39 | 40 | board[y][x - 1] = "X" 41 | # end: player moves 42 | 43 | # check rows 44 | for row in board: 45 | for i in range(4): 46 | if ( 47 | row[i] == "X" 48 | and row[i + 1] == "X" 49 | and row[i + 2] == "X" 50 | and row[i + 3] == "X" 51 | ): 52 | print("Player 1 (X) wins!") 53 | sys.exit(0) 54 | 55 | # check columns 56 | for i in range(7): 57 | if board[0][i] == "X" and board[1][i] == "X" and board[2][i] == "X" and board[3][i] == "X": 58 | print("Player 1 (X) wins!") 59 | sys.exit(0) 60 | elif board[1][i] == "X" and board[2][i] == "X" and board[3][i] == "X" and board[4][i] == "X": 61 | print("Player 1 (X) wins!") 62 | sys.exit(0) 63 | 64 | # check diagonals 65 | for y in range(2): 66 | for x in range(4): 67 | if ( 68 | board[y][x] == "X" 69 | and board[y + 1][x + 1] == "X" 70 | and board[y + 2][x + 2] == "X" 71 | and board[y + 3][x + 3] == "X" 72 | ): 73 | print("Player 1 (X) wins!") 74 | sys.exit(0) 75 | for y in range(2): 76 | for x in range(3, 7): 77 | if ( 78 | board[y][x] == "X" 79 | and board[y + 1][x - 1] == "X" 80 | and board[y + 2][x - 2] == "X" 81 | and board[y + 3][x - 3] == "X" 82 | ): 83 | print("Player 1 (X) wins!") 84 | sys.exit(0) 85 | 86 | # print the game board 87 | print() 88 | print("1 2 3 4 5 6 7") 89 | for row in board: 90 | line = "" 91 | for cell in row: 92 | line += cell + " " 93 | print(line) 94 | 95 | print() 96 | 97 | # second player moves 98 | x = input("enter a column (1-7) ") 99 | x = int(x) 100 | 101 | # find empty cell closest to bottom 102 | if board[0][x - 1] == ".": 103 | y = 0 104 | if board[1][x - 1] == ".": 105 | y = 1 106 | if board[2][x - 1] == ".": 107 | y = 2 108 | if board[3][x - 1] == ".": 109 | y = 3 110 | if board[4][x - 1] == ".": 111 | y = 4 112 | 113 | board[y][x - 1] = "O" 114 | 115 | # check rows 116 | for row in board: 117 | for i in range(4): 118 | if ( 119 | row[i] == "O" 120 | and row[i + 1] == "O" 121 | and row[i + 2] == "O" 122 | and row[i + 3] == "O" 123 | ): 124 | print("Player 2 (O) wins!") 125 | sys.exit(0) 126 | 127 | # check columns 128 | for i in range(7): 129 | if board[0][i] == "O" and board[1][i] == "O" and board[2][i] == "O" and board[3][i] == "O": 130 | print("Player 2 (O) wins!") 131 | sys.exit(0) 132 | elif board[1][i] == "O" and board[2][i] == "O" and board[3][i] == "O" and board[4][i] == "O": 133 | print("Player 2 (O) wins!") 134 | sys.exit(0) 135 | 136 | # check diagonals 137 | for y in range(2): 138 | for x in range(4): 139 | if ( 140 | board[y][x] == "O" 141 | and board[y + 1][x + 1] == "O" 142 | and board[y + 2][x + 2] == "O" 143 | and board[y + 3][x + 3] == "O" 144 | ): 145 | print("Player 2 (O) wins!") 146 | sys.exit(0) 147 | for y in range(2): 148 | for x in range(3, 7): 149 | if ( 150 | board[y][x] == "O" 151 | and board[y + 1][x - 1] == "O" 152 | and board[y + 2][x - 2] == "O" 153 | and board[y + 3][x - 3] == "O" 154 | ): 155 | print("Player 2 (O) wins!") 156 | sys.exit(0) 157 | -------------------------------------------------------------------------------- /refactoring/connect_four_clean.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | # create empty playing field 4 | d = [ 5 | [".", ".", ".", ".", ".", ".", "."], 6 | [".", ".", ".", ".", ".", ".", "."], 7 | [".", ".", ".", ".", ".", ".", "."], 8 | [".", ".", ".", ".", ".", ".", "."], 9 | [".", ".", ".", ".", ".", ".", "."], 10 | ] 11 | 12 | P1_PIECE = "X" 13 | P2_PIECE = "O" 14 | 15 | 16 | def print_playing_field(d): 17 | """print the playing field""" 18 | print() 19 | print("1 2 3 4 5 6 7") 20 | for row in d: 21 | line = "" 22 | for cell in row: 23 | line += cell + " " 24 | print(line) 25 | print() 26 | 27 | 28 | def find_empty_cell(d): 29 | """find empty cell closest to bottom""" 30 | for i in range(5): 31 | if d[i][x - 1] == ".": 32 | y = i 33 | return y 34 | 35 | 36 | def check_rows(d, player): 37 | for row in d: 38 | for i in range(4): 39 | if ( 40 | row[i] == player 41 | and row[i + 1] == player 42 | and row[i + 2] == player 43 | and row[i + 3] == player 44 | ): 45 | return True 46 | 47 | 48 | def check_columns(d, player): 49 | """check columns""" 50 | for i in range(7): 51 | if ( 52 | d[0][i] == player 53 | and d[1][i] == player 54 | and d[2][i] == player 55 | and d[3][i] == player 56 | ): 57 | return True 58 | elif ( 59 | d[1][i] == player 60 | and d[2][i] == player 61 | and d[3][i] == player 62 | and d[4][i] == player 63 | ): 64 | return True 65 | 66 | 67 | def check_diagonals(d, player): 68 | """check diagonals""" 69 | for y in range(2): 70 | for x in range(4): 71 | if ( 72 | d[y][x] == player 73 | and d[y + 1][x + 1] == player 74 | and d[y + 2][x + 2] == player 75 | and d[y + 3][x + 3] == player 76 | ): 77 | return True 78 | for y in range(2): 79 | for x in range(3, 7): 80 | if ( 81 | d[y][x] == player 82 | and d[y + 1][x - 1] == player 83 | and d[y + 2][x - 2] == player 84 | and d[y + 3][x - 3] == player 85 | ): 86 | return True 87 | 88 | 89 | won = False 90 | while not won: 91 | for player in [P1_PIECE, P2_PIECE]: 92 | print_playing_field(d) 93 | 94 | # first player moves 95 | x = input("enter a column (1-7) ") 96 | x = int(x) 97 | 98 | y = find_empty_cell(d) 99 | 100 | d[y][x - 1] = player 101 | 102 | won = ( 103 | check_rows(d, player) 104 | or check_columns(d, player) 105 | or check_diagonals(d, player) 106 | ) 107 | if won: 108 | print(f"Player {player} wins!") 109 | break 110 | -------------------------------------------------------------------------------- /refactoring/refactoring.rst: -------------------------------------------------------------------------------- 1 | Connect Four 2 | ============ 3 | 4 | Cleaning up code is an everyday activity of any prorammer. 5 | Clean programs are shorter, easier to understand and easier to change. 6 | The process of cleaning up is also called **refactoring**. 7 | More specifically, refactoring means **improving the structure of a program without 8 | changing its functionality.** 9 | 10 | In this chapter you will: 11 | ------------------------- 12 | 13 | ==== ============================================== 14 | area topic 15 | ==== ============================================== 16 | 🚀 clean up a connect four game 17 | 🔧 read code 18 | 🔧 apply refactoring: extract a function 19 | 🔧 apply refactoring: extract a loop 20 | 🐞 remove redundant code 21 | ==== ============================================== 22 | 23 | Exercise 1 24 | ---------- 25 | 26 | In :download:`connect_four.py` you find a working implementation 27 | of a simple *“Connect Four”* game. 28 | Writing such a program for the first time is a huge success! 29 | 30 | Run the game and see how it works. 31 | 32 | 33 | Exercise 2: Code review 34 | ----------------------- 35 | 36 | The first implementation often requires clean-up. 37 | Read the code in :download:`connect_four.py` 38 | 39 | Do you see any problems in the code? 40 | 41 | 42 | Exercise 3: Extract a function 43 | ------------------------------ 44 | 45 | In the code, there is a paragraph commented with *"print the game board*. 46 | This code paragraph has a well-defined functionality. 47 | Move it into a separate function. 48 | 49 | Define a function at the beginning of the file: 50 | 51 | .. code:: python3 52 | 53 | def print_board(board): 54 | ... 55 | 56 | Move the code paragraph into that function. 57 | Add a function call where you took the code from: 58 | 59 | .. code:: python3 60 | 61 | while True: 62 | 63 | print_board(board): 64 | 65 | # first player moves 66 | ... 67 | 68 | Run the game and make sure it still works. 69 | 70 | 71 | Exercise 4: Redundant code 72 | -------------------------- 73 | 74 | The code for the ``print_board()`` function 75 | appears a second time further below. 76 | 77 | Replace the code by the same function call. 78 | 79 | Because you already defined the function, 80 | you can use it multiple times. 81 | Your program should become shorter by a few lines. 82 | 83 | Run the game and make sure it still works. 84 | 85 | Exercise 5: A function with a parameter 86 | --------------------------------------- 87 | 88 | The next paragraph from *"first player moves"* to *"end: player moves"* 89 | can also be moved to a function. 90 | This time, we introduce an extra function parameter: the symbol for the player. 91 | 92 | Create a new function with the definition: 93 | 94 | .. code:: python3 95 | 96 | def player_move(board, symbol): 97 | ... 98 | 99 | Replace the ``"X"`` in the code by the new variable ``symbol``. 100 | Use the function call: 101 | 102 | .. code:: python3 103 | 104 | player_move(board, "X") 105 | 106 | Run the game and make sure it still works. 107 | 108 | Then, see if there is a similar code paragraph that you could replace by a function call. 109 | 110 | 111 | Exercise 6: More functions 112 | -------------------------- 113 | 114 | See if there are any other redundant blocks of code. 115 | Move them into functions as well. 116 | 117 | Then, run the game and make sure it still works. 118 | 119 | 120 | Exercise 7: Extract a loop 121 | -------------------------- 122 | 123 | Consider the following section of the code: 124 | 125 | .. code:: python3 126 | 127 | if board[0][x - 1] == ".": 128 | y = 0 129 | if board[1][x - 1] == ".": 130 | y = 1 131 | if board[2][x - 1] == ".": 132 | y = 2 133 | if board[3][x - 1] == ".": 134 | y = 3 135 | if board[4][x - 1] == ".": 136 | y = 4 137 | 138 | Here, there is redundant code on a smaller scale. 139 | Each pair of lines differs only by a single number. 140 | This code can be made shorter by using a ``for`` loop 141 | that counts from 0 to 4. 142 | 143 | What needs to be inserted into the two gaps? 144 | 145 | .. code:: python3 146 | 147 | for i in range(5): 148 | if board[___][x - 1] == ".": 149 | y = ___ 150 | 151 | Run the game and make sure it still works. 152 | 153 | 154 | The Code 155 | -------- 156 | 157 | Here is the complete (unclean) code: 158 | 159 | .. literalinclude:: connect_four.py 160 | -------------------------------------------------------------------------------- /reference/basics.rst: -------------------------------------------------------------------------------- 1 | Python Programs 2 | =============== 3 | 4 | A Python program is simply a text file that contains Python statements. 5 | 6 | - All Python programs should have the extension ``.py`` 7 | - Only one command per line is allowed 8 | - The statementsin the file are interpreted line by line 9 | 10 | To execute a Python program, you run it from the command line with: 11 | 12 | :: 13 | 14 | python my_program.py 15 | 16 | For those unfamiliar with the command line all Python editors have 17 | shortcuts to make running a program simpler. 18 | 19 | Variables 20 | --------- 21 | 22 | **Variables** are *‘named containers’* used to store values within 23 | Python. Variable names may be composed of letters, underscores and, 24 | after the first position, also digits. Lowercase letters are common, 25 | uppercase letters are usually used for constants like ``PI``. 26 | 27 | Variables can be used for calculating in place of the values they 28 | contain. 29 | 30 | Variable assignments 31 | -------------------- 32 | 33 | The operator ``=`` is used in Python to define a variable. A Python 34 | statement containing an ``=`` is called a **variable assignment**. The 35 | value on the right side of the equal sign will be stored in a variable 36 | with the name on the left side. 37 | 38 | Changing variables 39 | ------------------ 40 | 41 | You may assign to the same variable name twice: 42 | 43 | 44 | .. code:: python3 45 | 46 | In [1]: emily = 25952 47 | In [2]: emily = 222 48 | In [3]: emily 49 | Out[3]: 222 50 | 51 | In this case, the first value is overwritten by the second assignment. 52 | There is no way to obtain it afterwards. 53 | 54 | Python Statements 55 | ----------------- 56 | 57 | The lines you are writing all the time are also called Python 58 | **Statements**. A Statement is the smallest executable piece of code. 59 | 60 | So far, you have seen at least three different kinds of statements: 61 | 62 | - Calculate a number 63 | - Put a number into a variable 64 | - Print the number from a variable on the screen 65 | 66 | Reserved words 67 | -------------- 68 | 69 | Some words like ``import``, ``for`` and ``in`` are called **reserved 70 | words**. They have a special meaning in Python, which means that you 71 | cannont call a variable ``for`` or ``in``. There are 33 reserved words 72 | in Python 3. 73 | 74 | You can see the complete list with the commands: 75 | 76 | 77 | .. code:: python3 78 | 79 | import keyword 80 | keyword.kwlist 81 | 82 | Code blocks and indentation 83 | --------------------------- 84 | 85 | In Python, **blocks of code** are defined by indentation. They occur 86 | usually after a **control flow statement** (``for``, ``if``) or a 87 | **structural element** (e.g. a function). A code block contains one or 88 | more line that belong to it. Python recognizes this code block by 89 | **indentation**, meaning that each line starts with four extra spaces. 90 | All indented code blocks start with a colon (``:``) at the end of the 91 | line. 92 | 93 | Indentation is a central element of Python syntax. Indentation must not 94 | be used for decorative purposes. 95 | 96 | Comments 97 | -------- 98 | 99 | Comments are lines that are *not* executed. They allow you to document 100 | your code to make it easier to read. Also, you can temporarily disable 101 | lines of code. There are different ways to write comments: 102 | 103 | 104 | .. code:: python3 105 | 106 | # this is a one-line comment 107 | 108 | """This is also a one-line comment""" 109 | 110 | """ 111 | With triple quotes comments can 112 | stretch over multiple lines. 113 | """ 114 | 115 | '''triple single quotes work like triple double quotes.''' 116 | -------------------------------------------------------------------------------- /reference/builtin_functions.rst: -------------------------------------------------------------------------------- 1 | Builtin functions 2 | ================= 3 | 4 | Python 3.11 has 75 builtin functions. To start writing useful programs, 5 | knowing about 20 of them is sufficient. 6 | Many of them are shortcuts that make your everyday 7 | programming a lot easier. 8 | 9 | **These 20 functions are your basic vocabulary, knowing these is a must 10 | to write Python efficiently!** 11 | 12 | =============== ===== ===== ========= 13 | type conversion I/O math iterables 14 | =============== ===== ===== ========= 15 | int print abs range 16 | float input round len 17 | str open sum sorted 18 | bool min reversed 19 | tuple max enumerate 20 | list zip 21 | dict 22 | set 23 | =============== ===== ===== ========= 24 | 25 | Type Conversions 26 | ---------------- 27 | 28 | The **type conversion functions** convert one data type into another. 29 | Examples for them are in an earlier section: 30 | 31 | 32 | .. code:: python3 33 | 34 | int(x) str(x) dict(x) bool(x) 35 | float(x) list(x) tuple(x) set(x) 36 | 37 | Input and output 38 | ---------------- 39 | 40 | Basic reading and writing data requires just three functions: 41 | 42 | 43 | .. code:: python3 44 | 45 | print(s) input(s) open(filename, mode) 46 | 47 | Mathematical functions 48 | ---------------------- 49 | 50 | With ``abs()`` you can calculate the absolute value of a number: 51 | 52 | 53 | .. code:: python3 54 | 55 | >>> abs(-42) 56 | 42 57 | 58 | With ``round()`` you can round numbers to a given number of digits: 59 | 60 | 61 | .. code:: python3 62 | 63 | >>> round(3.14159, 2) 64 | 3.14 65 | 66 | The ``divmod()`` function calculates a division and a modulo at the same 67 | time: 68 | 69 | 70 | .. code:: python3 71 | 72 | >>> divmod(23, 5) 73 | (4, 3) 74 | 75 | The ``pow`` function does the same as the ``**`` operator: 76 | 77 | 78 | .. code:: python3 79 | 80 | >>> pow(3, 3) 81 | 27 82 | 83 | Working with sequences 84 | ---------------------- 85 | 86 | There are tons of functions that help with **Python sequences** (lists, 87 | dictionaries, tuples and *iterators*). The most common ones are: 88 | 89 | 90 | .. code:: python3 91 | 92 | len(x) min(x) sorted(x) enumerate(x) 93 | sum(x) max(x) reversed(x) zip(x) 94 | range(x) 95 | 96 | I will explain them one by one 97 | 98 | Determining the length of sequences 99 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 100 | 101 | The ``len()`` function returns an integer with the length of an 102 | argument. It works with strings, lists, tuples, and dictionaries. 103 | 104 | 105 | .. code:: python3 106 | 107 | >>> data = [0, 1, 2, 3] 108 | >>> len(data) 109 | 4 110 | 111 | Summing up numbers 112 | ------------------ 113 | 114 | The sum of a list of integer or float numbers can be calculated by the 115 | ``sum()`` function. 116 | 117 | 118 | .. code:: python3 119 | 120 | >>> data = [1, 2, 3, 4] 121 | >>> sum(data) 122 | 10 123 | 124 | Smallest and largest value 125 | -------------------------- 126 | 127 | The functions ``min()`` and ``max()`` determine the smallest and largest 128 | value of a list: 129 | 130 | 131 | .. code:: python3 132 | 133 | >>> data = [3, 5, 1, 7] 134 | >>> min(data) 135 | 1 136 | >>> max(data) 137 | 7 138 | 139 | Creating lists of integer numbers 140 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 141 | 142 | The ``range()`` function allows to create lists of numbers on-the-fly. 143 | There are two optional parameters for the start value and the step size. 144 | 145 | 146 | .. code:: python3 147 | 148 | >>> list(range(4)) 149 | [0, 1, 2, 3] 150 | >>> list(range(1, 5)) 151 | [1, 2, 3, 4] 152 | >>> list(range(2, 9, 2)) 153 | [2, 4, 6, 8] 154 | >>> list(range(5, 0, -1)) 155 | [5, 4, 3, 2, 1] 156 | 157 | Note that because ``range()`` returns an **iterator** (a kind of lazy 158 | on-demand list), you need to convert it to a list to see the data. 159 | 160 | Enumerating list elements 161 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 162 | 163 | The ``enumerate()`` function helps with counting elements. It creates 164 | tuples consisting of an integer number starting from zero and the 165 | elements of the list. 166 | 167 | 168 | .. code:: python3 169 | 170 | >>> fruits = ['apple', 'banana', 'orange'] 171 | >>> list(enumerate(fruits)) 172 | [(0, 'apple'), (1, 'banana'), (2, 'orange')] 173 | 174 | Note that ``enumerate()`` produces an iterator. To obtain a list, you 175 | need to convert it. 176 | 177 | ``enumerate()`` is a great shortcut to loops with counter variables: 178 | 179 | 180 | .. code:: python3 181 | 182 | i = 0 183 | for elem in data: 184 | print(i, elem) 185 | i += 1 186 | 187 | becomes simply: 188 | 189 | 190 | .. code:: python3 191 | 192 | for i, elem in enumerate(data): 193 | print(i, elem) 194 | 195 | Sorting data 196 | ~~~~~~~~~~~~ 197 | 198 | The ``sorted()`` function sorts a list or the keys of a dictionary, but 199 | does not change the original data. 200 | 201 | 202 | .. code:: python3 203 | 204 | >>> sorted(data) 205 | [1, 3, 5, 7] 206 | 207 | Reversing data 208 | ~~~~~~~~~~~~~~ 209 | 210 | The ``reversed()`` function reverses the order of list elements, but 211 | does not change the original data. It returns an iterator. 212 | 213 | 214 | .. code:: python3 215 | 216 | >>> data = [3, 5, 1, 7] 217 | >>> list(reversed(data)) 218 | [7, 1, 5, 3] 219 | 220 | Merging two lists 221 | ~~~~~~~~~~~~~~~~~ 222 | 223 | The ``zip()`` function associates the elements of two lists to a single 224 | list or tuple. Excess elements are ignored. 225 | 226 | 227 | .. code:: python3 228 | 229 | fruits = ['apple','banana','orange'] 230 | prices = [0.55, 0.75, 0.80, 1.23] 231 | for fruit, price in zip(fruits, prices): 232 | print(fruit, price) 233 | -------------------------------------------------------------------------------- /reference/data_types.rst: -------------------------------------------------------------------------------- 1 | Data Types in Python 2 | ==================== 3 | 4 | 5 | Match the data samples with their types. 6 | 7 | .. figure:: datatypes.png 8 | :alt: datatype exercise 9 | 10 | datatype exercise 11 | 12 | ========= ========================== ========= ======= 13 | data type description composite mutable 14 | ========= ========================== ========= ======= 15 | int integer numbers no no 16 | float floating-point numbers no no 17 | string characters no no 18 | bool ``True`` or ``False`` no no 19 | list sequence of items yes yes 20 | tuple immutable sequence yes no 21 | dict lookup table yes yes 22 | set collection of unique items yes yes 23 | NoneType just nothing no no 24 | ========= ========================== ========= ======= 25 | 26 | Composite data types 27 | -------------------- 28 | 29 | Some data types are **composite**, meaning that they may contain objects of other types. 30 | For instance, a `list` can contains strings, numbers or even other lists. 31 | 32 | Immutable and mutable data types 33 | -------------------------------- 34 | 35 | In Python there are basic and composite data types. The values of basic 36 | data types cannot be changed, they are **immutable**. Most of the 37 | composite data types are **mutable**. 38 | 39 | -------------- 40 | 41 | Immutable and mutable data types 42 | -------------------------------- 43 | 44 | In Python there are basic and composite data types. The values of basic 45 | data types cannot be changed, they are **immutable**. Most of the 46 | composite data types are **mutable**. 47 | 48 | The immutable data types in Python are: 49 | 50 | - Boolean (``True`` / ``False``) 51 | - Integer (``0``, ``1``, ``-3``) 52 | - Float (``1.0``, ``-0.3``, ``1.2345``) 53 | - Strings (``'apple'``, ``"banana"``) - both single and double quotes are valid 54 | - None (aka an empty variable) 55 | - Tuples (multiple values in parentheses, e.g. \ ``('Jack', 'Smith', 1990)``) 56 | 57 | The mutable data types are 58 | 59 | - List [1, 2, 2, 3] 60 | - Dictionary {‘name’: ‘John Smith’, ‘year’: 1990} 61 | - Set () 62 | 63 | -------------- 64 | 65 | Type conversions 66 | ---------------- 67 | 68 | Values can be converted into each other using *conversion functions*. 69 | Try the following: 70 | 71 | :: 72 | 73 | int('5.5') 74 | float(5) 75 | str(5.5) 76 | list("ABC") 77 | tuple([1,2,3]) 78 | dict([('A',1),('B',2)]) 79 | set([1,2,2,3]) 80 | -------------------------------------------------------------------------------- /reference/datatypes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/reference/datatypes.png -------------------------------------------------------------------------------- /reference/dictionaries.rst: -------------------------------------------------------------------------------- 1 | Dictionaries 2 | ============ 3 | 4 | Dictionaries are unordered, associative arrays. They consist of 5 | key/value pairs. They are very versatile data structures, but more 6 | difficult to use than lists if you are new to Python. As the name 7 | implies, dictionaries are good for looking up things, or **searching** 8 | in general. 9 | 10 | Creating dictionaries 11 | --------------------- 12 | 13 | Python dictionaries are defined with winged brackets. On the left side 14 | of each entry is the **key**, on the right side the **value**: 15 | 16 | 17 | .. code:: python3 18 | 19 | ratios = { 20 | 'Alice': 0.75, 21 | 'Bob': 0.55, 22 | 'Charlie': 0.80 23 | } 24 | 25 | Accessing elements in dictionaries 26 | ---------------------------------- 27 | 28 | By using square brackets and a key, you can retrieve the values from a 29 | dictionary. At least if the key is present: 30 | 31 | 32 | .. code:: python3 33 | 34 | ratios['Alice'] # 0.75 35 | ratios['Ewing'] # KeyError! 36 | 37 | Retrieving values in a fail-safe way: 38 | ------------------------------------- 39 | 40 | With the ``get()`` method you can assign an alternative value if the key 41 | was not found. 42 | 43 | 44 | .. code:: python3 45 | 46 | ratios.get('Alice') 47 | ratios.get('Ewing', 'sorry not found') 48 | 49 | Changing values in a dictionary 50 | ------------------------------- 51 | 52 | The contents of a dictionary can be modified. For instance if you start 53 | with an empty dictionary: 54 | 55 | 56 | .. code:: python3 57 | 58 | persons = {} 59 | 60 | Now you can add values one key/value pair at a time: 61 | 62 | 63 | .. code:: python3 64 | 65 | persons['Emily'] = 1977 66 | 67 | Setting values only if they dont exist yet: 68 | ------------------------------------------- 69 | 70 | 71 | .. code:: python3 72 | 73 | persons.setdefault('Alice', 1980) 74 | persons.setdefault('Emily', 1898) 75 | # for 'Emily', nothing happens 76 | 77 | Getting all keys or values: 78 | --------------------------- 79 | 80 | 81 | .. code:: python3 82 | 83 | ratios.keys() 84 | ratios.values() 85 | ratios.items() 86 | 87 | Checking whether a key exists 88 | ----------------------------- 89 | 90 | The ``in`` operators checks whether a key exists in the dictionary. 91 | 92 | 93 | .. code:: python3 94 | 95 | if 'Bob' in ratios: 96 | print('found it') 97 | 98 | Note that you can use ``in`` for the same with a list as well. The 99 | dictionary is **much faster**! 100 | 101 | Loops over a dictionary 102 | ----------------------- 103 | 104 | You can access the keys of a dictionary in a ``for`` loop. 105 | 106 | 107 | .. code:: python3 108 | 109 | for name in ratios: 110 | print(name) 111 | 112 | However, there is no stable order unless you sort the keys explicitly: 113 | 114 | 115 | .. code:: python3 116 | 117 | for name in sorted(ratios): 118 | print(name) 119 | 120 | What data can I use as keys? 121 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | 123 | Valid types for keys are: 124 | 125 | - integers 126 | - floats 127 | - strings 128 | - tuples 129 | - booleans 130 | 131 | You may mix keys of different type in one dictionary. However, 132 | **mutable** data types such as lists and other dictionaries are not 133 | allowed as keys. 134 | 135 | The concept behind this phenomenon is that dictionaries use a **hash 136 | function** to sort the keys internally. The hash function is what allows 137 | to look up values very quickly. 138 | -------------------------------------------------------------------------------- /reference/for_loops.rst: -------------------------------------------------------------------------------- 1 | Loops with for 2 | ============== 3 | 4 | The ``for`` loop allows you to repeat one or more instructions. To write 5 | a ``for`` loop you need two things: First a **sequence-like 6 | object**\ (e.g. a list, a string, a dictionary or the output of a 7 | function producing sequences). Second, a **variable** that takes 8 | different values as the loop iterates over the sequence. The variable is 9 | easier, because it doesn’t matter what name you give it. 10 | 11 | Things you can iterate over with ``for`` loops: 12 | 13 | - strings (character by character) 14 | - lists 15 | - dictionaries 16 | - files (line by line) 17 | - iterable functions (``range``, ``sorted``, ``reversed``) 18 | 19 | Loops with ``for`` are useful whenever you want to repeat instructions a 20 | known number of times, or when you wnat to do something for *all* 21 | elements of a sequence. Below you find some examples. 22 | 23 | Loops executing a given number of times 24 | --------------------------------------- 25 | 26 | With the ``range()`` function, you can set the number of iterations 27 | easily: 28 | 29 | 30 | .. code:: python3 31 | 32 | for i in range(7): 33 | print(i) 34 | 35 | or using an interval: 36 | 37 | 38 | .. code:: python3 39 | 40 | for i in range(10, 17): 41 | print(i) 42 | 43 | or backwards: 44 | 45 | 46 | .. code:: python3 47 | 48 | for i in range(17, 10, -1): 49 | print(i) 50 | 51 | Loops over a string 52 | ------------------- 53 | 54 | With a string as the sequence, you obtain single characters in each 55 | iteration. 56 | 57 | 58 | .. code:: python3 59 | 60 | for char in 'ABCD': 61 | print(char) 62 | 63 | Loops over a list 64 | ----------------- 65 | 66 | A list iterates simply once through each element: 67 | 68 | 69 | .. code:: python3 70 | 71 | for elem in [1, 22, 333, 4444, 55555]: 72 | print(elem) 73 | 74 | Loops over a dictionary 75 | ----------------------- 76 | 77 | With a dictionary, the ``for`` loop iterates over the keys. Note that 78 | the dictionary is inherently unordered. Theoretically, you could get the 79 | keys in a different order each time. 80 | 81 | 82 | .. code:: python3 83 | 84 | pairs = {'Alice': 'Bob', 'Ada': 'Charlie', 'Visual': 'Basic'} 85 | for key in pairs: 86 | print(key) 87 | print(pairs[key]) 88 | 89 | Looping over two lists simultaneously 90 | ------------------------------------- 91 | 92 | Sometimes, you want to look up corresponding items from two lists. A 93 | straightforward solution is to loop over an index: 94 | 95 | 96 | .. code:: python3 97 | 98 | names = ['Alice', 'Bob', 'Charlie', 'Delia'] 99 | jobs = ['admin', 'builder', 'cook', 'developer'] 100 | 101 | for i in range(4): 102 | print(names[i] + ' works as a ' + jobs[i]) 103 | 104 | However, the *pythonic* solution would be to use ``zip``: 105 | 106 | 107 | .. code:: python3 108 | 109 | for name, job in zip(names, jobs): 110 | print(name + ' works as a ' + job) 111 | 112 | Indented block 113 | -------------- 114 | 115 | All indented commands after the colon are executed *within* a ``for`` 116 | loop. The first unindented command is executed after the loop finishes. 117 | 118 | 119 | .. code:: python3 120 | 121 | for i in range(5): 122 | print('inside') 123 | print('also inside') 124 | print('outside') 125 | -------------------------------------------------------------------------------- /reference/functions.rst: -------------------------------------------------------------------------------- 1 | Functions 2 | ========= 3 | 4 | What is a function? 5 | ------------------- 6 | 7 | A function is an autonomous sub-program with local variables, input and 8 | output. Functions help you divide a program into smaller logical 9 | portions. It is much easier to write, reuse and debug a program 10 | consisting of many small functions than a single huge blob of code. 11 | 12 | In Python, a function definition must be followed by a code block: 13 | 14 | 15 | .. code:: python3 16 | 17 | def calc_price(fruit, n): 18 | '''Returns the price of fruits.''' 19 | if fruit == 'banana': 20 | return 0.75 * n 21 | 22 | print(calc_price('banana', 10)) 23 | 24 | Obligatory and optional parameters 25 | ---------------------------------- 26 | 27 | Each function can have **obligatory** parameters (that *must* be given 28 | when calling the function and **optional** parameters that have default 29 | values. The following function can be called in two ways: 30 | 31 | 32 | .. code:: python3 33 | 34 | def calc_price(fruit, n=1): 35 | '''Returns the price of fruits.''' 36 | if fruit == 'banana': 37 | return 0.75 * n 38 | 39 | print(calc_prices('banana')) 40 | print(calc_prices('banana', 100)) 41 | 42 | Warning 43 | ^^^^^^^ 44 | 45 | Do not use *mutable* default values (e.g. lists and dictionaries) in the 46 | function header. They make a mess! 47 | 48 | List and keyword parameters 49 | --------------------------- 50 | 51 | For even greater flexibility with function parameters you can also add a 52 | list ``*args`` for an unspecified number of extra parameters, or a 53 | dictionary ``**kwargs`` for keyword parameters. 54 | 55 | 56 | .. code:: python3 57 | 58 | def func(*args, **kwargs): 59 | print(args[1]) 60 | print(kwargs['a']) 61 | 62 | func(1, 2, a=3, b=4) 63 | 64 | This example may be a bit hard to digest, but these kinds of parameters 65 | are used widely. 66 | 67 | Return values 68 | ------------- 69 | 70 | A function may return values to the program part that called it. 71 | 72 | 73 | .. code:: python3 74 | 75 | return 0.75 76 | 77 | Multiple values are returned as a tuple. 78 | 79 | 80 | .. code:: python3 81 | 82 | return 'banana', 0.75 83 | 84 | In any case, the ``return`` statement ends the execution of a function. 85 | Nothing speaks against having multiple ``return`` statements in a 86 | function (although for clarity it should not be too many). 87 | -------------------------------------------------------------------------------- /reference/if.rst: -------------------------------------------------------------------------------- 1 | Conditional statements with ``if`` 2 | ================================== 3 | 4 | The ``if`` statement is used to implement decisions and branching in a 5 | program. One or more instructions are only executed if a condition 6 | matches: 7 | 8 | 9 | .. code:: python3 10 | 11 | if name == 'Emily': 12 | studies = 'Physics' 13 | 14 | There must be an ``if`` block, zero or more ``elif``\ ’s and an optional 15 | ``else`` block: 16 | 17 | 18 | .. code:: python3 19 | 20 | if name == 'Emily': 21 | studies = 'Physics' 22 | elif name == 'Maria': 23 | studies = 'Computer Science' 24 | elif name == 'Sarah': 25 | studies = 'Archaeology' 26 | else: 27 | studies = '-- not registered yet --' 28 | 29 | Code blocks 30 | ----------- 31 | 32 | After an ``if`` statement, all indented commands are treated as a code 33 | block, and are executed in the context of the condition. 34 | 35 | The next unindented command is executed in any case. 36 | 37 | Comparison operators 38 | -------------------- 39 | 40 | An ``if`` expression may contain comparison operators like: 41 | 42 | 43 | .. code:: python3 44 | 45 | a == b 46 | a != b 47 | a < b 48 | a > b 49 | a <= b 50 | a >= b 51 | 52 | On lists and strings you can also use: 53 | 54 | 55 | .. code:: python3 56 | 57 | a in b 58 | 59 | Multiple expressions can be combined with boolean logic (``and``, 60 | ``or``, ``not``): 61 | 62 | 63 | .. code:: python3 64 | 65 | a or b 66 | a and b 67 | not a 68 | (a or b) and not (c or d) 69 | 70 | Boolean value of variables 71 | -------------------------- 72 | 73 | Each variable can be interpreted as a boolean (``True``/``False``) 74 | value. All values are treated as ``True``, except for: 75 | 76 | 77 | .. code:: python3 78 | 79 | False 80 | 0 81 | [] 82 | '' 83 | {} 84 | set() 85 | None 86 | -------------------------------------------------------------------------------- /reference/images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/reference/images/cover.jpg -------------------------------------------------------------------------------- /reference/images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/reference/images/cover.png -------------------------------------------------------------------------------- /reference/images/indexing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krother/python_basics/f634254d7fa9039c2b401eedab932e578f45eade/reference/images/indexing.png -------------------------------------------------------------------------------- /reference/indexing.rst: -------------------------------------------------------------------------------- 1 | Indexing and Slicing 2 | ==================== 3 | 4 | **Computers and people count differently:** 5 | 6 | .. figure:: ./images/indexing.png 7 | :alt: indices for humans and computers 8 | 9 | indices for humans and computers 10 | 11 | Computers treat an address in memory as the *starting point* of a body 12 | of data. In the same sense, an *index* in Python always refers to such a 13 | starting point, something that is *in between* two objects in memory. We 14 | humans in contrast always count the objects themselves. 15 | 16 | This is why the indices used to slice lists are a bit unintuitive at 17 | first, e.g. in: 18 | 19 | 20 | .. code:: python3 21 | 22 | >>> s = "my fat cat" 23 | >>> s[3:6] 24 | 'fat' 25 | 26 | The diagram provides a practical model by which you can deduce indices 27 | yourself. 28 | 29 | Indexing 30 | -------- 31 | 32 | Many data types (lists, strings) allow to index items by their position: 33 | 34 | 35 | .. code:: python3 36 | 37 | s = 'my fat cat' 38 | s[0] # first 39 | s[2] # third 40 | s[-1] # last 41 | 42 | Using and index that does not exist causes an ``IndexError``. 43 | 44 | Slicing 45 | ------- 46 | 47 | We can define intervals. This is called **slicing**: 48 | 49 | 50 | .. code:: python3 51 | 52 | s = 'my fat cat' 53 | s[3:6] # -> 'fat' 54 | 55 | Slices may be open on either side: 56 | 57 | 58 | .. code:: python3 59 | 60 | s[3:] # -> 'fat cat' 61 | s[:6] # -> 'my fat' 62 | 63 | If you leave both number out, you copy the variable. This is sometimes a 64 | neat trick, if you want to manipulate a list, but preserve the original. 65 | 66 | 67 | .. code:: python3 68 | 69 | d = [1, 2, 3] 70 | e = d[:] 71 | d.append(4) 72 | len(d) # is now 4 73 | len(e) # still 3 74 | 75 | You can define slices with a step size: 76 | 77 | 78 | .. code:: python3 79 | 80 | s = 'my fat cat' 81 | s[1:8:2] # -> 'yftc' 82 | s[:8:2] # -> 'm a ' 83 | s[1::2] # -> 'yftct' 84 | 85 | The step size may even be negative: 86 | 87 | 88 | .. code:: python3 89 | 90 | s = 'my fat cat' 91 | s[::-1] # -> 'tac taf ym' 92 | -------------------------------------------------------------------------------- /reference/input.rst: -------------------------------------------------------------------------------- 1 | Reading text from the keyboard 2 | ============================== 3 | 4 | The ``input`` function 5 | ---------------------- 6 | 7 | Text can be read from the keyboard with the ``input`` function. 8 | ``input`` works with and without a message text. The value returned is 9 | always a string: 10 | 11 | 12 | .. code:: python3 13 | 14 | a = input() 15 | b = input('Please enter a number') 16 | 17 | Although the ``input`` command is rarely seen in big programs, it often 18 | helps to write small, understandable programs, especially while learning 19 | Python. 20 | -------------------------------------------------------------------------------- /reference/ipython_shell.rst: -------------------------------------------------------------------------------- 1 | The IPython Shell 2 | ================= 3 | 4 | The IPython shell allows you to enter Python commands one by one and 5 | executes them promptly. The IPython shell is a luxury version of the 6 | simpler Python shell. It is also called *interactive mode* or 7 | *interactive Python command line*. 8 | 9 | You can use any Python command from the *IPython Shell*: 10 | 11 | 12 | .. code:: python3 13 | 14 | In [1]: 1 + 1 15 | Out[1]: 2 16 | In [2]: 4 * 16 17 | Out[2]: 64 18 | In [3]: 19 | 20 | Results of each command are automatically printed to the screen. 21 | 22 | How to leave the IPython shell? 23 | ------------------------------- 24 | 25 | - You can leave the command line by Ctrl-z (Windows) or Ctrl-d (Linux). 26 | - If a program seems to be stuck, you can interrupt the shell with 27 | Ctrl-c. 28 | 29 | Magic Methods 30 | ------------- 31 | 32 | The IPython shell has a number of special commands or **Magic Methods**. 33 | Here are the most common ones: 34 | 35 | ============== ========================================= 36 | command description 37 | ============== ========================================= 38 | ``%run`` execute a program 39 | ``%paste`` paste and execute code from the clipboard 40 | ``%hist`` show recently entered commands 41 | ``ls`` show files in the current directory 42 | ``pwd`` print the current working directory 43 | ``cd `` change the working directory to ```` 44 | ``!`` execute ```` on the bash 45 | ============== ========================================= 46 | -------------------------------------------------------------------------------- /reference/lists.rst: -------------------------------------------------------------------------------- 1 | Lists 2 | ===== 3 | 4 | A list is a Python data type representing a sequence of elements. You 5 | can have lists of strings: 6 | 7 | 8 | .. code:: python3 9 | 10 | names = ['Hannah', 'Emily', 'Madison', 'Ashley', 'Sarah'] 11 | 12 | and also lists of numbers: 13 | 14 | 15 | .. code:: python3 16 | 17 | numbers = [25952, 23073, 19967, 17994, 17687] 18 | 19 | Accessing elements of lists 20 | --------------------------- 21 | 22 | Using square brackets, any element of a list and tuple can be accessed. 23 | The first character has the index 0. 24 | 25 | 26 | .. code:: python3 27 | 28 | print(names[0]) 29 | print(numbers[3]) 30 | 31 | Negative indices start counting from the last character. 32 | 33 | 34 | .. code:: python3 35 | 36 | print(names[-1]) 37 | 38 | Creating lists from other lists: 39 | -------------------------------- 40 | 41 | Lists can be sliced by applying square brackets in the same way as 42 | strings. 43 | 44 | 45 | .. code:: python3 46 | 47 | names = ['Hannah', 'Emily', 'Sarah', 'Maria'] 48 | names[1:3] 49 | names[0:2] 50 | names[:3] 51 | names[-2:] 52 | 53 | Copying a list 54 | -------------- 55 | 56 | You can use slicing to create a copy: 57 | 58 | 59 | .. code:: python3 60 | 61 | girls = names[:] 62 | 63 | Adding elements to a list 64 | ------------------------- 65 | 66 | Add a new element to the end of the list: 67 | 68 | 69 | .. code:: python3 70 | 71 | names.append('Marilyn') 72 | 73 | Removing elements from a list 74 | ----------------------------- 75 | 76 | Remove an element at a given index: 77 | 78 | 79 | .. code:: python3 80 | 81 | names.remove(3) 82 | 83 | Remove the last element: 84 | 85 | 86 | .. code:: python3 87 | 88 | names.pop() 89 | 90 | Replacing elements of a list 91 | ---------------------------- 92 | 93 | You can replace individual elements of a list by using an index in an 94 | assignment operation: 95 | 96 | 97 | .. code:: python3 98 | 99 | names[4] = 'Jessica' 100 | 101 | Sorting a list 102 | -------------- 103 | 104 | 105 | .. code:: python3 106 | 107 | names.sort() 108 | 109 | The ``itemgetter`` module allows you to sort lists by a specific column. 110 | E.g. to sort names by the 3rd character: 111 | 112 | 113 | .. code:: python3 114 | 115 | from operator import itemgetter 116 | 117 | cities.sort(key=itemgetter(2)) 118 | 119 | You can give a tuple of indices to sort first by one, then the other 120 | column: 121 | 122 | 123 | .. code:: python3 124 | 125 | cities.sort(key=itemgetter((1, 0))) 126 | 127 | Counting elements 128 | ----------------- 129 | 130 | 131 | .. code:: python3 132 | 133 | names = ['Hannah', 'Emily', 'Sarah', 'Emily', 'Maria'] 134 | names.count('Emily') 135 | -------------------------------------------------------------------------------- /reference/numbers.rst: -------------------------------------------------------------------------------- 1 | Numbers 2 | ======= 3 | 4 | Integer numbers 5 | --------------- 6 | 7 | Numerical values without decimal places are called **integers** or 8 | **ints**. In Python, integers are a predefined **data type**. 9 | 10 | 11 | .. code:: python3 12 | 13 | a = 42 14 | 15 | Floating-point numbers 16 | ---------------------- 17 | 18 | Numbers with decimal places are called **floating-point numbers** or 19 | **floats**. 20 | 21 | 22 | .. code:: python3 23 | 24 | b = 42.0 25 | pi = 3.14159 26 | 27 | Arithmetical Operators 28 | ---------------------- 29 | 30 | The arithmetical symbols like ``+ - * /`` connecting two numbers are 31 | called **operators**. In addition to the standard arithmetics a few 32 | other operators are available: 33 | 34 | 35 | .. code:: python3 36 | 37 | a = 7 38 | b = 4 39 | c = a - b 40 | d = a * b 41 | e = a / b 42 | f = a % b # modulo, 3 43 | g = a ** 2 # 49 44 | h = 7.0 // b # floor division, 1.0 45 | 46 | If you perform arithmetics with integer numbers, the result is also an 47 | integer. If one of the numbers is a float, the result will also be a 48 | float. When you perform a division, the result is always a 49 | floating-point number. 50 | 51 | Rounding and binary representation 52 | ---------------------------------- 53 | 54 | Occasionally, seemingly simple floating-point calculations will result 55 | in strange results, e.g. instead of ``0.3`` you might see: 56 | 57 | 58 | .. code:: python3 59 | 60 | >>> 0.1 + 0.2 61 | 0.30000000000000004 62 | 63 | This is related to the underlying binary representation of 64 | floating-point numbers. The precision of floats is by default 16 digits, 65 | which is enough for most applications (be aware that it might not, if 66 | you are doing astrophysics or other high-precision calculations). 67 | 68 | (This happens in all programming languages that use floats with limited 69 | precision, but they might round the floats automatically.) 70 | -------------------------------------------------------------------------------- /reference/operators.rst: -------------------------------------------------------------------------------- 1 | 2 | Operators 3 | ========= 4 | 5 | Here is an almost complete list of operators in Python. 6 | 7 | Arithmetics 8 | ----------- 9 | 10 | The operators are 11 | 12 | :: 13 | 14 | + - * / 15 | // ** % 16 | 17 | Comparison 18 | 19 | < > <= => == != 20 | 21 | and or not 22 | 23 | in not in 24 | 25 | & | 26 | 27 | -------------------------------------------------------------------------------- /reference/os.rst: -------------------------------------------------------------------------------- 1 | Working with directories 2 | ======================== 3 | 4 | Importing the os module 5 | ----------------------- 6 | 7 | Here, we will for the first time use a function that is not readily 8 | available in Python - it needs to be imported: 9 | 10 | 11 | .. code:: python3 12 | 13 | import os 14 | 15 | ``os`` is the name of a module that is automatically installed with 16 | Python. It is simply not kept in memory all the time. This is why we 17 | need to import it. 18 | 19 | Listing files in a directory: 20 | ----------------------------- 21 | 22 | The function 23 | 24 | 25 | .. code:: python3 26 | 27 | y = os.listdir("my_folder") 28 | 29 | gives you a list of all files in the directory ``my_folder`` and stores 30 | it in the variable ``y``. 31 | 32 | Changing directories 33 | -------------------- 34 | 35 | With the os module, you can change the current directory: 36 | 37 | 38 | .. code:: python3 39 | 40 | import os 41 | os.chdir('../python') 42 | 43 | Check whether a file exists 44 | --------------------------- 45 | 46 | 47 | .. code:: python3 48 | 49 | print(os.path.exists('my_file.txt')) 50 | 51 | Check file modification time 52 | ---------------------------- 53 | 54 | 55 | .. code:: python3 56 | 57 | import time 58 | 59 | t = os.path.getmtime('/home/krother/.bashrc') 60 | gmt = time.gmtime(t) 61 | time.strftime("%Y-%m-%d, %H:%M:%S", gmt) 62 | 63 | Overview 64 | -------- 65 | 66 | The table lists some frequently used functions in ``os``: 67 | 68 | ================================ ================================================= 69 | function description 70 | ================================ ================================================= 71 | ``os.listdir(path)`` returns list of file names in ``path`` 72 | ``os.remove(path)`` removes a file 73 | ``os.getcwd()`` returns current working directory 74 | ``os.path.exists(path)`` checks whether the given file or directory exists 75 | ``os.path.isdir(path)`` checks whether the given path is a directory 76 | ``os.path.isfile(path)`` checks whether the given path is a file 77 | ``os.path.getsize(path)`` returns file size 78 | ``os.path.getmtime(path)`` returns modification time 79 | ``os.path.split(path)`` cuts off the last dir/file name 80 | ``os.path.join(d1, d2, d3, ..)`` connects names by path separator 81 | ``os.environ[key]`` dictionary of environment variables 82 | ``os.system(cmd)`` executes shell command 83 | ================================ ================================================= 84 | -------------------------------------------------------------------------------- /reference/print.rst: -------------------------------------------------------------------------------- 1 | Writing to the Screen 2 | ===================== 3 | 4 | The command ``print()`` Writes tex output to the screen. It accepts one 5 | or more arguments in parentheses - all things that will be printed. You 6 | can print both strings and integer numbers. You can also provide 7 | variables as arguments to ``print()``. 8 | 9 | We need ``print`` because typing a variable name in a Python program 10 | does not give you any visible output. 11 | 12 | The Python ``print`` function is very versatile and accepts many 13 | combinations of strings, numbers, function calls, and arithmetic 14 | operations separated by commas. 15 | 16 | Examples for print statements: 17 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18 | 19 | .. code:: python3 20 | 21 | print('Hello World\n') 22 | print(3 + 4) 23 | print(3.4) 24 | 25 | print("""Text that 26 | stretches over 27 | multiple lines. 28 | """) 29 | 30 | print('number', 77) 31 | 32 | a = "7" 33 | print(a * 7) 34 | print(int(a) * 7) 35 | print("Hello", end=" ") 36 | print("World") 37 | -------------------------------------------------------------------------------- /reference/reading_files.rst: -------------------------------------------------------------------------------- 1 | Reading text files 2 | ================== 3 | 4 | Opening a file for reading 5 | -------------------------- 6 | 7 | Text files can be accessed using the ``open()`` function. ``open()`` 8 | gives you a *file object* that you can use in a ``for`` loop. The loop 9 | processes the contents of the file line by line: 10 | 11 | 12 | .. code:: python3 13 | 14 | f = open('my_file.txt') 15 | for line in f: 16 | print(line) 17 | 18 | Alternatively, you can write both commands in one line: 19 | 20 | 21 | .. code:: python3 22 | 23 | for line in open('my_file.txt'): 24 | print(line) 25 | 26 | Reading an entire file to a string variable. 27 | -------------------------------------------- 28 | 29 | You can read the entire content of a file to a single string: 30 | 31 | 32 | .. code:: python3 33 | 34 | f = open('my_file.txt') 35 | text = f.read() 36 | 37 | Reading a table with multiple columns 38 | ------------------------------------- 39 | 40 | Frequently you have data in text files separated into multiple columns, 41 | like this: 42 | 43 | :: 44 | 45 | Emily;Smith;23 46 | Charlie;Parker;45 47 | 48 | This file can be read with the following simple pattern: 49 | 50 | 51 | .. code:: python3 52 | 53 | for line in open('my_file.txt'): 54 | columns = line.strip().split(';') 55 | first = columns[0] 56 | last = columns[1] 57 | age = int(columns[2]) 58 | 59 | This pattern goes through a file line by line (the ``for`` line). It 60 | then chops off the newline character from each line (``strip``) and 61 | finally breaks the line into a list of items at the ``;`` character 62 | (``split``). 63 | 64 | The ``str.strip()`` function 65 | ---------------------------- 66 | 67 | With the string function ``strip()``, you chop off whitespace characters 68 | (spaces, newline characters and tabs) from both ends of a string. The 69 | code: 70 | 71 | 72 | .. code:: python3 73 | 74 | text = " this is my message " 75 | s = text.strip() 76 | print(s) 77 | 78 | produces ``"this is my message"``. 79 | 80 | The ``str.split()`` function 81 | ---------------------------- 82 | 83 | With the string function ``split(x)``, you can divide a string into a 84 | list of strings. ``x`` is the character at which you want to separate 85 | the columns (by default it splits on whitespace). 86 | 87 | 88 | .. code:: python3 89 | 90 | s = "this is text" 91 | t = s.split(" ") 92 | print(t) 93 | 94 | ["this", "is", "text"] 95 | 96 | Both ``strip()`` and ``split()`` perfectly complement each other. 97 | 98 | More sophisticated ways to read tabular information can be found in the 99 | Python modules ``csv`` and ``pandas``. 100 | 101 | Writing file and directory names 102 | -------------------------------- 103 | 104 | When opening files, you often need to specify a directory name as well. 105 | You can use both full or relative directory names. A full file name 106 | contains the entire path from the root directory, e.g.: 107 | 108 | :: 109 | 110 | /home/kristian/Desktop/myfile.txt 111 | 112 | or on Windows 113 | 114 | :: 115 | 116 | C:/Python3/python.exe 117 | 118 | A relative directory name starts from the current working directory, 119 | often the directory in which your program is started: 120 | 121 | :: 122 | 123 | data/my_file.txt 124 | 125 | or go one directory level up, then move into the folder below: 126 | 127 | :: 128 | 129 | ../data/my_file.txt 130 | 131 | Slashes versus Backslashes 132 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 133 | 134 | On Windows, getting directory names right is a bit cumbersome, because 135 | the directory names easily become long easily. Note that you can use 136 | forward slashed to separate between directories. If you use the 137 | backslash ``\``, you need to write a double backslash ``\\`` (because 138 | ``\`` is also used for escape sequences like ``\n`` and ``\t``). 139 | 140 | 141 | .. code:: python3 142 | 143 | f = open('..\\my_file.txt') 144 | f = open('C:\\Python\\my_file.txt') 145 | 146 | Closing files 147 | ------------- 148 | 149 | Closing files in Python is not mandatory but good practice. If you open 150 | too many files at the same time this can be a problem. 151 | 152 | 153 | .. code:: python3 154 | 155 | f.close() 156 | 157 | Reading files with a Context Manager 158 | ------------------------------------ 159 | 160 | The modern way to open files in Python is using a **Context Manager** (a 161 | code block started by ``with``). The ``with`` statement takes care of 162 | closing the file automatically: 163 | 164 | .. code:: python3 165 | 166 | with open('my_file.txt') as f: 167 | text = f.read() 168 | -------------------------------------------------------------------------------- /reference/run_from_terminal.rst: -------------------------------------------------------------------------------- 1 | 2 | Running Code from a Terminal 3 | ============================ 4 | 5 | In this chapter, you find a recipe to run a Python program from a command line or terminal. 6 | The recipe focuses on Windows users, because this is where the problem is most prevalent. 7 | 8 | Step 1: Create a project folder 9 | ------------------------------- 10 | 11 | Create a new folder for the project. 12 | In this exammple, name it ``hello``. 13 | 14 | Step 2: Create a Python file 15 | ---------------------------- 16 | 17 | Open your favorite code editor and create a new file ``hello.py``. 18 | Write a single line into it: 19 | 20 | .. code:: python3 21 | 22 | print("hello world") 23 | 24 | Store it in the new project folder ``hello``. 25 | 26 | 27 | Step 3: Open a terminal 28 | ----------------------- 29 | 30 | Start a new terminal session. 31 | 32 | On Windows, search for **Anaconda Prompt** in the Start Menu. 33 | 34 | In any case, you should see the text `(base)` at the beginning of the line with the prompt. 35 | This means Anaconda is installed and the terminal is properly set up for it. 36 | 37 | Step 4: Change directory 38 | ------------------------ 39 | 40 | Use the `cd ` command to switch in the terminal to the new project directory. 41 | 42 | On Windows, you can click into the address bar of the browser, copy the complete PATH to your project and paste it right after the `cd` command. 43 | 44 | When you type `dir` or `ls`, you should see the contents of the folder. 45 | 46 | Step 5: Run the program 47 | ----------------------- 48 | 49 | In the same terminal, type: 50 | 51 | :: 52 | 53 | python hello.py 54 | 55 | And you should se the message `hello world` appear. 56 | -------------------------------------------------------------------------------- /reference/string_formatting.rst: -------------------------------------------------------------------------------- 1 | String formatting 2 | ================= 3 | 4 | Variables and strings can be combined, using **f-strings**. f-strings 5 | contain placeholders with variable names and format characters. Here are 6 | some examples: 7 | 8 | 9 | .. code:: python3 10 | 11 | name = 'Roger' 12 | number = 42 13 | pi = 3.14159 14 | 15 | print(f'Hello {name}') 16 | print(f'Result: {number:6d}') 17 | print(f'{number:06d}') 18 | print(f'{name:>20} {name:20}') 19 | print(f'{pi:8.3f}) 20 | 21 | The winged brackets are placeholders for the parameters in the 22 | ``format`` function. Thy consist of two parts ``{a:b}``. Part ``a`` is a 23 | variable name (or expression). The optional part ``b`` contains format 24 | characters. Options include: 25 | 26 | - ``{var}`` – insert the variable only. 27 | - ``{var:xd}`` – an integer with x digits. 28 | - ``{var:5}`` – a right-aligned string of width 5. 32 | - ``{:6.2f}`` – a float number with 6 digits (2 after the dot). 33 | 34 | Remark 35 | ~~~~~~ 36 | 37 | The older method ``.format()`` (prior to Python 3.6) is sometimes used 38 | for string formatting: 39 | 40 | 41 | .. code:: python3 42 | 43 | print('{:6.3f}/{:6.3f}'.format(a, b)) 44 | -------------------------------------------------------------------------------- /reference/strings.rst: -------------------------------------------------------------------------------- 1 | Strings 2 | ======= 3 | 4 | Text values are called **strings**. In Python, strings are defined by 5 | single quotes, double quotes, triple-single or triple-double-quotes: 6 | 7 | 8 | .. code:: python3 9 | 10 | first = 'Emily' 11 | first = "Emily" 12 | first = '''Emily''' 13 | first = """Emily""" 14 | 15 | Special characters 16 | ------------------ 17 | 18 | Some characters in Python require special attention: 19 | 20 | ========= ======================== 21 | character meaning 22 | ========= ======================== 23 | ``\n`` Newline character 24 | ``\t`` tabulator 25 | ``\\`` normal, single backslash 26 | ========= ======================== 27 | 28 | Additionally, Python 3 encodes **Unicode** characters including German 29 | Umlauts, Chinese and Arab alphabets by default. However, they may not be 30 | interpreted in the same way in different environments. Just be a bit 31 | careful when using them. 32 | 33 | String concatenation 34 | -------------------- 35 | 36 | The operator ``+`` also works for strings, only that it concatenates the 37 | strings. It does not matter whether you write the strings as variables 38 | or as explicit values. 39 | 40 | With ``first = 'Emily'`` and ``last = 'Smith'`` the following three 41 | statements have the same result: 42 | 43 | 44 | .. code:: python3 45 | 46 | name = first + last 47 | name = first + "Smith" 48 | name = "Emily" + "Smith" 49 | 50 | Accessing single characters 51 | --------------------------- 52 | 53 | Using square brackets, any character of a string can be accessed. This 54 | is called **indexing**. The first character has the index ``[0]``, the 55 | second ``[1]`` and the fourth has the index ``[3]``. 56 | 57 | 58 | .. code:: python3 59 | 60 | name[0] 61 | name[3] 62 | 63 | With negative numbers, you can access single characters from the end, 64 | the index ``[-1]`` being the last, ``[-2]`` the second last character 65 | and so on: 66 | 67 | 68 | .. code:: python3 69 | 70 | name[-1] 71 | name[-2] 72 | 73 | Note that none of these modify the contents of the string variable. 74 | 75 | Creating substrings 76 | ------------------- 77 | 78 | Substrings can be formed by applying square brackets with two numbers 79 | inside separated by a colon (slices). The second number is not included 80 | in the substring itself. 81 | 82 | 83 | .. code:: python3 84 | 85 | name = 'Emily Smith' 86 | name[0:5] 87 | name[1:4] 88 | name[6:11] 89 | name[:3] 90 | name[-4:] 91 | 92 | String methods 93 | -------------- 94 | 95 | Every string in Python brings a list of functions to work with it. As 96 | the functions are contained within the string they are also called 97 | **methods**. They are used by adding the ``.`` to the string variable 98 | followed by the method name. 99 | 100 | Below you find a few of the available methods: 101 | 102 | Changing case 103 | ~~~~~~~~~~~~~ 104 | 105 | 106 | .. code:: python3 107 | 108 | name = 'Manipulating Strings \n' 109 | name.upper() 110 | name.lower() 111 | 112 | Removing whitespace at both ends 113 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | 115 | 116 | .. code:: python3 117 | 118 | name.strip() 119 | 120 | Cutting a string into columns 121 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | 123 | 124 | .. code:: python3 125 | 126 | name.split(' ') 127 | 128 | Searching for substrings 129 | ~~~~~~~~~~~~~~~~~~~~~~~~ 130 | 131 | 132 | .. code:: python3 133 | 134 | name.find('ing') 135 | 136 | The method returns the start index of the match. The result -1 means 137 | that no match has been found. 138 | 139 | Replacing substrings 140 | ~~~~~~~~~~~~~~~~~~~~ 141 | 142 | 143 | .. code:: python3 144 | 145 | name.replace('Strings','text') 146 | 147 | Checking beginning and end of a string 148 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 149 | 150 | Both of the following functions return a boolean: 151 | 152 | 153 | .. code:: python3 154 | 155 | name.startswith('Man') 156 | name.endswith('ings') 157 | -------------------------------------------------------------------------------- /reference/tuples.rst: -------------------------------------------------------------------------------- 1 | Tuples 2 | ====== 3 | 4 | A tuple is a sequence of elements that cannot be modified. They are 5 | useful to group elements of different type. 6 | 7 | 8 | .. code:: python3 9 | 10 | person = ('Emily', 'Smith', 23) 11 | 12 | In contrast to lists, tuples can also be used as **keys** in 13 | dictionaries. 14 | 15 | Indexing tuples 16 | --------------- 17 | 18 | Elements of tuples can be indexed in the same way as lists: 19 | 20 | 21 | .. code:: python3 22 | 23 | person[0] 24 | person[-2] 25 | person[1:] 26 | 27 | Iterating over tuples 28 | --------------------- 29 | 30 | You can run a ``for`` loop over a tuple: 31 | 32 | 33 | .. code:: python3 34 | 35 | for elem in person: 36 | print(elem) 37 | 38 | Packing and unpacking tuples 39 | ---------------------------- 40 | 41 | Enumerating multiple values separated by a comma implictly creates 42 | tuples: 43 | 44 | 45 | .. code:: python3 46 | 47 | person = 'Emily', 'Smith', 23 48 | 49 | Tuples can be unpacked to multiple variables: 50 | 51 | 52 | .. code:: python3 53 | 54 | first, last, age = person 55 | 56 | It is even possible to swap the value of variables that way: 57 | 58 | 59 | .. code:: python3 60 | 61 | first, last = last, first 62 | -------------------------------------------------------------------------------- /reference/type_conversions.rst: -------------------------------------------------------------------------------- 1 | Type conversions 2 | ================ 3 | 4 | Converting numbers to strings 5 | ----------------------------- 6 | 7 | If you have an integer or float number ``i``, you can make a string out 8 | of it with ``str(i)``: 9 | 10 | 11 | .. code:: python3 12 | 13 | text = str(2000) 14 | 15 | Alternatively, you can insert variables into an f-string (since Python 16 | 3.6): 17 | 18 | 19 | .. code:: python3 20 | 21 | number = 2000 22 | text = f"the year is: {number}" 23 | 24 | Format strings allow you to express floats with a given precision: 25 | 26 | 27 | .. code:: python3 28 | 29 | pi = 3.14159 30 | text = f"{pi:4.2f}" 31 | 32 | Also see `String formatting `__. 33 | 34 | Converting strings to numbers 35 | ----------------------------- 36 | 37 | If you have a string ``s``, you can make an integer out of it with 38 | ``int(s)``: 39 | 40 | 41 | .. code:: python3 42 | 43 | number = int("2000") 44 | 45 | The same works for a float: 46 | 47 | 48 | .. code:: python3 49 | 50 | number = float("3.14159") 51 | 52 | Other type conversions 53 | ---------------------- 54 | 55 | The functions ``int()``, ``float()`` and ``str()`` change the type of 56 | the given data. They are therefore called **type conversions**. There is 57 | a *conversion functions* for each Python data type. Try the following: 58 | 59 | 60 | .. code:: python3 61 | 62 | int('5.5') 63 | float(5) 64 | str(5.5) 65 | list("ABC") 66 | tuple([1, 2, 3]) 67 | dict([('A', 1), ('B', 2)]) 68 | set([1, 2, 2, 3]) 69 | -------------------------------------------------------------------------------- /reference/while.rst: -------------------------------------------------------------------------------- 1 | Conditional loops with while 2 | ============================ 3 | 4 | Another control flow statement is the **conditional loop** with 5 | ``while``. While loops combine the properties ``for`` and ``if``. The 6 | loop is executed as long as the conditional expression at the beginning 7 | holds. The conditional expressions work in exactly the same way as in 8 | ``if`` statements. 9 | 10 | Counting until a certain value 11 | ------------------------------ 12 | 13 | A simple usage of while is to count until an exit condition is met. The 14 | following loop calculates the sum of all numbers from 1 through 10: 15 | 16 | 17 | .. code:: python3 18 | 19 | i = 0 20 | total = 0 21 | while i < 10: 22 | print(i) 23 | i = i + 1 24 | total = total + i 25 | 26 | Searching through data 27 | ---------------------- 28 | 29 | With a ``while`` loop you can perform search operations - although many 30 | times the methods on lists and dictionaries will give you a shortcut. 31 | 32 | The following loop finds the first name starting with an ``'E'``: 33 | 34 | 35 | .. code:: python3 36 | 37 | data = ['Alice', 'Bob', 'Charlie', 'Emily', 'Fred'] 38 | i = 0 39 | while i < len(data) and not data[i].startswith('E'): 40 | i += 1 41 | print(i) 42 | 43 | Waiting for user input 44 | ---------------------- 45 | 46 | A ``while`` loop is also useful to let a user stop the program: 47 | 48 | 49 | .. code:: python3 50 | 51 | number = 0 52 | while input('press [Enter] to continue or [x] to exit') != 'x': 53 | number = number +1 54 | print(number) 55 | 56 | Endless loops 57 | ------------- 58 | 59 | With ``while`` it is possible to build loops that never stop. Most of 60 | the time this happens by accident. In the following loop, the 61 | instruction to decrease ``a`` is missing. It runs endlessly: 62 | 63 | 64 | .. code:: python3 65 | 66 | a = 10 67 | b = 1 68 | while a > 0: 69 | b = 1 - b 70 | print(b) 71 | -------------------------------------------------------------------------------- /reference/writing_files.rst: -------------------------------------------------------------------------------- 1 | Writing text files 2 | ================== 3 | 4 | Opening a file for writing 5 | -------------------------- 6 | 7 | Writing text to files is very similar to reading. One main difference is 8 | that you need to add the ``'w'`` parameter for *writing*. 9 | 10 | 11 | .. code:: python3 12 | 13 | f = open('my_file.txt','w') 14 | f.write(text) 15 | f.close() 16 | 17 | Writing a list of strings 18 | ------------------------- 19 | 20 | If your data is a list of strings, it can be written to a file in one 21 | line of code. You only need to take care of adding line breaks at the 22 | end of each line: 23 | 24 | 25 | .. code:: python3 26 | 27 | lines = ['first line\n', 'second line\n'] 28 | open('my_file.txt','w').writelines(lines) 29 | 30 | Writing a table to a text file 31 | ------------------------------ 32 | 33 | A straightforward pattern to write multiple columns to a file uses a 34 | ``for`` loop to create lines with separators and newline characters: 35 | 36 | 37 | .. code:: python3 38 | 39 | names = ['Emily', 'Bob', 'Charlie'] 40 | ages = [23, 45, 67] 41 | 42 | f = open('my_file.txt', 'w') 43 | for name, age in zip(names, ages): 44 | line = "{};{}\n".format(name, age) 45 | f.write(line) 46 | f.close() 47 | 48 | Like with reading, the ``csv`` and ``pandas`` offer more sophisticated 49 | ways to write tables. 50 | 51 | Appending to a file 52 | ------------------- 53 | 54 | It is possible to append text to an existing file, too. 55 | 56 | 57 | .. code:: python3 58 | 59 | f = open('my_file.txt','a') 60 | f.write('line appended at the end\n') 61 | f.close() 62 | 63 | Closing a file after writing 64 | ---------------------------- 65 | 66 | When writing data, Python *buffers* the data and writes it to the disk 67 | with a delay. The writing occurs after the file has been closed, when 68 | Python ends or when the buffer runs full. By using ``close()`` you make 69 | sure the data gets written. 70 | 71 | 72 | .. code:: python3 73 | 74 | f.close() 75 | 76 | Writing to a file with a Context Manager 77 | ---------------------------------------- 78 | 79 | The ``with`` statement is a **Context Manager** that takes care of 80 | closing a file automatically: 81 | 82 | 83 | .. code:: python3 84 | 85 | with open('my_file', 'w') as f: 86 | f.write('line of text\n') 87 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx 2 | sphinx-design 3 | sphinx-copybutton 4 | myst-parser 5 | git+https://github.com/krother/academis_sphinx_theme.git 6 | -------------------------------------------------------------------------------- /solutions/anagrams.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | from itertools import permutations 3 | 4 | 5 | def anagram(s1: str, s2: str) -> bool: 6 | """clean and neat solution in O(n log n) time""" 7 | return sorted(s1) == sorted(s2) 8 | 9 | 10 | def anagram(s1: str, s2: str) -> bool: 11 | """from scratch solution, also O(n log n) because of 'in' """ 12 | if len(s1) == len(s2): 13 | for c1 in s1: 14 | if c1 not in s2: 15 | return False 16 | return True 17 | return False 18 | 19 | def anagram(s1: str, s2: str) -> bool: 20 | """faster O(n) but fails for character duplicates""" 21 | return set(s1) == set(s2) 22 | 23 | def anagram(s1: str, s2: str) -> bool: 24 | """using counter dict, covers duplicates and should be O(n)""" 25 | return Counter(s1) == Counter(s2) 26 | 27 | 28 | def anagram(s1: str, s2: str) -> bool: 29 | """super slow, probably O(n!)""" 30 | return tuple(s1) in permutations(s2) 31 | 32 | 33 | 34 | assert anagram("players", "parsley") is True 35 | assert anagram("hello", "foo") is False -------------------------------------------------------------------------------- /solutions/checker.py: -------------------------------------------------------------------------------- 1 | """ 2 | Explain the code 3 | """ 4 | 5 | def square(x, y): 6 | return "#" if (x+y) % 2 == 0 else "_" 7 | 8 | checker = '\n'.join([''.join([square(x, y) for x in range(8)]) for y in range(8)]) 9 | print(checker) 10 | -------------------------------------------------------------------------------- /solutions/comprehensions.py: -------------------------------------------------------------------------------- 1 | # Comprehensions with numbers 2 | 3 | Create the following data structures with one-liners 4 | 5 | [x for x in range(7)] 6 | 7 | [x**2 for x in range(7)] 8 | 9 | [round(x**0.5, 2) for x in range(7)] 10 | 11 | [x for x in range(100) if x**0.5 == int(x**0.5)] 12 | 13 | {x: round(x**0.5, 2) for x in range(7)} 14 | 15 | sum([int(x) for x in "123456789"]) 16 | 17 | [x*y for x in range(3) for y in range(3)] 18 | 19 | [[x*y for y in range(3)] for x in range(3)] 20 | 21 | import random 22 | sorted([random.random() for i in range(10)]) 23 | 24 | import random 25 | [random.randint(1, 6) for i in range(10)] 26 | 27 | #---------------------------------------------- 28 | 29 | # comprehensions with strings 30 | from sklearn.datasets import fetch_20newsgroups 31 | 32 | docs = fetch_20newsgroups()['data'] 33 | 34 | {x: y for x, y in enumerate('ABC')} 35 | 36 | [len(d) for d in docs][:10] 37 | 38 | import numpy as np 39 | np.mean([len(d) for d in docs]) 40 | 41 | [d[:50] for d in docs if 'vegetarian' in d] 42 | 43 | [d.split("\n")[1] for d in docs if 'vegetarian' in d] 44 | 45 | [i for i, d in enumerate(docs) if 'vegetarian' in d] 46 | 47 | {word for d in docs for word in d.split() if word.startswith('poly')} 48 | 49 | bla = ["abc", "def"] 50 | [x for y in bla for x in y] 51 | 52 | [a+b for a in "abc" for b in "abc"] 53 | 54 | min([(len(d), d) for d in docs])[1] 55 | -------------------------------------------------------------------------------- /solutions/create_numpy_arrays.py: -------------------------------------------------------------------------------- 1 | """ 2 | Create NumPy arrays using one-liners: 3 | """ 4 | Create the following NumPy arrays using one-liners: 5 | 6 | import numpy as np 7 | 8 | # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 9 | 10 | # array([1. , 1.5, 2. , 2.5, 3. , 3.5, 4. ]) 11 | 12 | # array([0, 1, 2, 0, 1, 2, 0, 1, 2, 0]) 13 | 14 | # array([ 0, 1, 4, 9, 16, 25, 36, 49]) 15 | 16 | # array([ 1, 2, 4, 8, 16, 32, 64, 128, 256]) 17 | 18 | # array([ 0, 1, 3, 6, 10, 15, 21, 28]) 19 | 20 | # array([1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]) 21 | 22 | # array([1., 1., 1., 1., 0., 0., 1., 1., 1., 1.]) 23 | 24 | # array([-3.142, -2.094, -1.047, 0. , 1.047, 2.094, 3.142]) 25 | 26 | # array([0. , 0.69, 1.1 , 1.39, 1.61, 1.79, 1.95, 2.08, 2.2 ]) 27 | 28 | np.linspace(1.0, 2.0, 6) 29 | 30 | np.arange(10) 31 | 32 | np.arange(10) % 3 33 | 34 | np.arange(8) ** 2 35 | 36 | 2 ** np.arange(9) 37 | 38 | np.cumsum(np.arange(8)) 39 | 40 | np.repeat(np.array([1,2,3]), 3) 41 | 42 | np.hstack([np.ones(4), np.zeros(2), np.ones(4)]) 43 | 44 | (np.arange(-180, 181, 60) / 180 * np.pi).round(4) 45 | -------------------------------------------------------------------------------- /solutions/create_numpy_matrices.py: -------------------------------------------------------------------------------- 1 | # NumPy Matrices 2 | 3 | # Create the following matrices with a few NumPy commands: 4 | 5 | import numpy as np 6 | 7 | 8 | z = np.ones((4, 4)) 9 | z[1:3, 1:3] = 0 10 | z 11 | 12 | a = np.arange(4) 13 | a * np.ones((4, 1)) 14 | 15 | b = a.reshape(4, 1) 16 | b 17 | 18 | a * b 19 | 20 | c = a.reshape(2,2) 21 | np.tile(c, (2,2)) 22 | 23 | np.eye(4, 4) 24 | 25 | d = np.arange(16).reshape(4,4) 26 | d 27 | 28 | d.T 29 | 30 | ((d - d.T) >= 0).astype(np.int32) 31 | 32 | (np.arange(16).reshape(4,4) + np.array([1, 0, 1, 0]).reshape(4,1)) % 2 33 | -------------------------------------------------------------------------------- /solutions/format_strings.py: -------------------------------------------------------------------------------- 1 | # Format Strings 2 | label = "knights" 3 | n = 12 # number by John Dryden, not Monty Python 4 | mean = 1.2345678 5 | 6 | # produce the following strings using the data from the variables 7 | str(n) 8 | "12" 9 | 10 | # format string: >= 3.5 11 | f"{label}: {n}" 12 | template = "{}: {}" 13 | template.format(label, n) 14 | 15 | str(label) + ': ' + str(n) 16 | "%s: %i" % (label, n) 17 | 18 | "knights: 12" 19 | 20 | "{}: {}".format(label.upper()[:3], n) 21 | "KNI: 12" 22 | 23 | f"There are {n} {label} of the table round" 24 | "There are 12 knights of the table round" 25 | 26 | print(f"{label}\t\t:\t{n}") 27 | f"{label:10}:{n:10}" 28 | "knights : 12" 29 | 30 | f"{label:>10}:{n:<10}" 31 | " knights: 12" 32 | 33 | f"{label:10}:{n:010d}" 34 | "knights : 00012" 35 | 36 | 37 | print(f"{label}\n{n}\n{mean}") 38 | data = ['knights', '12', '12345'] 39 | print('\n'.join(data)) 40 | """knights 41 | 12 42 | 1.2345678""" 43 | 44 | str(round(mean, 2)) 45 | f"{mean:.2f}" 46 | "1.23" 1. 47 | 48 | f"{mean:15.10f}" 49 | " 1.2345678000" 50 | 51 | 52 | 53 | print(f"{n}") 54 | print(f"{label}: {n}") 55 | print(f"{label[:3].upper()}: {n}") 56 | print(f"There are {n} {label} of the table round") 57 | print(f"{label:10}: {n:5}") 58 | print(f"{label:>10}: {n:5}") 59 | print(f"{label:10}: {n:05}") 60 | print(f"{label}\n{n}\n{mean}") 61 | print(f"{mean:4.2f}") 62 | print(f"{mean:14.10f}") 63 | -------------------------------------------------------------------------------- /solutions/sierpinski.py: -------------------------------------------------------------------------------- 1 | 2 | code = { 3 | ' ': ' ', 4 | ' #': '#', 5 | ' # ': '#', 6 | ' ##': ' ', 7 | '# ': '#', 8 | '# #': ' ', 9 | '## ': ' ', 10 | '###': ' ', 11 | } 12 | 13 | N = 32 14 | line = " " * N + "#" + " " * N 15 | for _ in range(N): 16 | print(line) 17 | new = " " 18 | for start in range(len(line) - 2): 19 | sub = line[start: start + 3] 20 | new += code[sub] 21 | line = new + " " 22 | -------------------------------------------------------------------------------- /solutions/string_basics.py: -------------------------------------------------------------------------------- 1 | # Manipulating strings 2 | 3 | # fill in the gaps 4 | 5 | a = "With 4 parameters I can fit an elephant" 6 | 7 | b = a.upper() 8 | assert b == "WITH 4 PARAMETERS I CAN FIT AN ELEPHANT" 9 | 10 | c = a.replace('elephant', 'alligator') 11 | assert c == "With 4 parameters I can fit an alligator" 12 | 13 | d = a[18:] 14 | assert d == "I can fit an elephant" 15 | 16 | e = d.split() 17 | assert e == ['I', 'can', 'fit', 'an', 'elephant'] 18 | 19 | f = '***'.join(e) 20 | assert f == "I***can***fit***an***elephant" 21 | 22 | g = ' '.join([e[-1]] * 3) 23 | assert g == 'elephant elephant elephant' 24 | 25 | h = a.find('elephant') 26 | assert h == 31 27 | 28 | i = a.count('e') 29 | assert i == 4 30 | 31 | j = a + " and with 5 it will wiggle its trunk." 32 | assert j.endswith("and with 5 it will wiggle its trunk.") 33 | -------------------------------------------------------------------------------- /solutions/string_comprehensions.py: -------------------------------------------------------------------------------- 1 | 2 | # Comprehensions with strings 3 | 4 | # Solve the following with one-liners 5 | 6 | # 1. flatten the list 7 | data = ["abc", "def", "ghi"] 8 | result = [x for y in bla for x in y] 9 | assert result == list("abcdefghi") 10 | 11 | # 2. create all combinations 12 | first, second = "abc", "de" 13 | result = [a+b for a in first for b in second] 14 | assert result == ['ad', 'ae', 'bd', 'be', 'cd', 'ce'] 15 | 16 | # 3. create a dictionary 17 | result = {x: y for x, y in enumerate('ABC')} 18 | assert result == {0: 'A', 1: 'B', 2: 'C'} 19 | 20 | # 21 | # Use a list of 20k documents for the next exercises 22 | # 23 | from sklearn.datasets import fetch_20newsgroups 24 | import statistics 25 | 26 | docs = fetch_20newsgroups()['data'] 27 | 28 | # 4. calculate the length of each document in characters 29 | result = [len(d) for d in docs] 30 | assert result[:5] == [721, 858, 1981, 815, 1120] 31 | 32 | # 5. calculate the mean length 33 | result = statistics.mean([len(d) for d in docs]) 34 | assert round(result, 2) == 1949.31 35 | 36 | # 6. find the shortest document 37 | result = min([(len(d), d) for d in docs])[1] 38 | assert 'Graphics Library Package' in result 39 | 40 | # 7. find all documents containing the word 'vegetarian' 41 | result = [d[:50] for d in docs if 'vegetarian' in d] 42 | assert result[7].startswith('From: DMCOLES@NUACVM.ACNS.NWU.EDU\nSubject: Chicago') 43 | 44 | # 8. extract indices of all documents containing the word 'vegetarian' 45 | result = [i for i, d in enumerate(docs) if 'vegetarian' in d] 46 | assert 4355 in result 47 | 48 | # 9. extract the first line of each document 49 | result = [d.split("\n")[1] for d in docs] 50 | assert result[4] == 'Subject: Re: Shuttle Launch Question' 51 | 52 | 53 | # 10. find all unique words starting with 'poly' 54 | result = {word for d in docs for word in d.split() if word.startswith('poly')} 55 | assert len(result) == 50 56 | assert 'polypropylene' in result 57 | --------------------------------------------------------------------------------