Skip to content

Commit df5ad98

Browse files
authored
Merge pull request DOI-USGS#167 from aleaf/main
refactor(notebooks/part0_python_intro/03_useful-std-library-modules.i…
2 parents 15ba472 + 6ce6932 commit df5ad98

1 file changed

Lines changed: 63 additions & 46 deletions

File tree

notebooks/part0_python_intro/03_useful-std-library-modules.ipynb

Lines changed: 63 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
"# 03: Useful standard library modules\n",
88
"(pathlib, shutil, sys, os, subprocess, zipfile, etc.)\n",
99
"\n",
10-
"These packages are part of the standard python library and provide very useful functionality for working with your operating system and files. This notebook will provide explore these packages and demonstrate some of their functionality. Online documentation is at https://docs.python.org/3/library/.\n",
10+
"These packages are part of the standard python library and provide very useful functionality for working with your operating system and files. This notebook will provide these packages and demonstrate some of their functionality. Online documentation is at https://docs.python.org/3/library/.\n",
1111
"\n",
1212
"\n",
13-
"#### Topics covered:\n",
13+
"## Topics covered:\n",
1414
"* **pathlib**:\n",
1515
" * listing files\n",
1616
" * creating, moving and deleting files\n",
@@ -62,7 +62,9 @@
6262
"cell_type": "markdown",
6363
"metadata": {},
6464
"source": [
65-
"#### Make a ``Path()`` object for the current folder"
65+
"### Listing files\n",
66+
"\n",
67+
"#### Start by making a ``Path()`` object for the current folder"
6668
]
6769
},
6870
{
@@ -75,13 +77,6 @@
7577
"cwd"
7678
]
7779
},
78-
{
79-
"cell_type": "markdown",
80-
"metadata": {},
81-
"source": [
82-
"### Listing files"
83-
]
84-
},
8580
{
8681
"cell_type": "code",
8782
"execution_count": null,
@@ -185,7 +180,9 @@
185180
"cell_type": "markdown",
186181
"metadata": {},
187182
"source": [
188-
"#### Create a new path for the data subfolder"
183+
"### Creating files and folders\n",
184+
"\n",
185+
"#### make a ``Path`` object for a new subdirectory"
189186
]
190187
},
191188
{
@@ -194,8 +191,8 @@
194191
"metadata": {},
195192
"outputs": [],
196193
"source": [
197-
"data_path = cwd / 'data'\n",
198-
"data_path"
194+
"new_folder = cwd / 'more_files'\n",
195+
"new_folder"
199196
]
200197
},
201198
{
@@ -235,28 +232,7 @@
235232
"cell_type": "markdown",
236233
"metadata": {},
237234
"source": [
238-
"### Creating files and folders\n",
239-
"\n",
240-
"#### make a new subdirectory"
241-
]
242-
},
243-
{
244-
"cell_type": "code",
245-
"execution_count": null,
246-
"metadata": {},
247-
"outputs": [],
248-
"source": [
249-
"new_folder = cwd / 'more_files'\n",
250-
"new_folder"
251-
]
252-
},
253-
{
254-
"cell_type": "code",
255-
"execution_count": null,
256-
"metadata": {},
257-
"outputs": [],
258-
"source": [
259-
"new_folder.exists()"
235+
"#### make the actual folder"
260236
]
261237
},
262238
{
@@ -793,7 +769,7 @@
793769
"cell_type": "markdown",
794770
"metadata": {},
795771
"source": [
796-
"**Note**: Generally, importing code using ``sys.path`` is considered bad practice, because \n",
772+
"**Note**: Generally, importing code using ``sys.path`` is often considered bad practice, because \n",
797773
"\n",
798774
"* it can hide dependencies. \n",
799775
"\n",
@@ -802,7 +778,9 @@
802778
"\n",
803779
"* importing code using ``sys.path`` is also sensitive to the location of the script relative to the path. If the script is moved or used on someone else's computer with a different file structure, it'll break.\n",
804780
"\n",
805-
"In general, [installing reusable code in a package is the best way to go](https://nsls-ii.github.io/scientific-python-cookiecutter/). Packages provide a framework for organizing, documenting, testing and sharing code in a way that is easily understood by others.\n",
781+
"* this all said, sometimes using ``sys.path`` is expedient in reproducible workflows in that it can allow code to be consolidated and re-used across multiple scripts in various locations\n",
782+
"\n",
783+
"For code that is useful across multiple projects, [installing reusable code in a package can be the best way to go](https://learn.scientific-python.org/development/tutorials/). Packages provide a framework for organizing, documenting, testing and sharing code in a way that is easily understood by others.\n",
806784
"\n",
807785
"Whatever you do, avoid importing with an `*` (i.e. ``from mycode import *``) at all costs. This imports everything from the namespace of a module, which can lead to unintended consequences."
808786
]
@@ -816,7 +794,7 @@
816794
"\n",
817795
"### Changing the current working directory\n",
818796
"``pathlib`` doesn't do this. \n",
819-
"Note: this can obviously lead to trouble in scripts, so should usually be avoided, but sometimes it is necessary."
797+
"Note: this can obviously lead to trouble in scripts, so should usually be avoided, but sometimes it is necessary. In groundwater modeling workflows, for example, this can help keep flow and transport model files organized in separate folders."
820798
]
821799
},
822800
{
@@ -912,6 +890,33 @@
912890
"os.environ['CONDA_PREFIX']"
913891
]
914892
},
893+
{
894+
"cell_type": "markdown",
895+
"metadata": {},
896+
"source": [
897+
"### Running system commands\n",
898+
"`os.system` provides a limited way to run system commands. For more flexibility, use `subprocess` (below)."
899+
]
900+
},
901+
{
902+
"cell_type": "code",
903+
"execution_count": null,
904+
"metadata": {},
905+
"outputs": [],
906+
"source": [
907+
"os.system('ls -l')"
908+
]
909+
},
910+
{
911+
"cell_type": "code",
912+
"execution_count": null,
913+
"metadata": {},
914+
"outputs": [],
915+
"source": [
916+
"# on Windows\n",
917+
"os.system('dir')"
918+
]
919+
},
915920
{
916921
"cell_type": "markdown",
917922
"metadata": {},
@@ -943,7 +948,7 @@
943948
"outputs": [],
944949
"source": [
945950
"# if on mac/unix\n",
946-
"print(subprocess.run(['ls', '-l'], shell=True))"
951+
"print(subprocess.run(['ls', '-l']))"
947952
]
948953
},
949954
{
@@ -959,7 +964,7 @@
959964
"metadata": {},
960965
"outputs": [],
961966
"source": [
962-
"print(subprocess.run(['ls', '-l'], shell=True, cwd='..'))"
967+
"print(subprocess.run(['ls', '-l'], cwd='..'))"
963968
]
964969
},
965970
{
@@ -978,7 +983,7 @@
978983
"source": [
979984
"## ``zipfile`` — Work with ZIP archives\n",
980985
"\n",
981-
"#### zip up one of the files in data/"
986+
"### zip up one of the files in data/"
982987
]
983988
},
984989
{
@@ -995,7 +1000,7 @@
9951000
"cell_type": "markdown",
9961001
"metadata": {},
9971002
"source": [
998-
"#### now extract it"
1003+
"### now extract it"
9991004
]
10001005
},
10011006
{
@@ -1014,7 +1019,7 @@
10141019
"source": [
10151020
"## Testing Your Skills with a truly awful example:\n",
10161021
"\n",
1017-
"#### the problem:\n",
1022+
"### the problem:\n",
10181023
"Pretend that the file `data/fileio/netcdf_data.zip` contains some climate data (in the NetCDF format with the ``*.nc`` extension) that we downloaded. If you open `data/fileio/netcdf_data.zip`, you'll see that within a subfolder `zipped` are a bunch of additional subfolders, each for a different year. Within each subfolder is another zipfile. Within each of these zipfiles is yet another subfolder, inside of which is the actual data file we want (`prcp.nc`). "
10191024
]
10201025
},
@@ -1033,7 +1038,7 @@
10331038
"cell_type": "markdown",
10341039
"metadata": {},
10351040
"source": [
1036-
"#### the goal:\n",
1041+
"### the goal:\n",
10371042
"To extract all of these `prcp.nc` files into a single folder, after renaming them with their respective years (obtained from their enclosing folders or zip files). e.g. \n",
10381043
"```\n",
10391044
"prcp_1980.nc\n",
@@ -1042,7 +1047,7 @@
10421047
"```\n",
10431048
"This will allow us to open them together as a dataset in `xarray` (more on that later). Does this sound awful? I'm not making this up. This is the kind of structure you get when downloading tiles of climate data with the [Daymet Tile Selection Tool](https://daymet.ornl.gov/gridded/)\n",
10441049
"\n",
1045-
"#### hint:\n",
1050+
"### hint:\n",
10461051
"you might find these functions helpful:\n",
10471052
"```\n",
10481053
"ZipFile.extractall\n",
@@ -1061,7 +1066,7 @@
10611066
"cell_type": "markdown",
10621067
"metadata": {},
10631068
"source": [
1064-
"#### hint: start by using ``ZipFile.extractall()`` to extract all of the individual zip files from the main zip archive\n",
1069+
"### hint: start by using ``ZipFile.extractall()`` to extract all of the individual zip files from the main zip archive\n",
10651070
"This extracts the entire contents of the zip file to a designated folder"
10661071
]
10671072
},
@@ -1252,6 +1257,18 @@
12521257
"display_name": "pyclass",
12531258
"language": "python",
12541259
"name": "python3"
1260+
},
1261+
"language_info": {
1262+
"codemirror_mode": {
1263+
"name": "ipython",
1264+
"version": 3
1265+
},
1266+
"file_extension": ".py",
1267+
"mimetype": "text/x-python",
1268+
"name": "python",
1269+
"nbconvert_exporter": "python",
1270+
"pygments_lexer": "ipython3",
1271+
"version": "3.11.11"
12551272
}
12561273
},
12571274
"nbformat": 4,

0 commit comments

Comments
 (0)