├── xblock_jupyter_viewer ├── rest │ ├── __init__.py │ ├── urls.py │ ├── serializers.py │ └── views.py ├── __init__.py ├── static │ ├── html │ │ └── student_view.html │ └── README.txt ├── translations │ └── README.txt ├── post_processors.py ├── preprocessors.py ├── jupyter_utils.py ├── xblock_jupyter_viewer.py ├── output.log └── output.txt ├── .gitignore ├── demo-thumbnail.png ├── setup.py ├── LICENSE └── README.md /xblock_jupyter_viewer/rest/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.un~ 3 | *.swp 4 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/__init__.py: -------------------------------------------------------------------------------- 1 | from .xblock_jupyter_viewer import JupyterViewerXBlock 2 | -------------------------------------------------------------------------------- /demo-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iblai/jupyter-edx-viewer-xblock/HEAD/demo-thumbnail.png -------------------------------------------------------------------------------- /xblock_jupyter_viewer/static/html/student_view.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/translations/README.txt: -------------------------------------------------------------------------------- 1 | Use this translations directory to provide internationalized strings for your XBlock project. 2 | 3 | For more information on how to enable translations, visit the Open edX XBlock tutorial on Internationalization: 4 | http://edx.readthedocs.org/projects/xblock-tutorial/en/latest/edx_platform/edx_lms.html 5 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/rest/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | Defines a URL to return a notebook html page to be used in an iframe 3 | """ 4 | from django.conf.urls import url 5 | 6 | from .views import NotebookViewer 7 | 8 | app_name = 'xblock_jupyter_viewer' 9 | 10 | urlpatterns = [ 11 | url( 12 | r'^render_notebook/$', 13 | NotebookViewer.as_view(), 14 | name='jupyter_nb_viewer' 15 | ) 16 | ] 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/rest/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | 3 | 4 | class NotebookViewSerializer(serializers.Serializer): 5 | url = serializers.URLField() 6 | images_url = serializers.URLField(required=False) 7 | start = serializers.CharField(required=False) 8 | end = serializers.CharField(required=False) 9 | 10 | def validate_images_url(self, value): 11 | if not value.endswith('/'): 12 | raise serializers.ValidationError("Image Root URL must end with a '/'") 13 | return value 14 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/post_processors.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import re 3 | 4 | log = logging.getLogger(__name__) 5 | 6 | 7 | def remove_box_shadow(raw_html): 8 | """Removes box shadow around document by replacing defining class name""" 9 | container = "#notebook-container" 10 | log.debug("Found #notebook-container class: {}".format(raw_html.find(container))) 11 | 12 | return raw_html.replace(container, "#doesnotexisthere") 13 | 14 | 15 | def insert_target_blank(raw_html): 16 | """Adds 'target=_blank' attribute to all `` links """ 17 | return re.sub('()', _match_fn, raw_html.encode('utf-8')) 18 | 19 | 20 | def _match_fn(matchobj): 21 | """Return original with `target='_blank'` inserted""" 22 | s = matchobj.group(0) 23 | return '{} target="_blank" {}'.format(s[:2], s[3:]) 24 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/static/README.txt: -------------------------------------------------------------------------------- 1 | This static directory is for files that should be included in your kit as plain 2 | static files. 3 | 4 | You can ask the runtime for a URL that will retrieve these files with: 5 | 6 | url = self.runtime.local_resource_url(self, "static/js/lib.js") 7 | 8 | The default implementation is very strict though, and will not serve files from 9 | the static directory. It will serve files from a directory named "public". 10 | Create a directory alongside this one named "public", and put files there. 11 | Then you can get a url with code like this: 12 | 13 | url = self.runtime.local_resource_url(self, "public/js/lib.js") 14 | 15 | The sample code includes a function you can use to read the content of files 16 | in the static directory, like this: 17 | 18 | frag.add_javascript(self.resource_string("static/js/my_block.js")) 19 | 20 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """Setup for xblocktimetracker XBlock.""" 2 | 3 | import os 4 | from setuptools import setup 5 | 6 | 7 | def package_data(pkg, roots): 8 | """Generic function to find package_data. 9 | 10 | All of the files under each of the `roots` will be declared as package 11 | data for package `pkg`. 12 | 13 | """ 14 | data = [] 15 | for root in roots: 16 | for dirname, _, files in os.walk(os.path.join(pkg, root)): 17 | for fname in files: 18 | data.append(os.path.relpath(os.path.join(dirname, fname), pkg)) 19 | 20 | return {pkg: data} 21 | 22 | 23 | setup( 24 | name='xblock_jupyter_viewer', 25 | version='1.0.1', 26 | description='View Jupyter Notebooks in your XBlock', 27 | license='UNKNOWN', # TODO: choose a license: 'AGPL v3' and 'Apache 2.0' are popular. 28 | packages=[ 29 | 'xblock_jupyter_viewer', 30 | ], 31 | install_requires=[ 32 | 'XBlock', 33 | 'nbconvert', 34 | 'nbformat', 35 | 'requests' 36 | ], 37 | entry_points={ 38 | 'xblock.v1': [ 39 | 'xblock_jupyter_viewer = xblock_jupyter_viewer:JupyterViewerXBlock', 40 | ] 41 | }, 42 | package_data=package_data("xblock_jupyter_viewer", ["static", "public", "rest"]), 43 | ) 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2018, IBL Education 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/rest/views.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import traceback 3 | import sys 4 | 5 | from rest_framework.views import APIView 6 | from rest_framework.response import Response 7 | from rest_framework.renderers import JSONRenderer 8 | 9 | from django.http import HttpResponse 10 | 11 | from xblock_jupyter_viewer.jupyter_utils import process_nb 12 | from xblock_jupyter_viewer.rest.serializers import NotebookViewSerializer 13 | 14 | log = logging.getLogger(__name__) 15 | 16 | class NotebookViewer(APIView): 17 | """Fetches noteboook at url and returns HTML to be used in iframe""" 18 | 19 | renderer_classes = (JSONRenderer, ) 20 | 21 | def get(self, request): 22 | nb_data = NotebookViewSerializer(data=request.query_params) 23 | # Query Param Validation 24 | if not nb_data.is_valid(): 25 | return Response(data=nb_data.errors, status=400) 26 | 27 | try: 28 | html = process_nb(**nb_data.validated_data) 29 | 30 | # Thrown when nbformat fails - caution, other errors could throw this 31 | except ValueError as e: 32 | log.exception(e) 33 | error = "An error occurred while converting {}. Please see the "\ 34 | "LMS/CMS logs for more details"\ 35 | .format(nb_data.validated_data['url']) 36 | return HttpResponse(error, status=400) 37 | 38 | # Handle other exceptions nicely 39 | except Exception as e: 40 | log.exception(e) 41 | msg = "{} -- Check lms/cms logs for more information".format(e) 42 | return HttpResponse(msg, status=500) 43 | 44 | return HttpResponse(html, status=200) 45 | 46 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/preprocessors.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import re 3 | 4 | log = logging.getLogger(__name__) 5 | 6 | 7 | class Processor(object): 8 | """Base cell transformer - applies `process_cell` to each cell""" 9 | def __init__(self, nb): 10 | self.nb = nb 11 | 12 | def process_cell(self, cell): 13 | raise NotImplemented 14 | 15 | def finish(self): 16 | """Optional function to be called after iterations are complete""" 17 | pass 18 | 19 | 20 | class RemoveCustomCSS(Processor): 21 | """Remove the cell that loads custom css if it's present""" 22 | 23 | def __init__(self, nb): 24 | super(RemoveCustomCSS, self).__init__(nb) 25 | self.search_text = 'from IPython.core.display import HTML' 26 | self.found = False 27 | self.cell_num = 0 28 | 29 | def process_cell(self, cell): 30 | if not self.found: 31 | if self.search_text in cell['source']: 32 | log.debug("Found Custom CSS Cell @ cells[{}]".format(self.cell_num)) 33 | self.found = True 34 | return 35 | self.cell_num += 1 36 | 37 | def finish(self): 38 | """Remove custom css cell if found""" 39 | if self.found: 40 | del self.nb['cells'][self.cell_num] 41 | log.debug("Removed cell #: {} [custom css]".format(self.cell_num)) 42 | 43 | 44 | class ImageReplacement(Processor): 45 | """Replaces img src attribute with absolute path""" 46 | 47 | def __init__(self, nb, images_url): 48 | super(ImageReplacement, self).__init__(nb) 49 | self.images_url = images_url 50 | 51 | def process_cell(self, cell): 52 | matches = re.findall(r' 98 | """), 99 | ("Multiple MyXBlock", 100 | """ 101 | 102 | 103 | 104 | 105 | """), 106 | ] 107 | 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jupyter Notebook Viewer 2 | 3 | ## Overview 4 | _Fetch and display part of, or an entire Jupyter Notebook in an XBlock._ 5 | 6 | Jupyter is a "killer app" for education, said Prof. Lorena Barba in her [keynote](http://lorenabarba.com/gallery/prof-barba-gave-keynote-at-scipy-2014/) at the 2014 Scientific Python Conference ([video](https://youtu.be/TWxwKDT88GU?t=9m24s) available). 7 | Many people are writing lessons, tutorials, whole courses and even books using Jupyter. 8 | It is a **new genre of open educational resource** (OER). 9 | What if you want to create an online course on Open edX using content originally written as Jupyter notebook? 10 | You certainly don't want to duplicate the content, much less copy-and-paste. 11 | This XBlock allows you to embed the content dynamically from a notebook available on a public URL. 12 | 13 | 14 | 15 | ## Installation 16 | ### XBlock 17 | * login as the root user: `sudo -i` 18 | * New Installation: 19 | * `/edx/bin/pip.edxapp install git+https://github.com/ibleducation/jupyter-viewer-xblock.git` 20 | * Re-Installation: 21 | * `/edx/bin/pip.edxapp install --upgrade --no-deps --force-reinstall git+https://github.com/ibleducation/jupyter-viewer-xblock.git` 22 | * Restart the `edxapp` via `/edx/bin/supervisorctl restart edxapp:` 23 | 24 | ### Edx Server Setup 25 | * In the studio, go to the course you would like to implement this XBlock in 26 | * Under `Settings` at the top, select `Advanced Settings` 27 | * in the Advanced Module List, add: `"xblock_jupyter_viewer"` 28 | * ensure there is a comma after the second to last entry, and no comma exists after the last entry 29 | * Select Save 30 | 31 | The viewer can now be added to a unit by selecting `Jupyter Notebook Viewer` from the `Advanced` component menu 32 | 33 | ### LMS/CMS Setup 34 | In the following two files: 35 | * `/edx/app/edxapp/edx-platform/lms/urls.py` 36 | * `/edx/app/edxapp/edx-platform/cms/urls.py` 37 | 38 | Add the following to the bottom of each file: 39 | ```python 40 | # Jupyter Viewer XBlock Endpoint 41 | urlpatterns += ( 42 | url(r'^api/jupyter/', include('xblock_jupyter_viewer.rest.urls', 43 | namespace='xblock_jupyter_viewer')), 44 | ) 45 | ``` 46 | 47 | In the following files: 48 | * `/edx/app/edxapp/edx-platform/lms/envs/common.py` 49 | * `/edx/app/edxapp/edx-platform/cms/envs/common.py` 50 | 51 | Add the following at the bottom of the `INSTALLED_APPS` section: 52 | ```python 53 | # Jupyter Notebook Viewer XBlock 54 | 'xblock_jupyter_viewer', 55 | ``` 56 | 57 | Restart `edxapp` via `/edx/bin/supervisorctl restart edxapp:` 58 | 59 | ## How it works 60 | The XBlock contains an `iframe` that points to the REST endpoint. 61 | 62 | The REST endpoint takes the following query parameters: 63 | * `url`: URL to the **RAW** jupyter notebook JSON file 64 | * `start`: (optional) text that starting cell contains 65 | * if supplied, will start in **FIRST** cell that contains this text 66 | * if not supplied, it starts at the beginning 67 | * `end`: (optional) text that ending cell contains 68 | * if supplied, will end at **FIRST** cell that contains this text (not-inclusive - this cell is not shown) 69 | * if not supplied, it will end at the end of the document 70 | * `images_url`: (optional) url to root of an images location (for `` tags) 71 | * if supplied, this will be pre-pended to the filename in the `src` attribute of all `` tags in the notebook 72 | * example: 73 | * images_url :`http://mysite.com/images/` 74 | * `` becomes `` 75 | 76 | It is often easiest to use the markdown headers as the start/end tags, eg: 77 | * `### My Start Header` 78 | 79 | If either start/end tags cannot be found in the document, they are ignored. 80 | 81 | The REST endpoint returns the entire HTML + embedded CSS in order to be rendered in the XBlock iframe. 82 | 83 | The user can also set the height of the XBlock in pixels in the Studio. 84 | 85 | ## Pre/Post Processors 86 | There are various pre and post processors that are applied to notebook when converting it to the final HTML. 87 | 88 | ### Pre-Processors 89 | These operate on each cell of the notebook, typically making some kind of change to either the overall notebook structure or a single cell. 90 | 91 | The cells of the notebook are iterated over and each cell is passed to each processor in the sequence the processors are added. 92 | 93 | After all cells have completed, the `finish` function is called for each processor to do any final cleanup. 94 | 95 | New pre-processors can be added by subclassing `preprocessors.Processor` and appending an instance of it to the `transforms` list. 96 | 97 | ### Post-Processors 98 | These operate on the final, raw HTML output string, making modifications as necessary. 99 | 100 | New post processors can be added in the `postprocess` function 101 | 102 | ## Usage notes 103 | 104 | ### Watch the demo! 105 | 106 | [![demo](https://github.com/ibleducation/jupyter-viewer-xblock/blob/master/demo-thumbnail.png)](http://www.youtube.com/watch?v=K8jhWgQnxvI) 107 | 108 | ### Functionality 109 | 110 | The Jupyter Viewer XBlock allows a course author to add content to an online course on the Open edX platform, from a publicly available Jupyter notebook (e.g., on GitHub). 111 | If you only provide one parameter, the notebook's public URL, the XBlock will display the entire notebook in an iframe. 112 | But it's often the case that instructors write Jupyter notebooks with a full lesson, over several pages if printed. 113 | Showing the whole notebook in one frame withing the online course may yield a clunky user experience. 114 | In our experience, your online course will look beter if you display a whole lesson over several units in an Open edX learning sequence. 115 | You can achieve this effect by choosing _start_ and _end_ tags: strings in the source notebook that mark the first and (exclusive) last cells to display. 116 | After choosing these tags, you may want to adjust the iframe height to fit the content length. 117 | If you have images embedded in markdown cells, you are likely to have a relative path that works in your local notebook. 118 | In the XBlock, you can provide the absolute path to the images in your notebook repo to ensure that they are properly shown. 119 | 120 | ## Copyright and License 121 | 122 | (c) 2017 IBL Studios and Lorena A. Barba, [code is under BSD-3 clause](https://github.com/engineersCode/EngComp/blob/master/LICENSE). 123 | 124 | [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) 125 | 126 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/output.log: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 7 |
8 |
9 |
10 |
11 |
12 |
13 |

