diff --git a/000_Welcome_on_Board.ipynb b/000_Welcome_on_Board.ipynb index d089b43..445b996 100644 --- a/000_Welcome_on_Board.ipynb +++ b/000_Welcome_on_Board.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Welcome on Board!" ] }, @@ -676,14 +676,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "These notebooks have a virtual gathering place on [Piazza.com](https://piazza.com/e-learning_python_for_ocean_mapping/summer2019/om000/home) where you can ask (but also answer!) questions to instructors and fellow students." + "These notebooks have a virtual gathering place on [Piazza.com](https://piazza.com/class/js5dnu0q39n6qe) where you can ask (but also answer!) questions to instructors and fellow students." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "\"Piazza.com\\\"" + "\"Piazza.com\\\"" ] }, { @@ -692,14 +692,21 @@ "source": [ "\n", "\n", - "A red megaphone at the top-right corner of each notebook provides a link to [Piazza.com](https://piazza.com/e-learning_python_for_ocean_mapping/summer2019/om000/home). " + "A red megaphone at the top-right corner of each notebook provides a link to [Piazza.com](https://piazza.com/class/js5dnu0q39n6qe). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "If you click on this [Piazza.com](https://piazza.com/e-learning_python_for_ocean_mapping/summer2019/om000/home) link, you can register yourself as a student to access the virtual gathering place.\n", + "You can learn more about Piazza.com by watching [this video](https://www.youtube.com/watch?v=2jLSiN8E18w)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you click on this [Piazza.com](https://piazza.com/class/js5dnu0q39n6qe) link, you can register yourself as a student to access the virtual gathering place.\n", "\n", "Once registered, what about introducing yourself to the community?" ] @@ -713,7 +720,7 @@ "source": [ "\n", "\n", - "Add a note containing your self-introduction in the \"community\" folder on [Piazza.com](https://piazza.com/e-learning_python_for_ocean_mapping/summer2019/om000/home). The following image shows how to do it in eight steps. Feel free to customize the text in the note as you prefer!\n", + "Add a note containing your self-introduction in the \"community\" folder on [Piazza.com](https://piazza.com/class/js5dnu0q39n6qe). The following image shows how to do it in eight steps. Feel free to customize the text in the note as you prefer!\n", "

\n", "![Seven steps for a self-introduction note](images/000_250_eight_steps.png)" ] diff --git a/001_Variables_and_Types.ipynb b/001_Variables_and_Types.ipynb index e3883a8..33ffe84 100644 --- a/001_Variables_and_Types.ipynb +++ b/001_Variables_and_Types.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Variables and Types" ] }, diff --git a/002_Lists_of_Variables.ipynb b/002_Lists_of_Variables.ipynb index 88d0b6b..30627ed 100644 --- a/002_Lists_of_Variables.ipynb +++ b/002_Lists_of_Variables.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Lists of Variables" ] }, @@ -737,7 +737,7 @@ "outputs": [], "source": [ "cetaceans_list = [\"Bowhead whale\", \"North Atlantic right whale\", \"North Pacific right whale\", \"Southern right whale\"]\n", - "cetaceans_list.remove(\"North Atlantic right whale\")\n", + "cetaceans_list.remove(\"North Pacific right whale\")\n", "nr_or_cetaceans = len(cetaceans_list)\n", "print(nr_or_cetaceans)" ] diff --git a/003_Conditional_Execution.ipynb b/003_Conditional_Execution.ipynb index 8acdee1..504deb9 100644 --- a/003_Conditional_Execution.ipynb +++ b/003_Conditional_Execution.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Conditional Execution" ] }, @@ -689,14 +689,14 @@ "outputs": [], "source": [ "cur_strength = 5.5 # m/s\n", - "cur_type = \"unknown\"\n", + "cur_type = \"Unknown\"\n", "\n", "if cur_strength < 1.0:\n", - " cur_type = \"weak\"\n", + " cur_type = \"Weak\"\n", "elif cur_strength < 5.0:\n", - " cur_type = \"moderate\"\n", + " cur_type = \"Moderate\"\n", "else: # any current >= 5.0\n", - " cur_type = \"strong\"\n", + " cur_type = \"Strong\"\n", " \n", "print(cur_type)" ] @@ -708,7 +708,7 @@ "outputs": [], "source": [ "cur_strength = 5.5 # m/s\n", - "cur_type = \"unknown\"" + "cur_type = \"Unknown\"" ] }, { diff --git a/004_Loops.ipynb b/004_Loops.ipynb index e60df06..2785e43 100644 --- a/004_Loops.ipynb +++ b/004_Loops.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Loops" ] }, @@ -303,7 +303,7 @@ " if (ss_value < 1400.0) or (ss_value > 1600.0):\n", " continue\n", " \n", - " print(\"Sound speed: \" + str(ss_value) + \" m/sec.\")" + " print(\"Sound speed: \" + str(ss_value) + \" m/s.\")" ] }, { diff --git a/005_Write_Your_Own_Functions.ipynb b/005_Write_Your_Own_Functions.ipynb index e19951d..4f16532 100644 --- a/005_Write_Your_Own_Functions.ipynb +++ b/005_Write_Your_Own_Functions.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Functions" ] }, diff --git a/006_Read_and_Write_Text_Files.ipynb b/006_Read_and_Write_Text_Files.ipynb index 108fc30..50704a8 100644 --- a/006_Read_and_Write_Text_Files.ipynb +++ b/006_Read_and_Write_Text_Files.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Read and Write Text Files" ] }, @@ -19,7 +19,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "You have learned about lists and how to write your own functions with loops and conditional statements. This allows you to write programs performing a variety of tasks. \n", + "You have learned about lists and how to [write your own functions](005_Write_Your_Own_Functions.ipynb) with [loops](004_Loops.ipynb) and [conditional statements](003_Conditional_Execution.ipynb). This allows you to write programs performing a variety of tasks. \n", "\n", "However, a convenient mechanism to access data that you want to analyze is currently missing. In this notebook, we will explore the use of [files](https://en.wikipedia.org/wiki/Computer_file) since they are a common way to access stored data." ] @@ -78,7 +78,7 @@ "source": [ "\n", "\n", - "In Python, a **module** is a file containing definitions and statements. " + "In Python, a **module** is a file containing code (e.g., definitions and statements). " ] }, { @@ -183,7 +183,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "To be able to access the `data` sub-folder, we extend the previous code using `os.path.join()` and `os.path.exist()` functions to:\n", + "To be able to access the `data` sub-folder, we extend the previous code using `os.path.join()` and `os.path.exists()` functions to:\n", "\n", "- Create the absolute path to the `data` sub-folder.\n", "- Check whether the resulting path actually exists." @@ -242,7 +242,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We will now retrieve all the paths to the files in the `data` folder. Specifically, we will create a function `get_data_paths()` that returns a list containing all the files in that folder, using the `os.listdir()` function." + "We will now retrieve all the paths to the files in the `data` folder. Specifically, we will create a function `get_data_paths()` that returns a list containing all the files in that folder, using the `os.listdir()` function from the `os` module." ] }, { @@ -251,6 +251,8 @@ "metadata": {}, "outputs": [], "source": [ + "import os\n", + "\n", "def get_data_paths():\n", " data_paths = list() # create an empty list to be populated and returned\n", " data_folder = get_data_folder() # call the function you created to return the data directory path\n", @@ -289,7 +291,7 @@ "source": [ "\n", "\n", - "You do not need to remember all the names of the available Python functions, but you need to learn how to search for them. The [official Python documentation](https://docs.python.org/3.6/index.html) is a good place to start. You can also get a list of the functions in the `os.path` module by entering `dir('os.path')` in a code cell." + "You do not need to remember all the names of the available Python functions, but you need to learn how to search for them. The [official Python documentation](https://docs.python.org/3.6/index.html) is a good place to start. You can also get a list of the functions in the `os.path` module by entering `dir(os.path)` in a code cell." ] }, { @@ -428,7 +430,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "You may ask why there are 100 characters instead of 80? Each of the 20 rows has 4 visible characters (e.g., `30.8`), but there is also the invisible [newline character](https://en.wikipedia.org/wiki/Newline) (i.e., `\\n`) that text editors treat as a new line. Thus, `(4+1) * 20 = 100` characters." + "You may ask why there are 100 characters instead of 80? Each of the 20 rows has 4 visible characters (e.g., `30.8`), but there is also the invisible [newline character](https://en.wikipedia.org/wiki/Newline) (i.e., `\\n`) that text editors treat as a break between two lines. Thus, `(4+1) * 20 = 100` characters." ] }, { @@ -659,7 +661,7 @@ { "cell_type": "markdown", "metadata": { - "solution2": "shown", + "solution2": "hidden", "solution2_first": true }, "source": [ @@ -672,7 +674,7 @@ "cell_type": "code", "execution_count": null, "metadata": { - "solution2": "shown" + "solution2": "hidden" }, "outputs": [], "source": [ diff --git a/007_Dictionaries_and_Metadata.ipynb b/007_Dictionaries_and_Metadata.ipynb index 8bad430..53c4045 100644 --- a/007_Dictionaries_and_Metadata.ipynb +++ b/007_Dictionaries_and_Metadata.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Dictionaries" ] }, @@ -73,7 +73,7 @@ "\n", "- All the item pairs are printed between curly brackets (i.e., `{`, `}`). \n", "- The items are separated by a comma (e.g., the pair `\"Li\": \"Lithium\"` is an item). \n", - "- For each item, the two parts are separated by a `-`: the key on the left (e.g., `\"Li\"`) and the value on the right (e.g., `\"Lithium\"`).\n" + "- For each item, the two parts are separated by a `:` with the key (e.g., `\"Li\"`) on the left and the value (e.g., `\"Lithium\"`) on the right." ] }, { @@ -134,13 +134,6 @@ "By now, you may have noticed that the `str` variables in the above `chem_dict` are printed within single quotes `'` rather than double quotes `\"`. This is an alternative and valid way to define strings in Python. However, mixing `'` and `\"` in the same string results in an error. For consistency, we always use `\"` here." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## A `dict` is unordered" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -148,22 +141,13 @@ "When you print the content of a dictionary, you may have the items presented in an order that differs from the one that you used to populate the `dict`. This is **not** an error, but a specific property of a `dict`." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "A `dict` is an **unordered** container. The order of items insertion is not preserved." - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", - "If you need to preserve the items order, Python provides a special dictionary called [`OrderedDict`](https://docs.python.org/3.6/library/collections.html?highlight=ordereddict#ordereddict-objects)." + "A `dict` is an **unordered** container. The order of items insertion is not preserved. If you need to preserve the items order, Python provides a special dictionary called [`OrderedDict`](https://docs.python.org/3.6/library/collections.html?highlight=ordereddict#ordereddict-objects)." ] }, { diff --git a/008_A_Class_as_a_Data_Container.ipynb b/008_A_Class_as_a_Data_Container.ipynb index b7e784b..24eb6b1 100644 --- a/008_A_Class_as_a_Data_Container.ipynb +++ b/008_A_Class_as_a_Data_Container.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# A Class as a Data Container" ] }, @@ -349,7 +349,7 @@ "source": [ "\n", "\n", - "If you are interested in learning more about classes, you may read [this supplemental notebook](SUP_First_Steps_of_a_Class.ipynb)." + "If you are interested in learning more about classes, you may want to explore the [Introduction to Ocean Data Science](https://www.hydroffice.org/manuals/epom/ocean_data_science_quickstart.html) notebooks." ] }, { @@ -373,7 +373,8 @@ "metadata": {}, "source": [ "* [The official Python 3.6 documentation](https://docs.python.org/3.6/index.html)\n", - " * [Classes](https://docs.python.org/3.6/tutorial/classes.html)" + " * [Classes](https://docs.python.org/3.6/tutorial/classes.html)\n", + "* [Foundations of Ocean Data Science](https://www.hydroffice.org/manuals/epom/foundations_of_ocean_data_science.html)" ] }, { diff --git a/009_Summing-Up.ipynb b/009_Summing-Up.ipynb index 4159329..94ae105 100644 --- a/009_Summing-Up.ipynb +++ b/009_Summing-Up.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Summing-Up" ] }, @@ -258,7 +258,7 @@ "\n", "We can check the success of this operation by printing depths and sound speed values. We will do this by accessing the values by index with the help of the [`range()`](https://docs.python.org/3.6/library/stdtypes.html?#range) type.\n", "\n", - "A `range()` with an integer value as single parameter represents a sequence of numbers ranging from 0 to the value passed as a parameter. In the code below, we use `range` with `10`:" + "A `range()` with an integer value as single parameter represents a sequence of numbers ranging from 0 up to (but not including) the value passed as a parameter. In the code below, we use `range` with `10`:" ] }, { diff --git a/LICENSE b/LICENSE index 65c5ca8..0a04128 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. diff --git a/SUP_First_Steps_of_a_Class.ipynb b/SUP_First_Steps_of_a_Class.ipynb deleted file mode 100644 index 442c643..0000000 --- a/SUP_First_Steps_of_a_Class.ipynb +++ /dev/null @@ -1,608 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"ePOM\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"ePOM\"\n", - "# First Steps of a Class" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is time to learn how to define your own type! " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Creating your own type is a bit more complicated than writing functions, but it comes with big advantages that will be apparent soon." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "A user-defined type is called a **class**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We used several built-in types (e.g., `int`, `str`, `list`), thus you should have some familiarity with the concepts that we are going to introduce. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "A class provides a powerful means of bundling data and functionalities together." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will learn how to create a class by example. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Class Definition and Instantiation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Assuming that we want to create a class that is able to read and write the content of the `sal.txt` file cited in the [previous notebook](007_Read_and_Write_Text_Files.ipynb). As such, we will call this new class `SalinityManager`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is what we need to define such a class:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class SalinityManager:\n", - " \"\"\"A file manager for salinity\"\"\" # This is a docstring" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The first line of the above code contains: the `class` keyword, the class name (`SalinityManager`), and a `:`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The second line is a special text, called `docstring`, that provides a brief description of the class. The description is between `\"\"\" \"\"\"` (i.e., triple quotes)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "A class definition always starts with the `class` keyword. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Once defined, we can create an instance of the `SalinityManager` class, by calling it with `()` at the end:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sal_mng = SalinityManager()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "A **class** is like a **factory** for creating new instances of a given type." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "**Class instances** are commonly called **objects**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "type(sal_mng)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Because the `SalinityManager` class is defined in this \"main\" notebook, the full name of the type is `__main__.SalinityManager`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "At the moment, this new defined class is not that exciting. We will soon start to populate it with a number of useful **methods** and **attributes**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "The attributes are used to maintain the state of each class instance. The methods may modify the attributes and thus its state." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "The **methods** definition **always** has `self` as first parameter. The `self` is absent in the generic **functions** that we have seen in the [Write Your Own Functions notebook](005_Write_Your_Own_Functions.ipynb)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Class Initialization and Attributes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "The **class initialization** happens within a special method called `__init__(self)`. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you don't provide a `__init__(self)` method (like in the above code), Python will create an implicit one for you." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the `__init__(self)` method, you should declare all the **class attributes**. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "A **class attribute** is a variable that will be present in each object instantiated from a given class." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class SalinityManager:\n", - " \"\"\"A file manager for salinity\"\"\"\n", - " \n", - " def __init__(self):\n", - " self.sal_values = list()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above code, we declared that the class has an attribute named `sal_values` and that it will be initialized as an empty list." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "You can access the class attributes by using the `.` operator:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sal_mng = SalinityManager()\n", - "print(sal_mng.sal_values)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Initialization Parameters" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It is often the case that you want to pass some parameters to the class constructor. Those parameters are the ones that you define in the `__init__()` method:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class SalinityManager:\n", - " \"\"\"A file manager for salinity\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.sal_values = list()\n", - " self.sal_path = data_path\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above `__init__(self, data_path)`, the second parameter (`data_path`) becomes a mandatory parameter to be passed to the class constructor. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For being able to pass a valid `data_path` parameter, we will use an helper function based on the [previous notebook](005_Write_Your_Own_Functions.ipynb): " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - " \n", - "def get_data_paths():\n", - " data_paths = list()\n", - " cur_folder = os.path.abspath(os.path.curdir)\n", - " data_folder = os.path.join(cur_folder, \"data\")\n", - " data_filenames = os.listdir(data_folder)\n", - " \n", - " for data_filename in data_filenames:\n", - " data_path = os.path.join(data_folder, data_filename)\n", - " data_paths.append(data_path)\n", - " \n", - " data_paths.sort() # sort in alphabetical order\n", - " \n", - " return data_paths\n", - "\n", - "retrieved_paths = get_data_paths()\n", - "input_path = retrieved_paths[1]\n", - "print(\"The salinity file path is: \" + input_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we instantiate the class passing the salinity file path as parameter:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sal_mng = SalinityManager(data_path=input_path)\n", - "print(sal_mng.sal_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "But what happens if we don't pass a value for the `data_path` parameter?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sal_mng = SalinityManager()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Read the above error message. It should be clear what Python is complaining about!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The String Representation Method" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Another special method that may be explicitly added to a class is `__str__(self)`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "The `__str__(self)` method is called each time that you pass an object to the `print()` function." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If you don't explicitly write it, Python will provide a default implementation:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(sal_mng)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see after executing the above **Code** cell, the default solution is to simply provide the name and the [memory address](https://en.wikipedia.org/wiki/Memory_address) of the object. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the next code, we will write a `__str__(self)` that returns a `str` with some meaningful information about the status of the object." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class SalinityManager:\n", - " \"\"\"A file manager for salinity\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.sal_values = list()\n", - " self.sal_path = data_path\n", - " \n", - " def __str__(self):\n", - " sal_path_txt = \"path: \" + self.sal_path + \", \"\n", - " sal_values_txt = \"nr_values: \" + str(len(self.sal_values))\n", - " txt = \"SalinityManager[\" + sal_path_txt + sal_values_txt + \"]\"\n", - " return txt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After having execute the above code, the `print()` function of an object of this class will display what return by our custom `__str__(self)` method:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sal_mng = SalinityManager(data_path=input_path)\n", - "print(sal_mng)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "There are not fixed rules of what to return as `str`. The only requirement is to be a **nicely printable representation** of an object." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "solution2": "hidden", - "solution2_first": true - }, - "source": [ - "\n", - "\n", - "Write a class for a `TemperatureManager` with functionalities similar to the above `SalinityManager`. Then, add the code to demonstrate its functionalities." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "solution2": "hidden" - }, - "outputs": [], - "source": [ - "class TemperatureManager:\n", - " \"\"\"A file manager for temperature\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.temp_values = list()\n", - " self.temp_path = data_path\n", - " \n", - " def __str__(self):\n", - " temp_path_txt = \"path: \" + self.temp_path + \", \"\n", - " temp_values_txt = \"nr_values: \" + str(len(self.temp_values))\n", - " txt = \"TemperatureManager[\" + temp_path_txt + temp_values_txt + \"]\"\n", - " return txt\n", - " \n", - "input_path = retrieved_paths[2]\n", - "temp_mng = TemperatureManager(data_path=input_path)\n", - "print(temp_mng)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "## Useful References" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* [The official Python 3.6 documentation](https://docs.python.org/3.6/index.html)\n", - " * [Classes](https://docs.python.org/3.6/tutorial/classes.html)\n", - " * [String Representation Method](https://docs.python.org/3.6/reference/datamodel.html?highlight=repr#object.__str__)\n", - "* [Memory address](https://en.wikipedia.org/wiki/Memory_address)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "*For issues or suggestions related to this notebook, write to: epom@ccom.unh.edu*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "| [Contents](index.ipynb) | [More About Classes >](SUP_More_About_Classes.ipynb)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/SUP_More_About_Classes.ipynb b/SUP_More_About_Classes.ipynb deleted file mode 100644 index ff47e44..0000000 --- a/SUP_More_About_Classes.ipynb +++ /dev/null @@ -1,458 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"ePOM\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"ePOM\"\n", - "# More About Classes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A Python class has all the standard features required for [object-oriented programming](https://en.wikipedia.org/wiki/Object-oriented_programming)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "These standard features are:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* The presence of a [class inheritance mechanism](https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)). (Multiple base classes are allowed.)\n", - "* The property that a derived class can [override any methods](https://en.wikipedia.org/wiki/Method_overriding) of its base class. \n", - "* The possibility for a method to call the method of a base class with the same name. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Digging into these features is quite outside of the scope of this collection of notebooks. Thus, at the end of this notebook, you will know just a subset of what you can do with classes in Python. \n", - "\n", - "However, that subset should be a good base for you in case that you decide to continue the learning on your own." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The Class Interface" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As we have started to see in the [past notebook](008_First_Steps_of_a_Class.ipynb), objects contain data stored through the **class attributes**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The values in these attributes characterize the **class state**. Although you can directly modifies the attributes (and, thus, the class state), the proper way to proceed is to define the so-called **class interface**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "The **class interface** is represented by the set of the available methods for a class." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "What is the advantage of designing and maintaining a **class interface**? \n", - "\n", - "You can change the internal implementation (e.g., some attributes) without having to change the interface. This means that other parts of your program do **not** have to change to accommodate those changes." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Adding a `read(self)` Method" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In this first example of interface method, we will add a `read(self)`. \n", - "\n", - "This method performs similar operations to what was described in the [Read and Write Text Files notebook](007_Read_and_Write_Text_Files), but using the internal class attributes." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "class SalinityManager:\n", - " \"\"\"A file manager for salinity\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.sal_values = list()\n", - " self.sal_path = data_path\n", - " \n", - " def __str__(self):\n", - " sal_path_txt = \"path: \" + self.sal_path + \", \"\n", - " sal_values_txt = \"nr_values: \" + str(len(self.sal_values))\n", - " txt = \"SalinityManager[\" + sal_path_txt + sal_values_txt + \"]\"\n", - " return txt\n", - " \n", - " def read(self): # NEW METHOD!\n", - " # check whether the passed file does not exist\n", - " if not os.path.exists(self.sal_path):\n", - " raise RuntimeError(\"Unable to locate \" + self.sal_path)\n", - " \n", - " # read the file content\n", - " sal_file = open(self.sal_path)\n", - " sal_content = sal_file.read()\n", - " sal_file.close()\n", - " \n", - " # convert to float and append to the internal list of values\n", - " sal_lines = sal_content.splitlines() # split the string retrieved from the file by new line\n", - " for sal_line in sal_lines:\n", - " self.sal_values.append(float(sal_line)) # convert the string in each line to float, then append to the list\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "After executing the previous **Code** cell, we can test whether the new `read(self)` method is working:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def get_data_paths():\n", - " data_paths = list()\n", - " cur_folder = os.path.abspath(os.path.curdir)\n", - " data_folder = os.path.join(cur_folder, 'data')\n", - " data_filenames = os.listdir(data_folder)\n", - " \n", - " for data_filename in data_filenames:\n", - " data_path = os.path.join(data_folder, data_filename)\n", - " data_paths.append(data_path)\n", - " \n", - " data_paths.sort() # sort in alphabetical order\n", - " \n", - " return data_paths\n", - "\n", - "retrieved_paths = get_data_paths()\n", - "input_path = retrieved_paths[1]\n", - "\n", - "sal_mng = SalinityManager(data_path=input_path)\n", - "sal_mng.read()\n", - "print(sal_mng)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see from reading the `print()` output, the resulting object has 20 salinity values. \n", - "\n", - "If you want to see those value, you can use the `.` operator to access the `sal_values` attribute." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(sal_mng.sal_values)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Adding a `write(self, output_path)` Method" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Following the parallel with the [Read and Write Text Files notebook](007_Read_and_Write_Text_Files), we will now add a method to write the salinity data into an output file:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "class SalinityManager:\n", - " \"\"\"A file manager for salinity\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.sal_values = list()\n", - " self.sal_path = data_path\n", - " \n", - " def __str__(self):\n", - " sal_path_txt = \"path: \" + self.sal_path + \", \"\n", - " sal_values_txt = \"nr_values: \" + str(len(self.sal_values))\n", - " txt = \"SalinityManager[\" + sal_path_txt + sal_values_txt + \"]\"\n", - " return txt\n", - " \n", - " def read(self):\n", - " # check whether the passed file does not exist\n", - " if not os.path.exists(self.sal_path):\n", - " raise RuntimeError(\"Unable to locate \" + self.sal_path)\n", - " \n", - " # read the file content\n", - " sal_file = open(self.sal_path)\n", - " sal_content = sal_file.read()\n", - " sal_file.close()\n", - " \n", - " # convert to float and append to the internal list of values\n", - " sal_lines = sal_content.splitlines() # split the string retrieved from the file by new line\n", - " for sal_line in sal_lines:\n", - " self.sal_values.append(float(sal_line)) # convert the string in each line to float, then append to the list\n", - " \n", - " def write(self, output_path): # NEW METHOD!\n", - " output_file = open(output_path, mode=\"w\")\n", - " \n", - " for value in self.sal_values:\n", - " line_content = str(value) + \"\\n\" # the \"\\n\" is the character for the new line\n", - " output_file.write(line_content)\n", - " \n", - " output_file.close()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Before calling the new `write(self, output_path)` method, we need to set the output path:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def get_output_folder():\n", - " cur_folder = os.path.abspath(os.path.curdir)\n", - " output_folder = os.path.join(cur_folder, \"output\")\n", - " if os.path.exists(output_folder):\n", - " return output_folder\n", - " else: # in case that the output folder does not exists, we raise a meaningful error\n", - " raise RuntimeError(\"Unable to locate the output folder: \" + output_folder)\n", - "\n", - "output_folder = get_output_folder()\n", - "output_sal_path = os.path.join(output_folder, \"output_salinity.txt\")\n", - "print(\"The output file path is: \" + output_sal_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With the retrieved `output_sal_path`, we can now call the method to write the salinity values to the disk:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sal_mng = SalinityManager(data_path=input_path)\n", - "sal_mng.read()\n", - "sal_mng.write(output_path=output_sal_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "solution2": "hidden", - "solution2_first": true - }, - "source": [ - "\n", - "\n", - "Write a class that reads and writes the provided temperature file (`input_path`). Then, demonstrate how to use the class (i.e., by reading the temperature values and then writing them to disk). " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "solution2": "hidden" - }, - "outputs": [], - "source": [ - "class TemperatureManager:\n", - " \"\"\"A file manager for temperature\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.temp_values = list()\n", - " self.temp_path = data_path\n", - " \n", - " def __str__(self):\n", - " temp_path_txt = \"path: \" + self.temp_path + \", \"\n", - " temp_values_txt = \"nr_values: \" + str(len(self.temp_values))\n", - " txt = \"TemperatureManager[\" + temp_path_txt + temp_values_txt + \"]\"\n", - " return txt\n", - " \n", - " def read(self):\n", - " # check whether the passed file does not exist\n", - " if not os.path.exists(self.temp_path):\n", - " raise RuntimeError(\"Unable to locate \" + self.temp_path)\n", - " \n", - " # read the file content\n", - " temp_file = open(self.temp_path)\n", - " temp_content = temp_file.read()\n", - " temp_file.close()\n", - " \n", - " # convert to float and append to the internal list of values\n", - " temp_lines = temp_content.splitlines() # split the string retrieved from the file by new line\n", - " for temp_line in temp_lines:\n", - " self.temp_values.append(float(temp_line)) # convert the string in each line to float, then append to the list\n", - " \n", - " def write(self, output_path):\n", - " output_file = open(output_path, mode=\"w\")\n", - " \n", - " for value in self.temp_values:\n", - " line_content = str(value) + \"\\n\" # the \"\\n\" is the character for the new line\n", - " output_file.write(line_content)\n", - " \n", - " output_file.close() \n", - " \n", - "input_path = retrieved_paths[2]\n", - "print(\"The input file path is: \" + input_path) # this display the temperature text file to use as input\n", - "temp_mng = TemperatureManager(data_path=input_path)\n", - "temp_mng.read()\n", - "print(temp_mng)\n", - "\n", - "output_temp_path = os.path.join(output_folder, \"output_temperature.txt\")\n", - "print(\"The output file path is: \" + output_temp_path)\n", - "temp_mng.write(output_path=output_temp_path)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "input_path = retrieved_paths[2]\n", - "print(\"The input file path is: \" + input_path) # this display the temperature text file to use as input" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "## Useful References" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* [The official Python 3.6 documentation](https://docs.python.org/3.6/index.html)\n", - " * [Classes](https://docs.python.org/3.6/tutorial/classes.html)\n", - "* [Object-oriented Programming](https://en.wikipedia.org/wiki/Object-oriented_programming)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "*For issues or suggestions related to this notebook, write to: epom@ccom.unh.edu*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "[< First Steps of a Class](SUP_First_Steps_of_a_Class.ipynb) | [Contents](index.ipynb) | [Summing-Up with Classes >](SUP_Summing-Up_with_Classes.ipynb)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/SUP_Python_is_Dynamically_and_Strongly_Typed.ipynb b/SUP_Python_is_Dynamically_and_Strongly_Typed.ipynb index b30c1fd..efeb8c1 100644 --- a/SUP_Python_is_Dynamically_and_Strongly_Typed.ipynb +++ b/SUP_Python_is_Dynamically_and_Strongly_Typed.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Python is Dynamically and Strongly Typed" ] }, diff --git a/SUP_Summing-Up_With_Classes.ipynb b/SUP_Summing-Up_With_Classes.ipynb deleted file mode 100644 index 94e7aa7..0000000 --- a/SUP_Summing-Up_With_Classes.ipynb +++ /dev/null @@ -1,332 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"ePOM\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\"ePOM\"\n", - "# Summing-Up with Classes" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is the last notebook about classes. We will not introduce new big concepts, but we will apply what has been discussed in the past notebooks." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will do it by creating a class to manage the reading and the writing for a data format more complex that the ones that we met up to now." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This is the text content of the `ctd.txt` file in the `data` folder:\n", - "\n", - "![ctd_txt](images/010_000_ctd_txt.png)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As you can see in the above image, the first four rows contain some metadata information about when and where the data were collected." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The rows starting from the fifth line has a structure of four columns, with measures of depth, sound speed, temperature, and salinity." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The collection of multiple oceanographic measures is common for a [CTD instrument](https://en.wikipedia.org/wiki/CTD_(instrument)). " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Initial Class Creation" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As done in the [First Steps of a Class notebook](008_First_Steps_of_a_Class.ipynb), we will first create a class with just two special methods: `init(self)` and `print(self)`:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "class CTDManager:\n", - " \"\"\"A file manager for CTD data\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.depth_values = list()\n", - " self.temp_values = list()\n", - " self.sal_values = list()\n", - " self.ss_values = list()\n", - " self.metadata = dict()\n", - " self.ctd_path = data_path\n", - " \n", - " def __str__(self):\n", - " ctd_path_txt = \"path: \" + self.ctd_path + \", \"\n", - " ctd_values_txt = \"nr_values: \" + str(len(self.depth_values))\n", - " txt = \"CTDManager[\" + ctd_path_txt + ctd_values_txt + \", \" + str(self.metadata) + \"]\"\n", - " return txt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The above class is richer of attributes than the previous ones that we have created. In fact, we need to accommodate the metadata and four columns representing different types of measures. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We will retrieve the full path to the `ctd.txt` file, then we will pass it to the just created class:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def get_data_paths():\n", - " data_paths = list()\n", - " cur_folder = os.path.abspath(os.path.curdir)\n", - " data_folder = os.path.join(cur_folder, \"data\")\n", - " data_filenames = os.listdir(data_folder)\n", - " \n", - " for data_filename in data_filenames:\n", - " data_path = os.path.join(data_folder, data_filename)\n", - " data_paths.append(data_path)\n", - " \n", - " data_paths.sort() # sort in alphabetical order\n", - " \n", - " return data_paths\n", - "\n", - "retrieved_paths = get_data_paths()\n", - "input_path = retrieved_paths[0]\n", - "print(\"input path: \" + input_path)\n", - "\n", - "ctd_mng = CTDManager(data_path=input_path)\n", - "print(ctd_mng)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Reading Data" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Similarly to the `SalinityManager`, the `CTDManager` is now extended by adding a methods to its interface for reading data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class CTDManager:\n", - " \"\"\"A file manager for CTD data\"\"\"\n", - " \n", - " def __init__(self, data_path):\n", - " self.depth_values = list()\n", - " self.temp_values = list()\n", - " self.sal_values = list()\n", - " self.ss_values = list()\n", - " self.metadata = dict()\n", - " self.ctd_path = data_path\n", - " \n", - " def __str__(self):\n", - " ctd_path_txt = \"path: \" + self.ctd_path + \", \"\n", - " ctd_values_txt = \"nr_values: \" + str(len(self.depth_values))\n", - " txt = \"CTDManager[\" + ctd_path_txt + ctd_values_txt + ', ' + str(self.metadata) + \"]\"\n", - " return txt\n", - " \n", - " def read(self): # NEW METHOD!\n", - " # check whether the passed file does not exist\n", - " if not os.path.exists(self.ctd_path):\n", - " raise RuntimeError(\"Unable to locate \" + self.ctd_path)\n", - " \n", - " # read the file content\n", - " ctd_file = open(self.ctd_path)\n", - " ctd_content = ctd_file.read()\n", - " ctd_file.close()\n", - " \n", - " ctd_lines = ctd_content.splitlines()\n", - " count = 0 # to count the number of read rows\n", - " for ctd_line in ctd_lines:\n", - " \n", - " if count < 4: # measures \n", - " meta_pair = ctd_line.split(\":\"\")\n", - " self.metadata[meta_pair[0]] = meta_pair[1]\n", - " \n", - " else: # measures\n", - " measures = ctd_line.split()\n", - " self.depth_values.append(float(measures[0]))\n", - " self.temp_values.append(float(measures[1]))\n", - " self.sal_values.append(float(measures[2]))\n", - " self.ss_values.append(float(measures[3]))\n", - " \n", - " count += 1 # it is equal to write: count = count + 1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In the above code we have used the [`str.split()`](https://docs.python.org/3.6/library/stdtypes.html?#str.split) method. This method returns a list of the words in the string, using the passed delimiter string (e.g., `\":\"`). \n", - "\n", - "In case that a parameter is specified (as we did for the measures section of the code), the following splitting algorithm is applied: *\"runs of consecutive whitespace are regarded as a single separator, and the result will contain no empty strings at the start or end if the string has leading or trailing whitespace.\"*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Before calling the `write(self, output_path)` method, we need to set the output path:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def get_output_folder():\n", - " cur_folder = os.path.abspath(os.path.curdir)\n", - " output_folder = os.path.join(cur_folder, \"output\")\n", - " if os.path.exists(output_folder):\n", - " return output_folder\n", - " else: # in case that the output folder does not exists, we raise a meaningful error\n", - " raise RuntimeError(\"Unable to locate the output folder: \" + output_folder)\n", - "\n", - "output_folder = get_output_folder()\n", - "output_ctd_path = os.path.join(output_folder, \"output_ctd.txt\")\n", - "print(\"The output file path is: \" + output_ctd_path)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "With the retrieved `output_ctd_path`, we can now call the method to write the CTD values to the disk:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "ctd_mng = CTDManager(data_path=input_path)\n", - "ctd_mng.read()\n", - "print(ctd_mng)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It works! We have been able to read a complex format in just a few lines of code." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "***" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "## Useful References" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "* [The official Python 3.6 documentation](https://docs.python.org/3.6/index.html)\n", - "* [CTD instrument](https://en.wikipedia.org/wiki/CTD_(instrument))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "*For issues or suggestions related to this notebook, write to: epom@ccom.unh.edu*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "[< More About Classes](SUP_More_About_Classes.ipynb) | [Contents](index.ipynb) |" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/empty.ipynb b/empty.ipynb index ba7efe1..4c1c4e5 100644 --- a/empty.ipynb +++ b/empty.ipynb @@ -11,7 +11,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\"ePOM\"\n", + "\"ePOM\"\n", "# Title" ] }, diff --git a/images/000_200_piazza_com.png b/images/000_200_piazza_com.png index 4e0ed61..12a0d4d 100644 Binary files a/images/000_200_piazza_com.png and b/images/000_200_piazza_com.png differ diff --git a/images/python_basics.ico b/images/python_basics.ico new file mode 100644 index 0000000..07cc61d Binary files /dev/null and b/images/python_basics.ico differ diff --git a/index.ipynb b/index.ipynb index 9f07366..67da2a0 100644 --- a/index.ipynb +++ b/index.ipynb @@ -52,10 +52,7 @@ "source": [ "| Notebook Name | Topics |\n", "| --- | --- |\n", - "| [Python is Dynamically and Strongly Typed](SUP_Python_is_Dynamically_and_Strongly_Typed.ipynb) | Statically vs. Dynamically Typing. Strongly vs. Weakly Typing. |\n", - "| [First Steps of a Class](SUP_First_Steps_of_a_Class.ipynb) | `class`, `__init__`, `self`, class variables |\n", - "| [More About Classes](SUP_More_About_Classes.ipynb) | `class` interface. |\n", - "| [Summing-Up with Classes](SUP_Summing-Up_with_Classes.ipynb) | Review. |" + "| [Python is Dynamically and Strongly Typed](SUP_Python_is_Dynamically_and_Strongly_Typed.ipynb) | Statically vs. Dynamically Typing. Strongly vs. Weakly Typing. |" ] }, { @@ -77,14 +74,9 @@ "\n", "* [Semme Dijkstra](mailto:semmed@ccom.unh.edu>)\n", "\n", - "* [Jordan Chadwick](mailto:jordan.chadwick@gmail.com>)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Code and Text License" + "* [Jordan Chadwick](mailto:jordan.chadwick@gmail.com>)\n", + "\n", + "* [Tyanne Faulkes](mailto:tyanne.faulkes@noaa.gov>)" ] }, { @@ -99,28 +91,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Code Repository" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "GitHub url: [https://github.com/hydroffice/python_basics](https://github.com/hydroffice/python_basics)" + "Version: 1.1.2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Version" + "GitHub repository: [https://github.com/hydroffice/python_basics](https://github.com/hydroffice/python_basics)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "1.0.0" + "Documentation: [https://www.hydroffice.org/manuals/epom/index.html](https://www.hydroffice.org/manuals/epom/index.html)" ] }, {