├── .github └── workflows │ └── python-app.yml ├── .gitignore ├── LICENSE ├── README.md ├── assignments ├── README.md └── cold │ ├── cold.yaml │ └── data │ ├── cold-001.ans │ ├── cold-001.in │ ├── cold-002.ans │ └── cold-002.in ├── demos ├── count_down_wrapper.py ├── countdown.py ├── fibos │ ├── __init__.py │ └── fibo.py ├── function_unittest │ ├── add.py │ ├── main.py │ └── test_main.py ├── modules │ ├── main.py │ └── module2.py ├── package_demo.py ├── pickling.py ├── turtle │ ├── demo1.py │ ├── demo2.py │ ├── demo3.py │ ├── demo4.py │ ├── event1.py │ ├── event2.py │ ├── event3.py │ └── event4.py ├── type_checking │ └── type_check.py ├── users.yaml └── utility │ ├── __init__.py │ ├── factorial.py │ ├── fib.py │ └── fib_unittest.py ├── generatepdfs.sh ├── labs └── README.md ├── notebooks ├── Ch00-IntroCourseTableOfContents.ipynb ├── Ch01-Introduction.ipynb ├── Ch02-1-Data-Variables-StdIO.ipynb ├── Ch02-2-BitwiseOperators.ipynb ├── Ch03-1-Functions-Built-in.ipynb ├── Ch03-2-Functions-Library.ipynb ├── Ch03-3-Functions-UserDefined.ipynb ├── Ch03-4-UnittestingFunctions.ipynb ├── Ch03-5-NamespaceModulesRefactoring.ipynb ├── Ch03-6-Functions-Advanced.ipynb ├── Ch04-Conditionals.ipynb ├── Ch05-Iterations.ipynb ├── Ch06-Strings.ipynb ├── Ch07-Tuples.ipynb ├── Ch08-1-Lists.ipynb ├── Ch08-2-Lists-Advanced.ipynb ├── Ch09-1-Dictionaries.ipynb ├── Ch09-2-Built-in-DataStructures.ipynb ├── Ch10-1-FileIOYAML.ipynb ├── Ch10-2-Files-Advanced.ipynb ├── Ch10-2-RichLibrary.ipynb ├── Ch11-Turtles-Events.ipynb ├── Ch12-ModulesAndPackages.ipynb ├── Ch13-Recursion.ipynb ├── Ch14-OOP.ipynb ├── Ch15-Overloading-Polymorphism.ipynb ├── Ch16-Exceptions.ipynb ├── Ch17-PyGame.ipynb ├── Ch18-Inheritance.ipynb ├── Ch19-UnitTest.ipynb ├── Ch20-LinkedLists.ipynb ├── Ch21-Stacks.ipynb ├── Ch22-Queues.ipynb ├── Ch23-Trees.ipynb ├── Ch24-CodeOptimization-ExecutionTime.ipynb ├── Ch25-DynamicProgramming.ipynb ├── Ch26-SqliteDB.ipynb └── resources │ ├── BuildingBlocks.png │ ├── Inheritance.png │ ├── MultipleInheritance.png │ ├── PythonPrompt.png │ ├── brain.jpg │ ├── recursion-fib.svg │ ├── russiandolls.png │ ├── tree2.png │ └── tree3.png ├── paper.bib ├── paper.md ├── pdfs ├── Ch01-Introduction.pdf ├── Ch02-1-Data-Variables.pdf ├── Ch02-2-BitwiseOperators.pdf ├── Ch02-Data-Variables.pdf ├── Ch03-1-Functions-Built-in.pdf ├── Ch03-2-Functions-Library.pdf ├── Ch03-3-Functions-UserDefined.pdf ├── Ch04-Conditionals.pdf ├── Ch05-Iterations.pdf ├── Ch06-Strings.pdf ├── Ch07-Tuples.pdf ├── Ch08-1-Lists.pdf ├── Ch08-2-Lists-Advanced.pdf ├── Ch09-1-Dictionaries.pdf ├── Ch09-2-Built-in-DataStructures.pdf ├── Ch10-1-Files.pdf ├── Ch10-2-Files-Advanced.pdf ├── Ch11-Turtles-Events.pdf ├── Ch12-Modules.pdf ├── Ch12-ModulesAndPackages.pdf ├── Ch13-Recursion.pdf ├── Ch14-OOP.pdf ├── Ch15-Overloading-Polymorphism.pdf ├── Ch16-Exceptions.pdf ├── Ch17-PyGame.pdf ├── Ch18-Inheritance.pdf ├── Ch19-UnitTest.pdf ├── Ch20-LinkedLists.pdf ├── Ch21-Stacks.pdf ├── Ch22-Queues.pdf ├── Ch23-Trees.pdf ├── Ch24-CodeOptimization-ExecutionTime.pdf ├── Ch25-DynamicProgramming.pdf └── Ch26-SlqiteDB.pdf └── tests ├── __init__.py └── test_1.py /.github/workflows/python-app.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python 3 | 4 | name: Python application 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | build: 17 | 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v3 22 | - name: Set up Python 3.10 23 | uses: actions/setup-python@v3 24 | with: 25 | python-version: "3.10" 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install flake8 pytest 30 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 31 | - name: Lint with flake8 32 | run: | 33 | # stop the build if there are Python syntax errors or undefined names 34 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 35 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 36 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 37 | - name: Test with pytest 38 | run: | 39 | pytest tests 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # IPython 76 | profile_default/ 77 | ipython_config.py 78 | 79 | # pyenv 80 | .python-version 81 | 82 | # celery beat schedule file 83 | celerybeat-schedule 84 | 85 | # SageMath parsed files 86 | *.sage.py 87 | 88 | # Environments 89 | .env 90 | .venv 91 | env/ 92 | venv/ 93 | ENV/ 94 | env.bak/ 95 | venv.bak/ 96 | 97 | # Spyder project settings 98 | .spyderproject 99 | .spyproject 100 | 101 | # Rope project settings 102 | .ropeproject 103 | 104 | # mkdocs documentation 105 | /site 106 | 107 | # mypy 108 | .mypy_cache/ 109 | .dmypy.json 110 | dmypy.json 111 | 112 | # others 113 | *.DS_Store 114 | *.pickle 115 | *.db 116 | .ipynb_checkpoints/ 117 | *.pkl 118 | __pycache__/ 119 | *.txt 120 | 121 | *.db-journal 122 | .vscode 123 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Ram Basnet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FDS Python: Fundamentals and Data Structures with Python 2 | 3 | These jupyter notebooks are based on open-source textbook "How to Think Like a Computer Scientist: Learning with Python 3 (RLE)" by Peter Wentworth, Jeffrey Elkner, Allen B. Downey, and Chris Meyers found online [here](http://openbookproject.net/thinkcs/python/english3e/index.html). 4 | 5 | The primary goal of these notebooks is to help instructors easily adopt the open-source textbook to teach programming and problem solving using Python in an interactive and hands-on approach (a.k.a. learning-by-doing). Some new chapters with important concepts and topics have been added and some existing chapters have been slightly reordered. These notebooks primarily consist of outlines of theoritical concepts, keywords and definitions along with code, [code visualization](https://pythontutor.com) compounded by appropriately challenging [intercollegiate programming contests problems](https://open.kattis.com) where applicable to help students engage in the challenging concepts of coding and problem solving. 6 | 7 | See [paper.md](paper.md) file for statement of need. 8 | 9 | ## Notebook mapping with corresponding book chapter 10 | 11 | Note: If book chapter is missing, texbook doesn't provide one on the topic; all the notebooks are in **notebooks** folder 12 | 13 | | Notebook -> | Think Python3 Textbook | 14 | | --------- | ---------- | 15 | | [Ch01-Introduction](Ch01-Introduction.ipynb) | Chapter 1: The way of the program | 16 | | [Ch02-1-Data, Variables, Std IO](Ch02-1-Data-Variables-StdIO.ipynb) | Chapter 2: Data, Variables and Standard IO | 17 | | [Ch02-2-BitwiseOperators](Ch02-2-BitwiseOperators.ipynb) | Number Systems & Bitwise Operators | 18 | | [Ch03-1-Functions-Built-in](Ch03-1-Functions-Built-in.ipynb) | Examples of some built-in functions | 19 | | [Ch03-2-Functions-Library](Ch03-2-Functions-Library.ipynb) | Examples of standard libraries, e.g., math | 20 | | [Ch03-3-Functions-UserDefined](Ch03-3-Functions-UserDefined.ipynb)| Chapter 4 and 6: Functions and Fruitful functions | 21 | | [Ch03-4-Functions-Advanced](Ch03-4-Functions-Advanced.ipynb) | Some advanced topics on function | 22 | | [Ch04-Conditionals](Ch04-Conditionals.ipynb) | Chapter 5: Conditionals | 23 | | [Ch05-Iterations](Ch05-Iterations.ipynb) | Chapter 7: Iteration - for and while loops | 24 | | [Ch06-Strings](Ch06-Strings.ipynb) | Chapter 8: Strings | 25 | | [Ch07-Tuples](Ch07-Tuples.ipynb) | Chapter 9: Tuples | 26 | | [Ch08-1-Lists](Ch08-1-Lists.ipynb) | Chapter 11: Lists | 27 | | [Ch08-2-Lists-Advanced](Ch08-2-Lists-Comprehension-Lambda.ipynb) | List comprehension, Lambda function, map, reduce, filter | 28 | | [Ch09-1-Dictionaries](Ch09-1-Dictionaries.ipynb) | Chapter 20: Dictionaries | 29 | | [Ch09-2-Built-in-DataStructures](Ch09-2-Built-in-DataStructures.ipynb) | zip, set, Collections: OrderedDict, defaultdict, Counter | 30 | | [Ch10-1-Files](Ch10-1-Files.ipynb) | Chapter 13: Files - with, open, text file | 31 | | [Ch10-2-Files-Advanced](Ch10-2-Files-Advanced.ipynb) | Chapter 13: urllib, pickle, binary files, checksums | 32 | | [Ch11-Turtles-Events](Ch11-Turtles-Events.ipynb) | Chapter 3 & 10 | 33 | | [Ch12-ModulesAndPackages](Ch12-Modules.ipynb) | Chapter 12: Modules - built-in and user-defined | 34 | | [Ch13-Recursion](Ch13-Recursion.ipynb) | Chapter 18: Recursion | 35 | | [Ch14-OOP](Ch14-OOP.ipynb) | Chapter 15, 16 Classes and Basics | 36 | | [Ch15-Overloading-Polymorphism](Ch15-Overloading-Polymorphism.ipynb) | Chapter 21 and 22 | 37 | | [Ch16-Exceptions](Ch16-Exceptions.ipynb) | Chapter 19 Exceptions | 38 | | [Ch17-PyGame](Ch17-PyGame.ipynb) | Chapter 17 PyGame | 39 | | [Ch18-Inheritance](Ch18-Inheritance.ipynb) | Chapter 23 Inheritance | 40 | | [Ch19-Unittest](Ch19-UnitTest.ipynb) | UnitTest Framework | 41 | | [Ch20-LinkedLists](Ch20-LinkedLists.ipynb) | Chapter 24 Linked Lists | 42 | | [Ch21-Stacks](Ch21-Stacks.ipynb) | Chapter 25 Stacks | 43 | | [Ch22-Queues](Ch22-Queues.ipynb) | Chapter 26 Queues | 44 | | [Ch23-Trees](Ch23-Trees.ipynb) | Chapter 25 Trees | 45 | | [Ch24-CodeOptimization](Ch24-CodeOptimization-ExecutionTime.ipynb) | Code Optimization | 46 | | [Ch25-DynamicProgramming](Ch25-DynamicProgramming.ipynb) | Intro to Dynamic Programming | 47 | | [Ch26-Sqlite](Ch26-SqliteDB.ipynb) | Sqlite Database | 48 | 49 | ## PDF Format 50 | 51 | - pdf version of all the notebooks can be generated using the following script from a Terminal on Linux system 52 | - PDF file for each notebook file will be generated and stored in ./pdfs folder 53 | 54 | ```bash 55 | bash generatepdfs.sh 56 | ``` 57 | 58 | ## Who can use these notebooks 59 | 60 | ### University and High-school Coding Instructors 61 | 62 | Depending on the course level and topics covered, instructors can pick and choose appropriate chapters. E.g., we've used Chapter 1 - 15 (skipping some chapters such as Functions-Lambda) in Beginning programing 3/4-credit university courses (CS0 and CS1) where students have no prior experience to programming. On the other hand, we've also used all the chapters for 2-credit advanced programing courses where students have some prior programming experiences in Python or other programming languages (CS1, CS2 level). 63 | 64 | ### Self learners 65 | 66 | Depending on their skill and interest level, learners can move as swiftly as appropriate through the chapters. Try solving some exercises towards the end of each chapter before moving on to self-assess the mastery of the materials. 67 | 68 | ## How to use these notebooks 69 | 70 | ### Important 71 | 72 | In order to learn coding, it's very important to actually type code on your own from scratch and NOT copy paste! You can run provided cells to see the output, follow along and learn from it. However, it's very important that you either start a new notebook or add cells and write your own code from scratch to practice the concepts covered with many similar examples and solve the exercises provided. 73 | 74 | ### Online services 75 | 76 | You can launch an interactive session of this project using online Binder service: 77 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/rambasnet/thinkpythonnotebooks/master) or Google Colab. Each chapter, where applicable, provides [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com) to simply click and run the notebook in Google's Colab environment. 78 | 79 | ### On a local system 80 | 81 | To run these notebooks interactively and save your work locally, you need [Python 3][https://www.python.org/] and [Jupyter Notebook](http://jupyter.org/) -- an interactive web-based editor that allows you to create and share documents that contain live code and data. Anaconda or Miniconda is the recommended way to install Python and other packages on all modern platforms. 82 | 83 | #### Using Docker Container 84 | 85 | - Follow instruction here: [https://github.com/rambasnet/Dockerfiles](https://github.com/rambasnet/Dockerfiles) 86 | - Install Docker Desktop 87 | - Follow readme inside python folder to create Python image with required tools 88 | 89 | #### Local installation via Anaconda or Miniconda 90 | 91 | Anaconda or Miniconda has Python 3 and many other packages that you can easily install on any platform (Windows, Linux, and Mac). First, install Anaconda: [http://docs.continuum.io/anaconda/install/](http://docs.continuum.io/anaconda/install/) or Miniconda [https://conda.io/docs/user-guide/install/index.html](https://conda.io/docs/user-guide/install/index.html) for Python 3. 92 | 93 | After installing anaconda or miniconda, open a terminal or cmd prompt and run the following commands: 94 | 95 | ```bash 96 | conda update conda 97 | conda install notebook # or 98 | conda install -c conda-forge retrolab # uses notebook 99 | ``` 100 | 101 | #### Running the notebooks in VS Code 102 | 103 | - Python notebooks can be run natively in VS Code. Simply open the notebook file with extension ipynb in VS Code and run each cell; add new cell, etc. right from VS Code. 104 | 105 | #### Running the notebooks using jupyter notebook server 106 | 107 | Once Python 3 and Jupyter Notebook are installed, open a terminal change working directory using cd command to go into the folder where this repo is cloned and run the notebook from there: 108 | 109 | ```bash 110 | cd 111 | jupyter notebook # or 112 | jupyter retro 113 | ``` 114 | 115 | This will start a Jupyter session in your browser. Open any chapter and start coding... 116 | 117 | ## Contributing 118 | 119 | Contributions are accepted via pull requests. You can also open issues on bugs, typos or any corrections and suggest improvements on the notebooks. 120 | 121 | ## Copyright and License 122 | 123 | © 2019 Ram Basnet and T. Doleck. Permission is granted to copy, distribute and/or modify this document 124 | under the terms of the GNU Free Documentation License, Version 1.3 125 | or any later version published by the Free Software Foundation. See LICENSE file for details. 126 | 127 | -------------------------------------------------------------------------------- /assignments/README.md: -------------------------------------------------------------------------------- 1 | # CSCI 110 - CS0 Beginning Programming: Python 2 | 3 | | Name | Value | 4 | |:---|:---| 5 | | **Section** | FIXME | 6 | | **Semester** | FIXME | 7 | | **Student Name** | FIXME | 8 | | **Mav Username** | FIXME | 9 | | **GitHub Username** | FIXME | 10 | | **Repository URL** | FIXME | 11 | 12 | ## Assignments 13 | 14 | ### Assignment 0 15 | 16 | | Name | Value | 17 | | :--- | :--- | 18 | | Name | A0 - Hello World! | 19 | | Description | Setting up repo and dev tools | 20 | | Due Date | FIXME | 21 | | Status | in progress / completed | 22 | | Location | FIXME: URL TO THE CURRENT LAB FOLDER IN REMOTE REPO | 23 | | Self Grade | XX/100 | 24 | | Notes | fixed all the fixmes; setup and tested environment with hello world script | 25 | 26 | ## References 27 | 28 | 1. [Markdown Syntax](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) 29 | -------------------------------------------------------------------------------- /assignments/cold/cold.yaml: -------------------------------------------------------------------------------- 1 | accepted: 0 2 | cpu_limit: 1 second 3 | difficulty: 1.5 Easy 4 | mem_limit: 1024 MB 5 | problemid: cold 6 | submissions: 0 7 | title: Cold-puter Science 8 | -------------------------------------------------------------------------------- /assignments/cold/data/cold-001.ans: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /assignments/cold/data/cold-001.in: -------------------------------------------------------------------------------- 1 | 3 2 | 5 -10 15 3 | -------------------------------------------------------------------------------- /assignments/cold/data/cold-002.ans: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /assignments/cold/data/cold-002.in: -------------------------------------------------------------------------------- 1 | 5 2 | -14 -5 -39 -5 -7 3 | -------------------------------------------------------------------------------- /demos/count_down_wrapper.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Module to demonstrate Function Decorators.""" 3 | 4 | __author__ = "Ram Basnet" 5 | __copyright__ = "Copyright 2018" 6 | __license__ = "MIT" 7 | 8 | import time 9 | import os 10 | from functools import wraps 11 | # wraps - decorator function for preserving the name of the function being decorated 12 | 13 | def clearScreen(func): 14 | """Use system command to clear screen: https://docs.python.org/3/library/os.html""" 15 | 16 | @wraps(func) 17 | def wrapper(*args, **kwargs): 18 | if os.name == 'nt': # nt, posix, java 19 | os.system('cls') 20 | else: 21 | os.system('clear') 22 | return func(*args, **kwargs) 23 | return wrapper 24 | 25 | def slow_down(func): 26 | """Sleep 1 second before calling the function.""" 27 | 28 | @wraps(func) 29 | def wrapper_slow_down(*args, **kwargs): 30 | time.sleep(1) # sleep for a second 31 | return func(*args, **kwargs) # call and return the result from the func 32 | return wrapper_slow_down 33 | 34 | 35 | # a simple count down function 36 | @slow_down 37 | # @clearScreen # TODO: uncomment this line to apply clearScreen decorator 38 | def countDown(from_number): 39 | """A simple recursive countDown function that uses 2 function decorators.""" 40 | 41 | if from_number <= 0: 42 | print('Blast off!') 43 | else: 44 | print(from_number) 45 | countDown(from_number-1) 46 | 47 | 48 | if __name__ == "__main__": 49 | countDown(10) -------------------------------------------------------------------------------- /demos/countdown.py: -------------------------------------------------------------------------------- 1 | # while loop - countdown 2 | import time 3 | import os 4 | i = 10 5 | while True: 6 | print(i) 7 | time.sleep(1) 8 | os.system('clear') 9 | i -= 1 10 | if i == 0: 11 | break 12 | # time.sleep(1) 13 | # else: 14 | print('Happy new year!') 15 | -------------------------------------------------------------------------------- /demos/fibos/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/demos/fibos/__init__.py -------------------------------------------------------------------------------- /demos/fibos/fibo.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """ Fibonacci Module 3 | - Run the module providing an argument: 4 | $ python3 fibo.py 10 5 | """ 6 | 7 | import sys 8 | 9 | 10 | def fib(n: int) -> None: 11 | """ 12 | prints Fibonacci series up to nth term 13 | """ 14 | a, b = 0, 1 15 | print(a, b, end=' ') 16 | i = 2 17 | while i < n: 18 | a, b = b, a+b 19 | print(b, end=' ') 20 | i += 1 21 | print() 22 | 23 | 24 | def fib2(n: int) -> list[int]: 25 | """ 26 | returns list of Fibonacci series up to nth term 27 | """ 28 | result = [0, 1] 29 | i = 2 30 | while i < n: 31 | result.append(result[i-1] + result[i-2]) 32 | i += 1 33 | return result 34 | 35 | 36 | def main() -> None: 37 | """Main function 38 | """ 39 | fib(5) 40 | print(fib2(5)) 41 | fib(int(sys.argv[1])) 42 | print(fib2(int(sys.argv[1]))) 43 | 44 | 45 | if __name__ == "__main__": 46 | main() 47 | -------------------------------------------------------------------------------- /demos/function_unittest/add.py: -------------------------------------------------------------------------------- 1 | 2 | def add(a: int, b: int) -> int: 3 | """Add two numbers 4 | 5 | Args: 6 | a (int): first number 7 | b (int): second number 8 | 9 | Returns: 10 | int: sum of a and b 11 | """ 12 | return a+b 13 | 14 | 15 | def test_add() -> None: 16 | """Test add function 17 | """ 18 | ans = add(10, 20) 19 | expected = 30 20 | assert ans == expected 21 | 22 | 23 | def test_add2() -> None: 24 | """Test add function 25 | """ 26 | ans = add(5, 99) 27 | expected = 104 28 | assert ans == expected 29 | 30 | 31 | def test_add3() -> None: 32 | """Test add function 33 | """ 34 | ans = add(0, -10) 35 | excepted = -10 36 | assert ans == excepted 37 | -------------------------------------------------------------------------------- /demos/function_unittest/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | Kattis problem - 3 | CSCI 110 4 | 5 | Author: 6 | Date: 7 | 8 | Problem Satement: 9 | 10 | Algorithm Steps: 11 | 1. 12 | 2. 13 | ... 14 | """ 15 | 16 | 17 | def answer() -> str: 18 | """Function returns "Hello World!" string. 19 | 20 | Returns: 21 | str: returns "Hello World!" 22 | """ 23 | return 'Hello World!' 24 | 25 | 26 | def add(a: int, b: int) -> int: 27 | """Function adds two integers and returns the sum. 28 | 29 | Args: 30 | a (int): 1st operand 31 | b (int): 2nd operand 32 | 33 | Returns: 34 | int: return sum of a and b 35 | """ 36 | return a+b 37 | 38 | 39 | def main(): 40 | """Main function that solves the problem. 41 | """ 42 | 43 | # Read data 44 | # call anwer() function 45 | # print final answer 46 | ans = answer() 47 | print(ans) 48 | 49 | 50 | if __name__ == "__main__": 51 | # call main() if the module is run as the main module 52 | main() 53 | -------------------------------------------------------------------------------- /demos/function_unittest/test_main.py: -------------------------------------------------------------------------------- 1 | from main import answer, add 2 | 3 | 4 | def test_answer() -> None: 5 | """Test answer function 6 | """ 7 | expected = "Hello World!" 8 | ans = answer() 9 | assert ans == expected 10 | 11 | 12 | def test_add() -> None: 13 | """Test add function 14 | """ 15 | ans = add(10, 20) 16 | expected = 30 17 | assert ans == expected 18 | 19 | 20 | def test_add2() -> None: 21 | """Test add function 22 | """ 23 | ans = add(5, 99) 24 | expected = 104 25 | assert ans == expected 26 | 27 | 28 | def test_add3(): 29 | """Test add function 30 | """ 31 | ans = add(0, -10) 32 | excepted = -10 33 | assert ans == excepted 34 | -------------------------------------------------------------------------------- /demos/modules/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is named main module. 3 | Declares question, answer, and areaOfCircle function 4 | """ 5 | 6 | import math # first import standard library modules 7 | import module2 # then import user-defined modules 8 | # what happens if the imported the names following way? Uncomment, run the module and find out... 9 | # from module2 import * 10 | 11 | # global variables/CONSTANTS 12 | QUESTION = "What is the meaning of Life, the Universe, and Everything?" 13 | ANSWER = 42 14 | 15 | # a function 16 | 17 | 18 | def area_of_circle(radius): 19 | """ 20 | Given radius of a circle, finds and returns its area. 21 | """ 22 | return math.pi*radius**2 23 | 24 | 25 | def print_module_info() -> None: 26 | """Prints module information 27 | """ 28 | import module2 29 | print(__doc__) 30 | print(__file__) 31 | print(__name__) 32 | print(__package__) 33 | print('module2.__doc__ = ', module2.__doc__) 34 | print('module2.__file__ = ', module2.__file__) 35 | print('module2.__name__ = ', module2.__name__) 36 | print('module2.__package__ = ', module2.__package__) 37 | 38 | 39 | def access_module2_names() -> None: 40 | """Access names defined in module2 41 | """ 42 | print(module2.QUESTION) 43 | print(module2.ANSWER) 44 | 45 | 46 | def access_this_module_names() -> None: 47 | """Access names defined in this module 48 | """ 49 | print(QUESTION) 50 | print(ANSWER) 51 | area = area_of_circle(3) 52 | print(f"area = {area:.2f}") 53 | 54 | 55 | if __name__ == '__main__': 56 | access_module2_names() 57 | access_this_module_names() 58 | -------------------------------------------------------------------------------- /demos/modules/module2.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is module 2. Defines question, answer and 3 | circumference function 4 | """ 5 | import math 6 | # import module1 7 | 8 | QUESTION = "What is your quest?" 9 | ANSWER = "To seek the holy grail." 10 | 11 | 12 | def circumference(radius): 13 | """ 14 | Given radius of a circle, finds and returns its circumference. 15 | """ 16 | return math.pi*radius*2 17 | 18 | 19 | def test(): 20 | """ 21 | Function to test names defined in this module. 22 | """ 23 | print(QUESTION) 24 | print(ANSWER) 25 | print(f"circumference={circumference(3)}") 26 | 27 | 28 | # what happens if the import guard is not used and this module is imported? 29 | # comment out the following if statement and directly call test() and run main.py module to find out! 30 | if __name__ == '__main__': 31 | test() 32 | -------------------------------------------------------------------------------- /demos/package_demo.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module uses the fibos package defined in the root repository folder. 3 | """ 4 | 5 | import fibos.fibo as myfib 6 | from fibos import fibo 7 | 8 | def main(): 9 | print('First 10 numbers in Fibonacci seris:') 10 | myfib.fib(10) 11 | fibo.fib2(10) 12 | 13 | if __name__ == "__main__": 14 | main() 15 | 16 | -------------------------------------------------------------------------------- /demos/pickling.py: -------------------------------------------------------------------------------- 1 | """ 2 | pickling and unpickling or serialization and deserialization 3 | """ 4 | 5 | import pickle 6 | 7 | class Rectangle(object): 8 | ''' 9 | Rectangle class 10 | ''' 11 | def __init__(self, length=1, width=1): 12 | self.length = length 13 | self.width = width 14 | self.area = self.getArea() 15 | 16 | def getArea(self): 17 | return self.length * self.width 18 | 19 | def __str__(self): 20 | return "len: {0:.2f} width: {1:.2f} area: {2:.2f}".format( 21 | self.length, self.width, self.area) 22 | 23 | 24 | def main(): 25 | """ 26 | main function 27 | """ 28 | fileName = 'binary.pickle' 29 | try: 30 | with open(fileName, 'rb') as f: 31 | data = pickle.load(f) 32 | except FileNotFoundError: 33 | r = Rectangle(10, 5) 34 | data = {'a': ['apple', 'a2dsaf3@##', 'a$fdw'], 35 | 'b': ['ball', 'black', 'basket'], 36 | 'c': ('cat', 'c!dsfera'), 37 | 'r': r 38 | } 39 | with open(fileName, 'wb') as f: 40 | pickle.dump(data, f) 41 | print('file {0} not found! Pickle file {0} created.'.format(fileName)) 42 | else: 43 | if isinstance(data, dict): 44 | for key in data: 45 | print(key, '->', data[key]) 46 | 47 | 48 | if __name__ == "__main__": 49 | main() 50 | -------------------------------------------------------------------------------- /demos/turtle/demo1.py: -------------------------------------------------------------------------------- 1 | import turtle # Allows us to use turtles 2 | wn = turtle.Screen() # Creates a playground for turtles 3 | alex = turtle.Turtle() # Create a turtle, assign to alex 4 | 5 | alex.forward(50) # Tell alex to move forward by 50 units 6 | alex.left(90) # Tell alex to turn by 90 degrees 7 | alex.forward(30) # Complete the second side of a rectangle 8 | 9 | wn.mainloop() # Wait for user to close window 10 | -------------------------------------------------------------------------------- /demos/turtle/demo2.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | wn = turtle.Screen() 3 | wn.bgcolor("lightgreen") # Set the window background color 4 | wn.title("Hello, Tess!") # Set the window title 5 | 6 | tess = turtle.Turtle() 7 | tess.color("blue") # Tell tess to change her color 8 | tess.pensize(3) # Tell tess to set her pen width 9 | 10 | tess.forward(50) 11 | tess.left(120) 12 | tess.forward(50) 13 | 14 | wn.mainloop() 15 | -------------------------------------------------------------------------------- /demos/turtle/demo3.py: -------------------------------------------------------------------------------- 1 | # a herd of turtles 2 | 3 | import turtle 4 | wn = turtle.Screen() # Set up the window and its attributes 5 | wn.bgcolor("lightgreen") 6 | wn.title("Tess & Alex") 7 | 8 | tess = turtle.Turtle() # Create tess instance and set some attributes 9 | tess.color("hotpink") 10 | tess.pensize(5) 11 | 12 | alex = turtle.Turtle() # Create alex instance of turtle 13 | 14 | tess.forward(80) # Make tess draw equilateral triangle 15 | tess.left(120) 16 | tess.forward(80) 17 | tess.left(120) 18 | tess.forward(80) 19 | tess.left(120) # Complete the triangle 20 | 21 | tess.right(180) # Turn tess around 22 | tess.forward(80) # Move her away from the origin 23 | 24 | alex.forward(50) # Make alex draw a square 25 | alex.left(90) 26 | alex.forward(50) 27 | alex.left(90) 28 | alex.forward(50) 29 | alex.left(90) 30 | alex.forward(50) 31 | alex.left(90) 32 | 33 | wn.mainloop() 34 | -------------------------------------------------------------------------------- /demos/turtle/demo4.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | wn = turtle.Screen() 3 | wn.bgcolor("lightgreen") 4 | tess = turtle.Turtle() 5 | tess.shape("turtle") 6 | tess.color("blue") 7 | 8 | tess.penup() # This is new 9 | size = 20 10 | for i in range(30): 11 | tess.stamp() # Leave an impression on the canvas 12 | size = size + 3 # Increase the size on every iteration 13 | tess.forward(size) # Move tess along 14 | tess.right(24) # ... and turn her 15 | 16 | wn.mainloop() 17 | -------------------------------------------------------------------------------- /demos/turtle/event1.py: -------------------------------------------------------------------------------- 1 | # use arrow keys to move turtle 2 | 3 | import turtle 4 | 5 | turtle.setup(400, 500) # Determine the window size 6 | wn = turtle.Screen() # Get a reference to the window 7 | wn.title("Handling keypresses!") # Change the window title 8 | wn.bgcolor("lightgreen") # Set the background color 9 | tess = turtle.Turtle() # Create our favorite turtle 10 | 11 | # The next four functions are our "event handlers". 12 | 13 | 14 | def h1(): 15 | tess.forward(30) 16 | 17 | 18 | def h2(): 19 | tess.left(45) 20 | 21 | 22 | def h3(): 23 | tess.right(45) 24 | 25 | 26 | def h4(): 27 | wn.bye() # Close down the turtle window 28 | 29 | 30 | # These lines "wire up" keypresses to the handlers we've defined. 31 | wn.onkey(h1, "Up") 32 | wn.onkey(h2, "Left") 33 | wn.onkey(h3, "Right") 34 | wn.onkey(h4, "q") 35 | 36 | # Now we need to tell the window to start listening for events, 37 | # If any of the keys that we're monitoring is pressed, its 38 | # handler will be called. 39 | wn.listen() 40 | wn.mainloop() 41 | -------------------------------------------------------------------------------- /demos/turtle/event2.py: -------------------------------------------------------------------------------- 1 | # use mouse to move turtle 2 | 3 | import turtle 4 | 5 | turtle.setup(400, 500) 6 | wn = turtle.Screen() 7 | wn.title("How to handle mouse clicks on the window!") 8 | wn.bgcolor("lightgreen") 9 | 10 | tess = turtle.Turtle() 11 | tess.color("purple") 12 | tess.pensize(3) 13 | tess.shape("circle") 14 | 15 | 16 | def h1(x, y): 17 | tess.goto(x, y) 18 | 19 | 20 | wn.onclick(h1) # Wire up a click on the window. 21 | wn.mainloop() 22 | -------------------------------------------------------------------------------- /demos/turtle/event3.py: -------------------------------------------------------------------------------- 1 | import turtle 2 | # run two turtles using mouse clicks 3 | 4 | turtle.setup(400, 500) # Determine the window size 5 | wn = turtle.Screen() # Get a reference to the window 6 | wn.title("Handling mouse clicks!") # Change the window title 7 | wn.bgcolor("lightgreen") # Set the background color 8 | tess = turtle.Turtle() # Create two turtles 9 | tess.color("purple") 10 | alex = turtle.Turtle() # Move them apart 11 | alex.color("blue") 12 | alex.forward(100) 13 | 14 | 15 | def handler_for_tess(x, y): 16 | wn.title("Tess clicked at {0}, {1}".format(x, y)) 17 | tess.left(42) 18 | tess.forward(30) 19 | 20 | 21 | def handler_for_alex(x, y): 22 | wn.title("Alex clicked at {0}, {1}".format(x, y)) 23 | alex.right(84) 24 | alex.forward(50) 25 | 26 | 27 | tess.onclick(handler_for_tess) 28 | alex.onclick(handler_for_alex) 29 | 30 | wn.mainloop() 31 | -------------------------------------------------------------------------------- /demos/turtle/event4.py: -------------------------------------------------------------------------------- 1 | import turtle # Tess becomes a traffic light. 2 | # use spacebar to change colors 3 | 4 | turtle.setup(400, 500) 5 | wn = turtle.Screen() 6 | wn.title("Tess becomes a traffic light!") 7 | wn.bgcolor("lightgreen") 8 | tess = turtle.Turtle() 9 | 10 | 11 | def draw_housing(): 12 | """ Draw a nice housing to hold the traffic lights """ 13 | tess.pensize(3) 14 | tess.color("black", "darkgrey") 15 | tess.begin_fill() 16 | tess.forward(80) 17 | tess.left(90) 18 | tess.forward(200) 19 | tess.circle(40, 180) 20 | tess.forward(200) 21 | tess.left(90) 22 | tess.end_fill() 23 | 24 | 25 | draw_housing() 26 | 27 | tess.penup() 28 | # Position tess onto the place where the green light should be 29 | tess.forward(40) 30 | tess.left(90) 31 | tess.forward(50) 32 | # Turn tess into a big green circle 33 | tess.shape("circle") 34 | tess.shapesize(3) 35 | tess.fillcolor("green") 36 | 37 | # A traffic light is a kind of state machine with three states, 38 | # Green, Orange, Red. We number these states 0, 1, 2 39 | # When the machine changes state, we change tess' position and 40 | # her fillcolor. 41 | 42 | # This variable holds the current state of the machine 43 | state_num = 0 44 | 45 | 46 | def advance_state_machine(): 47 | global state_num 48 | if state_num == 0: # Transition from state 0 to state 1 49 | tess.forward(70) 50 | tess.fillcolor("orange") 51 | state_num = 1 52 | elif state_num == 1: # Transition from state 1 to state 2 53 | tess.forward(70) 54 | tess.fillcolor("red") 55 | state_num = 2 56 | else: # Transition from state 2 to state 0 57 | tess.back(140) 58 | tess.fillcolor("green") 59 | state_num = 0 60 | 61 | 62 | # Bind the event handler to the space key. 63 | wn.onkey(advance_state_machine, "space") 64 | 65 | wn.listen() # Listen for events 66 | wn.mainloop() 67 | -------------------------------------------------------------------------------- /demos/type_checking/type_check.py: -------------------------------------------------------------------------------- 1 | """Script to demonstrate typing in Python 3.5 and higher version. 2 | 3 | Must install and include path to pylint in VS Code. 4 | """ 5 | 6 | # Variable type annotations 7 | num: int = 10 8 | var: float = "Hello" 9 | 10 | name: str = "James Bond" 11 | var1: str = 100 12 | 13 | def greeting(name: str) -> str: 14 | return f'Hello, {name}!' 15 | 16 | print(greeting('James Bond')) 17 | print(greeting(3434.3434)) 18 | 19 | 20 | -------------------------------------------------------------------------------- /demos/users.yaml: -------------------------------------------------------------------------------- 1 | # list of players information 2 | - email: jdoe@gmail.com 3 | lost: 2 4 | name: John Doe 5 | password: password 6 | played: 10 7 | salt: 1234567890123456 8 | - email: jane@gmail.com 9 | lost: 1 10 | name: Jane Doe 11 | password: password123 12 | played: 5 13 | salt: aSdf#4afasDF 14 | -------------------------------------------------------------------------------- /demos/utility/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/demos/utility/__init__.py -------------------------------------------------------------------------------- /demos/utility/factorial.py: -------------------------------------------------------------------------------- 1 | """ 2 | This is the "example" module. 3 | 4 | The example module supplies one function, factorial(). For example, 5 | >>> factorial(5) 6 | 120 7 | """ 8 | 9 | def factorial(n): 10 | """ given a positive integer n, returns its factorial 11 | >>> factorial(1) 12 | 1 13 | >>> factorial(5) 14 | 120 15 | >>> factorial(20) 16 | 2432902008176640000 17 | >>> [factorial(n) for n in range(6)] 18 | [1, 1, 2, 6, 24, 120] 19 | >>> factorial(-1) 20 | Traceback (most recent call last): 21 | ... 22 | ValueError: n must be >= 0 23 | 24 | Factorials of floats are OK, but the float must be an exact integer: 25 | >>> factorial(30.1) 26 | Traceback (most recent call last): 27 | ... 28 | ValueError: n must be exact integer 29 | >>> factorial(30.0) 30 | 265252859812191058636308480000000 31 | 32 | It must also not be ridiculously large: 33 | >>> factorial(1e100) 34 | Traceback (most recent call last): 35 | ... 36 | OverflowError: n too large 37 | """ 38 | import math 39 | if n < 0: 40 | raise ValueError("n must be >= 0") 41 | if math.floor(n) != n: 42 | raise ValueError("n must be exact integer") 43 | 44 | if n+1 == n: # catch a value like 1e300 45 | raise OverflowError("n too large") 46 | 47 | fact = 1 48 | n = int(n) 49 | for i in range(1, n+1): 50 | fact *= i 51 | return fact 52 | 53 | def _test1(): 54 | print('test cases with assert statement called') 55 | assert factorial(1) == 1, "1! != 1" 56 | assert factorial(5) == 120, "5! != 120" 57 | assert factorial(20) == 2432902008176640000 58 | 59 | # factorial of -ve integer 60 | # factorial of non-integer 61 | print('all test cases passed!') 62 | 63 | def _test2(): 64 | print("docttest.testmod() called") 65 | import doctest 66 | doctest.testmod() 67 | print('all test cases passed!') 68 | 69 | if __name__ == "__main__": 70 | import sys 71 | if len(sys.argv) >= 2: 72 | if sys.argv[1] == 'test1': 73 | _test1() 74 | else: 75 | _test2() 76 | else: 77 | print('Usage: python factorial.py [test1/test2]') 78 | -------------------------------------------------------------------------------- /demos/utility/fib.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | import math 3 | """ Fibonacci Module """ 4 | 5 | def fib(n): 6 | """ Calculates the n-th Fibonacci number iteratively 7 | """ 8 | if n < 1: 9 | raise ValueError("expected integer") 10 | if math.floor(n) != n: 11 | raise ValueError("n must be exact integer") 12 | a, b = 1, 1 13 | for i in range(2, n+1): 14 | a, b = b, a + b 15 | return a 16 | 17 | def fibList(n): 18 | """ 19 | returns first n fibonacci sequence as list 20 | """ 21 | fibs = [1, 1] 22 | for i in range(2, n): 23 | fibs.append(fibs[-1]+fibs[-2]) 24 | return fibs 25 | -------------------------------------------------------------------------------- /demos/utility/fib_unittest.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | unittest for fib functions in fib.py module 5 | """ 6 | 7 | import unittest 8 | from fib import fib 9 | 10 | 11 | class FibTest(unittest.TestCase): 12 | # optional - executes before each test function 13 | def setUp(self): 14 | self.fibSeq = [(1, 1), (2, 1), (3, 2), (10, 55), (20, 6765)] 15 | print('setUp executed...') 16 | 17 | # any function that start with test* will be executed automatically 18 | def test1(self): 19 | print('test1') 20 | # assertEqual is defined in TestCase class 21 | for n, val in self.fibSeq: 22 | self.assertEqual(fib(n), val) 23 | 24 | def test2(self): 25 | print('test2') 26 | # function name can be arbitrary but must start with test or 27 | # should be runTest 28 | self.assertEqual(fib(1), 1) 29 | self.assertEqual(fib(10), 55) 30 | self.assertEqual(fib(20), 6765) 31 | 32 | def test3(self): 33 | print('test3') 34 | # doesn't test fib function but gets called... 35 | self.assertAlmostEqual(22/7, 3.142857, 6) 36 | # uncomment the following and run it 37 | # self.assertEqual(22/7, 3.142857) 38 | pass 39 | 40 | def testException(self): 41 | print('test exception') 42 | # notice function is not called but is is passed along with the parameter 43 | self.assertRaises(ValueError, fib, -1) 44 | 45 | # function without test word in name 46 | def someTest(self): 47 | print('someTest') 48 | print('This function will not run!') 49 | 50 | # optional - executes after each test function is executed 51 | def tearDown(self): 52 | self.fibElems = None 53 | print("tearDown executed...") 54 | 55 | 56 | if __name__ == "__main__": 57 | # auto-discover unittest in this module and run it... 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /generatepdfs.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | # Script to convert jupyter notebooks to PDF files. The pdfs are saved in ./pdfs folder 4 | 5 | sudo apt update 6 | sudo apt install -y pandoc texlive texlive-xetex > /dev/null 7 | 8 | files=$(find . -name '*.ipynb') 9 | for f in $files; do 10 | echo Converting: $f 11 | jupyter nbconvert --log-level=0 --output-dir='./pdfs' --to pdf $f > /dev/null 12 | done 13 | -------------------------------------------------------------------------------- /labs/README.md: -------------------------------------------------------------------------------- 1 | # Python Fundamental Labs 2 | 3 | - labs have been moved to its own repository at: [https://github.com/rambasnet/Python-Fundamentals-Lab](https://github.com/rambasnet/Python-Fundamentals-Lab) 4 | - separating should make it easier to work with GitHub Classroom 5 | - in the lab repo, see `readonly_lab` which is supposed to readonly for students 6 | - they can create their own `labs` folder in the repo and work on each lab 7 | - having a read only copy provides a good reference in case students accidently change part of the code they're not supposed to! 8 | -------------------------------------------------------------------------------- /notebooks/Ch00-IntroCourseTableOfContents.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "5ab57a49", 6 | "metadata": {}, 7 | "source": [ 8 | "# Table of Contents\n", 9 | "\n", 10 | "### [Ch01 - Introduction](./Ch01-Introduction.ipynb)\n", 11 | "### [Ch02 - Data, Variables & Standard IO](./Ch02-1-Data-Variables-StdIO.ipynb)\n", 12 | "### [Ch03-1 - Built-in Functions](./Ch03-1-Functions-Built-in.ipynb)\n", 13 | "### [Ch03-2 - Std Library Functions](./Ch03-2-Functions-Library.ipynb)\n", 14 | "### [Ch03-3 - User-defined Functions](./Ch03-3-Functions-UserDefined.ipynb)\n", 15 | "### [Ch03-4 - Unittesting](./Ch03-4-UnittestingFunctions.ipynb)\n", 16 | "### [Ch03-5 - Namespace, Modules & Refactoring](./Ch03-5-NamespaceModulesRefactoring.ipynb)\n", 17 | "### [Ch04 - Conditionals](./Ch04-Conditionals.ipynb)\n", 18 | "### [Ch05 - Iterations](./Ch05-Iterations.ipynb)\n", 19 | "### [Ch06 - Strings](./Ch06-Strings.ipynb)\n", 20 | "### [Ch07 - Tuples](./Ch07-Tuples.ipynb)\n", 21 | "### [Ch08-1 - Lists](./Ch08-1-Lists.ipynb)\n", 22 | "### [Ch09-1 - Dictionaries](./Ch09-1-Dictionaries.ipynb)\n", 23 | "### [Ch09-2 - Built-in Data Structures](./Ch09-2-Built-in-DataStructures.ipynb)\n", 24 | "### [Ch10-1 - File IO & YAML](./Ch10-1-FileIOYAML.ipynb)\n", 25 | "### [Ch10-2 - Rich UI Library](./Ch10-2-RichLibrary.ipynb)\n", 26 | "### [Ch13 - Recursion](./Ch13-Recursion.ipynb)\n", 27 | "### [Ch14 - OOP Introduction](./Ch14-OOP.ipynb)\n" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": null, 33 | "id": "e16018e4", 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [] 37 | } 38 | ], 39 | "metadata": { 40 | "kernelspec": { 41 | "display_name": "Python 3 (ipykernel)", 42 | "language": "python", 43 | "name": "python3" 44 | }, 45 | "language_info": { 46 | "codemirror_mode": { 47 | "name": "ipython", 48 | "version": 3 49 | }, 50 | "file_extension": ".py", 51 | "mimetype": "text/x-python", 52 | "name": "python", 53 | "nbconvert_exporter": "python", 54 | "pygments_lexer": "ipython3", 55 | "version": "3.10.8" 56 | } 57 | }, 58 | "nbformat": 4, 59 | "nbformat_minor": 5 60 | } 61 | -------------------------------------------------------------------------------- /notebooks/Ch01-Introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Introduction\n", 8 | "\"Open\n", 9 | "\n", 10 | "- HTML version of textbook: [http://openbookproject.net/thinkcs/python/english3e/way_of_the_program.html](http://openbookproject.net/thinkcs/python/english3e/way_of_the_program.html)\n", 11 | "- PDF version of textbook: [http://www.greenteapress.com/thinkpython/thinkCSpy/thinkCSpy.pdf](http://www.greenteapress.com/thinkpython/thinkCSpy/thinkCSpy.pdf)\n", 12 | "\n", 13 | "## Topics:\n", 14 | "- Python and its features\n", 15 | "- Ways to run Python code\n", 16 | "- The First Program and its anatomy\n", 17 | "- Computer program and its building blocks\n", 18 | "- Errors and Debugging\n", 19 | "\n", 20 | "## Python Programming Language\n", 21 | "\n", 22 | "- the single most important skill for a computer scientist is problem solving\n", 23 | "- Python is a tool that helps computer scientists and programmers solve problems by writing code\n", 24 | "- One of the most popular programming languages used in various fields: Data Science and Machine Learning, Security, Web Apps, etc.\n", 25 | "- Popularity of Python has been increasing over the years: https://www.tiobe.com/tiobe-index/" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "## Python Features\n", 33 | "- high-level general purpose programming language such as PHP, Perl, Java, JavaScript, C++, etc.\n", 34 | " - as opposed to low level machine language such as assembly\n", 35 | "- interpreted language; needs Python interpreter to execute Python code\n", 36 | "- platform independent/portable; python programs can be run in many platforms including Raspberry Pi\n", 37 | "- open source, can be freely downloaded and use: http://python.org\n", 38 | "- installed using Python package manager such as Anaconda or Miniconda: https://www.anaconda.com/download/\n", 39 | "- two versions Python 2.x and Python 3.x - Notebooks and the text use version 3.x which is the new standard" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "## The Zen of Python\n", 47 | "\n", 48 | "- Pythoneer Tim Peters succinctly channels the Benevolent dictator for life (BDFL)'s guiding principles for Python's design into 20 aphorisms, only 19 of which have been written down\n", 49 | "- Python Enhancement Proposal (PEP) 20 : https://www.python.org/dev/peps/pep-0020/ describes the Zen\n", 50 | "- the following statement is hidden as Easter Egg which states the Zen" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 3, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "name": "stdout", 60 | "output_type": "stream", 61 | "text": [ 62 | "The Zen of Python, by Tim Peters\n", 63 | "\n", 64 | "Beautiful is better than ugly.\n", 65 | "Explicit is better than implicit.\n", 66 | "Simple is better than complex.\n", 67 | "Complex is better than complicated.\n", 68 | "Flat is better than nested.\n", 69 | "Sparse is better than dense.\n", 70 | "Readability counts.\n", 71 | "Special cases aren't special enough to break the rules.\n", 72 | "Although practicality beats purity.\n", 73 | "Errors should never pass silently.\n", 74 | "Unless explicitly silenced.\n", 75 | "In the face of ambiguity, refuse the temptation to guess.\n", 76 | "There should be one-- and preferably only one --obvious way to do it.\n", 77 | "Although that way may not be obvious at first unless you're Dutch.\n", 78 | "Now is better than never.\n", 79 | "Although never is often better than *right* now.\n", 80 | "If the implementation is hard to explain, it's a bad idea.\n", 81 | "If the implementation is easy to explain, it may be a good idea.\n", 82 | "Namespaces are one honking great idea -- let's do more of those!\n" 83 | ] 84 | } 85 | ], 86 | "source": [ 87 | "import this" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## Learning and Writing Python Code\n", 95 | "- one must write code to learn it\n", 96 | "- Python provides interactive mode to practice and use Python for quick calculations such as a calculator\n", 97 | "- most use code editors to write long program also called scripts\n", 98 | "- use [pythontutor.com](http://www.pythontutor.com/) to visualize code execution\n", 99 | "\n", 100 | "### Python Development Environment\n", 101 | "\n", 102 | "- it's recommended to install a good set of programming tools such as Editor, version control software, etc. on your system and be familiar with them to become an effective problem solver\n", 103 | "- complete instructions on setting up development environment for Python on various Operating systems can be found here: https://github.com/rambasnet/DevEnvSetup\n", 104 | "\n", 105 | "### Chevron Prompt\n", 106 | "- Python provides a prompt on terminal to write Python in interactive mode\n", 107 | " - like a calculator\n", 108 | "- Once Python is installed and configured correctly, open terminal and type Python\n", 109 | "- [python.org](https://www.python.org/) also provides online Python prompt\n", 110 | "\n", 111 | "```python\n", 112 | " >>> 10 + 20.5\n", 113 | " 30.5\n", 114 | " >>> print('Hello World!')\n", 115 | " Hello World!\n", 116 | "```\n", 117 | "![Python Prompt](resources/PythonPrompt.png)\n", 118 | "\n", 119 | "### Jupyter Notebook\n", 120 | "- interactive notebook that can have live code, execution results and HTML, texts and multimedia contents!\n", 121 | "- great way to learn, experiment, and take notes while coding\n", 122 | "- Jupyter supports many programming languages such as C, C++, Java, JavaScript, etc.; Python is default!\n", 123 | "\n", 124 | "### Python Script \n", 125 | "- complete program written using a text editor or an Intergrated Development Environment (IDE) such as PyScripter, PyCharm, and Visual Studio (VS) Code, Nodepad++, etc.\n", 126 | "\n", 127 | "### Creating and running Python script\n", 128 | "- open your favourite editor\n", 129 | "- create a hello.py file\n", 130 | "- type print('Hello World!') and save the file\n", 131 | "- run the script from a terminal\n", 132 | "\n", 133 | "```python\n", 134 | "python hello.py\n", 135 | "```" 136 | ] 137 | }, 138 | { 139 | "cell_type": "markdown", 140 | "metadata": {}, 141 | "source": [ 142 | "## Computer Program\n", 143 | "- sequence of instructions that specifies how to perform a computation\n", 144 | "- some basic/fundamental concepts that make up a compupter program:\n", 145 | " - variables, input, output, math, conditional execution and repition\n", 146 | "\n", 147 | "![Program Building Blocks](resources/BuildingBlocks.png)\n", 148 | "\n", 149 | "### variables\n", 150 | "- memory location where data/value can be stored\n", 151 | "\n", 152 | "### input\n", 153 | "- get data from keyboard, a file, or some device\n", 154 | "\n", 155 | "### output\n", 156 | "- display data/answer on screen, or save it to file or to a device\n", 157 | "\n", 158 | "### math\n", 159 | "- basic mathematical operations such as addition, subtraction, multiplication, etc.\n", 160 | "\n", 161 | "### conditional execution\n", 162 | "- check for certain condititions and execute appropriate sequence of statements\n", 163 | "\n", 164 | "### repitition\n", 165 | "- perform some action repeatedly, usually with some variation every time" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "## Debugging\n", 173 | " - finding and getting rid of bugs/errors\n", 174 | " - as long as humans write computer codes, there'll be always errors in computer program\n", 175 | " - although frustrating at times, it is one of the most intellectually rich, challenging, and interesting part of programming" 176 | ] 177 | }, 178 | { 179 | "cell_type": "markdown", 180 | "metadata": {}, 181 | "source": [ 182 | "## Coding Errors\n", 183 | "- errors are also called bugs\n", 184 | "- 3 types: syntax, run-time and semantic\n", 185 | "\n", 186 | "### Syntax errors\n", 187 | "- program needs to follow Python syntax or grammar\n", 188 | "- Python interpreter points out any syntax error when one tries to run the program\n", 189 | "- can't run the program if it has syntax errors" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "### Run-time errors\n", 197 | "- also called run-time exceptions\n", 198 | "- these errors may appear while program is running under certain scenario\n", 199 | "- can be handled to certain extent by adequate testing\n", 200 | "\n", 201 | "### Semantic errors\n", 202 | "- program runs fine but gives wrong answer\n", 203 | "- also called logical errors which occur when the programmers may have misunderstanding of the language quarks or the problem statement or just plain wrong solution\n", 204 | "- can be identified and removed by adequate testing" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": {}, 210 | "source": [ 211 | " ## The First Python Program\n", 212 | " - python programs are usually called scripts\n", 213 | " - traditionally, Hello World is the first program one writes to learn the langauge" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 1, 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "name": "stdout", 223 | "output_type": "stream", 224 | "text": [ 225 | "Hello World!\n" 226 | ] 227 | } 228 | ], 229 | "source": [ 230 | "#----------------------------------------------------------\n", 231 | "# hello world program\n", 232 | "# by: John Doe\n", 233 | "# Jan 1 2017\n", 234 | "# Copyright: Anyone may freely copy or modify this program\n", 235 | "#----------------------------------------------------------\n", 236 | "\n", 237 | "print('Hello World!') # Say hello to the beautiful world!" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "## Anatomy of a Python Script\n", 245 | "\n", 246 | "- python script typically consists of instructions (statments) and comments\n", 247 | "- instructions can be single line and independent or grouped together as a block\n", 248 | "- instructions are for computer to carry out certain computations\n", 249 | "\n", 250 | "\n", 251 | "## Comments\n", 252 | "\n", 253 | "- Python uses \\# symbol to write a single line comment\n", 254 | "- comments are for readers/programmers to convey/explain what the code is doing or supposed to do\n", 255 | "- Python interpreter ignores the comments after \\# symbol\n", 256 | "\n", 257 | "\n", 258 | "## Style Guide for Python Code\n", 259 | "\n", 260 | "- Python creater Guido Van Rossum et al. have published style guide to write beautiful and compliant Python code\n", 261 | "- guidelines can be found described on Python Enhancement Proposol (PEP) 8 here: https://www.python.org/dev/peps/pep-0008/\n", 262 | "- E.g. the guide says that comments must be complete sentence and must be capitalized!" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "## Exercises\n", 270 | "\n", 271 | "### 1. Write a hello world script\n", 272 | "- write a python script that prints \"Hello World!\" as an output on the console\n", 273 | "\n", 274 | "### 2. ASCII Art\n", 275 | "- learn about ASCII Art\n", 276 | "- print some ASCII arts, texts of your choice\n", 277 | "- use ASCII Art text generator: http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20\n", 278 | "\n", 279 | "### 2. Write a script that prints various stages of the hangman game\n", 280 | "- game description: https://en.wikipedia.org/wiki/Hangman_(game)\n", 281 | "- produce the output seen in Example game section of the Wikipedia page\n", 282 | "\n", 283 | "## Kattis Problems\n", 284 | "### 1. hello problem\n", 285 | "- create a free account on Kattis: https://open.kattis.com/login\n", 286 | "- login and solve the hello problem: https://open.kattis.com/problems/hello\n", 287 | "\n", 288 | "### 2. Solve Velkomin!\n", 289 | "- solve the problem - velkomin [https://open.kattis.com/problems/velkomin](https://open.kattis.com/problems/velkomin)\n", 290 | "\n" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": null, 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [] 299 | } 300 | ], 301 | "metadata": { 302 | "kernelspec": { 303 | "display_name": "Python 3 (ipykernel)", 304 | "language": "python", 305 | "name": "python3" 306 | }, 307 | "language_info": { 308 | "codemirror_mode": { 309 | "name": "ipython", 310 | "version": 3 311 | }, 312 | "file_extension": ".py", 313 | "mimetype": "text/x-python", 314 | "name": "python", 315 | "nbconvert_exporter": "python", 316 | "pygments_lexer": "ipython3", 317 | "version": "3.8.12" 318 | } 319 | }, 320 | "nbformat": 4, 321 | "nbformat_minor": 4 322 | } 323 | -------------------------------------------------------------------------------- /notebooks/Ch02-2-BitwiseOperators.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 2. Bitwise Operators\n", 8 | "\n", 9 | "\"Open\n", 10 | "\n", 11 | "- https://wiki.python.org/moin/BitwiseOperators\n", 12 | "\n", 13 | "## Topics\n", 14 | "\n", 15 | "- Number systems\n", 16 | "- Binary representation of positive integers\n", 17 | "- Twos Complement for Negative Integers\n", 18 | "- Bitwise operators\n", 19 | "- Examples\n", 20 | "\n", 21 | "## Number systems\n", 22 | "\n", 23 | "- there are several number systems based on the base\n", 24 | " - base is number of unique digits number system uses to represent numbers\n", 25 | "- binary (base 2), octal (base 8), decimal (base 10), hexadecimal (base 16), etc.\n", 26 | "\n", 27 | "### Decimal number system\n", 28 | "- also called Hindu-Arabic number system\n", 29 | "- most commonly used number system that uses base 10\n", 30 | " - has 10 digits or numerals to represent numbers: 0..9\n", 31 | " - e.g. 1, 79, 1024, 12345, etc.\n", 32 | "- numerals representing numbers have different place values depending on position:\n", 33 | " - ones ($10^0$), tens($10^1$), hundreds($10^2$), thousands($10^3$), ten thousands($10^4$), etc.\n", 34 | " - e.g. 543.21 = $(5\\times10^2)+(4\\times10^1)+(3\\times10^0)+(2\\times10^{-1})+(1\\times10^{-2})$\n", 35 | " \n", 36 | "### Binary number system\n", 37 | "\n", 38 | "- digital computers work with binary number system\n", 39 | "- decimal number system and any text and symbols must be converted into binary for the computer systems to process, store and transmit\n", 40 | "- typically, programming language like C/C++ uses 32-bit or 64-bit depending on the architecture of the system to represent binary numbers\n", 41 | "- Python however uses \"INFINITE\" number of bits to represent Integers in binary\n", 42 | "\n", 43 | " \n", 44 | "## Number system conversion\n", 45 | "\n", 46 | "- since computers understand only binary, everything (data, code) must be converted into binary\n", 47 | "- all characaters (alphabets and symbols) are given decimal codes for electronic communication\n", 48 | " - these codes are called ASCII (American Standard Code for Information Interchange)\n", 49 | " - A -> 65; Z -> 90; a -> 97; z -> 122, * -> 42, etc.\n", 50 | " - see ASCII chart: https://en.cppreference.com/w/c/language/ascii\n", 51 | "\n", 52 | "### Converting decmial to binary number\n", 53 | "\n", 54 | "- Twos-complement for positive integers\n", 55 | "\n", 56 | "- algorithm steps:\n", 57 | " 1. repeteadly divide the decimal number by base 2 until the quotient becomes 0\n", 58 | " - note remainder for each division\n", 59 | " 2. collect all the remainders in reverse order\n", 60 | " - the first remainder is the last (least significant) digit in binary\n", 61 | " \n", 62 | "- example 1: what is decimal $(10)_{10}$ in binary $(?)_2$ ?\n", 63 | " - step 1:\n", 64 | " \n", 65 | " ```bash\n", 66 | " 10 / 2 : quotient: 5, remainder: 0\n", 67 | " 5 / 2 : quotient 2, remainder: 1\n", 68 | " 2 / 2 : quotient: 1, remainder: 0\n", 69 | " 1 / 2 : quotient: 0, remainder: 1 \n", 70 | " ```\n", 71 | " \n", 72 | " - step 2: \n", 73 | " - collect remainders from bottom up: 1010\n", 74 | " - so, $(10)_{10}$ = $(1010)_2$\n", 75 | " \n", 76 | "- example 2: what is decimal $(13)_{10}$ in $(?)_2$ ?\n", 77 | " - step 1:\n", 78 | " \n", 79 | " ```bash\n", 80 | " 13 / 2 : quotient: 6, remainder: 1\n", 81 | " 6 / 2 : quotient 3, remainder: 0\n", 82 | " 3 / 2 : quotient: 1, remainder: 1\n", 83 | " 1 / 2 : quotient: 0, remainder: 1 \n", 84 | " ```\n", 85 | " - step 2:\n", 86 | " - collect remainders from bottom up: 1101\n", 87 | " - so, $(13)_{10}$ = $(1101)_2$\n", 88 | " \n", 89 | "### Converting binary to decimal number\n", 90 | "- once the computer does the computation in binary, it needs to convert the results back to decimal number system for humans to understand\n", 91 | "- algorithm steps:\n", 92 | " 1. multiply each binary digit by its place value in binary\n", 93 | " 2. sum all the products\n", 94 | "\n", 95 | "- example 1: what is binary $(1010)_2$ in decimal $(?)_{10}?$\n", 96 | " - step 1:\n", 97 | " \n", 98 | " - $0\\times2^0 = 0$\n", 99 | " - $1\\times2^1 = 2$\n", 100 | " - $0\\times2^2 = 0$\n", 101 | " - $1\\times2^3 = 8$\n", 102 | " - step 2:\n", 103 | " - $0 + 2 + 0 + 8 = 10$\n", 104 | " - so, $(1010)_2$ = $(10)_{10}$\n", 105 | " \n", 106 | " \n", 107 | "- example 2: what is binary $(1101)_2$ in decimal $(?)_{10}?$\n", 108 | " - step 1:\n", 109 | " \n", 110 | " - $1\\times2^0 = 1$\n", 111 | " - $0\\times2^1 = 0$\n", 112 | " - $1\\times2^2 = 4$\n", 113 | " - $1\\times2^3 = 8$\n", 114 | "\n", 115 | " - step 2:\n", 116 | " - $1+0+4+8 = 13$\n", 117 | " - so, $(1101)_2$ = $(13)_{10}$\n", 118 | "- we got the same decimal vales we started from in previous examples\n", 119 | "\n" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "## Twos Complement for Negative (signed) integers\n", 127 | "- most common method of storing negative numbers on computers is a mathematical operation called Two's complement\n", 128 | "- Two's complement of an N-bit number is defined as its complement with respect to $2^N$\n", 129 | " - the sum of a number and its two's complement is $2^N$\n", 130 | "- e.g.: for the 3-bit binary number $010_2$, the two's complement is $110_2$, because $010_2 + 110_2 = 1000_2 = 2^3_{10}$\n", 131 | "- Two's complement of N-bit number can be found by flipping each bit and adding one to it\n", 132 | "- e.g. Find two's complement of 010 (3-bit integer)\n", 133 | "- Algorithm steps:\n", 134 | " 1. flipped each bit; 0 is flipped to 1 and 1 flipped to 0\n", 135 | " \n", 136 | " ```bash\n", 137 | " 010 -> 101\n", 138 | " ```\n", 139 | " \n", 140 | " 2. add 1 to the flipped binary \n", 141 | " \n", 142 | " ```bash\n", 143 | " \n", 144 | " 101\n", 145 | " +1\n", 146 | " -----\n", 147 | " 110\n", 148 | " ```\n", 149 | " \n", 150 | " \n", 151 | " ### Example 2\n", 152 | " - Represent decimal -13 using 32-bit binary\n", 153 | " - first find the binary of 13 and use Twos complement for negative integers\n", 154 | " " 155 | ] 156 | }, 157 | { 158 | "cell_type": "code", 159 | "execution_count": 3, 160 | "metadata": {}, 161 | "outputs": [ 162 | { 163 | "data": { 164 | "text/plain": [ 165 | "'0b1101'" 166 | ] 167 | }, 168 | "execution_count": 3, 169 | "metadata": {}, 170 | "output_type": "execute_result" 171 | } 172 | ], 173 | "source": [ 174 | "# built-in bin function converts integers into binary\n", 175 | "bin(13)\n", 176 | "# 00000000000000000000000000001101 - 32-bit" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 4, 182 | "metadata": {}, 183 | "outputs": [ 184 | { 185 | "data": { 186 | "text/plain": [ 187 | "'-0b1101'" 188 | ] 189 | }, 190 | "execution_count": 4, 191 | "metadata": {}, 192 | "output_type": "execute_result" 193 | } 194 | ], 195 | "source": [ 196 | "# Python uses -ve sign to represent -ve binary also\n", 197 | "bin(-13)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "markdown", 202 | "metadata": {}, 203 | "source": [ 204 | "### Two's complement of -13 with 32-bit is\n", 205 | "\n", 206 | "```python\n", 207 | "- 13 -> 00000000000000000000000000001101\n", 208 | "- flip every bit: 11111111111111111111111111110010\n", 209 | " +1\n", 210 | " -------------------------------------------\n", 211 | " 11111111111111111111111111110011 \n", 212 | "```\n", 213 | "\n", 214 | "### bitwise operators\n", 215 | "- https://wiki.python.org/moin/BitwiseOperators\n", 216 | "- bitwise operators work on binary numbers (bits)\n", 217 | " - integers are implicitly converted into binary and then bitwise operations are applied\n", 218 | "- bitwise operations are used in lower-level programming such as device drivers, low-level graphics, communications protocol packet assembly, encoding and decoding data, encryption technologies, etc.\n", 219 | "- a lot of integer arithmetic computations can be carried our much more efficiently using bitwise operations\n", 220 | "\n", 221 | "| Operator | Symbol | Symbol Name | Syntax |\tOperation |\n", 222 | "|------| ------ | ---- | ---- | --- |\n", 223 | "|bitwise left shift\t| << |\tleft angular bracket | x << y\t| all bits in x shifted left y bits; multiplication by $2^y$\n", 224 | "|bitwise right shift |\t>> | right angular bracket |x >> y\t| all bits in x shifted right y bits; division by $2^y$\n", 225 | "bitwise NOT\t| ~\t| tilde | ~x\t| all bits in x flipped\n", 226 | "|bitwise AND |\t& |\tampersand | x & y |\teach bit in x AND each bit in y\n", 227 | "|bitwise OR\t| \\| |\tpipe | x \\| y\t| each bit in x OR each bit in y\n", 228 | "bitwise XOR | ^ |\tcaret | x ^ y |\teach bit in x XOR each bit in y\n", 229 | "\n", 230 | "### table for bitwise operations\n", 231 | "\n", 232 | "#### & - bitwise AND\n", 233 | "| x | y | x & y |\n", 234 | "|:---:|:---:|:---:|\n", 235 | "| 1 | 1 | 1 | 1 |\n", 236 | "| 1 | 0 | 0 | 0 |\n", 237 | "| 0 | 1 | 0 | 0 |\n", 238 | "| 0 | 0 | 0 | 0 |\n", 239 | "\n", 240 | "#### | - bitwise OR\n", 241 | "| x | y | x \\| y |\n", 242 | "|:---:|:---:|:---:|\n", 243 | "| 1 | 1 | 1 |\n", 244 | "| 1 | 0 | 1 |\n", 245 | "| 0 | 1 | 1 |\n", 246 | "| 0 | 0 | 0 |\n", 247 | "\n", 248 | "#### ~ - bitwise NOT\n", 249 | "| x | ~x |\n", 250 | "|:---:|:---:|\n", 251 | "| 1 | 0 |\n", 252 | "| 0 | 1 |\n", 253 | "\n", 254 | "#### ^ - bitwise XOR\n", 255 | "| x | y | x ^ y |\n", 256 | "|:---:|:---:|:---:|\n", 257 | "| 1 | 1 | 0 |\n", 258 | "| 1 | 0 | 1 |\n", 259 | "| 0 | 1 | 1 |\n", 260 | "| 0 | 0 | 0 |\n", 261 | "\n", 262 | "#### bitwise left shift examples" 263 | ] 264 | }, 265 | { 266 | "cell_type": "code", 267 | "execution_count": 5, 268 | "metadata": {}, 269 | "outputs": [ 270 | { 271 | "data": { 272 | "text/plain": [ 273 | "16" 274 | ] 275 | }, 276 | "execution_count": 5, 277 | "metadata": {}, 278 | "output_type": "execute_result" 279 | } 280 | ], 281 | "source": [ 282 | "# convert 1 decimal to binary and shift left by 4 bits\n", 283 | "1 << 4 # same as 1*2*2*2*2; result is in decimal" 284 | ] 285 | }, 286 | { 287 | "cell_type": "markdown", 288 | "metadata": {}, 289 | "source": [ 290 | "#### Explanation\n", 291 | "- Note: in the following examples, binary uses 32-bit to represent decmial\n", 292 | "\n", 293 | "- $1_{10} = 00000000000000000000000000000001_2$\n", 294 | "- $1 << 4$ = $000000000000000000000000000010000 = 2^4 = 16_{10}$" 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "execution_count": 6, 300 | "metadata": {}, 301 | "outputs": [ 302 | { 303 | "data": { 304 | "text/plain": [ 305 | "48" 306 | ] 307 | }, 308 | "execution_count": 6, 309 | "metadata": {}, 310 | "output_type": "execute_result" 311 | } 312 | ], 313 | "source": [ 314 | "3 << 4 # same as 3*2*2*2*2 or 3*2^4" 315 | ] 316 | }, 317 | { 318 | "cell_type": "markdown", 319 | "metadata": {}, 320 | "source": [ 321 | "#### Explanation\n", 322 | "\n", 323 | "- $3_{10} = 00000000000000000000000000000011_2$\n", 324 | "- $3 << 4 = 00000000000000000000000000110000_2 = 2^5+2^4 = 32+16 = 48_{10}$\n", 325 | "\n", 326 | "#### Bitwise right shit examples" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": 7, 332 | "metadata": {}, 333 | "outputs": [ 334 | { 335 | "data": { 336 | "text/plain": [ 337 | "1" 338 | ] 339 | }, 340 | "execution_count": 7, 341 | "metadata": {}, 342 | "output_type": "execute_result" 343 | } 344 | ], 345 | "source": [ 346 | "1024 >> 10 # same as 1024/2/2/2/2/2/2/2/2/2/2" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "#### Explanation\n", 354 | "\n", 355 | "- $1024_{10} = 00000000000000000000010000000000_2$\n", 356 | "- $1024 >> 10 = 00000000000000000000000000000001_2 = 2^0 = 1_{10}$\n", 357 | "\n", 358 | "#### Bitwise NOT examples" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 8, 364 | "metadata": {}, 365 | "outputs": [ 366 | { 367 | "data": { 368 | "text/plain": [ 369 | "-1" 370 | ] 371 | }, 372 | "execution_count": 8, 373 | "metadata": {}, 374 | "output_type": "execute_result" 375 | } 376 | ], 377 | "source": [ 378 | "~0 # result shown is in decimal!" 379 | ] 380 | }, 381 | { 382 | "cell_type": "code", 383 | "execution_count": 9, 384 | "metadata": {}, 385 | "outputs": [ 386 | { 387 | "data": { 388 | "text/plain": [ 389 | "-2" 390 | ] 391 | }, 392 | "execution_count": 9, 393 | "metadata": {}, 394 | "output_type": "execute_result" 395 | } 396 | ], 397 | "source": [ 398 | "~1 # Note: 1 in binary using 32-bit width (31 0s and 1) 00000....1\n", 399 | "\n", 400 | "#result shown is in decimal" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "#### Explanation\n", 408 | "\n", 409 | "- $0_{10} = 00000000000000000000000000000000_2$\n", 410 | "- $1_{10} = 00000000000000000000000000000001_2$\n", 411 | "- $-1_{10} = 11111111111111111111111111111111_2$\n", 412 | "- $2_{10} = 00000000000000000000000000000010_2$\n", 413 | "- $-2_{10} = 11111111111111111111111111111110_2$\n", 414 | "- Note: -ve numbers are stored in Two's complement\n", 415 | " - 2's complement is calculated by flipping each bit and adding 1 to the binary of positive integer\n", 416 | " \n", 417 | "#### Bitwise AND examples" 418 | ] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": 10, 423 | "metadata": {}, 424 | "outputs": [ 425 | { 426 | "data": { 427 | "text/plain": [ 428 | "1" 429 | ] 430 | }, 431 | "execution_count": 10, 432 | "metadata": {}, 433 | "output_type": "execute_result" 434 | } 435 | ], 436 | "source": [ 437 | "1 & 1" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": 11, 443 | "metadata": {}, 444 | "outputs": [ 445 | { 446 | "data": { 447 | "text/plain": [ 448 | "0" 449 | ] 450 | }, 451 | "execution_count": 11, 452 | "metadata": {}, 453 | "output_type": "execute_result" 454 | } 455 | ], 456 | "source": [ 457 | "1 & 0" 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": 12, 463 | "metadata": {}, 464 | "outputs": [ 465 | { 466 | "data": { 467 | "text/plain": [ 468 | "0" 469 | ] 470 | }, 471 | "execution_count": 12, 472 | "metadata": {}, 473 | "output_type": "execute_result" 474 | } 475 | ], 476 | "source": [ 477 | "0 & 1" 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": 13, 483 | "metadata": {}, 484 | "outputs": [ 485 | { 486 | "data": { 487 | "text/plain": [ 488 | "0" 489 | ] 490 | }, 491 | "execution_count": 13, 492 | "metadata": {}, 493 | "output_type": "execute_result" 494 | } 495 | ], 496 | "source": [ 497 | "0 & 0" 498 | ] 499 | }, 500 | { 501 | "cell_type": "markdown", 502 | "metadata": {}, 503 | "source": [ 504 | "### Bitwise OR examples" 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": 14, 510 | "metadata": {}, 511 | "outputs": [ 512 | { 513 | "data": { 514 | "text/plain": [ 515 | "1" 516 | ] 517 | }, 518 | "execution_count": 14, 519 | "metadata": {}, 520 | "output_type": "execute_result" 521 | } 522 | ], 523 | "source": [ 524 | "1 | 1" 525 | ] 526 | }, 527 | { 528 | "cell_type": "code", 529 | "execution_count": 15, 530 | "metadata": {}, 531 | "outputs": [ 532 | { 533 | "data": { 534 | "text/plain": [ 535 | "1" 536 | ] 537 | }, 538 | "execution_count": 15, 539 | "metadata": {}, 540 | "output_type": "execute_result" 541 | } 542 | ], 543 | "source": [ 544 | "1 | 0" 545 | ] 546 | }, 547 | { 548 | "cell_type": "code", 549 | "execution_count": 16, 550 | "metadata": {}, 551 | "outputs": [ 552 | { 553 | "data": { 554 | "text/plain": [ 555 | "1" 556 | ] 557 | }, 558 | "execution_count": 16, 559 | "metadata": {}, 560 | "output_type": "execute_result" 561 | } 562 | ], 563 | "source": [ 564 | "0 | 1" 565 | ] 566 | }, 567 | { 568 | "cell_type": "code", 569 | "execution_count": 19, 570 | "metadata": {}, 571 | "outputs": [ 572 | { 573 | "data": { 574 | "text/plain": [ 575 | "0" 576 | ] 577 | }, 578 | "execution_count": 19, 579 | "metadata": {}, 580 | "output_type": "execute_result" 581 | } 582 | ], 583 | "source": [ 584 | "0 | 0" 585 | ] 586 | }, 587 | { 588 | "cell_type": "markdown", 589 | "metadata": {}, 590 | "source": [ 591 | "### Bitwise XOR examples" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": 20, 597 | "metadata": {}, 598 | "outputs": [ 599 | { 600 | "data": { 601 | "text/plain": [ 602 | "0" 603 | ] 604 | }, 605 | "execution_count": 20, 606 | "metadata": {}, 607 | "output_type": "execute_result" 608 | } 609 | ], 610 | "source": [ 611 | "1 ^ 1" 612 | ] 613 | }, 614 | { 615 | "cell_type": "code", 616 | "execution_count": 21, 617 | "metadata": {}, 618 | "outputs": [ 619 | { 620 | "data": { 621 | "text/plain": [ 622 | "1" 623 | ] 624 | }, 625 | "execution_count": 21, 626 | "metadata": {}, 627 | "output_type": "execute_result" 628 | } 629 | ], 630 | "source": [ 631 | "1 ^ 0" 632 | ] 633 | }, 634 | { 635 | "cell_type": "code", 636 | "execution_count": 22, 637 | "metadata": {}, 638 | "outputs": [ 639 | { 640 | "data": { 641 | "text/plain": [ 642 | "1" 643 | ] 644 | }, 645 | "execution_count": 22, 646 | "metadata": {}, 647 | "output_type": "execute_result" 648 | } 649 | ], 650 | "source": [ 651 | "0 ^ 1" 652 | ] 653 | }, 654 | { 655 | "cell_type": "code", 656 | "execution_count": 24, 657 | "metadata": {}, 658 | "outputs": [ 659 | { 660 | "data": { 661 | "text/plain": [ 662 | "0" 663 | ] 664 | }, 665 | "execution_count": 24, 666 | "metadata": {}, 667 | "output_type": "execute_result" 668 | } 669 | ], 670 | "source": [ 671 | "0 ^ 0" 672 | ] 673 | }, 674 | { 675 | "cell_type": "code", 676 | "execution_count": null, 677 | "metadata": {}, 678 | "outputs": [], 679 | "source": [] 680 | } 681 | ], 682 | "metadata": { 683 | "kernelspec": { 684 | "display_name": "Python 3 (ipykernel)", 685 | "language": "python", 686 | "name": "python3" 687 | }, 688 | "language_info": { 689 | "codemirror_mode": { 690 | "name": "ipython", 691 | "version": 3 692 | }, 693 | "file_extension": ".py", 694 | "mimetype": "text/x-python", 695 | "name": "python", 696 | "nbconvert_exporter": "python", 697 | "pygments_lexer": "ipython3", 698 | "version": "3.8.11" 699 | } 700 | }, 701 | "nbformat": 4, 702 | "nbformat_minor": 2 703 | } 704 | -------------------------------------------------------------------------------- /notebooks/Ch03-1-Functions-Built-in.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Built-in Functions\n", 8 | "\"Open\n", 9 | "\n", 10 | "- named sequence of code that does some specific task or a function\n", 11 | "- we'll learn how to define our own functions in [User Defined Functions chapter](./Ch03-3-Functions-UserDefined.ipynb)\n", 12 | "- some built-in functions we've used so far: `type( ), int( ), float( ), str( ), input( ), print( )`, etc.\n", 13 | "- Python provides a list of built-in functions that are readily available for use:\n", 14 | "https://docs.python.org/3/library/functions.html\n", 15 | "- below are examples of some built-in functions that may be useful to know" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "### bin(x)\n", 23 | "- converts an integer number $x$ to a binary string prefixed with \"0b\"." 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 1, 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "data": { 33 | "text/plain": [ 34 | "'0b11'" 35 | ] 36 | }, 37 | "execution_count": 1, 38 | "metadata": {}, 39 | "output_type": "execute_result" 40 | } 41 | ], 42 | "source": [ 43 | "bin(3)" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "metadata": {}, 49 | "source": [ 50 | "### format(value, format_spec)\n", 51 | "- formats the give value using format spec" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 1, 57 | "metadata": {}, 58 | "outputs": [ 59 | { 60 | "name": "stdout", 61 | "output_type": "stream", 62 | "text": [ 63 | "Help on built-in function format in module builtins:\n", 64 | "\n", 65 | "format(value, format_spec='', /)\n", 66 | " Return value.__format__(format_spec)\n", 67 | " \n", 68 | " format_spec defaults to the empty string.\n", 69 | " See the Format Specification Mini-Language section of help('FORMATTING') for\n", 70 | " details.\n", 71 | "\n" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "help(format)" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 2, 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "0b11\n", 89 | "11\n" 90 | ] 91 | } 92 | ], 93 | "source": [ 94 | "# If prefix \"0b is desired or not, use either of the following ways\n", 95 | "print(format(3, '#b'))\n", 96 | "print(format(3, 'b'))" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "### chr( uniCode )\n", 104 | "- returns the string representing a character whose Unicode code point is the integer uniCode\n", 105 | "- inverse of ord(character)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 3, 111 | "metadata": {}, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "A\n", 118 | "a\n", 119 | "€\n" 120 | ] 121 | } 122 | ], 123 | "source": [ 124 | "print(chr(65))\n", 125 | "print(chr(97))\n", 126 | "print(chr(8364))" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "### globals() and locals()\n", 134 | "- globals() returns a dictionary representing the current global symbol table\n", 135 | "- locals() returns a dictionary representing the current local symbol table" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 4, 141 | "metadata": {}, 142 | "outputs": [ 143 | { 144 | "data": { 145 | "text/plain": [ 146 | "{'__name__': '__main__',\n", 147 | " '__doc__': 'Automatically created module for IPython interactive environment',\n", 148 | " '__package__': None,\n", 149 | " '__loader__': None,\n", 150 | " '__spec__': None,\n", 151 | " '__builtin__': ,\n", 152 | " '__builtins__': ,\n", 153 | " '_ih': ['',\n", 154 | " 'bin(3)',\n", 155 | " '# If prefix \"0b is desired or not, use either of the following ways\\nprint(format(3, \\'#b\\'))\\nprint(format(3, \\'b\\'))',\n", 156 | " 'print(chr(65))\\nprint(chr(97))\\nprint(chr(8364))',\n", 157 | " 'globals()'],\n", 158 | " '_oh': {1: '0b11'},\n", 159 | " '_dh': ['/Volumes/Storage/GoogleDrive/CMU/Python/thinkpythonnotebooks'],\n", 160 | " '_sh': ,\n", 161 | " 'In': ['',\n", 162 | " 'bin(3)',\n", 163 | " '# If prefix \"0b is desired or not, use either of the following ways\\nprint(format(3, \\'#b\\'))\\nprint(format(3, \\'b\\'))',\n", 164 | " 'print(chr(65))\\nprint(chr(97))\\nprint(chr(8364))',\n", 165 | " 'globals()'],\n", 166 | " 'Out': {1: '0b11'},\n", 167 | " 'get_ipython': >,\n", 168 | " 'exit': ,\n", 169 | " 'quit': ,\n", 170 | " '_': '0b11',\n", 171 | " '__': '',\n", 172 | " '___': '',\n", 173 | " '_i': 'print(chr(65))\\nprint(chr(97))\\nprint(chr(8364))',\n", 174 | " '_ii': '# If prefix \"0b is desired or not, use either of the following ways\\nprint(format(3, \\'#b\\'))\\nprint(format(3, \\'b\\'))',\n", 175 | " '_iii': 'bin(3)',\n", 176 | " '_i1': 'bin(3)',\n", 177 | " '_1': '0b11',\n", 178 | " '_i2': '# If prefix \"0b is desired or not, use either of the following ways\\nprint(format(3, \\'#b\\'))\\nprint(format(3, \\'b\\'))',\n", 179 | " '_i3': 'print(chr(65))\\nprint(chr(97))\\nprint(chr(8364))',\n", 180 | " '_i4': 'globals()'}" 181 | ] 182 | }, 183 | "execution_count": 4, 184 | "metadata": {}, 185 | "output_type": "execute_result" 186 | } 187 | ], 188 | "source": [ 189 | "globals()" 190 | ] 191 | }, 192 | { 193 | "cell_type": "markdown", 194 | "metadata": {}, 195 | "source": [ 196 | "### hex(x)\n", 197 | "- convert an integer number to a lowercase hexadecimal string prefixed with \"0x\"" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 5, 203 | "metadata": {}, 204 | "outputs": [ 205 | { 206 | "name": "stdout", 207 | "output_type": "stream", 208 | "text": [ 209 | "0x2a\n", 210 | "-0x2a\n" 211 | ] 212 | } 213 | ], 214 | "source": [ 215 | "print(hex(42))\n", 216 | "print(hex(-42))" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 2, 222 | "metadata": {}, 223 | "outputs": [ 224 | { 225 | "name": "stdout", 226 | "output_type": "stream", 227 | "text": [ 228 | "0xff\n", 229 | "ff\n", 230 | "FF\n" 231 | ] 232 | } 233 | ], 234 | "source": [ 235 | "# Other ways\n", 236 | "print(format(255, '#x'))\n", 237 | "print(format(255, 'x'))\n", 238 | "print(format(255, 'X'))" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": {}, 244 | "source": [ 245 | "### oct(x)\n", 246 | "- return an octal string representation with \"0o\" prefix of a given integer x" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": 7, 252 | "metadata": {}, 253 | "outputs": [ 254 | { 255 | "name": "stdout", 256 | "output_type": "stream", 257 | "text": [ 258 | "0o144\n" 259 | ] 260 | } 261 | ], 262 | "source": [ 263 | "print(oct(100))" 264 | ] 265 | }, 266 | { 267 | "cell_type": "code", 268 | "execution_count": 8, 269 | "metadata": {}, 270 | "outputs": [ 271 | { 272 | "name": "stdout", 273 | "output_type": "stream", 274 | "text": [ 275 | "0o12\n", 276 | "12\n" 277 | ] 278 | } 279 | ], 280 | "source": [ 281 | "print(format(10, '#o'))\n", 282 | "print(format(10, 'o'))" 283 | ] 284 | }, 285 | { 286 | "cell_type": "markdown", 287 | "metadata": {}, 288 | "source": [ 289 | "### ord(c)\n", 290 | "- return an integer representing the Unicode code of a given Unicode character" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 9, 296 | "metadata": {}, 297 | "outputs": [ 298 | { 299 | "name": "stdout", 300 | "output_type": "stream", 301 | "text": [ 302 | "32\n", 303 | "126\n" 304 | ] 305 | } 306 | ], 307 | "source": [ 308 | "print(ord(' '))\n", 309 | "print(ord('~'))" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "### id(object)\n", 317 | "- return the 'identity' of an object\n", 318 | "- guaranteed unique integer and constant thoughout its lifetime" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": 10, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "x = 10" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": 11, 333 | "metadata": {}, 334 | "outputs": [ 335 | { 336 | "data": { 337 | "text/plain": [ 338 | "4525196800" 339 | ] 340 | }, 341 | "execution_count": 11, 342 | "metadata": {}, 343 | "output_type": "execute_result" 344 | } 345 | ], 346 | "source": [ 347 | "id(x)" 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "metadata": {}, 353 | "source": [ 354 | "### divmod(a, b)\n", 355 | "- given two non-complex numbers as arguments, return a pair of numbers as tuple consisting of their quotient and remainder using integer division" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 12, 361 | "metadata": {}, 362 | "outputs": [ 363 | { 364 | "name": "stdout", 365 | "output_type": "stream", 366 | "text": [ 367 | "(2, 1)\n", 368 | "2 1\n" 369 | ] 370 | } 371 | ], 372 | "source": [ 373 | "print(divmod(7, 3)) # Return (quotient, remainder)\n", 374 | "quotient, remainder = divmod(7, 3)\n", 375 | "print(quotient, remainder)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "### eval(expression, globals=None, locals=None)\n", 383 | "- the expression argument is parsed and evaluated as Python expression\n", 384 | "- syntax errors reported as exceptions" 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": 13, 390 | "metadata": {}, 391 | "outputs": [ 392 | { 393 | "name": "stdout", 394 | "output_type": "stream", 395 | "text": [ 396 | "4\n", 397 | "8\n" 398 | ] 399 | } 400 | ], 401 | "source": [ 402 | "y = 2\n", 403 | "print(eval('y**2'))\n", 404 | "print(eval('y+2*3'))" 405 | ] 406 | }, 407 | { 408 | "cell_type": "markdown", 409 | "metadata": {}, 410 | "source": [ 411 | "### max(iterable, ...) or max(arg1, arg2, ...)\n", 412 | "- returns the largest item in an iterable or the largest of two or more arguments" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 14, 418 | "metadata": {}, 419 | "outputs": [ 420 | { 421 | "name": "stdout", 422 | "output_type": "stream", 423 | "text": [ 424 | "max= 1000.5\n" 425 | ] 426 | } 427 | ], 428 | "source": [ 429 | "print('max=', max(100, 8.9, 999, 1000.5))" 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "metadata": {}, 435 | "source": [ 436 | "### min(arg1, arg2, ...)\n", 437 | "- returns the smallest of the the arguments (arg1, arg2...)" 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": 15, 443 | "metadata": {}, 444 | "outputs": [ 445 | { 446 | "name": "stdout", 447 | "output_type": "stream", 448 | "text": [ 449 | "min= 8.9\n" 450 | ] 451 | } 452 | ], 453 | "source": [ 454 | "print('min=', min(100, 8.9, 999, 1000.5))" 455 | ] 456 | }, 457 | { 458 | "cell_type": "markdown", 459 | "metadata": {}, 460 | "source": [ 461 | "### pow(base, exponent) \n", 462 | "- returns base to the power exponent" 463 | ] 464 | }, 465 | { 466 | "cell_type": "code", 467 | "execution_count": 16, 468 | "metadata": {}, 469 | "outputs": [ 470 | { 471 | "name": "stdout", 472 | "output_type": "stream", 473 | "text": [ 474 | "2 to the power 3 = 8\n" 475 | ] 476 | } 477 | ], 478 | "source": [ 479 | "print('2 to the power 3 =', pow(2, 3))" 480 | ] 481 | }, 482 | { 483 | "cell_type": "markdown", 484 | "metadata": {}, 485 | "source": [ 486 | "### print( )\n", 487 | "- print(*object, sep=' ', end='\\\\n', file=sys.stdout, flush=False) prototype\n", 488 | "- print takes many arguments and prints arbitrary number of values\n", 489 | "- below demos some print examples with different argument values" 490 | ] 491 | }, 492 | { 493 | "cell_type": "code", 494 | "execution_count": 1, 495 | "metadata": {}, 496 | "outputs": [ 497 | { 498 | "name": "stdout", 499 | "output_type": "stream", 500 | "text": [ 501 | "hihellonext line?\n" 502 | ] 503 | } 504 | ], 505 | "source": [ 506 | "print('hi', 'hello', sep='', end='')\n", 507 | "print('next line?')" 508 | ] 509 | }, 510 | { 511 | "cell_type": "code", 512 | "execution_count": 2, 513 | "metadata": {}, 514 | "outputs": [ 515 | { 516 | "name": "stdout", 517 | "output_type": "stream", 518 | "text": [ 519 | "hi hellonext line?\n" 520 | ] 521 | } 522 | ], 523 | "source": [ 524 | "print('hi', 'hello', sep=' ', end='')\n", 525 | "print('next line?')" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": 7, 531 | "metadata": {}, 532 | "outputs": [ 533 | { 534 | "name": "stdout", 535 | "output_type": "stream", 536 | "text": [ 537 | "hi$hello$1$2$3next line?\n" 538 | ] 539 | } 540 | ], 541 | "source": [ 542 | "print('hi', 'hello', 1, 2, 3, sep='$', end='', flush=True)\n", 543 | "print('next line?')" 544 | ] 545 | }, 546 | { 547 | "cell_type": "code", 548 | "execution_count": 4, 549 | "metadata": {}, 550 | "outputs": [ 551 | { 552 | "name": "stdout", 553 | "output_type": "stream", 554 | "text": [ 555 | "hi\thello\n", 556 | "next line?\n" 557 | ] 558 | } 559 | ], 560 | "source": [ 561 | "print('hi', 'hello', sep='\\t', end='\\n')\n", 562 | "print('next line?')" 563 | ] 564 | }, 565 | { 566 | "cell_type": "markdown", 567 | "metadata": {}, 568 | "source": [ 569 | "## Kattis Problems\n", 570 | "\n", 571 | "### Buka\n", 572 | "- [https://open.kattis.com/problems/buka](https://open.kattis.com/problems/buka)\n", 573 | "- Hint: use eval() on 3 input strings\n", 574 | "\n", 575 | "### Ekki dauði opna inni\n", 576 | "- [https://open.kattis.com/problems/ekkidaudi](https://open.kattis.com/problems/ekkidaudi)\n", 577 | "- Hinit: use .split('|') method on string and just print\n", 578 | "\n" 579 | ] 580 | }, 581 | { 582 | "cell_type": "code", 583 | "execution_count": null, 584 | "metadata": {}, 585 | "outputs": [], 586 | "source": [] 587 | } 588 | ], 589 | "metadata": { 590 | "kernelspec": { 591 | "display_name": "Python 3 (ipykernel)", 592 | "language": "python", 593 | "name": "python3" 594 | }, 595 | "language_info": { 596 | "codemirror_mode": { 597 | "name": "ipython", 598 | "version": 3 599 | }, 600 | "file_extension": ".py", 601 | "mimetype": "text/x-python", 602 | "name": "python", 603 | "nbconvert_exporter": "python", 604 | "pygments_lexer": "ipython3", 605 | "version": "3.8.12" 606 | } 607 | }, 608 | "nbformat": 4, 609 | "nbformat_minor": 4 610 | } 611 | -------------------------------------------------------------------------------- /notebooks/Ch07-Tuples.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tuples\n", 8 | "\"Open\n", 9 | "\n", 10 | "- http://openbookproject.net/thinkcs/python/english3e/tuples.html\n", 11 | "- containers used for grouping data values surrounded with parenthesis\n", 12 | "- data values in tuples are called elements/items/members\n", 13 | "- two major operations done with tuples are:\n", 14 | " 1. packing (creating tuples)\n", 15 | " 2. unpacking (storing data into individual variables)" 16 | ] 17 | }, 18 | { 19 | "cell_type": "code", 20 | "execution_count": 1, 21 | "metadata": {}, 22 | "outputs": [], 23 | "source": [ 24 | "year_born = (\"Paris Hilton\", 1981) # tuple packing" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 2, 30 | "metadata": {}, 31 | "outputs": [ 32 | { 33 | "name": "stdout", 34 | "output_type": "stream", 35 | "text": [ 36 | "('Paris Hilton', 1981)\n" 37 | ] 38 | } 39 | ], 40 | "source": [ 41 | "print(year_born)" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 11, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "star = \"Paris\", 'J', 'Hilton', 1981, 32, 1.2 # tuple packing without parenthesis" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": 12, 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "data": { 60 | "text/plain": [ 61 | "('Paris', 'J', 'Hilton', 1981, 32, 1.2)" 62 | ] 63 | }, 64 | "execution_count": 12, 65 | "metadata": {}, 66 | "output_type": "execute_result" 67 | } 68 | ], 69 | "source": [ 70 | "star" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 13, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "text/plain": [ 81 | "tuple" 82 | ] 83 | }, 84 | "execution_count": 13, 85 | "metadata": {}, 86 | "output_type": "execute_result" 87 | } 88 | ], 89 | "source": [ 90 | "type(star)" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 14, 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "# tuple assignment\n", 100 | "fname, mi, lname, year, age, income = star # tuple unpacking \n", 101 | "# no. of variables must match no. values in tuple" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 9, 107 | "metadata": {}, 108 | "outputs": [ 109 | { 110 | "data": { 111 | "text/plain": [ 112 | "'Paris'" 113 | ] 114 | }, 115 | "execution_count": 9, 116 | "metadata": {}, 117 | "output_type": "execute_result" 118 | } 119 | ], 120 | "source": [ 121 | "fname" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 10, 127 | "metadata": {}, 128 | "outputs": [ 129 | { 130 | "data": { 131 | "text/plain": [ 132 | "'Hilton'" 133 | ] 134 | }, 135 | "execution_count": 10, 136 | "metadata": {}, 137 | "output_type": "execute_result" 138 | } 139 | ], 140 | "source": [ 141 | "lname" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 11, 147 | "metadata": {}, 148 | "outputs": [ 149 | { 150 | "name": "stdout", 151 | "output_type": "stream", 152 | "text": [ 153 | "1.2\n" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "print(income)" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 12, 164 | "metadata": {}, 165 | "outputs": [], 166 | "source": [ 167 | "# swap values of two variables\n", 168 | "a = 100\n", 169 | "b = 200\n", 170 | "a, b = b, a" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": 13, 176 | "metadata": {}, 177 | "outputs": [ 178 | { 179 | "name": "stdout", 180 | "output_type": "stream", 181 | "text": [ 182 | "200 100\n" 183 | ] 184 | } 185 | ], 186 | "source": [ 187 | "print(a, b)" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "## Member access\n", 195 | "- each member of tuple can be accessed using `[ index ]` operator\n", 196 | "- index is 0-based or starts from 0" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 1, 202 | "metadata": {}, 203 | "outputs": [], 204 | "source": [ 205 | "name = ('John', 'A.', 'Smith')" 206 | ] 207 | }, 208 | { 209 | "cell_type": "code", 210 | "execution_count": 3, 211 | "metadata": {}, 212 | "outputs": [ 213 | { 214 | "name": "stdout", 215 | "output_type": "stream", 216 | "text": [ 217 | "John A. Smith\n" 218 | ] 219 | } 220 | ], 221 | "source": [ 222 | "print(name[0], name[1], name[2])" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "## Length of tuple\n", 230 | "\n", 231 | "- `len()` gives the length (no. of elements) of tuple" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 4, 237 | "metadata": {}, 238 | "outputs": [ 239 | { 240 | "data": { 241 | "text/plain": [ 242 | "3" 243 | ] 244 | }, 245 | "execution_count": 4, 246 | "metadata": {}, 247 | "output_type": "execute_result" 248 | } 249 | ], 250 | "source": [ 251 | "len(name)" 252 | ] 253 | }, 254 | { 255 | "cell_type": "markdown", 256 | "metadata": {}, 257 | "source": [ 258 | "## Tuple membership\n", 259 | "- **in** and **not in** boolean operators let's you check for membership" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": 7, 265 | "metadata": {}, 266 | "outputs": [ 267 | { 268 | "data": { 269 | "text/plain": [ 270 | "True" 271 | ] 272 | }, 273 | "execution_count": 7, 274 | "metadata": {}, 275 | "output_type": "execute_result" 276 | } 277 | ], 278 | "source": [ 279 | "'John' in name" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": 8, 285 | "metadata": {}, 286 | "outputs": [ 287 | { 288 | "data": { 289 | "text/plain": [ 290 | "False" 291 | ] 292 | }, 293 | "execution_count": 8, 294 | "metadata": {}, 295 | "output_type": "execute_result" 296 | } 297 | ], 298 | "source": [ 299 | "'B.' in name" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "execution_count": 9, 305 | "metadata": {}, 306 | "outputs": [ 307 | { 308 | "data": { 309 | "text/plain": [ 310 | "True" 311 | ] 312 | }, 313 | "execution_count": 9, 314 | "metadata": {}, 315 | "output_type": "execute_result" 316 | } 317 | ], 318 | "source": [ 319 | "'Jake' not in name" 320 | ] 321 | }, 322 | { 323 | "cell_type": "markdown", 324 | "metadata": {}, 325 | "source": [ 326 | "## Function can return multiple values as Tuple\n", 327 | "\n", 328 | "- multiple comma separated values can be packed and returned as tuple from function " 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": 2, 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [ 337 | "def maxAndMin(a, b, c, d, e):\n", 338 | " myMax = a #max(a, b, c, d, e)\n", 339 | " if myMax < b:\n", 340 | " myMax = b\n", 341 | " if myMax < c:\n", 342 | " myMax = c\n", 343 | " if myMax < d:\n", 344 | " myMax = d\n", 345 | " if myMax < e:\n", 346 | " myMax = e\n", 347 | " values = [a, b, c, d, e]\n", 348 | " myMin = min(values)\n", 349 | " return myMax, myMin\n", 350 | " " 351 | ] 352 | }, 353 | { 354 | "cell_type": "code", 355 | "execution_count": 4, 356 | "metadata": {}, 357 | "outputs": [ 358 | { 359 | "name": "stdout", 360 | "output_type": "stream", 361 | "text": [ 362 | "max = 100 and min = 5\n" 363 | ] 364 | } 365 | ], 366 | "source": [ 367 | "ab = maxAndMin(10, 20, 5, 100, 34)\n", 368 | "print(f'max = {ab[0]} and min = {ab[1]}')" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "metadata": {}, 374 | "source": [ 375 | "## Tuples are immutable\n", 376 | "- can't change tuple in-place or update its elements \n", 377 | " - similar to string" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": 5, 383 | "metadata": {}, 384 | "outputs": [ 385 | { 386 | "name": "stdout", 387 | "output_type": "stream", 388 | "text": [ 389 | "1\n" 390 | ] 391 | } 392 | ], 393 | "source": [ 394 | "a = (1, 2, 3)\n", 395 | "print(a[0])" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 6, 401 | "metadata": {}, 402 | "outputs": [ 403 | { 404 | "ename": "TypeError", 405 | "evalue": "'tuple' object does not support item assignment", 406 | "output_type": "error", 407 | "traceback": [ 408 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 409 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 410 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 411 | "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" 412 | ] 413 | } 414 | ], 415 | "source": [ 416 | "a[0] = 100" 417 | ] 418 | }, 419 | { 420 | "cell_type": "markdown", 421 | "metadata": {}, 422 | "source": [ 423 | "## Applications of Tuple\n", 424 | "\n", 425 | "- application of tuples is limited due to its immutability in nature" 426 | ] 427 | }, 428 | { 429 | "cell_type": "code", 430 | "execution_count": null, 431 | "metadata": {}, 432 | "outputs": [], 433 | "source": [] 434 | } 435 | ], 436 | "metadata": { 437 | "kernelspec": { 438 | "display_name": "Python 3", 439 | "language": "python", 440 | "name": "python3" 441 | }, 442 | "language_info": { 443 | "codemirror_mode": { 444 | "name": "ipython", 445 | "version": 3 446 | }, 447 | "file_extension": ".py", 448 | "mimetype": "text/x-python", 449 | "name": "python", 450 | "nbconvert_exporter": "python", 451 | "pygments_lexer": "ipython3", 452 | "version": "3.8.11" 453 | } 454 | }, 455 | "nbformat": 4, 456 | "nbformat_minor": 2 457 | } 458 | -------------------------------------------------------------------------------- /notebooks/Ch10-2-Files-Advanced.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Advanced Topics on Files" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## Working with HTML files\n", 15 | "- fetch an HTML page from web\n", 16 | "- parse the HTML file with BeautifulSoup library" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": {}, 23 | "outputs": [ 24 | { 25 | "data": { 26 | "text/plain": [ 27 | "('teaching.html', )" 28 | ] 29 | }, 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "output_type": "execute_result" 33 | } 34 | ], 35 | "source": [ 36 | "# fetch an html page\n", 37 | "import urllib.request\n", 38 | "url = 'https://rambasnet.github.io/teaching.html'\n", 39 | "localfile = 'teaching.html'\n", 40 | "urllib.request.urlretrieve(url, localfile)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 2, 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "name": "stdout", 50 | "output_type": "stream", 51 | "text": [ 52 | "There are 528 words in the file.\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "with open(localfile) as f:\n", 58 | " data = f.read()\n", 59 | "words = data.split(' ')\n", 60 | "print('There are {0} words in the file.'.format(len(words)))" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "## parsing HTML using BeautifulSoup library\n", 68 | "- install Beautifulsoup library\n", 69 | "```bash\n", 70 | " $ pip install bs4\n", 71 | "```\n", 72 | "- https://www.crummy.com/software/BeautifulSoup/bs4/doc/#\n", 73 | "- Alternative is nltk (Natural Language Toolkit) library\n", 74 | "- http://www.nltk.org/\n", 75 | "\n", 76 | "## Installing Parsers\n", 77 | "- supports the HTML parser included in Python’s standard library\n", 78 | "- also supports a number of third-party Python parsers such as very fast `lxml` parser" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "execution_count": 3, 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "name": "stdout", 88 | "output_type": "stream", 89 | "text": [ 90 | "Requirement already satisfied: bs4 in /Users/rbasnet/miniconda3/lib/python3.8/site-packages (0.0.1)\r\n", 91 | "Requirement already satisfied: beautifulsoup4 in /Users/rbasnet/miniconda3/lib/python3.8/site-packages (from bs4) (4.9.3)\r\n", 92 | "Requirement already satisfied: soupsieve>1.2 in /Users/rbasnet/miniconda3/lib/python3.8/site-packages (from beautifulsoup4->bs4) (2.0.1)\r\n" 93 | ] 94 | } 95 | ], 96 | "source": [ 97 | "# can run terminal/bash commands from notebook using !\n", 98 | "! pip install bs4" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 4, 104 | "metadata": {}, 105 | "outputs": [ 106 | { 107 | "name": "stdout", 108 | "output_type": "stream", 109 | "text": [ 110 | "Requirement already satisfied: lxml in /Users/rbasnet/miniconda3/lib/python3.8/site-packages (4.6.1)\r\n" 111 | ] 112 | } 113 | ], 114 | "source": [ 115 | "# install lxml parser\n", 116 | "! pip install lxml" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 5, 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "name": "stdout", 126 | "output_type": "stream", 127 | "text": [ 128 | "Dr. Ram BasnetAssociate Professor of Computer ScienceHomeTeachingResearchResourcesContactTeachingTeaching InterestsCybersecurityPython, C++, JavaScript, DatabasesData Science and ML ApplicationsWeb Design and Secure Web App DevelopmentCourses Taught at CMUCSCI 106- Web Design I  6CSCI 100- Beg. Python  8CSCI 111- CS1  10CSCI 112- CS2  7CSCI 206- Web2  2CSCI 250- CS3  3CSCI 310- Adv. Python  9CSCI 310- Adv. JavaScript  2CSCI 370- Computer Security  5CSCI 420- Cybersecurity  7CSCI 465- Net/App Security  7CSCI 396- Machine Learning  1FALL 2021 SCHEDULETimeMonTuesWedThrsFri9:00Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:509:3010:00     10:30     11:00Net/App SecCH 31511-11:50 Net/App SecCH 31511-11:50 Net/App SecCH 31511-11:5011:30  12:00     12:30     1:00CS1WS 1201-1:50CS1WS 1201-1:50CS1WS 1201-1:50CS1WS 1201-1:50CS1WS 1201-1:501:302:00     2:30     3:00 PythonCH 2763-3:50 PythonCH 2763-3:50 3:30   4:00     | Home | Teaching | Research | Resources | Contact |    © 2021\n" 129 | ] 130 | } 131 | ], 132 | "source": [ 133 | "from bs4 import BeautifulSoup\n", 134 | "localfile = 'teaching.html'\n", 135 | "with open(localfile) as f:\n", 136 | " #soup = BeautifulSoup(f, 'lxml') # used to but now not working!\n", 137 | " soup = BeautifulSoup(f, 'html.parser')\n", 138 | "text = soup.get_text()\n", 139 | "print(text)" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": 6, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [ 148 | "# break into lines and remove leading and trailing space on each line\n", 149 | "lines = [line.strip() for line in text.splitlines()]" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": 7, 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "name": "stdout", 159 | "output_type": "stream", 160 | "text": [ 161 | "['Dr. Ram BasnetAssociate Professor of Computer ScienceHomeTeachingResearchResourcesContactTeachingTeaching InterestsCybersecurityPython, C++, JavaScript, DatabasesData Science and ML ApplicationsWeb Design and Secure Web App DevelopmentCourses Taught at CMUCSCI 106- Web Design I \\xa06CSCI 100- Beg. Python \\xa08CSCI 111- CS1 \\xa010CSCI 112- CS2 \\xa07CSCI 206- Web2 \\xa02CSCI 250- CS3 \\xa03CSCI 310- Adv. Python \\xa09CSCI 310- Adv. JavaScript \\xa02CSCI 370- Computer Security \\xa05CSCI 420- Cybersecurity \\xa07CSCI 465- Net/App Security \\xa07CSCI 396- Machine Learning \\xa01FALL 2021 SCHEDULETimeMonTuesWedThrsFri9:00Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:50Off. Hr.CH 3299-9:509:3010:00\\xa0\\xa0\\xa0\\xa0\\xa010:30\\xa0\\xa0\\xa0\\xa0\\xa011:00Net/App SecCH 31511-11:50\\xa0Net/App SecCH 31511-11:50\\xa0Net/App SecCH 31511-11:5011:30\\xa0\\xa012:00\\xa0\\xa0\\xa0\\xa0\\xa012:30\\xa0\\xa0\\xa0\\xa0\\xa01:00CS1WS 1201-1:50CS1WS 1201-1:50CS1WS 1201-1:50CS1WS 1201-1:50CS1WS 1201-1:501:302:00\\xa0\\xa0\\xa0\\xa0\\xa02:30\\xa0\\xa0\\xa0\\xa0\\xa03:00\\xa0PythonCH 2763-3:50\\xa0PythonCH 2763-3:50\\xa03:30\\xa0\\xa0\\xa04:00\\xa0\\xa0\\xa0\\xa0\\xa0|\\xa0Home\\xa0|\\xa0Teaching\\xa0|\\xa0Research\\xa0|\\xa0Resources\\xa0|\\xa0Contact\\xa0| \\xa0\\xa0 © 2021']\n" 162 | ] 163 | } 164 | ], 165 | "source": [ 166 | "print(lines[:20])" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 8, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "# create list of words by spliting multi-word elements\n", 176 | "words = [word.strip().lower() for line in lines for word in line.split()]" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 9, 182 | "metadata": {}, 183 | "outputs": [ 184 | { 185 | "name": "stdout", 186 | "output_type": "stream", 187 | "text": [ 188 | "['dr.', 'ram', 'basnetassociate', 'professor', 'of', 'computer', 'sciencehometeachingresearchresourcescontactteachingteaching', 'interestscybersecuritypython,', 'c++,', 'javascript,', 'databasesdata', 'science', 'and', 'ml', 'applicationsweb', 'design', 'and', 'secure', 'web', 'app']\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "print(words[:20])" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": 10, 199 | "metadata": {}, 200 | "outputs": [ 201 | { 202 | "name": "stdout", 203 | "output_type": "stream", 204 | "text": [ 205 | "There are 119 words in the file.\n" 206 | ] 207 | } 208 | ], 209 | "source": [ 210 | "print('There are {0} words in the file.'.format(len(words)))" 211 | ] 212 | }, 213 | { 214 | "cell_type": "markdown", 215 | "metadata": {}, 216 | "source": [ 217 | "## Find histogram of words\n", 218 | "- use DefaultDict found in collections module\n", 219 | "- https://docs.python.org/3/library/collections.html" 220 | ] 221 | }, 222 | { 223 | "cell_type": "code", 224 | "execution_count": 11, 225 | "metadata": {}, 226 | "outputs": [], 227 | "source": [ 228 | "from collections import defaultdict" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": 12, 234 | "metadata": {}, 235 | "outputs": [], 236 | "source": [ 237 | "hist = defaultdict(int)\n", 238 | "for w in words:\n", 239 | " hist[w] += 1" 240 | ] 241 | }, 242 | { 243 | "cell_type": "code", 244 | "execution_count": 13, 245 | "metadata": {}, 246 | "outputs": [], 247 | "source": [ 248 | "# convert dict into a list of tuples\n", 249 | "listHist = [(k, v) for k, v in hist.items()]" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 14, 255 | "metadata": {}, 256 | "outputs": [ 257 | { 258 | "name": "stdout", 259 | "output_type": "stream", 260 | "text": [ 261 | "[('dr.', 1), ('ram', 1), ('basnetassociate', 1), ('professor', 1), ('of', 1), ('computer', 2), ('sciencehometeachingresearchresourcescontactteachingteaching', 1), ('interestscybersecuritypython,', 1), ('c++,', 1), ('javascript,', 1)]\n" 262 | ] 263 | } 264 | ], 265 | "source": [ 266 | "# print first 10 words and their frequency\n", 267 | "print(listHist[:10])" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": 15, 273 | "metadata": {}, 274 | "outputs": [], 275 | "source": [ 276 | "# sort list based on frequency in reverse order\n", 277 | "listHist.sort(key = lambda x: x[1], reverse=True)" 278 | ] 279 | }, 280 | { 281 | "cell_type": "code", 282 | "execution_count": 16, 283 | "metadata": {}, 284 | "outputs": [ 285 | { 286 | "name": "stdout", 287 | "output_type": "stream", 288 | "text": [ 289 | "[('|', 6), ('hr.ch', 5), ('3299-9:50off.', 4), ('1201-1:50cs1ws', 4), ('7csci', 3), ('net/app', 3), ('secch', 3), ('computer', 2), ('and', 2), ('design', 2)]\n" 290 | ] 291 | } 292 | ], 293 | "source": [ 294 | "# print the top 10 most frequent words\n", 295 | "print(listHist[:10])" 296 | ] 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "metadata": {}, 301 | "source": [ 302 | "### Use Counter collection\n", 303 | "- easier way!" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": 17, 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [ 312 | "from collections import Counter" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 18, 318 | "metadata": {}, 319 | "outputs": [], 320 | "source": [ 321 | "hist = Counter(words)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 19, 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "data": { 331 | "text/plain": [ 332 | "[('|', 6),\n", 333 | " ('hr.ch', 5),\n", 334 | " ('3299-9:50off.', 4),\n", 335 | " ('1201-1:50cs1ws', 4),\n", 336 | " ('7csci', 3),\n", 337 | " ('net/app', 3),\n", 338 | " ('secch', 3),\n", 339 | " ('computer', 2),\n", 340 | " ('and', 2),\n", 341 | " ('design', 2)]" 342 | ] 343 | }, 344 | "execution_count": 19, 345 | "metadata": {}, 346 | "output_type": "execute_result" 347 | } 348 | ], 349 | "source": [ 350 | "hist.most_common(10)" 351 | ] 352 | }, 353 | { 354 | "cell_type": "markdown", 355 | "metadata": {}, 356 | "source": [ 357 | "## working with binary files\n", 358 | "- the following example copies a binary file such as image" 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "execution_count": 20, 364 | "metadata": {}, 365 | "outputs": [], 366 | "source": [ 367 | "fileSrc = './resources/brain.jpg'\n", 368 | "fileDst = 'brain-copy.jpg'\n", 369 | "with open(fileSrc, 'rb') as rbf: \n", 370 | " #rb - read binary mode\n", 371 | " data = rbf.read() # read the whole binary file\n", 372 | " with open(fileDst, 'wb') as wbf:\n", 373 | " wbf.write(data) # write the whole binary file" 374 | ] 375 | }, 376 | { 377 | "cell_type": "markdown", 378 | "metadata": {}, 379 | "source": [ 380 | "## use checksum to compare if two files match exactly!\n", 381 | "- checksum makes sure that not a single bit is different between the two files\n", 382 | "- used in security\n", 383 | "- import and use hashlib - https://docs.python.org/3/library/hashlib.html" 384 | ] 385 | }, 386 | { 387 | "cell_type": "code", 388 | "execution_count": 21, 389 | "metadata": {}, 390 | "outputs": [ 391 | { 392 | "name": "stdout", 393 | "output_type": "stream", 394 | "text": [ 395 | "two files' checksums match!\n" 396 | ] 397 | } 398 | ], 399 | "source": [ 400 | "import hashlib\n", 401 | "file1Contents = open(fileSrc, 'rb').read()\n", 402 | "file2Contents = open(fileDst, 'rb').read()\n", 403 | "\n", 404 | "file1ChkSum = hashlib.sha256(file1Contents).hexdigest()\n", 405 | "file2ChkSum = hashlib.sha256(file2Contents).hexdigest()\n", 406 | "if (file1ChkSum == file2ChkSum):\n", 407 | " print('two files\\' checksums match!')\n", 408 | "else:\n", 409 | " print('oops! two files\\' checksums do NOT match!')" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "metadata": {}, 415 | "source": [ 416 | "## Python object serialization with pickle library\n", 417 | "- https://docs.python.org/3/library/pickle.html\n", 418 | "- pickle module implements binary protocols for serializing and de-serializing a Python object\n", 419 | "- Pickling - serializing python object\n", 420 | "- Unpickling - deserializing python object (inverse operation)\n", 421 | "- Unpickling untrusted picked files could have security implications\n", 422 | " - e.g., executing system commands; installing and executing third-party malicious packages and modules; etc.\n", 423 | " - for more: https://owasp.org/www-project-top-ten/2017/A8_2017-Insecure_Deserialization\n", 424 | " " 425 | ] 426 | }, 427 | { 428 | "cell_type": "code", 429 | "execution_count": 22, 430 | "metadata": {}, 431 | "outputs": [], 432 | "source": [ 433 | "import pickle\n", 434 | "alist = list(range(2, 21, 2))" 435 | ] 436 | }, 437 | { 438 | "cell_type": "code", 439 | "execution_count": 23, 440 | "metadata": {}, 441 | "outputs": [ 442 | { 443 | "name": "stdout", 444 | "output_type": "stream", 445 | "text": [ 446 | "[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]\n" 447 | ] 448 | } 449 | ], 450 | "source": [ 451 | "print(alist)" 452 | ] 453 | }, 454 | { 455 | "cell_type": "code", 456 | "execution_count": 24, 457 | "metadata": {}, 458 | "outputs": [], 459 | "source": [ 460 | "# let's pickle alist; serialize a list\n", 461 | "pickleFile = 'myPickle.pkl'\n", 462 | "with open(pickleFile, 'wb') as p:\n", 463 | " pickle.dump(alist, p)" 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "execution_count": 25, 469 | "metadata": {}, 470 | "outputs": [], 471 | "source": [ 472 | "# lets unpickle alist; deserialize a list\n", 473 | "with open(pickleFile, 'rb') as p:\n", 474 | " blist = pickle.load(p)" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "execution_count": 26, 480 | "metadata": {}, 481 | "outputs": [ 482 | { 483 | "data": { 484 | "text/plain": [ 485 | "True" 486 | ] 487 | }, 488 | "execution_count": 26, 489 | "metadata": {}, 490 | "output_type": "execute_result" 491 | } 492 | ], 493 | "source": [ 494 | "alist == blist" 495 | ] 496 | }, 497 | { 498 | "cell_type": "code", 499 | "execution_count": 27, 500 | "metadata": {}, 501 | "outputs": [], 502 | "source": [ 503 | "# dump Counter\n", 504 | "with open('wordCounter.pkl', 'wb') as p:\n", 505 | " pickle.dump(hist, p)\n", 506 | " " 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "execution_count": 28, 512 | "metadata": {}, 513 | "outputs": [], 514 | "source": [ 515 | "# load pickle\n", 516 | "with open('wordCounter.pkl', 'rb') as p:\n", 517 | " newHist = pickle.load(p)" 518 | ] 519 | }, 520 | { 521 | "cell_type": "code", 522 | "execution_count": 29, 523 | "metadata": {}, 524 | "outputs": [ 525 | { 526 | "data": { 527 | "text/plain": [ 528 | "True" 529 | ] 530 | }, 531 | "execution_count": 29, 532 | "metadata": {}, 533 | "output_type": "execute_result" 534 | } 535 | ], 536 | "source": [ 537 | "hist == newHist" 538 | ] 539 | }, 540 | { 541 | "cell_type": "code", 542 | "execution_count": 30, 543 | "metadata": {}, 544 | "outputs": [ 545 | { 546 | "data": { 547 | "text/plain": [ 548 | "[('|', 6), ('hr.ch', 5), ('3299-9:50off.', 4)]" 549 | ] 550 | }, 551 | "execution_count": 30, 552 | "metadata": {}, 553 | "output_type": "execute_result" 554 | } 555 | ], 556 | "source": [ 557 | "newHist.most_common(3)" 558 | ] 559 | }, 560 | { 561 | "cell_type": "code", 562 | "execution_count": null, 563 | "metadata": {}, 564 | "outputs": [], 565 | "source": [] 566 | } 567 | ], 568 | "metadata": { 569 | "kernelspec": { 570 | "display_name": "Python 3", 571 | "language": "python", 572 | "name": "python3" 573 | }, 574 | "language_info": { 575 | "codemirror_mode": { 576 | "name": "ipython", 577 | "version": 3 578 | }, 579 | "file_extension": ".py", 580 | "mimetype": "text/x-python", 581 | "name": "python", 582 | "nbconvert_exporter": "python", 583 | "pygments_lexer": "ipython3", 584 | "version": "3.8.11" 585 | } 586 | }, 587 | "nbformat": 4, 588 | "nbformat_minor": 2 589 | } 590 | -------------------------------------------------------------------------------- /notebooks/Ch10-2-RichLibrary.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Python Rich Library\n", 8 | "\n", 9 | "This notebook is a quick overview of the Python Rich library. Rich is a Python library for rich text and beautiful formatting in the terminal. It is a great tool for creating beautiful and interactive text-based interfaces.\n", 10 | "\n", 11 | "- [Rich Documentation](https://rich.readthedocs.io/en/latest/)\n", 12 | "- [GitHub Source and Demos](https://github.com/Textualize/rich)\n", 13 | "\n", 14 | "## Installation\n", 15 | "\n", 16 | "You can install the Rich library using pip:\n", 17 | "\n", 18 | "```bash\n", 19 | "pip install rich\n", 20 | "```\n" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "! pip install rich" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 1, 35 | "metadata": {}, 36 | "outputs": [], 37 | "source": [ 38 | "from rich import print" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 5, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "data": { 48 | "text/html": [ 49 | "
🔥 Hello, World! 🧛\n",
 50 |        "