Interacting with Python

This is the first lesson in our course "Engineering Computations", a one-semester course for second-year university students. The course uses Python, and assumes no prior programming experience. 14 | Our first step will be to get you interacting with Python. 15 | But let's also learn some background.

16 | 17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |

What is Python?

Python is now 26 years old. Its creator, Guido van Rossum, named it after the British comedy "Monty Python's Flying Circus." His goals for the language were that it be an "an easy and intuitive language just as powerful as major competitors," producing computer code "that is as understandable as plain English."

25 |

It is a general-purpose language, which means that you can use it for anything: organizing data, scraping the web, creating websites, analyzing sounds, creating games, and of course engineering computations.

26 |

Python is an interpreted language. This means that you can write Python commands and the computer can execute those instructions directly. Other programming languages—like C, C++ and Fortran—require a previous compilation step: translating the commands into machine language. 27 | A neat ability of Python is to be used interactively. Fernando Perez) famously created IPython as a side-project during his PhD. We're going to use IPython (the I stands for "interactive") in this lesson.

28 | 29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |

Why Python?

Because it's fun! With Python, the more you learn, the more you want to learn. 37 | You can find lots of resources online and, since Python is an open-source project, you'll also find a friendly community of people sharing their knowledge.

38 |

Python is known as a high-productivity language. As a programmer, you'll need less time to develop a solution with Python than with most languages. 39 | This is important to always bring up whenever someone complains that "Python is slow." 40 | Your time is more valuable than a machine's! 41 | (See the Recommended Readings section at the end.) 42 | And if we really need to speed up our program, we can re-write the slow parts in a compiled language afterwards. 43 | Because Python plays well with other languages :–)

44 |

