rename and ktx source files added

This commit is contained in:
SebastianoF
2020-01-12 14:22:49 +00:00
parent ac42b7e154
commit 3298f0258b
11 changed files with 1585 additions and 496 deletions

View File

@@ -4,16 +4,15 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"\n",
"# 100 numpy exercises\n", "# 100 numpy exercises\n",
"\n", "\n",
"This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow \n", "This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow\n",
"and in the numpy documentation. The goal of this collection is to offer a quick reference for both old \n", "and in the numpy documentation. The goal of this collection is to offer a quick reference for both old\n",
"and new users but also to provide a set of exercises for those who teach.\n", "and new users but also to provide a set of exercises for those who teach.\n",
"\n", "\n",
"\n", "\n",
"If you find an error or think you've a better way to solve some of them, feel \n", "If you find an error or think you've a better way to solve some of them, feel\n",
"free to open an issue at <https://github.com/rougier/numpy-100>\n" "free to open an issue at <https://github.com/rougier/numpy-100>"
] ]
}, },
{ {
@@ -27,7 +26,8 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Run the `initialize.py` module, then for each question you can query the answer or an hint with `hint(n)` or `answer(n)` for `n` question number." "Run the `initialize.py` module, then for each question you can query the\n",
"answer or an hint with `hint(n)` or `answer(n)` for `n` question number."
] ]
}, },
{ {
@@ -408,7 +408,7 @@
"print(sum(range(5),-1))\n", "print(sum(range(5),-1))\n",
"from numpy import *\n", "from numpy import *\n",
"print(sum(range(5),-1))\n", "print(sum(range(5),-1))\n",
"```\n" "```"
] ]
}, },
{ {
@@ -449,7 +449,7 @@
"np.array(0) / np.array(0)\n", "np.array(0) / np.array(0)\n",
"np.array(0) // np.array(0)\n", "np.array(0) // np.array(0)\n",
"np.array([np.nan]).astype(int).astype(float)\n", "np.array([np.nan]).astype(int).astype(float)\n",
"```\n" "```"
] ]
}, },
{ {
@@ -508,7 +508,7 @@
"#### 32. Is the following expressions true? (★☆☆)\n", "#### 32. Is the following expressions true? (★☆☆)\n",
"```python\n", "```python\n",
"np.sqrt(-1) == np.emath.sqrt(-1)\n", "np.sqrt(-1) == np.emath.sqrt(-1)\n",
"```\n" "```"
] ]
}, },
{ {
@@ -821,7 +821,7 @@
"1, 2, 3, 4, 5\n", "1, 2, 3, 4, 5\n",
"6, , , 7, 8\n", "6, , , 7, 8\n",
" , , 9,10,11\n", " , , 9,10,11\n",
"```\n" "```"
] ]
}, },
{ {
@@ -1213,7 +1213,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"#### 82. Compute a matrix rank (★★★) " "#### 82. Compute a matrix rank (★★★)"
] ]
}, },
{ {

View File

@@ -1,7 +1,6 @@
# 100 numpy exercises # 100 numpy exercises
This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow
@@ -10,8 +9,7 @@ and new users but also to provide a set of exercises for those who teach.
If you find an error or think you've a better way to solve some of them, feel If you find an error or think you've a better way to solve some of them, feel
free to open an issue at <https://github.com/rougier/numpy-100> free to open an issue at <https://github.com/rougier/numpy-100>File automatically generated. See the documentation to update questions/answers/hints programmatically.
File automatically generated. See the documentation to update questions/answers/hints programmatically.
#### 1. Import the numpy package under the name `np` (★☆☆) #### 1. Import the numpy package under the name `np` (★☆☆)
#### 2. Print the numpy version and the configuration (★☆☆) #### 2. Print the numpy version and the configuration (★☆☆)
@@ -79,7 +77,6 @@ from numpy import *
print(sum(range(5),-1)) print(sum(range(5),-1))
``` ```
#### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆) #### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆)
```python ```python
Z**Z Z**Z
@@ -97,7 +94,6 @@ np.array(0) // np.array(0)
np.array([np.nan]).astype(int).astype(float) np.array([np.nan]).astype(int).astype(float)
``` ```
#### 29. How to round away from zero a float array ? (★☆☆) #### 29. How to round away from zero a float array ? (★☆☆)
#### 30. How to find common values between two arrays? (★☆☆) #### 30. How to find common values between two arrays? (★☆☆)
@@ -109,7 +105,6 @@ np.array([np.nan]).astype(int).astype(float)
np.sqrt(-1) == np.emath.sqrt(-1) np.sqrt(-1) == np.emath.sqrt(-1)
``` ```
#### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆) #### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆)
#### 34. How to get all the dates corresponding to the month of July 2016? (★★☆) #### 34. How to get all the dates corresponding to the month of July 2016? (★★☆)
@@ -159,7 +154,6 @@ np.sqrt(-1) == np.emath.sqrt(-1)
, , 9,10,11 , , 9,10,11
``` ```
#### 55. What is the equivalent of enumerate for numpy arrays? (★★☆) #### 55. What is the equivalent of enumerate for numpy arrays? (★★☆)
#### 56. Generate a generic 2D Gaussian-like array (★★☆) #### 56. Generate a generic 2D Gaussian-like array (★★☆)

View File

@@ -1,7 +1,6 @@
# 100 numpy exercises # 100 numpy exercises
This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow
@@ -10,10 +9,9 @@ and new users but also to provide a set of exercises for those who teach.
If you find an error or think you've a better way to solve some of them, feel If you find an error or think you've a better way to solve some of them, feel
free to open an issue at <https://github.com/rougier/numpy-100> free to open an issue at <https://github.com/rougier/numpy-100>File automatically generated. See the documentation to update questions/answers/hints programmatically.
File automatically generated. See the documentation to update questions/answers/hints programmatically.
#### 1. Import the numpy package under the name `np` (★☆☆) #### 1. Import the numpy package under the name `np` (★☆☆)
`hint: import as ` `hint: import as`
#### 2. Print the numpy version and the configuration (★☆☆) #### 2. Print the numpy version and the configuration (★☆☆)
`hint: np.__version__, np.show_config)` `hint: np.__version__, np.show_config)`
#### 3. Create a null vector of size 10 (★☆☆) #### 3. Create a null vector of size 10 (★☆☆)
@@ -67,7 +65,7 @@ np.nan in set([np.nan])
#### 23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆) #### 23. Create a custom dtype that describes a color as four unsigned bytes (RGBA) (★☆☆)
`hint: np.dtype` `hint: np.dtype`
#### 24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆) #### 24. Multiply a 5x3 matrix by a 3x2 matrix (real matrix product) (★☆☆)
`hint: ` `hint:`
#### 25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆) #### 25. Given a 1D array, negate all elements which are between 3 and 8, in place. (★☆☆)
`hint: >, <=` `hint: >, <=`
#### 26. What is the output of the following script? (★☆☆) #### 26. What is the output of the following script? (★☆☆)
@@ -78,7 +76,6 @@ print(sum(range(5),-1))
from numpy import * from numpy import *
print(sum(range(5),-1)) print(sum(range(5),-1))
``` ```
`hint: np.sum` `hint: np.sum`
#### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆) #### 27. Consider an integer vector Z, which of these expressions are legal? (★☆☆)
```python ```python
@@ -96,8 +93,7 @@ np.array(0) / np.array(0)
np.array(0) // np.array(0) np.array(0) // np.array(0)
np.array([np.nan]).astype(int).astype(float) np.array([np.nan]).astype(int).astype(float)
``` ```
`No hints provided...`
`No hints provided... `
#### 29. How to round away from zero a float array ? (★☆☆) #### 29. How to round away from zero a float array ? (★☆☆)
`hint: np.uniform, np.copysign, np.ceil, np.abs` `hint: np.uniform, np.copysign, np.ceil, np.abs`
#### 30. How to find common values between two arrays? (★☆☆) #### 30. How to find common values between two arrays? (★☆☆)
@@ -108,7 +104,6 @@ np.array([np.nan]).astype(int).astype(float)
```python ```python
np.sqrt(-1) == np.emath.sqrt(-1) np.sqrt(-1) == np.emath.sqrt(-1)
``` ```
`hint: imaginary number` `hint: imaginary number`
#### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆) #### 33. How to get the dates of yesterday, today and tomorrow? (★☆☆)
`hint: np.datetime64, np.timedelta64` `hint: np.datetime64, np.timedelta64`
@@ -158,7 +153,6 @@ np.sqrt(-1) == np.emath.sqrt(-1)
6, , , 7, 8 6, , , 7, 8
, , 9,10,11 , , 9,10,11
``` ```
`hint: np.genfromtxt` `hint: np.genfromtxt`
#### 55. What is the equivalent of enumerate for numpy arrays? (★★☆) #### 55. What is the equivalent of enumerate for numpy arrays? (★★☆)
`hint: np.ndenumerate, np.ndindex` `hint: np.ndenumerate, np.ndindex`
@@ -227,7 +221,7 @@ np.sqrt(-1) == np.emath.sqrt(-1)
#### 87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★) #### 87. Consider a 16x16 array, how to get the block-sum (block size is 4x4)? (★★★)
`hint: np.add.reduceat` `hint: np.add.reduceat`
#### 88. How to implement the Game of Life using numpy arrays? (★★★) #### 88. How to implement the Game of Life using numpy arrays? (★★★)
`No hints provided... ` `No hints provided...`
#### 89. How to get the n largest values of an array (★★★) #### 89. How to get the n largest values of an array (★★★)
`hint: np.argsort | np.argpartition` `hint: np.argsort | np.argpartition`
#### 90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★) #### 90. Given an arbitrary number of vectors, build the cartesian product (every combinations of every item) (★★★)
@@ -247,7 +241,7 @@ np.sqrt(-1) == np.emath.sqrt(-1)
#### 97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★) #### 97. Considering 2 vectors A & B, write the einsum equivalent of inner, outer, sum, and mul function (★★★)
`hint: np.einsum` `hint: np.einsum`
#### 98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)? #### 98. Considering a path described by two vectors (X,Y), how to sample it using equidistant samples (★★★)?
`hint: np.cumsum, np.interp ` `hint: np.cumsum, np.interp`
#### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★) #### 99. Given an integer n and a 2D array X, select from X the rows which can be interpreted as draws from a multinomial distribution with n degrees, i.e., the rows which only contain integers and which sum to n. (★★★)
`hint: np.logical_and.reduce, np.mod` `hint: np.logical_and.reduce, np.mod`
#### 100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★) #### 100. Compute bootstrapped 95% confidence intervals for the mean of a 1D array X (i.e., resample the elements of an array with replacement N times, compute the mean of each sample, and then compute percentiles over the means). (★★★)

View File

@@ -4,16 +4,15 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"\n",
"# 100 numpy exercises\n", "# 100 numpy exercises\n",
"\n", "\n",
"This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow \n", "This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow\n",
"and in the numpy documentation. The goal of this collection is to offer a quick reference for both old \n", "and in the numpy documentation. The goal of this collection is to offer a quick reference for both old\n",
"and new users but also to provide a set of exercises for those who teach.\n", "and new users but also to provide a set of exercises for those who teach.\n",
"\n", "\n",
"\n", "\n",
"If you find an error or think you've a better way to solve some of them, feel \n", "If you find an error or think you've a better way to solve some of them, feel\n",
"free to open an issue at <https://github.com/rougier/numpy-100>\n" "free to open an issue at <https://github.com/rougier/numpy-100>"
] ]
}, },
{ {
@@ -27,7 +26,8 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Run the `initialize.py` module, then call a random question with `pick()`an hint towards its solution with `hint(n)` and the answer with `answer(n)`,where n is the number of the picked question." "Run the `initialize.py` module, then call a random question with `pick()` an hint towards its solution with\n",
"`hint(n)` and the answer with `answer(n)`, where n is the number of the picked question."
] ]
}, },
{ {

View File

@@ -7,9 +7,11 @@ This is a collection of numpy exercises from numpy mailing list, stack overflow,
[Test them on Binder](http://mybinder.org:/repo/rougier/numpy-100/notebooks/100_Numpy_exercises.ipynb) [Test them on Binder](http://mybinder.org:/repo/rougier/numpy-100/notebooks/100_Numpy_exercises.ipynb)
[Read them on GitHub](100_Numpy_exercises.md) [Read them on GitHub](100_Numpy_exercises.md)
Note: markdown and ipython notebook are created programmatically from the dictionary in `data_source.py`. Note: markdown and ipython notebook are created programmatically from the source data in `source/exercises.ktx`.
To modify the content of these files, chance the text in `data_source.py` and then re-generate them via the To modify the content of these files, please change the text in the source and run the `generators.py` module with a python
method into the `generators.py` module. interpreter with the libraries under `requirements.txt` installed.
The keyed text format (`ktx`) is a minimal human readable key-values to store text (markdown or others) indexed by keys.
This work is licensed under the MIT license. This work is licensed under the MIT license.
[![DOI](https://zenodo.org/badge/10173/rougier/numpy-100.svg)](https://zenodo.org/badge/latestdoi/10173/rougier/numpy-100) [![DOI](https://zenodo.org/badge/10173/rougier/numpy-100.svg)](https://zenodo.org/badge/latestdoi/10173/rougier/numpy-100)

View File

@@ -2,10 +2,41 @@ import os
import nbformat as nbf import nbformat as nbf
import mdutils import mdutils
import data_source as ds
def ktx_to_dict(input_file, keystarter='<'):
""" parsing keyed text to a python dictionary. """
answer = dict()
with open(input_file, 'r+') as f:
lines = f.readlines()
k, val = '', ''
for line in lines:
if line.startswith(keystarter):
k = line.replace(keystarter, '').strip()
val = ''
else:
val += line
if k:
answer.update({k: val.strip()})
return answer
def create_jupyter_notebook(destination_filename='numpy_100.ipynb'): def dict_to_ktx(input_dict, output_file, keystarter='<'):
""" Store a python dictionary to a keyed text"""
with open(output_file, 'w+') as f:
for k, val in input_dict.items():
f.write(f'{keystarter} {k}\n')
f.write(f'{val}\n\n')
HEADERS = ktx_to_dict(os.path.join('source', 'headers.ktx'))
QHA = ktx_to_dict(os.path.join('source', 'exercises100.ktx'))
def create_jupyter_notebook(destination_filename='100_Numpy_exercises.ipynb'):
""" Programmatically create jupyter notebook with the questions (and hints and solutions if required) """ Programmatically create jupyter notebook with the questions (and hints and solutions if required)
saved under data_source.py """ saved under data_source.py """
@@ -15,16 +46,16 @@ def create_jupyter_notebook(destination_filename='numpy_100.ipynb'):
nb['cells'] = [] nb['cells'] = []
# - Add header: # - Add header:
nb['cells'].append(nbf.v4.new_markdown_cell(ds.HEADER)) nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["header"]))
nb['cells'].append(nbf.v4.new_markdown_cell(ds.SUB_HEADER)) nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["sub_header"]))
nb['cells'].append(nbf.v4.new_markdown_cell(ds.JUPYTER_INSTRUCTIONS)) nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["jupyter_instruction"]))
# - Add initialisation # - Add initialisation
nb['cells'].append(nbf.v4.new_code_cell('%run initialise.py')) nb['cells'].append(nbf.v4.new_code_cell('%run initialise.py'))
# - Add questions and empty spaces for answers # - Add questions and empty spaces for answers
for n in range(1, 101): for n in range(1, 101):
nb['cells'].append(nbf.v4.new_markdown_cell(f'#### {n}. ' + ds.QHA[f'q{n}'])) nb['cells'].append(nbf.v4.new_markdown_cell(f'#### {n}. ' + QHA[f'q{n}']))
nb['cells'].append(nbf.v4.new_code_cell("")) nb['cells'].append(nbf.v4.new_code_cell(""))
# Delete file if one with the same name is found # Delete file if one with the same name is found
@@ -35,7 +66,7 @@ def create_jupyter_notebook(destination_filename='numpy_100.ipynb'):
nbf.write(nb, destination_filename) nbf.write(nb, destination_filename)
def create_jupyter_notebook_random_question(destination_filename='numpy_100_random.ipynb'): def create_jupyter_notebook_random_question(destination_filename='100_Numpy_random.ipynb'):
""" Programmatically create jupyter notebook with the questions (and hints and solutions if required) """ Programmatically create jupyter notebook with the questions (and hints and solutions if required)
saved under data_source.py """ saved under data_source.py """
@@ -45,9 +76,9 @@ def create_jupyter_notebook_random_question(destination_filename='numpy_100_rand
nb['cells'] = [] nb['cells'] = []
# - Add header: # - Add header:
nb['cells'].append(nbf.v4.new_markdown_cell(ds.HEADER)) nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["header"]))
nb['cells'].append(nbf.v4.new_markdown_cell(ds.SUB_HEADER)) nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["sub_header"]))
nb['cells'].append(nbf.v4.new_markdown_cell(ds.JUPYTER_INSTRUCTIONS_RAND)) nb['cells'].append(nbf.v4.new_markdown_cell(HEADERS["jupyter_instruction_rand"]))
# - Add initialisation # - Add initialisation
nb['cells'].append(nbf.v4.new_code_cell('%run initialise.py')) nb['cells'].append(nbf.v4.new_code_cell('%run initialise.py'))
@@ -61,7 +92,7 @@ def create_jupyter_notebook_random_question(destination_filename='numpy_100_rand
nbf.write(nb, destination_filename) nbf.write(nb, destination_filename)
def create_markdown(destination_filename='numpy_100', with_hints=False, with_solutions=False): def create_markdown(destination_filename='100_Numpy_exercises', with_hints=False, with_solutions=False):
# Create file name # Create file name
if with_hints: if with_hints:
destination_filename += '_with_hints' destination_filename += '_with_hints'
@@ -72,16 +103,16 @@ def create_markdown(destination_filename='numpy_100', with_hints=False, with_sol
mdfile = mdutils.MdUtils(file_name=destination_filename) mdfile = mdutils.MdUtils(file_name=destination_filename)
# Add headers # Add headers
mdfile.write(ds.HEADER) mdfile.write(HEADERS["header"])
mdfile.write(ds.SUB_HEADER) mdfile.write(HEADERS["sub_header"])
# Add questions (and hint or answers if required) # Add questions (and hint or answers if required)
for n in range(1, 101): for n in range(1, 101):
mdfile.new_header(title=f"{n}. {ds.QHA[f'q{n}']}", level=4) mdfile.new_header(title=f"{n}. {QHA[f'q{n}']}", level=4)
if with_hints: if with_hints:
mdfile.write(f"`{ds.QHA[f'h{n}']}`") mdfile.write(f"`{QHA[f'h{n}']}`")
if with_solutions: if with_solutions:
mdfile.insert_code(ds.QHA[f'a{n}'], language='python') mdfile.insert_code(QHA[f'a{n}'], language='python')
# Delete file if one with the same name is found # Delete file if one with the same name is found
if os.path.exists(destination_filename): if os.path.exists(destination_filename):

View File

@@ -1,18 +1,18 @@
import numpy as np import numpy as np
import data_source as ds import generators as ge
def question(n): def question(n):
print(f'{n}. ' + ds.QHA[f'q{n}']) print(f'{n}. ' + ge.QHA[f'q{n}'])
def hint(n): def hint(n):
print(ds.QHA[f'h{n}']) print(ge.QHA[f'h{n}'])
def answer(n): def answer(n):
print(ds.QHA[f'a{n}']) print(ge.QHA[f'a{n}'])
def pick(): def pick():

1457
source/exercises100.ktx Normal file

File diff suppressed because it is too large Load Diff

25
source/headers.ktx Normal file
View File

@@ -0,0 +1,25 @@
< header
# 100 numpy exercises
This is a collection of exercises that have been collected in the numpy mailing list, on stack overflow
and in the numpy documentation. The goal of this collection is to offer a quick reference for both old
and new users but also to provide a set of exercises for those who teach.
If you find an error or think you've a better way to solve some of them, feel
free to open an issue at <https://github.com/rougier/numpy-100>
< sub_header
File automatically generated. See the documentation to update questions/answers/hints programmatically.
< jupyter_instruction
Run the `initialize.py` module, then for each question you can query the
answer or an hint with `hint(n)` or `answer(n)` for `n` question number.
< jupyter_instruction_rand
Run the `initialize.py` module, then call a random question with `pick()` an hint towards its solution with
`hint(n)` and the answer with `answer(n)`, where n is the number of the picked question.