diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/0_docstring.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/0_docstring.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/0_docstring.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/0_docstring.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/1a_generated_tests.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/1a_generated_tests.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/1a_generated_tests.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/1a_generated_tests.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/1b_manual_refactor_tests.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/1b_manual_refactor_tests.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/1b_manual_refactor_tests.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/1b_manual_refactor_tests.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/2a_generated_function.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2a_generated_function.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/2a_generated_function.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2a_generated_function.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/2b_manual_refactor_function.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2b_manual_refactor_function.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/2b_manual_refactor_function.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2b_manual_refactor_function.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/2c_generated_refactor_function.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2c_generated_refactor_function.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/2c_generated_refactor_function.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2c_generated_refactor_function.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/2d_manual_refactor_function.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2d_manual_refactor_function.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/2d_manual_refactor_function.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/2d_manual_refactor_function.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/3_polish_implementation.py b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/3_polish_implementation.py similarity index 100% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/3_polish_implementation.py rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/3_polish_implementation.py diff --git a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/README.md b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/README.md similarity index 79% rename from 5_tdd_with_llms/examples/filter_and_sort_dictionaries/README.md rename to 5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/README.md index 9df3279..0807196 100644 --- a/5_tdd_with_llms/examples/filter_and_sort_dictionaries/README.md +++ b/5_tdd_with_llms/examples/filter_and_sort_dictionaries_with_llm/README.md @@ -1,5 +1,7 @@ # Filter and Sort +> This example is from the [Workflow with LLM guide video](../../workflow_with_llm.mp4) + Write a function that filters a list of dicts by key, and alphabetizes the entries by value. The function should not modify the argument list. diff --git a/5_tdd_with_llms/examples/repeat_character_from_et6_workshop/repeat_character.py b/5_tdd_with_llms/examples/repeat_character_from_et6_workshop/repeat_character.py new file mode 100644 index 0000000..dae89e8 --- /dev/null +++ b/5_tdd_with_llms/examples/repeat_character_from_et6_workshop/repeat_character.py @@ -0,0 +1,50 @@ +""" Repeat Character + +Write a function that takes in a string, a single character, and a number. +The function returns a string with each occurrence of the character repeated n times. + +""" + +def repeat_character(text: str, char_to_repeat: str, repetitions: int) -> str: + """The function returns a string with each occurrence of the character repeated n times. + + Parameters: + text (str): we will repeat the character in this string + char_to_repeat (str): this is the character we want to repeat + repetitions (int): how many times to repeat the character + + Returns: + string: the string with a single character repeated + + Raises: + AssertionError: if the first argument is not a string + AssertionError: if the second argument is not a single character + AssertionError: if the third argument is not an integer + AssertionError: if the third argument is less than 0 + + >>> repeat_character('Omnia', 'm', 7) + 'Ommmmmmmnia' + + >>> repeat_character('Jola-Moses', 's', 2) + 'Jola-Mossess' + + >>> repeat_character('Hasan', 'e', 999999999999) + 'Hasan' + + >>> repeat_character('Rafaa', 'a', 3) + 'Raaafaaaaaa' + """ + + assert isinstance(repetitions, int), 'third argument must be an integer' + assert repetitions >= 0, 'third argument cannot be less than 0' + + repeated_text = '' + + for char in text: + if char.lower() == char_to_repeat.lower(): + # repeated_text += char_to_repeat * repetitions + repeated_text += char * repetitions + else: + repeated_text += char + + return repeated_text diff --git a/5_tdd_with_llms/examples/repeat_character_from_et6_workshop/tests/test_repeat_character.py b/5_tdd_with_llms/examples/repeat_character_from_et6_workshop/tests/test_repeat_character.py new file mode 100644 index 0000000..16b1a7a --- /dev/null +++ b/5_tdd_with_llms/examples/repeat_character_from_et6_workshop/tests/test_repeat_character.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +""" + +import unittest +from ..repeat_character import repeat_character + +class TestRepeatCharacter(unittest.TestCase): + """""" + + def test_empty_string(self): + """it should return an empty if you pass an empty string""" + self.assertEqual(repeat_character('', '!', 100000000000), "") + + def test_zero_repetitions(self): + """it should return the same string without the repeated char""" + self.assertEqual(repeat_character('agabani', 'a', 0), "gbni") + + def test_repeat_character_seven_times(self): + """It should repeat 'm' 7 times in Omnia""" + self.assertEqual(repeat_character('Omnia', 'm', 7), "Ommmmmmmnia") + + def test_character_with_more_than_one(self): + """It should repeat 's' 2 times in Jola-Moses""" + self.assertEqual(repeat_character('Jola-Moses', 's', 2), 'Jola-Mossess') + + def test_character_doesnt_exist(self): + """It should repeat nothing in Hasan because there is no 'e'""" + self.assertEqual(repeat_character('Hasan', 'e', 999999999999), 'Hasan') + + def test_characters_that_are_next_to_each_other(self): + """It should repeat characters even if they're already repeated""" + self.assertEqual(repeat_character('Rafaa', 'a', 3), 'Raaafaaaaaa') + + def test_case_insensitive_upper_text(self): + """it should be case insensitive when the text is upper and the char is lower""" + self.assertEqual(repeat_character('Agabani', 'a', 0), "gbni") + + def test_case_insensitive_upper_char(self): + """it should be case insensitive when the text is lower and the char is upper""" + self.assertEqual(repeat_character('Agabani', 'A', 0), "gbni") + + def test_case_insensitive_with_non_zero_repetition(self): + """it should be case insensitive and repeat characters""" + self.assertEqual(repeat_character('Agabani', 'A', 2), "AAgaabaani") + + # test defensive assertions + def test_defensive_check_repetitions_is_not_int(self): + """it should raise an error if the reptitions is not an integer""" + with self.assertRaises(AssertionError): + repeat_character('Agabani', 'A', '3' ) + + def test_defensive_check_for_negative_repetitions(self): + """it should raise an error if the reptitions is less than 0""" + with self.assertRaises(AssertionError): + repeat_character('Agabani', 'A', -2) diff --git a/5_tdd_with_llms/exercises/tests/test_repeat_character.py b/5_tdd_with_llms/exercises/tests/test_repeat_character.py index 8b13789..e69de29 100644 --- a/5_tdd_with_llms/exercises/tests/test_repeat_character.py +++ b/5_tdd_with_llms/exercises/tests/test_repeat_character.py @@ -1 +0,0 @@ - diff --git a/5_tdd_with_llms/prep_work.md b/5_tdd_with_llms/prep_work.md index 3e57253..f43d05b 100644 --- a/5_tdd_with_llms/prep_work.md +++ b/5_tdd_with_llms/prep_work.md @@ -12,4 +12,4 @@ To prepare for the workshop, read through these two documents: [Test-Driven Deve You can explore integrating LLMs into your workflow after the workshop using these resources: - [Workflow with LLM](./workflow_with_llm.md) + [video guide](https://mit-emerging-talent.github.io/ET6-Programming-With-Python/5_tdd_with_llms/workflow_example.mp4) -- [Stepped examples](./examples/): Each of the files is a snapshot of a different step in the development process. The final product is in one file for demonstration, yours should be separated into two files. +- [`filter_and_sort_dictionaries_with_llm](./examples/filter_and_sort_dictionaries_with_llm/): This has snapshots of different steps in the development process. The final product is in one file for demonstration, yours should be separated into two files.