diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a1bcc661f20ad7aab9ca0e4daf499259d2a12f7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Original file copied From: https://gist.github.com/kjaanson/de713cff4ab7d493563fd9731a232534 +/*.egg-info +/.spyderproject +.spyderproject +.idea/* +/**/.DS_Store +/**/__pycache__ +/**/.ipynb_checkpoints +/.doit.db.bak +/.doit.db.dat +/.doit.db.dir +*.mp4 +*.mpg +*.html diff --git a/_Template.ipynb b/_Template.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..3d716a3601889e6a0f22f5b41ea2799702665a29 --- /dev/null +++ b/_Template.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "fc73d74c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "('answercheck.py', <http.client.HTTPMessage at 0x7fb0f93d4250>)" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "##ANSWER##\n", + "#Install answercheck in current directory\n", + "from urllib.request import urlretrieve\n", + "urlretrieve('https://raw.githubusercontent.com/colbrydi/jupytercheck/master/answercheck.py', filename='answercheck.py')\n", + "##ANSWER##" + ] + }, + { + "cell_type": "markdown", + "id": "3c2a4f39", + "metadata": {}, + "source": [ + "# Short title\n", + "long title" + ] + }, + { + "cell_type": "markdown", + "id": "2b78245b", + "metadata": {}, + "source": [ + "**_Optional_** Motivating picture: \n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "71e867d9", + "metadata": {}, + "source": [ + "## Description\n", + "This a description of the topic. \n", + "\n", + "\n", + "## Learning Goals\n", + "\n", + "Maybe we should include these as learning goals? Consider using [bloom's taxonomy](https://cft.vanderbilt.edu/guides-sub-pages/blooms-taxonomy/)" + ] + }, + { + "cell_type": "markdown", + "id": "2a07e824", + "metadata": {}, + "source": [ + "##ANSWER##\n", + "\n", + "TODO: Put a table here\n", + "\n", + "##ANSWER##" + ] + }, + { + "cell_type": "markdown", + "id": "58ec20e8", + "metadata": {}, + "source": [ + "## Self Assessment\n", + "\n", + "Questions that test for the learning goals and allows students to evaluate if they truly understand the topics." + ] + }, + { + "cell_type": "markdown", + "id": "5d237ca9", + "metadata": {}, + "source": [ + "## Training Materials\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "id": "21f9b14e", + "metadata": {}, + "source": [ + "[Direct Link to Video](https://www.youtube.com/watch?v=kzI-mPSY8y4)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "deeec8f7", + "metadata": {}, + "outputs": [ + { + "data": { + "image/jpeg": "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\n", + "text/html": [ + "\n", + " <iframe\n", + " width=\"100%\"\n", + " height=\"360\"\n", + " src=\"https://www.youtube.com/embed/kzI-mPSY8y4?cc_load_policy=True\"\n", + " frameborder=\"0\"\n", + " allowfullscreen\n", + " ></iframe>\n", + " " + ], + "text/plain": [ + "<IPython.lib.display.YouTubeVideo at 0x7fb0cc25a6d0>" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import YouTubeVideo\n", + "YouTubeVideo(\"kzI-mPSY8y4\",width=\"100%\", height=360, cc_load_policy=True)" + ] + }, + { + "cell_type": "markdown", + "id": "1b047470", + "metadata": {}, + "source": [ + "✅ **<span style=\"color:red\">Question:</span>** Example Multiple choice question:\n", + "\n", + "1. Answer 1\n", + "2. Answer b\n", + "3. Answer III\n", + "4. All of the above" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "ee42a54e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "3" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "##ANSWER##\n", + "3\n", + "##ANSWER##" + ] + }, + { + "cell_type": "markdown", + "id": "dd9c7fa5", + "metadata": {}, + "source": [ + "✅ **<span style=\"color:red\">Question:</span>** Example answercheck question: What is $x = 2+2$?\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "64684dfd", + "metadata": {}, + "outputs": [], + "source": [ + "#Put your answer here" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "619a2259", + "metadata": {}, + "outputs": [], + "source": [ + "##ANSWER##\n", + "x = 4\n", + "##ANSWER##" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "9cc2b34a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "CheckWarning: passed variable is <class 'int'> and not a numpy.matrix.\n", + " Trying to convert to a array matrix using ```A = np.matrix(A)```.\n", + "\n", + "\n", + "CheckWarning: passed matrix is int64 and not <class 'numpy.float64'>...\n", + " Trying to convert to float using ```A = A.astype(float)```.\n", + "\n", + "Testing [[4.]]\n", + "Answer seems to be correct\n", + "\n" + ] + } + ], + "source": [ + "from answercheck import checkanswer\n", + "checkanswer.vector(x,'2cab95d1b144d663bad1ce5c51020ae0')" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "8be3295e", + "metadata": {}, + "outputs": [], + "source": [ + "assert(True==True)" + ] + }, + { + "cell_type": "markdown", + "id": "44b461a0", + "metadata": {}, + "source": [ + "---\n", + "\n", + "Written by <<YOUR NAME HERE>>, Michigan State University \n", + "As part of the Data Science Bridge Project \n", + " \n", + "<a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc/4.0/\"><img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-nc/4.0/88x31.png\" /></a><br />This work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc/4.0/\">Creative Commons Attribution-NonCommercial 4.0 International License</a>." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/answercheck.py b/answercheck.py new file mode 100644 index 0000000000000000000000000000000000000000..ccee41e986db8f3220f521371c69074c3290863a --- /dev/null +++ b/answercheck.py @@ -0,0 +1,163 @@ +import hashlib +import numpy as np +import sympy as sym +import sys +import textwrap + + +# detailedwarnings = True + +# Things I fixed. Fixed Matrix rounding error +# Added more print warnings + +# TODO: Fix Printwarnings + + +def printwarning(message): + if checkanswer.detailedwarnings: + print(message) + + +class checkanswer(): + detailedwarnings = True + + def __init__(self, var, hashtag=None): + checkanswer.basic(var, hashtag) + + def basic(var, hashtag=None): + """Fuanction that encodes answers in a string called a Hash. + This is a one way function so a correct answer will generate the + correct has. An incorrect answer will generate an incorrect hash.""" + + if checkanswer.detailedwarnings: + print(f"Testing {var}") + else: + print(f"Testing Answer") + + curr_printopts = np.get_printoptions() + np.set_printoptions(threshold=sys.maxsize) + varstr = f"{var}" + np.set_printoptions(threshold=curr_printopts['threshold']) + + t2 = varstr.encode("utf-8") + m = hashlib.md5(t2) + checktag = m.hexdigest() + if hashtag: + if checktag == hashtag: + print("Answer seems to be correct\n") + else: + print("Answer seems to be incorrect\n") + assert checktag == hashtag, f"Answer is incorrect {checktag}" + else: + raise TypeError(f"No answer hastag provided: {checktag}") + + def float(A, hashtag=None, decimal_accuracy = 5): + """Function to check matrix type before hashing.""" + if(type(A) is not float): + if(type(A) is list): + printwarning(textwrap.dedent(f""" + CheckWarning: passed variable is a list and not a float... + Cannot convert list to float directly. We will assume this + list has only one element and covert to a numpy matrix + using ```A = np.matrix(A)```.\n""")) + A = np.matrix(A) + printwarning(textwrap.dedent(f""" + CheckWarning: passed variable is {type(A)} and not a float. + Trying to convert to a float using ```A = float(A)```.\n""")) + A = float(A) + A = np.round(A, decimals=decimal_accuracy) + if A == -0.00: + printwarning(textwrap.dedent(f""" + CheckWarning: Value is negative zero... + Converting to positive zero before checking using ```A = 0.00```.\n""")) + A = 0.00 + return checkanswer.basic(A, hashtag) + + def make_vector(A, decimal_accuracy = 5): + """Function to check matrix type before hashing.""" + if(type(A) is not np.matrix): + printwarning(textwrap.dedent(f""" + CheckWarning: passed variable is {type(A)} and not a numpy.matrix. + Trying to convert to a array matrix using ```A = np.matrix(A)```.\n""")) + A = np.matrix(A) + if not np.issubdtype(A.dtype, np.dtype(float).type): + printwarning(textwrap.dedent(f""" + CheckWarning: passed matrix is {A.dtype} and not {np.dtype(float).type}... + Trying to convert to float using ```A = A.astype(float)```.\n""")) + A = A.astype(float) + if(A.shape[0] != 1 and A.shape[1] != 1): + assert A.shape[0] != 1 and A.shape[1] != 1, \ + f"Matrix is not of vector format {A}" + if(A.shape[0] != 1): + printwarning(textwrap.dedent(f""" + CheckWarning: numpy.matrix is row vector... + Trying to convert to a column vector using ```A = A.T```.\n""")) + A = A.T + A = np.round(A, decimals=decimal_accuracy) + if not A[A == -0].size == 0: + printwarning(textwrap.dedent(f""" + CheckWarning: Vector contains negative values for zero... + Converting to positive values of zero using ```A[A==-0] = 0```.\n""")) + A[A == -0] = 0.00 + return A + + def vector(A, hashtag=None, decimal_accuracy = 5): + A = checkanswer.make_vector(A, decimal_accuracy) + return checkanswer.basic(A, hashtag) + + def eq_vector(A, hashtag=None, decimal_accuracy = 5): + A = checkanswer.make_vector(A, decimal_accuracy) + vecsum = np.sqrt(np.sum(np.dot(A,A.T))) + if not vecsum == 1: + printwarning(textwrap.dedent(f""" + CheckWarning: Vector sum of {A} has total value of {vecsum}... + Trying to normalize to unit vector to check answer using + using ```A = A/{vecsum}```.\n\n""")) + A = A/vecsum + if(A[0, 0] < 0): + printwarning(textwrap.dedent(f""" + CheckWarning: First element of {A} is negative ({A[0,0]}. + Trying to normalize by making this value positive using ```A = -A```.\n""")) + A = -A + A = np.round(A, decimals=decimal_accuracy) + if not A[A == -0].size == 0: + printwarning(textwrap.dedent(f""" + CheckWarning: Vector contains negative values for zero... + Converting to positive values of zero using ```A[A==-0] = 0```.\n""")) + A[A == -0] = 0.00 + return checkanswer.basic(A, hashtag) + + def make_matrix(A, decimal_accuracy = 5): + if(type(A) is not np.matrix): + printwarning(textwrap.dedent(f""" + CheckWarning: passed variable is {type(A)} and not a numpy.matrix... + Trying to convert to a array matrix using ```A = np.matrix(A)```.\n""")) + A = np.matrix(A) + if not np.issubdtype(A.dtype, np.dtype(float).type): + printwarning(textwrap.dedent(f""" + CheckWarning: passed matrix is {A.dtype} and not {np.dtype(float).type}... + Trying to convert to float using ```A = A.astype(float)```.\n""")) + A = A.astype(float) + A = np.round(A, decimals=decimal_accuracy) + if not A[A == -0].size == 0: + printwarning(textwrap.dedent(f""" + CheckWarning: Matrix contains negative values for zero... + Converting to positive values of zero using ```A[A==-0] = 0```.\n""")) + A[A == -0] = 0.00 + return A + + def matrix(A, hashtag=None, decimal_accuracy = 5): + """Function to check matrix type before hashing.""" + A = checkanswer.make_matrix(A, decimal_accuracy) + return checkanswer.basic(A, hashtag) + + # TODO: Not complete or tested. + def eq_matrix(A, hashtag=None, decimal_accuracy = 5): + """Function to convert matrix to reduced row echelon form + and then run hashing.""" + A = checkanswer.make_matrix(A, decimal_accuracy) + symA = sym.Matrix(A) + symA = symA.rref()[0] + A = np.matrix(symA) + A = checkanswer.make_matrix(A) + return checkanswer.basic(A, hashtag)