From a087eeb71dce2ffbf582769c5592d6985faff5e8 Mon Sep 17 00:00:00 2001 From: NilsForssen Date: Wed, 2 Feb 2022 16:44:15 +0100 Subject: [PATCH] windows --- .../2022-02-02_161144_pyuppgtest2_3.py | 379 ++++++++++++++++++ .../2022-02-02_161249_pyuppgtest2_3.py | 379 ++++++++++++++++++ .../2022-02-02_161421_pyuppgtest2_3.py | 379 ++++++++++++++++++ laboration2/uppgift_1.txt | 48 +-- laboration2/uppgift_2.txt | 62 +-- laboration2/uppgift_3.py | 14 +- laboration2/uppgift_3.txt | 30 ++ 7 files changed, 1230 insertions(+), 61 deletions(-) create mode 100755 laboration2/2022-02-02_161144_pyuppgtest2_3.py create mode 100755 laboration2/2022-02-02_161249_pyuppgtest2_3.py create mode 100755 laboration2/2022-02-02_161421_pyuppgtest2_3.py create mode 100644 laboration2/uppgift_3.txt diff --git a/laboration2/2022-02-02_161144_pyuppgtest2_3.py b/laboration2/2022-02-02_161144_pyuppgtest2_3.py new file mode 100755 index 0000000..6ad6618 --- /dev/null +++ b/laboration2/2022-02-02_161144_pyuppgtest2_3.py @@ -0,0 +1,379 @@ +# Author: Jody Foo (2016) + +""" Kör med python3 -B pyuppgtest2_3.py + +Var noga med att filen ni vill testa och den här testfilen ligger i samma +katalog. +""" + +import unittest +import sys +import importlib +import traceback +import logging +import logging.handlers +import re +import random +import copy +import io + + +def list_contents_is_equal(list1, list2): + if len(list1) != len(list2): + print("not equal lists:", list1, list2) + return False + else: + for value in list1: + if value not in list2: + print("not equal lists:", list1, list2) + return False + return True + + +class PyUppgift(unittest.TestCase): + """Test cases.""" + + # Default-värde. Ändras via argument till skriptet. + pass_points = 85 + + @classmethod + def setUpClass(cls): + cls.missing = [] + cls.errors = [] + cls.no_errors = [] + cls.points = [] + + @classmethod + def tearDownClass(cls): + """Skriv ut resultat när vi testat klart.""" + global log + if len(cls.no_errors) > 0: + log.info("\n#### KORREKT LÖSTA UPPGIFTER ####\n") + for message in cls.no_errors: + log.info(message.rstrip()) + + if len(cls.errors) > 0: + log.info("\n\n#### UPPGIFTER MED FEL ####\n") + log.info("Felsök genom att ha testanrop längst ner i din kodfil och") + log.info("skriv ut resultaten. Kontrollera också så att du har mellanrum") + log.info("på rätt ställe och att stora/små bokstäver stämmer överrens.\n") + for message in cls.errors: + log.info(message) + + if len(cls.missing) > 0: + log.info("\n\n#### SVAR SAKNAS FÖR NEDANSTÅENDE ####\n") + for message in cls.missing: + log.info(message) + log.info("\nKontrollera stavningen av dina funktioner. Användning av versaler/gemener") + log.info("har betydelse. \n") + + points = sum(cls.points) + log.info("\n#### SUMMA POÄNG: {}. ({} behövs)".format(points, cls.pass_points)) + # log.info(points) + if points >= cls.pass_points: + log.info("#### Du är preliminärt GODKÄND på Pythonuppgift 2.3!") + log.info(" ") + else: + # log.info("#### Du är INTE godkänd på Pythonuppgift 2.3") + log.info("#### " + str(cls.pass_points - points) + " poäng saknas för att få godkänt.") + log.info(" ") + + def save_error(self, uppg, exception, tb_stack): + global log + + # stringio = io.StringIO() + + # self.errors.append("UPPG " + uppg + ": Fel påträffades.") + exception_string_tokens = str(exception).split(":") + message = "UPPG " + uppg + ". Fel påträffades: " + # message += str(exception.__class__.__name__) + message += exception_string_tokens[-1].strip() + self.errors.append(message) + # self.errors.append("UPPG " + uppg + " " + + # str(exception.__class__.__name__) + ": " + + # repr(exception) + + # "") + # self.errors.append("UPPG " + uppg) + # tb_list = traceback.format_list(traceback.extract_stack(limit=3)) + # tb_list = traceback.format_list(traceback.extract_stack(limit=3)) + # tb_list = None + # if sys_traceback != None: + # tb_list = traceback.format_list(traceback.extract_tb(sys_traceback, limit=3)) + # else: + # tb_list = traceback.format_list(tb_stack) + # for line in tb_list: + # self.errors.append(line) + # traceback.print_exc(file=stringio, limit=1) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # traceback.print_last(file=stringio) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # traceback.print_stack(file=stringio) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # error_text = "ERROR TEXT: " + stringio.getvalue() + # stringio.close() + # print("ERROR STUFF" + error_text) + # self.errors.append(error_text) + + def save_missing(self, uppg, exception): + global log + ex_str = str(exception) + ex_str = re.sub(r".*('.*'$)", r"\1", ex_str) + self.missing.append("UPPG " + uppg + " Funktion saknas: " + ex_str) + + def save_no_errors(self, uppg, points): + global log + self.no_errors.append("UPPG " + uppg + ": " + str(points) + " poäng. \n") + self.points.append(points) + + + ## List- och stränghantering + def test_uppg_2_3_1(self): + points = 5 + uppg = "2.3.1" + try: + self.assertEqual(mod.replace_periods_with_newlines("hej.jag.heter"), + "hej\njag\nheter", "Punkter ej rätt utbytta i 'hej.jag.heter'") + self.assertEqual(mod.replace_periods_with_newlines("..."), "\n\n\n", + "Punkter ej rätt utbytta i '...'") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_2(self): + points = 10 + uppg = "2.3.2" + try: + self.assertEqual(mod.replace_char_in_string("hej.jag.heter", ".", "\n"), "hej\njag\nheter", + "Tecknet '.' är ej rätt utbytt till newline i 'hej.jag.heter'") + self.assertEqual(mod.replace_char_in_string("...", ".", "\n"), "\n\n\n", + "Tecknet '.' är ej rätt utbytt till newline i '...'") + self.assertEqual(mod.replace_char_in_string("hej5jag5heter", "5", "9"), "hej9jag9heter", + "Tecknet '5' är ej rätt utbytt till '9' i 'hej5jag5heter'") + self.assertEqual(mod.replace_char_in_string("...", " ", "A"), "...", + "Tecknet ' ' är ej rätt utbytt till 'A' i '...'") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_3_a(self): + points = 10 + uppg = "2.3.3.a" + try: + self.assertEqual(mod.reverse_string_while("hej"), "jeh", + "Strängen 'hej' returneras ej omvänt") + self.assertEqual(mod.reverse_string_while(""), "", + "Den tomma strängen returneras ej som sig själv") + self.assertEqual(mod.reverse_string_while("banankontakt"), "tkatnoknanab", + "Strängen 'banankontakt' returneras ej omvänt") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_3_b(self): + points = 10 + uppg = "2.3.3.b" + try: + self.assertEqual(mod.reverse_string_for("hej"), "jeh", + "Strängen 'hej' returneras ej omvänt") + self.assertEqual(mod.reverse_string_for(""), "", + "Den tomma strängen returneras ej som sig själv") + self.assertEqual(mod.reverse_string_for("banankontakt"), "tkatnoknanab", + "Strängen 'banankontakt' returneras ej omvänt") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_4(self): + points = 5 + uppg = "2.3.4" + try: + self.assertEqual(mod.get_five_first([1,2,3,4,5,6,7,8,9]), [1,2,3,4,5], + "Du returnerar ej de fem första från [1,2,3,4,5,6,7,8,9]") + self.assertEqual(mod.get_five_first(["hej","vad","heter","du","?","jag","heter","python"]), + ["hej","vad","heter","du","?"], + "Du returnerar ej de fem första från ['hej','vad','heter','du','?','jag','heter','python']") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_5(self): + points = 10 + uppg = "2.3.5" + try: + self.assertEqual(mod.get_nfirst([1,2,3,4,5,6,7,8,9], 3), [1,2,3], + "Du returnerar ej de 3 första ur [1,2,3,4,5,6,7,8,9]") + self.assertEqual(mod.get_nfirst(["hej","vad","heter","du","?","jag","heter","python"], + 7), + ["hej","vad","heter","du","?","jag","heter"], + "Du returnerar ej de 7 första ur ['hej','vad','heter','du','?','jag','heter','python']") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_6(self): + points = 10 + uppg = "2.3.6" + try: + self.assertListEqual(mod.get_all_less_than([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05], 3.3), + [1.0, 2.0, 3.0, 0.05], + "Du kan ej returnera de värden mindre än 3.3 i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05]") + self.assertListEqual(mod.get_all_less_than([0.05, 500.3, 0.1, 30.3], 4.5), [0.05, 0.1], + "Du kan ej returnera de värden mindre än 4.5 i [0.05, 500.3, 0.1, 30.3]") + self.assertListEqual(mod.get_all_less_than([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05], 0.05), [], + "Du kan ej returnera de värden mindre än 0.05 i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05]") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_7(self): + points = 5 + uppg = "2.3.7" + try: + self.assertListEqual(mod.get_all_even([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]), [2.0, 4.0, 6.0, 8.0], + "Du returnerar ej de jämna värdena i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]") + self.assertListEqual(mod.get_all_even([0, 2, 3, 4, 5, 6, 7, 8, 9]), [0,2, 4, 6, 8], + "Du returnerar ej de jämna värdena i [0, 2, 3, 4, 5, 6, 7, 8, 9]") + self.assertListEqual(mod.get_all_even([1, 3]), [], + "Du returnerar ej de jämna värdena i [1, 3]") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_8(self): + points = 5 + uppg = "2.3.8" + try: + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 3), [3, 6, 9], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 3") + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 2), [2, 4, 6, 8], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 2") + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 5), [5], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 5") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_9(self): + points = 5 + uppg = "2.3.9" + try: + values = [1, 2, 3, 4] + self.assertListEqual(mod.multiply_for_each(values, 3), [3, 6, 9, 12], + "Du returnerar ej listan med [1, 2, 3, 4] multiplicerat med 3.") + self.assertListEqual(values, [3, 6, 9, 12], "Du har ej ändrat den givna listan.") + values = [0, 2, 4] + self.assertListEqual(mod.multiply_for_each(values, 2), [0, 4, 8], + "Du returnerar ej listan med [0, 2, 4] multiplicerat med 2.") + self.assertListEqual(values, [0, 4, 8], "Du har ej ändrat den givna listan.") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_10(self): + points = 15 + uppg = "2.3.10" + try: + self.assertListEqual(mod.insert_at_asc_place([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 3.3), + [1.0, 2.0, 3.0, 3.3, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], + "Du har satt in 3.3 fel i [1.0, 2.0, 3.0, 3.3, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]") + self.assertListEqual(mod.insert_at_asc_place([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 10.0), + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], + "Du har satt in 10.0 fel i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]") + self.assertListEqual(mod.insert_at_asc_place([1, 3], 4), [1, 3, 4], "Du har satt in 4 fel i [1, 3]") + self.assertListEqual(mod.insert_at_asc_place([1, 3], 3), [1, 3, 3], "Du har satt in 3 fel i [1, 3]") + self.assertListEqual(mod.insert_at_asc_place([], 2), [2], "Du har inte satt in 2 i []") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_11(self): + points = 10 + uppg = "2.3.11" + try: + self.assertListEqual(mod.sort_asc([1, 3, 2, 0, -5, 12, 7]), [-5, 0, 1, 2, 3, 7, 12], + "Du har sorterat [1, 3, 2, 0, -5, 12, 7] fel") + self.assertListEqual(mod.sort_asc([1, 3]), [1, 3], + "Du har sorterat [1, 3] fel") + self.assertListEqual(mod.sort_asc([73, 2, 9, 0]), [0, 2, 9, 73], + "Du har sorterat [73, 2, 9, 0] fel") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + +if __name__ == '__main__': + + if len(sys.argv) > 1: + module_name = sys.argv[1].replace("/", ".") + + if len(sys.argv) > 2 and sys.argv[2].isdigit(): + PyUppgift.pass_points = int(sys.argv[2]) + + # remove any trailing .py + if module_name[-3:] == ".py": + module_name = module_name[:-3] + + # load module into mod + mod = importlib.import_module(module_name) + + # filename to minify later + filename = module_name + ".py" + + # set up loggger + # logging.basicConfig(filename='pyuppg1test.log', format="", filemode='w', level=logging.INFO) + logfilename = "pyuppgtest2_3.log" + log = logging.getLogger(__name__) + log.setLevel(logging.INFO) + handler = logging.FileHandler(logfilename, mode="w") + handler.setLevel(logging.INFO) + handler.setFormatter(logging.Formatter()) + log.addHandler(handler) + + # remove elements in sys.argv so that unittest.main does not get + # confused + del sys.argv[1:] + # unittest.main(verbosity=2) + # unittest.main(verbosity=1) + unittest.main() + + else: + sys.exit("Ingen mod att testa.") diff --git a/laboration2/2022-02-02_161249_pyuppgtest2_3.py b/laboration2/2022-02-02_161249_pyuppgtest2_3.py new file mode 100755 index 0000000..6ad6618 --- /dev/null +++ b/laboration2/2022-02-02_161249_pyuppgtest2_3.py @@ -0,0 +1,379 @@ +# Author: Jody Foo (2016) + +""" Kör med python3 -B pyuppgtest2_3.py + +Var noga med att filen ni vill testa och den här testfilen ligger i samma +katalog. +""" + +import unittest +import sys +import importlib +import traceback +import logging +import logging.handlers +import re +import random +import copy +import io + + +def list_contents_is_equal(list1, list2): + if len(list1) != len(list2): + print("not equal lists:", list1, list2) + return False + else: + for value in list1: + if value not in list2: + print("not equal lists:", list1, list2) + return False + return True + + +class PyUppgift(unittest.TestCase): + """Test cases.""" + + # Default-värde. Ändras via argument till skriptet. + pass_points = 85 + + @classmethod + def setUpClass(cls): + cls.missing = [] + cls.errors = [] + cls.no_errors = [] + cls.points = [] + + @classmethod + def tearDownClass(cls): + """Skriv ut resultat när vi testat klart.""" + global log + if len(cls.no_errors) > 0: + log.info("\n#### KORREKT LÖSTA UPPGIFTER ####\n") + for message in cls.no_errors: + log.info(message.rstrip()) + + if len(cls.errors) > 0: + log.info("\n\n#### UPPGIFTER MED FEL ####\n") + log.info("Felsök genom att ha testanrop längst ner i din kodfil och") + log.info("skriv ut resultaten. Kontrollera också så att du har mellanrum") + log.info("på rätt ställe och att stora/små bokstäver stämmer överrens.\n") + for message in cls.errors: + log.info(message) + + if len(cls.missing) > 0: + log.info("\n\n#### SVAR SAKNAS FÖR NEDANSTÅENDE ####\n") + for message in cls.missing: + log.info(message) + log.info("\nKontrollera stavningen av dina funktioner. Användning av versaler/gemener") + log.info("har betydelse. \n") + + points = sum(cls.points) + log.info("\n#### SUMMA POÄNG: {}. ({} behövs)".format(points, cls.pass_points)) + # log.info(points) + if points >= cls.pass_points: + log.info("#### Du är preliminärt GODKÄND på Pythonuppgift 2.3!") + log.info(" ") + else: + # log.info("#### Du är INTE godkänd på Pythonuppgift 2.3") + log.info("#### " + str(cls.pass_points - points) + " poäng saknas för att få godkänt.") + log.info(" ") + + def save_error(self, uppg, exception, tb_stack): + global log + + # stringio = io.StringIO() + + # self.errors.append("UPPG " + uppg + ": Fel påträffades.") + exception_string_tokens = str(exception).split(":") + message = "UPPG " + uppg + ". Fel påträffades: " + # message += str(exception.__class__.__name__) + message += exception_string_tokens[-1].strip() + self.errors.append(message) + # self.errors.append("UPPG " + uppg + " " + + # str(exception.__class__.__name__) + ": " + + # repr(exception) + + # "") + # self.errors.append("UPPG " + uppg) + # tb_list = traceback.format_list(traceback.extract_stack(limit=3)) + # tb_list = traceback.format_list(traceback.extract_stack(limit=3)) + # tb_list = None + # if sys_traceback != None: + # tb_list = traceback.format_list(traceback.extract_tb(sys_traceback, limit=3)) + # else: + # tb_list = traceback.format_list(tb_stack) + # for line in tb_list: + # self.errors.append(line) + # traceback.print_exc(file=stringio, limit=1) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # traceback.print_last(file=stringio) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # traceback.print_stack(file=stringio) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # error_text = "ERROR TEXT: " + stringio.getvalue() + # stringio.close() + # print("ERROR STUFF" + error_text) + # self.errors.append(error_text) + + def save_missing(self, uppg, exception): + global log + ex_str = str(exception) + ex_str = re.sub(r".*('.*'$)", r"\1", ex_str) + self.missing.append("UPPG " + uppg + " Funktion saknas: " + ex_str) + + def save_no_errors(self, uppg, points): + global log + self.no_errors.append("UPPG " + uppg + ": " + str(points) + " poäng. \n") + self.points.append(points) + + + ## List- och stränghantering + def test_uppg_2_3_1(self): + points = 5 + uppg = "2.3.1" + try: + self.assertEqual(mod.replace_periods_with_newlines("hej.jag.heter"), + "hej\njag\nheter", "Punkter ej rätt utbytta i 'hej.jag.heter'") + self.assertEqual(mod.replace_periods_with_newlines("..."), "\n\n\n", + "Punkter ej rätt utbytta i '...'") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_2(self): + points = 10 + uppg = "2.3.2" + try: + self.assertEqual(mod.replace_char_in_string("hej.jag.heter", ".", "\n"), "hej\njag\nheter", + "Tecknet '.' är ej rätt utbytt till newline i 'hej.jag.heter'") + self.assertEqual(mod.replace_char_in_string("...", ".", "\n"), "\n\n\n", + "Tecknet '.' är ej rätt utbytt till newline i '...'") + self.assertEqual(mod.replace_char_in_string("hej5jag5heter", "5", "9"), "hej9jag9heter", + "Tecknet '5' är ej rätt utbytt till '9' i 'hej5jag5heter'") + self.assertEqual(mod.replace_char_in_string("...", " ", "A"), "...", + "Tecknet ' ' är ej rätt utbytt till 'A' i '...'") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_3_a(self): + points = 10 + uppg = "2.3.3.a" + try: + self.assertEqual(mod.reverse_string_while("hej"), "jeh", + "Strängen 'hej' returneras ej omvänt") + self.assertEqual(mod.reverse_string_while(""), "", + "Den tomma strängen returneras ej som sig själv") + self.assertEqual(mod.reverse_string_while("banankontakt"), "tkatnoknanab", + "Strängen 'banankontakt' returneras ej omvänt") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_3_b(self): + points = 10 + uppg = "2.3.3.b" + try: + self.assertEqual(mod.reverse_string_for("hej"), "jeh", + "Strängen 'hej' returneras ej omvänt") + self.assertEqual(mod.reverse_string_for(""), "", + "Den tomma strängen returneras ej som sig själv") + self.assertEqual(mod.reverse_string_for("banankontakt"), "tkatnoknanab", + "Strängen 'banankontakt' returneras ej omvänt") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_4(self): + points = 5 + uppg = "2.3.4" + try: + self.assertEqual(mod.get_five_first([1,2,3,4,5,6,7,8,9]), [1,2,3,4,5], + "Du returnerar ej de fem första från [1,2,3,4,5,6,7,8,9]") + self.assertEqual(mod.get_five_first(["hej","vad","heter","du","?","jag","heter","python"]), + ["hej","vad","heter","du","?"], + "Du returnerar ej de fem första från ['hej','vad','heter','du','?','jag','heter','python']") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_5(self): + points = 10 + uppg = "2.3.5" + try: + self.assertEqual(mod.get_nfirst([1,2,3,4,5,6,7,8,9], 3), [1,2,3], + "Du returnerar ej de 3 första ur [1,2,3,4,5,6,7,8,9]") + self.assertEqual(mod.get_nfirst(["hej","vad","heter","du","?","jag","heter","python"], + 7), + ["hej","vad","heter","du","?","jag","heter"], + "Du returnerar ej de 7 första ur ['hej','vad','heter','du','?','jag','heter','python']") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_6(self): + points = 10 + uppg = "2.3.6" + try: + self.assertListEqual(mod.get_all_less_than([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05], 3.3), + [1.0, 2.0, 3.0, 0.05], + "Du kan ej returnera de värden mindre än 3.3 i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05]") + self.assertListEqual(mod.get_all_less_than([0.05, 500.3, 0.1, 30.3], 4.5), [0.05, 0.1], + "Du kan ej returnera de värden mindre än 4.5 i [0.05, 500.3, 0.1, 30.3]") + self.assertListEqual(mod.get_all_less_than([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05], 0.05), [], + "Du kan ej returnera de värden mindre än 0.05 i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05]") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_7(self): + points = 5 + uppg = "2.3.7" + try: + self.assertListEqual(mod.get_all_even([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]), [2.0, 4.0, 6.0, 8.0], + "Du returnerar ej de jämna värdena i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]") + self.assertListEqual(mod.get_all_even([0, 2, 3, 4, 5, 6, 7, 8, 9]), [0,2, 4, 6, 8], + "Du returnerar ej de jämna värdena i [0, 2, 3, 4, 5, 6, 7, 8, 9]") + self.assertListEqual(mod.get_all_even([1, 3]), [], + "Du returnerar ej de jämna värdena i [1, 3]") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_8(self): + points = 5 + uppg = "2.3.8" + try: + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 3), [3, 6, 9], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 3") + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 2), [2, 4, 6, 8], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 2") + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 5), [5], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 5") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_9(self): + points = 5 + uppg = "2.3.9" + try: + values = [1, 2, 3, 4] + self.assertListEqual(mod.multiply_for_each(values, 3), [3, 6, 9, 12], + "Du returnerar ej listan med [1, 2, 3, 4] multiplicerat med 3.") + self.assertListEqual(values, [3, 6, 9, 12], "Du har ej ändrat den givna listan.") + values = [0, 2, 4] + self.assertListEqual(mod.multiply_for_each(values, 2), [0, 4, 8], + "Du returnerar ej listan med [0, 2, 4] multiplicerat med 2.") + self.assertListEqual(values, [0, 4, 8], "Du har ej ändrat den givna listan.") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_10(self): + points = 15 + uppg = "2.3.10" + try: + self.assertListEqual(mod.insert_at_asc_place([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 3.3), + [1.0, 2.0, 3.0, 3.3, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], + "Du har satt in 3.3 fel i [1.0, 2.0, 3.0, 3.3, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]") + self.assertListEqual(mod.insert_at_asc_place([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 10.0), + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], + "Du har satt in 10.0 fel i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]") + self.assertListEqual(mod.insert_at_asc_place([1, 3], 4), [1, 3, 4], "Du har satt in 4 fel i [1, 3]") + self.assertListEqual(mod.insert_at_asc_place([1, 3], 3), [1, 3, 3], "Du har satt in 3 fel i [1, 3]") + self.assertListEqual(mod.insert_at_asc_place([], 2), [2], "Du har inte satt in 2 i []") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_11(self): + points = 10 + uppg = "2.3.11" + try: + self.assertListEqual(mod.sort_asc([1, 3, 2, 0, -5, 12, 7]), [-5, 0, 1, 2, 3, 7, 12], + "Du har sorterat [1, 3, 2, 0, -5, 12, 7] fel") + self.assertListEqual(mod.sort_asc([1, 3]), [1, 3], + "Du har sorterat [1, 3] fel") + self.assertListEqual(mod.sort_asc([73, 2, 9, 0]), [0, 2, 9, 73], + "Du har sorterat [73, 2, 9, 0] fel") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + +if __name__ == '__main__': + + if len(sys.argv) > 1: + module_name = sys.argv[1].replace("/", ".") + + if len(sys.argv) > 2 and sys.argv[2].isdigit(): + PyUppgift.pass_points = int(sys.argv[2]) + + # remove any trailing .py + if module_name[-3:] == ".py": + module_name = module_name[:-3] + + # load module into mod + mod = importlib.import_module(module_name) + + # filename to minify later + filename = module_name + ".py" + + # set up loggger + # logging.basicConfig(filename='pyuppg1test.log', format="", filemode='w', level=logging.INFO) + logfilename = "pyuppgtest2_3.log" + log = logging.getLogger(__name__) + log.setLevel(logging.INFO) + handler = logging.FileHandler(logfilename, mode="w") + handler.setLevel(logging.INFO) + handler.setFormatter(logging.Formatter()) + log.addHandler(handler) + + # remove elements in sys.argv so that unittest.main does not get + # confused + del sys.argv[1:] + # unittest.main(verbosity=2) + # unittest.main(verbosity=1) + unittest.main() + + else: + sys.exit("Ingen mod att testa.") diff --git a/laboration2/2022-02-02_161421_pyuppgtest2_3.py b/laboration2/2022-02-02_161421_pyuppgtest2_3.py new file mode 100755 index 0000000..6ad6618 --- /dev/null +++ b/laboration2/2022-02-02_161421_pyuppgtest2_3.py @@ -0,0 +1,379 @@ +# Author: Jody Foo (2016) + +""" Kör med python3 -B pyuppgtest2_3.py + +Var noga med att filen ni vill testa och den här testfilen ligger i samma +katalog. +""" + +import unittest +import sys +import importlib +import traceback +import logging +import logging.handlers +import re +import random +import copy +import io + + +def list_contents_is_equal(list1, list2): + if len(list1) != len(list2): + print("not equal lists:", list1, list2) + return False + else: + for value in list1: + if value not in list2: + print("not equal lists:", list1, list2) + return False + return True + + +class PyUppgift(unittest.TestCase): + """Test cases.""" + + # Default-värde. Ändras via argument till skriptet. + pass_points = 85 + + @classmethod + def setUpClass(cls): + cls.missing = [] + cls.errors = [] + cls.no_errors = [] + cls.points = [] + + @classmethod + def tearDownClass(cls): + """Skriv ut resultat när vi testat klart.""" + global log + if len(cls.no_errors) > 0: + log.info("\n#### KORREKT LÖSTA UPPGIFTER ####\n") + for message in cls.no_errors: + log.info(message.rstrip()) + + if len(cls.errors) > 0: + log.info("\n\n#### UPPGIFTER MED FEL ####\n") + log.info("Felsök genom att ha testanrop längst ner i din kodfil och") + log.info("skriv ut resultaten. Kontrollera också så att du har mellanrum") + log.info("på rätt ställe och att stora/små bokstäver stämmer överrens.\n") + for message in cls.errors: + log.info(message) + + if len(cls.missing) > 0: + log.info("\n\n#### SVAR SAKNAS FÖR NEDANSTÅENDE ####\n") + for message in cls.missing: + log.info(message) + log.info("\nKontrollera stavningen av dina funktioner. Användning av versaler/gemener") + log.info("har betydelse. \n") + + points = sum(cls.points) + log.info("\n#### SUMMA POÄNG: {}. ({} behövs)".format(points, cls.pass_points)) + # log.info(points) + if points >= cls.pass_points: + log.info("#### Du är preliminärt GODKÄND på Pythonuppgift 2.3!") + log.info(" ") + else: + # log.info("#### Du är INTE godkänd på Pythonuppgift 2.3") + log.info("#### " + str(cls.pass_points - points) + " poäng saknas för att få godkänt.") + log.info(" ") + + def save_error(self, uppg, exception, tb_stack): + global log + + # stringio = io.StringIO() + + # self.errors.append("UPPG " + uppg + ": Fel påträffades.") + exception_string_tokens = str(exception).split(":") + message = "UPPG " + uppg + ". Fel påträffades: " + # message += str(exception.__class__.__name__) + message += exception_string_tokens[-1].strip() + self.errors.append(message) + # self.errors.append("UPPG " + uppg + " " + + # str(exception.__class__.__name__) + ": " + + # repr(exception) + + # "") + # self.errors.append("UPPG " + uppg) + # tb_list = traceback.format_list(traceback.extract_stack(limit=3)) + # tb_list = traceback.format_list(traceback.extract_stack(limit=3)) + # tb_list = None + # if sys_traceback != None: + # tb_list = traceback.format_list(traceback.extract_tb(sys_traceback, limit=3)) + # else: + # tb_list = traceback.format_list(tb_stack) + # for line in tb_list: + # self.errors.append(line) + # traceback.print_exc(file=stringio, limit=1) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # traceback.print_last(file=stringio) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # traceback.print_stack(file=stringio) + # print("-"*60) + # stringio.write("-"*60 + "\n") + # error_text = "ERROR TEXT: " + stringio.getvalue() + # stringio.close() + # print("ERROR STUFF" + error_text) + # self.errors.append(error_text) + + def save_missing(self, uppg, exception): + global log + ex_str = str(exception) + ex_str = re.sub(r".*('.*'$)", r"\1", ex_str) + self.missing.append("UPPG " + uppg + " Funktion saknas: " + ex_str) + + def save_no_errors(self, uppg, points): + global log + self.no_errors.append("UPPG " + uppg + ": " + str(points) + " poäng. \n") + self.points.append(points) + + + ## List- och stränghantering + def test_uppg_2_3_1(self): + points = 5 + uppg = "2.3.1" + try: + self.assertEqual(mod.replace_periods_with_newlines("hej.jag.heter"), + "hej\njag\nheter", "Punkter ej rätt utbytta i 'hej.jag.heter'") + self.assertEqual(mod.replace_periods_with_newlines("..."), "\n\n\n", + "Punkter ej rätt utbytta i '...'") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_2(self): + points = 10 + uppg = "2.3.2" + try: + self.assertEqual(mod.replace_char_in_string("hej.jag.heter", ".", "\n"), "hej\njag\nheter", + "Tecknet '.' är ej rätt utbytt till newline i 'hej.jag.heter'") + self.assertEqual(mod.replace_char_in_string("...", ".", "\n"), "\n\n\n", + "Tecknet '.' är ej rätt utbytt till newline i '...'") + self.assertEqual(mod.replace_char_in_string("hej5jag5heter", "5", "9"), "hej9jag9heter", + "Tecknet '5' är ej rätt utbytt till '9' i 'hej5jag5heter'") + self.assertEqual(mod.replace_char_in_string("...", " ", "A"), "...", + "Tecknet ' ' är ej rätt utbytt till 'A' i '...'") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_3_a(self): + points = 10 + uppg = "2.3.3.a" + try: + self.assertEqual(mod.reverse_string_while("hej"), "jeh", + "Strängen 'hej' returneras ej omvänt") + self.assertEqual(mod.reverse_string_while(""), "", + "Den tomma strängen returneras ej som sig själv") + self.assertEqual(mod.reverse_string_while("banankontakt"), "tkatnoknanab", + "Strängen 'banankontakt' returneras ej omvänt") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_3_b(self): + points = 10 + uppg = "2.3.3.b" + try: + self.assertEqual(mod.reverse_string_for("hej"), "jeh", + "Strängen 'hej' returneras ej omvänt") + self.assertEqual(mod.reverse_string_for(""), "", + "Den tomma strängen returneras ej som sig själv") + self.assertEqual(mod.reverse_string_for("banankontakt"), "tkatnoknanab", + "Strängen 'banankontakt' returneras ej omvänt") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_4(self): + points = 5 + uppg = "2.3.4" + try: + self.assertEqual(mod.get_five_first([1,2,3,4,5,6,7,8,9]), [1,2,3,4,5], + "Du returnerar ej de fem första från [1,2,3,4,5,6,7,8,9]") + self.assertEqual(mod.get_five_first(["hej","vad","heter","du","?","jag","heter","python"]), + ["hej","vad","heter","du","?"], + "Du returnerar ej de fem första från ['hej','vad','heter','du','?','jag','heter','python']") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_5(self): + points = 10 + uppg = "2.3.5" + try: + self.assertEqual(mod.get_nfirst([1,2,3,4,5,6,7,8,9], 3), [1,2,3], + "Du returnerar ej de 3 första ur [1,2,3,4,5,6,7,8,9]") + self.assertEqual(mod.get_nfirst(["hej","vad","heter","du","?","jag","heter","python"], + 7), + ["hej","vad","heter","du","?","jag","heter"], + "Du returnerar ej de 7 första ur ['hej','vad','heter','du','?','jag','heter','python']") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_6(self): + points = 10 + uppg = "2.3.6" + try: + self.assertListEqual(mod.get_all_less_than([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05], 3.3), + [1.0, 2.0, 3.0, 0.05], + "Du kan ej returnera de värden mindre än 3.3 i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05]") + self.assertListEqual(mod.get_all_less_than([0.05, 500.3, 0.1, 30.3], 4.5), [0.05, 0.1], + "Du kan ej returnera de värden mindre än 4.5 i [0.05, 500.3, 0.1, 30.3]") + self.assertListEqual(mod.get_all_less_than([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05], 0.05), [], + "Du kan ej returnera de värden mindre än 0.05 i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.05]") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_7(self): + points = 5 + uppg = "2.3.7" + try: + self.assertListEqual(mod.get_all_even([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]), [2.0, 4.0, 6.0, 8.0], + "Du returnerar ej de jämna värdena i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]") + self.assertListEqual(mod.get_all_even([0, 2, 3, 4, 5, 6, 7, 8, 9]), [0,2, 4, 6, 8], + "Du returnerar ej de jämna värdena i [0, 2, 3, 4, 5, 6, 7, 8, 9]") + self.assertListEqual(mod.get_all_even([1, 3]), [], + "Du returnerar ej de jämna värdena i [1, 3]") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_8(self): + points = 5 + uppg = "2.3.8" + try: + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 3), [3, 6, 9], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 3") + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 2), [2, 4, 6, 8], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 2") + self.assertListEqual(mod.get_all_divisible([2, 3, 4, 5, 6, 7, 8, 9], 5), [5], + "Du kan ej returnera de värden i [2, 3, 4, 5, 6, 7, 8, 9] som är delbara med 5") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_9(self): + points = 5 + uppg = "2.3.9" + try: + values = [1, 2, 3, 4] + self.assertListEqual(mod.multiply_for_each(values, 3), [3, 6, 9, 12], + "Du returnerar ej listan med [1, 2, 3, 4] multiplicerat med 3.") + self.assertListEqual(values, [3, 6, 9, 12], "Du har ej ändrat den givna listan.") + values = [0, 2, 4] + self.assertListEqual(mod.multiply_for_each(values, 2), [0, 4, 8], + "Du returnerar ej listan med [0, 2, 4] multiplicerat med 2.") + self.assertListEqual(values, [0, 4, 8], "Du har ej ändrat den givna listan.") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_10(self): + points = 15 + uppg = "2.3.10" + try: + self.assertListEqual(mod.insert_at_asc_place([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 3.3), + [1.0, 2.0, 3.0, 3.3, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], + "Du har satt in 3.3 fel i [1.0, 2.0, 3.0, 3.3, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]") + self.assertListEqual(mod.insert_at_asc_place([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0], 10.0), + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0], + "Du har satt in 10.0 fel i [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0]") + self.assertListEqual(mod.insert_at_asc_place([1, 3], 4), [1, 3, 4], "Du har satt in 4 fel i [1, 3]") + self.assertListEqual(mod.insert_at_asc_place([1, 3], 3), [1, 3, 3], "Du har satt in 3 fel i [1, 3]") + self.assertListEqual(mod.insert_at_asc_place([], 2), [2], "Du har inte satt in 2 i []") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + def test_uppg_2_3_11(self): + points = 10 + uppg = "2.3.11" + try: + self.assertListEqual(mod.sort_asc([1, 3, 2, 0, -5, 12, 7]), [-5, 0, 1, 2, 3, 7, 12], + "Du har sorterat [1, 3, 2, 0, -5, 12, 7] fel") + self.assertListEqual(mod.sort_asc([1, 3]), [1, 3], + "Du har sorterat [1, 3] fel") + self.assertListEqual(mod.sort_asc([73, 2, 9, 0]), [0, 2, 9, 73], + "Du har sorterat [73, 2, 9, 0] fel") + except AttributeError as ae: + self.save_missing(uppg, ae) + except Exception as e: + self.save_error(uppg, e, traceback.extract_stack(limit=1)) + else: + self.save_no_errors(uppg, points) + + +if __name__ == '__main__': + + if len(sys.argv) > 1: + module_name = sys.argv[1].replace("/", ".") + + if len(sys.argv) > 2 and sys.argv[2].isdigit(): + PyUppgift.pass_points = int(sys.argv[2]) + + # remove any trailing .py + if module_name[-3:] == ".py": + module_name = module_name[:-3] + + # load module into mod + mod = importlib.import_module(module_name) + + # filename to minify later + filename = module_name + ".py" + + # set up loggger + # logging.basicConfig(filename='pyuppg1test.log', format="", filemode='w', level=logging.INFO) + logfilename = "pyuppgtest2_3.log" + log = logging.getLogger(__name__) + log.setLevel(logging.INFO) + handler = logging.FileHandler(logfilename, mode="w") + handler.setLevel(logging.INFO) + handler.setFormatter(logging.Formatter()) + log.addHandler(handler) + + # remove elements in sys.argv so that unittest.main does not get + # confused + del sys.argv[1:] + # unittest.main(verbosity=2) + # unittest.main(verbosity=1) + unittest.main() + + else: + sys.exit("Ingen mod att testa.") diff --git a/laboration2/uppgift_1.txt b/laboration2/uppgift_1.txt index e1453d3..ec1a094 100644 --- a/laboration2/uppgift_1.txt +++ b/laboration2/uppgift_1.txt @@ -1,24 +1,24 @@ -UEsDBBQAAAAIAI1pOlR8MOY2xwEAAEMFAAAaABwAbmlsZm8zNTktcHl1cHBnMl8xL29yaWcucHlV -VAkAA6k68WGpOvFhdXgLAAEEehxpWQQA4fUFlZTBbtQwEIbveYpZI6RsKSgbtFK1YnuFS7mVC0KW -N56kThM7GjuReB/ehBfD62y7NkXbkEMi//7m9++RnTdwPwyNqh1sskxiDQ0hOqWbXIse17sM/EPo -RtLAvmALDN7Bccp/crZioOow/F78gNUe2B0D7CwCu4ZJWesQ5AjCObiD378IeqWhFpMh5Q7m0Tox -rdh6XlhZ7h78S/DO6IZ3yrp8Et2INk3RoX7S4Ra2p9ToeENCYm4rQ0+5fbYw9NxNsYMAgA/57TML -89idif02Jp4Bi5F6z+IgQZ6Xl+Kn5Urz3mj3EDrHTT2PzlESGfberxV6FKTYLhj4FT5uzrle4jUe -KOXLm0t8L8gu9RYDqS6Ci8vG7VLfdtRqqW07dot7IcZmtG4xbnFw2B+QlmYxj86k+EV/bab/spdY -/c1vohN30r4ajfGJO8rzgTNSzpcgvRtBgrdQnm+F0g4bJC7RVqQGp4xOKn285yoQWp5Gt+Cvw7HG -x4h2/i/0U4S+j7tk3KvW5et4Yl/GTZq1IumQ1+a9i2EgoazoeC0qZygnQXgNjTGSV0ZLdezEegdx -9cb/1IoP5RauIOBgyO9oHdTtVZ7Wniaz7A9QSwMEFAAAAAgAjWk6VD0JczynAAAAKQEAACQAHABu -aWxmbzM1OS1weXVwcGcyXzEvcHl1cHBndGVzdDJfMS5sb2dVVAkAA6k68WGpOvFhdXgLAAEEehxp -WQQA4fUF41IGAgVv/6AgV+8QBZ/D04JDHBVCAwLcPd1CXIMUQLJcXCC+goKRnqGeoZWCqUJB/uEl -eel6SMJG2IWNsQubYBc2xS5sZqVgaIBF3BxFnAvsj+BQX19HhQD/wy1+7lYKJqZ6ChrGpgpJqRmH -t5UVa0LUuJQqHF5SpFBQlJqTmZuZB2SXKLj7u3gD9bgoFBxeqhBQWZKRn1daUJCemVYCskqRS0GB -CwBQSwMEFAAAAAgAjWk6VGg1mCJ4AAAAlAAAABsAHABuaWxmbzM1OS1weXVwcGcyXzEvaW5mby50 -eHRVVAkAA6k68WGpOvFhdXgLAAEEehxpWQQA4fUFRcxNDoMgEEDhPaeYC9AyA1jkMgZxsKSoxJ+F -t1dX3b6XfEPY2QOQIpIKJTWA2iN5suLYeL3XnEtatG1FyoUhfjn+eLj7UeuY097hq55iWfOY51Bg -Gux2TKCVMvjpg4nGusTchkDErml7hc5h/2dlPR+JOnw/yINdUEsBAh4DFAAAAAgAjWk6VHww5jbH -AQAAQwUAABoAGAAAAAAAAQAAAKSBAAAAAG5pbGZvMzU5LXB5dXBwZzJfMS9vcmlnLnB5VVQFAAOp -OvFhdXgLAAEEehxpWQQA4fUFUEsBAh4DFAAAAAgAjWk6VD0JczynAAAAKQEAACQAGAAAAAAAAQAA -AKSBGwIAAG5pbGZvMzU5LXB5dXBwZzJfMS9weXVwcGd0ZXN0Ml8xLmxvZ1VUBQADqTrxYXV4CwAB -BHocaVkEAOH1BVBLAQIeAxQAAAAIAI1pOlRoNZgieAAAAJQAAAAbABgAAAAAAAEAAACkgSADAABu -aWxmbzM1OS1weXVwcGcyXzEvaW5mby50eHRVVAUAA6k68WF1eAsAAQR6HGlZBADh9QVQSwUGAAAA -AAMAAwArAQAA7QMAAAAA \ No newline at end of file +UEsDBBQAAAAIAC2AQlTCjI1uzQEAAPAFAAAaABwAbmlsZm8zNTktcHl1cHBnMl8xL29yaWcucHlV +VAkAA8Wc+mHFnPphdXgLAAEEehxpWQQA4fUFnVRNb5wwEL3zK2ZdVWLTNGKJVoqqbq7tJbmll6qy +vHggJmAje0Dq/+k/6R+r+UgWFGdb6gNo3szzezzZvIOHpilUTrCLIok5FBaRlC5iLWrcforAL4vU +Wg3sK5bA4AP0Lf+K2YaByofye/IDNgdgdwywcgjsEjrlHCHIFgQR3MHvXxZqpSEXnbGKjubJkeg2 +bBuNyspxevQPwSujC14pR3Enqhbd0kaF+hmHW9hP7AKJF1ZIjF1m7LNz724o/eBNMkL9GgbB2/32 +hQ0gVqfJA+xDoy+TDgPdBza3OMCTMSl+Oq40r42mxyFVbvKxOplcwHDwG5ZCt8IqdtLqN/JS17uT +49e0HI82zEtvzvFqYd1aLdFYVQVIyXmhcq1O2epQDmdlyrZanZ1oi9bRaprDhrA+ol3r0TyRCdPO +6mnT/ZecxOwt3i5wtKfevdE4P9o9PJ1sI+V4EZf3c4DgPaSzm6k0YYGWS3SZVQ0poxdUb/iFBkLL +qbqF2U3sud7QLJsQ5XOA8nGep6F/lkr/TgvKpaE4x16yyNJjU0iiaaxQTlQ8FxkZG1th8RIKYyTP +jJaqj2yZ887/gpOrdA8XMEyDsf5LtwO6v4iX1KkZ/QFQSwMEFAAAAAgALYBCVD0JczynAAAAKQEA +ACQAHABuaWxmbzM1OS1weXVwcGcyXzEvcHl1cHBndGVzdDJfMS5sb2dVVAkAA8Wc+mHFnPphdXgL +AAEEehxpWQQA4fUF41IGAgVv/6AgV+8QBZ/D04JDHBVCAwLcPd1CXIMUQLJcXCC+goKRnqGeoZWC +qUJB/uEleel6SMJG2IWNsQubYBc2xS5sZqVgaIBF3BxFnAvsj+BQX19HhQD/wy1+7lYKJqZ6ChrG +pgpJqRmHt5UVa0LUuJQqHF5SpFBQlJqTmZuZB2SXKLj7u3gD9bgoFBxeqhBQWZKRn1daUJCemVYC +skqRS0GBCwBQSwMEFAAAAAgALYBCVK/BXqh4AAAAlAAAABsAHABuaWxmbzM1OS1weXVwcGcyXzEv +aW5mby50eHRVVAkAA8Wc+mHFnPphdXgLAAEEehxpWQQA4fUFRcxBDoMgEIXhPafgArbMKFC4jEEY +LCkqUVl4e2XV5K3+l3zBnWQ5R4HYiTYOygqwKFk9aH+uNeW49dKwmDJx/yX/o/D0Wsqc4jnCq1xs +29OcVpf5EuRRF069+Gij0HunhRqUm4wYgNQUvMYQ4M925WoSjvBuSMNuUEsBAh4DFAAAAAgALYBC +VMKMjW7NAQAA8AUAABoAGAAAAAAAAQAAAKSBAAAAAG5pbGZvMzU5LXB5dXBwZzJfMS9vcmlnLnB5 +VVQFAAPFnPphdXgLAAEEehxpWQQA4fUFUEsBAh4DFAAAAAgALYBCVD0JczynAAAAKQEAACQAGAAA +AAAAAQAAAKSBIQIAAG5pbGZvMzU5LXB5dXBwZzJfMS9weXVwcGd0ZXN0Ml8xLmxvZ1VUBQADxZz6 +YXV4CwABBHocaVkEAOH1BVBLAQIeAxQAAAAIAC2AQlSvwV6oeAAAAJQAAAAbABgAAAAAAAEAAACk +gSYDAABuaWxmbzM1OS1weXVwcGcyXzEvaW5mby50eHRVVAUAA8Wc+mF1eAsAAQR6HGlZBADh9QVQ +SwUGAAAAAAMAAwArAQAA8wMAAAAA \ No newline at end of file diff --git a/laboration2/uppgift_2.txt b/laboration2/uppgift_2.txt index 3f08920..a4bfa3f 100644 --- a/laboration2/uppgift_2.txt +++ b/laboration2/uppgift_2.txt @@ -1,31 +1,31 @@ -UEsDBBQAAAAIAPVxOlRPedNKJQMAADoMAAAaABwAbmlsZm8zNTktcHl1cHBnMl8yL29yaWcucHlV -VAkAA31J8WFcSfFhdXgLAAEEehxpWQQA4fUFrVbLctowFN3zFXcmGzuBBtpJFwxk2UWn3bUrhvEI -LIymtuyRZRL6Pf2T/livHrZky5BkGjbocc695x5dCW7gZ1Vl7CDh42SS0gPsBSWSJpLyJGe1TJ6O -LKdRvJwAfhisYQ56WJy/4TbON1s91zgErGCxMGCH+kCqivI0YnG3weBuDQsTSlDZCG6x4yoOpWg1 -3MBXksGJ5TkQkTUF5ZIKAkRKUNDZviwqQY+U16zkQPjp7x+eUgE1y4CcgHLAYLO8LCs/+YapZZTF -OAjCMxrNp1hJvO3p+U1Fmcgy4U2xo8I3yKy8xSbDgDt4P7vG5CnneuKuFew0DQq3EUdLryUR0q5P -0d80CczwIS/Y4vjvas14AcqcF+RftOsSz3cvozIpyLM1imGnZja1jV6cv5NntMHf2sy3wy5y9uSU -9+JsFstt7Fxih34optRs4dEkWo7nM6CBoX0/kdWvSDn3xnqUfzQvlIPDCnoFKEwgGBevKWL8ghpM -9v9qVibSsgsYqmHcqHkqRZqw3tupluqp3gnfh/7Jamj/OPXShm1hvdbjJeywo3+NnRbNa7psNX0h -OPNF/hANHdGoDjJU6LmjNwNLWjXduvo4Za+Vsi8bLhN7ALU17ETyhvrnqFHKs+vuBbz2RtSM423l -ez80WjpVJx8vbfjOxvE7oEGjopWDL0j27HTISxoReEFZKIWc8Lcvo75xtd9keiRLp2TEMb/hFBTT -mXW06IohCL33YvT1dJ60wa0GGLWjDgQMLthorqqsmpxI/JWPcJiQKT7M+NLjt5ru7HTX2qEJCVGd -q/e79pxPNCAvn/ANwC1YW2RHWRmG7moz1Iwjy44hxcVh9VWekodEI1ox7ejRCjc0M/YUBjQ/HKYc -IbcGRIE2/N/E0/EIMeAphYzdRQbx+shaO8PfZb12pkTUgyZ0oVeelS5GJfASOAHxYMNR3I4LiT3U -TW4jT+79Yj53BO8IkeFmt5Ezu88wlXSXwe9SvWV6c8eEPKbkHHFrSiXKFFpS8MeLx37ZiLxdQ/Tp -88OMxff45SdZwExDTJ66KZLyoN6iOnyDrt651z5BFy/kP1BLAwQUAAAACAD1cTpUnrMX088AAAA3 -AgAAJAAcAG5pbGZvMzU5LXB5dXBwZzJfMi9weXVwcGd0ZXN0Ml8yLmxvZ1VUCQADfUnxYVxJ8WF1 -eAsAAQR6HGlZBADh9QV1kU0OgjAUhPc9xRg3umkAf0B2JCAxqBDEA2iCQKLQIJq49wyeQK/gBXox -qW40tm/VN/PNvEVJtx0EYRx7QYI5v60SB+so8mfTxIshXELEDhjUoDrd2BiBVfxeZvTH2MoNQ5Uw -JAmhDiSBjy7nhwp+qOBHUnWsaBkrWkwFbyp4C3Legpyf2NC1f1nXFLr+3ULen7paLxYOopBfl75I -aRQ9U8M2zfnzfOx/IPcEfq/B6nRfHIqyfTfwQzdoQy4YfyC6NHlVnhjLil0jbnUIQF5QSwMEFAAA -AAgA9XE6VENawZV4AAAAlAAAABsAHABuaWxmbzM1OS1weXVwcGcyXzIvaW5mby50eHRVVAkAA31J -8WF9SfFhdXgLAAEEehxpWQQA4fUFRcxBDoMgEEDRPafgArTMCBi4jEEYLCkqUVl4+8qq2/+TF/1F -jnOUiEKCQMNBOdBOAWsnHc/ackn7oC1LuRAPHwpfik9vtS45XRO+6s32Iy9584WvUZ9t5cmPNKI0 -VhrtwcvZmyRVsJbUEMMMf1bUu0s44bsjHfsBUEsBAh4DFAAAAAgA9XE6VE9500olAwAAOgwAABoA -GAAAAAAAAQAAAKSBAAAAAG5pbGZvMzU5LXB5dXBwZzJfMi9vcmlnLnB5VVQFAAN9SfFhdXgLAAEE -ehxpWQQA4fUFUEsBAh4DFAAAAAgA9XE6VJ6zF9PPAAAANwIAACQAGAAAAAAAAQAAAKSBeQMAAG5p -bGZvMzU5LXB5dXBwZzJfMi9weXVwcGd0ZXN0Ml8yLmxvZ1VUBQADfUnxYXV4CwABBHocaVkEAOH1 -BVBLAQIeAxQAAAAIAPVxOlRDWsGVeAAAAJQAAAAbABgAAAAAAAEAAACkgaYEAABuaWxmbzM1OS1w -eXVwcGcyXzIvaW5mby50eHRVVAUAA31J8WF1eAsAAQR6HGlZBADh9QVQSwUGAAAAAAMAAwArAQAA -cwUAAAAA \ No newline at end of file +UEsDBBQAAAAIAFGAQlSokWTNIQMAAKoMAAAaABwAbmlsZm8zNTktcHl1cHBnMl8yL29yaWcucHlV +VAkAAwqd+mEKnfphdXgLAAEEehxpWQQA4fUFrVbLctowFN3zFXcmGzuBBtpJFxnIsotOu2tXDOMR +WBhNbdkjyyT0e/on/bFePUCyZZumDRv0OOfec4+uBDfwvaoytpfwfjJJ6R52ghJJE0l5krNaJs8H +ltMofpwAfhisYK5HxekL7uJ0vdFzDcP9JSwWButQ70hVUZ5GLL5sMLhbwUJPBZWN4BY66RexL8VZ +wg18JhkcWZ4DEVlTUC6pIECkBAWd7cqiEvRAec1KDoQff//iKRVQswzIESgHDDbLy7Lys6+ZWkZZ +jIMgPKPRfIqVxJu2oJ9UlIksE94UWyp8g8zKK2wyBLiDt7OrT51yrqVtrGCnqVu4Ddlbei2JkHZ9 +iganSWCGD7nii+O/qTf9BSh3rsgf9GuI17IvozIpyIt1imGvZja3DV+cvpIX9MHfWs83nTZy9uSU +t8KsF4+b2LnE9u1ITKnZwJPJ43CDqQ1h1FxkdapTNr6yNmUmzQtlZ7ecVjUKM6oeAaPyGB+Qhpn/ +X9rSRAqk6eChNMattOdSpAlrPbFqqZ7qneAZaZ+/RrYPXS+t2QZWKz1uC9riHfjRd6Y0r6mDWp2f +CK76wr+JhvbpVsceqvbs05uBZ1ckvlrTrmy4TOxR1dbNI8kb6p+4Rl0MHbI2oFndrGYcLzzf+ZHR +76lqkbhdisl08bhjudWvQf0FKFuvyPc8dsghwQj8C5k9usgRf1kz6jtaB60pSznmpd+nCor5zDqa +N2IPQu+9GB1BF4fO0X0RXW/qQEDnXvbnqsqqyYnEPxERDhMyxWcff0fwW023dro9+6EJCVHNrfeD +Dp5P9EpePuN7ghBYWcaFujRMfQHMUDMOLDuEFBeH1aM8JROJRrxi2tGTLcDQzNhTGND8cJiyh3w2 +Igq04d8znvZHiAGPK2RsBxkkDqydLUzuEyWi7jSji7z0nHQhKoE3w+WPOxuO4nZcSOyly+Q28tTe +L+ZzR/BOEBludhs5r9sMU4m+FH6n6mXbn1sm5CElp4hbQypRpnC+Rj3/7WK/aITeriD68PFhxuJ7 +/PLTLGCmITZT3RRJuVfvUx2+S2M3719epcErOvkDUEsDBBQAAAAIAFGAQlSesxfTzwAAADcCAAAk +ABwAbmlsZm8zNTktcHl1cHBnMl8yL3B5dXBwZ3Rlc3QyXzIubG9nVVQJAAMKnfphCp36YXV4CwAB +BHocaVkEAOH1BXWRTQ6CMBSE9z3FGDe6aQB/QHYkIDGoEMQDaIJAotAgmrj3DJ5Ar+AFejGpbjS2 +b9U38828RUm3HQRhHHtBgjm/rRIH6yjyZ9PEiyFcQsQOGNSgOt3YGIFV/F5m9MfYyg1DlTAkCaEO +JIGPLueHCn6o4EdSdaxoGStaTAVvKngLct6CnJ/Y0LV/WdcUuv7dQt6fulovFg6ikF+XvkhpFD1T +wzbN+fN87H8g9wR+r8HqdF8cirJ9N/BDN2hDLhh/ILo0eVWeGMuKXSNudQhAXlBLAwQUAAAACABR +gEJUpJ4/dHgAAACUAAAAGwAcAG5pbGZvMzU5LXB5dXBwZzJfMi9pbmZvLnR4dFVUCQADCp36YQqd ++mF1eAsAAQR6HGlZBADh9QVFzEsOgyAUheE5q7gbsIXLQ2EzhsDFkqISlYG7r4yanNF/ki/6ixwA +csSB94EwjqOTirWTjufackm71JalXAjCh8KX4tNbrUtO14yverP9yEvefIE16rOtEIRVdlLCe0pa +BIN8JDONOoiQUAr8s0O9u4QzvjvSsR9QSwECHgMUAAAACABRgEJUqJFkzSEDAACqDAAAGgAYAAAA +AAABAAAApIEAAAAAbmlsZm8zNTktcHl1cHBnMl8yL29yaWcucHlVVAUAAwqd+mF1eAsAAQR6HGlZ +BADh9QVQSwECHgMUAAAACABRgEJUnrMX088AAAA3AgAAJAAYAAAAAAABAAAApIF1AwAAbmlsZm8z +NTktcHl1cHBnMl8yL3B5dXBwZ3Rlc3QyXzIubG9nVVQFAAMKnfphdXgLAAEEehxpWQQA4fUFUEsB +Ah4DFAAAAAgAUYBCVKSeP3R4AAAAlAAAABsAGAAAAAAAAQAAAKSBogQAAG5pbGZvMzU5LXB5dXBw +ZzJfMi9pbmZvLnR4dFVUBQADCp36YXV4CwABBHocaVkEAOH1BVBLBQYAAAAAAwADACsBAABvBQAA +AAA= \ No newline at end of file diff --git a/laboration2/uppgift_3.py b/laboration2/uppgift_3.py index dd84c04..1c68317 100644 --- a/laboration2/uppgift_3.py +++ b/laboration2/uppgift_3.py @@ -1,7 +1,6 @@ # Uppgift 3 from random import shuffle - def replace_periods_with_newlines(string_value): s = "" for char in string_value: @@ -27,13 +26,14 @@ def reverse_string_while(string_value): s = "" while i > -1: s += string_value[i] + i -= 1 return s - def reverse_string_for(string_value): s = "" for char in string_value: s = char + s + return s def get_five_first(value_list): @@ -76,15 +76,18 @@ def insert_at_asc_place(values, new_value): # With binary search newList = values.copy() idx = 1 + if len(newList) == 0: + values = [new_value] + return values while True: mid = len(newList) // 2 if not mid: idx += new_value > newList[mid] values.insert(idx, new_value) break - if new_value > newList[mid]: + if new_value >= newList[mid]: newList = newList[mid:len(newList)] - idx += mid + idx += mid + 1 else: newList = newList[0:mid] idx -= mid @@ -92,7 +95,6 @@ def insert_at_asc_place(values, new_value): idx = 0 return values - def sort_asc(values): # Godtycklig sorteringsalgoritm, hoppas era testfall inte # har speciellt stora listor, annars lär vi sitta här ett tag. @@ -102,7 +104,7 @@ def sort_asc(values): while not sorted: shuffle(newList) for i in range(len(newList) - 1): - if newList[i] > newList[i+1]: + if newList[i] >= newList[i+1]: break else: sorted = True diff --git a/laboration2/uppgift_3.txt b/laboration2/uppgift_3.txt new file mode 100644 index 0000000..90e96a1 --- /dev/null +++ b/laboration2/uppgift_3.txt @@ -0,0 +1,30 @@ +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 \ No newline at end of file -- 2.30.2