Skip to content

Commit c965d58

Browse files
authored
Merge pull request #14 from gjbex/development
Development
2 parents 8fe9ab9 + fe15fc1 commit c965d58

12 files changed

+131
-90
lines changed

environment.yml

+1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ dependencies:
1717
- openssl
1818
- fastapi
1919
- fire
20+
- hydra-core
2021
prefix: /home/gjb/mambaforge/envs/python_for_systems_programming

hands-on/shell_interaction.ipynb

+19-20
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,13 @@
5151
"sh.ls('-l')"
5252
]
5353
},
54-
{
55-
"cell_type": "markdown",
56-
"metadata": {},
57-
"source": [
58-
"The output can be used by assigning the command to a variable, and using the result's `stdout` attribute. Note that the latter is a sequence of bytes, so it has to be decoded into a UTF-8 string for further processing."
59-
]
60-
},
6154
{
6255
"cell_type": "code",
6356
"execution_count": null,
6457
"metadata": {},
6558
"outputs": [],
6659
"source": [
67-
"cmd = sh.ls('-l', '-a', _encoding='UTF-8')"
60+
"result = sh.ls('-l', '-a')"
6861
]
6962
},
7063
{
@@ -73,7 +66,7 @@
7366
"metadata": {},
7467
"outputs": [],
7568
"source": [
76-
"lines = cmd.stdout.decode(encoding='utf8').split('\\n')"
69+
"lines = result.split('\\n')"
7770
]
7871
},
7972
{
@@ -109,7 +102,8 @@
109102
"metadata": {},
110103
"outputs": [],
111104
"source": [
112-
"sh.ls()"
105+
"for file in (line.strip() for line in sh.ls().split()):\n",
106+
" print(file)"
113107
]
114108
},
115109
{
@@ -179,7 +173,7 @@
179173
"metadata": {},
180174
"outputs": [],
181175
"source": [
182-
"sh.cat('tmp/date_file.txt')"
176+
"print(sh.cat('tmp/date_file.txt'))"
183177
]
184178
},
185179
{
@@ -228,14 +222,14 @@
228222
},
229223
"outputs": [],
230224
"source": [
231-
"sh.grep(sh.ls('-l'), r'\\.ipynb$')"
225+
"print(sh.grep('-e', r'\\.ipynb$', _in=sh.ls('-l')))"
232226
]
233227
},
234228
{
235229
"cell_type": "markdown",
236230
"metadata": {},
237231
"source": [
238-
"Pipe the output of `cut` into `sort`."
232+
"Pipe the output of `cut` into `sort`. Also use the `_iter` argument to create a generator over standard output."
239233
]
240234
},
241235
{
@@ -246,7 +240,8 @@
246240
},
247241
"outputs": [],
248242
"source": [
249-
"sh.sort(sh.cut('-d', ' ', '-f', '5', 'tmp/date_file.txt'), '-r')"
243+
"for line in sh.sort('-r', _in=sh.cut('-d', ' ', '-f', '5', 'tmp/date_file.txt'), _iter=True):\n",
244+
" print(line.strip())"
250245
]
251246
},
252247
{
@@ -315,10 +310,12 @@
315310
},
316311
"outputs": [],
317312
"source": [
313+
"process = sh.sleep(10, _bg=True, _bg_exc=False, _timeout=3)\n",
318314
"try:\n",
319-
" process = sh.sleep(10, _bg=True, _timeout=3)\n",
320-
"except TimeoutError as error:\n",
321-
" print(error)"
315+
" process.wait()\n",
316+
"except sh.TimeoutException as error:\n",
317+
" print('process timed out')\n",
318+
" print(error.exit_code)"
322319
]
323320
},
324321
{
@@ -578,7 +575,7 @@
578575
"metadata": {},
579576
"outputs": [],
580577
"source": [
581-
"process = subprocess.run('ls *.py', stdout=subprocess.PIPE, encoding='utf8', shell=True)"
578+
"process = subprocess.run('ls *.ipynb', stdout=subprocess.PIPE, encoding='utf8', shell=True)"
582579
]
583580
},
584581
{
@@ -653,7 +650,9 @@
653650
{
654651
"cell_type": "code",
655652
"execution_count": null,
656-
"metadata": {},
653+
"metadata": {
654+
"scrolled": true
655+
},
657656
"outputs": [],
658657
"source": [
659658
"process.returncode"
@@ -676,7 +675,7 @@
676675
"name": "python",
677676
"nbconvert_exporter": "python",
678677
"pygments_lexer": "ipython3",
679-
"version": "3.11.3"
678+
"version": "3.11.6"
680679
}
681680
},
682681
"nbformat": 4,

python_for_systems_programming.pptx

56 KB
Binary file not shown.

python_for_systems_programming_linux64_conda_specs.txt

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
@EXPLICIT
55
https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2
66
https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-openblas.conda
7-
https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda
7+
https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda
88
https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2
99
https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2
1010
https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2
@@ -53,7 +53,7 @@ https://repo.anaconda.com/pkgs/main/linux-64/lz4-c-1.9.4-h6a678d5_0.conda
5353
https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.6-h59595ed_0.conda
5454
https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.4.20240210-h59595ed_0.conda
5555
https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda
56-
https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.5-hd590300_0.conda
56+
https://conda.anaconda.org/conda-forge/linux-64/openssl-3.1.6-h4ab18f5_0.conda
5757
https://repo.anaconda.com/pkgs/main/linux-64/pcre-8.45-h295c915_0.conda
5858
https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda
5959
https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2
@@ -109,13 +109,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.9-h166bd
109109
https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.1-h516909a_0.tar.bz2
110110
https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.4-h0b41bf4_0.conda
111111
https://repo.anaconda.com/pkgs/main/linux-64/zstd-1.5.5-hc292b87_0.conda
112+
https://conda.anaconda.org/conda-forge/noarch/antlr-python-runtime-4.9.3-pyhd8ed1ab_1.tar.bz2
112113
https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda
113114
https://repo.anaconda.com/pkgs/main/noarch/backcall-0.2.0-pyhd3eb1b0_0.tar.bz2
114115
https://conda.anaconda.org/conda-forge/linux-64/bcrypt-4.1.2-py311h46250e7_0.conda
115116
https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hd590300_1.conda
116117
https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311hb755f60_1.conda
117118
https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2
118-
https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda
119+
https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda
119120
https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda
120121
https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda
121122
https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda
@@ -225,6 +226,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.cond
225226
https://repo.anaconda.com/pkgs/main/linux-64/libwebp-1.2.4-h11a3e52_1.conda
226227
https://conda.anaconda.org/conda-forge/noarch/matplotlib-inline-0.1.7-pyhd8ed1ab_0.conda
227228
https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.23.5-py311h5585df3_0.conda
229+
https://conda.anaconda.org/conda-forge/noarch/omegaconf-2.3.0-pyhd8ed1ab_0.conda
228230
https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.0-hfec8fc6_2.conda
229231
https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda
230232
https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda
@@ -249,6 +251,7 @@ https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2
249251
https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.22.0-h25f0c4b_2.conda
250252
https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-6.0.0-h8e241bc_0.conda
251253
https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda
254+
https://conda.anaconda.org/conda-forge/noarch/hydra-core-1.3.2-pyhd8ed1ab_0.conda
252255
https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda
253256
https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda
254257
https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda

source-code/hydra/README.md

+31-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ in the context of scientific software.
66
It support configuration file handling, command line arguments, logging,
77
multiruns and so on.
88

9+
910
## What is it?
1011

1112
1. `gen_rand.py`: Python script to write random numbers to standard
@@ -14,23 +15,50 @@ multiruns and so on.
1415
1. `config.yaml`: configuration file with the defaults.
1516
1. `distr/gauss.yaml`: configuration file for the Gaussian distirubtion.
1617
1. `distr/uniform.yaml`: configuration file for the uniform distirubtion.
18+
1. `file_config.yaml`: configuration file with the output file name.
19+
1. `debug.py`: Python script that simply prints the configuration settings for
20+
debugging purposes.
21+
1722

1823
## How to use it?
24+
1925
Run with configuratino file settings:
2026
```bash
2127
$ ./gen_rand.py
2228
```
29+
2330
To increase the number of random values:
2431
```bash
25-
$ ./gen_rand.py 10
32+
$ ./gen_rand.py n=10
2633
```
2734

2835
To use a uniform distribution:
2936
```bash
30-
$ ./gen_rand.py distr=uniform
37+
$ ./gen_rand.py distr=uniform
3138
```
3239

3340
To use a uniform distribution between -1 and 0:
3441
```bash
35-
$ ./gen_rand.py distr=uniform distr.a=-1.0 distr.b=0.0
42+
$ ./gen_rand.py distr=uniform distr.a=-1.0 distr.b=0.0
43+
```
44+
45+
To use a different configuration file:
46+
```bash
47+
$ ./gen_rand.py -cn file_config.yaml
48+
```
49+
or
50+
```bash
51+
$ ./gen_rand.py --config-name=file_config.yaml
52+
```
53+
54+
To perform multiple runs with different parameter values:
55+
```bash
56+
$ ./gen_rand.py -m distr=uniform,gauss
57+
```
58+
Note that if multiple parameters are to be varied, the Cartesian product of
59+
the values will be used.
60+
61+
To view the configuration settings, e.g., for debugging:
62+
```bash
63+
$ ./gen_rand.py --cfg=job distr=uniform
3664
```

source-code/hydra/conf/config.yaml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
verbose: False
21
n: 1
2+
file: false
33
defaults:
4-
- distr: gauss
4+
- distr: gauss
5+
- _self_
+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
distr:
2-
name: gauss
3-
mu: 0.0
4-
sigma: 1.0
1+
name: gauss
2+
mu: 0.0
3+
sigma: 1.0
+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
distr:
2-
name: uniform
3-
a: 0.0
4-
b: 1.0
1+
name: uniform
2+
a: 0.0
3+
b: 1.0
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
hydra:
2+
job:
3+
chdir: true
4+
n: 1
5+
file: output.txt
6+
defaults:
7+
- distr: gauss
8+
- _self_

source-code/hydra/debug.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env python
2+
3+
from omegaconf import DictConfig, OmegaConf
4+
import hydra
5+
6+
@hydra.main(version_base=None, config_path='conf/', config_name='config')
7+
def my_app(cfg):
8+
print(OmegaConf.to_yaml(cfg))
9+
10+
if __name__ == '__main__':
11+
my_app()

source-code/hydra/gen_rand.py

+16-18
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,34 @@
55
import numpy as np
66
import sys
77

8-
LOG = logging.getLogger(sys.argv[0])
98

10-
@hydra.main(config_path='conf/config.yaml')
9+
@hydra.main(version_base=None, config_path='conf/', config_name='config')
1110
def gen_rand(cfg):
12-
if cfg.verbose:
13-
print(cfg.pretty(), file=sys.stderr)
11+
logger = logging.getLogger(__name__)
1412
if cfg.n <= 0:
15-
LOG.error(f'negative number to generate {cfg.n}')
16-
return 1
17-
LOG.info(f'generating {cfg.n} random numbers')
18-
LOG.info(f'using {cfg.distr.name} distribution')
13+
logger.error(f'negative number to generate {cfg.n}')
14+
sys.exit(1)
15+
logger.info(f'generating {cfg.n} random numbers')
16+
logger.info(f'using {cfg.distr.name} distribution')
1917
if cfg.distr.name == 'gauss':
20-
LOG.info(f'mu={cfg.distr.mu}, sigma={cfg.distr.sigma}')
18+
logger.info(f'mu={cfg.distr.mu}, sigma={cfg.distr.sigma}')
2119
if cfg.distr.sigma <= 0:
22-
LOG.error(f'negative standard deviation {cfg.distr.sigma}')
23-
return 1
20+
logger.error(f'negative standard deviation {cfg.distr.sigma}')
21+
sys.exit(1)
2422
numbers = np.random.normal(loc=cfg.distr.mu, scale=cfg.distr.sigma,
2523
size=(cfg.n,))
2624
elif cfg.distr.name == 'uniform':
27-
LOG.info(f'a={cfg.distr.a}, b={cfg.distr.b}')
25+
logger.info(f'a={cfg.distr.a}, b={cfg.distr.b}')
2826
if cfg.distr.a >= cfg.distr.b:
29-
LOG.warning(f'lower bound exceed upper bound, '
27+
logger.warning(f'lower bound exceed upper bound, '
3028
f'{cfg.distr.a} >= {cfg.distr.b}')
3129
numbers = np.random.uniform(cfg.distr.a, cfg.distr.b, size=(cfg.n,))
32-
LOG.info('starting output')
30+
logger.info('starting output')
31+
out = open(cfg.file, 'w') if cfg.file else sys.stdout
3332
for number in numbers:
34-
print(number)
35-
LOG.info('output done')
33+
print(number, file=out)
34+
logger.info('output done')
3635
return 0
3736

3837
if __name__ == '__main__':
39-
status = gen_rand()
40-
sys.exit(status)
38+
gen_rand()

0 commit comments

Comments
 (0)