aifs-hints 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aifs_hints/__init__.py +4 -0
- aifs_hints/helper.py +81 -0
- aifs_hints/hints/machine_learning/01-Californian_Housing_Market.csv +222 -0
- aifs_hints-0.1.0.dist-info/METADATA +9 -0
- aifs_hints-0.1.0.dist-info/RECORD +7 -0
- aifs_hints-0.1.0.dist-info/WHEEL +5 -0
- aifs_hints-0.1.0.dist-info/top_level.txt +1 -0
aifs_hints/__init__.py
ADDED
aifs_hints/helper.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""Graduated hints for exercise notebooks.
|
|
2
|
+
|
|
3
|
+
Usage in a notebook:
|
|
4
|
+
from aifs_hints import get_helper
|
|
5
|
+
fetch_help = get_helper("Machine Learning", "Californian Housing Market")
|
|
6
|
+
fetch_help("10a", level=2)
|
|
7
|
+
"""
|
|
8
|
+
from importlib.resources import files
|
|
9
|
+
|
|
10
|
+
import pandas as pd
|
|
11
|
+
|
|
12
|
+
REQUIRED_COLUMNS = ["module", "exercise", "task", "todo", "nudge", "hint", "scaffold"]
|
|
13
|
+
|
|
14
|
+
LEVELS = {
|
|
15
|
+
1: ("nudge", "🟢 Level 1 · Nudge"),
|
|
16
|
+
2: ("hint", "🟡 Level 2 · Hint"),
|
|
17
|
+
3: ("scaffold", "🔴 Level 3 · Scaffold"),
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _read(source):
|
|
22
|
+
return pd.read_csv(source, dtype={"task": str}, keep_default_na=False)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_all_hints():
|
|
26
|
+
"""Concatenate every CSV shipped in the package (src/aifs_hints/hints/**)."""
|
|
27
|
+
frames = []
|
|
28
|
+
for csv in _iter_csv(files("aifs_hints") / "hints"):
|
|
29
|
+
df = _read(csv)
|
|
30
|
+
df["source_file"] = csv.name
|
|
31
|
+
frames.append(df)
|
|
32
|
+
if not frames:
|
|
33
|
+
return pd.DataFrame(columns=REQUIRED_COLUMNS)
|
|
34
|
+
return pd.concat(frames, ignore_index=True)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _iter_csv(folder):
|
|
38
|
+
for entry in folder.iterdir():
|
|
39
|
+
if entry.is_dir():
|
|
40
|
+
yield from _iter_csv(entry)
|
|
41
|
+
elif entry.name.endswith(".csv"):
|
|
42
|
+
yield entry
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def list_exercises():
|
|
46
|
+
"""(module, exercise) pairs available in the package."""
|
|
47
|
+
df = load_all_hints()
|
|
48
|
+
return sorted(set(zip(df["module"], df["exercise"])))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_helper(module, exercise, source=None):
|
|
52
|
+
"""Return a fetch_help(task, level=1, content=None) function bound to one exercise.
|
|
53
|
+
|
|
54
|
+
source: optional path or URL of a CSV, to override the hints shipped in the package
|
|
55
|
+
(useful to test a CSV before committing it).
|
|
56
|
+
"""
|
|
57
|
+
df = _read(source) if source else load_all_hints()
|
|
58
|
+
df = df[(df["module"] == module) & (df["exercise"] == exercise)]
|
|
59
|
+
if df.empty:
|
|
60
|
+
raise ValueError(
|
|
61
|
+
f"No hints found for module={module!r}, exercise={exercise!r}. "
|
|
62
|
+
"Check the spelling, or call aifs_hints.list_exercises()."
|
|
63
|
+
)
|
|
64
|
+
df = df.set_index("task")
|
|
65
|
+
|
|
66
|
+
def fetch_help(task, level=1, content=None):
|
|
67
|
+
from IPython.display import Markdown, display
|
|
68
|
+
|
|
69
|
+
task = str(task)
|
|
70
|
+
if task not in df.index:
|
|
71
|
+
print(f"No help found for task {task}.")
|
|
72
|
+
elif content == "todo":
|
|
73
|
+
print(df.loc[task, "todo"])
|
|
74
|
+
elif level not in LEVELS:
|
|
75
|
+
print("level must be 1, 2 or 3.")
|
|
76
|
+
else:
|
|
77
|
+
column, title = LEVELS[level]
|
|
78
|
+
display(Markdown(f"**{title}**\n\n{df.loc[task, column]}"))
|
|
79
|
+
|
|
80
|
+
fetch_help.tasks = list(df.index)
|
|
81
|
+
return fetch_help
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"module","exercise","task","todo","nudge","hint","scaffold"
|
|
2
|
+
"Machine Learning","Californian Housing Market","3a","### Display the target values of the dataset ###","The target values are stored **inside the `data` object** you just loaded: find them and display them.","The object returned by sklearn is a **Bunch**: it works like a dictionary, so you access its elements **by key**.","`data['target']`"
|
|
3
|
+
"Machine Learning","Californian Housing Market","3b","### Display the names of the explanatory variables ###","The names of the explanatory variables are also stored in `data`: find where, and display them.","List the **keys** of the Bunch with `.keys()` and pick the one that holds the names of the features.","`data['feature_names']`"
|
|
4
|
+
"Machine Learning","Californian Housing Market","4","### Build a DataFrame named dataset with: ###
|
|
5
|
+
### - one column per feature (with the feature names) ###
|
|
6
|
+
### - a ""Price"" column containing the target ###
|
|
7
|
+
### Then display the first rows ###","- Put the features in a DataFrame, with **the right column names**
|
|
8
|
+
- Add the target as a new `Price` column
|
|
9
|
+
- Check the first rows","- `pd.DataFrame` builds a DataFrame from a 2D array, and accepts a list of **column names**.
|
|
10
|
+
- A new column is created by assigning values to it: `dataset['new_column'] = ...`","- `pd.DataFrame(data=..., columns=...)` → `data` : `data.data`, `columns` : `data.feature_names`
|
|
11
|
+
- New column: `dataset['Price']` ← `data.target`"
|
|
12
|
+
"Machine Learning","Californian Housing Market","5","# Visualize pairwise dependencies
|
|
13
|
+
### 1. Create a scatter matrix of all the columns of dataset ###
|
|
14
|
+
### 2. Give it a title and a size big enough to be readable ###
|
|
15
|
+
### 3. Display the figure ###","- Plot **every pair of columns** in a single figure
|
|
16
|
+
- Make it big enough to be readable
|
|
17
|
+
- 👀 How does each feature relate to `Price`?","- Plotly Express has a function that draws **all pairwise scatter plots at once**: `px.scatter_matrix`.
|
|
18
|
+
- The default figure is too small for 9 columns: resize it with `fig.update_layout`.","- `px.scatter_matrix(dataset)`
|
|
19
|
+
- `fig.update_layout(title=..., autosize=False, width=..., height=...)` → around 1200 x 1200
|
|
20
|
+
- `fig.show()`"
|
|
21
|
+
"Machine Learning","Californian Housing Market","6","### 1. Create a boolean mask that keeps the rows where: ###
|
|
22
|
+
### AveRooms < 10, AveBedrms < 10, Population < 15000, ###
|
|
23
|
+
### AveOccup < 10 and Price < 5 ###
|
|
24
|
+
### 2. Apply the mask to dataset ###
|
|
25
|
+
### 3. Make the same scatter matrix as before on the filtered data ###","- Write **one condition per column** (the thresholds are in the instructions)
|
|
26
|
+
- Keep a row **only if all the conditions are true**
|
|
27
|
+
- Apply this filter to `dataset`, then redo the plot of question 5","- A comparison on a column (`<`, `>`…) returns a **boolean Series**.
|
|
28
|
+
- Combine boolean Series with `&` (not `and`).
|
|
29
|
+
- Filter the rows of a DataFrame with a boolean mask using `.loc`.","- One condition: `(dataset['AveRooms'] < 10)` ⚠️ the **parentheses** are mandatory
|
|
30
|
+
- Combine: `(condition_1) & (condition_2) & ...`
|
|
31
|
+
- Filter: `dataset.loc[mask, :]`"
|
|
32
|
+
"Machine Learning","Californian Housing Market","7","# Correlation matrix
|
|
33
|
+
### 1. Compute the correlation matrix of dataset (round it) ###
|
|
34
|
+
### 2. Plot it as a heatmap, with the column names on both axes ###
|
|
35
|
+
### 3. Display the figure ###","- Compute the **correlation** between every pair of columns
|
|
36
|
+
- Display it as a **heatmap**
|
|
37
|
+
- 👀 Read the `Price` row: which feature is the most correlated with the target?","- pandas computes the correlation matrix of a DataFrame with `.corr()`.
|
|
38
|
+
- `px.imshow` displays a 2D table as a heatmap.","- `dataset.corr()` (add `.round(2)` for readability)
|
|
39
|
+
- `px.imshow(corr_matrix, text_auto=True)` → `text_auto` writes the values in the cells"
|
|
40
|
+
"Machine Learning","Californian Housing Market","8","# Separate target variable Y from features X
|
|
41
|
+
print(""Separating labels from features..."")
|
|
42
|
+
|
|
43
|
+
### 1. Store the list of features to use (only ""MedInc"") in ###
|
|
44
|
+
### features_list, and the target name (""Price"") in ###
|
|
45
|
+
### target_variable ###
|
|
46
|
+
### 2. X = the features_list columns of dataset ###
|
|
47
|
+
### 3. Y = the target column ###
|
|
48
|
+
|
|
49
|
+
print(""...Done."")
|
|
50
|
+
print()
|
|
51
|
+
|
|
52
|
+
print('Y : ')
|
|
53
|
+
print(Y.head())
|
|
54
|
+
print()
|
|
55
|
+
print('X :')
|
|
56
|
+
print(X.head())","- `X` = only the `MedInc` column
|
|
57
|
+
- `Y` = the `Price` column
|
|
58
|
+
- ⚠️ `X` must stay a **table (2D)**: sklearn expects a 2D input for the features","- Select columns with `.loc`.
|
|
59
|
+
- With a **list** of names, `.loc` returns a DataFrame (2D). With a **single** name, it returns a Series (1D).","- `features_list = ['MedInc']`
|
|
60
|
+
- `dataset.loc[:, features_list]`
|
|
61
|
+
- `dataset.loc[:, target_variable]`"
|
|
62
|
+
"Machine Learning","Californian Housing Market","9","# Divide dataset Train set & Test set
|
|
63
|
+
print(""Dividing into train and test sets..."")
|
|
64
|
+
|
|
65
|
+
### Split X and Y into X_train, X_test, Y_train, Y_test ###
|
|
66
|
+
### (80% train / 20% test) ###
|
|
67
|
+
|
|
68
|
+
print(""...Done."")
|
|
69
|
+
print()","- Split `X` and `Y` into a train set and a test set
|
|
70
|
+
- 20% of the rows for the test set
|
|
71
|
+
- Make the split **reproducible**","`train_test_split` (from `sklearn.model_selection`) returns **4 objects**, in this order: `X_train, X_test, Y_train, Y_test`.
|
|
72
|
+
Its `random_state` parameter fixes the randomness.","`train_test_split(X, Y, test_size=0.2, random_state=0)`"
|
|
73
|
+
"Machine Learning","Californian Housing Market","10a","print(""Preprocessing X_train..."")
|
|
74
|
+
print(X_train.head())
|
|
75
|
+
print()
|
|
76
|
+
|
|
77
|
+
### Standardize all the columns of X_train ###
|
|
78
|
+
### 1. Instantiate a StandardScaler ###
|
|
79
|
+
### 2. Fit it AND transform X_train in a single step ###
|
|
80
|
+
|
|
81
|
+
print(""...Done!"")
|
|
82
|
+
print(X_train[0:5,:]) # X_train is now a numpy array","**Standardize** the training features: learn the mean and the standard deviation on the train set, and apply them.","- `StandardScaler` (from `sklearn.preprocessing`) standardizes every column.
|
|
83
|
+
- Its `.fit_transform()` method **learns and applies** in a single call.
|
|
84
|
+
- The result is a **numpy array**, no longer a DataFrame.","- `StandardScaler()`
|
|
85
|
+
- `scaler.fit_transform(X_train)`"
|
|
86
|
+
"Machine Learning","Californian Housing Market","10b","print(""Preprocessing X_test..."")
|
|
87
|
+
print(X_test.head())
|
|
88
|
+
print()
|
|
89
|
+
|
|
90
|
+
### Standardize X_test using the scaler fitted on X_train ###
|
|
91
|
+
|
|
92
|
+
print(""...Done!"")
|
|
93
|
+
print(X_test[0:5,:]) # X_test is now a numpy array","Apply **the same standardization** to the test set, using only what was learned on the train set.","- Reuse the **same** `scaler` object.
|
|
94
|
+
- `.transform()` applies the transformation **without learning** anything.
|
|
95
|
+
- ⚠️ Fitting on the test set would **leak** information from the test set into your preprocessing.","`scaler.transform(X_test)`"
|
|
96
|
+
"Machine Learning","Californian Housing Market","11a","# Train model
|
|
97
|
+
print(""Train model..."")
|
|
98
|
+
|
|
99
|
+
### 1. Instantiate a LinearRegression model named regressor ###
|
|
100
|
+
### (it's used in the next cells) ###
|
|
101
|
+
### 2. Fit it on the training set (X_train, Y_train) ###
|
|
102
|
+
|
|
103
|
+
print(""...Done."")","Create a **linear regression** model named `regressor`, and train it on the training set.","- The model is `LinearRegression` (from `sklearn.linear_model`).
|
|
104
|
+
- Every sklearn model is trained with `.fit()`.","- `LinearRegression()`
|
|
105
|
+
- `regressor.fit(X_train, Y_train)`"
|
|
106
|
+
"Machine Learning","Californian Housing Market","11b","# Print R^2 scores
|
|
107
|
+
### Complete the two prints with the R2 score of regressor ###
|
|
108
|
+
### on the training set and on the test set ###
|
|
109
|
+
print(""R2 score on training set : "", )
|
|
110
|
+
print(""R2 score on test set : "", )","- Compute the **R²** on the train set and on the test set
|
|
111
|
+
- 👀 Are the two scores close?","sklearn regressors have a `.score()` method that returns the **R²** directly.
|
|
112
|
+
(Alternative: `r2_score` from `sklearn.metrics`, with the true values and the predictions.)","- `regressor.score(X_train, Y_train)`
|
|
113
|
+
- `regressor.score(X_test, Y_test)`"
|
|
114
|
+
"Machine Learning","Californian Housing Market","12a","# Predictions on training set
|
|
115
|
+
print(""Predictions on training set..."")
|
|
116
|
+
|
|
117
|
+
### Use the trained regressor to predict on X_train ###
|
|
118
|
+
### Store the result in Y_train_pred ###
|
|
119
|
+
|
|
120
|
+
print(""...Done."")
|
|
121
|
+
print(Y_train_pred)
|
|
122
|
+
print()","Use the trained model to **predict** the prices of the training set.","Every trained sklearn model has a `.predict()` method.","`regressor.predict(X_train)`"
|
|
123
|
+
"Machine Learning","Californian Housing Market","12b","# Predictions on test set
|
|
124
|
+
print(""Predictions on test set..."")
|
|
125
|
+
|
|
126
|
+
### Use the same trained regressor to predict on X_test ###
|
|
127
|
+
### Store the result in Y_test_pred ###
|
|
128
|
+
|
|
129
|
+
print(""...Done."")
|
|
130
|
+
print(Y_test_pred)
|
|
131
|
+
print()","Same thing on the test set, **without retraining** the model.","Use `.predict()` again, on the test features.","`regressor.predict(X_test)`"
|
|
132
|
+
"Machine Learning","Californian Housing Market","12c","# Visualize the model
|
|
133
|
+
|
|
134
|
+
# Visualize predictions on training set
|
|
135
|
+
### 1. Scatter plot of the real values: x = X_train, y = Y_train ###
|
|
136
|
+
### 2. Add the regression line on top, with Y_train_pred as y ###
|
|
137
|
+
### 3. Display the figure ###
|
|
138
|
+
|
|
139
|
+
# Visualize predictions on test set
|
|
140
|
+
### Same thing on the test set: real values (X_test, Y_test) ###
|
|
141
|
+
### + predictions (Y_test_pred) on the same figure ###","For the train set, then for the test set, on the same figure:
|
|
142
|
+
- the **real prices** as points
|
|
143
|
+
- the **predictions** as a line","- `px.scatter` draws the points.
|
|
144
|
+
- `fig.add_trace(go.Scatter(...))` adds a line on top of an existing figure.
|
|
145
|
+
- ⚠️ `X_train` is now a **2D numpy array**: flatten it to 1D before giving it to plotly.","- Points: `px.scatter(x=..., y=Y_train, title=...)`
|
|
146
|
+
- Line: `fig.add_trace(go.Scatter(x=..., y=Y_train_pred, name=...))`
|
|
147
|
+
- `x` : `X_train.flatten().tolist()`"
|
|
148
|
+
"Machine Learning","Californian Housing Market","13a","# Separate target variable Y from features X
|
|
149
|
+
print(""Separating labels from features..."")
|
|
150
|
+
|
|
151
|
+
### 1. Store the name of the target column (""Price"") in ###
|
|
152
|
+
### a variable target_variable ###
|
|
153
|
+
### 2. X = all columns except the target ###
|
|
154
|
+
### 3. Y = only the target column ###
|
|
155
|
+
|
|
156
|
+
print(""...Done."")
|
|
157
|
+
print()
|
|
158
|
+
|
|
159
|
+
print('Y : ')
|
|
160
|
+
print(Y.head())
|
|
161
|
+
print()
|
|
162
|
+
print('X :')
|
|
163
|
+
X.head()","- `X` = **all the columns except** `Price`
|
|
164
|
+
- `Y` = the `Price` column","`.drop()` removes columns from a DataFrame (use `axis=1` for columns).","- `dataset.drop(target_variable, axis=1)`
|
|
165
|
+
- `dataset.loc[:, target_variable]`"
|
|
166
|
+
"Machine Learning","Californian Housing Market","13b","# Divide dataset Train set & Test set
|
|
167
|
+
print(""Dividing into train and test sets..."")
|
|
168
|
+
|
|
169
|
+
### Split X and Y into X_train, X_test, Y_train, Y_test ###
|
|
170
|
+
### (80% train / 20% test, same random_state as the baseline) ###
|
|
171
|
+
|
|
172
|
+
print(""...Done."")
|
|
173
|
+
print()","Split again into train and test, **exactly like for the baseline**, so the comparison is fair.","Same `train_test_split` as in question 9: the **same `random_state`** gives the same rows in each set.","`train_test_split(X, Y, test_size=0.2, random_state=0)`"
|
|
174
|
+
"Machine Learning","Californian Housing Market","13c","# Preprocessing
|
|
175
|
+
print(""Preprocessing X_train..."")
|
|
176
|
+
print(X_train.head())
|
|
177
|
+
print()
|
|
178
|
+
|
|
179
|
+
### Standardize all the columns of X_train (fit + transform) ###
|
|
180
|
+
|
|
181
|
+
print(""...Done!"")
|
|
182
|
+
print(X_train[0:5,:]) # X_train is now a numpy array","Standardize the training features again. ⚠️ `X` has more columns now.","You need a **new** `StandardScaler`: the previous one was fitted on one column only. Then `.fit_transform()`.","- `StandardScaler()`
|
|
183
|
+
- `scaler.fit_transform(X_train)`"
|
|
184
|
+
"Machine Learning","Californian Housing Market","13d","print(""Preprocessing X_test..."")
|
|
185
|
+
print(X_test.head())
|
|
186
|
+
print()
|
|
187
|
+
|
|
188
|
+
### Standardize X_test using the scaler fitted on X_train ###
|
|
189
|
+
|
|
190
|
+
print(""...Done!"")
|
|
191
|
+
print(X_test[0:5,:]) # X_test is now a numpy array","Apply the standardization to the test set, **without learning** on it.","`.transform()` of the scaler you just fitted on `X_train`.","`scaler.transform(X_test)`"
|
|
192
|
+
"Machine Learning","Californian Housing Market","13e","# Train model
|
|
193
|
+
print(""Train model..."")
|
|
194
|
+
|
|
195
|
+
### Instantiate a new LinearRegression named regressor and fit it ###
|
|
196
|
+
### on the training set ###
|
|
197
|
+
|
|
198
|
+
print(""...Done."")","Train a new linear regression, this time on **all the features**.","Same model and same method as in question 11: `LinearRegression` and `.fit()`.","- `LinearRegression()`
|
|
199
|
+
- `regressor.fit(X_train, Y_train)`"
|
|
200
|
+
"Machine Learning","Californian Housing Market","13f","# Print R^2 scores
|
|
201
|
+
### Complete the two prints with the R2 score of regressor ###
|
|
202
|
+
### Then compare them with the baseline model ###
|
|
203
|
+
print(""R2 score on training set : "", )
|
|
204
|
+
print(""R2 score on test set : "", )","- Compute the **R²** on the train set and on the test set
|
|
205
|
+
- 👀 Compare with the baseline: how much do you gain with all the features?","Same method as in question 11: `.score()`.","- `regressor.score(X_train, Y_train)`
|
|
206
|
+
- `regressor.score(X_test, Y_test)`"
|
|
207
|
+
"Machine Learning","Californian Housing Market","14a","### 1. Store the names of the features in column_names ###
|
|
208
|
+
### 2. Create a DataFrame coefs with one row per feature and ###
|
|
209
|
+
### its coefficient in the model ###
|
|
210
|
+
### 3. Display coefs ###","Build a table with **each feature name next to its coefficient** in the model.","- The learned coefficients are stored in the `.coef_` attribute of the model, **in the same order as the columns of `X`**.
|
|
211
|
+
- The names are simply `X.columns` (no complex preprocessing here).
|
|
212
|
+
- Build the table with `pd.DataFrame`, using the names as index.","`pd.DataFrame(index=column_names, data=regressor.coef_, columns=['coefficients'])`"
|
|
213
|
+
"Machine Learning","Californian Housing Market","14b","### 1. Compute the absolute value of the coefficients and sort them ###
|
|
214
|
+
### 2. Plot them in a horizontal bar chart ###
|
|
215
|
+
### 3. Remove the legend and add a left margin for the labels ###
|
|
216
|
+
### 4. Display the figure ###","- Rank the features by **importance** = size of the coefficient, **whatever its sign**
|
|
217
|
+
- Plot them in a horizontal bar chart
|
|
218
|
+
- 👀 Why can you compare the coefficients with each other here?","- `abs()` gives the absolute values, `.sort_values()` sorts them.
|
|
219
|
+
- `px.bar` with a horizontal orientation, then `fig.update_layout` to hide the legend and leave room for the labels.
|
|
220
|
+
- Coefficients are comparable because all the features were **standardized**.","- `abs(coefs).sort_values(by='coefficients')`
|
|
221
|
+
- `px.bar(feature_importance, orientation='h')`
|
|
222
|
+
- `fig.update_layout(showlegend=False, margin={'l': 120})`"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aifs_hints
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Graduated hints (nudge / hint / scaffold) for exercise notebooks
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Requires-Dist: pandas
|
|
7
|
+
Requires-Dist: ipython
|
|
8
|
+
Provides-Extra: dev
|
|
9
|
+
Requires-Dist: pytest; extra == "dev"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
aifs_hints/__init__.py,sha256=QX9ZuL0prOL_k6DLKLtDW9uBApXRr69qzrfR7ePHEUc,165
|
|
2
|
+
aifs_hints/helper.py,sha256=AOzZtpLAGIIvhLUXgKNM-_CCfR3zss_dYCFJtB2Gxns,2558
|
|
3
|
+
aifs_hints/hints/machine_learning/01-Californian_Housing_Market.csv,sha256=Hzf3W7swBLFp-vfoWunyHNy6Twmfhayg5gUMzVFo9AQ,15307
|
|
4
|
+
aifs_hints-0.1.0.dist-info/METADATA,sha256=ukOL7_K3t_mJcLCrE13pPwsYJpA_dYFiaLf6Ndw08pE,254
|
|
5
|
+
aifs_hints-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
6
|
+
aifs_hints-0.1.0.dist-info/top_level.txt,sha256=6nFBaP-9SrQ5hW7FEyih-NCpTf070Lm3eArn3fM2fzk,11
|
|
7
|
+
aifs_hints-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
aifs_hints
|