Skip to content
Snippets Groups Projects
Commit 5dcbe822 authored by tuhe's avatar tuhe
Browse files

Remote result viewing in early version

parent 04b17483
No related branches found
No related tags found
No related merge requests found
Showing
with 488 additions and 34 deletions
Metadata-Version: 2.1 Metadata-Version: 2.1
Name: unitgrade-devel Name: unitgrade-devel
Version: 0.1.54 Version: 0.1.55
Summary: A set of tools to develop unitgrade tests and reports and later evaluate them Summary: A set of tools to develop unitgrade tests and reports and later evaluate them
Home-page: https://lab.compute.dtu.dk/tuhe/unitgrade_private Home-page: https://lab.compute.dtu.dk/tuhe/unitgrade_private
Author: Tue Herlau Author: Tue Herlau
......
from unitgrade.evaluate import evaluate_report, python_code_str_id import sys
from unitgrade.evaluate import evaluate_report, python_code_str_id, _print_header
import textwrap import textwrap
import bz2 import bz2
import pickle import pickle
...@@ -6,6 +7,7 @@ import os ...@@ -6,6 +7,7 @@ import os
import zipfile import zipfile
import io import io
from unitgrade.utils import picklestring2dict, dict2picklestring, load_token, token_sep from unitgrade.utils import picklestring2dict, dict2picklestring, load_token, token_sep
from unitgrade import Report
def bzwrite(json_str, token): # to get around obfuscation issues def bzwrite(json_str, token): # to get around obfuscation issues
with getattr(bz2, 'open')(token, "wt") as f: with getattr(bz2, 'open')(token, "wt") as f:
...@@ -23,9 +25,6 @@ def gather_imports(imp): ...@@ -23,9 +25,6 @@ def gather_imports(imp):
if isinstance(im, list): if isinstance(im, list):
print("im is a list") print("im is a list")
print(im) print(im)
# the __path__ attribute *may* be a string in some cases. I had to fix this.
# print("path.:", __import__(m.__name__.split('.')[0]).__path__)
# top_package = __import__(m.__name__.split('.')[0]).__path__._path[0]
top_package = __import__(m.__name__.split('.')[0]).__path__[0] top_package = __import__(m.__name__.split('.')[0]).__path__[0]
module_import = False module_import = False
...@@ -58,13 +57,20 @@ parser = argparse.ArgumentParser(description='Evaluate your report.', epilog=""" ...@@ -58,13 +57,20 @@ parser = argparse.ArgumentParser(description='Evaluate your report.', epilog="""
> python report1_grade.py > python report1_grade.py
Finally, note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful. Depending on the course configuration, you get the online evaluation/verification results using the `--evaluation`-flag. Example:
> python report1_grade.py --evaluation
The evaluation is of course only available after the teacher has made it available.
Note that if your report is part of a module (package), and the report script requires part of that package, the -m option for python may be useful.
For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run: For instance, if the report file is in Documents/course_package/report3_complete.py, and `course_package` is a python package, then change directory to 'Documents/` and run:
> python -m course_package.report1 > python -m course_package.report1
see https://docs.python.org/3.9/using/cmdline.html see https://docs.python.org/3.9/using/cmdline.html
""", formatter_class=argparse.RawTextHelpFormatter) """, formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('--evaluation', action="store_true", help='Get the remote evaluation of this report')
parser.add_argument('--noprogress', action="store_true", help='Disable progress bars') parser.add_argument('--noprogress', action="store_true", help='Disable progress bars')
parser.add_argument('--autolab', action="store_true", help='Show Autolab results') parser.add_argument('--autolab', action="store_true", help='Show Autolab results')
parser.add_argument('--force_kill', action="store_true", help='Forcefully quit on exit.') parser.add_argument('--force_kill', action="store_true", help='Forcefully quit on exit.')
...@@ -96,6 +102,63 @@ def gather_report_source_include(report): ...@@ -96,6 +102,63 @@ def gather_report_source_include(report):
def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_source=False): def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_source=False):
# n = report.nL # n = report.nL
args = parser.parse_args() args = parser.parse_args()
if report.remote_url is not None and args.evaluation:
import datetime
_print_header(now=datetime.datetime.now(), big_header=True)
# get the remote evaluation.
# os.path.dirname(report._artifact_file())
mf = report._manifest_file()
if os.path.isfile(mf):
with open(mf, 'r') as f:
s = f.read()
from unitgrade.utils import checkout_remote_results
results = checkout_remote_results(report.remote_url, s.strip())
if results['html'] is None:
print("""Oy! I failed to download the verified results.
There can be three reasons why this this command failed:
* You have not yet uploaded a .token file (i.e., you have not yet handed in)
* You did not upload a .token file, but rather a file in some other format.
* You have reset/deleted files from the unitgrade_data directory. In this case I don't know what file to look for remotely.
* The .token files associated with this project have not yet been processed by the course responsible.
Assuming you have handed in, and it has been announced the results should be available online, you should contact a TA
for more information about what happened to your evaluation. Please don't contact the teachers directly.
""")
sys.exit()
print("Your verified results are:")
import tabulate
# import sys
print( tabulate.tabulate(results['df'], showindex=False) )
print("These scores are based on our internal tests.")
print("To see all your results, visit:")
print(">", results['url'])
print("Your total score was", results['total'])
sys.exit()
# import tabulate
# print( tabulate.tabulate(df, showindex=False) )
else:
print(f"""
The --evaluation flag is used to download and display the (teacher) verification of your result from:
> %s
That means you should only use this command after you have uploaded your .token file.
Error: I could not find information about previously generated tokens. The likely causes are:
* You have not generated a token and uploaded a .token-file yet
* You have uploaded a .token file, but it has not yet been evaluated.
"""%(report.remote_url,))
sys.exit()
results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True, results, table_data = evaluate_report(report, show_help_flag=False, show_expected=False, show_computed=False, silent=True,
show_progress_bar=not args.noprogress, show_progress_bar=not args.noprogress,
big_header=not args.autolab, big_header=not args.autolab,
...@@ -144,7 +207,19 @@ def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_ ...@@ -144,7 +207,19 @@ def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_
token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible, vstring) token = "%s_%i_of_%i%s.token"%(payload_out_base, obtain, possible, vstring)
token = os.path.normpath(os.path.join(output_dir, token)) token = os.path.normpath(os.path.join(output_dir, token))
save_token(results, "\n".join(s_include), token) b_hash = save_token(results, "\n".join(s_include), token)
try:
with open(report._manifest_file(), 'a') as _file:
_file.write("\n"+token + " " + b_hash)
except Exception as e:
print(e)
# ug_dir = os.path.dirname(report._artifact_file())
# ug_name = os.path.basename(report._artifact_file())
# MANIFEST = ug_dir + "/manifest."
if not args.autolab: if not args.autolab:
print("> Testing token file integrity...", sep="") print("> Testing token file integrity...", sep="")
...@@ -157,7 +232,7 @@ def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_ ...@@ -157,7 +232,7 @@ def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_
if args.force_kill: if args.force_kill:
print("Running sys.exit...") print("Running sys.exit...")
import threading import threading
import sys # import sys
# import os # import os
print("These are all the threads:") print("These are all the threads:")
for thread in threading.enumerate(): for thread in threading.enumerate():
...@@ -184,9 +259,7 @@ def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_ ...@@ -184,9 +259,7 @@ def gather_upload_to_campusnet(report, output_dir=None, token_include_plaintext_
os.kill(pid, 9) os.kill(pid, 9)
print("Raising exception instead...") print("Raising exception instead...")
# raise Exception("Quitting this shit.") # raise Exception("Quitting this shit.")
os._exit(0) os._exit(0)
sys.exit() sys.exit()
print("Sys.exit ran.") print("Sys.exit ran.")
...@@ -205,7 +278,7 @@ def save_token(dictionary, plain_text, file_out): ...@@ -205,7 +278,7 @@ def save_token(dictionary, plain_text, file_out):
out = [plain_text, token_sep, f"{b_hash} {b_l1}", token_sep, b] out = [plain_text, token_sep, f"{b_hash} {b_l1}", token_sep, b]
with open(file_out, 'w') as f: with open(file_out, 'w') as f:
f.write("\n".join(out)) f.write("\n".join(out))
return b_hash
......
...@@ -481,6 +481,12 @@ def docker_stagewise_evaluation(base_directory, Dockerfile=None, instructor_grad ...@@ -481,6 +481,12 @@ def docker_stagewise_evaluation(base_directory, Dockerfile=None, instructor_grad
for tf in glob.glob(fid +"/**/*.token", recursive=True): for tf in glob.glob(fid +"/**/*.token", recursive=True):
rs[id]['token_downloaded'] = tf rs[id]['token_downloaded'] = tf
tdata, _ = load_token(tf)
blake_hash = tdata['metadata']['file_reported_hash']
rs[id]['token_downloaded_hash'] = blake_hash
for cid in glob.glob(f"{stage4_dir}/{id}-*"): for cid in glob.glob(f"{stage4_dir}/{id}-*"):
type = os.path.basename(cid).split("-")[1] type = os.path.basename(cid).split("-")[1]
tokens = glob.glob(f"{cid}/*.token") tokens = glob.glob(f"{cid}/*.token")
......
...@@ -16,6 +16,8 @@ def make_dummies(zip_file_path="zip1.zip", n_handins=3, screwups=4, student_base ...@@ -16,6 +16,8 @@ def make_dummies(zip_file_path="zip1.zip", n_handins=3, screwups=4, student_base
# Deploy to this dir and create handins. Turn it all into a .zip file and return it. # Deploy to this dir and create handins. Turn it all into a .zip file and return it.
np.random.seed(42) np.random.seed(42)
manifests = {}
def copy_and_mutate(): def copy_and_mutate():
if os.path.isdir(tmp + "/students"): if os.path.isdir(tmp + "/students"):
shutil.rmtree(tmp + "/students") shutil.rmtree(tmp + "/students")
...@@ -60,42 +62,33 @@ def make_dummies(zip_file_path="zip1.zip", n_handins=3, screwups=4, student_base ...@@ -60,42 +62,33 @@ def make_dummies(zip_file_path="zip1.zip", n_handins=3, screwups=4, student_base
cmd = f"cd {tmp}/students && python -m {module}" cmd = f"cd {tmp}/students && python -m {module}"
print(cmd) print(cmd)
o = subprocess.run(cmd, shell=True, capture_output=True, check=True) o = subprocess.run(cmd, shell=True, capture_output=True, check=True)
print(o) # print(o)
token = glob.glob(os.path.dirname(tmp +"/students/"+os.path.relpath(student_grade_file, student_base_dir)) + "/*.token")[0] token = glob.glob(os.path.dirname(tmp +"/students/"+os.path.relpath(student_grade_file, student_base_dir)) + "/*.token")[0]
print(token)
return token
names = ['Alice', 'Bob', 'Charlie', 'Doris', 'Ebert']
# def zipfolder(foldername, target_dir): if os.path.isfile(f_ := f"""{os.path.dirname(token)}/unitgrade_data/token_{module.split(".")[-1]}.manifest"""):
# zipobj = zipfile.ZipFile(foldername + '.zip', 'w', zipfile.ZIP_DEFLATED) with open(f_) as f:
# rootlen = len(target_dir) + 1 manifest = f.read()
# for base, dirs, files in os.walk(target_dir): else:
# for file in files: manifests = None
# fn = os.path.join(base, file)
# zipobj.write(fn, fn[rootlen:])
print(token)
return token, manifest
names = ['Alice', 'Bob', 'Charlie', 'Doris', 'Ebert']
for k in range(n_handins): for k in range(n_handins):
token = copy_and_mutate() token, manifest = copy_and_mutate()
# Now make directory for handin and create the .zip file. # Now make directory for handin and create the .zip file.
id = 221000 + k id = 221000 + k
handin_folder = f"116607-35260 - s{id} - {names[k % len(names)]} - 1 March, 2022 518 PM" handin_folder = f"116607-35260 - s{id} - {names[k % len(names)]} - 1 March, 2022 518 PM"
os.makedirs(tmp + "/zip/"+handin_folder) os.makedirs(tmp + "/zip/"+handin_folder)
shutil.copy(token, tmp + "/zip/"+handin_folder +"/"+os.path.basename(token)) shutil.copy(token, tmp + "/zip/"+handin_folder +"/"+os.path.basename(token))
manifests[id] = manifest
shutil.make_archive(zip_file_path[:-4], shutil.make_archive(zip_file_path[:-4], 'zip', tmp + "/zip", '')
'zip', return zip_file_path, manifests
tmp+ "/zip",
'')
return zip_file_path
# zipfolder('zip1', tmp + "/zip/"+handin_folder) # insert your variables here # zipfolder('zip1', tmp + "/zip/"+handin_folder) # insert your variables here
......
[report]
exclude_also =
if __name__ == .__main__.:
__pycache__
.idea
*.token
cp.egg-info
cache.db
[
{
"key": "shift+alt+e",
"command": "editor.debug.action.selectionToRepl"
}
]
\ No newline at end of file
{
"python.testing.unittestArgs": [
"-v",
"-s",
"./cp",
"-p", "*tests*.py"
],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true,
}
# 001122 Introduction to programming in python
This repository contains code for 001122.
Please see our public homepage for reading material and installation instructions, including how you download and run the code on your own computer:
- https://tuhe.pages.compute.dtu.dk/001122public/installation/installation.html
""" Source code for 02466, Introduction to reinforcement learning and control, offered at DTU """
__version__ = "0.0.1"
# Do not import Matplotlib (or imports which import matplotlib) in case you have to run in headless mode.
import shutil
import inspect
import lzma, pickle
import numpy as np
import os
# Global imports from across the API. Allows imports like
# > from cp import Agent, train
# from cp.utils.irlc_plot import main_plot as main_plot
# from cp.utils.irlc_plot import plot_trajectory as plot_trajectory
# try:
# from cp.ex01.agent import Agent as Agent, train as train
# from cp.ex09.rl_agent import TabularAgent, ValueAgent
# except ImportError:
# pass
# from cp.utils.player_wrapper import interactive as interactive
# from cp.utils.lazylog import LazyLog # This one is unclear. Is it required?
# from cp.utils.timer import Timer
def get_ipp_base():
dir_path = os.path.dirname(os.path.realpath(__file__))
return dir_path
# def get_students_base():
# return os.path.join(get_ipp_base(), "../../../02465students/")
def pd2latex_(pd, index=False, escape=False, column_spec=None, **kwargs): # You can add column specs.
for c in pd.columns:
if pd[c].values.dtype == 'float64' and all(pd[c].values - np.round(pd[c].values)==0):
pd[c] = pd[c].astype(int)
ss = pd.to_latex(index=index, escape=escape, **kwargs)
return fix_bookstabs_latex_(ss,column_spec=column_spec)
def fix_bookstabs_latex_(ss, linewidth=True, first_column_left=True, column_spec=None):
to_tabular_x = linewidth
if to_tabular_x:
ss = ss.replace("tabular", "tabularx")
lines = ss.split("\n")
hd = lines[0].split("{")
if column_spec is None:
adj = (('l' if to_tabular_x else 'l') if first_column_left else 'C') + ("".join(["C"] * (len(hd[-1][:-1]) - 1)))
else:
adj = column_spec
# adj = ( ('l' if to_tabular_x else 'l') if first_column_left else 'C') + ("".join(["C"] * (len(hd[-1][:-1])-1)))
if linewidth:
lines[0] = "\\begin{tabularx}{\\linewidth}{" + adj + "}"
else:
lines[0] = "\\begin{tabular}{" + adj.lower() + "}"
ss = '\n'.join(lines)
return ss
def _savepdf_env(file, env):
from PIL import Image
import matplotlib.pyplot as plt
if hasattr(env, 'render_mode') and not env.render_mode == 'rgb_array':
env.render_mode, rmt = 'rgb_array', env.render_mode
frame = env.render()
if hasattr(env, 'render_mode') and not env.render_mode == 'rgb_array':
env.render_mode = rmt
im = Image.fromarray(frame)
snapshot_base = file
if snapshot_base.endswith(".png"):
sf = snapshot_base[:-4]
fext = 'png'
else:
fext = 'pdf'
if snapshot_base.endswith(".pdf"):
sf = snapshot_base[:-4]
else:
sf = snapshot_base
sf = f"{sf}.{fext}"
dn = os.path.dirname(sf)
if len(dn) > 0 and not os.path.isdir(dn):
os.makedirs(dn)
print("Saving snapshot of environment to", os.path.abspath(sf))
if fext == 'png':
im.save(sf)
from cp import _move_to_output_directory
_move_to_output_directory(sf)
else:
plt.figure(figsize=(16, 16))
plt.imshow(im)
plt.axis('off')
plt.tight_layout()
from cp import savepdf
savepdf(sf, verbose=True)
# plt.show()
def savepdf(pdf, verbose=False, watermark=False, env=None, _png=False):
"""
Convenience function for saving PDFs. Just call it after you have created your plot as ``savepdf('my_file.pdf')``
to save a PDF of the plot.
You can also pass an environment, in which case the environment will be stored to a pdf file.
:param pdf: The file to save to, for instance ``"my_pdf.pdf"``
:param verbose: Print output destination (optional)
:param watermark: Include a watermark (optional)
:return: Full path of the created PDF.
"""
if env is not None:
_savepdf_env(pdf, env)
return
import matplotlib.pyplot as plt
pdf = os.path.normpath(pdf.strip())
pdf = pdf+".pdf" if not pdf.endswith(".pdf") else pdf
if os.sep in pdf:
pdf = os.path.abspath(pdf)
else:
pdf = os.path.join(os.getcwd(), "pdf", pdf)
if not os.path.isdir(os.path.dirname(pdf)):
os.makedirs(os.path.dirname(pdf))
modules = [inspect.getmodule(s[0]) for s in inspect.stack()]
files = [m.__file__ for m in modules if m is not None]
if any( [f.endswith("RUN_OUTPUT_CAPTURE.py") for f in files] ):
return
# for s in stack:
# print(s)
# print(stack)
# for k in range(len(stack)-1, -1, -1):
# frame = stack[k]
# module = inspect.getmodule(frame[0])
# filename = module.__file__
# print(filename)
# if not any([filename.endswith(f) for f in ["pydev_code_executor.py", "pydevd.py", "_pydev_execfile.py", "pydevconsole.py", "pydev_ipython_console.py"] ]):
# # print("breaking c. debugger", filename)
# break
# if any( [filename.endswith(f) for f in ["pydevd.py", "_pydev_execfile.py"]]):
# print("pdf path could not be resolved due to debug mode being active in pycharm", filename)
# return
# print("Selected filename", filename)
# wd = os.path.dirname(filename)
# pdf_dir = wd +"/pdf"
# if filename.endswith("_RUN_OUTPUT_CAPTURE.py"):
# return
# if not os.path.isdir(pdf_dir):
# os.mkdir(pdf_dir)
wd = os.getcwd()
ipp_base = os.path.dirname(__file__)
if False:
pass
else:
plt.savefig(fname=pdf)
outf = os.path.normpath(os.path.abspath(pdf))
print("> [savepdf]", pdf + (f" [full path: {outf}]" if verbose else ""))
return outf
def _move_to_output_directory(file):
"""
Hidden function: Move file given file to static output dir.
"""
if not is_this_my_computer():
return
CDIR = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/')
shared_output_dir = CDIR + "/../../shared/output"
shutil.copy(file, shared_output_dir + "/"+ os.path.basename(file) )
# def bmatrix(a):
# if False:
# return a.__str__()
# else:
# np.set_printoptions(suppress=True)
# """Returns a LaTeX bmatrix
# :a: numpy array
# :returns: LaTeX bmatrix as a string
# """
# if len(a.shape) > 2:
# raise ValueError('bmatrix can at most display two dimensions')
# lines = str(a).replace('[', '').replace(']', '').splitlines()
# rv = [r'\begin{bmatrix}']
# rv += [' ' + ' & '.join(l.split()) + r'\\' for l in lines]
# rv += [r'\end{bmatrix}']
# return '\n'.join(rv)
def is_this_my_computer():
CDIR = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/')
return os.path.exists(CDIR + "/../../Exercises")
# def cache_write(object, file_name, only_on_professors_computer=False, verbose=True, protocol=-1): # -1 is default protocol. Fix crash issue with large files.
# if only_on_professors_computer and not is_this_my_computer():
# """ Probably for your own good :-). """
# return
#
# dn = os.path.dirname(file_name)
# if not os.path.exists(dn):
# os.mkdir(dn)
# if verbose: print("Writing cache...", file_name)
# with lzma.open(file_name, 'wb') as f:
# pickle.dump(object, f)
# # compress_pickle.dump(object, f, compression="lzma", protocol=protocol)
# if verbose:
# print("Done!")
def cache_exists(file_name):
return os.path.exists(file_name)
# def cache_read(file_name):
# if os.path.exists(file_name):
# with lzma.open(file_name, 'rb') as f:
# return pickle.load(f)
# else:
# return None
inputs = []
def minput(ls):
"""
Higher-order function to fix input.
The function is given a list of keyboard input strings it will dutifully enter into input. If one of the inputs in the
list is None, the function will throw an error. This is useful to terminate early and show what the user sees as
part of the interaction.
This function should eventually be absorbed into unitgrade once potential kinks involving stdout has been worked out.
:param ls: Input strings.
:return: An alternative input-function (for use in mocking)
"""
inputs.clear()
for l in ls:
inputs.append(l)
def _input(x):
l = inputs[0]
if l is None:
print(x)
raise GeneratorExit()
# raise Exception()
print(x, l)
del inputs[0]
return l
return _input
"""The exercises in this folder are intended as preparation for the course start."""
"""the fruit homework example problem for project 0. It should probably be among the exercises."""
def add(a,b):
"""Add the two numbers a and b and return their sum.
:param a: First number to add
:param b: Second number to add
:return: their sum, :math:`a + b`
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
"""Problem 0.1. Print out 'Hello' and 'World' on two separate lines."""
print("Hello")
# Put your code here so the program outputs
# > Hello
# > World
# on two lines.
# TODO: 1 lines missing.
"""This package represents exercise 1."""
"""A handful of python programming examples."""
# Example 1
print("Hello world")
# Example 2
print("hello")
print("world")
a = 2
b = 3
c = 1
x = 3
y = a*x**2 + b * x + c
# Example 3
def second_poly(x):
"""Compute a first order polynomial.
:param x: Input value :math:`x`
:return: :math:`y = 2x + 4`
"""
return 2 * x + 4
# example 4
def say_hello(name):
"""Print out "Hello {name}.
:param name: The name to say hello to
"""
print("Hello " + name)
"""This package represents exercise 1."""
"""Exercise 2.3: The Fibonacci sequence and recursion."""
def fibonacci_number(k):
"""Compute the :math:`k`'th Fibonacci number :math:`x_k`.
The function use the recursive relationship :math:`x_{k+1} = x_k + x_{k-1}`, along with the initial conditions
:math:`x_0 =0, x_1 = 1`, to complete the sequence up to :math:`k`.
:param k: An integer
:return: The corresponding term :math:`x_k` of the Fibonacci sequence as an integer.
"""
if k == 0:
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
elif k == 1:
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
else:
# TODO: 1 lines missing.
raise NotImplementedError("Fix this stuff")
if __name__ == "__main__":
print("The term x_0 should be 0, you got:", fibonacci_number(0))
print("The term x_1 should be 1, you got:", fibonacci_number(1))
print("The term x_2 should be 1, you got:", fibonacci_number(1))
print("The term x_6 should be 8, you got:", fibonacci_number(6))
"""Problem 1.1."""
def evaluate_taylor(x: float) -> float:
r"""Compute the third order taylor approximation.
Compute (and return) the Taylor approximation of :math:`\log(x)`. Remember the function must return a ``float``.
:param x: The input to evaluate.
:return: The taylor approximation of :math:`\log(x)`, i.e. :math:`y`
"""
# TODO: 1 lines missing.
raise NotImplementedError("Define y = (x-1) - 1/2 * ... here.")
return y
"""Problem 1.2. Implement a function that computes (and return) the third order Taylor-approximation here."""
# TODO: Code has been removed from here.
raise NotImplementedError("Insert your solution and remove this error.")
"""Problem 1.3. Compute the third order taylor approximation evaluated in x here and store it in a variable y."""
x = 1.5
# Define y = ... here.
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
# print(y) should work.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment