Skip to content
Snippets Groups Projects
Commit 9b76dc5a authored by Philipp Risius's avatar Philipp Risius
Browse files

update notebooks

parent ed356494
Branches main
No related tags found
No related merge requests found
......@@ -23,7 +23,7 @@ dependencies:
- nbgrader
# TODO: Plugins for students
- --extra-index-url https://gitlab.ub.uni-giessen.de/api/v4/projects/920/packages/pypi/simple
- Pytest-Nbgrader
- pytest-nbgrader
# - nbgrader-jhaas
# TODO: Plugins for lecturers
- --extra-index-url https://gitlab.ub.uni-giessen.de/api/v4/projects/790/packages/pypi/simple
......
%% Cell type:code id:da8df839 tags:
%% Cell type:markdown id:4006378c-ac96-4262-8ecd-29bd18b9d338 tags:
``` python
import pathlib
import yaml
import numpy as np
from pytest_nbgrader.test_assertions import almost_equal, equal_scope, equal_types, equal_value
from pytest_nbgrader.test_cases import TestCase, TestSubtask
from pytest_nbgrader import dumper
```
# Showcase: Data generation for tests
%% Cell type:code id:7ceaa747 tags:
%% Cell type:code id:da8df839 tags:
``` python
# Task 1: Exchange two variables
left = {
'float': [1.0, 2.0, 3.0],
'int': [0, 1, 2],
'bool': [True, True, False, False],
'mixed': [1, 2.0, 3 + 4j, True],
}
right = {
'float': [4.0, 5.0, 6.0],
'int': [30, 121, 4452],
'bool': [True, False, True, False],
'mixed': [1 + 3j, 2, False, 5.0],
}
type_mixtures = (
('float', 'float'),
('int', 'int'),
('bool', 'bool'),
('int', 'float'),
('int', 'bool'),
('float', 'bool'),
('mixed', 'mixed'),
)
test_cases = {
f'{left_types}_{right_types}': [
TestCase(
inputs=(tuple(), {'a': x, 'b': y}), expected=(tuple(), {'a': y, 'b': x})
)
for x, y in zip(left[left_types], right[right_types])
]
for left_types, right_types in type_mixtures
}
assertions = {
equal_value: (('a', 'b'), {}),
equal_types: (('a', 'b'), {}),
equal_scope: (tuple(), {}),
}
task_exchange = {
types: TestSubtask(cases=test_cases[types], assertions=assertions)
for types in [f'{left}_{right}' for left, right in type_mixtures]
}
from pytest_nbgrader.assertions import equal_value
from pytest_nbgrader.cases import TestCase, TestSubtask
from pytest_nbgrader import dumper
```
%% Cell type:code id:be6cbc07 tags:
``` python
# TODO: Task2: Euclidean distance
epsilon = 1e-6
cases = [
(
tuple(),
{
f'{vec}{component}': hash(f'{vec}{component}+{salt}') % 7
- 3
+ 0.01 * np.random.rand() * epsilon
for vec in 'ab'
for component in '123'
}
| {'ganz_kleiner_wert': epsilon},
)
for salt in 'abcdefghijklmnopqrstuvwxyz'
]
def euclidean_norm(a1, a2, a3, **args):
return {'abs_a': (a1 ** 2 + a2 ** 2 + a3 ** 2) ** (1 / 2)}
%% Cell type:markdown id:0abcb6c1-bab0-4d47-8ffd-d59accfd62ee tags:
def difference_vector(a1, a2, a3, b1, b2, b3, **args):
return {'ab1': b1 - a1, 'ab2': b2 - a2, 'ab3': b3 - a3}
def euclidean_distance(a1, a2, a3, b1, b2, b3, **args):
return {
'abs_ab': euclidean_norm(*difference_vector(a1, a2, a3, b1, b2, b3).values())[
'abs_a'
]
}
def intersection_yz_plane(a1, a2, a3, b1, b2, b3, ganz_kleiner_wert, **args):
if abs(b1 - a1) > ganz_kleiner_wert:
s = a1 / (a1 - b1)
return {
'schnittpunkt1': 0,
'schnittpunkt2': a2 + s * (b2 - a2),
'schnittpunkt3': a3 + s * (b3 - a3),
}
else:
return {f'schnittpunkt{n}': None for n in range(1, 4)}
def cross_product(a1, a2, a3, b1, b2, b3, **args):
return {
'kreuz_produkt1': a2 * b3 - a3 * b2,
'kreuz_produkt2': a3 * b1 - a1 * b3,
'kreuz_produkt3': a1 * b2 - a2 * b1,
}
generators = {
'norm': euclidean_norm,
'difference': difference_vector,
'distance': euclidean_distance,
'schnittpunkt': intersection_yz_plane,
'kreuzprodukt': cross_product,
}
task_euclidean_geometry = {
key: TestSubtask(
cases=[
TestCase(
inputs=(args, kwargs), expected=(tuple(), function(*args, **kwargs))
)
for args, kwargs in cases
],
assertions={
almost_equal: (
tuple(function(**cases[0][1]).keys()),
{'atol': epsilon, 'rtol': epsilon},
),
},
)
for key, function in generators.items()
}
```
## Programmatically generate test cases
%% Cell type:code id:524e04dd tags:
``` python
# Task 3: Divisibility
## Subtask 1: order inputs a, b. Divisor shall be 1.
np.random.seed(1)
def order(a, b, **args):
return (a, b) if b > a else (b, a)
cases_order = [
(tuple(), dict(zip('ab', np.random.randint(-1e2, 1e2, 2))) | {'divisor': 1})
for _ in range(30)
]
results_order = [
(
tuple(),
dict(zip('ab', order(*args, **kwargs))),
)
for args, kwargs in cases_order
]
test_cases_order = [TestCase(*s) for s in zip(cases_order, results_order)]
task_divisibility = {
'order': TestSubtask(
cases=test_cases_order, assertions={equal_value: (('a', 'b'), {})}
)
}
## Subtask 2-5 assume ordered intervals (a, b). Divisor shall be 1.
def anzahl(a, b, **args):
return b - a + 1
cases_anzahl = [(args, kwargs | {'divisor': 1}) for args, kwargs in results_order]
test_cases_anzahl = [
test_cases = [
# Let's generate a test case manually:
TestCase(
inputs=(args, kwargs),
expected=(args, kwargs | {'anzahl': anzahl(*args, **kwargs)}),
inputs=(tuple(), {'lower_bound': -10, 'upper_bound': 5, 'divisor': 3}),
expected=(tuple(), {'number_of_divisibles': 5})
)
for args, kwargs in cases_anzahl
]
task_divisibility['anzahl'] = TestSubtask(
cases=test_cases_anzahl, assertions={equal_value: (('anzahl',), {})}
)
## Subtasks 3-5 assume various divisors
def teilbar_klein(a, b, divisor, **args):
try:
return (i for i in range(a, b + 1) if i % divisor == 0).__next__()
except StopIteration:
return None
def anzahl_teilbar(a, b, divisor, **args):
return sum([i % divisor == 0 for i in range(a, b + 1)])
def produkt_teilbar(a, b, divisor, **args):
return np.prod(
[i for i in range(a, b + 1) if i % divisor == 0 and i != 0], dtype=object
task_divisibility = {
'number_of_divisibles': TestSubtask(
test_cases,
assertions={equal_value: (('number_of_divisibles'), {})},
)
generators = {
'teilbar_klein': teilbar_klein,
'anzahl_teilbar': anzahl_teilbar,
'produkt_teilbar': produkt_teilbar,
}
```
cases = [
(args, kwargs | {'divisor': np.random.randint(1, 20) * np.random.choice((-1, 1))})
for args, kwargs in results_order
]
%% Cell type:markdown id:52b1946d-91d2-40d5-af87-a4742202fa8b tags:
task_divisibility |= {
key: TestSubtask(
[
TestCase(
inputs=(args, kwargs),
expected=(tuple(), {key: function(*args, **kwargs)}),
)
for args, kwargs in cases
],
assertions={equal_value: ((key,), {})},
)
for key, function in generators.items()
}
```
## Dump test cases as `.yml`
%% Cell type:code id:4e2ddbba tags:
``` python
dumper.dump_exercise(
{
'ExchangeVariables': task_exchange,
'EuclideanGeometry': task_euclidean_geometry,
'Divisibility': task_divisibility,
},
)
```
......
......@@ -154,7 +154,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"id": "859cec0c-0ed2-48e0-8e3b-a5354b517652",
"metadata": {
"nbgrader": {
......@@ -190,7 +190,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "9619ee19-e3f4-419c-802a-6d4c7de51791",
"metadata": {
"nbgrader": {
......@@ -215,7 +215,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "65e0b2ef-5b7b-4362-a40c-ace635562ca1",
"metadata": {
"nbgrader": {
......@@ -253,7 +253,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "2c8836da-d468-49ed-aab4-24a340750f22",
"metadata": {
"nbgrader": {
......@@ -278,7 +278,7 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": null,
"id": "fd405a9e-c8bc-4546-8bff-41f73c7b4c06",
"metadata": {
"nbgrader": {
......
%% Cell type:markdown id:84bbb171-a0e2-4506-a89e-e8f4899f537d tags:
## Quizzes (thanks to jupyterquiz)
## Quizzes
%% Cell type:code id:5ba0e591-b2e7-445d-9011-cdf04326f460 tags:
``` python
import jupyterquiz
```
%% Cell type:markdown id:d60f1183-279d-445c-9113-a5011e2c1f73 tags:
* Quizzes are converted to json and embedded as spans
* the converted version is "invisible"
#### Quiz
* (SC) What are ungraded quizzes good for?
+ This
- That
#### End Quiz
%% Cell type:code id:8d5f80cf-0a4f-40f7-b7a5-d84bd6f3d851 tags:
``` python
jupyterquiz.display_quiz('#quiz0')
```
......
%% Cell type:markdown id:ed5cb36f-5137-49b4-9b3f-e46ed0214d8a tags:
# Pytest Integration
%% Cell type:markdown id:1f18a76f-5acb-42fd-9062-2c86dd3f2e03 tags:
## Example: Divisibility
%% Cell type:markdown id:1098fa0f-433d-440d-b3bd-8c56c9d75836 tags:
You get a `lower_bound` and an `upper_bound` of an interval, as well as a `divisor`.
How many numbers in the interval are divisible by `divisor`? Write your solution to `number_of_divisibles`!
%% Cell type:markdown id:3947c769-e153-48e5-8f6d-d55ec8ab5098 tags:
Here is an example. Note that your code needs to work with different numbers as well!
%% Cell type:code id:e5474f20-00d2-4ed0-b550-c8688d4f820b tags:
``` python
lower_bound, upper_bound, divisor = 4, 19, 7
number_of_divisibles = 2
```
%% Cell type:code id:eadc399b-0fbc-42df-820e-a3adb557ca9c tags:
``` python
### BEGIN SOLUTION
number_of_divisibles = 0
for value in range(lower_bound, upper_bound):
if value % divisor == 0:
number_of_divisibles += 1
### END SOLUTION
```
%% Cell type:markdown id:98d0695a-033d-4a81-bb3e-6933b283d345 tags:
### Submit to Pytest
%% Cell type:code id:c8f51814-d7d3-488e-a54c-e920c9c2231f tags:
``` python
import pytest
from pytest_nbgrader import loader
import pathlib
loader.Submission.submit(_i)
```
%% Cell type:markdown id:4c1ec8d5-b1ac-446d-aad0-add9e12f8096 tags:
### Run test cases
%% Cell type:code id:49fe1fa4-c73d-4d05-a208-21164756d32f tags:
``` python
test_cases = pathlib.Path('tests') / 'number_divisible.yml'
```
%% Output
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[2], line 1
----> 1 test_cases = pathlib.Path('tests')
NameError: name 'pathlib' is not defined
%% Cell type:code id:1080730e-c653-4f11-84fd-3625685f333c tags:
``` python
assert pytest.main(['-x', '--cases', test_cases] is pytest.ExitCode.OK
assert pytest.main(['-x', '--cases', test_cases]) is pytest.ExitCode.OK
```
%% Cell type:markdown id:93200728-9e8e-462f-98fb-a8fdcf134465 tags:
### Run Pytest File
%% Cell type:code id:559d321a-f829-4c9e-ad38-dae66259a9de tags:
``` python
!pip freeze
```
%% Output
aiofiles @ file:///home/conda/feedstock_root/build_artifacts/aiofiles_1664378549280/work
aiosqlite @ file:///home/conda/feedstock_root/build_artifacts/aiosqlite_1682491975081/work
alembic==1.12.0
anyio==3.7.1
argon2-cffi @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi_1692818318753/work
argon2-cffi-bindings @ file:///home/conda/feedstock_root/build_artifacts/argon2-cffi-bindings_1666850842190/work
arrow @ file:///home/conda/feedstock_root/build_artifacts/arrow_1662382474514/work
asttokens @ file:///home/conda/feedstock_root/build_artifacts/asttokens_1694046349000/work
attrs @ file:///home/conda/feedstock_root/build_artifacts/attrs_1683424013410/work
Babel @ file:///home/conda/feedstock_root/build_artifacts/babel_1677767029043/work
backcall @ file:///home/conda/feedstock_root/build_artifacts/backcall_1592338393461/work
backports.functools-lru-cache @ file:///home/conda/feedstock_root/build_artifacts/backports.functools_lru_cache_1687772187254/work
beautifulsoup4 @ file:///home/conda/feedstock_root/build_artifacts/beautifulsoup4_1680888073205/work
bleach @ file:///home/conda/feedstock_root/build_artifacts/bleach_1674535352125/work
Brotli @ file:///home/conda/feedstock_root/build_artifacts/brotli-split_1693583441880/work
cached-property @ file:///home/conda/feedstock_root/build_artifacts/cached_property_1615209429212/work
certifi==2023.7.22
cffi @ file:///home/conda/feedstock_root/build_artifacts/cffi_1671179355965/work
charset-normalizer @ file:///home/conda/feedstock_root/build_artifacts/charset-normalizer_1688813409104/work
click @ file:///home/conda/feedstock_root/build_artifacts/click_1692311806742/work
colorama @ file:///home/conda/feedstock_root/build_artifacts/colorama_1666700638685/work
comm @ file:///home/conda/feedstock_root/build_artifacts/comm_1691044910542/work
contourpy @ file:///home/conda/feedstock_root/build_artifacts/contourpy_1686733806710/work
cycler @ file:///home/conda/feedstock_root/build_artifacts/cycler_1635519461629/work
debugpy @ file:///home/conda/feedstock_root/build_artifacts/debugpy_1694569164216/work
decorator @ file:///home/conda/feedstock_root/build_artifacts/decorator_1641555617451/work
defusedxml @ file:///home/conda/feedstock_root/build_artifacts/defusedxml_1615232257335/work
entrypoints @ file:///home/conda/feedstock_root/build_artifacts/entrypoints_1643888246732/work
exceptiongroup @ file:///home/conda/feedstock_root/build_artifacts/exceptiongroup_1692026125334/work
executing @ file:///home/conda/feedstock_root/build_artifacts/executing_1667317341051/work
fastjsonschema @ file:///home/conda/feedstock_root/build_artifacts/python-fastjsonschema_1690055433477/work/dist
fonttools @ file:///home/conda/feedstock_root/build_artifacts/fonttools_1692542607195/work
fqdn @ file:///home/conda/feedstock_root/build_artifacts/fqdn_1638810296540/work/dist
greenlet==2.0.2
hypothesis @ file:///home/conda/feedstock_root/build_artifacts/hypothesis_1694394297869/work
idna @ file:///home/conda/feedstock_root/build_artifacts/idna_1663625384323/work
importlib-metadata @ file:///home/conda/feedstock_root/build_artifacts/importlib-metadata_1688754491823/work
importlib-resources @ file:///home/conda/feedstock_root/build_artifacts/importlib_resources_1691408075105/work
iniconfig @ file:///home/conda/feedstock_root/build_artifacts/iniconfig_1673103042956/work
ipykernel @ file:///home/conda/feedstock_root/build_artifacts/ipykernel_1693880262622/work
ipython @ file:///home/conda/feedstock_root/build_artifacts/ipython_1693579759651/work
ipython-genutils==0.2.0
ipywidgets @ file:///home/conda/feedstock_root/build_artifacts/ipywidgets_1694607144474/work
isoduration @ file:///home/conda/feedstock_root/build_artifacts/isoduration_1638811571363/work/dist
jedi @ file:///home/conda/feedstock_root/build_artifacts/jedi_1690896916983/work
Jinja2 @ file:///home/conda/feedstock_root/build_artifacts/jinja2_1654302431367/work
json5 @ file:///home/conda/feedstock_root/build_artifacts/json5_1688248289187/work
jsonpointer @ file:///home/conda/feedstock_root/build_artifacts/jsonpointer_1694629064854/work
jsonschema @ file:///home/conda/feedstock_root/build_artifacts/jsonschema-meta_1691761378595/work
jsonschema-specifications @ file:///home/conda/feedstock_root/build_artifacts/jsonschema-specifications_1689701150890/work
jupyter @ file:///home/conda/feedstock_root/build_artifacts/jupyter_1670249594847/work
jupyter-console @ file:///home/conda/feedstock_root/build_artifacts/jupyter_console_1678118109161/work
jupyter-events @ file:///home/conda/feedstock_root/build_artifacts/jupyter_events_1691505939576/work
jupyter-server==1.24.0
jupyter-ydoc @ file:///home/conda/feedstock_root/build_artifacts/jupyter_ydoc_1685535850115/work/dist
jupyter_client @ file:///home/conda/feedstock_root/build_artifacts/jupyter_client_1673615989977/work
jupyter_core @ file:///home/conda/feedstock_root/build_artifacts/jupyter_core_1686775603054/work
jupyter_server_fileid @ file:///home/conda/feedstock_root/build_artifacts/jupyter_server_fileid_1681071667289/work
jupyter_server_terminals @ file:///home/conda/feedstock_root/build_artifacts/jupyter_server_terminals_1673491454549/work
jupyter_server_ydoc @ file:///home/conda/feedstock_root/build_artifacts/jupyter_server_ydoc_1678043727957/work
jupyterlab @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_1687805419669/work
jupyterlab-deck @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab-deck_1667437084920/work
jupyterlab-fonts @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab-fonts_1666644845625/work
jupyterlab-pygments @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_pygments_1649936611996/work
jupyterlab-widgets @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_widgets_1694598704522/work
jupyterlab_server @ file:///home/conda/feedstock_root/build_artifacts/jupyterlab_server-split_1694531968623/work
JupyterQuiz==2.6.3
kiwisolver @ file:///home/conda/feedstock_root/build_artifacts/kiwisolver_1692883585750/work
Mako==1.2.4
MarkupSafe @ file:///home/conda/feedstock_root/build_artifacts/markupsafe_1685769042879/work
matplotlib @ file:///home/conda/feedstock_root/build_artifacts/matplotlib-suite_1688684873414/work
matplotlib-inline @ file:///home/conda/feedstock_root/build_artifacts/matplotlib-inline_1660814786464/work
mistune @ file:///home/conda/feedstock_root/build_artifacts/mistune_1692116650819/work
munkres==1.1.4
nbclassic @ file:///home/conda/feedstock_root/build_artifacts/nbclassic_1683202081046/work
nbclient @ file:///home/conda/feedstock_root/build_artifacts/nbclient_1684790896106/work
nbconvert @ file:///home/conda/feedstock_root/build_artifacts/nbconvert-meta_1693331710275/work
nbformat @ file:///home/conda/feedstock_root/build_artifacts/nbformat_1690814868471/work
nbgrader==0.8.5
nbgrader-jupyterquiz==0.0.9
nest-asyncio @ file:///home/conda/feedstock_root/build_artifacts/nest-asyncio_1664684991461/work
notebook @ file:///home/conda/feedstock_root/build_artifacts/notebook_1691436218243/work
notebook_shim @ file:///home/conda/feedstock_root/build_artifacts/notebook-shim_1682360583588/work
numpy @ file:///home/conda/feedstock_root/build_artifacts/numpy_1691056235090/work
overrides @ file:///home/conda/feedstock_root/build_artifacts/overrides_1691338815398/work
packaging @ file:///home/conda/feedstock_root/build_artifacts/packaging_1681337016113/work
pandas @ file:///home/conda/feedstock_root/build_artifacts/pandas_1693415143648/work
pandocfilters @ file:///home/conda/feedstock_root/build_artifacts/pandocfilters_1631603243851/work
parso @ file:///home/conda/feedstock_root/build_artifacts/parso_1638334955874/work
pexpect @ file:///home/conda/feedstock_root/build_artifacts/pexpect_1667297516076/work
pickleshare @ file:///home/conda/feedstock_root/build_artifacts/pickleshare_1602536217715/work
Pillow @ file:///home/conda/feedstock_root/build_artifacts/pillow_1688255851102/work
pkgutil_resolve_name @ file:///home/conda/feedstock_root/build_artifacts/pkgutil-resolve-name_1694617248815/work
platformdirs @ file:///home/conda/feedstock_root/build_artifacts/platformdirs_1690813113769/work
pluggy @ file:///home/conda/feedstock_root/build_artifacts/pluggy_1693086607691/work
ply==3.11
prometheus-client @ file:///home/conda/feedstock_root/build_artifacts/prometheus_client_1689032443210/work
prompt-toolkit @ file:///home/conda/feedstock_root/build_artifacts/prompt-toolkit_1688565951714/work
psutil @ file:///home/conda/feedstock_root/build_artifacts/psutil_1681775010077/work
ptyprocess @ file:///home/conda/feedstock_root/build_artifacts/ptyprocess_1609419310487/work/dist/ptyprocess-0.7.0-py2.py3-none-any.whl
pure-eval @ file:///home/conda/feedstock_root/build_artifacts/pure_eval_1642875951954/work
pycparser @ file:///home/conda/feedstock_root/build_artifacts/pycparser_1636257122734/work
Pygments @ file:///home/conda/feedstock_root/build_artifacts/pygments_1691408637400/work
pyparsing @ file:///home/conda/feedstock_root/build_artifacts/pyparsing_1652235407899/work
PyQt5==5.15.9
PyQt5-sip==12.12.2
PySocks @ file:///home/conda/feedstock_root/build_artifacts/pysocks_1661604839144/work
pytest @ file:///home/conda/feedstock_root/build_artifacts/pytest_1694128424395/work
Pytest-Nbgrader==0.0
python-dateutil @ file:///home/conda/feedstock_root/build_artifacts/python-dateutil_1626286286081/work
python-json-logger @ file:///home/conda/feedstock_root/build_artifacts/python-json-logger_1677079630776/work
pytz @ file:///home/conda/feedstock_root/build_artifacts/pytz_1693930252784/work
PyYAML @ file:///home/conda/feedstock_root/build_artifacts/pyyaml_1692737134679/work
pyzmq @ file:///home/conda/feedstock_root/build_artifacts/pyzmq_1666828549901/work
qtconsole @ file:///home/conda/feedstock_root/build_artifacts/qtconsole-base_1693604303222/work
QtPy @ file:///home/conda/feedstock_root/build_artifacts/qtpy_1693347765905/work
rapidfuzz==3.3.0
referencing @ file:///home/conda/feedstock_root/build_artifacts/referencing_1691337268233/work
requests @ file:///home/conda/feedstock_root/build_artifacts/requests_1684774241324/work
rfc3339-validator @ file:///home/conda/feedstock_root/build_artifacts/rfc3339-validator_1638811747357/work
rfc3986-validator @ file:///home/conda/feedstock_root/build_artifacts/rfc3986-validator_1598024191506/work
rpds-py @ file:///home/conda/feedstock_root/build_artifacts/rpds-py_1694630936738/work
scipy @ file:///home/conda/feedstock_root/build_artifacts/scipy-split_1694606876598/work/base/dist/scipy-1.11.2-cp311-cp311-linux_x86_64.whl#sha256=a0b7957f603be694c9ce7dd897141b4da87eed874affd97e6b9e442d399d66d6
Send2Trash @ file:///home/conda/feedstock_root/build_artifacts/send2trash_1682601222253/work
sip @ file:///home/conda/feedstock_root/build_artifacts/sip_1690986065722/work
six @ file:///home/conda/feedstock_root/build_artifacts/six_1620240208055/work
sniffio @ file:///home/conda/feedstock_root/build_artifacts/sniffio_1662051266223/work
sortedcontainers @ file:///home/conda/feedstock_root/build_artifacts/sortedcontainers_1621217038088/work
soupsieve @ file:///home/conda/feedstock_root/build_artifacts/soupsieve_1693929250441/work
SQLAlchemy==2.0.20
stack-data @ file:///home/conda/feedstock_root/build_artifacts/stack_data_1669632077133/work
terminado @ file:///home/conda/feedstock_root/build_artifacts/terminado_1670253674810/work
tinycss2 @ file:///home/conda/feedstock_root/build_artifacts/tinycss2_1666100256010/work
toml @ file:///home/conda/feedstock_root/build_artifacts/toml_1604308577558/work
tomli @ file:///home/conda/feedstock_root/build_artifacts/tomli_1644342247877/work
tornado @ file:///home/conda/feedstock_root/build_artifacts/tornado_1692311768944/work
traitlets @ file:///home/conda/feedstock_root/build_artifacts/traitlets_1675110562325/work
typing-utils @ file:///home/conda/feedstock_root/build_artifacts/typing_utils_1622899189314/work
typing_extensions @ file:///home/conda/feedstock_root/build_artifacts/typing_extensions_1688315532570/work
tzdata @ file:///home/conda/feedstock_root/build_artifacts/python-tzdata_1680081134351/work
uri-template @ file:///home/conda/feedstock_root/build_artifacts/uri-template_1688655812972/work/dist
urllib3 @ file:///home/conda/feedstock_root/build_artifacts/urllib3_1689789803562/work
wcwidth @ file:///home/conda/feedstock_root/build_artifacts/wcwidth_1673864653149/work
webcolors @ file:///home/conda/feedstock_root/build_artifacts/webcolors_1679900785843/work
webencodings @ file:///home/conda/feedstock_root/build_artifacts/webencodings_1694681268211/work
websocket-client @ file:///home/conda/feedstock_root/build_artifacts/websocket-client_1694440396544/work
widgetsnbextension @ file:///home/conda/feedstock_root/build_artifacts/widgetsnbextension_1694598693908/work
y-py @ file:///home/conda/feedstock_root/build_artifacts/y-py_1677231021422/work
ypy-websocket @ file:///home/conda/feedstock_root/build_artifacts/ypy-websocket_1670333059911/work
zipp @ file:///home/conda/feedstock_root/build_artifacts/zipp_1689374466814/work
%% Cell type:code id:641296d4-86fb-481e-91c9-ec1e62a41209 tags:
``` python
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment