diff --git a/binder/environment.yml b/binder/environment.yml
index d5a1d4a..dc19b06 100644
--- a/binder/environment.yml
+++ b/binder/environment.yml
@@ -5,5 +5,6 @@ dependencies:
- numpy=1.15.0
- pandas=0.23.4
- python=3.7.0
+ - ipywidgets
- faker
diff --git a/requirements.txt b/requirements.txt
index 8a571d2..2573e05 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,10 +10,10 @@ backcall=0.1.0=py37_0
blas=1.0=mkl
bleach=2.1.3=py37_0
ca-certificates=2018.03.07=0
-certifi=2018.8.24=py37_1
+certifi=2018.10.15=py37_0
cffi=1.11.5=py37h342bebf_0
constantly=15.1.0=py37h28b3542_0
-cryptography=2.3=py37hdbc3d79_0
+cryptography=2.3.1=py37ha12b0ac_2
cryptography-vectors=2.3=py37_0
dbus=1.13.2=h760590f_1
decorator=4.3.0=py37_0
@@ -31,7 +31,7 @@ intel-openmp=2018.0.3=0
ipykernel=4.8.2=py37_0
ipython=6.5.0=py37_0
ipython_genutils=0.2.0=py37_0
-ipywidgets=7.4.0=py37_0
+ipywidgets=7.4.2=py37_0
jedi=0.12.1=py37_0
jinja2=2.10=py37_0
jpeg=9b=he5867d9_2
@@ -59,7 +59,7 @@ ncurses=6.1=h0a44026_0
notebook=5.6.0=py37_0
numpy=1.15.0=py37h648b28d_0
numpy-base=1.15.0=py37h8a80b8c_0
-openssl=1.0.2p=h1de35cc_0
+openssl=1.1.1=h1de35cc_0
pandas=0.23.4=py37h6440ff4_0
pandoc=2.2.1=h1a437c5_0
pandocfilters=1.4.2=py37_1
@@ -77,7 +77,7 @@ pycparser=2.18=py37_1
pygments=2.2.0=py37_0
pyopenssl=18.0.0=py37_0
pyqt=5.9.2=py37h655552a_0
-python=3.7.0=hc167b69_0
+python=3.7.1=haf84260_3
python-dateutil=2.7.3=py37_0
pytz=2018.5=py37_0
pyzmq=17.1.2=py37h1de35cc_0
@@ -90,11 +90,11 @@ setuptools=40.0.0=py37_0
simplegeneric=0.8.1=py37_2
sip=4.19.8=py37h0a44026_0
six=1.11.0=py37_1
-sqlite=3.24.0=ha441bb4_0
+sqlite=3.25.2=ha441bb4_0
terminado=0.8.1=py37_1
testpath=0.3.1=py37_0
text-unidecode=1.2=py37_0
-tk=8.6.7=h35a86e2_3
+tk=8.6.8=ha441bb4_0
tornado=5.1=py37h1de35cc_0
traitlets=4.3.2=py37_0
twisted=18.7.0=py37h1de35cc_1
diff --git a/s2n03-challenge1-top-referrers.ipynb b/s2n03-challenge1-top-referrers.ipynb
index dca016d..725eec3 100644
--- a/s2n03-challenge1-top-referrers.ipynb
+++ b/s2n03-challenge1-top-referrers.ipynb
@@ -10,7 +10,9 @@
"\n",
"Currently, anyone with **5 or more** referrals is considered a top referrer.\n",
"\n",
- "In the cell labelled CHALLENGE, follow the instructions to return what is required. Use `Kernel > Restart and run all cells` to check your work. If all the tests pass, you got it!"
+ "When you have completed the challenge, press the `Run Tests` button.\n",
+ "\n",
+ "*Need a little extra help? Check out the [Treehouse Forum](https://teamtreehouse.com/community?instruction=4552).*"
]
},
{
@@ -241,6 +243,20 @@
"execution_count": 3,
"metadata": {},
"outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "3173395f5f7e4c1dacc395df45c550f1",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(description='Run Tests', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
{
"data": {
"text/markdown": [
@@ -271,7 +287,7 @@
"AssertionError: 475 != 142 : Whoops I received a different count than I expected, make sure the last line is the entire resulting DataFrame (not just the head)\n",
"\n",
"----------------------------------------------------------------------\n",
- "Ran 3 tests in 0.005s\n",
+ "Ran 3 tests in 0.006s\n",
"\n",
"FAILED (failures=3)\n",
"\n",
@@ -288,6 +304,13 @@
"source": [
"check(__name__, 'Find the top referrers')"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
@@ -306,7 +329,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.0"
+ "version": "3.7.1"
}
},
"nbformat": 4,
diff --git a/s2n05-challenge2-update-user.ipynb b/s2n05-challenge2-update-user.ipynb
index 7045ff3..3a817c8 100644
--- a/s2n05-challenge2-update-user.ipynb
+++ b/s2n05-challenge2-update-user.ipynb
@@ -12,7 +12,9 @@
"\n",
"There are a couple ways to make this change happen, let's see what you can figure out!\n",
"\n",
- "After you've completed the TODO's choose `Kernel > Restart and Run all Cells` to see your results!\n"
+ "After you've completed the TODO's click the `Run Tests` button\n",
+ "\n",
+ "*Need a little extra help? Check out the [Treehouse Forum](https://teamtreehouse.com/community?instruction=4572).*"
]
},
{
@@ -44,13 +46,6 @@
"len(users)"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
{
"cell_type": "code",
"execution_count": 2,
@@ -120,8 +115,8 @@
"
\n",
" adrian | \n",
" Adrian | \n",
- " Yang | \n",
- " adrian.yang@teamtreehouse.com | \n",
+ " Fang | \n",
+ " adrian.fang@teamtreehouse.com | \n",
" True | \n",
" 2018-04-28 | \n",
" 3 | \n",
@@ -207,7 +202,7 @@
"aaron Aaron Davis aaron6348@gmail.com \n",
"acook Anthony Cook cook@gmail.com \n",
"adam.saunders Adam Saunders adam@gmail.com \n",
- "adrian Adrian Yang adrian.yang@teamtreehouse.com \n",
+ "adrian Adrian Fang adrian.fang@teamtreehouse.com \n",
"adrian.blair Adrian Blair adrian9335@gmail.com \n",
"... ... ... ... \n",
"wilson Robert Wilson robert@yahoo.com \n",
@@ -253,6 +248,20 @@
"execution_count": 3,
"metadata": {},
"outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "ca87e33565ed41e39c1d89da5125f6cc",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(description='Run Tests', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
{
"data": {
"text/markdown": [
@@ -262,7 +271,7 @@
"FAIL: test_jeffrey_with_one_f (tests.helpers.TestUpdateUsers)\n",
"----------------------------------------------------------------------\n",
"Traceback (most recent call last):\n",
- " File \"/Users/craig/Code/scripting/intro-to-pandas/tests/test_cells.py\", line 52, in test_jeffrey_with_one_f\n",
+ " File \"/Users/craig/Code/scripting/intro-to-pandas/tests/test_cells.py\", line 56, in test_jeffrey_with_one_f\n",
" 'Did you rename the username jeffrey to jefrey?'\n",
"AssertionError: False is not true : Did you rename the username jeffrey to jefrey?\n",
"\n",
@@ -270,12 +279,12 @@
"FAIL: test_kim_deal (tests.helpers.TestUpdateUsers)\n",
"----------------------------------------------------------------------\n",
"Traceback (most recent call last):\n",
- " File \"/Users/craig/Code/scripting/intro-to-pandas/tests/test_cells.py\", line 46, in test_kim_deal\n",
+ " File \"/Users/craig/Code/scripting/intro-to-pandas/tests/test_cells.py\", line 50, in test_kim_deal\n",
" 'Are you sure you updated the last name of kimberly@yahoo.com to \"Deal\"?'\n",
"AssertionError: nan != 'Deal' : Are you sure you updated the last name of kimberly@yahoo.com to \"Deal\"?\n",
"\n",
"----------------------------------------------------------------------\n",
- "Ran 2 tests in 0.002s\n",
+ "Ran 2 tests in 0.003s\n",
"\n",
"FAILED (failures=2)\n",
"\n",
@@ -310,7 +319,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.0"
+ "version": "3.7.1"
}
},
"nbformat": 4,
diff --git a/s2n09-challenge3-verified-email-list.ipynb b/s2n09-challenge3-verified-email-list.ipynb
index 9c3f1e5..9b1d018 100644
--- a/s2n09-challenge3-verified-email-list.ipynb
+++ b/s2n09-challenge3-verified-email-list.ipynb
@@ -13,7 +13,9 @@
"\n",
"Ensure that all first names are title cased. Do not include any records that have a missing last name, and make sure that their email is verified (**`email_verified`** should be set True). Sort by last name and then by first.\n",
"\n",
- "Choose `Kernel > Restart & Run all` to run the tests properly. \n"
+ "Once you have completed the TODOs, choose the `Run Tests` button.\n",
+ "\n",
+ "*Need a little extra help? Check out the [Treehouse Forum](https://teamtreehouse.com/community?instruction=4573).*\n"
]
},
{
@@ -245,6 +247,20 @@
"execution_count": 3,
"metadata": {},
"outputs": [
+ {
+ "data": {
+ "application/vnd.jupyter.widget-view+json": {
+ "model_id": "9979fc1830b443128f18c18c4cc5f59f",
+ "version_major": 2,
+ "version_minor": 0
+ },
+ "text/plain": [
+ "Button(description='Run Tests', style=ButtonStyle())"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
{
"data": {
"text/markdown": [
@@ -294,7 +310,7 @@
"AssertionError: 19 != 0 : Make sure you title case the first names, there are still some lower case versions\n",
"\n",
"----------------------------------------------------------------------\n",
- "Ran 5 tests in 0.034s\n",
+ "Ran 5 tests in 0.033s\n",
"\n",
"FAILED (failures=5)\n",
"\n",
@@ -329,7 +345,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.7.0"
+ "version": "3.7.1"
}
},
"nbformat": 4,
diff --git a/tests/helpers.py b/tests/helpers.py
index 939ebaa..b2cb391 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -4,7 +4,8 @@
import sys
import unittest
-from IPython.display import display, Markdown
+from IPython.display import display, Markdown, Javascript
+import ipywidgets as widgets
registered_tests = {}
@@ -23,9 +24,13 @@ def wrapped(cls):
def cell_matching(module, test_text):
# In is a list of notebook cell inputs
# Out is a dictionary of cell outputs
+ matching_indices = []
for index, value in enumerate(module.In):
if test_text in value:
- return Cell(value, module.Out.get(index))
+ matching_indices.append(index)
+ if matching_indices:
+ # The last entry is the call to `check`
+ return Cell(value, module.Out.get(matching_indices[-2]))
return None, None
@@ -43,6 +48,9 @@ class BoundTestClass(test_cls):
BoundTestClass.__doc__ = "Cell Tests for " + test_text
return BoundTestClass
+def execute_all_cells(b):
+ display(Javascript('''IPython.notebook.execute_all_cells();'''))
+
def check(module_name, test_text):
module = sys.modules[module_name]
@@ -51,4 +59,7 @@ def check(module_name, test_text):
runner = unittest.TextTestRunner(stream=output_stream)
runner.run(unittest.defaultTestLoader.loadTestsFromTestCase(test_class))
md = '```\n' + output_stream.getvalue() + '\n```'
+ button = widgets.Button(description='Run Tests')
+ button.on_click(execute_all_cells)
+ display(button)
display(Markdown(md))