The top technology companies use Python: Google, Facebook, Dropbox, Wikipedia, Yahoo!, YouTube… And this year, Python took the No. 1 spot in the interactive list of The 2017 Top Programming Languages, by IEEE Spectrum (IEEE is the world's largest technical professional society).

45 | 46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |

Python is a versatile language, you can analyze data, build websites (e.g., Instagram, Mozilla, Pinterest), make art or music, etc. Because it is a versatile language, employers love Python: if you know Python they will want to hire you. —Jessica McKellar, ex Director of the Python Software Foundation, in a 2014 tutorial.

54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |

Let's get started

In this first lesson, we will be using IPython: a tool for working with Python interactively. If you have it installed in the computer you're using for this lesson, you enter the program by typing

62 |

ipython

63 |

on the command-line interface (the Terminal app on Mac OSX, and on Windows possibly the PowerShell or git bash). You will get a few lines of text about your IPython version and how to get help, and a blinking cursor next to the input line counter:

64 |

In[1]:

65 |

That input line is ready to receive any Python code to be executed interactively. The output of the code will be shown to you next to Out[1], and so on for successive input/output lines.

66 |
Note:

Our plan for this course is to work in a computer lab, where everyone will have a computer with everything installed ahead of time. For this reason, we won't discuss installation right now. Later on, when you're eager to work on your personal computer, we'll help you install everything you need. It's all free!

67 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |

Your first program

In every programming class ever, your first program consists of printing a "Hello" message. In Python, you use the print() function, with your message inside quotation marks.

76 | 77 |
78 |
79 |
80 |
81 |
82 |
In [1]:
83 |
84 |
85 |
print("Hello world!!")
  86 | 
87 | 88 |
89 |
90 |
91 | 92 |
93 |
94 | 95 | 96 |
97 | 98 |
99 | 100 | 101 |
102 |
Hello world!!
 103 | 
104 |
105 |
106 | 107 |
108 |
109 | 110 |
111 |
112 |
113 |
114 |
115 |

Easy peasy!! You just wrote your first program and you learned how to use the print() function. Yes, print() is a function: we pass the argument we want the function to act on, inside the parentheses. In the case above, we passed a string, which is a series of characters between quotation marks. Don't worry, we will come back to what strings are later on in this lesson.

116 | 117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
Key concept: function

A function is a compact collection of code that executes some action on its arguments. Every Python function has a name, used to call it, and takes its arguments inside round brackets. Some arguments may be optional (which means they have a default value defined inside the function), others are required. For example, the print() function has one required argument: the string of characters it should print out for you.

125 |

Python comes with many built-in functions, but you can also build your own. Chunking blocks of code into functions is one of the best strategies to deal with complex programs. It makes you more efficient, because you can reuse the code that you wrote into a function. Modularity and reuse are every programmer's friend.

126 | 127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |

Python as a calculator

Try any arithmetic operation in IPython. The symbols are what you would expect, except for the "raise-to-the-power-of" operator, which you obtain with two asterisks: **. Try all of these:

135 |
+   -   *   /   **   %   //
 136 | 
137 |

The % symbol is the modulo operator (divide and return remainder), and the double-slash is floor division.

138 | 139 |
140 |
141 |
142 |
143 |
144 |
In [2]:
145 |
146 |
147 |
2 + 2
 148 | 
149 | 150 |
151 |
152 |
153 | 154 |
155 |
156 | 157 | 158 |
159 | 160 |
Out[2]:
161 | 162 | 163 | 164 | 165 |
166 |
4
167 |
168 | 169 |
170 | 171 |
172 |
173 | 174 |
175 |
176 |
177 |
In [3]:
178 |
179 |
180 |
1.25 + 3.65
 181 | 
182 | 183 |
184 |
185 |
186 | 187 |
188 |
189 | 190 | 191 |
192 | 193 |
Out[3]:
194 | 195 | 196 | 197 | 198 |
199 |
4.9
200 |
201 | 202 |
203 | 204 |
205 |
206 | 207 |
208 |
209 |
210 |
In [4]:
211 |
212 |
213 |
5 - 3
 214 | 
215 | 216 |
217 |
218 |
219 | 220 |
221 |
222 | 223 | 224 |
225 | 226 |
Out[4]:
227 | 228 | 229 | 230 | 231 |
232 |
2
233 |
234 | 235 |
236 | 237 |
238 |
239 | 240 |
241 |
242 |
243 |
In [5]:
244 |
245 |
246 |
2 * 4
 247 | 
248 | 249 |
250 |
251 |
252 | 253 |
254 |
255 | 256 | 257 |
258 | 259 |
Out[5]:
260 | 261 | 262 | 263 | 264 |
265 |
8
266 |
267 | 268 |
269 | 270 |
271 |
272 | 273 |
274 |
275 |
276 |
In [6]:
277 |
278 |
279 |
7 / 2
 280 | 
281 | 282 |
283 |
284 |
285 | 286 |
287 |
288 | 289 | 290 |
291 | 292 |
Out[6]:
293 | 294 | 295 | 296 | 297 |
298 |
3.5
299 |
300 | 301 |
302 | 303 |
304 |
305 | 306 |
307 |
308 |
309 |
In [7]:
310 |
311 |
312 |
2**3
 313 | 
314 | 315 |
316 |
317 |
318 | 319 |
320 |
321 | 322 | 323 |
324 | 325 |
Out[7]:
326 | 327 | 328 | 329 | 330 |
331 |
8
332 |
333 | 334 |
335 | 336 |
337 |
338 | 339 |
340 |
341 |
342 |
343 |
344 |

Let's see an interesting case:

345 | 346 |
347 |
348 |
349 |
350 |
351 |
In [8]:
352 |
353 |
354 |
9**1/2
 355 | 
356 | 357 |
358 |
359 |
360 | 361 |
362 |
363 | 364 | 365 |
366 | 367 |
Out[8]:
368 | 369 | 370 | 371 | 372 |
373 |
4.5
374 |
375 | 376 |
377 | 378 |
379 |
380 | 381 |
382 |
383 |
384 |
385 |
386 |
Discuss with your neighbor:

What happened? Isn't $9^{1/2} = 3$? (Raising to the power $1/2$ is the same as taking the square root.) Did Python get this wrong?

387 |

Compare with this:

388 | 389 |
390 |
391 |
392 |
393 |
394 |
In [9]:
395 |
396 |
397 |
9**(1/2)
 398 | 
399 | 400 |
401 |
402 |
403 | 404 |
405 |
406 | 407 | 408 |
409 | 410 |
Out[9]:
411 | 412 | 413 | 414 | 415 |
416 |
3.0
417 |
418 | 419 |
420 | 421 |
422 |
423 | 424 |
425 |
426 |
427 |
428 |
429 |

Yes! The order of operations matters!

430 |

If you don't remember what we are talking about, review the Arithmetics/Order of operations. A frequent situation that exposes this is the following:

431 | 432 |
433 |
434 |
435 |
436 |
437 |
In [10]:
438 |
439 |
440 |
3 + 3 / 2
 441 | 
442 | 443 |
444 |
445 |
446 | 447 |
448 |
449 | 450 | 451 |
452 | 453 |
Out[10]:
454 | 455 | 456 | 457 | 458 |
459 |
4.5
460 |
461 | 462 |
463 | 464 |
465 |
466 | 467 |
468 |
469 |
470 |
In [11]:
471 |
472 |
473 |
(3 + 3) / 2
 474 | 
475 | 476 |
477 |
478 |
479 | 480 |
481 |
482 | 483 | 484 |
485 | 486 |
Out[11]:
487 | 488 | 489 | 490 | 491 |
492 |
3.0
493 |
494 | 495 |
496 | 497 |
498 |
499 | 500 |
501 |
502 |
503 |
504 |
505 |

In the first case, we are adding $3$ plus the number resulting of the operation $3/2$. If we want the division to apply to the result of $3+3$, we need the parentheses.

506 | 507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
Exercises:

Use IPython (as a calculator) to solve the following two problems:

515 |
    516 |
  1. The volume of a sphere with radius $r$ is $\frac{4}{3}\pi r^3$. What is the volume of a sphere with diameter 6.65 cm?

    517 |

    For the value of $\pi$ use 3.14159 (for now). Compare your answer with the solution up to 4 decimal numbers.

    518 |

    Hint: 523.5983 is wrong and 615.9184 is also wrong.

    519 |
  2. 520 |
  3. Suppose the cover price of a book is $\$ 24.95$, but bookstores get a $40\%$ discount. Shipping costs $\$3$ for the first copy and $75$ cents for each additional copy. What is the total wholesale cost for $60$ copies? Compare your answer with the solution up to 2 decimal numbers.

    521 |
  4. 522 |
523 | 524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |

To reveal the answers, highlight the following line of text using the mouse:

532 | 533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |

Answer exercise 1: 153.9796 Answer exercise 2: 945.45

541 | 542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |

Variables and their type

Variables consist of two parts: a name and a value. When we want to give a variable its name and value, we use the equal sign: name = value. This is called an assignment. The name of the variable goes on the left and the value on the right.

550 |

The first thing to get used to is that the equal sign in an assignment has a different meaning than it has in Algebra! Think of it as an arrow pointing from name to value.

551 |

552 |

We have many possibilities for variable names: they can be made up of upper and lowercase letters, underscores and digits… although digits cannot go on the front of the name. For example, valid variable names are:

553 |
x
 554 |     x1
 555 |     X_2
 556 |     name_3
 557 |     NameLastname
 558 | 
559 |

Keep in mind, there are reserved words that you can't use; they are the special Python keywords.

560 |

OK. Let's assign some values to variables and do some operations with them:

561 | 562 |
563 |
564 |
565 |
566 |
567 |
In [12]:
568 |
569 |
570 |
x = 3
 571 | 
572 | 573 |
574 |
575 |
576 | 577 |
578 |
579 |
580 |
In [13]:
581 |
582 |
583 |
y = 4.5
 584 | 
585 | 586 |
587 |
588 |
589 | 590 |
591 |
592 |
593 |
594 |
595 |
Exercise:

Print the values of the variables x and y.

596 | 597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |

Let's do some arithmetic operations with our new variables:

605 | 606 |
607 |
608 |
609 |
610 |
611 |
In [14]:
612 |
613 |
614 |
x + y
 615 | 
616 | 617 |
618 |
619 |
620 | 621 |
622 |
623 | 624 | 625 |
626 | 627 |
Out[14]:
628 | 629 | 630 | 631 | 632 |
633 |
7.5
634 |
635 | 636 |
637 | 638 |
639 |
640 | 641 |
642 |
643 |
644 |
In [15]:
645 |
646 |
647 |
2**x
 648 | 
649 | 650 |
651 |
652 |
653 | 654 |
655 |
656 | 657 | 658 |
659 | 660 |
Out[15]:
661 | 662 | 663 | 664 | 665 |
666 |
8
667 |
668 | 669 |
670 | 671 |
672 |
673 | 674 |
675 |
676 |
677 |
In [16]:
678 |
679 |
680 |
y - 3
 681 | 
682 | 683 |
684 |
685 |
686 | 687 |
688 |
689 | 690 | 691 |
692 | 693 |
Out[16]:
694 | 695 | 696 | 697 | 698 |
699 |
1.5
700 |
701 | 702 |
703 | 704 |
705 |
706 | 707 |
708 |
709 |
710 |
711 |
712 |

And now, let's check the values of x and y. Are they still the same as they were when you assigned them?

713 | 714 |
715 |
716 |
717 |
718 |
719 |
In [17]:
720 |
721 |
722 |
print(x)
 723 | 
724 | 725 |
726 |
727 |
728 | 729 |
730 |
731 | 732 | 733 |
734 | 735 |
736 | 737 | 738 |
739 |
3
 740 | 
741 |
742 |
743 | 744 |
745 |
746 | 747 |
748 |
749 |
750 |
In [18]:
751 |
752 |
753 |
print(y)
 754 | 
755 | 756 |
757 |
758 |
759 | 760 |
761 |
762 | 763 | 764 |
765 | 766 |
767 | 768 | 769 |
770 |
4.5
 771 | 
772 |
773 |
774 | 775 |
776 |
777 | 778 |
779 |
780 |
781 |
782 |
783 |

String variables

In addition to name and value, Python variables have a type: the type of the value it refers to. For example, an integer value has type int, and a real number has type float. A string is a variable consisting of a sequence of characters marked by two quotes, and it has type str.

784 | 785 |
786 |
787 |
788 |
789 |
790 |
In [19]:
791 |
792 |
793 |
z = 'this is a string'
 794 | 
795 | 796 |
797 |
798 |
799 | 800 |
801 |
802 |
803 |
In [20]:
804 |
805 |
806 |
w = '1'
 807 | 
808 | 809 |
810 |
811 |
812 | 813 |
814 |
815 |
816 |
817 |
818 |

What if you try to "add" two strings?

819 | 820 |
821 |
822 |
823 |
824 |
825 |
In [21]:
826 |
827 |
828 |
z + w
 829 | 
830 | 831 |
832 |
833 |
834 | 835 |
836 |
837 | 838 | 839 |
840 | 841 |
Out[21]:
842 | 843 | 844 | 845 | 846 |
847 |
'this is a string1'
848 |
849 | 850 |
851 | 852 |
853 |
854 | 855 |
856 |
857 |
858 |
859 |
860 |

The operation above is called concatenation: chaining two strings together into one. Insteresting, eh? But look at this:

861 | 862 |
863 |
864 |
865 |
866 |
867 |
In [22]:
868 |
869 |
870 |
x + w
 871 | 
872 | 873 |
874 |
875 |
876 | 877 |
878 |
879 | 880 | 881 |
882 | 883 |
884 | 885 | 886 |
887 |
 888 | ---------------------------------------------------------------------------
 889 | TypeError                                 Traceback (most recent call last)
 890 | <ipython-input-22-bc79f95cdaf2> in <module>()
 891 | ----> 1 x + w
 892 | 
 893 | TypeError: unsupported operand type(s) for +: 'int' and 'str'
894 |
895 |
896 | 897 |
898 |
899 | 900 |
901 |
902 |
903 |
904 |
905 |

Error! Why? Let's inspect what Python has to say and explore what is happening.

906 |

Python is a dynamic language, which means that you don't need to specify a type to invoke an existing object. The humorous nickname for this is "duck typing":

907 |

"If it looks like a duck, and quacks like a duck, then it's probably a duck."

In other words, a variable has a type, but we don't need to specify it. It will just behave like it's supposed to when we operate with it (it'll quack and walk like nature intended it to).

908 |

But sometimes you need to make sure you know the type of a variable. Thankfully, Python offers a function to find out the type of a variable: type().

909 | 910 |
911 |
912 |
913 |
914 |
915 |
In [23]:
916 |
917 |
918 |
type(x)
 919 | 
920 | 921 |
922 |
923 |
924 | 925 |
926 |
927 | 928 | 929 |
930 | 931 |
Out[23]:
932 | 933 | 934 | 935 | 936 |
937 |
int
938 |
939 | 940 |
941 | 942 |
943 |
944 | 945 |
946 |
947 |
948 |
In [24]:
949 |
950 |
951 |
type(w)
 952 | 
953 | 954 |
955 |
956 |
957 | 958 |
959 |
960 | 961 | 962 |
963 | 964 |
Out[24]:
965 | 966 | 967 | 968 | 969 |
970 |
str
971 |
972 | 973 |
974 | 975 |
976 |
977 | 978 |
979 |
980 |
981 |
In [25]:
982 |
983 |
984 |
type(y)
 985 | 
986 | 987 |
988 |
989 |
990 | 991 |
992 |
993 | 994 | 995 |
996 | 997 |
Out[25]:
998 | 999 | 1000 | 1001 | 1002 |
1003 |
float
1004 |
1005 | 1006 |
1007 | 1008 |
1009 |
1010 | 1011 |
1012 |
1013 |
1014 |
1015 |
1016 |

More assignments

What if you want to assign to a new variable the result of an operation that involves other variables? Well, you totally can!

1017 | 1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
In [26]:
1024 |
1025 |
1026 |
sum_xy = x + y
1027 | diff_xy = x - y
1028 | 
1029 | 1030 |
1031 |
1032 |
1033 | 1034 |
1035 |
1036 |
1037 |
In [27]:
1038 |
1039 |
1040 |
print('The sum of x and y is:', sum_xy)
1041 | print('The difference between x and y is:', diff_xy)
1042 | 
1043 | 1044 |
1045 |
1046 |
1047 | 1048 |
1049 |
1050 | 1051 | 1052 |
1053 | 1054 |
1055 | 1056 | 1057 |
1058 |
The sum of x and y is: 7.5
1059 | The difference between x and y is: -1.5
1060 | 
1061 |
1062 |
1063 | 1064 |
1065 |
1066 | 1067 |
1068 |
1069 |
1070 |
1071 |
1072 |

Notice what we did above: we used the print() function with a string message, followed by a variable, and Python printed a useful combination of the message and the variable value. This is a pro tip! You want to print for humans. Let's now check the type of the new variables we just created above:

1073 | 1074 |
1075 |
1076 |
1077 |
1078 |
1079 |
In [28]:
1080 |
1081 |
1082 |
type(sum_xy)
1083 | 
1084 | 1085 |
1086 |
1087 |
1088 | 1089 |
1090 |
1091 | 1092 | 1093 |
1094 | 1095 |
Out[28]:
1096 | 1097 | 1098 | 1099 | 1100 |
1101 |
float
1102 |
1103 | 1104 |
1105 | 1106 |
1107 |
1108 | 1109 |
1110 |
1111 |
1112 |
In [29]:
1113 |
1114 |
1115 |
type(diff_xy)
1116 | 
1117 | 1118 |
1119 |
1120 |
1121 | 1122 |
1123 |
1124 | 1125 | 1126 |
1127 | 1128 |
Out[29]:
1129 | 1130 | 1131 | 1132 | 1133 |
1134 |
float
1135 |
1136 | 1137 |
1138 | 1139 |
1140 |
1141 | 1142 |
1143 |
1144 |
1145 |
1146 |
1147 |
Discuss with your neighbor:

Can you summarize what we did above?

1148 | 1149 |
1150 |
1151 |
1152 |
1153 |
1154 |
1155 |
1156 |

Special variables

Python has special variables that are built into the language. These are: 1157 | True, False, None and NotImplemented. 1158 | For now, we will look at just the first three of these.

1159 |

Boolean variables are used to represent truth values, and they can take one of two possible values: True and False. 1160 | Logical expressions return a boolean. Here is the simplest logical expression, using the keyword not:

1161 |
not True
1162 | 
1163 |

It returns… you guessed it… False.

1164 |

The Python function bool() returns a truth value assigned to any argument. Any number other than zero has a truth value of True, as well as any nonempty string or list. The number zero and any empty string or list will have a truth value of False. Explore the bool() function with various arguments.

1165 | 1166 |
1167 |
1168 |
1169 |
1170 |
1171 |
In [30]:
1172 |
1173 |
1174 |
bool(0)
1175 | 
1176 | 1177 |
1178 |
1179 |
1180 | 1181 |
1182 |
1183 | 1184 | 1185 |
1186 | 1187 |
Out[30]:
1188 | 1189 | 1190 | 1191 | 1192 |
1193 |
False
1194 |
1195 | 1196 |
1197 | 1198 |
1199 |
1200 | 1201 |
1202 |
1203 |
1204 |
In [31]:
1205 |
1206 |
1207 |
bool('Do we need oxygen?')
1208 | 
1209 | 1210 |
1211 |
1212 |
1213 | 1214 |
1215 |
1216 | 1217 | 1218 |
1219 | 1220 |
Out[31]:
1221 | 1222 | 1223 | 1224 | 1225 |
1226 |
True
1227 |
1228 | 1229 |
1230 | 1231 |
1232 |
1233 | 1234 |
1235 |
1236 |
1237 |
In [32]:
1238 |
1239 |
1240 |
bool('We do not need oxygen')
1241 | 
1242 | 1243 |
1244 |
1245 |
1246 | 1247 |
1248 |
1249 | 1250 | 1251 |
1252 | 1253 |
Out[32]:
1254 | 1255 | 1256 | 1257 | 1258 |
1259 |
True
1260 |
1261 | 1262 |
1263 | 1264 |
1265 |
1266 | 1267 |
1268 |
1269 |
1270 |
1271 |
1272 |

None is not Zero: None is a special variable indicating that no value was assigned or that a behavior is undefined. It is different than the value zero, an empty string, or some other nil value.

1273 |

You can check that it is not zero by trying to add it to a number. Let's see what happens when we try that:

1274 | 1275 |
1276 |
1277 |
1278 |
1279 |
1280 |
In [33]:
1281 |
1282 |
1283 |
a = None
1284 | 
1285 | b = 3
1286 | 
1287 | 1288 |
1289 |
1290 |
1291 | 1292 |
1293 |
1294 |
1295 |
In [34]:
1296 |
1297 |
1298 |
a + b
1299 | 
1300 | 1301 |
1302 |
1303 |
1304 | 1305 |
1306 |
1307 | 1308 | 1309 |
1310 | 1311 |
1312 | 1313 | 1314 |
1315 |
1316 | ---------------------------------------------------------------------------
1317 | TypeError                                 Traceback (most recent call last)
1318 | <ipython-input-34-f96fb8f649b6> in <module>()
1319 | ----> 1 a + b
1320 | 
1321 | TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
1322 |
1323 |
1324 | 1325 |
1326 |
1327 | 1328 |
1329 |
1330 |
1331 |
1332 |
1333 |

Logical and comparison operators

The Python comparison operators are: <, <=, >, >=, ==, !=. They compare two objects and return either True or False: smaller than, smaller or equal, greater than, greater or equal, equal, not equal. Try it!

1334 | 1335 |
1336 |
1337 |
1338 |
1339 |
1340 |
In [35]:
1341 |
1342 |
1343 |
x = 3
1344 | y = 5
1345 | 
1346 | 1347 |
1348 |
1349 |
1350 | 1351 |
1352 |
1353 |
1354 |
In [36]:
1355 |
1356 |
1357 |
x > y
1358 | 
1359 | 1360 |
1361 |
1362 |
1363 | 1364 |
1365 |
1366 | 1367 | 1368 |
1369 | 1370 |
Out[36]:
1371 | 1372 | 1373 | 1374 | 1375 |
1376 |
False
1377 |
1378 | 1379 |
1380 | 1381 |
1382 |
1383 | 1384 |
1385 |
1386 |
1387 |
1388 |
1389 |

We can assign the truth value of a comparison operation to a new variable name:

1390 | 1391 |
1392 |
1393 |
1394 |
1395 |
1396 |
In [37]:
1397 |
1398 |
1399 |
z = x > y
1400 | 
1401 | 1402 |
1403 |
1404 |
1405 | 1406 |
1407 |
1408 |
1409 |
In [38]:
1410 |
1411 |
1412 |
z
1413 | 
1414 | 1415 |
1416 |
1417 |
1418 | 1419 |
1420 |
1421 | 1422 | 1423 |
1424 | 1425 |
Out[38]:
1426 | 1427 | 1428 | 1429 | 1430 |
1431 |
False
1432 |
1433 | 1434 |
1435 | 1436 |
1437 |
1438 | 1439 |
1440 |
1441 |
1442 |
In [39]:
1443 |
1444 |
1445 |
type(z)
1446 | 
1447 | 1448 |
1449 |
1450 |
1451 | 1452 |
1453 |
1454 | 1455 | 1456 |
1457 | 1458 |
Out[39]:
1459 | 1460 | 1461 | 1462 | 1463 |
1464 |
bool
1465 |
1466 | 1467 |
1468 | 1469 |
1470 |
1471 | 1472 |
1473 |
1474 |
1475 |
1476 |
1477 |

Logical operators are the following: and, or, and not. They work just like English (with the added bonus of being always consistent, not like English speakers!). A logical expression with and is True if both operands are true, and one with or is True when either operand is true. And the keyword not always negates the expression that follows.

1478 |

Let's do some examples:

1479 | 1480 |
1481 |
1482 |
1483 |
1484 |
1485 |
In [40]:
1486 |
1487 |
1488 |
a = 5
1489 | b = 3
1490 | c = 10
1491 | 
1492 | 1493 |
1494 |
1495 |
1496 | 1497 |
1498 |
1499 |
1500 |
In [41]:
1501 |
1502 |
1503 |
a > b and b > c
1504 | 
1505 | 1506 |
1507 |
1508 |
1509 | 1510 |
1511 |
1512 | 1513 | 1514 |
1515 | 1516 |
Out[41]:
1517 | 1518 | 1519 | 1520 | 1521 |
1522 |
False
1523 |
1524 | 1525 |
1526 | 1527 |
1528 |
1529 | 1530 |
1531 |
1532 |
1533 |
1534 |
1535 |

Remember that the logical operator and is True only when both operands are True. In the case above the first operand is True but the second one is False.

1536 |

If we try the or operation using the same operands we should get a True.

1537 | 1538 |
1539 |
1540 |
1541 |
1542 |
1543 |
In [42]:
1544 |
1545 |
1546 |
a > b or b > c
1547 | 
1548 | 1549 |
1550 |
1551 |
1552 | 1553 |
1554 |
1555 | 1556 | 1557 |
1558 | 1559 |
Out[42]:
1560 | 1561 | 1562 | 1563 | 1564 |
1565 |
True
1566 |
1567 | 1568 |
1569 | 1570 |
1571 |
1572 | 1573 |
1574 |
1575 |
1576 |
1577 |
1578 |

And the negation of the second operand results in …

1579 | 1580 |
1581 |
1582 |
1583 |
1584 |
1585 |
In [43]:
1586 |
1587 |
1588 |
not b > c
1589 | 
1590 | 1591 |
1592 |
1593 |
1594 | 1595 |
1596 |
1597 | 1598 | 1599 |
1600 | 1601 |
Out[43]:
1602 | 1603 | 1604 | 1605 | 1606 |
1607 |
True
1608 |
1609 | 1610 |
1611 | 1612 |
1613 |
1614 | 1615 |
1616 |
1617 |
1618 |
1619 |
1620 |

What if we negate the second operand in the and operation above?

1621 |
Note:

Be careful with the order of logical operations. The order of precedence in logic is:

1622 |
    1623 |
  1. Negation
  2. 1624 |
  3. And
  4. 1625 |
  5. Or
  6. 1626 |
1627 |

If you don't rememeber this, make sure to use parentheses to indicate the order you want.

1628 | 1629 |
1630 |
1631 |
1632 |
1633 |
1634 |
1635 |
1636 |
Exercise:

What is happening in the case below? Play around with logical operators and try some examples.

1637 | 1638 |
1639 |
1640 |
1641 |
1642 |
1643 |
In [44]:
1644 |
1645 |
1646 |
a > b and not b > c
1647 | 
1648 | 1649 |
1650 |
1651 |
1652 | 1653 |
1654 |
1655 | 1656 | 1657 |
1658 | 1659 |
Out[44]:
1660 | 1661 | 1662 | 1663 | 1664 |
1665 |
True
1666 |
1667 | 1668 |
1669 | 1670 |
1671 |
1672 | 1673 |
1674 |
1675 |
1676 |
1677 |
1678 |

What we've learned

    1679 |
  • Using the print() function. The concept of function.
  • 1680 |
  • Using Python as a calculator.
  • 1681 |
  • Concepts of variable, type, assignment.
  • 1682 |
  • Special variables: True, False, None.
  • 1683 |
  • Supported operations, logical operations.
  • 1684 |
  • Reading error messages.
  • 1685 |
1686 | 1687 |
1688 |
1689 |
1690 |
1691 |
1692 |
1693 |
1694 |

References

Throughout this course module, we will be drawing from the following references:

1695 |
    1696 |
  1. Effective Computation in Physics: Field Guide to Research with Python (2015). Anthony Scopatz & Kathryn D. Huff. O'Reilly Media, Inc.
  2. 1697 |
  3. Python for Everybody: Exploring Data Using Python 3 (2016). Charles R. Severance. PDF available
  4. 1698 |
  5. Think Python: How to Think Like a Computer Scientist (2012). Allen Downey. Green Tea Press. PDF available
  6. 1699 |
1700 | 1701 |
1702 |
1703 |
1704 |
1705 |
1706 |
1707 |
1708 | 1712 | 1713 |
1714 |
1715 |
1716 |
1717 |
1718 |
In [45]:
1719 |
1720 |
1721 |
# Execute this cell to load the notebook's style sheet, then ignore it
1722 | from IPython.core.display import HTML
1723 | css_file = '../../style/custom.css'
1724 | HTML(open(css_file, "r").read())
1725 | 
1726 | 1727 |
1728 |
1729 |
1730 | 1731 |
1732 |
1733 | 1734 | 1735 |
1736 | 1737 |
Out[45]:
1738 | 1739 | 1740 | 1741 |
1742 | 1743 | 1744 | 1745 | 1873 | 1889 | 1890 |
1891 | 1892 |
1893 | 1894 |
1895 |
1896 | 1897 |
1898 | 1899 | 1900 | 1901 | -------------------------------------------------------------------------------- /xblock_jupyter_viewer/output.txt: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 | 7 |
8 | 9 |
Content under Creative Commons Attribution license CC-BY 4.0, code under BSD 3-Clause License © 2017 L.A. Barba, N.C. Clementi
10 | 11 |
12 | 13 |
14 | 15 |
16 | 17 |
18 | 19 |
20 | 21 |
22 | 23 |
24 | 25 |

Interacting with Python

This is the first lesson in our course "Engineering Computations", a one-semester course for second-year university students. The course uses Python, and assumes no prior programming experience. 26 | 27 | Our first step will be to get you interacting with Python. 28 | 29 | But let's also learn some background.

30 | 31 | 32 | 33 |
34 | 35 |
36 | 37 |
38 | 39 |
40 | 41 |
42 | 43 |
44 | 45 |
46 | 47 |

What is Python?

Python is now 26 years old. Its creator, Guido van Rossum, named it after the British comedy "Monty Python's Flying Circus." His goals for the language were that it be an "an easy and intuitive language just as powerful as major competitors," producing computer code "that is as understandable as plain English."

48 | 49 |

It is a general-purpose language, which means that you can use it for anything: organizing data, scraping the web, creating websites, analyzing sounds, creating games, and of course engineering computations.

50 | 51 |

Python is an interpreted language. This means that you can write Python commands and the computer can execute those instructions directly. Other programming languages—like C, C++ and Fortran—require a previous compilation step: translating the commands into machine language. 52 | 53 | A neat ability of Python is to be used interactively. Fernando Perez) famously created IPython as a side-project during his PhD. We're going to use IPython (the I stands for "interactive") in this lesson.

54 | 55 | 56 | 57 |
58 | 59 |
60 | 61 |
62 | 63 |
64 | 65 |
66 | 67 |
68 | 69 |
70 | 71 |

Why Python?

Because it's fun! With Python, the more you learn, the more you want to learn. 72 | 73 | You can find lots of resources online and, since Python is an open-source project, you'll also find a friendly community of people sharing their knowledge.

74 | 75 |

Python is known as a high-productivity language. As a programmer, you'll need less time to develop a solution with Python than with most languages. 76 | 77 | This is important to always bring up whenever someone complains that "Python is slow." 78 | 79 | Your time is more valuable than a machine's! 80 | 81 | (See the Recommended Readings section at the end.) 82 | 83 | And if we really need to speed up our program, we can re-write the slow parts in a compiled language afterwards. 84 | 85 | Because Python plays well with other languages :–)