\n" 51 | ], 52 | "text/plain": [ 53 | "🔥 Hello, \u001b[1;35mWorld\u001b[0m! 🧛\n" 54 | ] 55 | }, 56 | "metadata": {}, 57 | "output_type": "display_data" 58 | } 59 | ], 60 | "source": [ 61 | "print(\":fire: Hello, [bold magenta]World[/bold magenta]!\", \":vampire:\")" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "## Go through the following Examples on a Terminal\n", 69 | "\n", 70 | "- run the following examples from command line\n", 71 | "\n", 72 | "```bash\n", 73 | "$ python -m rich\n", 74 | "$ python -m rich.table\n", 75 | "$ python -m rich.progress\n", 76 | "$ python -m rich.status\n", 77 | "$ python -m rich.columns\n", 78 | "$ python -m rich.tree\n", 79 | "$ python -m rich.panel\n", 80 | "$ python -m rich.box\n", 81 | "```\n", 82 | "\n", 83 | "- look at examples from GitHub source\n", 84 | "\n", 85 | "- Console API\n", 86 | "- Styles\n", 87 | "- Prompt\n", 88 | "- Progress\n", 89 | "- Table\n" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [] 98 | } 99 | ], 100 | "metadata": { 101 | "kernelspec": { 102 | "display_name": "Python 3", 103 | "language": "python", 104 | "name": "python3" 105 | }, 106 | "language_info": { 107 | "codemirror_mode": { 108 | "name": "ipython", 109 | "version": 3 110 | }, 111 | "file_extension": ".py", 112 | "mimetype": "text/x-python", 113 | "name": "python", 114 | "nbconvert_exporter": "python", 115 | "pygments_lexer": "ipython3", 116 | "version": "3.11.5" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 2 121 | } 122 | -------------------------------------------------------------------------------- /notebooks/Ch13-Recursion.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Recursion\n", 8 | "\"Open\n", 9 | "\n", 10 | "\n", 11 | "\n", 12 | "- defining something in terms of itself usually at some smaller scale, perhaps multiple times, to achieve your objective\n", 13 | " - e.g., a human being is someone whose mother is a human being\n", 14 | " - directory is a structure that holds files and (smaller) directories, etc.\n", 15 | " - fractals is a drawing which also has self-similar structure, where it can be defined in terms of itself\n", 16 | "- in programming, functions can generally call themselves to solve similar but smaller subproblems\n", 17 | " - this technique is called recursion\n", 18 | "\n", 19 | "\n", 20 | "## Definitions\n", 21 | "\n", 22 | "- **Recursion:** The process of solving a problem by reducing it to smaller versions of itself\n", 23 | "- **Recursive definition:** a definition in which something is defined in terms of smaller version of itself\n", 24 | "- **Recursive algorithm:** an algorithm that finds a solution to a given problem by reducing the problem to smaller versions of itself\n", 25 | "- **Infinite recursion:** recursive call that never stops\n", 26 | "\n", 27 | "### general construct of recursive algorithms\n", 28 | "\n", 29 | "- recursive algorithms/solutions have base case(s) and general case(s):\n", 30 | "1. must have one or more base case(s) \n", 31 | " - provides direct answer tha\n", 32 | " t makes the recursion stop\n", 33 | " - answer to the smallest subproblem\n", 34 | "2. must have one or more general case(s)\n", 35 | " - functions recursively reduce themselves to one of the base case(s)" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | " \n", 43 | "### Python Recursion Depth Limit\n", 44 | "- by default Python limits recursion depth to something < 3000\n", 45 | "- you can set it up higher if needed" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": 1, 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "import sys" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 2, 60 | "metadata": { 61 | "scrolled": true 62 | }, 63 | "outputs": [ 64 | { 65 | "data": { 66 | "text/plain": [ 67 | "3000" 68 | ] 69 | }, 70 | "execution_count": 2, 71 | "metadata": {}, 72 | "output_type": "execute_result" 73 | } 74 | ], 75 | "source": [ 76 | "sys.getrecursionlimit()" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "sys.setrecursionlimit(1_000_000)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": 4, 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "1000000" 97 | ] 98 | }, 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "sys.getrecursionlimit()" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "### recursive countdown example" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 5, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "# Recursively print countdown from 10-1 and blast off!\n", 122 | "# Run it as a script\n", 123 | "import time\n", 124 | "def countDown(n):\n", 125 | " if n == 0:\n", 126 | " print('Blast Off!')\n", 127 | " time.sleep(1)\n", 128 | " else:\n", 129 | " print(n)\n", 130 | " time.sleep(1)\n", 131 | " countDown(n-1)\n", 132 | " #print(n)\n", 133 | " " 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 6, 139 | "metadata": {}, 140 | "outputs": [ 141 | { 142 | "name": "stdout", 143 | "output_type": "stream", 144 | "text": [ 145 | "10\n", 146 | "9\n", 147 | "8\n", 148 | "7\n", 149 | "6\n", 150 | "5\n", 151 | "4\n", 152 | "3\n", 153 | "2\n", 154 | "1\n", 155 | "Blast Off!\n" 156 | ] 157 | } 158 | ], 159 | "source": [ 160 | "countDown(10)" 161 | ] 162 | }, 163 | { 164 | "cell_type": "markdown", 165 | "metadata": {}, 166 | "source": [ 167 | "### Sum of First N positive integers\n", 168 | "\n", 169 | "- use recursion to find the sum of first N positive integers\n", 170 | "\n", 171 | "```\n", 172 | " first_sum(1) = 1 (base case)\n", 173 | " first_sum(n) = n + first_sum(n-1) for n > 1 (general case)\n", 174 | "```" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 1, 180 | "metadata": {}, 181 | "outputs": [], 182 | "source": [ 183 | "def first_sum(n):\n", 184 | " if n == 1:\n", 185 | " return 1\n", 186 | " else:\n", 187 | " return n + first_sum(n-1)" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 2, 193 | "metadata": {}, 194 | "outputs": [ 195 | { 196 | "data": { 197 | "text/plain": [ 198 | "5050" 199 | ] 200 | }, 201 | "execution_count": 2, 202 | "metadata": {}, 203 | "output_type": "execute_result" 204 | } 205 | ], 206 | "source": [ 207 | "first_sum(100)" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": 3, 213 | "metadata": {}, 214 | "outputs": [], 215 | "source": [ 216 | "# use tail recursion optimization\n", 217 | "# Python doesn't optimize tail recursion \n", 218 | "# read the blog by Guido van Rossum - http://neopythonic.blogspot.com/2009/04/tail-recursion-elimination.html\n", 219 | "def sum_tail(n, running_tot=1):\n", 220 | " if n == 1:\n", 221 | " return running_tot\n", 222 | " else:\n", 223 | " return sum_tail(n-1, running_tot+n)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 6, 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "data": { 233 | "text/plain": [ 234 | "5050" 235 | ] 236 | }, 237 | "execution_count": 6, 238 | "metadata": {}, 239 | "output_type": "execute_result" 240 | } 241 | ], 242 | "source": [ 243 | "sum_tail(100, 1)" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "## Fibonacci numbers\n", 251 | "- Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...\n", 252 | "- devised by Fibonacci (1170-1250), who used the sequence to model the breeding of (pairs) of rabbits\n", 253 | "- say in generation 7 you had 21 pairs in total, of which 13 were adults, then in next generation the adults will have bred new children, and the previous children will have grown up to become adults. So, in generation 8, you'll have 13+21=34 rabbits, of which 21 are adults." 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "### Fibonacci number definition\n", 261 | "```\n", 262 | "fib(0) = 0 (base case 1)\n", 263 | "fib(1) = 1 (base case 2)\n", 264 | "fib(n) = fib(n-1) + fib(n-2) for n >= 2 (general case)\n", 265 | "```" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 8, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "# Finding Fibonacci number in series\n", 275 | "count = 0\n", 276 | "def fib(n):\n", 277 | " global count\n", 278 | " count += 1\n", 279 | " if n <= 1:\n", 280 | " return n\n", 281 | " f = fib(n-1) + fib(n-2)\n", 282 | " return f" 283 | ] 284 | }, 285 | { 286 | "cell_type": "code", 287 | "execution_count": 9, 288 | "metadata": {}, 289 | "outputs": [ 290 | { 291 | "name": "stdout", 292 | "output_type": "stream", 293 | "text": [ 294 | "fib was called 7049155 times.\n" 295 | ] 296 | } 297 | ], 298 | "source": [ 299 | "fib(32)\n", 300 | "print(f'fib was called {count} times.')\n", 301 | "assert fib(8) == 21\n", 302 | "assert fib(10) == 55" 303 | ] 304 | }, 305 | { 306 | "cell_type": "markdown", 307 | "metadata": {}, 308 | "source": [ 309 | "\n", 310 | "\n", 311 | "### visualize fib(4) using pythontutor.com\n", 312 | "- https://goo.gl/YNizhH\n", 313 | "\n", 314 | "### You can timeit\n", 315 | "\n", 316 | "- use timeit function to see how long fib(n) takes" 317 | ] 318 | }, 319 | { 320 | "cell_type": "code", 321 | "execution_count": 10, 322 | "metadata": {}, 323 | "outputs": [], 324 | "source": [ 325 | "from timeit import timeit" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": 11, 331 | "metadata": {}, 332 | "outputs": [ 333 | { 334 | "data": { 335 | "text/plain": [ 336 | "1.1521884420071729" 337 | ] 338 | }, 339 | "execution_count": 11, 340 | "metadata": {}, 341 | "output_type": "execute_result" 342 | } 343 | ], 344 | "source": [ 345 | "timeit(\"fib(32)\", globals=globals(), number=1)" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "### how many times is fib() called for fib(4)?\n", 353 | "- Modify fib to count the number of times fib gets called.\n", 354 | "- Time complexity of recursive fib function is $O(2^n)$ or precisely $O(1.6180^n)$ \n", 355 | " - 1.6180 is also called golden ratio" 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": 12, 361 | "metadata": {}, 362 | "outputs": [], 363 | "source": [ 364 | "def fib_tail(n, a, b):\n", 365 | " if n == 0:\n", 366 | " return a\n", 367 | " if n == 1:\n", 368 | " return b\n", 369 | " return fib_tail(n-1, b, a+b)" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 13, 375 | "metadata": {}, 376 | "outputs": [ 377 | { 378 | "name": "stdout", 379 | "output_type": "stream", 380 | "text": [ 381 | "2178309\n" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "print(fib_tail(32, 0, 1))" 387 | ] 388 | }, 389 | { 390 | "cell_type": "code", 391 | "execution_count": 14, 392 | "metadata": {}, 393 | "outputs": [ 394 | { 395 | "data": { 396 | "text/plain": [ 397 | "1.3885000953450799e-05" 398 | ] 399 | }, 400 | "execution_count": 14, 401 | "metadata": {}, 402 | "output_type": "execute_result" 403 | } 404 | ], 405 | "source": [ 406 | "timeit(\"fib_tail(32, 0, 1)\", globals=globals(), number=1)" 407 | ] 408 | }, 409 | { 410 | "cell_type": "markdown", 411 | "metadata": {}, 412 | "source": [ 413 | "### Factorial definition\n", 414 | "\n", 415 | "```\n", 416 | " 1! = 1 (base case)\n", 417 | " n! = n * (n-1)! for n > 1 (general case)\n", 418 | "```\n", 419 | "\n", 420 | "- Exercise - Implement factorial recursive solution; see homework assignment!" 421 | ] 422 | }, 423 | { 424 | "cell_type": "markdown", 425 | "metadata": {}, 426 | "source": [ 427 | "## Drawing Fractals\n", 428 | "- for our purposes, a fractal is a drawing which also has self-similar structure, where it can be defined in terms of itself.\n", 429 | "- see Koch fractal example in text book section 18.1" 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "metadata": {}, 435 | "source": [ 436 | "### an animated fractal, using PyGame library\n", 437 | "- install PyGame library using the following bash script!\n", 438 | "- if PyGame is already installed and is the current version, there's no harm!\n", 439 | "- we use pip to install Python packages; so update pip just in case" 440 | ] 441 | }, 442 | { 443 | "cell_type": "code", 444 | "execution_count": null, 445 | "metadata": {}, 446 | "outputs": [], 447 | "source": [ 448 | "%%bash\n", 449 | "pip install --upgrade pip\n", 450 | "pip install pygame" 451 | ] 452 | }, 453 | { 454 | "cell_type": "code", 455 | "execution_count": null, 456 | "metadata": {}, 457 | "outputs": [], 458 | "source": [ 459 | "# animated fractal; when done just close the window or force kill if not responding!\n", 460 | "# this program doesn't run in colab or online services. You must run locally from notebook or as a script!\n", 461 | "\n", 462 | "import pygame, math\n", 463 | "pygame.init() # prepare the pygame module for use\n", 464 | "\n", 465 | "# Create a new surface and window.\n", 466 | "surface_size = 1024\n", 467 | "main_surface = pygame.display.set_mode((surface_size,surface_size))\n", 468 | "my_clock = pygame.time.Clock()\n", 469 | "\n", 470 | "\n", 471 | "def draw_tree(order, theta, sz, posn, heading, color=(0,0,0), depth=0):\n", 472 | "\n", 473 | " trunk_ratio = 0.29 # How big is the trunk relative to whole tree?\n", 474 | " trunk = sz * trunk_ratio # length of trunk\n", 475 | " delta_x = trunk * math.cos(heading)\n", 476 | " delta_y = trunk * math.sin(heading)\n", 477 | " (u, v) = posn\n", 478 | " newpos = (u + delta_x, v + delta_y)\n", 479 | " pygame.draw.line(main_surface, color, posn, newpos)\n", 480 | "\n", 481 | " if order > 0: # Draw another layer of subtrees\n", 482 | "\n", 483 | " # These next six lines are a simple hack to make the two major halves\n", 484 | " # of the recursion different colors. Fiddle here to change colors\n", 485 | " # at other depths, or when depth is even, or odd, etc.\n", 486 | " if depth == 0:\n", 487 | " color1 = (255, 0, 0)\n", 488 | " color2 = (0, 0, 255)\n", 489 | " else:\n", 490 | " color1 = color\n", 491 | " color2 = color\n", 492 | "\n", 493 | " # make the recursive calls to draw the two subtrees\n", 494 | " newsz = sz*(1 - trunk_ratio)\n", 495 | " draw_tree(order-1, theta, newsz, newpos, heading-theta, color1, depth+1)\n", 496 | " draw_tree(order-1, theta, newsz, newpos, heading+theta, color2, depth+1)\n", 497 | "\n", 498 | "\n", 499 | "def gameloop():\n", 500 | "\n", 501 | " theta = 0\n", 502 | " while True:\n", 503 | "\n", 504 | " # Handle evente from keyboard, mouse, etc.\n", 505 | " ev = pygame.event.poll()\n", 506 | " if ev.type == pygame.QUIT:\n", 507 | " break;\n", 508 | "\n", 509 | " # Updates - change the angle\n", 510 | " theta += 0.01\n", 511 | "\n", 512 | " # Draw everything\n", 513 | " main_surface.fill((255, 255, 0))\n", 514 | " draw_tree(9, theta, surface_size*0.9, (surface_size//2, surface_size-50), -math.pi/2)\n", 515 | "\n", 516 | " pygame.display.flip()\n", 517 | " my_clock.tick(120)\n", 518 | "\n", 519 | "\n", 520 | "gameloop()\n", 521 | "pygame.quit()" 522 | ] 523 | }, 524 | { 525 | "cell_type": "markdown", 526 | "metadata": {}, 527 | "source": [ 528 | "### exercise 1\n", 529 | "Write a recursive fact(n) function that takes a positive integer n and returns its factorial.\n", 530 | "
\n",
531 |     "Here are some test cases that the fact(n) should pass:\n",
532 |     "assert fact(5) == 120\n",
533 |     "assert fact(10) == 3628800\n",
534 |     "assert fact(100) == math.factorial(100)\n",
535 |     "
" 536 | ] 537 | }, 538 | { 539 | "cell_type": "markdown", 540 | "metadata": {}, 541 | "source": [ 542 | "### exercise 2\n", 543 | "Write a recursive function -- gcd(a, b) -- that finds the greatest common divisor of two given positive integers, a and b.\n", 544 | "- see algorithm [in Khan Academy](https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-euclidean-algorithm)\n", 545 | "
\n",
546 |     "Here are some test cases that gcd(a, b) should pass:\n",
547 |     "assert gcd(2, 100) == 2\n",
548 |     "assert gcd(50, 10) == 10\n",
549 |     "assert gcd(125, 75) == 25\n",
550 |     "
" 551 | ] 552 | }, 553 | { 554 | "cell_type": "markdown", 555 | "metadata": {}, 556 | "source": [ 557 | "### exercise 3\n", 558 | "Write a program that simulates the steps required to solve the \"Tower of Hanoii\" puzzle for some disks n.\n", 559 | "- https://www.mathsisfun.com/games/towerofhanoi.html\n", 560 | "\n", 561 | "- Recursive algorithm \n", 562 | "- If there are 1 or more disks to move:\n", 563 | " 1. Move the top n-1 disks from needle 1 (source) to needle 2 (helper), using needle 3 (dest) as the intermediate needle\n", 564 | " 2. Move disk number n from needle 1 (src) to needle 3 (dest)\n", 565 | " 3. Move the top n - 1 disks from needle 2 (helper) to needle 3 (dest), using needle 1 (src) as the intermediate needle" 566 | ] 567 | }, 568 | { 569 | "cell_type": "code", 570 | "execution_count": null, 571 | "metadata": {}, 572 | "outputs": [], 573 | "source": [ 574 | "def moveDisks(n, src, helper, dst):\n", 575 | " if n > 0:\n", 576 | " moveDisks(n-1, src, dst, helper)\n", 577 | " print('Move disk #{} from {} to {}'.format(n, src, dst))\n", 578 | " moveDisks(n-1, helper, src, dst)" 579 | ] 580 | }, 581 | { 582 | "cell_type": "code", 583 | "execution_count": null, 584 | "metadata": { 585 | "scrolled": true 586 | }, 587 | "outputs": [], 588 | "source": [ 589 | "moveDisks(3, 'needle1', 'needle2', 'needle3')" 590 | ] 591 | }, 592 | { 593 | "cell_type": "markdown", 594 | "metadata": { 595 | "collapsed": true 596 | }, 597 | "source": [ 598 | "## Kattis problems\n", 599 | "\n", 600 | "- the following Kattis problems can be solved using recursion:\n", 601 | "\n", 602 | "1. Last Factorial Digit: https://open.kattis.com/problems/lastfactorialdigit\n", 603 | "2. Watch Out For Those Hailstones! - https://open.kattis.com/problems/hailstone\n", 604 | "3. Of of Sorts - https://open.kattis.com/problems/outofsorts\n", 605 | " - Hint: implement recursive binary search and apply to the generated unsorted sequence" 606 | ] 607 | }, 608 | { 609 | "cell_type": "code", 610 | "execution_count": null, 611 | "metadata": {}, 612 | "outputs": [], 613 | "source": [] 614 | } 615 | ], 616 | "metadata": { 617 | "kernelspec": { 618 | "display_name": "Python 3 (ipykernel)", 619 | "language": "python", 620 | "name": "python3" 621 | }, 622 | "language_info": { 623 | "codemirror_mode": { 624 | "name": "ipython", 625 | "version": 3 626 | }, 627 | "file_extension": ".py", 628 | "mimetype": "text/x-python", 629 | "name": "python", 630 | "nbconvert_exporter": "python", 631 | "pygments_lexer": "ipython3", 632 | "version": "3.10.8" 633 | } 634 | }, 635 | "nbformat": 4, 636 | "nbformat_minor": 2 637 | } 638 | -------------------------------------------------------------------------------- /notebooks/Ch16-Exceptions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Exceptions\n", 8 | "\"Open\n", 9 | "\n", 10 | "\n", 11 | "http://openbookproject.net/thinkcs/python/english3e/exceptions.html\n", 12 | "- dealing with bugs is normal part of programming\n", 13 | "- debugging is a very handy programming skill\n", 14 | "\n", 15 | "## category of bugs\n", 16 | "- syntax errors\n", 17 | "- logical/semantic errors\n", 18 | "- runtime errors/exceptions" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "## exceptions\n", 26 | "- when runtime error occurs, it creates and throws an exception object\n", 27 | "- program halts; Python prints out the traceback with exception name and message\n", 28 | "- https://docs.python.org/3/tutorial/errors.html" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 1, 34 | "metadata": {}, 35 | "outputs": [ 36 | { 37 | "ename": "ZeroDivisionError", 38 | "evalue": "division by zero", 39 | "output_type": "error", 40 | "traceback": [ 41 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 42 | "\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", 43 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m55\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 44 | "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" 45 | ] 46 | } 47 | ], 48 | "source": [ 49 | "print(55/0)" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 2, 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "ename": "IndexError", 59 | "evalue": "list index out of range", 60 | "output_type": "error", 61 | "traceback": [ 62 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 63 | "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", 64 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0malist\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0malist\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 65 | "\u001b[0;31mIndexError\u001b[0m: list index out of range" 66 | ] 67 | } 68 | ], 69 | "source": [ 70 | "alist = []\n", 71 | "print(alist[0])" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 3, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "ename": "TypeError", 81 | "evalue": "'tuple' object does not support item assignment", 82 | "output_type": "error", 83 | "traceback": [ 84 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 85 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 86 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0matup\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'a'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'b'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'c'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0matup\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'A'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 87 | "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" 88 | ] 89 | } 90 | ], 91 | "source": [ 92 | "atup = ('a', 'b', 'c')\n", 93 | "atup[0] = 'A'" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "- each exception has two parts- Name: description" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "## catching exceptions\n", 108 | "- use try and except blocks\n", 109 | "- try statement has several separate clauses/parts\n", 110 | "
\n",
111 |     "    try:\n",
112 |     "        # statement(s) thay may potentially throw(s) exception\n",
113 |     "    except ExceptionName1:\n",
114 |     "        # catch specific exception ExceptionName1\n",
115 |     "        # statement(s) to handle the exception\n",
116 |     "    [except ExceptionName2 as err:\n",
117 |     "        # statements\n",
118 |     "    ]\n",
119 |     "    [except:\n",
120 |     "        # catch any error not caught by previous except blocks\n",
121 |     "    ]\n",
122 |     "    [else:\n",
123 |     "        # follows all except clause\n",
124 |     "        # executes if try clause does NOT raise an exception\n",
125 |     "    ]\n",
126 |     "    [finally:\n",
127 |     "        # clean-up actions that must be executed under all circumstances; \n",
128 |     "        # exectued on the way out when try block is left via a break, continue, or return statement\n",
129 |     "    ]\n",
130 |     "
\n", 131 | "- [ ] optional " 132 | ] 133 | }, 134 | { 135 | "cell_type": "markdown", 136 | "metadata": {}, 137 | "source": [ 138 | "### example 1" 139 | ] 140 | }, 141 | { 142 | "cell_type": "code", 143 | "execution_count": 12, 144 | "metadata": {}, 145 | "outputs": [ 146 | { 147 | "name": "stdout", 148 | "output_type": "stream", 149 | "text": [ 150 | "Enter dividend: 10\n", 151 | "Enter divisor: 2\n", 152 | "quotient= 5.0\n", 153 | "remainder= 0\n", 154 | "executing finally clause\n" 155 | ] 156 | } 157 | ], 158 | "source": [ 159 | "try:\n", 160 | " x = int(input(\"Enter dividend: \"))\n", 161 | " y = int(input(\"Enter divisor: \"))\n", 162 | " quotient = x/y\n", 163 | " remainder = x%y\n", 164 | "except ZeroDivisionError as ex:\n", 165 | " print('Exception occured:', ex)\n", 166 | " print('arguments:', ex.args)\n", 167 | "except ValueError as ex:\n", 168 | " print(ex)\n", 169 | "except Exception as ex1:\n", 170 | " print('Some exception occured...', ex1)\n", 171 | "except:\n", 172 | " print('some exception flew by...')\n", 173 | "else:\n", 174 | " print(\"quotient=\", quotient)\n", 175 | " print(\"remainder=\", remainder)\n", 176 | "finally:\n", 177 | " print(\"executing finally clause\")" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 9, 183 | "metadata": {}, 184 | "outputs": [ 185 | { 186 | "name": "stdout", 187 | "output_type": "stream", 188 | "text": [ 189 | "enter a numberadsf\n" 190 | ] 191 | }, 192 | { 193 | "ename": "ValueError", 194 | "evalue": "invalid literal for int() with base 10: 'adsf'", 195 | "output_type": "error", 196 | "traceback": [ 197 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 198 | "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", 199 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'enter a number'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 200 | "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'adsf'" 201 | ] 202 | } 203 | ], 204 | "source": [ 205 | "int(input('enter a number'))" 206 | ] 207 | }, 208 | { 209 | "cell_type": "markdown", 210 | "metadata": {}, 211 | "source": [ 212 | "### example 2\n", 213 | "- input validation" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 13, 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "name": "stdout", 223 | "output_type": "stream", 224 | "text": [ 225 | "Please enter a number: adf\n", 226 | "Oops! That was not a valid number. Try again...\n", 227 | "Please enter a number: asdf\n", 228 | "Oops! That was not a valid number. Try again...\n", 229 | "Please enter a number: asdf\n", 230 | "Oops! That was not a valid number. Try again...\n", 231 | "Please enter a number: sdasf\n", 232 | "Oops! That was not a valid number. Try again...\n", 233 | "Please enter a number: 2434.3534\n", 234 | "Oops! That was not a valid number. Try again...\n", 235 | "Please enter a number: 3534\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | "while True:\n", 241 | " try:\n", 242 | " x = int(input(\"Please enter a integer: \"))\n", 243 | " break\n", 244 | " except ValueError:\n", 245 | " print(\"Oops! That was not a valid number. Try again...\")" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 14, 251 | "metadata": {}, 252 | "outputs": [ 253 | { 254 | "data": { 255 | "text/plain": [ 256 | "3534" 257 | ] 258 | }, 259 | "execution_count": 14, 260 | "metadata": {}, 261 | "output_type": "execute_result" 262 | } 263 | ], 264 | "source": [ 265 | "x" 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "metadata": {}, 271 | "source": [ 272 | "## raising exceptions\n", 273 | "- raise statement allows programer to throw their own exceptions\n", 274 | "- Python provides several built-in exceptions\n", 275 | " - e.g.: NameError, ModuleNotFoundError, MemoryError, etc.\n", 276 | " - for details: https://docs.python.org/3/library/exceptions.html" 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": {}, 282 | "source": [ 283 | "### example 1" 284 | ] 285 | }, 286 | { 287 | "cell_type": "code", 288 | "execution_count": 15, 289 | "metadata": {}, 290 | "outputs": [ 291 | { 292 | "ename": "NameError", 293 | "evalue": "MyException", 294 | "output_type": "error", 295 | "traceback": [ 296 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 297 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 298 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"MyException\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 299 | "\u001b[0;31mNameError\u001b[0m: MyException" 300 | ] 301 | } 302 | ], 303 | "source": [ 304 | "raise NameError(\"MyException\")" 305 | ] 306 | }, 307 | { 308 | "cell_type": "code", 309 | "execution_count": 16, 310 | "metadata": {}, 311 | "outputs": [ 312 | { 313 | "name": "stdout", 314 | "output_type": "stream", 315 | "text": [ 316 | "An exception flew by...\n" 317 | ] 318 | }, 319 | { 320 | "ename": "NameError", 321 | "evalue": "My Exception", 322 | "output_type": "error", 323 | "traceback": [ 324 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 325 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 326 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# except and raise execption\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'My Exception'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mNameError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'An exception flew by...'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 327 | "\u001b[0;31mNameError\u001b[0m: My Exception" 328 | ] 329 | } 330 | ], 331 | "source": [ 332 | "# except and raise execption\n", 333 | "try:\n", 334 | " raise NameError('My Exception')\n", 335 | "except NameError:\n", 336 | " print('An exception flew by...')\n", 337 | " raise" 338 | ] 339 | }, 340 | { 341 | "cell_type": "markdown", 342 | "metadata": {}, 343 | "source": [ 344 | "## user-defined exceptions\n", 345 | "- one can define their own exceptions and raise them as needed\n", 346 | "- should typically derive from the Exception class, either directly or indirectly\n", 347 | "\n", 348 | "### example 1" 349 | ] 350 | }, 351 | { 352 | "cell_type": "code", 353 | "execution_count": null, 354 | "metadata": {}, 355 | "outputs": [], 356 | "source": [ 357 | "class InputError(Exception):\n", 358 | " \"\"\"\n", 359 | " Exception raised for errors in the input.\n", 360 | " \n", 361 | " Attributes:\n", 362 | " expression -- input expression in which the error occured\n", 363 | " message -- explaination of the error\n", 364 | " \"\"\"\n", 365 | " def __init__(self, expression, message):\n", 366 | " self.expression = expression\n", 367 | " self.message = message\n", 368 | " " 369 | ] 370 | }, 371 | { 372 | "cell_type": "code", 373 | "execution_count": null, 374 | "metadata": {}, 375 | "outputs": [], 376 | "source": [ 377 | "help(InputError)" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": null, 383 | "metadata": {}, 384 | "outputs": [], 385 | "source": [ 386 | "def getInteger():\n", 387 | " x = input('Enter an integer number: ')\n", 388 | " if not x.isdigit():\n", 389 | " raise InputError(x, 'That is not an integer!')\n", 390 | " return int(x)" 391 | ] 392 | }, 393 | { 394 | "cell_type": "code", 395 | "execution_count": null, 396 | "metadata": {}, 397 | "outputs": [], 398 | "source": [ 399 | "x = getInteger()\n", 400 | "print(x)" 401 | ] 402 | }, 403 | { 404 | "cell_type": "markdown", 405 | "metadata": {}, 406 | "source": [ 407 | "## catch user-defined exception" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "execution_count": null, 413 | "metadata": {}, 414 | "outputs": [], 415 | "source": [ 416 | "try:\n", 417 | " x = getInteger() #may throw InputError\n", 418 | "except InputError as ie:\n", 419 | " print('Exception:', ie)\n", 420 | " # can throw ie again\n", 421 | "else:\n", 422 | " print('{}^2 = {}'.format(x, x**2))" 423 | ] 424 | }, 425 | { 426 | "cell_type": "code", 427 | "execution_count": null, 428 | "metadata": {}, 429 | "outputs": [], 430 | "source": [] 431 | } 432 | ], 433 | "metadata": { 434 | "kernelspec": { 435 | "display_name": "Python 3 (ipykernel)", 436 | "language": "python", 437 | "name": "python3" 438 | }, 439 | "language_info": { 440 | "codemirror_mode": { 441 | "name": "ipython", 442 | "version": 3 443 | }, 444 | "file_extension": ".py", 445 | "mimetype": "text/x-python", 446 | "name": "python", 447 | "nbconvert_exporter": "python", 448 | "pygments_lexer": "ipython3", 449 | "version": "3.9.7" 450 | } 451 | }, 452 | "nbformat": 4, 453 | "nbformat_minor": 4 454 | } 455 | -------------------------------------------------------------------------------- /notebooks/Ch17-PyGame.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# PyGame\n", 8 | "http://openbookproject.net/thinkcs/python/english3e/pygame.html\n", 9 | "\n", 10 | "- third-party package that is used in Game development using Python\n", 11 | "- must install using pip - https://www.pygame.org/download.shtml\n", 12 | "\n", 13 | "```bash\n", 14 | "$ pip install pygame\n", 15 | "```\n", 16 | "\n", 17 | "- see documentation: http://openbookproject.net/thinkcs/python/english3e/pygame.html\n", 18 | "- see `demos/pygamedemos` folder within the repository to run the provided source codes" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "metadata": {}, 25 | "outputs": [ 26 | { 27 | "name": "stdout", 28 | "output_type": "stream", 29 | "text": [ 30 | "Requirement already satisfied: pygame in /Users/rbasnet/miniconda3/lib/python3.7/site-packages (1.9.4)\n" 31 | ] 32 | } 33 | ], 34 | "source": [ 35 | "%%bash\n", 36 | "# install pygame\n", 37 | "pip install pygame" 38 | ] 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "# The game loop\n", 45 | "\n", 46 | "\n", 47 | "\n", 48 | "In every game, in the setup section we’ll create a window, load and prepare some content, and then enter the game loop. The game loop continuously does four main things:\n", 49 | "\n", 50 | "- it polls for events — i.e. asks the system whether events have occurred — and responds appropriately,\n", 51 | "- it updates whatever internal data structures or objects need changing,\n", 52 | "- it draws the current state of the game into a (non-visible) surface,\n", 53 | "- it puts the just-drawn surface on display." 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 2, 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "name": "stdout", 63 | "output_type": "stream", 64 | "text": [ 65 | "pygame 1.9.4\n", 66 | "Hello from the pygame community. https://www.pygame.org/contribute.html\n" 67 | ] 68 | } 69 | ], 70 | "source": [ 71 | "import pygame\n", 72 | "\n", 73 | "def main():\n", 74 | " \"\"\" Set up the game and run the main game loop \"\"\"\n", 75 | " pygame.init() # Prepare the pygame module for use\n", 76 | " surface_sz = 480 # Desired physical surface size, in pixels.\n", 77 | "\n", 78 | " # Create surface of (width, height), and its window.\n", 79 | " main_surface = pygame.display.set_mode((surface_sz, surface_sz))\n", 80 | "\n", 81 | " # Set up some data to describe a small rectangle and its color\n", 82 | " small_rect = (300, 200, 150, 90)\n", 83 | " some_color = (255, 0, 0) # A color is a mix of (Red, Green, Blue)\n", 84 | "\n", 85 | " while True:\n", 86 | " ev = pygame.event.poll() # Look for any event\n", 87 | " if ev.type == pygame.QUIT: # Window close button clicked?\n", 88 | " break # ... leave game loop\n", 89 | "\n", 90 | " # Update your game objects and data structures here...\n", 91 | "\n", 92 | " # We draw everything from scratch on each frame.\n", 93 | " # So first fill everything with the background color\n", 94 | " main_surface.fill((0, 200, 255))\n", 95 | "\n", 96 | " # Overpaint a smaller rectangle on the main surface\n", 97 | " main_surface.fill(some_color, small_rect)\n", 98 | "\n", 99 | " # Now the surface is ready, tell pygame to display it!\n", 100 | " pygame.display.flip()\n", 101 | "\n", 102 | " pygame.quit() # Once we leave the loop, close the window.\n", 103 | "\n", 104 | "main()" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 1, 110 | "metadata": {}, 111 | "outputs": [ 112 | { 113 | "name": "stdout", 114 | "output_type": "stream", 115 | "text": [ 116 | "pygame 1.9.4\n", 117 | "Hello from the pygame community. https://www.pygame.org/contribute.html\n" 118 | ] 119 | }, 120 | { 121 | "name": "stderr", 122 | "output_type": "stream", 123 | "text": [ 124 | "/Users/rbasnet/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:18: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n", 125 | "/Users/rbasnet/miniconda3/lib/python3.7/site-packages/ipykernel_launcher.py:30: DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead\n" 126 | ] 127 | } 128 | ], 129 | "source": [ 130 | "import pygame\n", 131 | "import time\n", 132 | "\n", 133 | "def main():\n", 134 | "\n", 135 | " pygame.init() # Prepare the PyGame module for use\n", 136 | " main_surface = pygame.display.set_mode((480, 240))\n", 137 | "\n", 138 | " # Load an image to draw. Substitute your own.\n", 139 | " # PyGame handles gif, jpg, png, etc. image types.\n", 140 | " ball = pygame.image.load(\"pygame/ball.png\")\n", 141 | " ball = pygame.transform.scale(ball, [20, 20])\n", 142 | " # Create a font for rendering text\n", 143 | " my_font = pygame.font.SysFont(\"Courier\", 16)\n", 144 | "\n", 145 | " frame_count = 0\n", 146 | " frame_rate = 0\n", 147 | " t0 = time.clock()\n", 148 | "\n", 149 | " while True:\n", 150 | "\n", 151 | " # Look for an event from keyboard, mouse, joystick, etc.\n", 152 | " ev = pygame.event.poll()\n", 153 | " if ev.type == pygame.QUIT: # Window close button clicked?\n", 154 | " break # Leave game loop\n", 155 | "\n", 156 | " # Do other bits of logic for the game here\n", 157 | " frame_count += 1\n", 158 | " if frame_count % 500 == 0:\n", 159 | " t1 = time.clock()\n", 160 | " frame_rate = 500 / (t1-t0)\n", 161 | " t0 = t1\n", 162 | "\n", 163 | " # Completely redraw the surface, starting with background\n", 164 | " main_surface.fill((0, 200, 255))\n", 165 | "\n", 166 | " # Put a red rectangle somewhere on the surface\n", 167 | " main_surface.fill((255,0,0), (300, 100, 150, 90))\n", 168 | "\n", 169 | " # Copy our image to the surface, at this (x,y) posn\n", 170 | " main_surface.blit(ball, (100, 120))\n", 171 | "\n", 172 | " # Make a new surface with an image of the text\n", 173 | " the_text = my_font.render(\"Frame = {0}, rate = {1:.2f} fps\"\n", 174 | " .format(frame_count, frame_rate), True, (0,0,0))\n", 175 | " # Copy the text surface to the main surface\n", 176 | " main_surface.blit(the_text, (10, 10))\n", 177 | "\n", 178 | " # Now that everything is drawn, put it on display!\n", 179 | " pygame.display.flip()\n", 180 | "\n", 181 | " pygame.quit()\n", 182 | "\n", 183 | "\n", 184 | "main()" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [] 193 | } 194 | ], 195 | "metadata": { 196 | "kernelspec": { 197 | "display_name": "Python 3", 198 | "language": "python", 199 | "name": "python3" 200 | }, 201 | "language_info": { 202 | "codemirror_mode": { 203 | "name": "ipython", 204 | "version": 3 205 | }, 206 | "file_extension": ".py", 207 | "mimetype": "text/x-python", 208 | "name": "python", 209 | "nbconvert_exporter": "python", 210 | "pygments_lexer": "ipython3", 211 | "version": "3.8.11" 212 | } 213 | }, 214 | "nbformat": 4, 215 | "nbformat_minor": 2 216 | } 217 | -------------------------------------------------------------------------------- /notebooks/Ch19-UnitTest.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Unit Test\n", 8 | "\n", 9 | "\"Open\n", 10 | "\n", 11 | "## Topics\n", 12 | "- unit testing\n", 13 | "- test-driven development\n", 14 | "- doctest\n", 15 | "\n", 16 | "## Test\n", 17 | "- coders/software engineers spend as much time debugging and testing their codes as they spend on developing/writing the codes\n", 18 | "- \"To err is human, but to preserve in error is diabolic.\" - anonymous\n", 19 | " - this more than two thousand-years old proverb fits with coding\n", 20 | "- \"Program testing can be used to show the presence of bugs, but never to show their absence!\" - Edsger W. Dijkstra\n", 21 | "- code coverage is used to measure the degree to which the source code of a program is executed when a particular test suite runs\n", 22 | "- various coverage criteria:\n", 23 | " - function coverage\n", 24 | " - statement coverage\n", 25 | " - branch coverage\n", 26 | " - condition coverage\n", 27 | " - loop coverage\n", 28 | " - data-flow coverage\n", 29 | " - function entry/exit coverage\n", 30 | "- full path coverage is usually impractical or impossible\n", 31 | " - module with a succession of $n$ decision in it can have up to $2^n$ paths\n", 32 | " - loops can result in an infinite number of paths\n", 33 | "- see this repository for more examples of unit testing: https://github.com/rambasnet/KattisDemos" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "## Test-driven development\n", 41 | "- write test cases before or simultaneously along with the code implementation\n", 42 | "- 3 simple ways to test your code natively at the functional level\n", 43 | " 1. assert statements - natively supported in many languages; as we've used before\n", 44 | " 2. doctest - simple, interactive technique, but makes the source code look messy, as they're defined inside the same function and module\n", 45 | " 3. unit test - preferred; separates the code with test " 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "## doctest\n", 53 | "- https://docs.python.org/3/library/doctest.html\n", 54 | "- to check that a module’s docstrings are up-to-date by verifying that all interactive examples still work as documented.\n", 55 | "- to perform regression testing by verifying that interactive examples from a test file or a test object work as expected.\n", 56 | "- to write tutorial documentation for a package, liberally illustrated with input-output examples. Depending on whether the examples or the expository text are emphasized, this has the flavor of “literate testing” or “executable documentation”." 57 | ] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": {}, 62 | "source": [ 63 | "### doctest demo\n", 64 | "- see `factorial.py` in `demos/utility` package for doctest example" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "## Unit testing\n", 72 | "- python provides unittest standard library to help with unit testing\n", 73 | "- documentation: https://docs.python.org/dev/library/unittest.html#module-unittest\n", 74 | "- see `fib_unittest.py` in `demos/utility` package for unittest example\n", 75 | "- run `fib_unittest.py` from command line to run the test suite" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "## Exercise\n", 83 | "1. Write unittest to test functions in demos/utility/factorial.py module.\n", 84 | "2. Solve kattis problems with along with unit testing for each problem" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": { 91 | "collapsed": true 92 | }, 93 | "outputs": [], 94 | "source": [] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.11.1 (main, Dec 23 2022, 09:40:27) [Clang 14.0.0 (clang-1400.0.29.202)]" 114 | }, 115 | "vscode": { 116 | "interpreter": { 117 | "hash": "1a1af0ee75eeea9e2e1ee996c87e7a2b11a0bebd85af04bb136d915cefc0abce" 118 | } 119 | } 120 | }, 121 | "nbformat": 4, 122 | "nbformat_minor": 2 123 | } 124 | -------------------------------------------------------------------------------- /notebooks/Ch21-Stacks.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Stacks\n", 8 | "\"Open\n", 9 | "\n", 10 | "http://openbookproject.net/thinkcs/python/english3e/stacks.html\n", 11 | "\n", 12 | "- container adapters or abstract data type (ADT) that may use list or linked-list as containers to hold data\n", 13 | "- specifically designed to operate as a LIFO (last-in-first-out) or FILO (first-in-last-out) data structure \n", 14 | " - last item added is the first to be removed\n", 15 | "- built-in alternative: deque - https://docs.python.org/3/library/collections.html#collections.deque\n", 16 | " \n", 17 | "## The Stack ADT\n", 18 | "- an ADT is defined by the operations that can be performed on it, called an interface.\n", 19 | "- interface of stack consists of the following basic operations:\n", 20 | " - \\__init__ - initialize a new empty stack\n", 21 | " - \\__len__ - returns length/size of the stack\n", 22 | " - push - add a new item to the stack\n", 23 | " - pop - remove and return last item that was added to the stack\n", 24 | " - is_empty - check if the stack is empty" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "## Implementing stack with Python list\n", 32 | "- Python list provides a several methods that we can take advantage of to emulate Stack ADT" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "class Stack:\n", 42 | " def __init__(self):\n", 43 | " self.items = []\n", 44 | " \n", 45 | " def __len__(self):\n", 46 | " return len(self.items)\n", 47 | " \n", 48 | " def push(self, item):\n", 49 | " self.items.append(item)\n", 50 | " \n", 51 | " def pop(self):\n", 52 | " return self.items.pop()\n", 53 | " \n", 54 | " def is_empty(self):\n", 55 | " return len(self.items == 0)\n" 56 | ] 57 | }, 58 | { 59 | "cell_type": "markdown", 60 | "metadata": {}, 61 | "source": [ 62 | "## Applications of stack" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "s = Stack()\n", 72 | "s.push(54)\n", 73 | "s.push(45)\n", 74 | "s.push('+')" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "## visualize stack with pythontutor\n", 82 | "https://goo.gl/Q4wZaL" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": 5, 88 | "metadata": {}, 89 | "outputs": [ 90 | { 91 | "data": { 92 | "text/html": [ 93 | "\n", 94 | " \n", 103 | " " 104 | ], 105 | "text/plain": [ 106 | "" 107 | ] 108 | }, 109 | "execution_count": 5, 110 | "metadata": {}, 111 | "output_type": "execute_result" 112 | } 113 | ], 114 | "source": [ 115 | "from IPython.display import IFrame\n", 116 | "src = \"\"\"\n", 117 | "http://pythontutor.com/iframe-embed.html#code=class%20Stack%3A%0A%20%20%20%20def%20__init__%28self%29%3A%0A%20%20%20%20%20%20%20%20self.items%20%3D%20%5B%5D%0A%20%20%20%20%0A%20%20%20%20def%20__len__%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20len%28self.items%29%0A%20%20%20%20%0A%20%20%20%20def%20push%28self,%20item%29%3A%0A%20%20%20%20%20%20%20%20self.items.append%28item%29%0A%20%20%20%20%20%20%20%20%0A%20%20%20%20def%20pop%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20self.items.pop%28%29%0A%20%20%20%20%0A%20%20%20%20def%20is_empty%28self%29%3A%0A%20%20%20%20%20%20%20%20return%20len%28self.items%20%3D%3D%200%29%0A%20%20%20%20%20%20%20%20%0As%20%3D%20Stack%28%29%0As.push%2854%29%0As.push%2845%29%0As.push%28'%2B'%29&codeDivHeight=400&codeDivWidth=350&cumulative=false&curInstr=0&heapPrimitives=false&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false\n", 118 | "\"\"\"\n", 119 | "IFrame(src, width=900, height=500)" 120 | ] 121 | }, 122 | { 123 | "cell_type": "markdown", 124 | "metadata": {}, 125 | "source": [ 126 | "## using a stack to evaluate postfix notation\n", 127 | "- infix notation: 1 + 2\n", 128 | "- prefix notation: + 1 2\n", 129 | "- postfix notation: 1 2 +\n", 130 | " - operator follows the operands\n", 131 | " - no need to use parenthesis to control oder of operations\n", 132 | "- algorithm steps:\n", 133 | " 1. starting at the beginning of the expression, get one term/token (operator or operand) at a time\n", 134 | " a. if the term is an operand, push it on the stack\n", 135 | " b. if the term is an operator, pop two operands off the stack, perform the operation on them, and push the result back on the stack\n", 136 | " 2. When you get to the end of the expression, there should be exactly one operand left on the stack, the result." 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 8, 142 | "metadata": {}, 143 | "outputs": [], 144 | "source": [ 145 | "# given a postfix notation such as: 56 47 + 2 *, the following function evaluates the result using Stack ADT\n", 146 | "def eval_postfix(expr):\n", 147 | " tokens = expr.split()\n", 148 | " stack = Stack()\n", 149 | " for token in tokens:\n", 150 | " token = token.strip()\n", 151 | " if not token:\n", 152 | " continue\n", 153 | " if token == '+':\n", 154 | " s = stack.pop() + stack.pop()\n", 155 | " stack.push(s)\n", 156 | " elif token == '*':\n", 157 | " prod = stack.pop() * stack.pop()\n", 158 | " stack.push(prod)\n", 159 | " # /, and - are left as exercise\n", 160 | " else:\n", 161 | " stack.push(int(token))\n", 162 | " \n", 163 | " return stack.pop()\n", 164 | " " 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 9, 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "206\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "print(eval_postfix('56 47 + 2 *'))" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 11, 187 | "metadata": {}, 188 | "outputs": [ 189 | { 190 | "data": { 191 | "text/plain": [ 192 | "206" 193 | ] 194 | }, 195 | "execution_count": 11, 196 | "metadata": {}, 197 | "output_type": "execute_result" 198 | } 199 | ], 200 | "source": [ 201 | "# which is same as: (56 + 47) * 2 in infix notation\n", 202 | "eval('(56 + 47) * 2')" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "## exercises\n", 210 | "1. Write a function that converts infix notation to postfix notation, e.g., given infix notation $4 - 2 + 3$ the program should output corresponding postfix notation $4 \\ 2 - 3\\ +$\n", 211 | "\n", 212 | "## Following Kattis problems can be solved using Stack\n", 213 | "1. Backspace problem: https://open.kattis.com/problems/backspace\n", 214 | "- Game of throwns: https://open.kattis.com/problems/throwns\n", 215 | "- Even Up Solitaire: https://open.kattis.com/problems/evenup\n", 216 | "- Working at the Restaurant: https://open.kattis.com/problems/restaurant\n", 217 | "- Pairing Socks: https://open.kattis.com/problems/pairingsocks\n", 218 | "- Find stack-based problems in Kattis: https://cpbook.net/methodstosolve search for stack" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "execution_count": null, 224 | "metadata": {}, 225 | "outputs": [], 226 | "source": [] 227 | } 228 | ], 229 | "metadata": { 230 | "kernelspec": { 231 | "display_name": "Python 3", 232 | "language": "python", 233 | "name": "python3" 234 | }, 235 | "language_info": { 236 | "codemirror_mode": { 237 | "name": "ipython", 238 | "version": 3 239 | }, 240 | "file_extension": ".py", 241 | "mimetype": "text/x-python", 242 | "name": "python", 243 | "nbconvert_exporter": "python", 244 | "pygments_lexer": "ipython3", 245 | "version": "3.11.1 (main, Dec 23 2022, 09:40:27) [Clang 14.0.0 (clang-1400.0.29.202)]" 246 | }, 247 | "vscode": { 248 | "interpreter": { 249 | "hash": "1a1af0ee75eeea9e2e1ee996c87e7a2b11a0bebd85af04bb136d915cefc0abce" 250 | } 251 | } 252 | }, 253 | "nbformat": 4, 254 | "nbformat_minor": 2 255 | } 256 | -------------------------------------------------------------------------------- /notebooks/Ch22-Queues.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Queues\n", 8 | "\"Open\n", 9 | "\n", 10 | "http://openbookproject.net/thinkcs/python/english3e/queues.html\n", 11 | "- another container adapter or ADT, which is typically a first-in-first-out (FIFO) data structure\n", 12 | "- mimics real-world queue/line of people waiting for something\n", 13 | "- rule that determines who goes next is called the queuing policy\n", 14 | "- the most general queuing policy is priority queuing, in which each item/person is assigned a priority and the element with highest priority goes first, regardless of the order of the arrival\n", 15 | "- built-in alternative - deque: https://docs.python.org/3/library/collections.html#collections.deque" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "## The Queue ADT\n", 23 | "- can be implemented using built-in list or linked list as the container to hold the elements\n", 24 | "- queque ADT is defined by the following operations:\n", 25 | " - \\__init__ : initialize the queue\n", 26 | " - insert : add a new item to the queue\n", 27 | " - remove : remove and return the first element that was added\n", 28 | " - is_empty : check whether the queue is empty" 29 | ] 30 | }, 31 | { 32 | "cell_type": "markdown", 33 | "metadata": {}, 34 | "source": [ 35 | "## Linked Queue" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 1, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "class Node:\n", 45 | " def __init__(self, data):\n", 46 | " self.cargo = data\n", 47 | " self.next = None\n", 48 | " \n", 49 | " def __str__(self):\n", 50 | " return \"{}\".format(self.cargo)\n", 51 | " " 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": 4, 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "class Queue:\n", 61 | " def __init__(self):\n", 62 | " self.length = 0\n", 63 | " self.head = None\n", 64 | " self.tail = None\n", 65 | " \n", 66 | " def is_empty(self):\n", 67 | " return self.length == 0\n", 68 | " \n", 69 | " def insert(self, data):\n", 70 | " node = Node(data)\n", 71 | " if not self.head: # empty queue\n", 72 | " self.head = self.tail = node\n", 73 | " else:\n", 74 | " # add new node as the last node\n", 75 | " self.tail.next = node\n", 76 | " self.tail = node\n", 77 | " self.length += 1\n", 78 | " \n", 79 | " def remove(self):\n", 80 | " data = self.head.cargo\n", 81 | " # make the head point to 2nd element\n", 82 | " self.head = self.head.next\n", 83 | " self.length -= 1\n", 84 | " # update tail if the queue becomes empty after removing the first node\n", 85 | " if self.length == 0:\n", 86 | " self.tail = None\n", 87 | " \n", 88 | " return data\n", 89 | " \n", 90 | " def __len__(self):\n", 91 | " return self.length" 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "metadata": {}, 97 | "source": [ 98 | "### quick test of Queue ADT" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 5, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "q = Queue()\n", 108 | "q.insert(1)\n", 109 | "q.insert(2)\n", 110 | "q.insert('a')\n", 111 | "assert q.remove() == 1\n", 112 | "assert len(q) == 2\n", 113 | "q.insert(100)\n", 114 | "assert q.remove() == 2" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "## Priority Queue ADT\n", 122 | "- better built-in alternative: heapq- https://docs.python.org/3/library/heapq.html\n", 123 | "- Priority Queue ADT implementation\n", 124 | "- use the same methods/interfaces as Queue with only difference in remove function; where the item removed is the highest priority\n", 125 | " - item removed is not necessarily the first one that was added; rather an item in the queue with highest priority\n", 126 | " - e.g., if the items in the queue have names, we might choose item in alphabetical order\n", 127 | " - if they're bowling scores, we might go from highest to lowest, but if they're golf scores, we would go from lowest to highest" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 6, 133 | "metadata": {}, 134 | "outputs": [], 135 | "source": [ 136 | "class PriorityQueue:\n", 137 | " def __init__(self):\n", 138 | " self.items = []\n", 139 | " \n", 140 | " def is_empty(self):\n", 141 | " return self.items == []\n", 142 | " \n", 143 | " def insert(self, data):\n", 144 | " self.items.append(data)\n", 145 | " \n", 146 | " def remove(self):\n", 147 | " maxi = 0\n", 148 | " for i in range(1, len(self.items)):\n", 149 | " if self.items[i] > self.items[maxi]:\n", 150 | " maxi = i\n", 151 | " item = self.items[maxi]\n", 152 | " del self.items[maxi]\n", 153 | " return item\n", 154 | " \n", 155 | " def __len__(self):\n", 156 | " return len(self.items)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": {}, 162 | "source": [ 163 | "### test priority queue ADT" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 7, 169 | "metadata": {}, 170 | "outputs": [], 171 | "source": [ 172 | "q = PriorityQueue()\n", 173 | "for num in [11, 12, 14, 13]:\n", 174 | " q.insert(num)\n", 175 | " " 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": 8, 181 | "metadata": {}, 182 | "outputs": [ 183 | { 184 | "name": "stdout", 185 | "output_type": "stream", 186 | "text": [ 187 | "14\n", 188 | "13\n", 189 | "12\n", 190 | "11\n" 191 | ] 192 | } 193 | ], 194 | "source": [ 195 | "while not q.is_empty():\n", 196 | " print(q.remove())" 197 | ] 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "metadata": {}, 202 | "source": [ 203 | "## The Golfer class\n", 204 | "- keeps track of the names and scores of golfers" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": 10, 210 | "metadata": {}, 211 | "outputs": [], 212 | "source": [ 213 | "class Golfer:\n", 214 | " def __init__(self, name, score):\n", 215 | " self.name = name\n", 216 | " self.score = score\n", 217 | " \n", 218 | " def __str__(self):\n", 219 | " return \"{0:16}: {1}\".format(self.name, self.score)\n", 220 | " \n", 221 | " # lowest score gets highest priority\n", 222 | " def __gt__(self, other):\n", 223 | " return self.score < other.score # lower score has the higher priority" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": 11, 229 | "metadata": {}, 230 | "outputs": [ 231 | { 232 | "name": "stdout", 233 | "output_type": "stream", 234 | "text": [ 235 | "Hal Sutton : 20\n" 236 | ] 237 | } 238 | ], 239 | "source": [ 240 | "tiger = Golfer('Tigher Woods', 40)\n", 241 | "phil = Golfer('Phil Mickelson', 30)\n", 242 | "hal = Golfer('Hal Sutton', 20)\n", 243 | "pq = PriorityQueue()\n", 244 | "pq.insert(tiger)\n", 245 | "pq.insert(phil)\n", 246 | "pq.insert(hal)\n", 247 | "print(pq.remove())" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": 12, 253 | "metadata": {}, 254 | "outputs": [ 255 | { 256 | "name": "stdout", 257 | "output_type": "stream", 258 | "text": [ 259 | "Phil Mickelson : 30\n", 260 | "Tigher Woods : 40\n" 261 | ] 262 | } 263 | ], 264 | "source": [ 265 | "while not pq.is_empty():\n", 266 | " print(pq.remove())" 267 | ] 268 | }, 269 | { 270 | "cell_type": "markdown", 271 | "metadata": {}, 272 | "source": [ 273 | "## exercises" 274 | ] 275 | }, 276 | { 277 | "cell_type": "markdown", 278 | "metadata": {}, 279 | "source": [ 280 | "1. Write an implementation of the Queue ADT using Python list. Compare the performance of this implementation to the ImprovedQueue for a range of queue lengths.\n", 281 | "- Write an implementation of the Priority Queue ADT using linked list. You should keep the list sorted so that removal is a constant time operation. Compare the performance of this implementation with the Python list implementation." 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "## Kattis problems that can be solved using Queue\n", 289 | "1. Solve kattis problem Bank Queue: https://open.kattis.com/problems/bank\n", 290 | "- Server - https://open.kattis.com/problems/server\n", 291 | "- Ferry Loading III - https://open.kattis.com/problems/ferryloading3\n", 292 | "- Foosball Dynasty - https://open.kattis.com/problems/foosball\n", 293 | "- Disastrous Downtime: https://open.kattis.com/problems/downtime" 294 | ] 295 | }, 296 | { 297 | "cell_type": "code", 298 | "execution_count": null, 299 | "metadata": {}, 300 | "outputs": [], 301 | "source": [] 302 | } 303 | ], 304 | "metadata": { 305 | "kernelspec": { 306 | "display_name": "Python 3", 307 | "language": "python", 308 | "name": "python3" 309 | }, 310 | "language_info": { 311 | "codemirror_mode": { 312 | "name": "ipython", 313 | "version": 3 314 | }, 315 | "file_extension": ".py", 316 | "mimetype": "text/x-python", 317 | "name": "python", 318 | "nbconvert_exporter": "python", 319 | "pygments_lexer": "ipython3", 320 | "version": "3.7.2" 321 | } 322 | }, 323 | "nbformat": 4, 324 | "nbformat_minor": 2 325 | } 326 | -------------------------------------------------------------------------------- /notebooks/resources/BuildingBlocks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/BuildingBlocks.png -------------------------------------------------------------------------------- /notebooks/resources/Inheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/Inheritance.png -------------------------------------------------------------------------------- /notebooks/resources/MultipleInheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/MultipleInheritance.png -------------------------------------------------------------------------------- /notebooks/resources/PythonPrompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/PythonPrompt.png -------------------------------------------------------------------------------- /notebooks/resources/brain.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/brain.jpg -------------------------------------------------------------------------------- /notebooks/resources/recursion-fib.svg: -------------------------------------------------------------------------------- 1 | fib ( 5 )fib(4)fib(3)fib(3)fib(2)fib(0)fib(1)fib(1)fib(2)fib(0)fib(1)fib(1)fib(2)fib(0)fib(1) -------------------------------------------------------------------------------- /notebooks/resources/russiandolls.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/russiandolls.png -------------------------------------------------------------------------------- /notebooks/resources/tree2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/tree2.png -------------------------------------------------------------------------------- /notebooks/resources/tree3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/notebooks/resources/tree3.png -------------------------------------------------------------------------------- /paper.bib: -------------------------------------------------------------------------------- 1 | @article{Basnet2018, 2 | Author = {Basnet, Ram and Doleck, Tenzin and Lemay, David and Bazelais, Paul}, 3 | Title = {Exploring Computer Science Students' Continuance Intentions to Use Kattis. Education and Information Technologies}, 4 | Volume = {23(3)}, 5 | Pages = {1145–1158}, 6 | Doi = {10.1007/s10639-017-9658-2}, 7 | Year = {2018}} 8 | 9 | @article{Guo2013, 10 | Author = {Guo, P.}, 11 | Title = {Online python tutor: embeddable web-based program visualization for cs education}, 12 | Journal = {Proceeding of the 44th ACM technical symposium on Computer science education}, 13 | Pages = {579-584}, 14 | Publisher = {ACM}, 15 | Year = {2013}} 16 | 17 | @misc{Guo2014, 18 | Author = {Guo, P.}, 19 | Title = {Python Is Now the Most Popular Introductory Teaching Language at Top U.S. Universities [Blog]}, 20 | Howpublished = {\URL{https://cacm.acm.org/blogs/blog-cacm/176450-python-is-now-the-most-popular-introductory-teaching-language-at-top-u-s-universities/fulltext}}, 21 | Year = {2014}} 22 | 23 | @article{OHara2015, 24 | Author = {O'Hara, K. and Blank, D. and Marshall, J.}, 25 | Title = {Computational notebooks for AI education}, 26 | Year = {2015}, 27 | Journal = {Proceedings of the International Florida Artificial Intelligence Research Society Conference (FLAIRS), Hollywood, FL}} 28 | 29 | @article{Mannila2006, 30 | Author = {Mannila, L. and Peltomäki, M. and Salakoski, T.}, 31 | Year = {2006}, 32 | Title = {What about a simple language? Analyzing the difficulties in learning to program}, 33 | Journal = {Computer Science Education}, 34 | Volume = {16(3)}, 35 | Pages = {211-227}, 36 | Doi = {10.1080/08993400600912384}} 37 | 38 | @ariticle{Rockinson-Szapkiw2013, 39 | Author = {Rockinson-Szapkiw, A. and Wendt, J. and Lunde, R.}, 40 | Year = {2013}, 41 | Title = {Electronic Versus Print Textbooks: The Influence of Textbook Format on University Students' Self-Regulated Learning Strategies, Motivation, and Text Anxiety}, 42 | Journal = {American Journal of Distance Education}, 43 | Volume = {27(3)}, 44 | Pages = {179-188}, 45 | Doi = {10.1080/08923647.2013.796230}} 46 | 47 | @article{Robins2003, 48 | Author = {Robins, A. and Rountree, J. and Rountree, N.}, 49 | Title = {Learning and teaching programming: A review and discussion}, 50 | Journal = {Computer Science Education}, 51 | Volume = {13(2)}, 52 | Pages = {137–172}, 53 | Doi = {10.1076/csed.13.2.137.14200}, 54 | Year = {2013}} 55 | 56 | @artilce{Shen2014, 57 | Author = {Shen, H.}, 58 | Title = {Interactive notebooks: Sharing the code}, 59 | Year = {2014}, 60 | Journal = {Nature}, 61 | Volume = {515(7525)}, 62 | Pages = {151-152}, 63 | Doi = {10.1038/515151a}} 64 | 65 | @book{Wentworth2012, 66 | Author = {Wentworth, P. and Elkner, J. and Downey, A. B. and Meyers, C.}, 67 | Year = {2012}, 68 | Title = {How to Think Like a Computer Scientist: Learning with Python 3 (RLE)}, 69 | Howpublished = {\URL{http://openbookproject.net/thinkcs/python/english3e/}}, 70 | Edition = {2}} 71 | -------------------------------------------------------------------------------- /paper.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "FDS Python: Fundamentals and Data Structures with Python" 3 | tags: 4 | - python programming 5 | - think python3 6 | - fundamentals of programming 7 | - data structures 8 | - interactive python 9 | authors: 10 | - name: Ram B. Basnet 11 | orcid: 0000-0001-6864-6893 12 | affiliation: 1 13 | - name: Tenzin Doleck 14 | affiliation: 2 15 | affiliations: 16 | - name: Colorado Mesa University 17 | index: 1 18 | - name: McGill University 19 | index: 2 20 | date: 4 Februrary 2019 21 | bibliography: paper.bib 22 | --- 23 | 24 | # Summary 25 | 26 | It is well acknowledged that programming is a challenging endeavor [@Robins2003]. As such, considerations of the suitability of programming languages, such as Python, for teaching and learning programming have received growing interest [@Mannila2006]. In fact, among programming languages, Python is the most popular language for introductory computer science courses among US universities [@Guo2014]. 27 | 28 | Although Python provides a way to quickly write and test code and concepts in the interactive ">>>, chevron prompt" mode, the codes and results vanish and cannot be easily reproduced once the session is terminated. Moreover, writing multiple lines of codes or functions is not intuitive because of the language's strict syntactic rules on enforcing whitespaces to represent block of codes. Jupyter notebooks can easily overcome these drawbacks as one can quickly and interactively write single to many lines of codes and at the same time keep track of the output results as part of the notes. Furthermore, students can refer to what they have done and manage all their notes in one convenient location. 29 | 30 | These notebooks are designed to accommodate beginners as well as experienced programmers who are interested in teaching and learning to code in Python. More importantly, the interactive nature of these notebooks force students to code to learn and not learn to code. [Pythontutor](http://pythontutor.com) [@Guo2013] is used to help students visualize and understand the concepts better by working on problems from [open.kattis.com](https://open.kattis.com/) [@Basnet2018] where appropriate. 31 | 32 | # Statement of need 33 | 34 | Textbooks, powerpoint slides, notes and code snippets are commonly used for delivering course content in programming courses; however, "a majority of university students do not regularly read course textbooks" [@Rockinson-Szapkiw2013]. Moreover, teaching and learning programming using notes and slides alone can be pretty dry and less effective. Even if this technique is supplemented by live interactive coding session, it may seem disorganized and harder to follow, especially for novice programmers who are learning everything -- concepts, definitions, syntax and coding -- at the same timeTo ameliorate this situation, educators have suggested the use of computational notebooks, such as the Jupyter computational notebook project, for offering both new ways of instruction and making interactive curricula [@OHara2015;@Shen2014]. 35 | 36 | Most successful commercial textbooks provide a lot of pre-built teaching materials (powerpoint slides, notes, question bank and answers, source codes, etc.) needed for an instructor to quickly adopt their text and teach the courses. On the other hand, most open-source textbooks mostly lack these required teaching aids making it harder for instructors to adopt them into their curriculum. 37 | 38 | FDS Python is an open-source set of Jupyter notebooks that covers fundamental concepts of programming and data structures using Python. These interactive notebooks are based on the open-source textbook: [Think Python: How to Think Like a Computer Scientist](http://openbookproject.net/thinkcs/python/english3e/index.html) [@Wentworth2012]. The notebooks consist of a summary of the theory/lecture notes and syntax of concepts (similar to powerpoints) along with interactive code examples compounded with code visualization and interesting problems to help engage beginner as well as advanced programmers. Besides most of the concepts covered in the textbook, these notebooks also contain several new, important and advanced concepts on automated testing, code optimization and memoization, Python language intricacies such as built-in libraries and functions, list and dictionary comprehension, lambda functions, etc. 39 | 40 | The notebooks, however, are not intended to be complete learning modules or entirely replace the textbook but rather much needed teaching materials for new instructors to aid in adopting the open-source textbook to especially teach Python using a practical, follow-along live coding approach. These notebooks are being used in university courses (Beginning and Advanced Programming courses) since 2017 at Colorado Mesa University. Depending on the need and the audience skill level, instructors in introductory programming course can spend more time demonstrating the concepts with many examples supplementing them with visualization; in contrast, in advanced or intensive boot camp like courses, instructors can skip the theoretical portions and instead focus on the syntax and spend more time on advanced topics and concepts with live examples. 41 | 42 | # References 43 | -------------------------------------------------------------------------------- /pdfs/Ch01-Introduction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch01-Introduction.pdf -------------------------------------------------------------------------------- /pdfs/Ch02-1-Data-Variables.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch02-1-Data-Variables.pdf -------------------------------------------------------------------------------- /pdfs/Ch02-2-BitwiseOperators.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch02-2-BitwiseOperators.pdf -------------------------------------------------------------------------------- /pdfs/Ch02-Data-Variables.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch02-Data-Variables.pdf -------------------------------------------------------------------------------- /pdfs/Ch03-1-Functions-Built-in.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch03-1-Functions-Built-in.pdf -------------------------------------------------------------------------------- /pdfs/Ch03-2-Functions-Library.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch03-2-Functions-Library.pdf -------------------------------------------------------------------------------- /pdfs/Ch03-3-Functions-UserDefined.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch03-3-Functions-UserDefined.pdf -------------------------------------------------------------------------------- /pdfs/Ch04-Conditionals.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch04-Conditionals.pdf -------------------------------------------------------------------------------- /pdfs/Ch05-Iterations.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch05-Iterations.pdf -------------------------------------------------------------------------------- /pdfs/Ch06-Strings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch06-Strings.pdf -------------------------------------------------------------------------------- /pdfs/Ch07-Tuples.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch07-Tuples.pdf -------------------------------------------------------------------------------- /pdfs/Ch08-1-Lists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch08-1-Lists.pdf -------------------------------------------------------------------------------- /pdfs/Ch08-2-Lists-Advanced.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch08-2-Lists-Advanced.pdf -------------------------------------------------------------------------------- /pdfs/Ch09-1-Dictionaries.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch09-1-Dictionaries.pdf -------------------------------------------------------------------------------- /pdfs/Ch09-2-Built-in-DataStructures.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch09-2-Built-in-DataStructures.pdf -------------------------------------------------------------------------------- /pdfs/Ch10-1-Files.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch10-1-Files.pdf -------------------------------------------------------------------------------- /pdfs/Ch10-2-Files-Advanced.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch10-2-Files-Advanced.pdf -------------------------------------------------------------------------------- /pdfs/Ch11-Turtles-Events.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch11-Turtles-Events.pdf -------------------------------------------------------------------------------- /pdfs/Ch12-Modules.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch12-Modules.pdf -------------------------------------------------------------------------------- /pdfs/Ch12-ModulesAndPackages.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch12-ModulesAndPackages.pdf -------------------------------------------------------------------------------- /pdfs/Ch13-Recursion.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch13-Recursion.pdf -------------------------------------------------------------------------------- /pdfs/Ch14-OOP.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch14-OOP.pdf -------------------------------------------------------------------------------- /pdfs/Ch15-Overloading-Polymorphism.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch15-Overloading-Polymorphism.pdf -------------------------------------------------------------------------------- /pdfs/Ch16-Exceptions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch16-Exceptions.pdf -------------------------------------------------------------------------------- /pdfs/Ch17-PyGame.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch17-PyGame.pdf -------------------------------------------------------------------------------- /pdfs/Ch18-Inheritance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch18-Inheritance.pdf -------------------------------------------------------------------------------- /pdfs/Ch19-UnitTest.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch19-UnitTest.pdf -------------------------------------------------------------------------------- /pdfs/Ch20-LinkedLists.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch20-LinkedLists.pdf -------------------------------------------------------------------------------- /pdfs/Ch21-Stacks.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch21-Stacks.pdf -------------------------------------------------------------------------------- /pdfs/Ch22-Queues.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch22-Queues.pdf -------------------------------------------------------------------------------- /pdfs/Ch23-Trees.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch23-Trees.pdf -------------------------------------------------------------------------------- /pdfs/Ch24-CodeOptimization-ExecutionTime.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch24-CodeOptimization-ExecutionTime.pdf -------------------------------------------------------------------------------- /pdfs/Ch25-DynamicProgramming.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch25-DynamicProgramming.pdf -------------------------------------------------------------------------------- /pdfs/Ch26-SlqiteDB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/pdfs/Ch26-SlqiteDB.pdf -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rambasnet/Python-Fundamentals/a1aa9ebf6a069a7aafda95abd509cbd3020a9f77/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_1.py: -------------------------------------------------------------------------------- 1 | def test_dummy(): 2 | assert 1 == 1 3 | 4 | --------------------------------------------------------------------------------