├── 00_images ├── Wave_sine.png ├── ai │ ├── ibrahim.gif │ └── unit_testing_gemini_generated.png ├── redmonk_2024.png ├── rounding_bias.png ├── ChangRRPCC2006.png ├── Grading_SciPro.png ├── Gradient_descent.gif ├── integral_example.png ├── Gaussian_distribution.png ├── accuracy_and_precision.png ├── accuracy_vs_precision_1.png ├── accuracy_vs_precision_2.png ├── accuracy_vs_precision_3.png ├── top_compchem_libraries.png ├── ChemRxiv_coronavirus_2020.png ├── 31_machine_learning │ ├── numpy_nn.png │ ├── nn_diagram.odg │ ├── perceptron_english.png │ ├── deep_neural_network.png │ ├── scikit_learn_ml_map.png │ ├── nn_perceptron_example.png │ ├── nn_perceptron_example_nodes.png │ ├── shallow_learning_depictions.jpg │ └── nn_perceptron_example_wo_bias.png ├── scientifc_programing_bing.jpeg ├── sigfigs_gemini_generated_image.png ├── alexander-muzenhardt-753371-unsplash.jpg └── sigfigs_gemini_generated_image_aliens.png ├── data_3d.csv ├── data_3d_semi.csv ├── data_eu.csv ├── student_questions.ipynb ├── scientific_figures.ipynb ├── etiquette_and_practices.ipynb ├── jupyter_notebooks_intro.ipynb ├── README.md ├── function_example.ipynb ├── statistics_simple.ipynb ├── expressions_types_variables.ipynb ├── operations.ipynb ├── csv_library.ipynb ├── tips.csv ├── colaboratory_introduction.ipynb ├── containers.ipynb ├── citation_lecture.ipynb ├── t-test.ipynb ├── mid_semester_review.ipynb ├── intro_example.ipynb ├── numpy_polynomials.ipynb ├── testing_exceptions_unit_extra_info.ipynb ├── introduction.ipynb └── classes.ipynb /00_images/Wave_sine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/Wave_sine.png -------------------------------------------------------------------------------- /00_images/ai/ibrahim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/ai/ibrahim.gif -------------------------------------------------------------------------------- /00_images/redmonk_2024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/redmonk_2024.png -------------------------------------------------------------------------------- /00_images/rounding_bias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/rounding_bias.png -------------------------------------------------------------------------------- /00_images/ChangRRPCC2006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/ChangRRPCC2006.png -------------------------------------------------------------------------------- /00_images/Grading_SciPro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/Grading_SciPro.png -------------------------------------------------------------------------------- /00_images/Gradient_descent.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/Gradient_descent.gif -------------------------------------------------------------------------------- /00_images/integral_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/integral_example.png -------------------------------------------------------------------------------- /00_images/Gaussian_distribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/Gaussian_distribution.png -------------------------------------------------------------------------------- /00_images/accuracy_and_precision.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/accuracy_and_precision.png -------------------------------------------------------------------------------- /00_images/accuracy_vs_precision_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/accuracy_vs_precision_1.png -------------------------------------------------------------------------------- /00_images/accuracy_vs_precision_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/accuracy_vs_precision_2.png -------------------------------------------------------------------------------- /00_images/accuracy_vs_precision_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/accuracy_vs_precision_3.png -------------------------------------------------------------------------------- /00_images/top_compchem_libraries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/top_compchem_libraries.png -------------------------------------------------------------------------------- /00_images/ChemRxiv_coronavirus_2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/ChemRxiv_coronavirus_2020.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/numpy_nn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/numpy_nn.png -------------------------------------------------------------------------------- /00_images/scientifc_programing_bing.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/scientifc_programing_bing.jpeg -------------------------------------------------------------------------------- /00_images/31_machine_learning/nn_diagram.odg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/nn_diagram.odg -------------------------------------------------------------------------------- /00_images/sigfigs_gemini_generated_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/sigfigs_gemini_generated_image.png -------------------------------------------------------------------------------- /00_images/ai/unit_testing_gemini_generated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/ai/unit_testing_gemini_generated.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/perceptron_english.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/perceptron_english.png -------------------------------------------------------------------------------- /00_images/alexander-muzenhardt-753371-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/alexander-muzenhardt-753371-unsplash.jpg -------------------------------------------------------------------------------- /00_images/sigfigs_gemini_generated_image_aliens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/sigfigs_gemini_generated_image_aliens.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/deep_neural_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/deep_neural_network.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/scikit_learn_ml_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/scikit_learn_ml_map.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/nn_perceptron_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/nn_perceptron_example.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/nn_perceptron_example_nodes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/nn_perceptron_example_nodes.png -------------------------------------------------------------------------------- /00_images/31_machine_learning/shallow_learning_depictions.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/shallow_learning_depictions.jpg -------------------------------------------------------------------------------- /00_images/31_machine_learning/nn_perceptron_example_wo_bias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/karlkirschner/Scientific_Programming_Course/HEAD/00_images/31_machine_learning/nn_perceptron_example_wo_bias.png -------------------------------------------------------------------------------- /data_3d.csv: -------------------------------------------------------------------------------- 1 | Time,Exp,Theory 2 | 0.0,0.1185,0.2255 3 | 0.5,0.6524,0.3052 4 | 1.0,0.1291,0.0744 5 | 1.5,0.9445,0.7611 6 | 2.0,0.0272,0.1183 7 | 2.5,0.7598,0.0450 8 | 3.0,0.8159,0.2669 9 | 3.5,0.8003,0.1770 10 | 4.0,0.5716,0.2433 11 | 4.5,0.6651,0.2302 12 | 5.0,0.9983,0.0772 13 | 5.5,0.1004,0.0805 14 | 6.0,0.8433,0.6214 15 | 6.5,0.0067,0.1156 16 | 7.0,0.8238,0.1607 17 | 7.5,0.3952,0.0420 18 | 8.0,0.6452,0.1123 19 | 8.5,0.8480,0.3830 20 | 9.0,0.1986,0.5566 21 | 9.5,0.9114,0.6670 22 | 10.0,0.7693,0.5655 23 | 10.5,0.5009,0.4875 24 | 11.0,0.2110,0.0104 25 | 11.5,0.9227,0.4968 26 | 12.0,0.0461,0.2639 27 | 12.5,0.2177,0.2197 28 | 13.0,0.9554,0.9440 29 | 13.5,0.6130,0.2423 30 | -------------------------------------------------------------------------------- /data_3d_semi.csv: -------------------------------------------------------------------------------- 1 | Time;Exp;Theory 2 | 0.0;0.1185;0.2255 3 | 0.5;0.6524;0.3052 4 | 1.0;0.1291;0.0744 5 | 1.5;0.9445;0.7611 6 | 2.0;0.0272;0.1183 7 | 2.5;0.7598;0.0450 8 | 3.0;0.8159;0.2669 9 | 3.5;0.8003;0.1770 10 | 4.0;0.5716;0.2433 11 | 4.5;0.6651;0.2302 12 | 5.0;0.9983;0.0772 13 | 5.5;0.1004;0.0805 14 | 6.0;0.8433;0.6214 15 | 6.5;0.0067;0.1156 16 | 7.0;0.8238;0.1607 17 | 7.5;0.3952;0.0420 18 | 8.0;0.6452;0.1123 19 | 8.5;0.8480;0.3830 20 | 9.0;0.1986;0.5566 21 | 9.5;0.9114;0.6670 22 | 10.0;0.7693;0.5655 23 | 10.5;0.5009;0.4875 24 | 11.0;0.2110;0.0104 25 | 11.5;0.9227;0.4968 26 | 12.0;0.0461;0.2639 27 | 12.5;0.2177;0.2197 28 | 13.0;0.9554;0.9440 29 | 13.5;0.6130;0.2423 30 | -------------------------------------------------------------------------------- /data_eu.csv: -------------------------------------------------------------------------------- 1 | Time;Exp;Theory;Value 2 | 0,0;0,1185;0,226;10.135,11 3 | 0,5;0,6524;0,305;11.106,23 4 | 1,0;0,1291;0,074;12.347,45 5 | 1,5;0,9445;0,761;18.421,76 6 | 2,0;0,0272;0,118;13.551,78 7 | 2,5;0,7598;0,045;14.827,12 8 | 3,0;0,8159;0,267;14.305,56 9 | 3,5;0,8003;0,177;10.908,72 10 | 4,0;0,5716;0,243;11.106,23 11 | 4,5;0,6651;0,230;12.347,45 12 | 5,0;0,9983;0,077;18.421,76 13 | 5,5;0,1004;0,081;13.551,78 14 | 6,0;0,8433;0,621;14.827,12 15 | 6,5;0,0067;0,116;14.305,56 16 | 7,0;0,8238;0,161;10.908,72 17 | 7,5;0,3952;0,042;11.106,23 18 | 8,0;0,6452;0,112;12.347,45 19 | 8,5;0,8480;0,383;18.421,76 20 | 9,0;0,1986;0,557;13.551,78 21 | 9,5;0,9114;0,667;14.827,12 22 | 10,0;0,7693;0,566;14.305,56 23 | 10,5;0,5009;0,488;10.908,72 24 | 11,0;0,2110;0,010;11.106,23 25 | 11,5;0,9227;0,497;12.347,45 26 | 12,0;0,0461;0,264;18.421,76 27 | 12,5;0,2177;0,220;13.551,78 28 | 13,0;0,9554;0,944;14.827,12 29 | 13,5;0,6130;0,242;14.305,56 30 | -------------------------------------------------------------------------------- /student_questions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Questions during course\n", 8 | "\n", 9 | "## Lecture 1\n", 10 | "1. Does Python have Double object type?\n", 11 | "\n", 12 | " Answer: Python's float type has double precision. NumPy has options for higher percision." 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [] 21 | } 22 | ], 23 | "metadata": { 24 | "kernelspec": { 25 | "display_name": "Python 3", 26 | "language": "python", 27 | "name": "python3" 28 | }, 29 | "language_info": { 30 | "codemirror_mode": { 31 | "name": "ipython", 32 | "version": 3 33 | }, 34 | "file_extension": ".py", 35 | "mimetype": "text/x-python", 36 | "name": "python", 37 | "nbconvert_exporter": "python", 38 | "pygments_lexer": "ipython3", 39 | "version": "3.8.1" 40 | } 41 | }, 42 | "nbformat": 4, 43 | "nbformat_minor": 2 44 | } 45 | -------------------------------------------------------------------------------- /scientific_figures.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#
Scientific Figures\n", 8 | "\n", 9 | "- General Figure Making Advice\n", 10 | " - [Ten Simple Rules for Better Figures (PLoS)](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1003833)\n", 11 | "\n", 12 | " \n", 13 | "- Colorblindness\n", 14 | " - [Wong, Bang. \"Points of view: Color blindness.\" Nature (2011) 441.](https://www.nature.com/articles/nmeth.1618#citeas)\n", 15 | " - [Colorbrewer (for pallete suggestions)](https://colorbrewer2.org)" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "Ideas:\n", 23 | " - Find a figure that gives examples of possible plots\n", 24 | " - Talk about the components that go into making a good plot (e.g. ticks, legend, lables)" 25 | ] 26 | } 27 | ], 28 | "metadata": { 29 | "kernelspec": { 30 | "display_name": "Python 3 (ipykernel)", 31 | "language": "python", 32 | "name": "python3" 33 | }, 34 | "language_info": { 35 | "codemirror_mode": { 36 | "name": "ipython", 37 | "version": 3 38 | }, 39 | "file_extension": ".py", 40 | "mimetype": "text/x-python", 41 | "name": "python", 42 | "nbconvert_exporter": "python", 43 | "pygments_lexer": "ipython3", 44 | "version": "3.8.10" 45 | } 46 | }, 47 | "nbformat": 4, 48 | "nbformat_minor": 2 49 | } 50 | -------------------------------------------------------------------------------- /etiquette_and_practices.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#
Online Lecture Etiquette\n", 8 | " \n", 9 | "1. Keep your microphone off\n", 10 | "2. Keep your camera off\n", 11 | "3. **Exception** - when you ask a question\n", 12 | "4. Use the \"raise hand\" tool\n", 13 | "\n", 14 | "5. Find a quite room where you can be alone (if possible)\n", 15 | " \n", 16 | "- Stay focus - don't off-topic web surf during the lectures\n", 17 | "- Be self disciplined" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "#
Good Practice at Home" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "1. Backup your harddrive(s) (e.g. before installing software)\n", 32 | "2. Use a cloud (e.g. Google Drive, GitHub, GitLab, Dropbox)\n", 33 | "3. For [conda](https://docs.conda.io/projects/conda/en/latest/#) users - create environments for specific installations (e.g. jupyter notebook)" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [] 42 | } 43 | ], 44 | "metadata": { 45 | "kernelspec": { 46 | "display_name": "Python 3", 47 | "language": "python", 48 | "name": "python3" 49 | }, 50 | "language_info": { 51 | "codemirror_mode": { 52 | "name": "ipython", 53 | "version": 3 54 | }, 55 | "file_extension": ".py", 56 | "mimetype": "text/x-python", 57 | "name": "python", 58 | "nbconvert_exporter": "python", 59 | "pygments_lexer": "ipython3", 60 | "version": "3.8.1" 61 | } 62 | }, 63 | "nbformat": 4, 64 | "nbformat_minor": 2 65 | } 66 | -------------------------------------------------------------------------------- /jupyter_notebooks_intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Jupyter Notebooks\n", 8 | "\n", 9 | "### Cells\n", 10 | "\n", 11 | "When you are editing a cell in Jupyter notebook, you need to re-run the cell by pressing **` + `**. This will allow changes you made to be available to other cells.\n", 12 | "\n", 13 | "### Common Jupyter operations\n", 14 | "\n", 15 | "#### Inserting and removing cells\n", 16 | "\n", 17 | "- Use the \"plus sign\" icon to insert a cell below the currently selected cell\n", 18 | "- Use \"Insert\" -> \"Insert Cell Above\" from the menu to insert above\n", 19 | "\n", 20 | "#### Clear the output of all cells\n", 21 | "\n", 22 | "- Use \"Kernel\" -> \"Restart\" from the menu to restart the kernel\n", 23 | " - A kernel is a \"computational engine\" (a fundamental program) that executes a code that you write\n", 24 | " - click on \"clear all outputs & restart\" to have all the output cleared\n", 25 | "\n", 26 | "#### Save your notebook file locally\n", 27 | "\n", 28 | "- Clear the output of all cells\n", 29 | "- Use \"File\" -> \"Download as\" -> \"IPython Notebook (.ipynb)\"\n", 30 | "***" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [] 39 | } 40 | ], 41 | "metadata": { 42 | "kernelspec": { 43 | "display_name": "Python 3 (ipykernel)", 44 | "language": "python", 45 | "name": "python3" 46 | }, 47 | "language_info": { 48 | "codemirror_mode": { 49 | "name": "ipython", 50 | "version": 3 51 | }, 52 | "file_extension": ".py", 53 | "mimetype": "text/x-python", 54 | "name": "python", 55 | "nbconvert_exporter": "python", 56 | "pygments_lexer": "ipython3", 57 | "version": "3.9.7" 58 | } 59 | }, 60 | "nbformat": 4, 61 | "nbformat_minor": 2 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Scientific Programming with Python 2 | 3 | Course material for given at University of Applied Science Bonn-Rhein-Sieg. 4 | 5 | This course’s goal is to introduce students to the Python3 programming language with a scientific mindset. Basic programming concepts (e.g. list, dictionaries, conditions, functions) will be covered, with specialized libraries focused upon that are used within the scientific community (e.g. matplotlib, numpy, scipy). Students will also be introduced to Jupyter notebooks, Integrated Development Environments (IDE), and writing unit tests. The basic ideas behind good scholarship (i.e. wissenschaftliche arbeit) will also be discussed. 6 | 7 | Python is increasingly one of the most important programming languages that is used (TIOBE ranked #3, IEEE’s Spectrum ranked #1). Due to its ease of use, extensive libraries and readability, researchers from diverse fields have made it their “go-to” programing language. For example, researchers use Python to create customized workflow for simulations; to analyze experiment- and simulation-generated data; and to create professional data plots. The course presents the foundation of Python, with a focus on its scientific application. It will cover the following concepts: 8 | 9 | - Programming basic concepts 10 | - Jupyter notebooks, Google Colaboratory 11 | - Python IDE (e.g. PyCharm, Sublime) 12 | - Creating custom functions and personal libraries 13 | - Calling and using external libraries 14 | - Popular scientific community-based libraries (e.g. Statistics, Pandas, Matplotlib, Numpy) 15 | - Writing command-line programs with input flags 16 | - Using unit tests to improve code development 17 | 18 | Scholarship topics will include: 19 | - Workflows, backups, version control 20 | - Reproducibility 21 | - International Units 22 | - Use of constants 23 | - Regression, extrapolation, parameter optimization 24 | - Keeping It Simple and Smart (K.I.S.S.) 25 | - Citations and giving credit 26 | 27 | This work is licensed under a 28 | [Creative Commons Attribution-ShareAlike 4.0 International License][cc-by-sa]. 29 | 30 | [![CC BY-SA 4.0][cc-by-sa-image]][cc-by-sa] 31 | 32 | [cc-by-sa]: http://creativecommons.org/licenses/by-sa/4.0/ 33 | [cc-by-sa-image]: https://licensebuttons.net/l/by-sa/4.0/88x31.png 34 | [cc-by-sa-shield]: https://img.shields.io/badge/License-CC%20BY--SA%204.0-lightgrey.svg 35 | -------------------------------------------------------------------------------- /function_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "#!/usr/bin/env python3\n", 10 | "\n", 11 | "\n", 12 | "def ask_for_input():\n", 13 | " adj_1 = input('Adjective: ')\n", 14 | " adj_2 = input('Adjective: ')\n", 15 | " noun_1 = input('Noun: ')\n", 16 | " noun_2 = input('Noun: ')\n", 17 | " adj_3 = input('Adjective: ')\n", 18 | " pl_noun_1 = input('Plural Noun: ')\n", 19 | " game = input('Game: ')\n", 20 | " pl_noun_2 = input('Plural Noun: ')\n", 21 | " verb_1 = input('Verb ending in -ing: ')\n", 22 | " verb_2 = input('Verb ending in -ing: ')\n", 23 | " print()\n", 24 | "\n", 25 | " return (adj_1, adj_2, noun_1, noun_2, adj_3, pl_noun_1, game, pl_noun_2, verb_1, verb_2)\n", 26 | "\n", 27 | "\n", 28 | "# Assign variables\n", 29 | "adj_1 = ''\n", 30 | "adj_2 = ''\n", 31 | "noun_1 = ''\n", 32 | "noun_2 = ''\n", 33 | "adj_3 = ''\n", 34 | "pl_Noun_1 = ''\n", 35 | "game = ''\n", 36 | "pl_Noun_2 = ''\n", 37 | "verb_1 = ''\n", 38 | "verb_2 = ''\n", 39 | "\n", 40 | "# Main part of program\n", 41 | "print()\n", 42 | "print('Let\\'s play Mad Libs')\n", 43 | "print('Please fill in the following information.')\n", 44 | "print()\n", 45 | "\n", 46 | "adj_1, adj_2, noun_1, noun_2, adj_3, pl_noun_1, game, pl_noun_2, verb_1, verb_2 = ask_for_input()\n", 47 | "\n", 48 | "print('A vacation is when you take a trip to some', adj_1, 'place with your', adj_2, 'family.')\n", 49 | "print('Usually you go to some place that is near a/an', noun_1, 'or up on a/an', noun_2, '.')\n", 50 | "print('A good vacation place is one where you can ride', pl_noun_1, 'or play', game)\n", 51 | "print('or go hunting for', pl_noun_2, '. I like to spend my time', verb_1, 'or', verb_2, '.')\n", 52 | "print()" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [] 61 | } 62 | ], 63 | "metadata": { 64 | "kernelspec": { 65 | "display_name": "Python 3", 66 | "language": "python", 67 | "name": "python3" 68 | }, 69 | "language_info": { 70 | "codemirror_mode": { 71 | "name": "ipython", 72 | "version": 3 73 | }, 74 | "file_extension": ".py", 75 | "mimetype": "text/x-python", 76 | "name": "python", 77 | "nbconvert_exporter": "python", 78 | "pygments_lexer": "ipython3", 79 | "version": "3.8.1" 80 | } 81 | }, 82 | "nbformat": 4, 83 | "nbformat_minor": 2 84 | } 85 | -------------------------------------------------------------------------------- /statistics_simple.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## The Statistics Library\n", 8 | "- Relaively Simple (compared to numpy or scipy)\n", 9 | " - low number of other library dependencies (i.e. more \"usable\" by the community)\n", 10 | "- Relaively Slow (compared to numpy) - use with smaller data sets\n", 11 | "- More precise (compared to numpy) - when high precision is important" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## Mean, median, standard deviation and variance\n", 19 | "- Measures of the center in a numerical data\n", 20 | " - Mean (i.e. average): can be influenced by several outliers\n", 21 | " - Median: the middle value of sorted data (less influenced by outliers)\n", 22 | "- Standard Deviation: a measure of the data's uncertainty\n", 23 | "- Variance: a measure of the data's spread" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import matplotlib.pyplot as plt\n", 33 | "import statistics" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "#### 3 Data sets \n", 41 | "- They have the same mean value\n", 42 | "- They have different median, standard deviation and variance\n", 43 | "- Asssumption: these values have 2 (e.g. 65.) or 3 (i.e. 110.) sigfigs" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "data_1 = [65, 75, 73, 50, 60, 64, 69, 62, 67, 85]\n", 53 | "data_2 = [85, 79, 57, 39, 45, 71, 67, 87, 91, 49]\n", 54 | "data_3 = [43, 51, 53, 110, 50, 48, 87, 69, 68, 91]" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "plt.figure()\n", 64 | "plt.xlim(0, 9)\n", 65 | "plt.ylim(30, 120)\n", 66 | "\n", 67 | "plt.plot(data_1, marker='.', markersize=10)\n", 68 | "plt.show()" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "https://matplotlib.org/3.2.1/api/markers_api.html" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "plt.figure()\n", 85 | "plt.xlim(0, 9)\n", 86 | "plt.ylim(30, 120)\n", 87 | "\n", 88 | "plt.plot(data_2)\n", 89 | "plt.show()" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "plt.figure()\n", 99 | "plt.xlim(0, 9)\n", 100 | "plt.ylim(30, 120)\n", 101 | "\n", 102 | "plt.plot(data_3)\n", 103 | "plt.show()" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "---\n", 111 | "## Calculate some common statistics (and show on plot)" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "### Data Set 1" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": {}, 125 | "outputs": [], 126 | "source": [ 127 | "data_1.sort()\n", 128 | "data_1" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": null, 134 | "metadata": {}, 135 | "outputs": [], 136 | "source": [ 137 | "print(f'Mean: {statistics.mean(data_1)}')\n", 138 | "print(f'Median: {statistics.median(data_1)}')\n", 139 | "print(f'StDev: {statistics.stdev(data_1)}')\n", 140 | "print(f'Variance: {statistics.variance(data_1)}')" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "Mean: read\n", 148 | "\n", 149 | "Median: green" 150 | ] 151 | }, 152 | { 153 | "cell_type": "code", 154 | "execution_count": null, 155 | "metadata": {}, 156 | "outputs": [], 157 | "source": [ 158 | "plt.figure()\n", 159 | "plt.xlim(0, 9)\n", 160 | "plt.ylim(30, 120)\n", 161 | "\n", 162 | "plt.axhline(y=67, color='red')\n", 163 | "plt.axhline(y=66, color='green')\n", 164 | "\n", 165 | "plt.plot(data_1, marker='.', markersize=10)\n", 166 | "plt.show()" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": {}, 172 | "source": [ 173 | "### Data Set 2" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": null, 179 | "metadata": {}, 180 | "outputs": [], 181 | "source": [ 182 | "print(f'Mean: {statistics.mean(data_2)}')\n", 183 | "print(f'Median: {statistics.median(data_2)}')\n", 184 | "print(f'StDev: {statistics.stdev(data_2)}')\n", 185 | "print(f'Variance: {statistics.variance(data_2)}')" 186 | ] 187 | }, 188 | { 189 | "cell_type": "code", 190 | "execution_count": null, 191 | "metadata": {}, 192 | "outputs": [], 193 | "source": [ 194 | "plt.figure()\n", 195 | "plt.xlim(0, 9)\n", 196 | "plt.ylim(30, 120)\n", 197 | "\n", 198 | "plt.axhline(y=67, color='red')\n", 199 | "plt.axhline(y=69, color='green')\n", 200 | "\n", 201 | "plt.plot(data_2, marker='.', markersize=10)\n", 202 | "plt.show()" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "metadata": {}, 208 | "source": [ 209 | "### Data Set 3" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": null, 215 | "metadata": {}, 216 | "outputs": [], 217 | "source": [ 218 | "print(f'Mean: {statistics.mean(data_3)}')\n", 219 | "print(f'Median: {statistics.median(data_3)}')\n", 220 | "print(f'StDev: {statistics.stdev(data_3)}')\n", 221 | "print(f'Variance: {statistics.variance(data_3)}')" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": null, 227 | "metadata": {}, 228 | "outputs": [], 229 | "source": [ 230 | "plt.figure()\n", 231 | "plt.xlim(0, 9)\n", 232 | "plt.ylim(30, 120)\n", 233 | "\n", 234 | "plt.axhline(y=67, color='red')\n", 235 | "plt.axhline(y=60, color='green')\n", 236 | "\n", 237 | "plt.plot(data_3, marker='.', markersize=10)\n", 238 | "plt.show()" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": {}, 244 | "source": [ 245 | "## How might the above code been done better?\n", 246 | "\n", 247 | "- reduce possible inclusion of errors" 248 | ] 249 | }, 250 | { 251 | "cell_type": "code", 252 | "execution_count": null, 253 | "metadata": {}, 254 | "outputs": [], 255 | "source": [ 256 | "def do_statistics(working_data=None):\n", 257 | " print(f'Mean: {statistics.mean(working_data)}')\n", 258 | " print(f'Median: {statistics.median(working_data)}')\n", 259 | " print(f'StDev: {statistics.stdev(working_data)}')\n", 260 | " print(f'Variance: {statistics.variance(working_data)}')\n", 261 | "\n", 262 | "do_statistics(data_1)" 263 | ] 264 | }, 265 | { 266 | "cell_type": "markdown", 267 | "metadata": {}, 268 | "source": [ 269 | "---\n", 270 | "Source: https://www.siyavula.com/read/maths/grade-11/statistics/11-statistics-04" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": {}, 277 | "outputs": [], 278 | "source": [] 279 | } 280 | ], 281 | "metadata": { 282 | "kernelspec": { 283 | "display_name": "Python 3 (ipykernel)", 284 | "language": "python", 285 | "name": "python3" 286 | }, 287 | "language_info": { 288 | "codemirror_mode": { 289 | "name": "ipython", 290 | "version": 3 291 | }, 292 | "file_extension": ".py", 293 | "mimetype": "text/x-python", 294 | "name": "python", 295 | "nbconvert_exporter": "python", 296 | "pygments_lexer": "ipython3", 297 | "version": "3.8.10" 298 | } 299 | }, 300 | "nbformat": 4, 301 | "nbformat_minor": 2 302 | } 303 | -------------------------------------------------------------------------------- /expressions_types_variables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
\n", 8 | "\n", 9 | "#
Scientific Programming in Python\n", 10 | "##
Karl N. Kirschner
Bonn-Rhein-Sieg University of Applied Sciences
Sankt Augustin, Germany\n", 11 | "\n", 12 | "#
Expressions, Types and Variables\n", 13 | "\n", 14 | "
" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "## Expressions\n", 22 | "An expression is a command that returns a value. For example:" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "2 + 2" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "abs(-2 - 2)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "
\n", 48 | "\n", 49 | "## Types\n", 50 | "\n", 51 | "Everything in Python is an object and every object in Python has a type. Some of the basic type include:\n", 52 | "\n", 53 | "- `int` (integer: a whole number with no decimal place)\n", 54 | " - `10`\n", 55 | " - `-3`\n", 56 | "- `float` (float: a number that has a decimal place)\n", 57 | " - `7.41`\n", 58 | " - `-0.006`\n", 59 | "- `bool` (boolean: a binary value that is either true or false)\n", 60 | " - `True`\n", 61 | " - `False`\n", 62 | "- `str` (string: a sequence of characters enclosed in single quotes, double quotes and a mixture)\n", 63 | " - `'this is a string using single quotes'`\n", 64 | " - `\"this is a string using double quotes\"`\n", 65 | " - `\"Socrates once said, 'The only true wisdom is in knowing you know nothing.'\"`\n", 66 | "- `NoneType` (a special type representing the absence of a value)\n", 67 | " - `None`" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "type(4)" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "type(2.1)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "type(3 > 4)" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "metadata": {}, 101 | "outputs": [], 102 | "source": [ 103 | "print(3 > 4)" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "type([1, 2, 3, 4])" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [ 121 | "type(range(3, 9, 1))" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "Tip: using the `type` will help you figure out many problems in Python, especially when using functions. " 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "
\n", 136 | "\n", 137 | "## Variables\n", 138 | "A variable is assigned an object. You can modify that assignment (i.e., the variable's value) at any time.\n", 139 | "\n", 140 | "Example - Encode the following statement: \"my_variable is assigned the object [1.1, 1.2, 1.3]\":\n", 141 | "\n", 142 | "`my_variable = [1.1, 1.2, 1.3]`\n", 143 | "\n", 144 | "#### Naming rules\n", 145 | "- Variables can only contain letters (e.g., A, B, C, a, b, c), numbers (e.g., 1, 2, 3) and underscores (i.e., _ ).\n", 146 | "\n", 147 | "\n", 148 | "- Variable names can start with\n", 149 | " - a letter (e.g., `a_name`)\n", 150 | " - an underscore (e.g., `_name`)\n", 151 | " - these should be reserved for \"private\"/\"internal\" variables that are not meant to be used outside of the current code. For illustration, `from module import *` will not import any `_name` variables). However, you can do it directly: `from module import _name`.\n", 152 | "\n", 153 | "\n", 154 | "- Variable names cannot start with\n", 155 | " - a number (e.g., `1name`).\n", 156 | " \n", 157 | " \n", 158 | "- Spaces are not allowed in variable names (e.g., `student name`), so we use underscores instead of spaces (e.g., `student_name`).\n", 159 | "\n", 160 | "\n", 161 | "- pothole (a.k.a. snake) case is prefered in Python (e.g., `weather_data`).\n", 162 | "\n", 163 | "- Camal case (e.g., `weatherData`) is used less often.\n", 164 | "\n", 165 | "\n", 166 | "- Variable names should be descriptive, without being too long. For example, a code concening motorcycle wheels - `mc_wheels` is better than just `wheels` and the extended `number_of_wheels_on_a_motorycle`." 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "newton_quote = \"Isaac Newton once said, 'If I have seen further, it is by standing on the shoulders of GIANTS.'\"\n", 176 | "\n", 177 | "print(newton_quote)" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "- You cannot use Python keywords (e.g., `lambda`, `type`) as variable names." 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": null, 190 | "metadata": {}, 191 | "outputs": [], 192 | "source": [ 193 | "import keyword\n", 194 | "keyword.kwlist" 195 | ] 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "metadata": {}, 200 | "source": [ 201 | "
\n", 202 | "\n", 203 | "## Python's Comprehension\n", 204 | "\n", 205 | "Comprehensions are a Pythonic way to create containers with content on a single line (via for loops).\n", 206 | "\n", 207 | "Possible types:\n", 208 | "- List: `['a', 'b', 'c', 'c', 'c']`\n", 209 | "\n", 210 | "- Set: `{'a', 'b', 'c'}`\n", 211 | " - list with unique items\n", 212 | " \n", 213 | "- Dictionary: `{'a': 1, 'b': 2, 'c': 3}`\n", 214 | " - {key: value}" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "#### Lists\n", 222 | "\n", 223 | "The regular approach:" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "execution_count": null, 229 | "metadata": {}, 230 | "outputs": [], 231 | "source": [ 232 | "my_list = []\n", 233 | "\n", 234 | "for number in range(1, 5, 1):\n", 235 | " my_list.append(number)\n", 236 | "\n", 237 | "my_list" 238 | ] 239 | }, 240 | { 241 | "cell_type": "markdown", 242 | "metadata": {}, 243 | "source": [ 244 | "The comprehension approach:" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "[number for number in range(1, 5, 1)]" 254 | ] 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "Can also do this with strings:" 261 | ] 262 | }, 263 | { 264 | "cell_type": "code", 265 | "execution_count": null, 266 | "metadata": {}, 267 | "outputs": [], 268 | "source": [ 269 | "[letter for letter in 'Learning this is super.']" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": {}, 275 | "source": [ 276 | "One can even generate nested lists:" 277 | ] 278 | }, 279 | { 280 | "cell_type": "code", 281 | "execution_count": null, 282 | "metadata": {}, 283 | "outputs": [], 284 | "source": [ 285 | "[[number_1 + number_2 for number_2 in range(20, 25, 1)] for number_1 in range(1, 5, 1)]" 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "metadata": {}, 291 | "source": [ 292 | "#### Sets" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": null, 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [ 301 | "{letter for letter in 'Learning this is super.'} ## non-duplicated letters (e.g., 's')" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": {}, 307 | "source": [ 308 | "#### Dictionaries" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": null, 314 | "metadata": {}, 315 | "outputs": [], 316 | "source": [ 317 | "{number: number**2 for number in range(1, 5, 1)}" 318 | ] 319 | } 320 | ], 321 | "metadata": { 322 | "kernelspec": { 323 | "display_name": "Python 3 (ipykernel)", 324 | "language": "python", 325 | "name": "python3" 326 | }, 327 | "language_info": { 328 | "codemirror_mode": { 329 | "name": "ipython", 330 | "version": 3 331 | }, 332 | "file_extension": ".py", 333 | "mimetype": "text/x-python", 334 | "name": "python", 335 | "nbconvert_exporter": "python", 336 | "pygments_lexer": "ipython3", 337 | "version": "3.13.2" 338 | } 339 | }, 340 | "nbformat": 4, 341 | "nbformat_minor": 4 342 | } 343 | -------------------------------------------------------------------------------- /operations.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#
Basic Operators\n", 8 | "***" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "Class exercise:\n", 16 | " Using a calculator (i.e. not via coding), calculate:\n", 17 | " \n", 18 | " 2 + 3 * 4 / 5\n", 19 | " \n", 20 | " Write your answer in the the 'chat box'\n", 21 | " \n", 22 | "


















\n", 23 | "


















" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "Answer = 4.4 (we will see how this done below)\n", 31 | "\n", 32 | "---\n", 33 | "# Operators\n", 34 | "\n", 35 | "In Python, there are different types of **operators** (special symbols) that operate on different values. Some of the basic operators include:\n", 36 | "\n", 37 | "- arithmetic operators\n", 38 | " - **`+`** (addition)\n", 39 | " - **`-`** (subtraction)\n", 40 | " - **`*`** (multiplication)\n", 41 | " - **`/`** (division)\n", 42 | " - __`**`__ (exponent)\n", 43 | "\n", 44 | "\n", 45 | "- assignment operators\n", 46 | " - **`=`** (assign a value)\n", 47 | " - **`+=`** (add and re-assign; increment)\n", 48 | " - **`-=`** (subtract and re-assign; decrement)\n", 49 | " - **`*=`** (multiply and re-assign)\n", 50 | "\n", 51 | "\n", 52 | "- comparison operators (return either `True` or `False`; booleans)\n", 53 | " - **`==`** (equal to)\n", 54 | " - **`!=`** (not equal to)\n", 55 | " - **`<`** (less than)\n", 56 | " - **`<=`** (less than or equal to)\n", 57 | " - **`>`** (greater than)\n", 58 | " - **`>=`** (greater than or equal to)" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "---\n", 66 | "## Order of Operation\n", 67 | "\n", 68 | "When multiple operators are used in a single expression, **operator precedence** determines which parts of the expression are evaluated in which order.\n", 69 | "\n", 70 | "Operators with higher precedence are evaluated first.\n", 71 | "\n", 72 | "Operators with the same precedence are evaluated from **left to right**.\n", 73 | "\n", 74 | "Precedence importance ordering:\n", 75 | "1. `()` parentheses, for grouping\n", 76 | "2. `**` exponent\n", 77 | "3. `*`, `/` multiplication and division\n", 78 | "4. `+`, `-` addition and subtraction\n", 79 | "5. `==`, `!=`, `<`, `<=`, `>`, `>=` comparisons\n", 80 | "\n", 81 | "\n", 82 | "#### Additional information:\n", 83 | "\n", 84 | "1. https://docs.python.org/3/reference/expressions.html#operator-precedence\n", 85 | "\n", 86 | "2. https://en.wikipedia.org/wiki/Order_of_operations" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "#### Example 1: 2 + 3 * 4 / 5\n", 94 | "\n", 95 | "> Step 1. $3 * 4 = 12$ (**Notice**: `*` and `/` have the same precedence, but `*` is farthest to the left)\n", 96 | "\n", 97 | "> Step 2. $12 / 5 = 2.2$\n", 98 | "\n", 99 | "> Step 3. $2 + 2.2 = 4.4$\n", 100 | "\n", 101 | "Now, let's see what Python gives:" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "metadata": {}, 108 | "outputs": [], 109 | "source": [ 110 | "equation = 2.0 + 3.0 * 4.0 / 5.0\n", 111 | "\n", 112 | "print(\"2.0 + 3.0 * 4.0 / 5.0 = {0}\".format(equation))" 113 | ] 114 | }, 115 | { 116 | "cell_type": "markdown", 117 | "metadata": {}, 118 | "source": [ 119 | "Next, let's force a specific sequence of actions to occur by using `()`.\n", 120 | "\n", 121 | "#### Example 2: (2 + 3) * 4 / 5" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": null, 127 | "metadata": {}, 128 | "outputs": [], 129 | "source": [ 130 | "equation = (2.0 + 3.0) * 4.0 / 5.0\n", 131 | "\n", 132 | "print(\"(2.0 + 3.0) * 4.0 / 5.0 = {0}\".format(equation))\n", 133 | "\n", 134 | "print('''\n", 135 | " i.e. step 1: 2.0 + 3.0 = 5.0\n", 136 | " step 2: 5.0 * 4.0 = 20.0 since * is further left than /\n", 137 | " step 3: 20.0 / 5.0 = 4.0\n", 138 | " ''')" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "#### Example 3: 2 + 3 * 4 ** 2 / 5" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": null, 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [ 154 | "equation = 2 + 3 * 4 ** 2 / 5\n", 155 | "\n", 156 | "print(\"2 + 3 * 4 ** 2 / 5 = \", equation)\n", 157 | "\n", 158 | "print(\"\"\"\n", 159 | " i.e. 4**2 = 16\n", 160 | " 3*16 = 48\n", 161 | " 48/5 = 9.6\n", 162 | " 2+9.6 = 11.6\n", 163 | " \"\"\")" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "#### Example 4: 2 + (3 * 4) ** 2 / 5" 171 | ] 172 | }, 173 | { 174 | "cell_type": "code", 175 | "execution_count": null, 176 | "metadata": {}, 177 | "outputs": [], 178 | "source": [ 179 | "equation = 2 + (3 * 4) ** 2 / 5\n", 180 | "\n", 181 | "print(\"2 + (3 * 4) ** 2 / 5 = \", equation)\n", 182 | "\n", 183 | "print(\"\"\"\n", 184 | " i.e. 3*4 = 12\n", 185 | " 12**2 = 144\n", 186 | " 144/5 = 28.8\n", 187 | " 2+28.8 = 30.8\n", 188 | " \"\"\")" 189 | ] 190 | }, 191 | { 192 | "cell_type": "markdown", 193 | "metadata": {}, 194 | "source": [ 195 | "**Take-home Message**: Be careful in encoding mathematical equations so that you do introduce and error.\n", 196 | "\n", 197 | "---\n", 198 | "## Increment (by reassigning variable)\n", 199 | "- right-hand-side happens first, and then the left-hand-side\n", 200 | "\n", 201 | "In the following assignment statements\n", 202 | "- evaluation of the right-hand-side is done first, then\n", 203 | "- it is assigned to the variable" 204 | ] 205 | }, 206 | { 207 | "cell_type": "markdown", 208 | "metadata": {}, 209 | "source": [ 210 | "Simple demonstration - counting plants, starting with 1" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "metadata": {}, 217 | "outputs": [], 218 | "source": [ 219 | "planets = 1\n", 220 | "print(planets)" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "Now lets add 1 more to the number of planets:\n", 228 | "- notice how `planets + 1` is computed first\n", 229 | "- then the new value is assigned to the variable `planets`" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "metadata": {}, 236 | "outputs": [], 237 | "source": [ 238 | "planets = planets + 1\n", 239 | "print(planets)" 240 | ] 241 | }, 242 | { 243 | "cell_type": "markdown", 244 | "metadata": {}, 245 | "source": [ 246 | "Alternatively, we can use `+= 1` instead of `planets + 1`:" 247 | ] 248 | }, 249 | { 250 | "cell_type": "code", 251 | "execution_count": null, 252 | "metadata": {}, 253 | "outputs": [], 254 | "source": [ 255 | "\n", 256 | "planets += 1\n", 257 | "print(planets)" 258 | ] 259 | }, 260 | { 261 | "cell_type": "markdown", 262 | "metadata": {}, 263 | "source": [ 264 | "`+=` will increment other numbers too" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "metadata": {}, 271 | "outputs": [], 272 | "source": [ 273 | "planets += 5\n", 274 | "print(planets)" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "---\n", 282 | "## Booleans\n", 283 | "- used through comparison operators (e.g. `<=`)\n", 284 | "\n", 285 | "Demo Scenerio - you have to discover more than 10 planets before you graduate." 286 | ] 287 | }, 288 | { 289 | "cell_type": "code", 290 | "execution_count": null, 291 | "metadata": {}, 292 | "outputs": [], 293 | "source": [ 294 | "total_planets = 10\n", 295 | "print(total_planets < planets)" 296 | ] 297 | }, 298 | { 299 | "cell_type": "markdown", 300 | "metadata": {}, 301 | "source": [ 302 | "### Why could this be interesting?\n", 303 | "- you can create conditions" 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": null, 309 | "metadata": {}, 310 | "outputs": [], 311 | "source": [ 312 | "planets = 0\n", 313 | "\n", 314 | "if (total_planets < planets) == False:\n", 315 | " print('You can not graduate yet - get back to work!')\n", 316 | "else:\n", 317 | " print('Congratulations - it is time to move on!')" 318 | ] 319 | }, 320 | { 321 | "cell_type": "markdown", 322 | "metadata": {}, 323 | "source": [ 324 | "- you can create loops" 325 | ] 326 | }, 327 | { 328 | "cell_type": "code", 329 | "execution_count": null, 330 | "metadata": {}, 331 | "outputs": [], 332 | "source": [ 333 | "planets = 0\n", 334 | "graduating = False\n", 335 | "\n", 336 | "while not graduating:\n", 337 | " if (total_planets < planets) == False:\n", 338 | " print('You can not graduate yet. Number of planets discovered: {0}'.format(planets))\n", 339 | " planets += 1\n", 340 | " else:\n", 341 | " print('Congratulations - it is time to move on!')\n", 342 | " graduating = True" 343 | ] 344 | } 345 | ], 346 | "metadata": { 347 | "kernelspec": { 348 | "display_name": "Python 3 (ipykernel)", 349 | "language": "python", 350 | "name": "python3" 351 | }, 352 | "language_info": { 353 | "codemirror_mode": { 354 | "name": "ipython", 355 | "version": 3 356 | }, 357 | "file_extension": ".py", 358 | "mimetype": "text/x-python", 359 | "name": "python", 360 | "nbconvert_exporter": "python", 361 | "pygments_lexer": "ipython3", 362 | "version": "3.8.17" 363 | } 364 | }, 365 | "nbformat": 4, 366 | "nbformat_minor": 2 367 | } 368 | -------------------------------------------------------------------------------- /csv_library.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "***\n", 8 | "# Reading Data Files\n", 9 | "- Commma Separated Value (CSV) files - a generic text file for data\n", 10 | " - (https://en.wikipedia.org/wiki/Comma-separated_values)\n", 11 | "\n", 12 | "\n", 13 | "- Use the csv standard library - https://docs.python.org/3/library/csv.html\n", 14 | "\n", 15 | "---\n", 16 | "\n", 17 | "The data within a CSV files can be separated by things other than a 'comma':\n", 18 | "\n", 19 | "comma: 1.0 , 2.0 , 3.0\n", 20 | "\n", 21 | "semicolon: 1.0 ; 2.0 ; 3.0\n", 22 | "\n", 23 | "includes quotes (for groupings): 1 , 2 , \"a, b, c\"\n", 24 | "\n", 25 | "---\n", 26 | "\n", 27 | "We will use the following file for reading in some three-dimensional data.\n", 28 | "\n", 29 | "**data_3d.csv** contains the following information:\n", 30 | "- Hearder first line\n", 31 | "- 28 data rows\n", 32 | "- 3 data columns (Time, Exp and Theory)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "import csv" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "## CSV data file acan be found at\n", 51 | "## https://github.com/karlkirschner/2020_Scientific_Programming/blob/master/data_3d.csv\n", 52 | "\n", 53 | "## For Colabs\n", 54 | "\n", 55 | "## In order to upload data\n", 56 | "#from google.colab import files\n", 57 | "#uploaded = files.upload()\n", 58 | "\n", 59 | "## In order to show the plots\n", 60 | "#%matplotlib inline" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "Example of a true comma separated value file" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "## A Jupyter and Linux bash trick for looking into a file\n", 77 | "!head data_3d.csv --lines=10" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "Example of a semicolon separated value file." 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "!head data_3d_semi.csv --lines=10" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "For the cells that follow - we will use the data_3d.csv file." 101 | ] 102 | }, 103 | { 104 | "cell_type": "code", 105 | "execution_count": null, 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "time = []\n", 110 | "exp = []\n", 111 | "sim = []\n", 112 | "\n", 113 | "with open('data_3d.csv') as file:\n", 114 | " read_it = csv.reader(file, delimiter=',')\n", 115 | "\n", 116 | " next(read_it) ## skips header (i.e. the first row)\n", 117 | " \n", 118 | " for row in read_it:\n", 119 | " time.append(float((row[0])))\n", 120 | " exp.append(float(row[1]))\n", 121 | " sim.append(float(row[2]))" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "Now we have created three list that contains floats, giving us our data that we can then do something with!\n", 129 | "\n", 130 | "---\n", 131 | "#### Slicing\n", 132 | "A quick note about getting a slice of data from a list.\n", 133 | "\n", 134 | "Let's say that **a** is a list, then we can get different ranges via:\n", 135 | "\n", 136 | "a (or a[:]) ## a copy of the whole array\n", 137 | "\n", 138 | "a[start:stop] ## items start to stop-1\n", 139 | "\n", 140 | "a[start:] ## items start to end of list\n", 141 | "\n", 142 | "a[:stop] ## items start of list to stop-1\n", 143 | "\n", 144 | "a[item] ## a single item" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [ 153 | "print(time)" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [ 162 | "print(time[:])" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": null, 168 | "metadata": {}, 169 | "outputs": [], 170 | "source": [ 171 | "print(time[5:15])" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "print(time[5:])" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": null, 186 | "metadata": {}, 187 | "outputs": [], 188 | "source": [ 189 | "print(time[:15])" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": null, 195 | "metadata": {}, 196 | "outputs": [], 197 | "source": [ 198 | "print(time[1])" 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "metadata": {}, 204 | "source": [ 205 | "---\n", 206 | "Okay, back to our original focus.\n", 207 | "\n", 208 | "Let's verify that our items are indeed numbers (we will come back to this in a bit)." 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "execution_count": null, 214 | "metadata": {}, 215 | "outputs": [], 216 | "source": [ 217 | "type(time[0])" 218 | ] 219 | }, 220 | { 221 | "cell_type": "markdown", 222 | "metadata": {}, 223 | "source": [ 224 | "We can treat the items within the time list and floats." 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": null, 230 | "metadata": {}, 231 | "outputs": [], 232 | "source": [ 233 | "time[1] - time[0]" 234 | ] 235 | }, 236 | { 237 | "cell_type": "markdown", 238 | "metadata": {}, 239 | "source": [ 240 | "---\n", 241 | "### Okay, so let's demo how we could use this data.\n", 242 | "\n", 243 | "(Again, we take a peak into our future and do some plotting.)" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": null, 249 | "metadata": {}, 250 | "outputs": [], 251 | "source": [ 252 | "import matplotlib.pyplot as plt" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": null, 258 | "metadata": {}, 259 | "outputs": [], 260 | "source": [ 261 | "## For Colabs\n", 262 | "## In order to show the plots\n", 263 | "\n", 264 | "#%matplotlib inline" 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "metadata": {}, 271 | "outputs": [], 272 | "source": [ 273 | "plt.style.use('seaborn-whitegrid')\n", 274 | "plt.figure(figsize=(15,5))\n", 275 | "\n", 276 | "plt.plot(time, exp, linewidth=5, linestyle='solid', label='Experimental')\n", 277 | "plt.plot(time, sim, linewidth=5, linestyle='dashed', label='Simulated')\n", 278 | "\n", 279 | "plt.xlabel('Time (seconds)')\n", 280 | "plt.ylabel('Y-Axis (Unit)')\n", 281 | "plt.title('Experimental and Simulated Results')\n", 282 | "plt.grid(True)\n", 283 | "\n", 284 | "plt.show()" 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": {}, 290 | "source": [ 291 | "Notice that we have gaps in the tick marks for the x-axis.\n", 292 | "\n", 293 | "How can we easily change this for plotting?\n", 294 | "- Read the x-axis data as: **strings** (versus a float as above) and plot again.\n", 295 | "\n", 296 | " ```time.append(str(row[0]))```" 297 | ] 298 | }, 299 | { 300 | "cell_type": "code", 301 | "execution_count": null, 302 | "metadata": {}, 303 | "outputs": [], 304 | "source": [ 305 | "time=[]\n", 306 | "exp=[]\n", 307 | "sim=[]\n", 308 | "\n", 309 | "with open('data_3d.csv') as file:\n", 310 | " read_it = csv.reader(file, delimiter=',')\n", 311 | "\n", 312 | " next(read_it)\n", 313 | " \n", 314 | " for row in read_it:\n", 315 | " time.append(str(row[0]))\n", 316 | " exp.append(float(row[1]))\n", 317 | " sim.append(float(row[2]))" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": null, 323 | "metadata": {}, 324 | "outputs": [], 325 | "source": [ 326 | "type(time[0])" 327 | ] 328 | }, 329 | { 330 | "cell_type": "code", 331 | "execution_count": null, 332 | "metadata": {}, 333 | "outputs": [], 334 | "source": [ 335 | "plt.style.use('seaborn-whitegrid')\n", 336 | "plt.figure(figsize=(15,5))\n", 337 | "\n", 338 | "plt.plot(time, exp, linewidth=5, linestyle='solid', label='Experimental')\n", 339 | "plt.plot(time, sim, linewidth=5, linestyle='dashed', label='Simulated')\n", 340 | "\n", 341 | "plt.xlabel('Time (seconds)')\n", 342 | "plt.ylabel('Y-Axis (Unit)')\n", 343 | "plt.title('Experimental and Simulated Results')\n", 344 | "plt.grid(True)\n", 345 | "plt.show()" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "**Notice**: the x-axis ticks have changed - every data point is now labeled.\n", 353 | "\n", 354 | "**Also notice**: we can no longer treat them a numbers" 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": null, 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "time[1] - time[0]" 364 | ] 365 | }, 366 | { 367 | "cell_type": "code", 368 | "execution_count": null, 369 | "metadata": {}, 370 | "outputs": [], 371 | "source": [ 372 | "float(time[1]) - float(time[0])" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [] 379 | } 380 | ], 381 | "metadata": { 382 | "kernelspec": { 383 | "display_name": "Python 3", 384 | "language": "python", 385 | "name": "python3" 386 | }, 387 | "language_info": { 388 | "codemirror_mode": { 389 | "name": "ipython", 390 | "version": 3 391 | }, 392 | "file_extension": ".py", 393 | "mimetype": "text/x-python", 394 | "name": "python", 395 | "nbconvert_exporter": "python", 396 | "pygments_lexer": "ipython3", 397 | "version": "3.8.1" 398 | } 399 | }, 400 | "nbformat": 4, 401 | "nbformat_minor": 2 402 | } 403 | -------------------------------------------------------------------------------- /tips.csv: -------------------------------------------------------------------------------- 1 | "total_bill","tip","sex","smoker","day","time","size" 2 | 16.99,1.01,"Female","No","Sun","Dinner",2 3 | 10.34,1.66,"Male","No","Sun","Dinner",3 4 | 21.01,3.5,"Male","No","Sun","Dinner",3 5 | 23.68,3.31,"Male","No","Sun","Dinner",2 6 | 24.59,3.61,"Female","No","Sun","Dinner",4 7 | 25.29,4.71,"Male","No","Sun","Dinner",4 8 | 8.77,2,"Male","No","Sun","Dinner",2 9 | 26.88,3.12,"Male","No","Sun","Dinner",4 10 | 15.04,1.96,"Male","No","Sun","Dinner",2 11 | 14.78,3.23,"Male","No","Sun","Dinner",2 12 | 10.27,1.71,"Male","No","Sun","Dinner",2 13 | 35.26,5,"Female","No","Sun","Dinner",4 14 | 15.42,1.57,"Male","No","Sun","Dinner",2 15 | 18.43,3,"Male","No","Sun","Dinner",4 16 | 14.83,3.02,"Female","No","Sun","Dinner",2 17 | 21.58,3.92,"Male","No","Sun","Dinner",2 18 | 10.33,1.67,"Female","No","Sun","Dinner",3 19 | 16.29,3.71,"Male","No","Sun","Dinner",3 20 | 16.97,3.5,"Female","No","Sun","Dinner",3 21 | 20.65,3.35,"Male","No","Sat","Dinner",3 22 | 17.92,4.08,"Male","No","Sat","Dinner",2 23 | 20.29,2.75,"Female","No","Sat","Dinner",2 24 | 15.77,2.23,"Female","No","Sat","Dinner",2 25 | 39.42,7.58,"Male","No","Sat","Dinner",4 26 | 19.82,3.18,"Male","No","Sat","Dinner",2 27 | 17.81,2.34,"Male","No","Sat","Dinner",4 28 | 13.37,2,"Male","No","Sat","Dinner",2 29 | 12.69,2,"Male","No","Sat","Dinner",2 30 | 21.7,4.3,"Male","No","Sat","Dinner",2 31 | 19.65,3,"Female","No","Sat","Dinner",2 32 | 9.55,1.45,"Male","No","Sat","Dinner",2 33 | 18.35,2.5,"Male","No","Sat","Dinner",4 34 | 15.06,3,"Female","No","Sat","Dinner",2 35 | 20.69,2.45,"Female","No","Sat","Dinner",4 36 | 17.78,3.27,"Male","No","Sat","Dinner",2 37 | 24.06,3.6,"Male","No","Sat","Dinner",3 38 | 16.31,2,"Male","No","Sat","Dinner",3 39 | 16.93,3.07,"Female","No","Sat","Dinner",3 40 | 18.69,2.31,"Male","No","Sat","Dinner",3 41 | 31.27,5,"Male","No","Sat","Dinner",3 42 | 16.04,2.24,"Male","No","Sat","Dinner",3 43 | 17.46,2.54,"Male","No","Sun","Dinner",2 44 | 13.94,3.06,"Male","No","Sun","Dinner",2 45 | 9.68,1.32,"Male","No","Sun","Dinner",2 46 | 30.4,5.6,"Male","No","Sun","Dinner",4 47 | 18.29,3,"Male","No","Sun","Dinner",2 48 | 22.23,5,"Male","No","Sun","Dinner",2 49 | 32.4,6,"Male","No","Sun","Dinner",4 50 | 28.55,2.05,"Male","No","Sun","Dinner",3 51 | 18.04,3,"Male","No","Sun","Dinner",2 52 | 12.54,2.5,"Male","No","Sun","Dinner",2 53 | 10.29,2.6,"Female","No","Sun","Dinner",2 54 | 34.81,5.2,"Female","No","Sun","Dinner",4 55 | 9.94,1.56,"Male","No","Sun","Dinner",2 56 | 25.56,4.34,"Male","No","Sun","Dinner",4 57 | 19.49,3.51,"Male","No","Sun","Dinner",2 58 | 38.01,3,"Male","Yes","Sat","Dinner",4 59 | 26.41,1.5,"Female","No","Sat","Dinner",2 60 | 11.24,1.76,"Male","Yes","Sat","Dinner",2 61 | 48.27,6.73,"Male","No","Sat","Dinner",4 62 | 20.29,3.21,"Male","Yes","Sat","Dinner",2 63 | 13.81,2,"Male","Yes","Sat","Dinner",2 64 | 11.02,1.98,"Male","Yes","Sat","Dinner",2 65 | 18.29,3.76,"Male","Yes","Sat","Dinner",4 66 | 17.59,2.64,"Male","No","Sat","Dinner",3 67 | 20.08,3.15,"Male","No","Sat","Dinner",3 68 | 16.45,2.47,"Female","No","Sat","Dinner",2 69 | 3.07,1,"Female","Yes","Sat","Dinner",1 70 | 20.23,2.01,"Male","No","Sat","Dinner",2 71 | 15.01,2.09,"Male","Yes","Sat","Dinner",2 72 | 12.02,1.97,"Male","No","Sat","Dinner",2 73 | 17.07,3,"Female","No","Sat","Dinner",3 74 | 26.86,3.14,"Female","Yes","Sat","Dinner",2 75 | 25.28,5,"Female","Yes","Sat","Dinner",2 76 | 14.73,2.2,"Female","No","Sat","Dinner",2 77 | 10.51,1.25,"Male","No","Sat","Dinner",2 78 | 17.92,3.08,"Male","Yes","Sat","Dinner",2 79 | 27.2,4,"Male","No","Thur","Lunch",4 80 | 22.76,3,"Male","No","Thur","Lunch",2 81 | 17.29,2.71,"Male","No","Thur","Lunch",2 82 | 19.44,3,"Male","Yes","Thur","Lunch",2 83 | 16.66,3.4,"Male","No","Thur","Lunch",2 84 | 10.07,1.83,"Female","No","Thur","Lunch",1 85 | 32.68,5,"Male","Yes","Thur","Lunch",2 86 | 15.98,2.03,"Male","No","Thur","Lunch",2 87 | 34.83,5.17,"Female","No","Thur","Lunch",4 88 | 13.03,2,"Male","No","Thur","Lunch",2 89 | 18.28,4,"Male","No","Thur","Lunch",2 90 | 24.71,5.85,"Male","No","Thur","Lunch",2 91 | 21.16,3,"Male","No","Thur","Lunch",2 92 | 28.97,3,"Male","Yes","Fri","Dinner",2 93 | 22.49,3.5,"Male","No","Fri","Dinner",2 94 | 5.75,1,"Female","Yes","Fri","Dinner",2 95 | 16.32,4.3,"Female","Yes","Fri","Dinner",2 96 | 22.75,3.25,"Female","No","Fri","Dinner",2 97 | 40.17,4.73,"Male","Yes","Fri","Dinner",4 98 | 27.28,4,"Male","Yes","Fri","Dinner",2 99 | 12.03,1.5,"Male","Yes","Fri","Dinner",2 100 | 21.01,3,"Male","Yes","Fri","Dinner",2 101 | 12.46,1.5,"Male","No","Fri","Dinner",2 102 | 11.35,2.5,"Female","Yes","Fri","Dinner",2 103 | 15.38,3,"Female","Yes","Fri","Dinner",2 104 | 44.3,2.5,"Female","Yes","Sat","Dinner",3 105 | 22.42,3.48,"Female","Yes","Sat","Dinner",2 106 | 20.92,4.08,"Female","No","Sat","Dinner",2 107 | 15.36,1.64,"Male","Yes","Sat","Dinner",2 108 | 20.49,4.06,"Male","Yes","Sat","Dinner",2 109 | 25.21,4.29,"Male","Yes","Sat","Dinner",2 110 | 18.24,3.76,"Male","No","Sat","Dinner",2 111 | 14.31,4,"Female","Yes","Sat","Dinner",2 112 | 14,3,"Male","No","Sat","Dinner",2 113 | 7.25,1,"Female","No","Sat","Dinner",1 114 | 38.07,4,"Male","No","Sun","Dinner",3 115 | 23.95,2.55,"Male","No","Sun","Dinner",2 116 | 25.71,4,"Female","No","Sun","Dinner",3 117 | 17.31,3.5,"Female","No","Sun","Dinner",2 118 | 29.93,5.07,"Male","No","Sun","Dinner",4 119 | 10.65,1.5,"Female","No","Thur","Lunch",2 120 | 12.43,1.8,"Female","No","Thur","Lunch",2 121 | 24.08,2.92,"Female","No","Thur","Lunch",4 122 | 11.69,2.31,"Male","No","Thur","Lunch",2 123 | 13.42,1.68,"Female","No","Thur","Lunch",2 124 | 14.26,2.5,"Male","No","Thur","Lunch",2 125 | 15.95,2,"Male","No","Thur","Lunch",2 126 | 12.48,2.52,"Female","No","Thur","Lunch",2 127 | 29.8,4.2,"Female","No","Thur","Lunch",6 128 | 8.52,1.48,"Male","No","Thur","Lunch",2 129 | 14.52,2,"Female","No","Thur","Lunch",2 130 | 11.38,2,"Female","No","Thur","Lunch",2 131 | 22.82,2.18,"Male","No","Thur","Lunch",3 132 | 19.08,1.5,"Male","No","Thur","Lunch",2 133 | 20.27,2.83,"Female","No","Thur","Lunch",2 134 | 11.17,1.5,"Female","No","Thur","Lunch",2 135 | 12.26,2,"Female","No","Thur","Lunch",2 136 | 18.26,3.25,"Female","No","Thur","Lunch",2 137 | 8.51,1.25,"Female","No","Thur","Lunch",2 138 | 10.33,2,"Female","No","Thur","Lunch",2 139 | 14.15,2,"Female","No","Thur","Lunch",2 140 | 16,2,"Male","Yes","Thur","Lunch",2 141 | 13.16,2.75,"Female","No","Thur","Lunch",2 142 | 17.47,3.5,"Female","No","Thur","Lunch",2 143 | 34.3,6.7,"Male","No","Thur","Lunch",6 144 | 41.19,5,"Male","No","Thur","Lunch",5 145 | 27.05,5,"Female","No","Thur","Lunch",6 146 | 16.43,2.3,"Female","No","Thur","Lunch",2 147 | 8.35,1.5,"Female","No","Thur","Lunch",2 148 | 18.64,1.36,"Female","No","Thur","Lunch",3 149 | 11.87,1.63,"Female","No","Thur","Lunch",2 150 | 9.78,1.73,"Male","No","Thur","Lunch",2 151 | 7.51,2,"Male","No","Thur","Lunch",2 152 | 14.07,2.5,"Male","No","Sun","Dinner",2 153 | 13.13,2,"Male","No","Sun","Dinner",2 154 | 17.26,2.74,"Male","No","Sun","Dinner",3 155 | 24.55,2,"Male","No","Sun","Dinner",4 156 | 19.77,2,"Male","No","Sun","Dinner",4 157 | 29.85,5.14,"Female","No","Sun","Dinner",5 158 | 48.17,5,"Male","No","Sun","Dinner",6 159 | 25,3.75,"Female","No","Sun","Dinner",4 160 | 13.39,2.61,"Female","No","Sun","Dinner",2 161 | 16.49,2,"Male","No","Sun","Dinner",4 162 | 21.5,3.5,"Male","No","Sun","Dinner",4 163 | 12.66,2.5,"Male","No","Sun","Dinner",2 164 | 16.21,2,"Female","No","Sun","Dinner",3 165 | 13.81,2,"Male","No","Sun","Dinner",2 166 | 17.51,3,"Female","Yes","Sun","Dinner",2 167 | 24.52,3.48,"Male","No","Sun","Dinner",3 168 | 20.76,2.24,"Male","No","Sun","Dinner",2 169 | 31.71,4.5,"Male","No","Sun","Dinner",4 170 | 10.59,1.61,"Female","Yes","Sat","Dinner",2 171 | 10.63,2,"Female","Yes","Sat","Dinner",2 172 | 50.81,10,"Male","Yes","Sat","Dinner",3 173 | 15.81,3.16,"Male","Yes","Sat","Dinner",2 174 | 7.25,5.15,"Male","Yes","Sun","Dinner",2 175 | 31.85,3.18,"Male","Yes","Sun","Dinner",2 176 | 16.82,4,"Male","Yes","Sun","Dinner",2 177 | 32.9,3.11,"Male","Yes","Sun","Dinner",2 178 | 17.89,2,"Male","Yes","Sun","Dinner",2 179 | 14.48,2,"Male","Yes","Sun","Dinner",2 180 | 9.6,4,"Female","Yes","Sun","Dinner",2 181 | 34.63,3.55,"Male","Yes","Sun","Dinner",2 182 | 34.65,3.68,"Male","Yes","Sun","Dinner",4 183 | 23.33,5.65,"Male","Yes","Sun","Dinner",2 184 | 45.35,3.5,"Male","Yes","Sun","Dinner",3 185 | 23.17,6.5,"Male","Yes","Sun","Dinner",4 186 | 40.55,3,"Male","Yes","Sun","Dinner",2 187 | 20.69,5,"Male","No","Sun","Dinner",5 188 | 20.9,3.5,"Female","Yes","Sun","Dinner",3 189 | 30.46,2,"Male","Yes","Sun","Dinner",5 190 | 18.15,3.5,"Female","Yes","Sun","Dinner",3 191 | 23.1,4,"Male","Yes","Sun","Dinner",3 192 | 15.69,1.5,"Male","Yes","Sun","Dinner",2 193 | 19.81,4.19,"Female","Yes","Thur","Lunch",2 194 | 28.44,2.56,"Male","Yes","Thur","Lunch",2 195 | 15.48,2.02,"Male","Yes","Thur","Lunch",2 196 | 16.58,4,"Male","Yes","Thur","Lunch",2 197 | 7.56,1.44,"Male","No","Thur","Lunch",2 198 | 10.34,2,"Male","Yes","Thur","Lunch",2 199 | 43.11,5,"Female","Yes","Thur","Lunch",4 200 | 13,2,"Female","Yes","Thur","Lunch",2 201 | 13.51,2,"Male","Yes","Thur","Lunch",2 202 | 18.71,4,"Male","Yes","Thur","Lunch",3 203 | 12.74,2.01,"Female","Yes","Thur","Lunch",2 204 | 13,2,"Female","Yes","Thur","Lunch",2 205 | 16.4,2.5,"Female","Yes","Thur","Lunch",2 206 | 20.53,4,"Male","Yes","Thur","Lunch",4 207 | 16.47,3.23,"Female","Yes","Thur","Lunch",3 208 | 26.59,3.41,"Male","Yes","Sat","Dinner",3 209 | 38.73,3,"Male","Yes","Sat","Dinner",4 210 | 24.27,2.03,"Male","Yes","Sat","Dinner",2 211 | 12.76,2.23,"Female","Yes","Sat","Dinner",2 212 | 30.06,2,"Male","Yes","Sat","Dinner",3 213 | 25.89,5.16,"Male","Yes","Sat","Dinner",4 214 | 48.33,9,"Male","No","Sat","Dinner",4 215 | 13.27,2.5,"Female","Yes","Sat","Dinner",2 216 | 28.17,6.5,"Female","Yes","Sat","Dinner",3 217 | 12.9,1.1,"Female","Yes","Sat","Dinner",2 218 | 28.15,3,"Male","Yes","Sat","Dinner",5 219 | 11.59,1.5,"Male","Yes","Sat","Dinner",2 220 | 7.74,1.44,"Male","Yes","Sat","Dinner",2 221 | 30.14,3.09,"Female","Yes","Sat","Dinner",4 222 | 12.16,2.2,"Male","Yes","Fri","Lunch",2 223 | 13.42,3.48,"Female","Yes","Fri","Lunch",2 224 | 8.58,1.92,"Male","Yes","Fri","Lunch",1 225 | 15.98,3,"Female","No","Fri","Lunch",3 226 | 13.42,1.58,"Male","Yes","Fri","Lunch",2 227 | 16.27,2.5,"Female","Yes","Fri","Lunch",2 228 | 10.09,2,"Female","Yes","Fri","Lunch",2 229 | 20.45,3,"Male","No","Sat","Dinner",4 230 | 13.28,2.72,"Male","No","Sat","Dinner",2 231 | 22.12,2.88,"Female","Yes","Sat","Dinner",2 232 | 24.01,2,"Male","Yes","Sat","Dinner",4 233 | 15.69,3,"Male","Yes","Sat","Dinner",3 234 | 11.61,3.39,"Male","No","Sat","Dinner",2 235 | 10.77,1.47,"Male","No","Sat","Dinner",2 236 | 15.53,3,"Male","Yes","Sat","Dinner",2 237 | 10.07,1.25,"Male","No","Sat","Dinner",2 238 | 12.6,1,"Male","Yes","Sat","Dinner",2 239 | 32.83,1.17,"Male","Yes","Sat","Dinner",2 240 | 35.83,4.67,"Female","No","Sat","Dinner",3 241 | 29.03,5.92,"Male","No","Sat","Dinner",3 242 | 27.18,2,"Female","Yes","Sat","Dinner",2 243 | 22.67,2,"Male","Yes","Sat","Dinner",2 244 | 17.82,1.75,"Male","No","Sat","Dinner",2 245 | 18.78,3,"Female","No","Thur","Dinner",2 246 | -------------------------------------------------------------------------------- /colaboratory_introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "colab_type": "text", 7 | "id": "5fCEDCU_qrC0" 8 | }, 9 | "source": [ 10 | "

\"Colaboratory

\n", 11 | "\n", 12 | "

Welcome to Colaboratory!

\n", 13 | "\n", 14 | "\n", 15 | "Colaboratory is a free Jupyter notebook environment that requires no setup and runs entirely in the cloud.\n", 16 | "\n", 17 | "With Colaboratory you can write and execute code, save and share your analyses, and access powerful computing resources, all for free from your browser." 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "metadata": { 24 | "colab": { 25 | "height": 420 26 | }, 27 | "colab_type": "code", 28 | "id": "xitplqMNk_Hc", 29 | "outputId": "ed4f60d2-878d-4056-c438-352dac39a112" 30 | }, 31 | "outputs": [], 32 | "source": [ 33 | "#@title Introducing Colaboratory { display-mode: \"form\" }\n", 34 | "#@markdown This 3-minute video gives an overview of the key features of Colaboratory:\n", 35 | "from IPython.display import YouTubeVideo\n", 36 | "YouTubeVideo('inN8seMm7UI', width=600, height=400)" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": { 42 | "colab_type": "text", 43 | "id": "GJBs_flRovLc" 44 | }, 45 | "source": [ 46 | "## Getting Started\n", 47 | "\n", 48 | "The document you are reading is a [Jupyter notebook](https://jupyter.org/), hosted in Colaboratory. It is not a static page, but an interactive environment that lets you write and execute code in Python and other languages.\n", 49 | "\n", 50 | "For example, here is a **code cell** with a short Python script that computes a value, stores it in a variable, and prints the result:" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "colab": { 58 | "height": 35 59 | }, 60 | "colab_type": "code", 61 | "id": "gJr_9dXGpJ05", 62 | "outputId": "5626194c-e802-4293-942d-2908885c3c1f" 63 | }, 64 | "outputs": [], 65 | "source": [ 66 | "seconds_in_a_day = 24 * 60 * 60\n", 67 | "seconds_in_a_day" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": { 73 | "colab_type": "text", 74 | "id": "2fhs6GZ4qFMx" 75 | }, 76 | "source": [ 77 | "To execute the code in the above cell, select it with a click and then either press the play button to the left of the code, or use the keyboard shortcut \"Command/Ctrl+Enter\".\n", 78 | "\n", 79 | "All cells modify the same global state, so variables that you define by executing a cell can be used in other cells:" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": { 86 | "colab": { 87 | "height": 35 88 | }, 89 | "colab_type": "code", 90 | "id": "-gE-Ez1qtyIA", 91 | "outputId": "8d2e4259-4682-4e19-b683-7b9087f28820" 92 | }, 93 | "outputs": [], 94 | "source": [ 95 | "seconds_in_a_week = 7 * seconds_in_a_day\n", 96 | "seconds_in_a_week" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": { 102 | "colab_type": "text", 103 | "id": "lSrWNr3MuFUS" 104 | }, 105 | "source": [ 106 | "For more information about working with Colaboratory notebooks, see [Overview of Colaboratory](/notebooks/basic_features_overview.ipynb).\n" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": { 112 | "colab_type": "text", 113 | "id": "JyG45Qk3qQLS" 114 | }, 115 | "source": [ 116 | "---\n", 117 | "# Cells\n", 118 | "A notebook is a list of cells. Cells contain either explanatory text or executable code and its output. Click a cell to select it." 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": { 124 | "colab_type": "text", 125 | "id": "KR921S_OQSHG" 126 | }, 127 | "source": [ 128 | "## Code cells\n", 129 | "Below is a **code cell**. Once the toolbar button indicates CONNECTED, click in the cell to select it and execute the contents in the following ways:\n", 130 | "\n", 131 | "* Click the **Play icon** in the left gutter of the cell;\n", 132 | "* Type **Cmd/Ctrl+Enter** to run the cell in place;\n", 133 | "* Type **Shift+Enter** to run the cell and move focus to the next cell (adding one if none exists); or\n", 134 | "* Type **Alt+Enter** to run the cell and insert a new code cell immediately below it.\n", 135 | "\n", 136 | "There are additional options for running some or all cells in the **Runtime** menu.\n" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": null, 142 | "metadata": { 143 | "cellView": "both", 144 | "colab": { 145 | "base_uri": "https://localhost:8080/", 146 | "height": 34 147 | }, 148 | "colab_type": "code", 149 | "executionInfo": { 150 | "elapsed": 809, 151 | "status": "ok", 152 | "timestamp": 1585470408839, 153 | "user": { 154 | "displayName": "", 155 | "photoUrl": "", 156 | "userId": "" 157 | }, 158 | "user_tz": -120 159 | }, 160 | "id": "WUtu4316QSHL", 161 | "outputId": "3446364b-328c-4383-a2e7-0b4a2e4fb6d5" 162 | }, 163 | "outputs": [], 164 | "source": [ 165 | "a = 13\n", 166 | "a" 167 | ] 168 | }, 169 | { 170 | "cell_type": "markdown", 171 | "metadata": { 172 | "colab_type": "text", 173 | "id": "Id6tDF1HQSHD" 174 | }, 175 | "source": [ 176 | "## Text cells\n", 177 | "This is a **text cell**. You can **double-click** to edit this cell. Text cells\n", 178 | "use markdown syntax. To learn more, see our [markdown\n", 179 | "guide](/notebooks/markdown_guide.ipynb).\n", 180 | "\n", 181 | "You can also add math to text cells using [LaTeX](http://www.latex-project.org/)\n", 182 | "to be rendered by [MathJax](https://www.mathjax.org). Just place the statement\n", 183 | "within a pair of **\\$** signs. For example `$\\sqrt{3x-1}+(1+x)^2$` becomes\n", 184 | "$\\sqrt{3x-1}+(1+x)^2.$\n" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": { 190 | "colab_type": "text", 191 | "id": "7bqjkGKwQSHW" 192 | }, 193 | "source": [ 194 | "## Adding and moving cells\n", 195 | "You can add new cells by using the **+ CODE** and **+ TEXT** buttons that show when you hover between cells. These buttons are also in the toolbar above the notebook where they can be used to add a cell below the currently selected cell.\n", 196 | "\n", 197 | "You can move a cell by selecting it and clicking **Cell Up** or **Cell Down** in the top toolbar. \n", 198 | "\n", 199 | "Consecutive cells can be selected by \"lasso selection\" by dragging from outside one cell and through the group. Non-adjacent cells can be selected concurrently by clicking one and then holding down Ctrl while clicking another. Similarly, using Shift instead of Ctrl will select all intermediate cells." 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": { 205 | "colab_type": "text", 206 | "id": "aro-UJgUQSH1" 207 | }, 208 | "source": [ 209 | "# Integration with Drive\n", 210 | "\n", 211 | "Colaboratory is integrated with Google Drive. It allows you to share, comment, and collaborate on the same document with multiple people:\n", 212 | "\n", 213 | "* The **SHARE** button (top-right of the toolbar) allows you to share the notebook and control permissions set on it.\n", 214 | "\n", 215 | "* **File->Make a Copy** creates a copy of the notebook in Drive.\n", 216 | "\n", 217 | "* **File->Save** saves the File to Drive. **File->Save and checkpoint** pins the version so it doesn't get deleted from the revision history. \n", 218 | "\n", 219 | "* **File->Revision history** shows the notebook's revision history. " 220 | ] 221 | }, 222 | { 223 | "cell_type": "markdown", 224 | "metadata": { 225 | "colab_type": "text", 226 | "id": "4hfV37gxpP_c" 227 | }, 228 | "source": [ 229 | "## Commenting on a cell\n", 230 | "You can comment on a Colaboratory notebook like you would on a Google Document. Comments are attached to cells, and are displayed next to the cell they refer to. If you have **comment-only** permissions, you will see a comment button on the top right of the cell when you hover over it.\n", 231 | "\n", 232 | "If you have edit or comment permissions you can comment on a cell in one of three ways: \n", 233 | "\n", 234 | "1. Select a cell and click the comment button in the toolbar above the top-right corner of the cell.\n", 235 | "1. Right click a text cell and select **Add a comment** from the context menu.\n", 236 | "3. Use the shortcut **Ctrl+Shift+M** to add a comment to the currently selected cell. \n", 237 | "\n", 238 | "You can resolve and reply to comments, and you can target comments to specific collaborators by typing *+[email address]* (e.g., `+user@domain.com`). Addressed collaborators will be emailed. \n", 239 | "\n", 240 | "The Comment button in the top-right corner of the page shows all comments attached to the notebook." 241 | ] 242 | }, 243 | { 244 | "cell_type": "markdown", 245 | "metadata": { 246 | "colab_type": "text", 247 | "id": "-Rh3-Vt9Nev9" 248 | }, 249 | "source": [ 250 | "## More Resources\n", 251 | "- [Guide to Markdown](/notebooks/markdown_guide.ipynb)\n", 252 | "- Colaboratory is built on top of [Jupyter Notebook](https://jupyter.org/)." 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": { 258 | "colab_type": "text", 259 | "id": "8HFGaSr3eYKE" 260 | }, 261 | "source": [ 262 | "---\n", 263 | "**Original Sources:**\n", 264 | "1. https://colab.research.google.com/notebooks/welcome.ipynb\n", 265 | "2. https://colab.research.google.com/notebooks/basic_features_overview.ipynb" 266 | ] 267 | } 268 | ], 269 | "metadata": { 270 | "colab": { 271 | "collapsed_sections": [], 272 | "name": "colaboratory_introduction", 273 | "provenance": [ 274 | { 275 | "file_id": "/v2/external/notebooks/welcome.ipynb", 276 | "timestamp": 1585471612038 277 | } 278 | ], 279 | "toc_visible": true 280 | }, 281 | "kernelspec": { 282 | "display_name": "Python 3", 283 | "language": "python", 284 | "name": "python3" 285 | }, 286 | "language_info": { 287 | "codemirror_mode": { 288 | "name": "ipython", 289 | "version": 3 290 | }, 291 | "file_extension": ".py", 292 | "mimetype": "text/x-python", 293 | "name": "python", 294 | "nbconvert_exporter": "python", 295 | "pygments_lexer": "ipython3", 296 | "version": "3.8.1" 297 | } 298 | }, 299 | "nbformat": 4, 300 | "nbformat_minor": 1 301 | } 302 | -------------------------------------------------------------------------------- /containers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "**Lecture is based on:**\n", 8 | "\n", 9 | "-[learning-python3.ipynb] https://gist.github.com/kenjyco/69eeb503125035f21a9d \n", 10 | "-[Introduction to Python] http://introtopython.org/lists_tuples.html#Tuples\n", 11 | "***" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": {}, 17 | "source": [ 18 | "## Containers (i.e. collections)\n", 19 | "\n", 20 | "Containers are objects that group other objects (i.e. they collect things).\n", 21 | "\n", 22 | "- **str** - string: \n", 23 | " - immutable\n", 24 | " - indexed by integers\n", 25 | " - items are stored in the order they were added\n", 26 | " - can use +, *, +=, and *= operators\n", 27 | "\n", 28 | "\n", 29 | "- **list** - list:\n", 30 | " - mutable\n", 31 | " - indexed by integers\n", 32 | " - items are stored in the order they were added\n", 33 | " - can use +, *, +=, and *= operators\n", 34 | " > ['Star Wars', 1, \"Empire\", 2, 'Jedi', '3', True, 1, 1]\n", 35 | "\n", 36 | "- **tuple** - tuple:\n", 37 | " - immutable\n", 38 | " - indexed by integers\n", 39 | " - items are stored in the order they were added\n", 40 | " - can use +, *, +=, and *= operators\n", 41 | " - faster than mutable lists\n", 42 | " > ('Star Wars', 1, \"Empire\", 2, 'Jedi', '3', True, 1, 1)\n", 43 | "\n", 44 | "- **dict** - dictionary:\n", 45 | " - mutable\n", 46 | " - key-value pairs are indexed by immutable keys\n", 47 | " - items are NOT stored in the order they were added\n", 48 | " - use dictionaries as an alternative to switch functions\n", 49 | " > {'year': 1992, 'western': 'Unforgiven', 'scifi': ['Aliens3', 'Seedpeople']}\n", 50 | "\n", 51 | "- **set** - set:\n", 52 | " - mutable\n", 53 | " - not indexed at all\n", 54 | " - items are NOT stored in the order they were added\n", 55 | " - can only contain immutable objects\n", 56 | " - does NOT contain duplicate objects\n", 57 | " > {'Star Wars', 1, \"Empire\", 2, 'Jedi', '3', True}\n", 58 | "\n", 59 | "**Note**:\n", 60 | "- When defining lists, tuples, or sets, use commas (,) to separate the individual items\n", 61 | "- When defining dicts, use a colon (:) to separate keys from values and commas (,) to separate the key-value pairs.\n", 62 | "***" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "### Strings\n", 70 | "\n", 71 | "- immutable\n", 72 | "- indexed by integers\n", 73 | "- items are stored in the order they were added\n", 74 | "- can use +, *, +=, and *= operators" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "my_string = 'Mom'\n", 84 | "\n", 85 | "print(my_string[0])\n", 86 | "print(my_string[1])\n", 87 | "print(my_string[-1])\n", 88 | "len(my_string)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "execution_count": null, 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "## an example for immutable and its error\n", 98 | "my_string[1] = 'u'" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "***\n", 106 | "### Lists\n", 107 | "- mutable\n", 108 | "- indexed by integers\n", 109 | "- items are stored in the order they were added\n", 110 | "- can use +, *, +=, and *= operators" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "## Create a list\n", 120 | "movies = ['Star Wars', 'X-men', 'Forest Gump']\n", 121 | "\n", 122 | "movies = ['Star Wars',\n", 123 | " 'X-men',\n", 124 | " 'Forest Gump']\n", 125 | "\n", 126 | "print(movies)\n", 127 | "print()\n", 128 | "print('First item: {0}'.format(movies[1]))\n", 129 | "print('Last item: {0}'.format(movies[-1]))\n", 130 | "print('Number of movies: {0}'.format(len(movies)))" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [ 139 | "## mutable\n", 140 | "movies.append('Blade Runner') # add to the end\n", 141 | "print(movies)\n", 142 | "\n", 143 | "movies.pop() # remove last item and print\n", 144 | "print(movies)\n", 145 | "\n", 146 | "movies.remove('X-men') # remove specific item\n", 147 | "print(movies)\n", 148 | "\n", 149 | "movies.insert(1, 'Gattaca') # add to position 1\n", 150 | "print(movies)\n", 151 | "\n", 152 | "movies.extend(['Solo', '2001']) # add multiple items to end\n", 153 | "print(movies)\n", 154 | "\n", 155 | "movies[3] = 'Blade Runner' # replace position 3 (i.e. the 4th movie)\n", 156 | "print(movies)" 157 | ] 158 | }, 159 | { 160 | "cell_type": "code", 161 | "execution_count": null, 162 | "metadata": {}, 163 | "outputs": [], 164 | "source": [ 165 | "## sorting\n", 166 | "x = sorted(['dogs', 'cats', 'dragons', 'Chicago',\n", 167 | " 'Bonn', 'ants', 'mice'])\n", 168 | "print(x)\n", 169 | "\n", 170 | "y = sorted([0, 10, 1, 3.6, 7, 5, 2, -3])\n", 171 | "print(y)" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": {}, 178 | "outputs": [], 179 | "source": [ 180 | "## max, min, sum and abs\n", 181 | "print( min([0, 10, 1, 3.6, 7, 5, 2, -3]) )\n", 182 | "print( max([0, 10, 1, 3.6, 7, 5, 2, -3]) )\n", 183 | "print( sum([0, 10, 1, 3.6, 7, 5, 2, -3]) )" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "***\n", 191 | "### Dictionaries\n", 192 | "Dictionaries allow you to connect pieces of knowledge together using a **key: value** pairing" 193 | ] 194 | }, 195 | { 196 | "cell_type": "code", 197 | "execution_count": null, 198 | "metadata": {}, 199 | "outputs": [], 200 | "source": [ 201 | "movies = {} # creates an empty dictionary that can later be added to\n", 202 | "\n", 203 | "# create a filled list\n", 204 | "movies = {'scifi': 'Star Wars',\n", 205 | " 'romance': 'Titanic',\n", 206 | " 'western': 'Unforgiven'}\n", 207 | "\n", 208 | "print(movies)\n", 209 | "print()\n", 210 | "print(movies['western'])\n", 211 | "print()\n", 212 | "print(movies['western'], movies['romance'])" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": null, 218 | "metadata": {}, 219 | "outputs": [], 220 | "source": [ 221 | "## Add a new key:value pair\n", 222 | "movies['horror'] = '28 Days Later'\n", 223 | "print(movies)\n", 224 | "print()\n", 225 | "\n", 226 | "movies.update( {'comedies' : 'The Big Lebowski'} )\n", 227 | "print(movies)\n", 228 | "print()" 229 | ] 230 | }, 231 | { 232 | "cell_type": "code", 233 | "execution_count": null, 234 | "metadata": {}, 235 | "outputs": [], 236 | "source": [ 237 | "## Modify a value\n", 238 | "movies['horror'] = 'The Evil Dead'\n", 239 | "print(movies)\n", 240 | "print()\n", 241 | "\n", 242 | "movies.update(romance = 'love actually')\n", 243 | "print(movies)\n", 244 | "print()" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": null, 250 | "metadata": {}, 251 | "outputs": [], 252 | "source": [ 253 | "## Delete a key:value pair\n", 254 | "del movies['romance'] ## or\n", 255 | "\n", 256 | "#movies.pop('romance')\n", 257 | "\n", 258 | "print(movies)" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "metadata": {}, 265 | "outputs": [], 266 | "source": [ 267 | "## Modify a key\n", 268 | "\n", 269 | "## Copy and the delete\n", 270 | "movies['sci_fi'] = movies['scifi']\n", 271 | "del movies['scifi']\n", 272 | "print(movies)" 273 | ] 274 | }, 275 | { 276 | "cell_type": "code", 277 | "execution_count": null, 278 | "metadata": {}, 279 | "outputs": [], 280 | "source": [ 281 | "## Add two dictionaries together\n", 282 | "movies_his = {'scifi': 'Star Wars', 'western': 'Unforgiven'}\n", 283 | "movies_her = {'horror': 'The Evil Dead', 'comedies': 'The Big Lebowski'}\n", 284 | "\n", 285 | "movies_his.update(movies_her)\n", 286 | "print(movies_his)" 287 | ] 288 | }, 289 | { 290 | "cell_type": "code", 291 | "execution_count": null, 292 | "metadata": {}, 293 | "outputs": [], 294 | "source": [ 295 | "## Values as lists\n", 296 | "movies = {'scifi': ['Star Wars'], 'romance': ['Titanic'],\n", 297 | " 'western': ['Unforgiven']}\n", 298 | "\n", 299 | "# Add a value to a key\n", 300 | "movies['scifi'].append('Blade Runner')\n", 301 | "print(movies)\n", 302 | "\n", 303 | "# Remove last value of a key\n", 304 | "movies['scifi'].pop(-1)\n", 305 | "print(movies)" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": null, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "## type functions\n", 315 | "type(movies)" 316 | ] 317 | }, 318 | { 319 | "cell_type": "markdown", 320 | "metadata": {}, 321 | "source": [ 322 | "***\n", 323 | "### Dictionaries replace switch functions\n", 324 | "\n", 325 | "Python does not have a switch function like the following bash example:" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "metadata": {}, 332 | "outputs": [], 333 | "source": [ 334 | "%%bash\n", 335 | "\n", 336 | "printf 'Which do you want?\\n'\n", 337 | "ARGUMENT=1\n", 338 | "\n", 339 | "case $ARGUMENT in\n", 340 | " 0)\n", 341 | " echo \"zero\"\n", 342 | " ;;\n", 343 | " 1)\n", 344 | " echo \"one\"\n", 345 | " ;;\n", 346 | " 2)\n", 347 | " echo \"two\"\n", 348 | " ;; \n", 349 | " *)\n", 350 | " echo \"nothing\"\n", 351 | " ;;\n", 352 | "esac" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": null, 358 | "metadata": {}, 359 | "outputs": [], 360 | "source": [ 361 | "def numbers_to_strings(argument):\n", 362 | " #Define the dictionary:\n", 363 | " switcher = {\n", 364 | " 0: \"zero\",\n", 365 | " 1: \"one\",\n", 366 | " 2: \"two\",\n", 367 | " }\n", 368 | " return switcher.get(argument, \"nothing\")\n", 369 | "\n", 370 | "print('Which do you want?')\n", 371 | "\n", 372 | "numbers_to_strings(1)" 373 | ] 374 | }, 375 | { 376 | "cell_type": "markdown", 377 | "metadata": {}, 378 | "source": [ 379 | "***\n", 380 | "Link to [Program Files Notebook](program_file.ipynb)" 381 | ] 382 | }, 383 | { 384 | "cell_type": "code", 385 | "execution_count": null, 386 | "metadata": {}, 387 | "outputs": [], 388 | "source": [] 389 | } 390 | ], 391 | "metadata": { 392 | "kernelspec": { 393 | "display_name": "Python 3", 394 | "language": "python", 395 | "name": "python3" 396 | }, 397 | "language_info": { 398 | "codemirror_mode": { 399 | "name": "ipython", 400 | "version": 3 401 | }, 402 | "file_extension": ".py", 403 | "mimetype": "text/x-python", 404 | "name": "python", 405 | "nbconvert_exporter": "python", 406 | "pygments_lexer": "ipython3", 407 | "version": "3.5.3" 408 | } 409 | }, 410 | "nbformat": 4, 411 | "nbformat_minor": 2 412 | } 413 | -------------------------------------------------------------------------------- /citation_lecture.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "#
Scientific Programming with Python
\n", 8 | "\n", 9 | "##
Citations
\n", 10 | "\n", 11 | "###
Standing on the shoulders of giants and how to avoiding plagiarism
\n", 12 | "\n", 13 | "\n", 14 | "###
Karl N. Kirschner
Department of Computer Science,
University of Applied Sciences Bonn-Rhein-Sieg
Sankt Augustin, Germany
\n", 15 | "\n", 16 | "
\n", 17 | "\n", 18 | "#### Why spend time doing proper citations?\n", 19 | "\n", 20 | "1. Provides **credit** for hard work done\n", 21 | "\n", 22 | "2. Enables **reproducibility**\n", 23 | "\n", 24 | "3. Enables **fact-checking**\n", 25 | "\n", 26 | "4. Demonstrates and builds your **credibility as a scholar**\n", 27 | "\n", 28 | "5. Enables you to **avoid plagiarism**\n", 29 | "\n", 30 | "6. Establishes the work to be authoritative – being scholarly – **strengthens your arguments/finding**\n", 31 | "\n", 32 | "\n", 33 | "#### When do you need to cite?\n", 34 | "\n", 35 | "When you obtain knowledge/information from\n", 36 | "\n", 37 | "1. journals, books, theses, etc.\n", 38 | "2. creditable websites (e.g. Pandas, Numpy)\n", 39 | "3. private communications (e.g. professor, mentor)\n", 40 | "\n", 41 | "This includes when you use\n", 42 | "\n", 43 | "1. existing datasets\n", 44 | "2. other people's code (e.g. libraries, open-source, github)\n", 45 | "3. direct and indirect quotes\n", 46 | "4. original figures, plots, tables, etc.\n", 47 | " - this can occur when presenting state-of-the-art or in the Results section of your thesis (e.g. \"Figure was obtained from reference 1.\")\n", 48 | "5. Modified images, plots, tables that are pulled from other sources (e.g. \"The original unmodified figure can be found in reference 1.\")\n", 49 | "\n", 50 | "#### Formatting\n", 51 | "\n", 52 | "1. Citation styles within the body of the text\n", 53 | "\n", 54 | "`Promiscuity underlies the concept of drug repurposing [8-13].`\n", 55 | "\n", 56 | "2. Reference/Citation formats in the reference section\n", 57 | "\n", 58 | "`1. T.T. Ashburn and K.B. Thor, \"Drug repositioning: identifying and developing new uses for existing drugs.\" Nat. Rev. Drug Discov., 2004, 3, 673-683`\n", 59 | "\n", 60 | "\n", 61 | "#### Possible (and often) Pitfalls\n", 62 | "1. Not citing the original source\n", 63 | "2. Propagating errors created by other’s carelessness (e.g. not reading the original source; double checking the author's name, page numbers, volumes, etc.)\n", 64 | "3. Inconsistent formats (e.g. author initials vs. full given name; abbreviated journal names vs. full journal names)\n", 65 | "4. Accents on special characters (e.g. ä, ö, ü)\n", 66 | "\n", 67 | "\n", 68 | "#### Additional Information\n", 69 | "\n", 70 | "IEEE Citation Style\n", 71 | "- common for computer scientists and engineers\n", 72 | "- http://pitt.libguides.com/citationhelp/ieee\n", 73 | "\n", 74 | "\n", 75 | "#### Examples\n", 76 | "\n", 77 | "The following two examples will demonstrate\n", 78 | "1. Why citing knowledge is important by providing an example text with (Example 1) and without (Example 2) citation.\n", 79 | "2. What type of information should be cited and how the citation is done and how the references are formatted.\n", 80 | "\n", 81 | "
" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "##
Example 1
\n", 89 | "\n", 90 | "##
Thesis Title
\n", 91 | "##
Jane Doe
June 1, 2022
\n", 92 | "\n", 93 | "#### Introduction\n", 94 | "The goal of this thesis is perform and evaluate a molecular dynamics (MD) simulation of liquid water. The simulated observable recorded was the liquid's density that describes how molecularly compact a chemical system is (i.e. how close the molecules are to one another). Experimentally, the density for pure water was measured to be 0.995659 $\\text{g}/\\text{cm}^3$ at 30.0 °C.\n", 95 | "\n", 96 | "Et cetera ...\n", 97 | "\n", 98 | "#### Methodology\n", 99 | "\n", 100 | "The MD simulations were performed using the AMBER software package (v. 12). The liquid-phase simulation contained 500 TIP3P water molecules. Constant volume production simulations were ran for 110 ns. Langevin dynamics with a collision frequency (i.e. gamma_ln) of 1.0 ps$^{-1}$ was used for regulating the temperature at 30.0 °C.\n", 101 | "\n", 102 | "The resulting data were analyzed using the Python3 programming language. The following libraries were specifically Numpy (v. 1.22) and Pandas (v. 1.4.2) in the data analysis. \n", 103 | "\n", 104 | "\n", 105 | "Et cetera ...\n", 106 | "\n", 107 | "---" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "##### Questions\n", 115 | "\n", 116 | "1. Why should we trust the information present in the writing?\n", 117 | "\n", 118 | "\n", 119 | "2. Where does the experimental density value come from?\n", 120 | "\n", 121 | "\n", 122 | "3. Who and where was the AMBER software developed?\n", 123 | "\n", 124 | "\n", 125 | "4. What exactly is a TIP3P water molecule?\n", 126 | "\n", 127 | "\n", 128 | "5. Why is the value of 1.0 ps$^{-1}$ good for the collision frequency (a parameter that is set in the modelling)?\n", 129 | "\n", 130 | "\n", 131 | "6. Who develped Python?\n", 132 | "\n", 133 | "\n", 134 | "7. For the Python libraries, where can one \n", 135 | " - download their code,\n", 136 | " - learn about what functions are available,\n", 137 | " - learn about how to use those functions,\n", 138 | " - learn about how equations are emplemented, and\n", 139 | " - learn about any of the hidden parameters settings?\n", 140 | "\n", 141 | "
\n", 142 | "









" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "##
Example 2
\n", 150 | "\n", 151 | "\n", 152 | "##
Thesis Title
\n", 153 | "##
Jane Doe
June 1, 2022
\n", 154 | "\n", 155 | "#### Introduction\n", 156 | "The goal of this thesis is perform and evaluate a molecular dynamics (MD) simulation of liquid water. The simulated observable recorded was the liquid's density that describes how molecularly compact a chemical system is (i.e. how close the molecules are to one another). Experimentally, the density for pure water was measured to be 0.995659 $\\text{g}/\\text{cm}^3$ at 30.0 °C [1].\n", 157 | "\n", 158 | "Et cetera ...\n", 159 | "\n", 160 | "#### Methodology\n", 161 | "\n", 162 | "The MD simulations were performed using the AMBER software package [2, 3] (v. 12). The liquid-phase simulation contained 500 TIP3P [4, 5] water molecules. Constant volume production simulations were ran for 110 ns. Langevin dynamics [6] with a collision frequency (i.e. gamma_ln) of 1.0 ps$^{-1}$ [7] was used for regulating the temperature at 30.0 °C.\n", 163 | "\n", 164 | "The resulting data were analyzed using the Python3 [8, 9] programming language. The following libraries were specifically Numpy [10, 11] (v. 1.22) and Pandas [12, 13] (v. 1.4.2) in the data analysis. \n", 165 | "\n", 166 | "\n", 167 | "Et cetera ...\n", 168 | "\n", 169 | "
\n", 170 | "\n", 171 | "#### References\n", 172 | "\n", 173 | "[1] M. Vedamuthu, S. Singh, and G.W. Robinson, \"Properties of liquid water: origin of the density anomalies.\" J. Phys. Chem., 1994, 98, 2222-2230.\n", 174 | "\n", 175 | "[2] D.A. Case, H.M. Aktulga, K. Belfon, I.Y. Ben-Shalom, J.T. Berryman, S.R. Brozell, D.S. Cerutti, T.E. Cheatham, III, G.A. Cisneros, V.W.D. Cruzeiro, T.A. Darden, R.E. Duke, G. Giambasu, M.K. Gilson, H. Gohlke, A.W. Goetz, R. Harris, S. Izadi, S.A. Izmailov, K. Kasavajhala, M.C. Kaymak, E. King, A. Kovalenko, T. Kurtzman, T.S. Lee, S. LeGrand, P. Li, C. Lin, J. Liu, T. Luchko, R. Luo, M. Machado, V. Man, M. Manathunga, K.M. Merz, Y. Miao, O. Mikhailovskii, G. Monard, H. Nguyen, K.A. O'Hearn, A. Onufriev, F. Pan, S. Pantano, R. Qi, A. Rahnamoun, D.R. Roe, A. Roitberg, C. Sagui, S. Schott-Verdugo, A. Shajan, J. Shen, C.L. Simmerling, N.R. Skrynnikov, J. Smith, J. Swails, R.C. Walker, J Wang, J. Wang, H. Wei, R.M. Wolf, X. Wu, Y. Xiong, Y. Xue, D.M. York, S. Zhao, and P.A. Kollman (2022), Amber 2022, University of California, San Francisco. (https://ambermd.org/index.php)\n", 176 | "\n", 177 | "[3] R. Salomon-Ferrer, D.A. Case, R.C. Walker, \"An overview of the Amber biomolecular simulation package.\" WIREs Comput. Mol. Sci., 2013, 3, 198-210. \n", 178 | "\n", 179 | "[4] W.L. Jorgensen, J. Chandrasekhar, J.D. Madura, R.W. Impey, and M.L. Klein, \"Comparison of simple potential functions for simulating liquid water.\" J. Chem. Phys., 1983, 79, 926-935.\n", 180 | "\n", 181 | "[5] P. Mark and L. Nilsson, \"Structure and Dynamics of the TIP3P, SPC, and SPC/E Water Models at 298 K.\" J. Phys. Chem. A, 2001, 105, 9954-9960. \n", 182 | "\n", 183 | "[6] R.W. Pastor, B.R. Brooks, and A. Szabo, \"An Analysis of the Accuracy of Langevin and Molecular Dynamics Algorithms.\" Mol. Phys., 1988, 65, 1409-1419.\n", 184 | "\n", 185 | "[7] R. Anandakrishnan, A. Drozdetski, R.C. Walker, and A.V. Onufriev, \"Speed of Conformational Change: Comparing Explicit and Implicit Solvent Molecular Dynamics Simulations.\" Biophys. J., 2015, 108, 1153–1164.\n", 186 | "\n", 187 | "[8] Python Software Foundation. Python Language Reference, version 3.8. visited on April 30, 2022 (http://www.python.org).\n", 188 | "\n", 189 | "[9] van Rossum, G. Python tutorial, Technical Report CS-R9526, Centrum voor Wiskunde en Informatica (CWI), Amsterdam, 1995.\n", 190 | "\n", 191 | "[10] C.R. Harris, K.J. Millman, S.J. van der Walt, et al. \"Array programming with NumPy.\" Nature, 2020, 585, 357-362\n", 192 | "\n", 193 | "[11] Numpy User Guide, https://numpy.org/doc/stable/user/index.html, visited on April 29, 2022.\n", 194 | "\n", 195 | "[12] The Pandas Development Team pandas-dev/pandas: Pandas Zenodo, 2020 (https://pandas.pydata.org).\n", 196 | "\n", 197 | "[13] Pandas User Guide, https://pandas.pydata.org/docs/user_guide/index.html#user-guide, visited on April 30, 2022.\n", 198 | "\n", 199 | "---" 200 | ] 201 | }, 202 | { 203 | "cell_type": "markdown", 204 | "metadata": {}, 205 | "source": [ 206 | "##### Comments\n", 207 | "\n", 208 | "1. Example 2 is more professionally done and is considered to be more academic than Example 1.\n", 209 | "\n", 210 | "\n", 211 | "2. Due to the citations and properly formatted references section that includes all of the pertinent information, one can validate the information given in the writing (e.g. the density of water at 30.0 °C).\n", 212 | "\n", 213 | "\n", 214 | "3. Consequently, the writing becomes more substantial and trustworthy since its information content isn’t just coming from the author, but also from several checkable sources." 215 | ] 216 | }, 217 | { 218 | "cell_type": "code", 219 | "execution_count": null, 220 | "metadata": {}, 221 | "outputs": [], 222 | "source": [] 223 | } 224 | ], 225 | "metadata": { 226 | "kernelspec": { 227 | "display_name": "Python 3 (ipykernel)", 228 | "language": "python", 229 | "name": "python3" 230 | }, 231 | "language_info": { 232 | "codemirror_mode": { 233 | "name": "ipython", 234 | "version": 3 235 | }, 236 | "file_extension": ".py", 237 | "mimetype": "text/x-python", 238 | "name": "python", 239 | "nbconvert_exporter": "python", 240 | "pygments_lexer": "ipython3", 241 | "version": "3.8.10" 242 | } 243 | }, 244 | "nbformat": 4, 245 | "nbformat_minor": 2 246 | } 247 | -------------------------------------------------------------------------------- /t-test.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## T-Tests\n", 8 | "- Used on two samples data sets that are numeric\n", 9 | " - if you have more than two data sets, then you must either do it a) pairwise T-tests, or something else (e.g. Anova)\n", 10 | "\n", 11 | "A T-test does two things:\n", 12 | "1. How **different** two means values (obtained from two sets of distributed data) are - T value\n", 13 | " - Samller values indicate less differences\n", 14 | " \n", 15 | "2. How **significant** are these differences (i.e. did they occur randomly/by chance) - P value\n", 16 | " - Smaller values indicate that they were not random (i.e. P=0.05 means there is a 5% probability that the results happened by chance).\n", 17 | "\n", 18 | "\n", 19 | "Random, Gaussian (i.e. normal) distributin of data points\n", 20 | "- random.normal: https://numpy.org/doc/stable/reference/random/generated/numpy.random.normal.html\n", 21 | " - creates a Gaussian distribution with a curve width based on a standard deviation value" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "from scipy import stats\n", 31 | "import matplotlib.pyplot as plt\n", 32 | "import numpy as np" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "## Three data sets - with means at 0.0 and 2.0, and standard deviations of 1.0 and 0.5\n", 42 | "data1 = np.random.normal(0.0, 1.0, size=50)\n", 43 | "data2 = np.random.normal(0.0, 0.5, size=50)\n", 44 | "data3 = np.random.normal(2.0, 1.0, size=50)" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "Note: std = 0, would provide perfect resulting means of either 0.0 and 2.0.\n", 52 | "\n", 53 | "So, let's check what the means actually are (i.e. the effect of the std. dev.)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "np.mean(data1)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "np.mean(data2)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "np.mean(data3)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "plt.plot()\n", 90 | "plt.plot(data1, '-o')\n", 91 | "plt.plot(data2, '-r')\n", 92 | "plt.plot(data3, '-g')\n", 93 | "\n", 94 | "plt.hlines(np.mean(data1), 0, 50, colors='blue')\n", 95 | "plt.hlines(np.mean(data2), 0, 50, colors='red')\n", 96 | "plt.hlines(np.mean(data3), 0, 50, colors='green')\n", 97 | "\n", 98 | "plt.show()" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "Use seaborn to easily plot the histogram of the data" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": null, 111 | "metadata": {}, 112 | "outputs": [], 113 | "source": [ 114 | "import seaborn as sns\n", 115 | "\n", 116 | "plt.plot()\n", 117 | "sns.kdeplot(data1, color='blue', shade=True)\n", 118 | "sns.kdeplot(data2, color='red', shade=True)\n", 119 | "sns.kdeplot(data3, color='green', shade=True)\n", 120 | "plt.title(\"Histogram of Data\")\n", 121 | "plt.show()" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "#### t-test\n", 129 | "- https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html\n", 130 | "\n", 131 | "- \"The test measures **whether the mean (expected) value differs significantly across samples**.\"\n", 132 | "\n", 133 | "- A **large p-value** (e.g. **0.05, 0.1**), then it is likely that the averages are not distinguishable.\"\n", 134 | "\n", 135 | "- \"If the p-value is smaller than the threshold, e.g. 1%, 5% or 10%, then we reject the null hypothesis of equal averages.\"" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": {}, 142 | "outputs": [], 143 | "source": [ 144 | "t_stat, p_value = stats.ttest_ind(data1, data3, equal_var = False)" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "metadata": {}, 151 | "outputs": [], 152 | "source": [ 153 | "t_stat" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": null, 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [ 162 | "p_value" 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": {}, 168 | "source": [ 169 | "---\n", 170 | "#### Real-world example\n", 171 | "\n", 172 | "Research task: Investigate the height, weight, gender and age of a population of people (e.g. Germans)\n", 173 | "- We can't investigate the full population, so we must sample a random subset of people" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": null, 179 | "metadata": {}, 180 | "outputs": [], 181 | "source": [ 182 | "len(np.random.random_sample((50,)))" 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": null, 188 | "metadata": {}, 189 | "outputs": [], 190 | "source": [ 191 | "import pandas as pd\n", 192 | "\n", 193 | "np.random.seed(10)\n", 194 | "\n", 195 | "height = np.random.uniform(0.5, 2.0, size=50)\n", 196 | "weight = np.random.uniform(15.0, 90.0, size=50)\n", 197 | "gender = np.random.choice(('Male', 'Female'), size=50, p=[0.4, 0.6]) ## With a 40:60 ratio of male:female\n", 198 | "age = np.random.uniform(3.0, 80.0, size=50)" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": null, 204 | "metadata": {}, 205 | "outputs": [], 206 | "source": [ 207 | "height" 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": null, 213 | "metadata": {}, 214 | "outputs": [], 215 | "source": [ 216 | "np.array([height, weight, gender, age])" 217 | ] 218 | }, 219 | { 220 | "cell_type": "markdown", 221 | "metadata": {}, 222 | "source": [ 223 | "Create a dataframe that contains the information of our variables.\n", 224 | "- 1 catagorical type data: gender\n", 225 | "- 3 numeric type data: height, weight and age" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": null, 231 | "metadata": {}, 232 | "outputs": [], 233 | "source": [ 234 | "df = pd.DataFrame(list(zip(height, weight, gender, age)), columns=['height (m)', 'weight (kg)', 'gender', 'age'])" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": {}, 241 | "outputs": [], 242 | "source": [ 243 | "df" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": null, 249 | "metadata": {}, 250 | "outputs": [], 251 | "source": [ 252 | "df[df[\"gender\"] == \"Male\"].count()" 253 | ] 254 | }, 255 | { 256 | "cell_type": "code", 257 | "execution_count": null, 258 | "metadata": {}, 259 | "outputs": [], 260 | "source": [ 261 | "df[df[\"gender\"] == \"Female\"].count()" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "Now let's look at our random distribution and think about correlation between the data." 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": null, 274 | "metadata": {}, 275 | "outputs": [], 276 | "source": [ 277 | "hist = sns.FacetGrid(df, col=\"gender\")\n", 278 | "hist.map(sns.distplot, \"height (m)\", bins=20)\n", 279 | "hist.add_legend()" 280 | ] 281 | }, 282 | { 283 | "cell_type": "code", 284 | "execution_count": null, 285 | "metadata": {}, 286 | "outputs": [], 287 | "source": [ 288 | "hist = sns.FacetGrid(df, col=\"gender\")\n", 289 | "hist.map(sns.distplot, \"weight (kg)\", bins=20)\n", 290 | "hist.add_legend()" 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": null, 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [ 299 | "hist = sns.FacetGrid(df, col=\"gender\")\n", 300 | "hist.map(sns.distplot, \"age\", bins=20)\n", 301 | "hist.add_legend()" 302 | ] 303 | }, 304 | { 305 | "cell_type": "markdown", 306 | "metadata": {}, 307 | "source": [ 308 | "Compute the mean and median as a function of the gender.\n", 309 | "- use pandas groupby function" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": {}, 316 | "outputs": [], 317 | "source": [ 318 | "df.groupby(['gender']).mean()" 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "execution_count": null, 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "df.groupby(['gender']).median()" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": null, 333 | "metadata": {}, 334 | "outputs": [], 335 | "source": [ 336 | "sns.lmplot(x='weight (kg)', y='age', data=df, hue='gender', fit_reg=True, legend=True)\n", 337 | "plt.show()" 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": null, 343 | "metadata": {}, 344 | "outputs": [], 345 | "source": [ 346 | "sns.lmplot(x='height (m)', y='age', data=df, hue='gender', fit_reg=True, legend=True)\n", 347 | "plt.show()" 348 | ] 349 | }, 350 | { 351 | "cell_type": "code", 352 | "execution_count": null, 353 | "metadata": {}, 354 | "outputs": [], 355 | "source": [ 356 | "sns.lmplot(x='height (m)', y='weight (kg)', data=df, hue='gender', fit_reg=True, legend=True)\n", 357 | "plt.show()" 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": null, 363 | "metadata": {}, 364 | "outputs": [], 365 | "source": [ 366 | "sns.jointplot(x='height (m)', y='age', data=df, kind='reg', color='b')\n", 367 | "plt.show()" 368 | ] 369 | }, 370 | { 371 | "cell_type": "markdown", 372 | "metadata": {}, 373 | "source": [ 374 | "####\n", 375 | "Research Question: Is there a difference between the number of mean and women in the population?\n", 376 | "- Hypothesis Zero (aka Null Hypotheis): there is no difference\n", 377 | "- Hypothesis One: there is a difference\n", 378 | "\n", 379 | "In other words - is our sampling of the real population artifically skewed, or is it likely to be real?" 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "execution_count": null, 385 | "metadata": {}, 386 | "outputs": [], 387 | "source": [ 388 | "sns.countplot(x=\"gender\", data=df)" 389 | ] 390 | }, 391 | { 392 | "cell_type": "markdown", 393 | "metadata": {}, 394 | "source": [ 395 | "We must first determine a threshold for how low our statisical result is for use to have confidence that the Null Hypothesis is wrong - i.e. the probability value (P-value) that the Null Hypothesis is wrong.\n", 396 | "\n", 397 | "Common convention is 5%\n", 398 | "\n", 399 | "One-Sample Proportion Test" 400 | ] 401 | }, 402 | { 403 | "cell_type": "code", 404 | "execution_count": null, 405 | "metadata": {}, 406 | "outputs": [], 407 | "source": [ 408 | "from scipy import stats\n", 409 | "\n", 410 | "test = np.array([60,40])\n", 411 | "stats.zscore(test)\n" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": null, 417 | "metadata": {}, 418 | "outputs": [], 419 | "source": [ 420 | "df.groupby('gender')['age'].transform(stats.zscore)" 421 | ] 422 | }, 423 | { 424 | "cell_type": "code", 425 | "execution_count": null, 426 | "metadata": {}, 427 | "outputs": [], 428 | "source": [ 429 | "x = (df.groupby('gender')['age'])" 430 | ] 431 | }, 432 | { 433 | "cell_type": "code", 434 | "execution_count": null, 435 | "metadata": {}, 436 | "outputs": [], 437 | "source": [ 438 | "for i in x:\n", 439 | " print(i)" 440 | ] 441 | } 442 | ], 443 | "metadata": { 444 | "kernelspec": { 445 | "display_name": "Python 3", 446 | "language": "python", 447 | "name": "python3" 448 | }, 449 | "language_info": { 450 | "codemirror_mode": { 451 | "name": "ipython", 452 | "version": 3 453 | }, 454 | "file_extension": ".py", 455 | "mimetype": "text/x-python", 456 | "name": "python", 457 | "nbconvert_exporter": "python", 458 | "pygments_lexer": "ipython3", 459 | "version": "3.8.1" 460 | } 461 | }, 462 | "nbformat": 4, 463 | "nbformat_minor": 2 464 | } 465 | -------------------------------------------------------------------------------- /mid_semester_review.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
\n", 8 | "\n", 9 | "#
Scientific Programming in Python\n", 10 | "\n", 11 | "##
Karl N. Kirschner
Bonn-Rhein-Sieg University of Applied Sciences
Sankt Augustin, Germany\n", 12 | "\n", 13 | "#
ca. Mid Semseter Review\n", 14 | "###
(plus a few new ideas)\n", 15 | "\n", 16 | "
" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## Scientific Programming\n", 24 | "\n", 25 | "**Definition**\n", 26 | "1. Programming whose goal is for scientific usage (e.g. workflows, data analysis) and visualization.\n", 27 | "\n", 28 | "2. Learning to program is an academic, scholarly manner (i.e. wissenschaftliches Arbeit).\n", 29 | " - minimize errors\n", 30 | " - enable others to expand upon your ideas\n", 31 | " - reproducible results\n", 32 | " - convey knowledge (e.g. ideas are placed into context and explained)\n", 33 | " - being precise and explicit in what is done\n", 34 | " - following established standards within computer science (e.g. PEP8)\n", 35 | "\n", 36 | "**3 Ways to Think About It**\n", 37 | "1. **Usage**: to perform mathematics (simple numerical computations to some complex math models)\n", 38 | "\n", 39 | "2. **Practice**: to create while maintaining good scholarship\n", 40 | " - knowing what is state-of-the-art\n", 41 | " - being clear and supportive (e.g. citing sources)\n", 42 | " - write code in concise, explicit manner (i.e. do something with understanding and intention)\n", 43 | " - write code in a way that minimizes the chances of introducing an error\n", 44 | " - \"A machine requires precise instructions, which users often fail to supply\"[1]\n", 45 | "\n", 46 | "3. **Target**: to support science (doing research, data support and analysis)\n", 47 | " - \"Scientists commonly use languages such as Python and R to conduct and **automate analyses**, because in this way they can **speed data crunching**, **increase reproducibility**, protect data from accidental deletion or alteration and handle data sets that would overwhelm commercial applications.\"[1]\n", 48 | " - Create workflows to help do the research\n", 49 | " - Create simulations (increasingly becoming more important in research)\n", 50 | " - exploratory: for understanding raw data\n", 51 | " - supportive: for strengthening interpretations of the data\n", 52 | " - predictive: creating new ideas\n", 53 | " \n", 54 | "[1] Baker, Monya. \"Scientific computing: code alert.\" Nature 541, no. 7638 (2017): 563-565.\n", 55 | "\n", 56 | "
\n", 57 | "\n", 58 | "#### Conceptual highlights about the course\n", 59 | "1. Significant amount of personal feedback\n", 60 | "\n", 61 | "2. Emphasis on\n", 62 | " - **K**eep **I**t (i.e. coding) **S**imple & **S**mart (K.I.S.S.)\n", 63 | " - $C^3$: code is **clear** (i.e. clarity), **concise**, and place into **context**\n", 64 | " - easily readable and understandable\n", 65 | " - use of built-in functions over libraries with large overhead\n", 66 | " - user functions for reproducibility, reuse, and error reduction" 67 | ] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": {}, 72 | "source": [ 73 | "#### Lots of built-in keywords and commands" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "**Built-in Functions**\n", 81 | "https://docs.python.org/3/library/functions.html\n", 82 | "\n", 83 | "`abs()\t\t\tdivmod()\t\tinput()\t\t open()\t staticmethod()`
\n", 84 | "`all()\t\t\tenumerate()\t int()\t\t ord()\t str()`
\n", 85 | "`any()\t\t\teval()\t\t isinstance()\tpow()\t sum()`
\n", 86 | "`basestring()\t execfile() \tissubclass()\tprint() super()`
\n", 87 | "`bin()\t\t file()\t\t iter()\t\t property() tuple()`
\n", 88 | "`bool()\t\t filter()\t len()\t\t range()\t type()`
\n", 89 | "`bytearray()\t float()\t list()\t\t raw_input() unichr()`
\n", 90 | "`callable()\t format()\t\tlocals()\t\treduce() unicode()`
\n", 91 | "`chr()\t\t\tfrozenset()\t long()\t\t reload() vars()`
\n", 92 | "`classmethod()\tgetattr()\t map()\t\t repr()\t\txrange()`
\n", 93 | "`cmp()\t\t\tglobals()\t max()\t\t reversed()\tzip()`
\n", 94 | "`compile()\t\thasattr()\t memoryview() round()\t __import__()`
\n", 95 | "`complex()\t\thash()\t\t min()\t\t set()`
\n", 96 | "`delattr()\t\thelp()\t\t next()\t setattr()`
\n", 97 | "`dict()\t\t hex()\t\t object()\t slice()`
\n", 98 | "`dir()\t\t\tid()\t\t oct()\t sorted()`
\n", 99 | "***" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "import keyword\n", 109 | "keyword.kwlist" 110 | ] 111 | }, 112 | { 113 | "cell_type": "markdown", 114 | "metadata": {}, 115 | "source": [ 116 | "#### A comprehensive list of built-in functions and modules\n", 117 | "\n", 118 | "Functions:" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": {}, 125 | "outputs": [], 126 | "source": [ 127 | "dir(__builtins__)" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "Modules:" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [ 143 | "help('modules')" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "
\n", 151 | "\n", 152 | "### What we have learned about so far\n", 153 | "\n", 154 | "1. User functions - creating one code block that focuses on a single idea/concept\n", 155 | " - typing - adds **clarity** to the code\n", 156 | " - **context** through good block comments, and\n", 157 | " - some internal code control ideas (e.g. isinstance, checking for None default assignments)\n", 158 | "\n", 159 | "\n", 160 | "2. Writing **concise** code without losing clarity (i.e. not making it confusing)\n", 161 | " - easier to understand\n", 162 | " - easier to debug\n", 163 | " - less prone to introducing errors\n", 164 | "\n", 165 | "\n", 166 | "3. Significant Figures and Rounding Numbers\n", 167 | "\n", 168 | "\n", 169 | "4. PEP8 styles recommendations\n", 170 | " - why it is important\n", 171 | " - order for importing libraries\n", 172 | " - indentation, spacing and line length\n", 173 | "\n", 174 | "\n", 175 | "5. Pandas library\n", 176 | " - reading in csv files (series and dataframes)\n", 177 | " - Pandas built in math functions\n", 178 | " - plotting data\n", 179 | "\n", 180 | "
" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "#### Data Structures Review\n", 188 | "\n", 189 | "- Lists\n", 190 | "- Dictionaries\n", 191 | "- Tuples\n", 192 | "\n", 193 | "**lists**" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "my_list = ['Christmas', 'Halloween', 'German Unity Day', \"New Year's Day\", \"Christmas\"]\n", 203 | "type(my_list)" 204 | ] 205 | }, 206 | { 207 | "cell_type": "code", 208 | "execution_count": null, 209 | "metadata": {}, 210 | "outputs": [], 211 | "source": [ 212 | "for holiday in my_list:\n", 213 | " print(holiday)" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": null, 219 | "metadata": {}, 220 | "outputs": [], 221 | "source": [ 222 | "my_list" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": null, 228 | "metadata": {}, 229 | "outputs": [], 230 | "source": [ 231 | "my_list[0] = 'Carnival'\n", 232 | "my_list" 233 | ] 234 | }, 235 | { 236 | "cell_type": "markdown", 237 | "metadata": {}, 238 | "source": [ 239 | "**tuples**\n", 240 | "- faster than lists, bacause they are\n", 241 | "- not mutable (i.e. immutable)" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": null, 247 | "metadata": {}, 248 | "outputs": [], 249 | "source": [ 250 | "my_tuple = ('Christmas', 'Halloween', 'German Unity Day', \"New Year's Day\", \"Christmas\")\n", 251 | "type(my_tuple)" 252 | ] 253 | }, 254 | { 255 | "cell_type": "code", 256 | "execution_count": null, 257 | "metadata": {}, 258 | "outputs": [], 259 | "source": [ 260 | "for holiday in my_tuple:\n", 261 | " print(holiday)" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "metadata": {}, 268 | "outputs": [], 269 | "source": [ 270 | "my_tuple[0] = 'Carnival'\n", 271 | "my_tuple" 272 | ] 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "**dictionary**" 279 | ] 280 | }, 281 | { 282 | "cell_type": "code", 283 | "execution_count": null, 284 | "metadata": {}, 285 | "outputs": [], 286 | "source": [ 287 | "my_dictionary = {'German Holidays': ['Christmas', 'Halloween', 'German Unity Day', \"New Year's Day\", \"Christmas\"],\n", 288 | " 'US Holidays': ['Christmas', 'Halloween', 'Thanksgiving', \"New Year's Day\", \"Christmas\"]}\n", 289 | "my_dictionary" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": null, 295 | "metadata": {}, 296 | "outputs": [], 297 | "source": [ 298 | "type(my_dictionary)" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": null, 304 | "metadata": {}, 305 | "outputs": [], 306 | "source": [ 307 | "my_dictionary.get('US Holidays')" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": null, 313 | "metadata": {}, 314 | "outputs": [], 315 | "source": [ 316 | "list(my_dictionary.keys())" 317 | ] 318 | }, 319 | { 320 | "cell_type": "code", 321 | "execution_count": null, 322 | "metadata": {}, 323 | "outputs": [], 324 | "source": [ 325 | "list(my_dictionary.values())" 326 | ] 327 | }, 328 | { 329 | "cell_type": "code", 330 | "execution_count": null, 331 | "metadata": {}, 332 | "outputs": [], 333 | "source": [ 334 | "list(my_dictionary.items())" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": null, 340 | "metadata": {}, 341 | "outputs": [], 342 | "source": [ 343 | "for key, value in my_dictionary.items():\n", 344 | " print(key, value)" 345 | ] 346 | }, 347 | { 348 | "cell_type": "markdown", 349 | "metadata": {}, 350 | "source": [ 351 | "#### Identify unique entries\n", 352 | "\n", 353 | "- sets\n", 354 | " - mutable\n", 355 | "- frozen sets\n", 356 | " - immutable" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": null, 362 | "metadata": {}, 363 | "outputs": [], 364 | "source": [ 365 | "my_set = set(my_list)\n", 366 | "my_set" 367 | ] 368 | }, 369 | { 370 | "cell_type": "code", 371 | "execution_count": null, 372 | "metadata": {}, 373 | "outputs": [], 374 | "source": [ 375 | "type(my_set)" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "execution_count": null, 381 | "metadata": {}, 382 | "outputs": [], 383 | "source": [ 384 | "for holiday in my_set:\n", 385 | " print(holiday)" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": null, 391 | "metadata": {}, 392 | "outputs": [], 393 | "source": [ 394 | "my_set.remove(\"New Year's Day\")\n", 395 | "my_set" 396 | ] 397 | }, 398 | { 399 | "cell_type": "markdown", 400 | "metadata": {}, 401 | "source": [ 402 | "**frozen set** (a small new idea that we haven't seen before)" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": null, 408 | "metadata": {}, 409 | "outputs": [], 410 | "source": [ 411 | "my_frozenset = frozenset(my_list)\n", 412 | "my_frozenset" 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": null, 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "type(my_frozenset)" 422 | ] 423 | }, 424 | { 425 | "cell_type": "code", 426 | "execution_count": null, 427 | "metadata": {}, 428 | "outputs": [], 429 | "source": [ 430 | "my_frozenset.remove(\"Christmas\")" 431 | ] 432 | } 433 | ], 434 | "metadata": { 435 | "kernelspec": { 436 | "display_name": "Python 3 (ipykernel)", 437 | "language": "python", 438 | "name": "python3" 439 | }, 440 | "language_info": { 441 | "codemirror_mode": { 442 | "name": "ipython", 443 | "version": 3 444 | }, 445 | "file_extension": ".py", 446 | "mimetype": "text/x-python", 447 | "name": "python", 448 | "nbconvert_exporter": "python", 449 | "pygments_lexer": "ipython3", 450 | "version": "3.8.10" 451 | } 452 | }, 453 | "nbformat": 4, 454 | "nbformat_minor": 2 455 | } 456 | -------------------------------------------------------------------------------- /intro_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
\n", 8 | "\n", 9 | "#
Scientific Programming in Python\n", 10 | "##
Karl N. Kirschner
Bonn-Rhein-Sieg University of Applied Sciences
Sankt Augustin, Germany\n", 11 | "\n", 12 | "##
Introductory Python3 Examples\n", 13 | "\n", 14 | "##
(and Demo of Jupyter Notebook / Colaboratory)\n", 15 | "\n", 16 | "
" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## What might I consider to be a good Jupyter-notebook and coding for a homework solution?\n", 24 | "\n", 25 | "### Example 1 - A Solution that Contains All Key Ingredients\n", 26 | "- markdown cells (name, context and sources)\n", 27 | "- code cells (clear, concise and well formatted)\n", 28 | "\n", 29 | "
" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "#### Title: A Simple Example with a Markdown and Code Cell\n", 37 | "\n", 38 | "Author: SciPro_012\n", 39 | "\n", 40 | "Date: March 31, 2025\n", 41 | "\n", 42 | "Goal: Provide an example of Kirschner's expectations for a good Jupyter-notebook and coding. Both markdown and code cells are exemplified.\n", 43 | "\n", 44 | "Task 1: Name four famous scientific women [1-4] using a for loop.\n", 45 | "\n", 46 | "References\n", 47 | "1. Miller, C.C. \"A gifted mathematician who is now recognized as the first computer programmer\". The New York Times, 8 March 2018. https://www.nytimes.com/interactive/2018/obituaries/overlooked-ada-lovelace.html. Online, accessed September 9, 2022.\n", 48 | "2. Rockwell, S. \"The life and legacy of Marie Curie.\" The Yale Journal of Biology and Medicine 76.4-6 (2003): 167.\n", 49 | "3. Uberoi, C. \"Rosalind Franklin: The woman scientist of DNA.\" Resonance 9.3 (2004): 3-5.\n", 50 | "4. Maria Goeppert Mayer - Facts. NobelPrize.org. Nobel Prize Outreach AB 2022. https://www.nobelprize.org/prizes/physics/1963/mayer/facts. Online, accessed September 9, 2022." 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "index = 1\n", 60 | "\n", 61 | "famous_scientists = ['Ada Love', 'Marie Curie', 'Rosalind Franklin', 'Maria Goeppert Mayer']\n", 62 | "\n", 63 | "for person in famous_scientists:\n", 64 | " print(f'Scientist number {index} is {person}.')\n", 65 | " index += 1" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "
\n", 73 | "\n", 74 | "Talking Points:\n", 75 | "\n", 76 | "1. Commenting code using Jupyter's markdown capabilities\n", 77 | " - porvide context\n", 78 | " - convey thoughts and ideas\n", 79 | " - provide sources of information\n", 80 | "\n", 81 | "\n", 82 | "2. Creating objects (i.e., `index` and `famous_scientists`)\n", 83 | " - human-readable (versus nondescriptive `x` or `s`)\n", 84 | " - proper spacing between list items\n", 85 | "\n", 86 | "\n", 87 | "3. Creation of a \"for loop\" (versus 4 print statements)\n", 88 | " - reduces chances of error\n", 89 | "\n", 90 | "\n", 91 | "4. Python incrementing a number by plus 1 (note: could also `-=`)\n", 92 | "\n", 93 | "\n", 94 | "5. Print statement with f-string formatting\n", 95 | " - concise and clear\n", 96 | "\n", 97 | "\n", 98 | "6. Overall, concisely and cleanly written code" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "
\n", 106 | "\n", 107 | "The purpose of the rest of this notebook is to provide you with additional insight into how one might improve their own work.\n", 108 | "\n", 109 | "- A poor example will be given, followed by how it can be improved.\n", 110 | "\n", 111 | "\n", 112 | "### Example 2a - A Poor Solution\n", 113 | "There are always multiple solutions for achieving the same goal.\n", 114 | "\n", 115 | "Here is a poor solution to the homework, whose was to compute the cube of the numbers 0-9: \n", 116 | "\n", 117 | "
" 118 | ] 119 | }, 120 | { 121 | "cell_type": "code", 122 | "execution_count": null, 123 | "metadata": {}, 124 | "outputs": [], 125 | "source": [ 126 | "#Simple Program, SciPro_012 March 20, 2025\n", 127 | "#Ein Beispiel of what might be a poor solution for demonstrating how it can be improved (better writting, reducing error) through iterative revisions.\n", 128 | "\n", 129 | "\n", 130 | "print('The cube of', 0, 'ist', 0*0*0) # take the cube of 0\n", 131 | "print('The cube of {0} ist {1}.'.format(1, 1*1*1)) # take the cub of 1\n", 132 | "print('The cube of {0} ist {1}.'.format(2, 2**2)) # ect.\n", 133 | "print('The cube of', 3, 'ist', 3*3*3, '.')\n", 134 | "print('The cube of', 3, 'ist {0}.'.format(4*4*4))\n", 135 | "print('The cube of {0} ist {1}.'.format(4, 5*5*5))\n", 136 | "print('The cube of {0} is {1}.'.format(3, 6*6*6))\n", 137 | "\n", 138 | "print(\"The cube of {0} ist {1}.\".format(6, 7*7*7))\n", 139 | "print(f\"The cube of {8} ist {8*8*8}.\")\n", 140 | "print(f'The cube of 9 ist {9*9*9}.')" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "
\n", 148 | "\n", 149 | "Problems with the above code:\n", 150 | "\n", 151 | "1. Lots of information group at once in the first two lines\n", 152 | "\n", 153 | "\n", 154 | "2. The problem context is poorly given as a comment (a markdown cell would have been better), and with mixed German/English language\n", 155 | " - German: `Ein Beispiel` and `ist`\n", 156 | " - Misspelled: `ect.`, `cub`\n", 157 | "\n", 158 | "3. Comment runs off the screen - must scroll to read it all\n", 159 | "\n", 160 | "\n", 161 | "5. Inline comments (e.g., `# take the cube of 0`) are not needed to understand the code\n", 162 | "\n", 163 | "\n", 164 | "6. Inconsistent formatting (i.e. printing and blank line usage)\n", 165 | "\n", 166 | " - `print('The cube of', 0, 'ist', 0*0*0)`, vs\n", 167 | " - `print('The cube of {0} ist {1}.'.format(1, 1*1*1))`, vs\n", 168 | " - `print(f\"The cube of {8} ist {8*8*8}.\")`\n", 169 | "\n", 170 | "\n", 171 | "7. Not concisely written (10 lines to print the cube of each number)\n", 172 | " - notice that the errors are hard to see\n", 173 | " - usage of 3 instead of 4: `print('The cube of', 3, 'ist {0}.'.format(4*4*4))`\n", 174 | " - raising to a power of 2, not 3: `print('The cube of {0} ist {1}.'.format(2, 2**2))`\n", 175 | " \n", 176 | "Could have been done better, and thus reduce the chances of introducing a programmer error." 177 | ] 178 | }, 179 | { 180 | "cell_type": "markdown", 181 | "metadata": {}, 182 | "source": [ 183 | "### Example 2b - A Better Solution\n", 184 | "\n", 185 | "Having writing the solution's first draft, now revise:\n", 186 | "\n", 187 | "- communicate better using markdown cells\n", 188 | "- coding more concisely\n", 189 | "\n", 190 | "
" 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": {}, 196 | "source": [ 197 | "Simple Program Improved\n", 198 | "\n", 199 | "Author: SciPro_012\n", 200 | "\n", 201 | "Date: March 20, 2025\n", 202 | "\n", 203 | "---\n", 204 | "\n", 205 | "Goal: Provide an example of how code can be improved through a revision.\n", 206 | "\n", 207 | "Task 1: Take the cube of intergers from 0 to 9." 208 | ] 209 | }, 210 | { 211 | "cell_type": "code", 212 | "execution_count": null, 213 | "metadata": {}, 214 | "outputs": [], 215 | "source": [ 216 | "number_tuple = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)\n", 217 | "\n", 218 | "for number in number_tuple:\n", 219 | " number_cube = number**3\n", 220 | " print('The cube of {0} is {1}.'.format(number, number_cube))" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "Result: a much better solution.\n", 228 | "\n", 229 | "However, there are 2 issues:\n", 230 | "\n", 231 | "1. manually providing a list of sequential numbers (could introduce a typo)\n", 232 | "\n", 233 | "\n", 234 | "2. the use of older print statement (less concise and less readable)\n", 235 | "\n", 236 | "
" 237 | ] 238 | }, 239 | { 240 | "cell_type": "markdown", 241 | "metadata": {}, 242 | "source": [ 243 | "### Example 2c - An Even Better Solution" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "Now, let's further improve the code cell part above - use a built-in function (`range`)\n", 251 | "\n", 252 | "
" 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": {}, 258 | "source": [ 259 | "Simple Program Improved Again\n", 260 | "\n", 261 | "Author: SciPro_01234\n", 262 | "\n", 263 | "Date: October 2, 2023\n", 264 | "\n", 265 | "---\n", 266 | "\n", 267 | "Goal: Provide an example of how code can be improved through iterative revisions.\n", 268 | "\n", 269 | "Task 1: Take the cube of intergers from 0 to 9." 270 | ] 271 | }, 272 | { 273 | "cell_type": "code", 274 | "execution_count": null, 275 | "metadata": {}, 276 | "outputs": [], 277 | "source": [ 278 | "number_list = range(0, 10, 1)\n", 279 | "\n", 280 | "for number in number_list:\n", 281 | " print(f'The cube of {number} is {number**3}.')" 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "
\n", 289 | "\n", 290 | "The following is better than above example because the codes is\n", 291 | "\n", 292 | "1. still readable (i.e., not too concise nor too \"clever\"), and\n", 293 | "\n", 294 | "2. the number of variables/objects is kept to a minimum, specifically\n", 295 | " - two: `number` and `number_list`, versus\n", 296 | " - three: `number`, `number_list` and `number_cube`)\n", 297 | "\n", 298 | "3. use of modern `f-string` print statement" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": {}, 304 | "source": [ 305 | "An alternative and still good solution, which is even a bit simpler (i.e., elimating the need to define a `number_list` object)." 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": null, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "number = 0\n", 315 | "\n", 316 | "while number < 10:\n", 317 | " print(f'The cube of {number} is {number**3}.')\n", 318 | " number += 1" 319 | ] 320 | }, 321 | { 322 | "cell_type": "markdown", 323 | "metadata": {}, 324 | "source": [ 325 | "
\n", 326 | "\n", 327 | "
\n", 328 | "\n", 329 | "## Take-home Points\n", 330 | "\n", 331 | "1. Better coding is acheived through iterations of its writing (i.e., code revision).\n", 332 | "\n", 333 | "2. Context and communicting thoughts/ideas using Jupyter's markdown capabilities\n", 334 | "\n", 335 | "3. Good academics scholarship (e.g., writing, citing sources)\n", 336 | "\n", 337 | "4. Human-readable object/variable naming (versus nondescriptive `x` or `s`)\n", 338 | "\n", 339 | "5. Concise coding (e.g., for loop, f-string formatting)\n", 340 | "\n", 341 | "6. Coding that reduces chances of introducing programmer's errors\n", 342 | "\n", 343 | "7. Citing knowledge (see first example above)" 344 | ] 345 | }, 346 | { 347 | "cell_type": "code", 348 | "execution_count": null, 349 | "metadata": {}, 350 | "outputs": [], 351 | "source": [] 352 | } 353 | ], 354 | "metadata": { 355 | "kernelspec": { 356 | "display_name": "Python 3 (ipykernel)", 357 | "language": "python", 358 | "name": "python3" 359 | }, 360 | "language_info": { 361 | "codemirror_mode": { 362 | "name": "ipython", 363 | "version": 3 364 | }, 365 | "file_extension": ".py", 366 | "mimetype": "text/x-python", 367 | "name": "python", 368 | "nbconvert_exporter": "python", 369 | "pygments_lexer": "ipython3", 370 | "version": "3.13.2" 371 | } 372 | }, 373 | "nbformat": 4, 374 | "nbformat_minor": 4 375 | } 376 | -------------------------------------------------------------------------------- /numpy_polynomials.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "1f0ce628", 6 | "metadata": {}, 7 | "source": [ 8 | "
\n", 9 | "\n", 10 | "\n", 11 | "# Polynomials\n", 12 | "\n", 13 | "## Importance of polynomials in science\n", 14 | "\n", 15 | "They are prevalent in all fields - ranging from physics to economics.\n", 16 | "\n", 17 | "**Examples**:\n", 18 | "- chemistry: model potential energy surfaces\n", 19 | "- astronomy: model object (stars, planets, asteroids) trajectories, velocities, interactions \n", 20 | "- economics: model forecast money trends\n", 21 | "- meteorology: model weather patterns\n", 22 | "- engineering: create physical designs (roller coaster)\n", 23 | "- virology: predict contagion growth\n", 24 | "- statistics: regressions and interpolation\n", 25 | "\n", 26 | "Often in the real world, we can rarely evaluate functions exactly (i.e., **analytically**) because they become **too complicated**. Instead, we evaluate functions **using approximations created using polynomials** (e.g., Taylor series expansions: https://en.wikipedia.org/wiki/Taylor_series).\n", 27 | "\n", 28 | "---\n", 29 | "\n", 30 | "## Polynomials Definition and Components\n", 31 | "\n", 32 | "Example (2$^{nd}$-degree polynomial; a.k.a. **Quadratic**): $3x^2 + 2x + 1$\n", 33 | "\n", 34 | "where the overall polynomial **degree** is defined by the **highest power** value (i.e., $x^2$: 2$^{nd}$-degree), and the **coefficients** are $\\mathbf{3}$, $\\mathbf{2}$, $\\mathbf{1}$. The **terms** are $\\mathbf{3x^2}$, $\\mathbf{2x}$, and $\\mathbf{1}$.\n", 35 | "\n", 36 | "- https://en.wikipedia.org/wiki/Polynomial\n", 37 | "\n", 38 | "\n", 39 | "## Example of simple polynomials using Numpy functions\n", 40 | "\n", 41 | "#### Creating one-dimensional polynomials to various degrees: \n", 42 | "- https://numpy.org/doc/stable/reference/routines.polynomials-package.html#module-numpy.polynomial\n", 43 | "- `numpy.polynomial.polynomial`: https://numpy.org/doc/stable/reference/routines.polynomials.html\n", 44 | "\n", 45 | "
\n", 46 | "\n", 47 | "Okay, let's revisit the idea of polynomials and slowly build up our understanding together." 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "id": "fe395a92", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "import matplotlib.pyplot as plt\n", 58 | "import numpy as np\n", 59 | "import numpy.polynomial.polynomial as poly" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "id": "f6c6139e", 65 | "metadata": {}, 66 | "source": [ 67 | "1. Create a one dimensional (i.e., has one variable...x) polynomials using a function\n", 68 | " - using different coefficient(s)\n", 69 | " - evaluate the resulting function using a variable (i.e., x) value of 2.\n", 70 | "\n", 71 | "To do this **concisely** and to **reduce error**, let's create a user-defined function that\n", 72 | "\n", 73 | "a) generates a polynomial using provided coefficients,\n", 74 | "\n", 75 | "b) prints out the polynomial equation and\n", 76 | "\n", 77 | "c) its value when evaluated at x=2\n", 78 | "\n", 79 | "**Note**: I do not provide a docstring comment to `isinstance` within this function to simplify the teaching message. Normally, you should include them." 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "id": "43545095-ca35-4cd0-b5a7-74ed1074cd41", 86 | "metadata": {}, 87 | "outputs": [], 88 | "source": [ 89 | "def my_1d_polynomial(coeff: list):\n", 90 | " \"\"\"\n", 91 | " Creates a numpy.polynomial.Polynomial object from poly1d-style coefficients,\n", 92 | " displays it in LaTeX, and evaluates it and x=2.\n", 93 | "\n", 94 | " Args:\n", 95 | " coefficients: Coefficients ordered [a_0, a_1, ..., a_n].\n", 96 | " \"\"\"\n", 97 | " polynomial = poly.Polynomial(coeff)\n", 98 | "\n", 99 | " print(f'The value of the polynomial when x=2 is: {polynomial(2)}')\n", 100 | "\n", 101 | " print(\"The polynomial function is:\")\n", 102 | " return polynomial" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "id": "2763e62c", 108 | "metadata": {}, 109 | "source": [ 110 | "#### One coefficient (not very exciting): [M] --> $M$" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "id": "cd0c38b6", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "coefficients = [3]\n", 121 | "my_1d_polynomial(coeff=coefficients)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "id": "445825fa", 127 | "metadata": {}, 128 | "source": [ 129 | "Notice that the polynomial generated does not have an 'x' term...the equation is just a constant.\n", 130 | "\n", 131 | "That means the y-values of the \"polynomial\" equation \"3\" is 3 for all x-values:" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "id": "e6ad295d", 138 | "metadata": {}, 139 | "outputs": [], 140 | "source": [ 141 | "plt.plot()\n", 142 | "plt.hlines(xmin=0, xmax=10, y=3)\n", 143 | "plt.show()" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "id": "9d9dff3d", 149 | "metadata": {}, 150 | "source": [ 151 | "#### Two coefficients: [M, N] --> $M + Nx$\n", 152 | "- Note how the M shifts to the x" 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": null, 158 | "id": "39a33a98", 159 | "metadata": {}, 160 | "outputs": [], 161 | "source": [ 162 | "coefficients = [2, 1]\n", 163 | "my_1d_polynomial(coeff=coefficients)" 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "id": "a737dfe5", 169 | "metadata": {}, 170 | "source": [ 171 | "##### Including a negative coefficients: [-1, 1]" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "id": "6e46edcd", 178 | "metadata": {}, 179 | "outputs": [], 180 | "source": [ 181 | "coefficients = [-1, 1]\n", 182 | "my_1d_polynomial(coeff=coefficients)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "id": "c8e49f19", 188 | "metadata": {}, 189 | "source": [ 190 | "#### Three coefficients: [M, N, O] --> $M + Nx + Ox^2$" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "execution_count": null, 196 | "id": "a5389129", 197 | "metadata": {}, 198 | "outputs": [], 199 | "source": [ 200 | "# coefficients = [x^2, x, constant]\n", 201 | "coefficients = [-4, 1, -2]\n", 202 | "my_1d_polynomial(coeff=coefficients)" 203 | ] 204 | }, 205 | { 206 | "cell_type": "markdown", 207 | "id": "1dd9d533", 208 | "metadata": {}, 209 | "source": [ 210 | "#### Four coefficients: [M, N, O, P] --> $M + Nx + Ox^2 + Px^3$" 211 | ] 212 | }, 213 | { 214 | "cell_type": "code", 215 | "execution_count": null, 216 | "id": "cc678750", 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "coefficients = [-1, 1, -4, 5]\n", 221 | "my_1d_polynomial(coeff=coefficients)" 222 | ] 223 | }, 224 | { 225 | "cell_type": "markdown", 226 | "id": "428af698", 227 | "metadata": {}, 228 | "source": [ 229 | "#### Access the Polynomial's Coefficients" 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": null, 235 | "id": "78a7a86a", 236 | "metadata": {}, 237 | "outputs": [], 238 | "source": [ 239 | "polynomial = poly.Polynomial(coefficients)\n", 240 | "\n", 241 | "polynomial.coef" 242 | ] 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "id": "668701f3", 247 | "metadata": {}, 248 | "source": [ 249 | "#### Access the Polynomial's Order (a.k.a. Degree)" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": null, 255 | "id": "6c8f5524", 256 | "metadata": {}, 257 | "outputs": [], 258 | "source": [ 259 | "polynomial.degree()" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "id": "3071942b", 265 | "metadata": {}, 266 | "source": [ 267 | "## Math with polynomials\n", 268 | "\n", 269 | "#### Square of a polynomial\n", 270 | "\n", 271 | "The square of a polynomial\n", 272 | "\n", 273 | "\n", 274 | "$\n", 275 | "\\begin{align}\n", 276 | "(a + b)^2 &= (a + b)(a + b)\\\\\n", 277 | " &= a^2 + 2ab + b^2\n", 278 | "\\end{align}\n", 279 | "$\n", 280 | "\n", 281 | "**Example**:\n", 282 | "\n", 283 | "${2x + 1}$\n", 284 | "\n", 285 | "Thus, when we square this polynomial:\n", 286 | "\n", 287 | "$({2x + 1})^2 = (2x + 1)(2x + 1) = 4x^2 + 4x + 1$\n", 288 | "\n", 289 | "(**NumPy's display**: $1.0 + 4.0x + 4.0x^2$)\n", 290 | "\n", 291 | "So, how do we code this:" 292 | ] 293 | }, 294 | { 295 | "cell_type": "code", 296 | "execution_count": null, 297 | "id": "2b293c77", 298 | "metadata": {}, 299 | "outputs": [], 300 | "source": [ 301 | "coefficients = [1, 2]\n", 302 | "\n", 303 | "polynomial = poly.Polynomial(coefficients)\n", 304 | "\n", 305 | "poly_square = polynomial**2\n", 306 | "\n", 307 | "print(poly_square)" 308 | ] 309 | }, 310 | { 311 | "cell_type": "markdown", 312 | "id": "2d91a4c8", 313 | "metadata": {}, 314 | "source": [ 315 | "Now evaluate the squared polynomial at x=2\n", 316 | "\n", 317 | "(i.e., $ (2x + 1)^2 \\text{ at }x=2 \\rightarrow 4*2^2 + 4*2 + 1$)" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": null, 323 | "id": "eafb76e6", 324 | "metadata": {}, 325 | "outputs": [], 326 | "source": [ 327 | "poly_square(2)" 328 | ] 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "id": "8e6e0878", 333 | "metadata": {}, 334 | "source": [ 335 | "#### A polynomial cubed" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": null, 341 | "id": "21e231c4", 342 | "metadata": {}, 343 | "outputs": [], 344 | "source": [ 345 | "print(polynomial**3)" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "id": "e60ebef5", 351 | "metadata": {}, 352 | "source": [ 353 | "Summary so far:\n", 354 | "1. We reviewed what a polynomial is,\n", 355 | "2. We learned that `numpy.polynomial.polynomial` (i.e., `poly`) allows us to create n-degree polynomials that depend on x data\n", 356 | "3. We learned that we can do some polynomial math easily\n", 357 | "\n", 358 | "
\n", 359 | "\n", 360 | "What happens, though, when you have **x- and y-data** that follow a **polynomial form**, but you **don't know** the **coefficients** to define the polynomial?\n", 361 | "\n", 362 | "\n", 363 | "## Numpy's `polyfit` Function\n", 364 | "\n", 365 | "Fit a polynomial of a specified degree to specific data (x, y).\n", 366 | "\n", 367 | "Returns a \"vector\" of coefficients that minimizes the squared error.\n", 368 | "\n", 369 | "- https://numpy.org/doc/stable/reference/generated/numpy.polyfit.html\n", 370 | "\n", 371 | "First, let's create some **nonideal data** that follows a **cubic polynomial** form." 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": null, 377 | "id": "9f4b5b82", 378 | "metadata": {}, 379 | "outputs": [], 380 | "source": [ 381 | "x_values = [-12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1,\n", 382 | " 0, 1, 2, 3, 4, 5, 6, 7, 8]\n", 383 | "\n", 384 | "y_values = [2000, 1500, 1400, 700, 600, 500, 300, 100, 70, 30, 20, 5,\n", 385 | " 4, 7, 10, 6, -10, -50, -200, -220, -400]" 386 | ] 387 | }, 388 | { 389 | "cell_type": "code", 390 | "execution_count": null, 391 | "id": "2ea722c2", 392 | "metadata": {}, 393 | "outputs": [], 394 | "source": [ 395 | "plt.plot()\n", 396 | "plt.plot(x_values, y_values, 'o', markersize=15)\n", 397 | "plt.show()" 398 | ] 399 | }, 400 | { 401 | "cell_type": "markdown", 402 | "id": "f833017f", 403 | "metadata": {}, 404 | "source": [ 405 | "Now, `polyfit` will fit a n-degree polynomial (i.e., 3$^{rd}$ degree) to the provided x- and y-data.\n", 406 | "\n", 407 | "The `polyfit` function returns coefficients.\n", 408 | "\n", 409 | "Recall from above: four coefficients are needed to define a 3$^{rd}$ degree polynomial\n", 410 | "\n", 411 | "[M, N, O, P] --> $M + Nx + Ox^2 + Px^3$" 412 | ] 413 | }, 414 | { 415 | "cell_type": "code", 416 | "execution_count": null, 417 | "id": "3c890c78", 418 | "metadata": {}, 419 | "outputs": [], 420 | "source": [ 421 | "coefficients = np.polyfit(x_values, y_values, 3)\n", 422 | "coefficients" 423 | ] 424 | }, 425 | { 426 | "cell_type": "markdown", 427 | "id": "203b43de", 428 | "metadata": {}, 429 | "source": [ 430 | "Therefore, we have the following polynomial (rounded coefficients):\n", 431 | "\n", 432 | "$-1.046*x^3 + 1.696*x^2 + 3.413*x + 2.793$\n", 433 | "\n", 434 | "Now we can use Numpy's `poly1d` to encode this polynomial exactly:\n", 435 | "\n", 436 | "- Note, we must reverse the coefficients\n", 437 | " - `coefficients[::-1]`, or\n", 438 | " - `np.flip(coefficients)` (more human readable)" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": null, 444 | "id": "1f37527a", 445 | "metadata": {}, 446 | "outputs": [], 447 | "source": [ 448 | "cubic_polynomial = poly.Polynomial(np.flip(coefficients))\n", 449 | "print(cubic_polynomial)" 450 | ] 451 | }, 452 | { 453 | "cell_type": "markdown", 454 | "id": "d7f69413", 455 | "metadata": {}, 456 | "source": [ 457 | "Now, using this cubic polynomial that we created, we can generate **\"ideal\" y-data** given a range of **x-data values**." 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": null, 463 | "id": "819fc8e1", 464 | "metadata": {}, 465 | "outputs": [], 466 | "source": [ 467 | "y_ideal_cubic = cubic_polynomial(x_values)" 468 | ] 469 | }, 470 | { 471 | "cell_type": "markdown", 472 | "id": "375854cb", 473 | "metadata": {}, 474 | "source": [ 475 | "Plot both the original data and the data from the fitted cubic polynomial:" 476 | ] 477 | }, 478 | { 479 | "cell_type": "code", 480 | "execution_count": null, 481 | "id": "72511232", 482 | "metadata": {}, 483 | "outputs": [], 484 | "source": [ 485 | "plt.plot()\n", 486 | "plt.plot(x_values, y_values, 'o', markersize=15)\n", 487 | "plt.plot(x_values, y_ideal_cubic, '-', linewidth=5)\n", 488 | "plt.show()" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "id": "4d7c7a20-13f1-4bc0-afc6-048251870d00", 495 | "metadata": {}, 496 | "outputs": [], 497 | "source": [] 498 | } 499 | ], 500 | "metadata": { 501 | "kernelspec": { 502 | "display_name": "Python 3 (ipykernel)", 503 | "language": "python", 504 | "name": "python3" 505 | }, 506 | "language_info": { 507 | "codemirror_mode": { 508 | "name": "ipython", 509 | "version": 3 510 | }, 511 | "file_extension": ".py", 512 | "mimetype": "text/x-python", 513 | "name": "python", 514 | "nbconvert_exporter": "python", 515 | "pygments_lexer": "ipython3", 516 | "version": "3.13.2" 517 | } 518 | }, 519 | "nbformat": 4, 520 | "nbformat_minor": 5 521 | } 522 | -------------------------------------------------------------------------------- /testing_exceptions_unit_extra_info.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
\n", 8 | "\n", 9 | "#
Scientific Programming in Python\n", 10 | "\n", 11 | "##
Karl N. Kirschner
Bonn-Rhein-Sieg University of Applied Sciences
Sankt Augustin, Germany\n", 12 | "\n", 13 | "#
Extra Information for

Testing Inside your Code

and

Testing the Code Itself\n", 14 | "\n", 15 | "\n", 16 | "\n", 17 | "
\n", 18 | "\n", 19 | "**Note**: All user-defined functions in the notebook do not include document strings (i.e. block comments) or internal checks. This is purposely done to focus on the teaching aspects of the lecture. **A full and proper user-defined function would include these.**" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "# A quick reminder about typing\n", 27 | "\n", 28 | "Note that **typing** (a.k.a. type hinting, annotating functions) - actually **doesn't enforce** anything.\n", 29 | "\n", 30 | "We use them for our own and others' **clarification** of the code and its usage.\n", 31 | "\n", 32 | "To **enforce** the types, you must use `isinstance` statements." 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "def user_function(number: float) -> float:\n", 42 | " return number*2" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "user_function(number='me')" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "---\n", 59 | "\n", 60 | "# `assert` versus `raise`\n", 61 | "\n", 62 | "### `assert`\n", 63 | "\n", 64 | "**Usage**: `assert test_condition, 'Error message to display'`\n", 65 | "\n", 66 | "- specify expectations for what your variables are\n", 67 | "- A helpful way to **debug** code\n", 68 | "\n", 69 | "\n", 70 | "- Includes **traceback** (a.k.a. stack trace, stack traceback, backtrace) to show you the sequence of calls and associated problems\n", 71 | " - https://realpython.com/python-traceback\n", 72 | "\n", 73 | "- An `assert` statement is **equivalent** to the following code:\n", 74 | "\n", 75 | "```python\n", 76 | "if not condition:\n", 77 | " raise AssertionError()\n", 78 | "```\n", 79 | "\n", 80 | "\n", 81 | "- Asserts are **not** meant to **test for expected conditions**\n", 82 | " - **Security issue**: see below." 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "my_test_obj = 5\n", 92 | "\n", 93 | "assert my_test_obj != 5, 'ERROR MESSAGE FROM YOUR INSTRUCTOR - I LIKE YELLING WHEN I TYPE MESSAGES'" 94 | ] 95 | }, 96 | { 97 | "cell_type": "markdown", 98 | "metadata": {}, 99 | "source": [ 100 | "### Practical usage\n", 101 | "\n", 102 | "1. Create & demo a simple function without and `assert` statement\n", 103 | "2. Create & demo one with an `assert` statement" 104 | ] 105 | }, 106 | { 107 | "cell_type": "code", 108 | "execution_count": null, 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [ 112 | "def divide_me(number_1: float, number_2: float) -> float:\n", 113 | "\n", 114 | " return number_1/number_2\n", 115 | "\n", 116 | "\n", 117 | "divide_me(number_1=1.0, number_2=2.0)" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "The functions **runs fine**, **but** we could provide more customized feedback." 125 | ] 126 | }, 127 | { 128 | "cell_type": "code", 129 | "execution_count": null, 130 | "metadata": {}, 131 | "outputs": [], 132 | "source": [ 133 | "divide_me(number_1=1.0, number_2=None)" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "An `assert` can check to make sure that a variable is not `None` (via `!=` or `is not None`), allowing you to customize the feedback (i.e. placing the error into context)." 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [ 149 | "def divide_me(number_1: float, number_2: float) -> float:\n", 150 | "\n", 151 | " assert number_1 is not None, 'The numerator was not provided.'\n", 152 | " assert number_2 != None, 'The denominator was not provided.'\n", 153 | " assert number_2 != 0.0, \"Error: you can't divide by zero. How dare you try!\"\n", 154 | "\n", 155 | " return number_1/number_2\n", 156 | "\n", 157 | "\n", 158 | "divide_me(number_1=1.0, number_2=None)" 159 | ] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "metadata": {}, 164 | "source": [ 165 | "## `assert` Security issue\n", 166 | "\n", 167 | "There is also a way for users to **circumvent** (i.e. get around) assert statements.\n", 168 | "\n", 169 | "From a bash terminal:\n", 170 | "- **python assert_example.py**: reads the assert statement (everything seems to be working properly)\n", 171 | "- **python -O assert_example.py**: the assert statement is not read (i.e. it is bypassed), and instead prints a standard error statement\n", 172 | "\n", 173 | "In the following, I will also demonstrate how one can write a Python script in Jupyter notebook and save it to your hard drive." 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "
\n", 181 | "\n", 182 | "### Sidenote: Jupyter Notebook Magic Commands\n", 183 | "\n", 184 | "https://ipython.readthedocs.io/en/stable/interactive/magics.html\n", 185 | "\n", 186 | "https://towardsdatascience.com/useful-ipython-magic-commands-245e6c024711\n", 187 | "\n", 188 | "1. line magic commands (`%`) - the input directly follows the `%`\n", 189 | "2. cell magic commands (`%%`) - the entire cell becomes the input\n", 190 | "\n", 191 | "- `%load` import code from a Python script (e.g. `%load filename.py`)\n", 192 | "\n", 193 | "- `%%writefile filename`: write the contents of a cell to a file\n", 194 | "\n", 195 | "- `%timeit` and `%%timeit`: code performance" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": null, 201 | "metadata": {}, 202 | "outputs": [], 203 | "source": [ 204 | "%lsmagic" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": {}, 210 | "source": [ 211 | "Getting help is easy - just add a `?` to the end of the command:" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "%%writefile?" 221 | ] 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "
" 228 | ] 229 | }, 230 | { 231 | "cell_type": "markdown", 232 | "metadata": {}, 233 | "source": [ 234 | "#### Use a magic command to create a python script:" 235 | ] 236 | }, 237 | { 238 | "cell_type": "code", 239 | "execution_count": null, 240 | "metadata": {}, 241 | "outputs": [], 242 | "source": [ 243 | "%%writefile 'assert_example.py'\n", 244 | "#!/usr/bin/env python\n", 245 | "\n", 246 | "'''\n", 247 | "An example of why using assert to test for expected conditions is bad.\n", 248 | "\n", 249 | "You can \"turn off\" asserts by typing \"python -O filename.py\" and thus\n", 250 | " bypassing the check.\n", 251 | "\n", 252 | "Expectations when running the code in a bash terminal:\n", 253 | "python assert_example.py -> assert is read and prints out its error\n", 254 | "python -O assert_example.py -> assert is not read and the program runs\n", 255 | "'''\n", 256 | "\n", 257 | "def simple_print(number_1: float, number_2: float) -> float:\n", 258 | "\n", 259 | " assert number_1 != None, \"Error: you did not provide a numerator\"\n", 260 | " assert number_2 != None, \"Error: you did not provide a denominator\"\n", 261 | " assert number_2 != 0, \"Number 2 can't be zero\"\n", 262 | "\n", 263 | " print(number_1, number_2)\n", 264 | "\n", 265 | "simple_print(number_1=None, number_2=0.0)" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": null, 271 | "metadata": {}, 272 | "outputs": [], 273 | "source": [ 274 | "%cat 'assert_example.py'" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "**Note:** The following works when executed from a **local computer** that has the above python script saved to the working directory." 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "metadata": {}, 288 | "outputs": [], 289 | "source": [ 290 | "%%bash\n", 291 | "\n", 292 | "python assert_example.py" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "Including a **`-O`** will **ignore all assert statements**.\n", 300 | "\n", 301 | "Why do this?\n", 302 | "- Also sets the special builtin name `__debug__` to `False` (`True` by default)\n", 303 | " - E.g.: `if __debug__ then:`\n", 304 | "- Useful while working/optimizing code.\n", 305 | "- Results is a very small performance boost." 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": null, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "%%bash\n", 315 | "\n", 316 | "python3 -O assert_example.py" 317 | ] 318 | }, 319 | { 320 | "cell_type": "code", 321 | "execution_count": null, 322 | "metadata": {}, 323 | "outputs": [], 324 | "source": [ 325 | "%rm assert_example.py" 326 | ] 327 | }, 328 | { 329 | "cell_type": "markdown", 330 | "metadata": {}, 331 | "source": [ 332 | "#### Take-home message about `asserts` and in-my-opinion:\n", 333 | "\n", 334 | "- They help debug your code during its development.\n", 335 | "- They are not as robust as one thinks.\n", 336 | "- There are better ways to have internal checks." 337 | ] 338 | }, 339 | { 340 | "cell_type": "markdown", 341 | "metadata": {}, 342 | "source": [ 343 | "
\n", 344 | "\n", 345 | "## Sidenote: `TypeError` versus `ValueError`\n", 346 | "\n", 347 | "- `ValueError`: raised when an operation or function receives an argument that\n", 348 | " 1. has the **correct type**, but\n", 349 | " 2. an **inappropriate value**\n", 350 | "\n", 351 | "\n", 352 | "- `TypeError`: raised when passing arguments of the **wrong type** (e.g. passing a `list` when an `int` is expected)\n", 353 | "\n", 354 | "Best understood through the following example..." 355 | ] 356 | }, 357 | { 358 | "cell_type": "code", 359 | "execution_count": null, 360 | "metadata": {}, 361 | "outputs": [], 362 | "source": [ 363 | "def attempt_float(number):\n", 364 | " try:\n", 365 | " return float(number)\n", 366 | "\n", 367 | " except (TypeError):\n", 368 | " print(f'Input ({number}) (type: {type(number)}) was not the right type (i.e TypeError).')\n", 369 | "\n", 370 | " except (ValueError):\n", 371 | " print(f'Input ({number}) (type: {type(number)}) was not a correct value (i.e. ValueError).')" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": null, 377 | "metadata": {}, 378 | "outputs": [], 379 | "source": [ 380 | "attempt_float(0.1)" 381 | ] 382 | }, 383 | { 384 | "cell_type": "markdown", 385 | "metadata": {}, 386 | "source": [ 387 | "The built-in float can also accept a string if it is a decimal:\n", 388 | "\"If the argument is a string, it should contain a decimal number...\" (https://docs.python.org/3/library/functions.html#float)" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": null, 394 | "metadata": {}, 395 | "outputs": [], 396 | "source": [ 397 | "attempt_float('0.1')" 398 | ] 399 | }, 400 | { 401 | "cell_type": "code", 402 | "execution_count": null, 403 | "metadata": {}, 404 | "outputs": [], 405 | "source": [ 406 | "## a ValueError (correct type, wrong value)\n", 407 | "attempt_float('something')" 408 | ] 409 | }, 410 | { 411 | "cell_type": "code", 412 | "execution_count": null, 413 | "metadata": {}, 414 | "outputs": [], 415 | "source": [ 416 | "## a TypeError (wrong type)\n", 417 | "attempt_float([0.1, 0.2])" 418 | ] 419 | }, 420 | { 421 | "cell_type": "markdown", 422 | "metadata": {}, 423 | "source": [ 424 | "# Pytest\n", 425 | "\n", 426 | "## Introducing `pytest.mark.parametrize`" 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "execution_count": null, 432 | "metadata": {}, 433 | "outputs": [], 434 | "source": [ 435 | "%%writefile test_even.py\n", 436 | "import pytest\n", 437 | "\n", 438 | "\n", 439 | "def add(number_1: int|float, number_2: int|float) -> float:\n", 440 | " \"\"\"\n", 441 | " Returns the sum of two numbers.\n", 442 | "\n", 443 | " Parameters:\n", 444 | " number_1: The first number.\n", 445 | " number_2: The second number.\n", 446 | "\n", 447 | " Returns:\n", 448 | " int or float: The sum of a and b.\n", 449 | " \"\"\"\n", 450 | " return number_1 + number_2\n", 451 | "\n", 452 | "\n", 453 | "def test_add_multiple_inputs():\n", 454 | " ''' An initial attempt that uses a for loop within the test (avoid this).\n", 455 | " '''\n", 456 | " test_data = [(1, 2, 3),\n", 457 | " (-1, -1, -2),\n", 458 | " (5, 0, 5)]\n", 459 | " for num_1, num_2, expected in test_data:\n", 460 | " assert add(number_1=num_1, number_2=num_2) == expected" 461 | ] 462 | }, 463 | { 464 | "cell_type": "code", 465 | "execution_count": null, 466 | "metadata": {}, 467 | "outputs": [], 468 | "source": [ 469 | "!pytest -vs test_even.py" 470 | ] 471 | }, 472 | { 473 | "cell_type": "code", 474 | "execution_count": null, 475 | "metadata": {}, 476 | "outputs": [], 477 | "source": [ 478 | "%%writefile test_add_numbers.py\n", 479 | "import pytest\n", 480 | "\n", 481 | "\n", 482 | "def add(number_1: int|float, number_2: int|float) -> float:\n", 483 | " \"\"\"\n", 484 | " Returns the sum of two numbers.\n", 485 | "\n", 486 | " Parameters:\n", 487 | " number_1: The first number.\n", 488 | " number_2: The second number.\n", 489 | "\n", 490 | " Returns:\n", 491 | " int or float: The sum of a and b.\n", 492 | " \"\"\"\n", 493 | " return number_1 + number_2\n", 494 | "\n", 495 | "\n", 496 | "@pytest.mark.parametrize(\"num_1, num_2, expected\", [(1, 2, 3), # Test Case 1: Positive numbers\n", 497 | " (-1, -1, -2), # Test Case 2: Negative numbers\n", 498 | " (5, 0, 5), # Test Case 3: Testing with zero\n", 499 | " (100, -50, 50)]) # Test Case 4: Positive and negative\n", 500 | "\n", 501 | "def test_add(num_1, num_2, expected):\n", 502 | " assert add(number_1=num_1, number_2=num_2) == expected" 503 | ] 504 | }, 505 | { 506 | "cell_type": "code", 507 | "execution_count": null, 508 | "metadata": {}, 509 | "outputs": [], 510 | "source": [ 511 | "!pytest -vs test_add_numbers.py" 512 | ] 513 | }, 514 | { 515 | "cell_type": "code", 516 | "execution_count": null, 517 | "metadata": {}, 518 | "outputs": [], 519 | "source": [ 520 | "! rm test_add_numbers.py" 521 | ] 522 | } 523 | ], 524 | "metadata": { 525 | "kernelspec": { 526 | "display_name": "Python 3 (ipykernel)", 527 | "language": "python", 528 | "name": "python3" 529 | }, 530 | "language_info": { 531 | "codemirror_mode": { 532 | "name": "ipython", 533 | "version": 3 534 | }, 535 | "file_extension": ".py", 536 | "mimetype": "text/x-python", 537 | "name": "python", 538 | "nbconvert_exporter": "python", 539 | "pygments_lexer": "ipython3", 540 | "version": "3.13.1" 541 | } 542 | }, 543 | "nbformat": 4, 544 | "nbformat_minor": 4 545 | } 546 | -------------------------------------------------------------------------------- /introduction.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
\n", 8 | "\n", 9 | "#
Scientific Programming in Python\n", 10 | "##
Karl N. Kirschner, Ph.D.
Bonn-Rhein-Sieg University of Applied Sciences
Sankt Augustin, Germany\n", 11 | "\n", 12 | "#
Course Introduction\n", 13 | "\n", 14 | "
" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "
\n", 70 | "\n", 71 | "# Good Practices in Programming and Other Disciplines\n", 72 | "## (and keys to success in this course)\n", 73 | "\n", 74 | "### $\\textrm{C}^3$: code is written concisely, with a clear thought process, and placed into context\n", 75 | "\n", 76 | "1. **Concise**, cleanly written code and output\n", 77 | " - Easy to read and understand\n", 78 | " - Reduced chances of introducing programmer error\n", 79 | " - Easier to debug\n", 80 | "

\n", 81 | "\n", 82 | "2. **Clear** thought process with a logical grouping of code\n", 83 | " - User-defined functions that contain a single concept\n", 84 | " - Logical separation and isolation of individual ideas (e.g. using separate code cells & user-defined functions)\n", 85 | " - Promotes usability and reusability in future code (i.e., user-defined functions)\n", 86 | " - Easier to debug\n", 87 | "

\n", 88 | "\n", 89 | "3. **Context** for the code's a) purpose and b) usage are provided\n", 90 | " - Block comments, in-line comments and docstrings (e.g., user-defined functions) - purpose, usage, special notes\n", 91 | " - Jupyter-notebook markdown language (citations, data interpretation)\n", 92 | "\n", 93 | "\n", 94 | "### K.I.S.S.: Keep It (i.e., coding) Simple & Smart\n", 95 | "- $\\textrm{C}^3$ - concise, clear and context\n", 96 | "- Use of built-in functions over libraries with large overhead\n", 97 | "- User-defined functions for reproducibility, reuse, error reduction and isolating ideas\n", 98 | "\n", 99 | "$\\textrm{C}^3$ and K.I.S.S. are the same keys to success that are found in **all** scientific working.\n", 100 | "\n", 101 | "### Academic Scholarship: Developed during bachelor studies\n", 102 | "\n", 103 | "**You will need to do this for your thesis.**\n", 104 | "\n", 105 | "- **Citing sources** of existing knowledge\n", 106 | " - Providing credit to scientists and programmers\n", 107 | " - Helps to enable reproducibility\n", 108 | " - Indicates that you are well-educated (and you pay attention to details)\n", 109 | "- **Communicating** your thoughts/ideas (less assumption occur then)\n", 110 | "- **Good Writing**\n", 111 | " - $\\textrm{C}^3$\n", 112 | " - K.I.S.S.\n", 113 | " - Using complete sentences (i.e., a subject, a verb and usually an object)\n", 114 | "- Providing **units** for numbers when appropriate\n", 115 | "\n", 116 | "
" 117 | ] 118 | }, 119 | { 120 | "cell_type": "markdown", 121 | "metadata": {}, 122 | "source": [ 123 | "## Scientific Programming\n", 124 | "\n", 125 | "
\n", 126 | "
\n", 127 | "Generated with Bing AI ∙ September 25, 2024 at 12:21 PM\n", 128 | "
\n", 129 | "\n", 130 | "**Definition**\n", 131 | "
    \n", 132 | "
  1. Programming whose goal is for scientific usage (e.g., workflows, data analysis) and visualization.\n", 133 | "
  2. Learning to program in an academic, scholarly manner (i.e., wissenschaftliches Arbeit).\n", 134 | "
\n", 135 | "\n", 136 | "**3 Ways to Think About It**\n", 137 | "
    \n", 138 | "
  1. Usage: encoding ideas into mathematical models (from simple numerical computations to AI)\n", 139 | "

    \n", 140 | "
  2. Practice: to create code and knowledge while maintaining good scholarship\n", 141 | "
      \n", 142 | "
    1. Knowing what is the state-of-the-art\n", 143 | "
    2. Being careful (error handling, testing), clear (code and documentation) and maintainabile\n", 144 | "
    3. Computer's literalism: \"A machine requires precise instructions, which users often fail to supply\" [1]\n", 145 | "
    4. Generate reproducible results\n", 146 | "
    \n", 147 | "
    \n", 148 | "
  3. Target: to support science (doing research, data support and analysis)\n", 149 | "
      \n", 150 | "
    1. \"Scientists ... use ... Python ... to conduct and automate analyses ... speed data crunching, increase reproducibility ... and handle data sets that would overwhelm commercial applications.\" [1]\n", 151 | "
    2. Create workflows to help do the research\n", 152 | "
    3. Create simulations (very important in research)\n", 153 | "
        \n", 154 | "
      1. exploratory: for understanding raw data\n", 155 | "
      2. supportive: for strengthening interpretations of the data\n", 156 | "
      3. predictive: creating new ideas\n", 157 | "
      \n", 158 | "
    \n", 159 | " \n", 160 | "
\n", 161 | "\n", 162 | "[1] Baker, Monya. \"Scientific computing: code alert.\" Nature 541, no. 7638 (2017): 563-565, (https://www.nature.com/articles/nj7638-563a).\n", 163 | "\n", 164 | "
" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "
\n", 172 | "\n", 173 | "## Why is this Important?\n", 174 | "\n", 175 | "- \"Societally important science relies on models and the software implementing them. The scientific community must ensure that the findings and recommendations put forth based on those models conform to the highest scientific expectation\" [2]\n", 176 | "\n", 177 | "[2] L. N. Joppa et al., “Troubling Trends in Scientific Software Use,” Science, 340(6134), 814–815, 2013. (https://www.science.org/doi/10.1126/science.1231535)\n", 178 | "\n", 179 | "\n", 180 | "- AI usage: \"The challenge of ensuring scientific software works correctly isn’t new. What’s different now is that code LLMs can generate endless streams of plausible-looking code - at a time when research integrity is already threatened by a critical loss of resources. If we cannot ensure that our code corresponds to our scientific ideas, we risk preventable errors that will further undermine public trust in research.\" [3]\n", 181 | "\n", 182 | "[3] O’Brien, G. Threats to scientific software from over-reliance on AI code assistants. Nat Comput Sci 5, 701–703, 2025. (https://doi.org/10.1038/s43588-025-00845-2)" 183 | ] 184 | }, 185 | { 186 | "cell_type": "markdown", 187 | "metadata": {}, 188 | "source": [ 189 | "Positive Example:\n", 190 | "- During the Covid pandemic (March 20th, 2021), 9 of the 10 ChemRxiv (preprint server) highlights had significant computer modeling.\n", 191 | " - Meaning: computer models were the first to provide new knowledge that targeted the Coronavirus.\n", 192 | "\n", 193 | "
\n", 194 | "\n", 195 | "Negative Example:\n", 196 | "- A 2001 article and its 2005 retraction: G. Changet al., “Retraction,” Science, 314(5807), 1875, 2006\n", 197 | " - Top 2, highly respected scientific journal\n", 198 | " - Peer-review - who very likely did not review the author's code\n", 199 | " - a case for open-source software\n", 200 | "\n", 201 | "
" 202 | ] 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "metadata": {}, 207 | "source": [ 208 | "
\n", 209 | "\n", 210 | "## Why Python?\n", 211 | "\n", 212 | "Python is increasingly regarded as an important programming language.\n", 213 | "\n", 214 | "\n", 215 | "Due to its ease of use, extensive libraries and readability, scientific researchers have made it their \"go-to\" programming language.\n", 216 | "\n", 217 | "For example researchers use Python to create customized workflow for simulations (i.e., modeling); to analyze data (e.g., statistics); to create professional data plots (i.e., visualization); and to enable data and workflows reproducibility\n", 218 | "\n", 219 | "\n", 220 | "- Accessible and human readable: especially to people outside of computer science (natural scientists; engineers)\n", 221 | "- Powerful: many libraries that are created by domain experts\n", 222 | "- Modular: good for creating larger programs by creating user-defined functions that do (i.e., isolate) specific tasks\n", 223 | "\n", 224 | "\n", 225 | "Most popular programming languages (via reference [3])\n", 226 | "1. JavaScript\n", 227 | "2. Python\n", 228 | "3. Java\n", 229 | "4. PHP\n", 230 | "5. C#\n", 231 | "6. TypeScript\n", 232 | "6. CSS\n", 233 | "8. C++\n", 234 | "9. Ruby\n", 235 | "\n", 236 | "
\n", 237 | "\n", 238 | "3. Stephen O'Grady, \"The RedMonk Programming Language Rankings: June 2022\", Redmonk Link, March 8, 2024. Accessed on March 24, 2025.\n", 239 | "\n", 240 | "
\n", 241 | "\n", 242 | "## The Disciplines that use Python - Its \"Main\" Catagories\n", 243 | "\n", 244 | "For a Python job, one should know a) Python's core and b) one of the following categories:\n", 245 | "\n", 246 | "- Web - flask, django, html, javascript\n", 247 | "- Data engineering (collecting data) - sql, airflow, luigi\n", 248 | "- Software engineering - git, unit testing, large codebases\n", 249 | "- Cyber security - requests, volatility, pyew, peepdf, penetration tests\n", 250 | "- **Data science / scientific python** (seeking new knowledge)\n", 251 | "\n", 252 | "## What are the most important libraries to know?\n", 253 | "\n", 254 | "### Top libraries\n", 255 | "- 150 GitHub computational chemistry + machine learning (i.e., natural scientists who know about coding) repositories [4]\n", 256 | "\n", 257 | "1. Numpy\n", 258 | "2. Pandas\n", 259 | "3. PyTorch\n", 260 | "4. sklearn\n", 261 | "5. Matplotlib\n", 262 | "6. SciPy\n", 263 | "7. TensorFlow\n", 264 | "\n", 265 | "
\n", 266 | "\n", 267 | "4. Hagg, A and Kirschner, KN \"Open-source machine learning in computational chemistry.\" J Chem Inf Model, 63(15), 4505-4532, 2023. (https://pubs.acs.org/doi/full/10.1021/acs.jcim.3c00643)\n", 268 | "\n", 269 | "
" 270 | ] 271 | }, 272 | { 273 | "cell_type": "markdown", 274 | "metadata": {}, 275 | "source": [ 276 | "## Getting Python and Environments\n", 277 | "
    \n", 278 | "
  • Having Python (and desired libraries) installed onto your computer\n", 279 | " \n", 283 | "\n", 284 | "### Local Environment\n", 285 | "Recommend: Conda (https://docs.conda.io/en/latest) and/or Mamba (https://mamba.readthedocs.io/en/latest)\n", 286 | "\n", 287 | "- Package and environment management\n", 288 | "- Windows, macOS, and Linux\n", 289 | "- Example - can install different Python versions with different library dependencies $\\rightarrow$ allowing isolation of workspaces\n", 290 | "- Mamba is better at dependency resolutions\n", 291 | "\n", 292 | "### Write and Execute a Code\n", 293 | "
      \n", 294 | "
    • Jupyter Notebooks: Jupyter - Strongly recommended for this course\n", 295 | "
        \n", 296 | "
      • Writing online and offline\n", 297 | "
      • Execute: directly and offline\n", 298 | "
      • (Allows you/us to better explore unit testing later in the semester.)\n", 299 | "
      \n", 300 | "\n", 301 | "
      \n", 302 | "
    • Google's Colaboratory: Colab\n", 303 | "
        \n", 304 | "
      • Writing in a browser and online\n", 305 | "
      • Execute: directly and online\n", 306 | "
      \n", 307 | "\n", 308 | "
      \n", 309 | "
    • Text Editor and Integrated Development Environment (IDE)\n", 310 | "
        \n", 311 | "
      • Written using simple editors (e.g., texteditor, gedit, sublime)\n", 312 | "
      • Written using IDE (Integrated Development Environment)\n", 313 | " \n", 318 | "
      • \n", 319 | "
      \n", 320 | "\n", 321 | "
      \n", 322 | "\n", 330 | "
    \n", 331 | "
    " 332 | ] 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "metadata": {}, 337 | "source": [ 338 | "## Important Course Information\n", 339 | "
      \n", 340 | "
    • Lectures will be ca. 90 minutes long\n", 341 | "
    • We will make use of LEA\n", 342 | "
    • Syllabus - much of the important course info (on LEA)\n", 343 | "
    • I am available through university email (I tend to respond to these fairly quickly)\n", 344 | "
    • Individual/group in-person and online meetings can be made upon request\n", 345 | "
    \n", 346 | "\n", 347 | "
    " 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "metadata": {}, 353 | "source": [ 354 | "\n", 355 | "# Python Easter Eggs" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "- Experience Antigravity" 363 | ] 364 | }, 365 | { 366 | "cell_type": "code", 367 | "execution_count": null, 368 | "metadata": {}, 369 | "outputs": [], 370 | "source": [ 371 | "import antigravity" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": null, 377 | "metadata": {}, 378 | "outputs": [], 379 | "source": [] 380 | } 381 | ], 382 | "metadata": { 383 | "kernelspec": { 384 | "display_name": "Python 3 (ipykernel)", 385 | "language": "python", 386 | "name": "python3" 387 | }, 388 | "language_info": { 389 | "codemirror_mode": { 390 | "name": "ipython", 391 | "version": 3 392 | }, 393 | "file_extension": ".py", 394 | "mimetype": "text/x-python", 395 | "name": "python", 396 | "nbconvert_exporter": "python", 397 | "pygments_lexer": "ipython3", 398 | "version": "3.13.1" 399 | } 400 | }, 401 | "nbformat": 4, 402 | "nbformat_minor": 4 403 | } 404 | -------------------------------------------------------------------------------- /classes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "
    \n", 8 | "\n", 9 | "#
    Scientific Programming in Python\n", 10 | "##
    Karl N. Kirschner
    Bonn-Rhein-Sieg University of Applied Sciences
    Sankt Augustin, Germany\n", 11 | "\n", 12 | "#
    Classes
    \n", 13 | "\n", 14 | "
    \"Classes provide a means of bundling data and functionality together.\" [1]
    \n", 15 | "\n", 16 | "
    \n", 17 | " \n", 18 | "**Object-oriented programming**\n", 19 | " \n", 20 | "- Write a class that represents a \"real-world\" thing or situation\n", 21 | " - a set of instructions for making an instance (see below)\n", 22 | "\n", 23 | "\n", 24 | "- Call that class to create inidividual objects\n", 25 | "\n", 26 | "- According to PEP8:\n", 27 | " - **classes** are **capitalized** and uses **CamalCase**\n", 28 | " - **methods** are lowercase and uses **pot_hole**\n", 29 | "\n", 30 | "#### Sources\n", 31 | "1. Python Software Foundation, \"Classes\" Lasted Accessed on 21.02.2024 (https://docs.python.org/3/tutorial/classes.html#classes)\n", 32 | "2. \"What does __init__ and self do in python?\" Reddit's \n", 33 | "r/learnpython, Lasted Accessed on 21.02.2024 (https://www.reddit.com/r/learnpython/comments/19aghsb/comment/kimgw46/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button)\n", 34 | "3. GeeksforGeeks \"Access Modifiers in Python: Public, Private and Protected\" Lasted Accessed on 21.02.2024 (https://www.geeksforgeeks.org/access-modifiers-in-python-public-private-and-protected)\n", 35 | "\n", 36 | "
    " 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "## Do we need `Classes`?\n", 44 | "\n", 45 | "Strickly speaking, we don't.\n", 46 | "\n", 47 | "However, they do have advantages -- just like user-defined functions -- which includes improving a code's:\n", 48 | "\n", 49 | "- readability\n", 50 | "\n", 51 | "\n", 52 | "- organization (i.e., **contextual idea/concepts grouping**) - at a higher level than user-defined functions\n", 53 | " - Put related idea/concepts together under one header\n", 54 | "\n", 55 | "\n", 56 | "- usability\n", 57 | "\n", 58 | "\n", 59 | "- encapsulation: restricting variable access and methods to help prevent accidental modification\n", 60 | " - enables a separation between what the \"outside world\" knows about an object versus what the object knows about itself [2]\n", 61 | " - protected and private variable (indicated using a single leading underscore (i.e., `_`) in the naming):\n", 62 | " - \" ...there is a convention that is followed by most Python code: a name prefixed with an underscore (e.g. `_spam`) should be treated as a non-public part of the API (whether it is a function, a method or a data member).\" [1, 3]\n", 63 | " - public: `some_name`\n", 64 | " - protected: `_some_name`\n", 65 | " - private: `__some_name`\n", 66 | " \n", 67 | " - also is used to \"hide\" data\n", 68 | "\n", 69 | "\n", 70 | "- inheritance" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": {}, 77 | "outputs": [], 78 | "source": [ 79 | "class Dog():\n", 80 | " \"\"\" A dog model.\n", 81 | " \"\"\"\n", 82 | " \n", 83 | " def __init__(self, name, age):\n", 84 | " 'Initialize name and age attributes'\n", 85 | " self.name = name ## public variable\n", 86 | " self.age = age\n", 87 | " self.breed = 'mutt' ## a default value\n", 88 | "\n", 89 | " def sit(self):\n", 90 | " 'Simulates sitting due to a command given.'\n", 91 | " print(f'{self.name} is now sitting.')\n", 92 | "\n", 93 | "\n", 94 | " def roll_over(self):\n", 95 | " 'Simulates rolling over due to a command given.'\n", 96 | " print(f'{self.name} is now rolling over.')" 97 | ] 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "#### The first \"method\"\n", 104 | "A method is a function that is part of a class.\n", 105 | "\n", 106 | "`def __init__(self, name, age)`:\n", 107 | "\n", 108 | "- A special Python method that will **automatically run** when we create a new instance (i.e., call the class)\n", 109 | " - the two leading and trailing underscores (`__`) indicate special methods (a.k.a. \"magic methods\" or \"dunder methods\")\n", 110 | " - more about underscores (`_`): https://www.datacamp.com/community/tutorials/role-underscore-python\n", 111 | "\n", 112 | "- `__init__` **initialise** the created class **instance** (i.e., setting the attributes that it expects it to have)\n", 113 | "\n", 114 | "- `self` refers to the **current instance**\n", 115 | " - the name **self** is agreed upon as standard practice (however, you could use something different, but this is not recommended)\n", 116 | "\n", 117 | "\n", 118 | "- Three parameters are required\n", 119 | " - **self** (**required** and must come **first**)\n", 120 | " - **name** and **dog** (i.e., attributes)\n", 121 | " \n", 122 | "\n", 123 | "- Two more methods\n", 124 | " - sit and roll_over\n", 125 | " - in a real coding situation, these methods would contain code that make a robot dog sit or roll over" 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "metadata": {}, 131 | "source": [ 132 | "#### Making a new instance from a class\n", 133 | "- Convention is to have **instances** as **lower case**" 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": null, 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [ 142 | "pet_1 = Dog('Emma', 6)" 143 | ] 144 | }, 145 | { 146 | "cell_type": "markdown", 147 | "metadata": {}, 148 | "source": [ 149 | "What happened here:\n", 150 | "1. A new instance of a `Dog` object is created\n", 151 | "2. `__init__` is called and makes the assignments to the `name` and `age` variables\n", 152 | "3. The new `Dog` object is assigned to the variable `pet_1`\n", 153 | "\n", 154 | "\n", 155 | "\n", 156 | "##### Accessing the newly made instance\n", 157 | "To access an instance's (i.e., `pet_1`) attribute (e.g., `age`) of the class (i.e., `Dog`):" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": null, 163 | "metadata": {}, 164 | "outputs": [], 165 | "source": [ 166 | "print(f'My dog, {pet_1.name}, is a {pet_1.breed} and she is {pet_1.age} years old.')" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": null, 172 | "metadata": {}, 173 | "outputs": [], 174 | "source": [ 175 | "pet_1.sit()" 176 | ] 177 | }, 178 | { 179 | "cell_type": "code", 180 | "execution_count": null, 181 | "metadata": {}, 182 | "outputs": [], 183 | "source": [ 184 | "pet_1.roll_over()" 185 | ] 186 | }, 187 | { 188 | "cell_type": "markdown", 189 | "metadata": {}, 190 | "source": [ 191 | "
    \n", 192 | "\n", 193 | "#### Modify an attribute value directly" 194 | ] 195 | }, 196 | { 197 | "cell_type": "code", 198 | "execution_count": null, 199 | "metadata": {}, 200 | "outputs": [], 201 | "source": [ 202 | "pet_1.breed = 'terrier'\n", 203 | "\n", 204 | "print(f'My dog, {pet_1.name}, is a {pet_1.breed} and she is {pet_1.age} years old.')" 205 | ] 206 | }, 207 | { 208 | "cell_type": "markdown", 209 | "metadata": {}, 210 | "source": [ 211 | "#### Modify an attribute value through a new method" 212 | ] 213 | }, 214 | { 215 | "cell_type": "code", 216 | "execution_count": null, 217 | "metadata": {}, 218 | "outputs": [], 219 | "source": [ 220 | "pet_2 = Dog('Emma', 6)\n", 221 | "\n", 222 | "print(f'My dog, {pet_2.name}, is a {pet_2.breed} and she is {pet_2.age} years old.')" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "
    \n", 230 | "\n", 231 | "Alternatively, we can create another method that does the updates an attribute:" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": null, 237 | "metadata": {}, 238 | "outputs": [], 239 | "source": [ 240 | "class Dog():\n", 241 | " \"\"\"A Dog model\"\"\"\n", 242 | " \n", 243 | " def __init__(self, name, age):\n", 244 | " \"\"\"Initialize name and age attributes\"\"\"\n", 245 | " self.name = name\n", 246 | " self.age = age\n", 247 | " self.breed = 'mutt'\n", 248 | "\n", 249 | " def sit(self):\n", 250 | " \"\"\"Simulate a dog sitting due to a command given.\"\"\"\n", 251 | " print(\"{0} is now sitting.\".format(self.name))\n", 252 | "\n", 253 | "\n", 254 | " def roll_over(self):\n", 255 | " \"\"\"Simulate a dog rolling over due to a command given.\"\"\"\n", 256 | " print(\"{0} is now rolling over.\".format(self.name))\n", 257 | "\n", 258 | "\n", 259 | " def update_breed(self, new_breed):\n", 260 | " \"\"\"Set breed to new value.\"\"\"\n", 261 | " self.breed = new_breed" 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "execution_count": null, 267 | "metadata": {}, 268 | "outputs": [], 269 | "source": [ 270 | "pet_3 = Dog('Emma', 6)" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": null, 276 | "metadata": {}, 277 | "outputs": [], 278 | "source": [ 279 | "pet_3.update_breed('chihuahua')\n", 280 | "\n", 281 | "print(f'My dog, {pet_3.name}, is a {pet_3.breed} and she is {pet_3.age} years old.')" 282 | ] 283 | }, 284 | { 285 | "cell_type": "code", 286 | "execution_count": null, 287 | "metadata": {}, 288 | "outputs": [], 289 | "source": [ 290 | "pet_3.update_breed('terrier')\n", 291 | "\n", 292 | "print(f'My dog, {pet_3.name}, is a {pet_3.breed} and she is {pet_3.age} years old.')" 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "
    \n", 300 | "\n", 301 | "### A word of caution\n", 302 | "- Bypass internal checks written into methods" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "execution_count": null, 308 | "metadata": {}, 309 | "outputs": [], 310 | "source": [ 311 | "class Dog():\n", 312 | " \"\"\"A Dog model\"\"\"\n", 313 | " \n", 314 | " def __init__(self, name, age):\n", 315 | " \"\"\"Initialize name and age attributes\"\"\"\n", 316 | " self.name = name\n", 317 | " self.age = age\n", 318 | " self.breed = 'mutt'\n", 319 | "\n", 320 | " def sit(self):\n", 321 | " \"\"\"Simulate a dog sitting due to a command given.\"\"\"\n", 322 | " print(\"{0} is now sitting.\".format(self.name))\n", 323 | "\n", 324 | "\n", 325 | " def roll_over(self):\n", 326 | " \"\"\"Simulate a dog rolling over due to a command given.\"\"\"\n", 327 | " print(\"{0} is now rolling over.\".format(self.name))\n", 328 | "\n", 329 | "\n", 330 | " def update_breed(self, new_breed):\n", 331 | " \"\"\"Set breed to new value.\"\"\"\n", 332 | " if new_breed == 'pug':\n", 333 | " print(\"Pugs are not allowed.\")\n", 334 | " else:\n", 335 | " self.breed = new_breed" 336 | ] 337 | }, 338 | { 339 | "cell_type": "code", 340 | "execution_count": null, 341 | "metadata": {}, 342 | "outputs": [], 343 | "source": [ 344 | "pet_4 = Dog('Emma', 6)\n", 345 | "\n", 346 | "pet_4.update_breed('pug')" 347 | ] 348 | }, 349 | { 350 | "cell_type": "markdown", 351 | "metadata": {}, 352 | "source": [ 353 | "That is all okay.\n", 354 | "\n", 355 | "But the `update_breed` can be bypassed by setting the attribute directly." 356 | ] 357 | }, 358 | { 359 | "cell_type": "code", 360 | "execution_count": null, 361 | "metadata": {}, 362 | "outputs": [], 363 | "source": [ 364 | "pet_4.breed = 'pug'\n", 365 | "\n", 366 | "print(f'My dog, {pet_4.name}, is a {pet_4.breed} and she is {pet_4.age} years old.')" 367 | ] 368 | }, 369 | { 370 | "cell_type": "markdown", 371 | "metadata": {}, 372 | "source": [ 373 | "
    \n", 374 | "\n", 375 | "## Encapsulation\n", 376 | "\n", 377 | "Create a variable that is private the represents an animal's species:" 378 | ] 379 | }, 380 | { 381 | "cell_type": "code", 382 | "execution_count": null, 383 | "metadata": {}, 384 | "outputs": [], 385 | "source": [ 386 | "class Dog():\n", 387 | " \"\"\" A dog model.\n", 388 | " \"\"\"\n", 389 | " \n", 390 | " def __init__(self, name, age):\n", 391 | " 'Initialize name and age attributes'\n", 392 | " self.name = name\n", 393 | " self.age = age\n", 394 | " self.breed = 'mutt'\n", 395 | " \n", 396 | " self._species = 'mammal'\n", 397 | "\n", 398 | " def sit(self):\n", 399 | " 'Simulates sitting due to a command given.'\n", 400 | " print(f'{self.name} is now sitting.')\n", 401 | "\n", 402 | "\n", 403 | " def roll_over(self):\n", 404 | " 'Simulates rolling over due to a command given.'\n", 405 | " print(f'{self.name} is now rolling over.')" 406 | ] 407 | }, 408 | { 409 | "cell_type": "code", 410 | "execution_count": null, 411 | "metadata": {}, 412 | "outputs": [], 413 | "source": [ 414 | "pet_5 = Dog('Emma', 6)\n", 415 | "\n", 416 | "print(f'My dog (a {pet_5._species}), {pet_5.name}, is a {pet_5.breed} and she is {pet_5.age} years old.')" 417 | ] 418 | }, 419 | { 420 | "cell_type": "markdown", 421 | "metadata": {}, 422 | "source": [ 423 | "Since `_species` is a private variable, one still runs the risk of being a able to modify it:" 424 | ] 425 | }, 426 | { 427 | "cell_type": "code", 428 | "execution_count": null, 429 | "metadata": {}, 430 | "outputs": [], 431 | "source": [ 432 | "pet_5._species = 'bird'\n", 433 | "\n", 434 | "print(f'My dog (a {pet_5._species}), {pet_5.name}, is a {pet_5.breed} and she is {pet_5.age} years old.')" 435 | ] 436 | }, 437 | { 438 | "cell_type": "markdown", 439 | "metadata": {}, 440 | "source": [ 441 | "### An alternative example" 442 | ] 443 | }, 444 | { 445 | "cell_type": "code", 446 | "execution_count": null, 447 | "metadata": {}, 448 | "outputs": [], 449 | "source": [ 450 | "class BankAccount:\n", 451 | " ''' Example to show how public, protected and private variables\n", 452 | " and modules work (i.e., name, _name, and __name).\n", 453 | " \n", 454 | " Original source:\n", 455 | " https://www.tutorialspoint.com/access-modifiers-in-python-public-private-and-protected\n", 456 | " '''\n", 457 | " def __init__(self, account_number, nationality):\n", 458 | " self.__account_number = account_number\n", 459 | " self.nationality = nationality\n", 460 | "\n", 461 | "\n", 462 | " def display_nationality(self):\n", 463 | " ''' A public module (no underscore in name)\n", 464 | " '''\n", 465 | " print(\"Nationality:\", self.nationality)\n", 466 | "\n", 467 | "\n", 468 | " def _display_nationality(self):\n", 469 | " ''' A protected module (1 underscore in name)\n", 470 | " '''\n", 471 | " print(\"Nationality:\", self.nationality)\n", 472 | "\n", 473 | "\n", 474 | " def __display_nationality(self):\n", 475 | " ''' A private module (2 underscore in name)\n", 476 | " '''\n", 477 | " print(\"Nationality:\", self.nationality)" 478 | ] 479 | }, 480 | { 481 | "cell_type": "code", 482 | "execution_count": null, 483 | "metadata": {}, 484 | "outputs": [], 485 | "source": [ 486 | "person_1 = BankAccount(1234567890, 'DE')\n", 487 | "\n", 488 | "person_1.display_nationality()" 489 | ] 490 | }, 491 | { 492 | "cell_type": "code", 493 | "execution_count": null, 494 | "metadata": {}, 495 | "outputs": [], 496 | "source": [ 497 | "person_1._display_nationality()" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": null, 503 | "metadata": {}, 504 | "outputs": [], 505 | "source": [ 506 | "person_1.__display_nationality()" 507 | ] 508 | }, 509 | { 510 | "cell_type": "markdown", 511 | "metadata": {}, 512 | "source": [ 513 | "
    \n", 514 | "\n", 515 | "## Example 2: UFO" 516 | ] 517 | }, 518 | { 519 | "cell_type": "code", 520 | "execution_count": null, 521 | "metadata": {}, 522 | "outputs": [], 523 | "source": [ 524 | "class Ufo():\n", 525 | " \"\"\"A UFO model\"\"\"\n", 526 | " \n", 527 | " def __init__(self, origin, attitude):\n", 528 | " \"\"\"Initialize the UFO's physical origin and if they are friendly\"\"\"\n", 529 | " self.origin = origin\n", 530 | " self.friendly = attitude\n", 531 | "\n", 532 | "\n", 533 | " def species(self):\n", 534 | " \"\"\"The alien's species that controls the UFO\"\"\"\n", 535 | "\n", 536 | "\n", 537 | " def craft_shape(self):\n", 538 | " \"\"\"The UFO's shape\"\"\"\n", 539 | " #print(self.origin.)\n" 540 | ] 541 | }, 542 | { 543 | "cell_type": "code", 544 | "execution_count": null, 545 | "metadata": {}, 546 | "outputs": [], 547 | "source": [ 548 | "first_ufo = Ufo('mars', 'friendly')\n", 549 | "first_ufo.origin" 550 | ] 551 | }, 552 | { 553 | "cell_type": "code", 554 | "execution_count": null, 555 | "metadata": {}, 556 | "outputs": [], 557 | "source": [ 558 | "second_ufo = Ufo('venus', 'unfriendly')\n", 559 | "second_ufo.origin" 560 | ] 561 | }, 562 | { 563 | "cell_type": "code", 564 | "execution_count": null, 565 | "metadata": {}, 566 | "outputs": [], 567 | "source": [ 568 | "print('The first UFO is from {0} and they are {1}.'.format(first_ufo.origin, first_ufo.friendly))\n", 569 | "print('The second UFO is from {0} and they are {1}.'.format(second_ufo.origin, second_ufo.friendly))" 570 | ] 571 | }, 572 | { 573 | "cell_type": "code", 574 | "execution_count": null, 575 | "metadata": {}, 576 | "outputs": [], 577 | "source": [] 578 | } 579 | ], 580 | "metadata": { 581 | "kernelspec": { 582 | "display_name": "Python 3 (ipykernel)", 583 | "language": "python", 584 | "name": "python3" 585 | }, 586 | "language_info": { 587 | "codemirror_mode": { 588 | "name": "ipython", 589 | "version": 3 590 | }, 591 | "file_extension": ".py", 592 | "mimetype": "text/x-python", 593 | "name": "python", 594 | "nbconvert_exporter": "python", 595 | "pygments_lexer": "ipython3", 596 | "version": "3.10.13" 597 | } 598 | }, 599 | "nbformat": 4, 600 | "nbformat_minor": 2 601 | } 602 | --------------------------------------------------------------------------------