86 | 87 |

The top technology companies use Python: Google, Facebook, Dropbox, Wikipedia, Yahoo!, YouTube… And this year, Python took the No. 1 spot in the interactive list of The 2017 Top Programming Languages, by IEEE Spectrum (IEEE is the world's largest technical professional society).

88 | 89 | 90 | 91 |
92 | 93 |
94 | 95 |
96 | 97 |
98 | 99 |
100 | 101 |
102 | 103 |
104 | 105 |

Python is a versatile language, you can analyze data, build websites (e.g., Instagram, Mozilla, Pinterest), make art or music, etc. Because it is a versatile language, employers love Python: if you know Python they will want to hire you. —Jessica McKellar, ex Director of the Python Software Foundation, in a 2014 tutorial.

106 | 107 |
108 | 109 |
110 | 111 |
112 | 113 |
114 | 115 |
116 | 117 |
118 | 119 |
120 | 121 |

Let's get started

In this first lesson, we will be using IPython: a tool for working with Python interactively. If you have it installed in the computer you're using for this lesson, you enter the program by typing

122 | 123 |

ipython

124 | 125 |

on the command-line interface (the Terminal app on Mac OSX, and on Windows possibly the PowerShell or git bash). You will get a few lines of text about your IPython version and how to get help, and a blinking cursor next to the input line counter:

126 | 127 |

In[1]:

128 | 129 |

That input line is ready to receive any Python code to be executed interactively. The output of the code will be shown to you next to Out[1], and so on for successive input/output lines.

130 | 131 |
Note:

Our plan for this course is to work in a computer lab, where everyone will have a computer with everything installed ahead of time. For this reason, we won't discuss installation right now. Later on, when you're eager to work on your personal computer, we'll help you install everything you need. It's all free!

132 | 133 | 134 | 135 |
136 | 137 |
138 | 139 |
140 | 141 |
142 | 143 |
144 | 145 |
146 | 147 |
148 | 149 |

Your first program

In every programming class ever, your first program consists of printing a "Hello" message. In Python, you use the print() function, with your message inside quotation marks.

150 | 151 | 152 | 153 |
154 | 155 |
156 | 157 |
158 | 159 |
160 | 161 |
162 | 163 |
In [1]:
164 | 165 |
166 | 167 |
168 | 169 |
print("Hello world!!")
 170 | 
 171 | 
172 | 173 | 174 | 175 |
176 | 177 |
178 | 179 |
180 | 181 | 182 | 183 |
184 | 185 |
186 | 187 | 188 | 189 | 190 | 191 |
192 | 193 | 194 | 195 |
196 | 197 | 198 | 199 | 200 | 201 |
202 | 203 |
Hello world!!
 204 | 
 205 | 
206 | 207 |
208 | 209 |
210 | 211 | 212 | 213 |
214 | 215 |
216 | 217 | 218 | 219 |
220 | 221 |
222 | 223 |
224 | 225 |
226 | 227 |
228 | 229 |

Easy peasy!! You just wrote your first program and you learned how to use the print() function. Yes, print() is a function: we pass the argument we want the function to act on, inside the parentheses. In the case above, we passed a string, which is a series of characters between quotation marks. Don't worry, we will come back to what strings are later on in this lesson.

230 | 231 | 232 | 233 |
234 | 235 |
236 | 237 |
238 | 239 |
240 | 241 |
242 | 243 |
244 | 245 |
246 | 247 |
Key concept: function

A function is a compact collection of code that executes some action on its arguments. Every Python function has a name, used to call it, and takes its arguments inside round brackets. Some arguments may be optional (which means they have a default value defined inside the function), others are required. For example, the print() function has one required argument: the string of characters it should print out for you.

248 | 249 |

Python comes with many built-in functions, but you can also build your own. Chunking blocks of code into functions is one of the best strategies to deal with complex programs. It makes you more efficient, because you can reuse the code that you wrote into a function. Modularity and reuse are every programmer's friend.

250 | 251 | 252 | 253 |
254 | 255 |
256 | 257 |
258 | 259 |
260 | 261 |
262 | 263 |
264 | 265 |
266 | 267 |

Python as a calculator

Try any arithmetic operation in IPython. The symbols are what you would expect, except for the "raise-to-the-power-of" operator, which you obtain with two asterisks: **. Try all of these:

268 | 269 |
+   -   *   /   **   %   //
 270 | 
 271 | 
272 | 273 |

The % symbol is the modulo operator (divide and return remainder), and the double-slash is floor division.

274 | 275 | 276 | 277 |
278 | 279 |
280 | 281 |
282 | 283 |
284 | 285 |
286 | 287 |
In [2]:
288 | 289 |
290 | 291 |
292 | 293 |
2 + 2
 294 | 
 295 | 
296 | 297 | 298 | 299 |
300 | 301 |
302 | 303 |
304 | 305 | 306 | 307 |
308 | 309 |
310 | 311 | 312 | 313 | 314 | 315 |
316 | 317 | 318 | 319 |
Out[2]:
320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 | 331 |
4
332 | 333 |
334 | 335 | 336 | 337 |
338 | 339 | 340 | 341 |
342 | 343 |
344 | 345 | 346 | 347 |
348 | 349 |
350 | 351 |
352 | 353 |
In [3]:
354 | 355 |
356 | 357 |
358 | 359 |
1.25 + 3.65
 360 | 
 361 | 
362 | 363 | 364 | 365 |
366 | 367 |
368 | 369 |
370 | 371 | 372 | 373 |
374 | 375 |
376 | 377 | 378 | 379 | 380 | 381 |
382 | 383 | 384 | 385 |
Out[3]:
386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 |
396 | 397 |
4.9
398 | 399 |
400 | 401 | 402 | 403 |
404 | 405 | 406 | 407 |
408 | 409 |
410 | 411 | 412 | 413 |
414 | 415 |
416 | 417 |
418 | 419 |
In [4]:
420 | 421 |
422 | 423 |
424 | 425 |
5 - 3
 426 | 
 427 | 
428 | 429 | 430 | 431 |
432 | 433 |
434 | 435 |
436 | 437 | 438 | 439 |
440 | 441 |
442 | 443 | 444 | 445 | 446 | 447 |
448 | 449 | 450 | 451 |
Out[4]:
452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 |
462 | 463 |
2
464 | 465 |
466 | 467 | 468 | 469 |
470 | 471 | 472 | 473 |
474 | 475 |
476 | 477 | 478 | 479 |
480 | 481 |
482 | 483 |
484 | 485 |
In [5]:
486 | 487 |
488 | 489 |
490 | 491 |
2 * 4
 492 | 
 493 | 
494 | 495 | 496 | 497 |
498 | 499 |
500 | 501 |
502 | 503 | 504 | 505 |
506 | 507 |
508 | 509 | 510 | 511 | 512 | 513 |
514 | 515 | 516 | 517 |
Out[5]:
518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 |
528 | 529 |
8
530 | 531 |
532 | 533 | 534 | 535 |
536 | 537 | 538 | 539 |
540 | 541 |
542 | 543 | 544 | 545 |
546 | 547 |
548 | 549 |
550 | 551 |
In [6]:
552 | 553 |
554 | 555 |
556 | 557 |
7 / 2
 558 | 
 559 | 
560 | 561 | 562 | 563 |
564 | 565 |
566 | 567 |
568 | 569 | 570 | 571 |
572 | 573 |
574 | 575 | 576 | 577 | 578 | 579 |
580 | 581 | 582 | 583 |
Out[6]:
584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 |
594 | 595 |
3.5
596 | 597 |
598 | 599 | 600 | 601 |
602 | 603 | 604 | 605 |
606 | 607 |
608 | 609 | 610 | 611 |
612 | 613 |
614 | 615 |
616 | 617 |
In [7]:
618 | 619 |
620 | 621 |
622 | 623 |
2**3
 624 | 
 625 | 
626 | 627 | 628 | 629 |
630 | 631 |
632 | 633 |
634 | 635 | 636 | 637 |
638 | 639 |
640 | 641 | 642 | 643 | 644 | 645 |
646 | 647 | 648 | 649 |
Out[7]:
650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 |
660 | 661 |
8
662 | 663 |
664 | 665 | 666 | 667 |
668 | 669 | 670 | 671 |
672 | 673 |
674 | 675 | 676 | 677 |
678 | 679 |
680 | 681 |
682 | 683 |
684 | 685 |
686 | 687 |

Let's see an interesting case:

688 | 689 | 690 | 691 |
692 | 693 |
694 | 695 |
696 | 697 |
698 | 699 |
700 | 701 |
In [8]:
702 | 703 |
704 | 705 |
706 | 707 |
9**1/2
 708 | 
 709 | 
710 | 711 | 712 | 713 |
714 | 715 |
716 | 717 |
718 | 719 | 720 | 721 |
722 | 723 |
724 | 725 | 726 | 727 | 728 | 729 |
730 | 731 | 732 | 733 |
Out[8]:
734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 |
744 | 745 |
4.5
746 | 747 |
748 | 749 | 750 | 751 |
752 | 753 | 754 | 755 |
756 | 757 |
758 | 759 | 760 | 761 |
762 | 763 |
764 | 765 |
766 | 767 |
768 | 769 |
770 | 771 |
Discuss with your neighbor:

What happened? Isn't $9^{1/2} = 3$? (Raising to the power $1/2$ is the same as taking the square root.) Did Python get this wrong?

772 | 773 |

Compare with this:

774 | 775 | 776 | 777 |
778 | 779 |
780 | 781 |
782 | 783 |
784 | 785 |
786 | 787 |
In [9]:
788 | 789 |
790 | 791 |
792 | 793 |
9**(1/2)
 794 | 
 795 | 
796 | 797 | 798 | 799 |
800 | 801 |
802 | 803 |
804 | 805 | 806 | 807 |
808 | 809 |
810 | 811 | 812 | 813 | 814 | 815 |
816 | 817 | 818 | 819 |
Out[9]:
820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 |
830 | 831 |
3.0
832 | 833 |
834 | 835 | 836 | 837 |
838 | 839 | 840 | 841 |
842 | 843 |
844 | 845 | 846 | 847 |
848 | 849 |
850 | 851 |
852 | 853 |
854 | 855 |
856 | 857 |

Yes! The order of operations matters!

858 | 859 |

If you don't remember what we are talking about, review the Arithmetics/Order of operations. A frequent situation that exposes this is the following:

860 | 861 | 862 | 863 |
864 | 865 |
866 | 867 |
868 | 869 |
870 | 871 |
872 | 873 |
In [10]:
874 | 875 |
876 | 877 |
878 | 879 |
3 + 3 / 2
 880 | 
 881 | 
882 | 883 | 884 | 885 |
886 | 887 |
888 | 889 |
890 | 891 | 892 | 893 |
894 | 895 |
896 | 897 | 898 | 899 | 900 | 901 |
902 | 903 | 904 | 905 |
Out[10]:
906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 |
916 | 917 |
4.5
918 | 919 |
920 | 921 | 922 | 923 |
924 | 925 | 926 | 927 |
928 | 929 |
930 | 931 | 932 | 933 |
934 | 935 |
936 | 937 |
938 | 939 |
In [11]:
940 | 941 |
942 | 943 |
944 | 945 |
(3 + 3) / 2
 946 | 
 947 | 
948 | 949 | 950 | 951 |
952 | 953 |
954 | 955 |
956 | 957 | 958 | 959 |
960 | 961 |
962 | 963 | 964 | 965 | 966 | 967 |
968 | 969 | 970 | 971 |
Out[11]:
972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 |
982 | 983 |
3.0
984 | 985 |
986 | 987 | 988 | 989 |
990 | 991 | 992 | 993 |
994 | 995 |
996 | 997 | 998 | 999 |
1000 | 1001 |
1002 | 1003 |
1004 | 1005 |
1006 | 1007 |
1008 | 1009 |

In the first case, we are adding $3$ plus the number resulting of the operation $3/2$. If we want the division to apply to the result of $3+3$, we need the parentheses.

1010 | 1011 | 1012 | 1013 |
1014 | 1015 |
1016 | 1017 |
1018 | 1019 |
1020 | 1021 |
1022 | 1023 |
1024 | 1025 |
1026 | 1027 |
Exercises:

Use IPython (as a calculator) to solve the following two problems:

1028 | 1029 |
    1030 | 1031 |
  1. The volume of a sphere with radius $r$ is $\frac{4}{3}\pi r^3$. What is the volume of a sphere with diameter 6.65 cm?

    1032 | 1033 |

    For the value of $\pi$ use 3.14159 (for now). Compare your answer with the solution up to 4 decimal numbers.

    1034 | 1035 |

    Hint: 523.5983 is wrong and 615.9184 is also wrong.

    1036 | 1037 |
  2. 1038 | 1039 |
  3. Suppose the cover price of a book is $\$ 24.95$, but bookstores get a $40\%$ discount. Shipping costs $\$3$ for the first copy and $75$ cents for each additional copy. What is the total wholesale cost for $60$ copies? Compare your answer with the solution up to 2 decimal numbers.

    1040 | 1041 |
  4. 1042 | 1043 |
1044 | 1045 | 1046 | 1047 |
1048 | 1049 |
1050 | 1051 |
1052 | 1053 |
1054 | 1055 |
1056 | 1057 |
1058 | 1059 |
1060 | 1061 |

To reveal the answers, highlight the following line of text using the mouse:

1062 | 1063 | 1064 | 1065 |
1066 | 1067 |
1068 | 1069 |
1070 | 1071 |
1072 | 1073 |
1074 | 1075 |
1076 | 1077 |
1078 | 1079 |

Answer exercise 1: 153.9796 Answer exercise 2: 945.45

1080 | 1081 | 1082 | 1083 |
1084 | 1085 |
1086 | 1087 |
1088 | 1089 |
1090 | 1091 |
1092 | 1093 |
1094 | 1095 |
1096 | 1097 |

Variables and their type

Variables consist of two parts: a name and a value. When we want to give a variable its name and value, we use the equal sign: name = value. This is called an assignment. The name of the variable goes on the left and the value on the right.

1098 | 1099 |

The first thing to get used to is that the equal sign in an assignment has a different meaning than it has in Algebra! Think of it as an arrow pointing from name to value.

1100 | 1101 |

1102 | 1103 |

We have many possibilities for variable names: they can be made up of upper and lowercase letters, underscores and digits… although digits cannot go on the front of the name. For example, valid variable names are:

1104 | 1105 |
x
1106 | 
1107 |     x1
1108 | 
1109 |     X_2
1110 | 
1111 |     name_3
1112 | 
1113 |     NameLastname
1114 | 
1115 | 
1116 | 1117 |

Keep in mind, there are reserved words that you can't use; they are the special Python keywords.

1118 | 1119 |

OK. Let's assign some values to variables and do some operations with them:

1120 | 1121 | 1122 | 1123 |
1124 | 1125 |
1126 | 1127 |
1128 | 1129 |
1130 | 1131 |
1132 | 1133 |
In [12]:
1134 | 1135 |
1136 | 1137 |
1138 | 1139 |
x = 3
1140 | 
1141 | 
1142 | 1143 | 1144 | 1145 |
1146 | 1147 |
1148 | 1149 |
1150 | 1151 | 1152 | 1153 |
1154 | 1155 |
1156 | 1157 |
1158 | 1159 |
In [13]:
1160 | 1161 |
1162 | 1163 |
1164 | 1165 |
y = 4.5
1166 | 
1167 | 
1168 | 1169 | 1170 | 1171 |
1172 | 1173 |
1174 | 1175 |
1176 | 1177 | 1178 | 1179 |
1180 | 1181 |
1182 | 1183 |
1184 | 1185 |
1186 | 1187 |
1188 | 1189 |
Exercise:

Print the values of the variables x and y.

1190 | 1191 | 1192 | 1193 |
1194 | 1195 |
1196 | 1197 |
1198 | 1199 |
1200 | 1201 |
1202 | 1203 |
1204 | 1205 |
1206 | 1207 |

Let's do some arithmetic operations with our new variables:

1208 | 1209 | 1210 | 1211 |
1212 | 1213 |
1214 | 1215 |
1216 | 1217 |
1218 | 1219 |
1220 | 1221 |
In [14]:
1222 | 1223 |
1224 | 1225 |
1226 | 1227 |
x + y
1228 | 
1229 | 
1230 | 1231 | 1232 | 1233 |
1234 | 1235 |
1236 | 1237 |
1238 | 1239 | 1240 | 1241 |
1242 | 1243 |
1244 | 1245 | 1246 | 1247 | 1248 | 1249 |
1250 | 1251 | 1252 | 1253 |
Out[14]:
1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 |
1264 | 1265 |
7.5
1266 | 1267 |
1268 | 1269 | 1270 | 1271 |
1272 | 1273 | 1274 | 1275 |
1276 | 1277 |
1278 | 1279 | 1280 | 1281 |
1282 | 1283 |
1284 | 1285 |
1286 | 1287 |
In [15]:
1288 | 1289 |
1290 | 1291 |
1292 | 1293 |
2**x
1294 | 
1295 | 
1296 | 1297 | 1298 | 1299 |
1300 | 1301 |
1302 | 1303 |
1304 | 1305 | 1306 | 1307 |
1308 | 1309 |
1310 | 1311 | 1312 | 1313 | 1314 | 1315 |
1316 | 1317 | 1318 | 1319 |
Out[15]:
1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 |
1330 | 1331 |
8
1332 | 1333 |
1334 | 1335 | 1336 | 1337 |
1338 | 1339 | 1340 | 1341 |
1342 | 1343 |
1344 | 1345 | 1346 | 1347 |
1348 | 1349 |
1350 | 1351 |
1352 | 1353 |
In [16]:
1354 | 1355 |
1356 | 1357 |
1358 | 1359 |
y - 3
1360 | 
1361 | 
1362 | 1363 | 1364 | 1365 |
1366 | 1367 |
1368 | 1369 |
1370 | 1371 | 1372 | 1373 |
1374 | 1375 |
1376 | 1377 | 1378 | 1379 | 1380 | 1381 |
1382 | 1383 | 1384 | 1385 |
Out[16]:
1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 |
1396 | 1397 |
1.5
1398 | 1399 |
1400 | 1401 | 1402 | 1403 |
1404 | 1405 | 1406 | 1407 |
1408 | 1409 |
1410 | 1411 | 1412 | 1413 |
1414 | 1415 |
1416 | 1417 |
1418 | 1419 |
1420 | 1421 |
1422 | 1423 |

And now, let's check the values of x and y. Are they still the same as they were when you assigned them?

1424 | 1425 | 1426 | 1427 |
1428 | 1429 |
1430 | 1431 |
1432 | 1433 |
1434 | 1435 |
1436 | 1437 |
In [17]:
1438 | 1439 |
1440 | 1441 |
1442 | 1443 |
print(x)
1444 | 
1445 | 
1446 | 1447 | 1448 | 1449 |
1450 | 1451 |
1452 | 1453 |
1454 | 1455 | 1456 | 1457 |
1458 | 1459 |
1460 | 1461 | 1462 | 1463 | 1464 | 1465 |
1466 | 1467 | 1468 | 1469 |
1470 | 1471 | 1472 | 1473 | 1474 | 1475 |
1476 | 1477 |
3
1478 | 
1479 | 
1480 | 1481 |
1482 | 1483 |
1484 | 1485 | 1486 | 1487 |
1488 | 1489 |
1490 | 1491 | 1492 | 1493 |
1494 | 1495 |
1496 | 1497 |
1498 | 1499 |
In [18]:
1500 | 1501 |
1502 | 1503 |
1504 | 1505 |
print(y)
1506 | 
1507 | 
1508 | 1509 | 1510 | 1511 |
1512 | 1513 |
1514 | 1515 |
1516 | 1517 | 1518 | 1519 |
1520 | 1521 |
1522 | 1523 | 1524 | 1525 | 1526 | 1527 |
1528 | 1529 | 1530 | 1531 |
1532 | 1533 | 1534 | 1535 | 1536 | 1537 |
1538 | 1539 |
4.5
1540 | 
1541 | 
1542 | 1543 |
1544 | 1545 |
1546 | 1547 | 1548 | 1549 |
1550 | 1551 |
1552 | 1553 | 1554 | 1555 |
1556 | 1557 |
1558 | 1559 |
1560 | 1561 |
1562 | 1563 |
1564 | 1565 |

String variables

In addition to name and value, Python variables have a type: the type of the value it refers to. For example, an integer value has type int, and a real number has type float. A string is a variable consisting of a sequence of characters marked by two quotes, and it has type str.

1566 | 1567 | 1568 | 1569 |
1570 | 1571 |
1572 | 1573 |
1574 | 1575 |
1576 | 1577 |
1578 | 1579 |
In [19]:
1580 | 1581 |
1582 | 1583 |
1584 | 1585 |
z = 'this is a string'
1586 | 
1587 | 
1588 | 1589 | 1590 | 1591 |
1592 | 1593 |
1594 | 1595 |
1596 | 1597 | 1598 | 1599 |
1600 | 1601 |
1602 | 1603 |
1604 | 1605 |
In [20]:
1606 | 1607 |
1608 | 1609 |
1610 | 1611 |
w = '1'
1612 | 
1613 | 
1614 | 1615 | 1616 | 1617 |
1618 | 1619 |
1620 | 1621 |
1622 | 1623 | 1624 | 1625 |
1626 | 1627 |
1628 | 1629 |
1630 | 1631 |
1632 | 1633 |
1634 | 1635 |

What if you try to "add" two strings?

1636 | 1637 | 1638 | 1639 |
1640 | 1641 |
1642 | 1643 |
1644 | 1645 |
1646 | 1647 |
1648 | 1649 |
In [21]:
1650 | 1651 |
1652 | 1653 |
1654 | 1655 |
z + w
1656 | 
1657 | 
1658 | 1659 | 1660 | 1661 |
1662 | 1663 |
1664 | 1665 |
1666 | 1667 | 1668 | 1669 |
1670 | 1671 |
1672 | 1673 | 1674 | 1675 | 1676 | 1677 |
1678 | 1679 | 1680 | 1681 |
Out[21]:
1682 | 1683 | 1684 | 1685 | 1686 | 1687 | 1688 | 1689 | 1690 | 1691 |
1692 | 1693 |
'this is a string1'
1694 | 1695 |
1696 | 1697 | 1698 | 1699 |
1700 | 1701 | 1702 | 1703 |
1704 | 1705 |
1706 | 1707 | 1708 | 1709 |
1710 | 1711 |
1712 | 1713 |
1714 | 1715 |
1716 | 1717 |
1718 | 1719 |

The operation above is called concatenation: chaining two strings together into one. Insteresting, eh? But look at this:

1720 | 1721 | 1722 | 1723 |
1724 | 1725 |
1726 | 1727 |
1728 | 1729 |
1730 | 1731 |
1732 | 1733 |
In [22]:
1734 | 1735 |
1736 | 1737 |
1738 | 1739 |
x + w
1740 | 
1741 | 
1742 | 1743 | 1744 | 1745 |
1746 | 1747 |
1748 | 1749 |
1750 | 1751 | 1752 | 1753 |
1754 | 1755 |
1756 | 1757 | 1758 | 1759 | 1760 | 1761 |
1762 | 1763 | 1764 | 1765 |
1766 | 1767 | 1768 | 1769 | 1770 | 1771 |
1772 | 1773 |
1774 | 
1775 | ---------------------------------------------------------------------------
1776 | 
1777 | TypeError                                 Traceback (most recent call last)
1778 | 
1779 | <ipython-input-22-bc79f95cdaf2> in <module>()
1780 | 
1781 | ----> 1 x + w
1782 | 
1783 | 
1784 | 
1785 | TypeError: unsupported operand type(s) for +: 'int' and 'str'
1786 | 1787 |
1788 | 1789 |
1790 | 1791 | 1792 | 1793 |
1794 | 1795 |
1796 | 1797 | 1798 | 1799 |
1800 | 1801 |
1802 | 1803 |
1804 | 1805 |
1806 | 1807 |
1808 | 1809 |

Error! Why? Let's inspect what Python has to say and explore what is happening.

1810 | 1811 |

Python is a dynamic language, which means that you don't need to specify a type to invoke an existing object. The humorous nickname for this is "duck typing":

1812 | 1813 |

"If it looks like a duck, and quacks like a duck, then it's probably a duck."

In other words, a variable has a type, but we don't need to specify it. It will just behave like it's supposed to when we operate with it (it'll quack and walk like nature intended it to).

1814 | 1815 |

But sometimes you need to make sure you know the type of a variable. Thankfully, Python offers a function to find out the type of a variable: type().

1816 | 1817 | 1818 | 1819 |
1820 | 1821 |
1822 | 1823 |
1824 | 1825 |
1826 | 1827 |
1828 | 1829 |
In [23]:
1830 | 1831 |
1832 | 1833 |
1834 | 1835 |
type(x)
1836 | 
1837 | 
1838 | 1839 | 1840 | 1841 |
1842 | 1843 |
1844 | 1845 |
1846 | 1847 | 1848 | 1849 |
1850 | 1851 |
1852 | 1853 | 1854 | 1855 | 1856 | 1857 |
1858 | 1859 | 1860 | 1861 |
Out[23]:
1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 |
1872 | 1873 |
int
1874 | 1875 |
1876 | 1877 | 1878 | 1879 |
1880 | 1881 | 1882 | 1883 |
1884 | 1885 |
1886 | 1887 | 1888 | 1889 |
1890 | 1891 |
1892 | 1893 |
1894 | 1895 |
In [24]:
1896 | 1897 |
1898 | 1899 |
1900 | 1901 |
type(w)
1902 | 
1903 | 
1904 | 1905 | 1906 | 1907 |
1908 | 1909 |
1910 | 1911 |
1912 | 1913 | 1914 | 1915 |
1916 | 1917 |
1918 | 1919 | 1920 | 1921 | 1922 | 1923 |
1924 | 1925 | 1926 | 1927 |
Out[24]:
1928 | 1929 | 1930 | 1931 | 1932 | 1933 | 1934 | 1935 | 1936 | 1937 |
1938 | 1939 |
str
1940 | 1941 |
1942 | 1943 | 1944 | 1945 |
1946 | 1947 | 1948 | 1949 |
1950 | 1951 |
1952 | 1953 | 1954 | 1955 |
1956 | 1957 |
1958 | 1959 |
1960 | 1961 |
In [25]:
1962 | 1963 |
1964 | 1965 |
1966 | 1967 |
type(y)
1968 | 
1969 | 
1970 | 1971 | 1972 | 1973 |
1974 | 1975 |
1976 | 1977 |
1978 | 1979 | 1980 | 1981 |
1982 | 1983 |
1984 | 1985 | 1986 | 1987 | 1988 | 1989 |
1990 | 1991 | 1992 | 1993 |
Out[25]:
1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 |
2004 | 2005 |
float
2006 | 2007 |
2008 | 2009 | 2010 | 2011 |
2012 | 2013 | 2014 | 2015 |
2016 | 2017 |
2018 | 2019 | 2020 | 2021 |
2022 | 2023 |
2024 | 2025 |
2026 | 2027 |
2028 | 2029 |
2030 | 2031 |

More assignments

What if you want to assign to a new variable the result of an operation that involves other variables? Well, you totally can!

2032 | 2033 | 2034 | 2035 |
2036 | 2037 |
2038 | 2039 |
2040 | 2041 |
2042 | 2043 |
2044 | 2045 |
In [26]:
2046 | 2047 |
2048 | 2049 |
2050 | 2051 |
sum_xy = x + y
2052 | 
2053 | diff_xy = x - y
2054 | 
2055 | 
2056 | 2057 | 2058 | 2059 |
2060 | 2061 |
2062 | 2063 |
2064 | 2065 | 2066 | 2067 |
2068 | 2069 |
2070 | 2071 |
2072 | 2073 |
In [27]:
2074 | 2075 |
2076 | 2077 |
2078 | 2079 |
print('The sum of x and y is:', sum_xy)
2080 | 
2081 | print('The difference between x and y is:', diff_xy)
2082 | 
2083 | 
2084 | 2085 | 2086 | 2087 |
2088 | 2089 |
2090 | 2091 |
2092 | 2093 | 2094 | 2095 |
2096 | 2097 |
2098 | 2099 | 2100 | 2101 | 2102 | 2103 |
2104 | 2105 | 2106 | 2107 |
2108 | 2109 | 2110 | 2111 | 2112 | 2113 |
2114 | 2115 |
The sum of x and y is: 7.5
2116 | 
2117 | The difference between x and y is: -1.5
2118 | 
2119 | 
2120 | 2121 |
2122 | 2123 |
2124 | 2125 | 2126 | 2127 |
2128 | 2129 |
2130 | 2131 | 2132 | 2133 |
2134 | 2135 |
2136 | 2137 |
2138 | 2139 |
2140 | 2141 |
2142 | 2143 |

Notice what we did above: we used the print() function with a string message, followed by a variable, and Python printed a useful combination of the message and the variable value. This is a pro tip! You want to print for humans. Let's now check the type of the new variables we just created above:

2144 | 2145 | 2146 | 2147 |
2148 | 2149 |
2150 | 2151 |
2152 | 2153 |
2154 | 2155 |
2156 | 2157 |
In [28]:
2158 | 2159 |
2160 | 2161 |
2162 | 2163 |
type(sum_xy)
2164 | 
2165 | 
2166 | 2167 | 2168 | 2169 |
2170 | 2171 |
2172 | 2173 |
2174 | 2175 | 2176 | 2177 |
2178 | 2179 |
2180 | 2181 | 2182 | 2183 | 2184 | 2185 |
2186 | 2187 | 2188 | 2189 |
Out[28]:
2190 | 2191 | 2192 | 2193 | 2194 | 2195 | 2196 | 2197 | 2198 | 2199 |
2200 | 2201 |
float
2202 | 2203 |
2204 | 2205 | 2206 | 2207 |
2208 | 2209 | 2210 | 2211 |
2212 | 2213 |
2214 | 2215 | 2216 | 2217 |
2218 | 2219 |
2220 | 2221 |
2222 | 2223 |
In [29]:
2224 | 2225 |
2226 | 2227 |
2228 | 2229 |
type(diff_xy)
2230 | 
2231 | 
2232 | 2233 | 2234 | 2235 |
2236 | 2237 |
2238 | 2239 |
2240 | 2241 | 2242 | 2243 |
2244 | 2245 |
2246 | 2247 | 2248 | 2249 | 2250 | 2251 |
2252 | 2253 | 2254 | 2255 |
Out[29]:
2256 | 2257 | 2258 | 2259 | 2260 | 2261 | 2262 | 2263 | 2264 | 2265 |
2266 | 2267 |
float
2268 | 2269 |
2270 | 2271 | 2272 | 2273 |
2274 | 2275 | 2276 | 2277 |
2278 | 2279 |
2280 | 2281 | 2282 | 2283 |
2284 | 2285 |
2286 | 2287 |
2288 | 2289 |
2290 | 2291 |
2292 | 2293 |
Discuss with your neighbor:

Can you summarize what we did above?

2294 | 2295 | 2296 | 2297 |
2298 | 2299 |
2300 | 2301 |
2302 | 2303 |
2304 | 2305 |
2306 | 2307 |
2308 | 2309 |
2310 | 2311 |

Special variables

Python has special variables that are built into the language. These are: 2312 | 2313 | True, False, None and NotImplemented. 2314 | 2315 | For now, we will look at just the first three of these.

2316 | 2317 |

Boolean variables are used to represent truth values, and they can take one of two possible values: True and False. 2318 | 2319 | Logical expressions return a boolean. Here is the simplest logical expression, using the keyword not:

2320 | 2321 |
not True
2322 | 
2323 | 
2324 | 2325 |

It returns… you guessed it… False.

2326 | 2327 |

The Python function bool() returns a truth value assigned to any argument. Any number other than zero has a truth value of True, as well as any nonempty string or list. The number zero and any empty string or list will have a truth value of False. Explore the bool() function with various arguments.

2328 | 2329 | 2330 | 2331 |
2332 | 2333 |
2334 | 2335 |
2336 | 2337 |
2338 | 2339 |
2340 | 2341 |
In [30]:
2342 | 2343 |
2344 | 2345 |
2346 | 2347 |
bool(0)
2348 | 
2349 | 
2350 | 2351 | 2352 | 2353 |
2354 | 2355 |
2356 | 2357 |
2358 | 2359 | 2360 | 2361 |
2362 | 2363 |
2364 | 2365 | 2366 | 2367 | 2368 | 2369 |
2370 | 2371 | 2372 | 2373 |
Out[30]:
2374 | 2375 | 2376 | 2377 | 2378 | 2379 | 2380 | 2381 | 2382 | 2383 |
2384 | 2385 |
False
2386 | 2387 |
2388 | 2389 | 2390 | 2391 |
2392 | 2393 | 2394 | 2395 |
2396 | 2397 |
2398 | 2399 | 2400 | 2401 |
2402 | 2403 |
2404 | 2405 |
2406 | 2407 |
In [31]:
2408 | 2409 |
2410 | 2411 |
2412 | 2413 |
bool('Do we need oxygen?')
2414 | 
2415 | 
2416 | 2417 | 2418 | 2419 |
2420 | 2421 |
2422 | 2423 |
2424 | 2425 | 2426 | 2427 |
2428 | 2429 |
2430 | 2431 | 2432 | 2433 | 2434 | 2435 |
2436 | 2437 | 2438 | 2439 |
Out[31]:
2440 | 2441 | 2442 | 2443 | 2444 | 2445 | 2446 | 2447 | 2448 | 2449 |
2450 | 2451 |
True
2452 | 2453 |
2454 | 2455 | 2456 | 2457 |
2458 | 2459 | 2460 | 2461 |
2462 | 2463 |
2464 | 2465 | 2466 | 2467 |
2468 | 2469 |
2470 | 2471 |
2472 | 2473 |
In [32]:
2474 | 2475 |
2476 | 2477 |
2478 | 2479 |
bool('We do not need oxygen')
2480 | 
2481 | 
2482 | 2483 | 2484 | 2485 |
2486 | 2487 |
2488 | 2489 |
2490 | 2491 | 2492 | 2493 |
2494 | 2495 |
2496 | 2497 | 2498 | 2499 | 2500 | 2501 |
2502 | 2503 | 2504 | 2505 |
Out[32]:
2506 | 2507 | 2508 | 2509 | 2510 | 2511 | 2512 | 2513 | 2514 | 2515 |
2516 | 2517 |
True
2518 | 2519 |
2520 | 2521 | 2522 | 2523 |
2524 | 2525 | 2526 | 2527 |
2528 | 2529 |
2530 | 2531 | 2532 | 2533 |
2534 | 2535 |
2536 | 2537 |
2538 | 2539 |
2540 | 2541 |
2542 | 2543 |

None is not Zero: None is a special variable indicating that no value was assigned or that a behavior is undefined. It is different than the value zero, an empty string, or some other nil value.

2544 | 2545 |

You can check that it is not zero by trying to add it to a number. Let's see what happens when we try that:

2546 | 2547 | 2548 | 2549 |
2550 | 2551 |
2552 | 2553 |
2554 | 2555 |
2556 | 2557 |
2558 | 2559 |
In [33]:
2560 | 2561 |
2562 | 2563 |
2564 | 2565 |
a = None
2566 | 
2567 | 
2568 | 
2569 | b = 3
2570 | 
2571 | 
2572 | 2573 | 2574 | 2575 |
2576 | 2577 |
2578 | 2579 |
2580 | 2581 | 2582 | 2583 |
2584 | 2585 |
2586 | 2587 |
2588 | 2589 |
In [34]:
2590 | 2591 |
2592 | 2593 |
2594 | 2595 |
a + b
2596 | 
2597 | 
2598 | 2599 | 2600 | 2601 |
2602 | 2603 |
2604 | 2605 |
2606 | 2607 | 2608 | 2609 |
2610 | 2611 |
2612 | 2613 | 2614 | 2615 | 2616 | 2617 |
2618 | 2619 | 2620 | 2621 |
2622 | 2623 | 2624 | 2625 | 2626 | 2627 |
2628 | 2629 |
2630 | 
2631 | ---------------------------------------------------------------------------
2632 | 
2633 | TypeError                                 Traceback (most recent call last)
2634 | 
2635 | <ipython-input-34-f96fb8f649b6> in <module>()
2636 | 
2637 | ----> 1 a + b
2638 | 
2639 | 
2640 | 
2641 | TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
2642 | 2643 |
2644 | 2645 |
2646 | 2647 | 2648 | 2649 |
2650 | 2651 |
2652 | 2653 | 2654 | 2655 |
2656 | 2657 |
2658 | 2659 |
2660 | 2661 |
2662 | 2663 |
2664 | 2665 |

Logical and comparison operators

The Python comparison operators are: <, <=, >, >=, ==, !=. They compare two objects and return either True or False: smaller than, smaller or equal, greater than, greater or equal, equal, not equal. Try it!

2666 | 2667 | 2668 | 2669 |
2670 | 2671 |
2672 | 2673 |
2674 | 2675 |
2676 | 2677 |
2678 | 2679 |
In [35]:
2680 | 2681 |
2682 | 2683 |
2684 | 2685 |
x = 3
2686 | 
2687 | y = 5
2688 | 
2689 | 
2690 | 2691 | 2692 | 2693 |
2694 | 2695 |
2696 | 2697 |
2698 | 2699 | 2700 | 2701 |
2702 | 2703 |
2704 | 2705 |
2706 | 2707 |
In [36]:
2708 | 2709 |
2710 | 2711 |
2712 | 2713 |
x > y
2714 | 
2715 | 
2716 | 2717 | 2718 | 2719 |
2720 | 2721 |
2722 | 2723 |
2724 | 2725 | 2726 | 2727 |
2728 | 2729 |
2730 | 2731 | 2732 | 2733 | 2734 | 2735 |
2736 | 2737 | 2738 | 2739 |
Out[36]:
2740 | 2741 | 2742 | 2743 | 2744 | 2745 | 2746 | 2747 | 2748 | 2749 |
2750 | 2751 |
False
2752 | 2753 |
2754 | 2755 | 2756 | 2757 |
2758 | 2759 | 2760 | 2761 |
2762 | 2763 |
2764 | 2765 | 2766 | 2767 |
2768 | 2769 |
2770 | 2771 |
2772 | 2773 |
2774 | 2775 |
2776 | 2777 |

We can assign the truth value of a comparison operation to a new variable name:

2778 | 2779 | 2780 | 2781 |
2782 | 2783 |
2784 | 2785 |
2786 | 2787 |
2788 | 2789 |
2790 | 2791 |
In [37]:
2792 | 2793 |
2794 | 2795 |
2796 | 2797 |
z = x > y
2798 | 
2799 | 
2800 | 2801 | 2802 | 2803 |
2804 | 2805 |
2806 | 2807 |
2808 | 2809 | 2810 | 2811 |
2812 | 2813 |
2814 | 2815 |
2816 | 2817 |
In [38]:
2818 | 2819 |
2820 | 2821 |
2822 | 2823 |
z
2824 | 
2825 | 
2826 | 2827 | 2828 | 2829 |
2830 | 2831 |
2832 | 2833 |
2834 | 2835 | 2836 | 2837 |
2838 | 2839 |
2840 | 2841 | 2842 | 2843 | 2844 | 2845 |
2846 | 2847 | 2848 | 2849 |
Out[38]:
2850 | 2851 | 2852 | 2853 | 2854 | 2855 | 2856 | 2857 | 2858 | 2859 |
2860 | 2861 |
False
2862 | 2863 |
2864 | 2865 | 2866 | 2867 |
2868 | 2869 | 2870 | 2871 |
2872 | 2873 |
2874 | 2875 | 2876 | 2877 |
2878 | 2879 |
2880 | 2881 |
2882 | 2883 |
In [39]:
2884 | 2885 |
2886 | 2887 |
2888 | 2889 |
type(z)
2890 | 
2891 | 
2892 | 2893 | 2894 | 2895 |
2896 | 2897 |
2898 | 2899 |
2900 | 2901 | 2902 | 2903 |
2904 | 2905 |
2906 | 2907 | 2908 | 2909 | 2910 | 2911 |
2912 | 2913 | 2914 | 2915 |
Out[39]:
2916 | 2917 | 2918 | 2919 | 2920 | 2921 | 2922 | 2923 | 2924 | 2925 |
2926 | 2927 |
bool
2928 | 2929 |
2930 | 2931 | 2932 | 2933 |
2934 | 2935 | 2936 | 2937 |
2938 | 2939 |
2940 | 2941 | 2942 | 2943 |
2944 | 2945 |
2946 | 2947 |
2948 | 2949 |
2950 | 2951 |
2952 | 2953 |

Logical operators are the following: and, or, and not. They work just like English (with the added bonus of being always consistent, not like English speakers!). A logical expression with and is True if both operands are true, and one with or is True when either operand is true. And the keyword not always negates the expression that follows.

2954 | 2955 |

Let's do some examples:

2956 | 2957 | 2958 | 2959 |
2960 | 2961 |
2962 | 2963 |
2964 | 2965 |
2966 | 2967 |
2968 | 2969 |
In [40]:
2970 | 2971 |
2972 | 2973 |
2974 | 2975 |
a = 5
2976 | 
2977 | b = 3
2978 | 
2979 | c = 10
2980 | 
2981 | 
2982 | 2983 | 2984 | 2985 |
2986 | 2987 |
2988 | 2989 |
2990 | 2991 | 2992 | 2993 |
2994 | 2995 |
2996 | 2997 |
2998 | 2999 |
In [41]:
3000 | 3001 |
3002 | 3003 |
3004 | 3005 |
a > b and b > c
3006 | 
3007 | 
3008 | 3009 | 3010 | 3011 |
3012 | 3013 |
3014 | 3015 |
3016 | 3017 | 3018 | 3019 |
3020 | 3021 |
3022 | 3023 | 3024 | 3025 | 3026 | 3027 |
3028 | 3029 | 3030 | 3031 |
Out[41]:
3032 | 3033 | 3034 | 3035 | 3036 | 3037 | 3038 | 3039 | 3040 | 3041 |
3042 | 3043 |
False
3044 | 3045 |
3046 | 3047 | 3048 | 3049 |
3050 | 3051 | 3052 | 3053 |
3054 | 3055 |
3056 | 3057 | 3058 | 3059 |
3060 | 3061 |
3062 | 3063 |
3064 | 3065 |
3066 | 3067 |
3068 | 3069 |

Remember that the logical operator and is True only when both operands are True. In the case above the first operand is True but the second one is False.

3070 | 3071 |

If we try the or operation using the same operands we should get a True.

3072 | 3073 | 3074 | 3075 |
3076 | 3077 |
3078 | 3079 |
3080 | 3081 |
3082 | 3083 |
3084 | 3085 |
In [42]:
3086 | 3087 |
3088 | 3089 |
3090 | 3091 |
a > b or b > c
3092 | 
3093 | 
3094 | 3095 | 3096 | 3097 |
3098 | 3099 |
3100 | 3101 |
3102 | 3103 | 3104 | 3105 |
3106 | 3107 |
3108 | 3109 | 3110 | 3111 | 3112 | 3113 |
3114 | 3115 | 3116 | 3117 |
Out[42]:
3118 | 3119 | 3120 | 3121 | 3122 | 3123 | 3124 | 3125 | 3126 | 3127 |
3128 | 3129 |
True
3130 | 3131 |
3132 | 3133 | 3134 | 3135 |
3136 | 3137 | 3138 | 3139 |
3140 | 3141 |
3142 | 3143 | 3144 | 3145 |
3146 | 3147 |
3148 | 3149 |
3150 | 3151 |
3152 | 3153 |
3154 | 3155 |

And the negation of the second operand results in …

3156 | 3157 | 3158 | 3159 |
3160 | 3161 |
3162 | 3163 |
3164 | 3165 |
3166 | 3167 |
3168 | 3169 |
In [43]:
3170 | 3171 |
3172 | 3173 |
3174 | 3175 |
not b > c
3176 | 
3177 | 
3178 | 3179 | 3180 | 3181 |
3182 | 3183 |
3184 | 3185 |
3186 | 3187 | 3188 | 3189 |
3190 | 3191 |
3192 | 3193 | 3194 | 3195 | 3196 | 3197 |
3198 | 3199 | 3200 | 3201 |
Out[43]:
3202 | 3203 | 3204 | 3205 | 3206 | 3207 | 3208 | 3209 | 3210 | 3211 |
3212 | 3213 |
True
3214 | 3215 |
3216 | 3217 | 3218 | 3219 |
3220 | 3221 | 3222 | 3223 |
3224 | 3225 |
3226 | 3227 | 3228 | 3229 |
3230 | 3231 |
3232 | 3233 |
3234 | 3235 |
3236 | 3237 |
3238 | 3239 |

What if we negate the second operand in the and operation above?

3240 | 3241 |
Note:

Be careful with the order of logical operations. The order of precedence in logic is:

3242 | 3243 |
    3244 | 3245 |
  1. Negation
  2. 3246 | 3247 |
  3. And
  4. 3248 | 3249 |
  5. Or
  6. 3250 | 3251 |
3252 | 3253 |

If you don't rememeber this, make sure to use parentheses to indicate the order you want.

3254 | 3255 | 3256 | 3257 |
3258 | 3259 |
3260 | 3261 |
3262 | 3263 |
3264 | 3265 |
3266 | 3267 |
3268 | 3269 |
3270 | 3271 |
Exercise:

What is happening in the case below? Play around with logical operators and try some examples.

3272 | 3273 | 3274 | 3275 |
3276 | 3277 |
3278 | 3279 |
3280 | 3281 |
3282 | 3283 |
3284 | 3285 |
In [44]:
3286 | 3287 |
3288 | 3289 |
3290 | 3291 |
a > b and not b > c
3292 | 
3293 | 
3294 | 3295 | 3296 | 3297 |
3298 | 3299 |
3300 | 3301 |
3302 | 3303 | 3304 | 3305 |
3306 | 3307 |
3308 | 3309 | 3310 | 3311 | 3312 | 3313 |
3314 | 3315 | 3316 | 3317 |
Out[44]:
3318 | 3319 | 3320 | 3321 | 3322 | 3323 | 3324 | 3325 | 3326 | 3327 |
3328 | 3329 |
True
3330 | 3331 |
3332 | 3333 | 3334 | 3335 |
3336 | 3337 | 3338 | 3339 |
3340 | 3341 |
3342 | 3343 | 3344 | 3345 |
3346 | 3347 |
3348 | 3349 |
3350 | 3351 |
3352 | 3353 |
3354 | 3355 |

What we've learned

    3356 | 3357 |
  • Using the print() function. The concept of function.
  • 3358 | 3359 |
  • Using Python as a calculator.
  • 3360 | 3361 |
  • Concepts of variable, type, assignment.
  • 3362 | 3363 |
  • Special variables: True, False, None.
  • 3364 | 3365 |
  • Supported operations, logical operations.
  • 3366 | 3367 |
  • Reading error messages.
  • 3368 | 3369 |
3370 | 3371 | 3372 | 3373 |
3374 | 3375 |
3376 | 3377 |
3378 | 3379 |
3380 | 3381 |
3382 | 3383 |
3384 | 3385 |
3386 | 3387 |

References

Throughout this course module, we will be drawing from the following references:

3388 | 3389 |
    3390 | 3391 |
  1. Effective Computation in Physics: Field Guide to Research with Python (2015). Anthony Scopatz & Kathryn D. Huff. O'Reilly Media, Inc.
  2. 3392 | 3393 |
  3. Python for Everybody: Exploring Data Using Python 3 (2016). Charles R. Severance. PDF available
  4. 3394 | 3395 |
  5. Think Python: How to Think Like a Computer Scientist (2012). Allen Downey. Green Tea Press. PDF available
  6. 3396 | 3397 |
3398 | 3399 | 3400 | 3401 |
3402 | 3403 |
3404 | 3405 |
3406 | 3407 |
3408 | 3409 |
3410 | 3411 |
3412 | 3413 |
3414 | 3415 | 3422 | 3423 | 3424 | 3425 |
3426 | 3427 |
3428 | 3429 |
3430 | 3431 |
3432 | 3433 |
3434 | 3435 |
In [45]:
3436 | 3437 |
3438 | 3439 |
3440 | 3441 |
# Execute this cell to load the notebook's style sheet, then ignore it
3442 | 
3443 | from IPython.core.display import HTML
3444 | 
3445 | css_file = '../../style/custom.css'
3446 | 
3447 | HTML(open(css_file, "r").read())
3448 | 
3449 | 
3450 | 3451 | 3452 | 3453 |
3454 | 3455 |
3456 | 3457 |
3458 | 3459 | 3460 | 3461 |
3462 | 3463 |
3464 | 3465 | 3466 | 3467 | 3468 | 3469 |
3470 | 3471 | 3472 | 3473 |
Out[45]:
3474 | 3475 | 3476 | 3477 | 3478 | 3479 | 3480 | 3481 |
3482 | 3483 | 3484 | 3485 | 3486 | 3487 | 3488 | 3489 | 3744 | 3745 | 3776 | 3777 | 3778 | 3779 |
3780 | 3781 | 3782 | 3783 |
3784 | 3785 | 3786 | 3787 |
3788 | 3789 |
3790 | 3791 | 3792 | 3793 |
3794 | 3795 | 3796 | 3797 | 3798 | 3799 | 3800 | 3801 | INFO:__main__:Fetching URL: https://raw.githubusercontent.com/engineersCode/EngComp/master/modules/1_offtheground/1_Interacting_with_Python.ipynb 3802 | 3803 | INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): raw.githubusercontent.com 3804 | 3805 | DEBUG:requests.packages.urllib3.connectionpool:"GET /engineersCode/EngComp/master/modules/1_offtheground/1_Interacting_with_Python.ipynb HTTP/1.1" 200 9686 3806 | 3807 | DEBUG:traitlets:Applying preprocessor: TagRemovePreprocessor 3808 | 3809 | DEBUG:traitlets:Applying preprocessor: RegexRemovePreprocessor 3810 | 3811 | DEBUG:traitlets:Applying preprocessor: coalesce_streams 3812 | 3813 | DEBUG:traitlets:Applying preprocessor: CSSHTMLHeaderPreprocessor 3814 | 3815 | DEBUG:traitlets:Applying preprocessor: HighlightMagicsPreprocessor 3816 | 3817 | DEBUG:traitlets:Attempting to load template basic 3818 | 3819 | DEBUG:traitlets: template_path: . 3820 | 3821 | --------------------------------------------------------------------------------