Skip to content
Snippets Groups Projects
Commit 5566611e authored by tuhe's avatar tuhe
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 580 additions and 0 deletions
"""Exercise 3.8: Exponential function."""
def exponential(x : float, n : int) -> float:
"""Compute the exponential :math:`x^n` using recursion.
First focus on the case where :math:`n=0`, then :math:`n > 0` and finally :math:`n < 0`.
:param x: the base number :math:`x`.
:param n: the power :math:`n`.
:return: the computed value.
"""
# TODO: 6 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
"""Exercise 3.7: Heart attack."""
def heart_attack(age:int, weight:int, smoker:bool) -> str:
"""Return a string indicating the risk of a person for having heart attack.
:param age: The age of the person.
:param weight: The weight of the person in kilograms.
:param smoker: Does the person smoke cigarettes?
:return: A string, either "low" or "high", indicating the risk for having heart attack.
"""
# TODO: 12 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return risk
"""This example is used in the lecture notes to illustrate the import statement. Ignore it for the exercises."""
def just_a_function():
"""Print two lines to the terminal."""
print("Hello!")
print("I am justin-a-function :-).")
"""Exercise 3.6: Solar panel."""
def solar_panel(move : bool, swap : bool, hot : bool, empty : bool):
"""Print out whether it is a good idea to install solar panels on an object with the given properties.
:param move: does the object move around?
:param swap: does the object allow swapping or recharging battery?
:param hot: is the object hot to the touch when it is running?
:param empty: are there other empty places near the object?
"""
# TODO: 19 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
"""Exercises for week 4."""
"""Exercise 4.2-4.3: Let the world know you have written your last bug."""
def last_bug():
"""Write a nice message enclosed by lines and pipes that clearly indicate you have written your last bug.
The function should print out the following three lines in the console:
.. code-block:: console
------------------------------
| I have written my last bug |
------------------------------
"""
# TODO: 5 lines missing.
raise NotImplementedError("Use print(...) to print the output here.")
def nice_sign(msg : str):
"""Print the input string as a nice sign by enclosing it with pipes.
Note that the input message can vary in length.
.. code-block:: console
---------------
| {input msg} |
---------------
:param msg: The message to enclose.
"""
# You can use len(msg) to get the number of characters and "-"*10 to repeat a character (try in the console!)
# TODO: 4 lines missing.
raise NotImplementedError("Use print(...) to print the output here.")
if __name__ == "__main__":
last_bug() # Done with the bugs
nice_sign("Hello world")
This diff is collapsed.
"""Exercise 4.12-4.16."""
def is_word_guessed(secret_word : str, letters_guessed : str) -> bool:
"""Determine if the word has been guessed.
:param secret_word: The word to guess
:param letters_guessed: A ``str`` containing the letters that have currently been guessed
:return: True if and only if all letters in ``secret_word`` have been guessed.
"""
# TODO: 4 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return guessed
def get_guessed_word(secret_word : str, letters_guessed : str) -> str:
"""Format the secret word for the user by removing letters that have not been guessed yet.
Given a list of the available letters, the function will replace the letters in the secret word with `'_ '`
(i.e., a lower-case followed by a space). For instance, if the secret word is ``"cat"``, and the
available letters are ``"ct"``, then the function should return ``"c_ t"``.
:param secret_word: A ``str``, the word the user is guessing
:param letters_guessed: A ``str`` containing which letters have been guessed so far
:return: A ``str``, comprised of letters, underscores (_), and spaces that represents which letters in secret_word have been guessed so far.
"""
# TODO: 6 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return word
def get_available_letters(letters_guessed : str) -> str:
"""
Return the letters which are available, i.e. have not been guessed so far.
The input string represents the letters the user have guessed, and the output should then be the lower-case
letters which are not contained in that string. The function is used to show the user which
letters are available in each round.
:param letters_guessed: A `str` representing the letters the user has already guessed
:return: A `str` containing the letters the user has not guessed at yet.
"""
# TODO: 2 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return letters
def hangman(secret_word : str, guesses : str):
"""
Play an interactive game of Hangman.
This function should launch an interactive game of Hangman. The details of the game is defined in the
project description available online, and should be read carefully.
* The game should first display how many letters are in the secret word. You should start by generating this output.
* Before each round, the user should see how many guesses that are left and which letters are not yet used
* In each round, the user is prompted to input a letter. Use the ``input('..')`` function for this.
* The user is given feedback based on whether the letter is in the word or not. The program also performs error handling.
* The game terminates when the user win, has exceeded the number of guesses, or if the user makes an illegal input.
in this case the user is shown a score.
:param secret_word: The secret word to guess, for instance ``"cow"``
:param guesses: The number of available guesses, for instance ``6``
"""
# TODO: Code has been removed from here.
raise NotImplementedError("Insert your solution and remove this error.")
if __name__ == "__main__":
print("This should return True: ", is_word_guessed("dog", "tdohg"))
print("This should return False: ", is_word_guessed("dog", "dthk"))
print("This should be 'c_ w': ", get_guessed_word('cow', 'kcwt'))
print("Available letters when we have tried 'abcdefghijk'; this should be about half the alphabet: ", get_available_letters('abcdefghijk'))
print("Lets launch hangman. Try the inputs in the exercise description and see if you get the same")
hangman("cow", 4)
"""Exercise 4.1 and 4.2."""
import math
def square_root(a : float) -> float:
r"""Compute the square root, see section 7.5 in Think Python.
:param a: A number to compute the square root of.
:return: :math:`\sqrt{a}`.
"""
# TODO: 7 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return sqrt_a
def ramanujan() -> float:
r"""Compute the Ramanujan approximation of :math:`\pi` using a sufficient number of terms.
:return: A high-quality approximation of :math:`\pi` as a ``float``.
"""
# TODO: 9 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return pi
if __name__ == "__main__":
print("approximate pi", ramanujan())
print("square root of 2 is", square_root(2))
"""Exercise 4.1: Checking if a word is a palindrome."""
def is_palindrome(word : str) -> bool:
"""Check if ``word`` is a palindrome.
:param word: The word to check
:return: ``True`` if input is a palindrome and otherwise ``False``
"""
# TODO: 2 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return is_a_palindrome
if __name__ == "__main__":
print("Is Madam a palindrome?", is_palindrome('madam'))
print("Is gentleman a palindrome?", is_palindrome('gentleman'))
"""Exercise 4.x-4.y."""
def matching(expression :str) -> bool:
"""Tell if the parenthesis match in a mathematical expression.
For instance, the parenthesis match in ``"3x(y-1)(3y+(x-1))"`` but not in ``"3x(y-4))"``
:param expression: An expression containing zero or more parenthesis.
:return: ``True`` if the number of open/close parenthesis match, otherwise ``False``
"""
# TODO: 9 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return matching
def find_index_of_equality(expression : str) -> int:
"""Find an index ``i`` which split the expression into two balanced parts.
Given an expression containing opening and closing parenthesis, for instance ``"(()())"``, this function should
return an index ``i``, such that when the string is split at ``i``, the
number of opening parenthesis ``(`` in the left-hand part equal the number of closing parenthesis ``)`` in the
right-hand part. For instance, if ``i=2``, the expression is split into the right, left hand parts:
- ``"(()"``
- ``"())"``
In this case the left-hand part contains ``2`` opening parenthesis and ``2`` closign parenthesis so ``i`` is the right index.
Similarly, for ``"()"``, the answer would be ``1``.
:param expression: An expression only consisting of opening and closing parenthesis.
:return: The index ``i`` as an int.
"""
# TODO: 6 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return i
def print_the_dialogue(s : str):
"""Print all dialogue in a manuscript.
Given a manuscript (as a ``str``), this function will find all lines of dialogue to the console, one line of
dialogue per printed line. Dialogue is enclosed by double ticks, i.e. this ``str`` contains two pieces of dialogue:
``"''My dear Mr. Bennet,'' said his lady to him one day, ''have you heard that Netherfield Park is let at last?''"``
:param s: The manuscript as a ``str``.
"""
# TODO: 4 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
def find_innermost_part(s : str) -> str:
"""Find the innermost part of a mathematical expression.
The innermost part is a substring enclosed in parenthessis but not containing parenthesis.
For instance, given ``"3(x+(4-y^2))"``, then ``"4-y^2"`` is an inner-most part.
The parenthesis can be assumed to match.
:param s: The mathematical expression as a ``str``
:return: The innermost part as a ``str``
"""
# TODO: 3 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return inner_part
if __name__ == "__main__":
print("Does the parenthesis match?", matching("2x(x+2)"))
print("Does the parenthesis match?", matching("2x(x+(2-y)^2)"))
print("Does the parenthesis match?", matching("4x"))
print("Does the parenthesis match?", matching("2x(x+2"))
print("Does the parenthesis match?", matching("2x)(x"))
print("Does the parenthesis match?", matching("4x()(()))"))
s = "(())))("
print("Index of equality for", s, "is", find_index_of_equality(s))
dialogue = "He said: ''How are you old wife''? She answered, perplexed, ''I am not your wife''"
print_the_dialogue(dialogue)
"""Play a game of hangman by loading a random word."""
import random
import os
def load_words() -> list:
"""
Return a list of valid words. Words are strings of lowercase letters.
Depending on the size of the word list, this function may
take a while to finish.
:return: The available words as a list.
"""
from cp.ex08.words import load_words
wordlist = load_words(os.path.join(os.path.dirname(__file__), "files", "5000-words.txt")).split()
return wordlist
def choose_word() -> str:
"""Select a word at random.
:return: A randomly selected word, useful for playing hangman.
"""
wordlist = load_words()
return random.choice(wordlist)
"""Exercise XX."""
def common_prefix(word1 : str, word2 : str) -> str:
"""
Return the longest string so that both ``word1``, and ``word2`` begin with that string.
:param word1: First word
:param word2: Second word
:return: The longest common prefix.
"""
# TODO: 6 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return prefix
def common_prefix3(word1 : str, word2 : str, word3 : str) -> str:
"""
Return the longest string so that both ``word1``, ``word2``, and ``word3`` begin with that string.
:param word1: First word
:param word2: Second word
:param word3: Third word
:return: The longest common prefix.
"""
# TODO: 1 lines missing.
raise NotImplementedError("Insert your solution and remove this error.")
return prefix
# Driver Code
if __name__ == "__main__":
print("The longest Common Prefix is :", common_prefix("egregious", "egg"))
print("The longest Common Prefix is :", common_prefix3("egg", "egregious", "eggplant"))
"""Dummy (test) project to test your installation."""
This diff is collapsed.
from unitgrade import Report, UTestCase
import cp
import io
import unittest
from unittest.mock import patch
class HelloWorld(UTestCase):
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def test_say_hello(self, mock_stdout):
from cp.ex00 import say_hello
# lib = importlib.reload(say_hello)
lines = mock_stdout.getvalue().strip().splitlines()
self.assertEqual(len(lines), 2, msg=f"Wrong number of lines. Your program should print(..) out two lines, you got: {lines}, {say_hello.__file__}")
print("Testing the first line")
self.assertEqual(lines[0], "Hello", msg="You must have somehow changed the first print(...) statement in the program. Did you delete it?") # Rem
print("Testing the second line")
self.assertEqual(lines[1], "World", msg="Your second print statement did not produce the correct output.") # Remember the output must be capitalized.
class Project0(Report):
title = "Project for week 00 (Try to complete this before the course starts)"
remote_url = "https://cp.pages.compute.dtu.dk/02002public/_static/evaluation/"
pack_imports = [cp]
individual_imports = []
questions = [
(HelloWorld, 10),
]
if __name__ == '__main__':
from unitgrade import evaluate_report_student
evaluate_report_student(Project0())
File added
"""Dummy (test) project from 02465."""
This diff is collapsed.
import string
from unitgrade import hide
from cp import minput
from unittest.mock import patch
import io
import unittest
from unitgrade import UTestCase, Report
import math
class TestTheFunctionToBisect(UTestCase):
def test_f(self):
from cp.ex03.bisect import f
self.assertAlmostEqual(f(0), 0.1411200080598672)
self.assertAlmostEqual(f(1), 0.4871688735635369 )
self.assertAlmostEqual(f(2), -0.9484917234010158)
self.assertAlmostEqual(f(math.pi), 0.6145000731172406 )
self.assertAlmostEqual(f(-10), 0.244199939520782)
self.assertAlmostEqual(f(117), -0.9996260520700749)
class TestIsThereARoot(UTestCase):
def test_root_exists(self):
from cp.ex03.bisect import is_there_a_root
self.assertTrue(is_there_a_root(1, 3)) # root exists between 0 and pi
def test_no_root_exists(self):
from cp.ex03.bisect import is_there_a_root
self.assertFalse(is_there_a_root(3.2, 3.8)) # no root exists between 0 and 2pi
def test_root_not_found(self):
from cp.ex03.bisect import is_there_a_root
self.assertFalse(is_there_a_root(1, 3.5))
class TestBisect(UTestCase):
def test_base_case(self):
from cp.ex03.bisect import bisect
self.assertAlmostEqual(bisect(1, 3, 0.1), 1.8125)
self.assertAlmostEqual(bisect(1, 5.5, 0.1), 4.0234375)
def test_tolerances(self):
from cp.ex03.bisect import bisect
self.assertAlmostEqual(bisect(2, 3.5, 10), 2.75)
self.assertAlmostEqual(bisect(2, 3.5, 0.1), 3.03125)
def test_no_solution(self):
from cp.ex03.bisect import bisect
self.assertTrue(math.isnan(bisect(1, 3.5, 1)))
class HangmanIsGuessed(UTestCase):
def test_is_word_guessed(self):
from cp.ex04.hangman import is_word_guessed
self.assertTrue(is_word_guessed("dog", "tdohg"))
self.assertTrue(is_word_guessed("dog", "tdohg"))
self.assertFalse(is_word_guessed("dog", ""))
self.assertFalse(is_word_guessed("species", "sdcbwegk"))
self.assertTrue(is_word_guessed("species", "qseicps"))
class HangmanGuessedWord(UTestCase):
def test_get_guessed_word(self):
from cp.ex04.hangman import get_guessed_word
self.assertEqual(get_guessed_word('cow', 'kcw'), 'c_ w')
self.assertEqual(get_guessed_word('apple', ''), '_ _ _ _ _ ')
self.assertEqual(get_guessed_word('tasks', 'ws'), '_ _ s_ s')
class HangmanAvailableLetters(UTestCase):
def test_get_available_letters(self):
from cp.ex04.hangman import get_available_letters
self.assertEqual(len(get_available_letters('')), 26)
self.assertEqual(set(get_available_letters('bcdew')), set(string.ascii_lowercase).difference('bcdew'))
class Hangman(UTestCase):
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def test_hangman_startup(self, mock_stdout):
from cp.ex04.hangman import hangman
try:
with unittest.mock.patch('builtins.input', minput([None])):
hangman("cow", guesses=4)
except GeneratorExit as e:
pass
out = mock_stdout.getvalue()
lines = out.splitlines()
self.assertEqual(len(lines), 4, msg='You must print 4 lines')
self.assertEqual(lines[0], 'Hangman! To save Bob, you must guess a 3 letter word within 4 attempts.', msg='First printed line is wrong')
self.assertEqual(lines[1], '----', msg='Second printed line is wrong')
self.assertEqual(lines[2], 'You have 4 guesses left.', msg='Third printed line is wrong')
self.assertTrue("." in lines[3] and ":" in lines[3], msg="Your fourth line must have both a colon and a period")
fp = lines[3].split(".")[0].split(":")[1].strip()
self.assertEqual(len(fp), 26, msg="The alphabet has 26 letters.")
self.assertEqual(set(fp), set(string.ascii_lowercase), msg="You failed to print the alphabet")
def chk_alphabet(self, line, missing):
self.assertTrue("." in line and ":" in line, msg="Your alphabet printout must have both a colon and a period")
fp = line.split(".")[0].split(":")[1].strip()
ab = set( [c for c in string.ascii_lowercase if c not in missing])
self.assertEqual(len(fp), len(ab), msg="The alphabet printout has to few characters")
self.assertEqual(set(fp), ab, msg="You failed to print the alphabet")
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def test_hangman_correct(self, mock_stdout):
from cp.ex04.hangman import hangman
try:
with unittest.mock.patch('builtins.input', minput(['w', None])):
hangman("cow", guesses=4)
except GeneratorExit as e:
pass
out = mock_stdout.getvalue()
lines = out.splitlines()
self.assertEqual(len(lines), 8, msg='You must print 8 lines')
self.assertEqual(lines[-4], 'Good guess: _ _ w', msg='Format guessed word correctly')
self.assertEqual(lines[-3], '----')
self.assertEqual(lines[-2], 'You have 3 guesses left.', msg='Third printed line is wrong')
self.chk_alphabet(lines[-1], missing='w')
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def test_hangman_false(self, mock_stdout):
from cp.ex04.hangman import hangman
try:
with unittest.mock.patch('builtins.input', minput(['q', None])):
hangman("doggy", guesses=4)
except GeneratorExit as e:
pass
out = mock_stdout.getvalue()
lines = out.splitlines()
self.assertEqual(len(lines), 8, msg='You must print 8 lines')
self.assertEqual(lines[-4], 'Oh no: _ _ _ _ _ ', msg='Format guessed word correctly')
self.assertEqual(lines[-3], '----')
self.assertEqual(lines[-2], 'You have 3 guesses left.', msg='Third printed line is wrong')
self.chk_alphabet(lines[-1], missing='q')
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def test_hangman_win(self, mock_stdout):
from cp.ex04.hangman import hangman
try:
with unittest.mock.patch('builtins.input', minput(['q', 'd', 'g', 'o', 'y', None])):
hangman("doggy", guesses=8)
except GeneratorExit as e:
pass
out = mock_stdout.getvalue()
lines = out.splitlines()
self.assertEqual(len(lines), 22, msg='You must print 22 lines')
self.assertTrue(lines[-1], 'Your score is 20')
@unittest.mock.patch('sys.stdout', new_callable=io.StringIO)
def test_hangman_loose(self, mock_stdout):
from cp.ex04.hangman import hangman
try:
with unittest.mock.patch('builtins.input', minput(['%'])):
hangman("cat", guesses=5)
except GeneratorExit as e:
pass
out = mock_stdout.getvalue()
lines = out.splitlines()
self.assertEqual(len(lines), 5, msg='You must print 5 lines')
self.assertTrue(lines[-1], 'Game over :-(. Your score is 0 points.')
class Project2(Report):
title = "Project 2"
remote_url = "https://cp.pages.compute.dtu.dk/02002public/_static/evaluation/"
abbreviate_questions = True
questions = [(TestTheFunctionToBisect, 5),
(TestIsThereARoot, 15),
(TestBisect, 15),
(HangmanIsGuessed, 10),
(HangmanGuessedWord, 10),
(HangmanAvailableLetters, 10),
(Hangman, 30),
]
import cp
pack_imports = [cp]
if __name__ == "__main__":
from unitgrade import evaluate_report_student
evaluate_report_student(Project2())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment