{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
LICENSE\n", "\n", "MIT License\n", "\n", "Copyright (c) 2018 Oleksii Trekhleb\n", "\n", "Permission is hereby granted, free of charge, to any person obtaining a copy\n", "of this software and associated documentation files (the \"Software\"), to deal\n", "in the Software without restriction, including without limitation the rights\n", "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n", "copies of the Software, and to permit persons to whom the Software is\n", "furnished to do so, subject to the following conditions:\n", "\n", "The above copyright notice and this permission notice shall be included in all\n", "copies or substantial portions of the Software.\n", "\n", "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n", "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n", "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n", "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n", "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n", "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n", "SOFTWARE.\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Python programming basics" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "tags": [] }, "outputs": [], "source": [ "# set up the env\n", "\n", "import pytest\n", "import ipytest\n", "import unittest\n", "\n", "ipytest.autoconfig()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Operators" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Implement a function to generate the Fibonacci sequence up to a specified number of terms." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def fibonacci(n):\n", " \"\"\"\n", " Generate the Fibonacci sequence up to the given number of terms.\n", "\n", " Args:\n", " n (int): The number of Fibonacci terms to generate.\n", "\n", " Returns:\n", " list: A list containing the Fibonacci sequence.\n", "\n", " \"\"\"\n", " sequence = [0, 1]\n", " while len(sequence) < ____:\n", " next_num = sequence[____] + sequence[____]\n", " ____.append(____)\n", " return sequence[:n]\n", "\n", "\n", "# Testing fibonacci function\n", "fib_sequence = fibonacci(10)\n", "assert fib_sequence == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34], \"Fibonacci sequence test failed\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestFibonacci:\n", " def test_fibonacci_sequence(self):\n", " # Test case 1: Valid input\n", " n = 10\n", " expected_sequence = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\n", "\n", " # Act\n", " result = fibonacci(n)\n", "\n", " # Assert\n", " assert result == expected_sequence\n", "\n", " def test_fibonacci_sequence_zero_terms(self):\n", " # Test case 2: Zero terms\n", " n = 0\n", " expected_sequence = []\n", "\n", " # Act\n", " result = fibonacci(n)\n", "\n", " # Assert\n", " assert result == expected_sequence\n", "\n", " def test_fibonacci_sequence_single_term(self):\n", " # Test case 3: Single term\n", " n = 1\n", " expected_sequence = [0]\n", "\n", " # Act\n", " result = fibonacci(n)\n", "\n", " # Assert\n", " assert result == expected_sequence" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "You can consider to start the Fibonacci sequence with [0, 1] and generate the next numbers using the last two elements.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Implement a function for insertion sort to sort a list in ascending order." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def insertion_sort(arr):\n", " \"\"\"\n", " Perform insertion sort on the given list.\n", "\n", " Args:\n", " arr (list): The unsorted list to be sorted in-place.\n", "\n", " Returns:\n", " None. The input list is sorted in-place.\n", "\n", " \"\"\"\n", " for i in range(1, len(arr)):\n", " key = arr[i]\n", " j = ____ - ____\n", " while j >= 0 and arr[j] > ____:\n", " arr[j + 1] = arr[j]\n", " j -= ____\n", " arr[j + ____] = ____\n", "\n", "\n", "# Testing insertion_sort function\n", "unsorted_list = [5, 3, 8, 4, 2]\n", "insertion_sort(unsorted_list)\n", "assert unsorted_list == [2, 3, 4, 5, 8], \"Insertion sort test failed\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestInsertionSort:\n", " def test_insertion_sort(self):\n", " # Test case 1: Unsorted list\n", " arr = [5, 3, 8, 4, 2]\n", " expected_sorted_list = [2, 3, 4, 5, 8]\n", "\n", " # Act\n", " insertion_sort(arr)\n", "\n", " # Assert\n", " assert arr == expected_sorted_list\n", "\n", " def test_insertion_sort_empty_list(self):\n", " # Test case 2: Empty list\n", " arr = []\n", " expected_sorted_list = []\n", "\n", " # Act\n", " insertion_sort(arr)\n", "\n", " # Assert\n", " assert arr == expected_sorted_list\n", "\n", " def test_insertion_sort_single_element_list(self):\n", " # Test case 3: Single element list\n", " arr = [5]\n", " expected_sorted_list = [5]\n", "\n", " # Act\n", " insertion_sort(arr)\n", "\n", " # Assert\n", " assert arr == expected_sorted_list\n", "\n", " def test_insertion_sort_sorted_list(self):\n", " # Test case 4: Already sorted list\n", " arr = [2, 3, 4, 5, 8]\n", " expected_sorted_list = [2, 3, 4, 5, 8]\n", "\n", " # Act\n", " insertion_sort(arr)\n", "\n", " # Assert\n", " assert arr == expected_sorted_list" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "You can consider to iterate and compare elements, shifting them to sort the list.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Implement a function to calculate the square root of a number using the Babylonian method." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Inspired by SICP http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1.7\n", "def sqrt(x):\n", " \"\"\"\n", " Implement a function to calculate the square root of a given number using the Babylonian method.\n", "\n", " Args:\n", " x (float): The number for which the square root is to be calculated.\n", "\n", " Returns:\n", " float: The square root of the given number.\n", "\n", " \"\"\"\n", "\n", " def average(a, b):\n", " return (a + b) / 2.0\n", "\n", " def is_good_enough(guess):\n", " return abs((guess * guess) - ____) < 0.001\n", "\n", " def improve(guess):\n", " return average(guess, x / guess)\n", "\n", " def sqrt_iter(guess):\n", " if is_good_enough(guess):\n", " return ____\n", " else:\n", " return ____(improve(____))\n", "\n", " return sqrt_iter(1.0)\n", "\n", "\n", "# Testing sqrt function\n", "assert abs(sqrt(9) - 3.0) < 0.001, \"Square root test failed\"\n", "assert abs(sqrt(16) - 4.0) < 0.001, \"Square root test failed\"\n", "assert abs(sqrt(25) - 5.0) < 0.001, \"Square root test failed\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestSqrt:\n", " def test_sqrt(self):\n", " # Test case 1: Square root of 9\n", " x = 9\n", " expected_result = 3.0\n", "\n", " # Act\n", " result = sqrt(x)\n", "\n", " # Assert\n", " assert abs(result - expected_result) < 0.001\n", "\n", " def test_sqrt_perfect_square(self):\n", " # Test case 2: Square root of a perfect square (16)\n", " x = 16\n", " expected_result = 4.0\n", "\n", " # Act\n", " result = sqrt(x)\n", "\n", " # Assert\n", " assert abs(result - expected_result) < 0.001\n", "\n", " def test_sqrt_non_perfect_square(self):\n", " # Test case 3: Square root of a non-perfect square (25)\n", " x = 25\n", " expected_result = 5.0\n", "\n", " # Act\n", " result = sqrt(x)\n", "\n", " # Assert\n", " assert abs(result - expected_result) < 0.001" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "You can consider using iterative approximation to calculate the square root.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## String" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### str.upper" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "def capitalize_first_letter(string):\n", " \"\"\"\n", " Capitalizes the first letter of each word in a string.\n", "\n", " Args:\n", " string (str): The input string.\n", "\n", " Returns:\n", " str: The input string with the first letter of each word capitalized.\n", " \"\"\"\n", " words = string.split()\n", " result = []\n", " for ____ in words:\n", " capitalized_word = word[0].____() + word[1:]\n", " result.____(capitalized_word)\n", " return ' '.join(____)\n", "\n", "\n", "sentence = \"hello, world! this is a sample sentence.\"\n", "assert capitalize_first_letter(sentence) == \"Hello, World! This Is A Sample Sentence.\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCapitalizeFirstLetterper(unittest.TestCase):\n", "\n", " def test_string_upper_happy_case(self):\n", " # assign\n", " test_string = 'Python strings are COOL!'\n", "\n", " # act\n", " actual_result = capitalize_first_letter(test_string)\n", "\n", " # assert\n", " expected_result = 'Python Strings Are COOL!'\n", " self.assertEqual(actual_result, expected_result)\n", "\n", " def test_string_upper_none_string(self):\n", " # act & assert\n", " with self.assertRaises(Exception):\n", " capitalize_first_letter(None)\n", "\n", " def test_string_upper_empty_string(self):\n", " # assign\n", " test_string = ''\n", "\n", " # act\n", " actual_result = capitalize_first_letter(test_string)\n", "\n", " # assert\n", " expected_result = ''\n", " self.assertEqual(actual_result, expected_result)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "You can consider splitting the string into words, capitalizing the first letter of each word, and joining the words back together.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### str.title" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def capitalize_words(sentence, exclude_words=None):\n", " \"\"\"\n", " Capitalizes the first letter of each word in a sentence,\n", " excluding certain words specified in the exclude_words list.\n", "\n", " Args:\n", " sentence (str): The input sentence.\n", " exclude_words (list, optional): List of words to be excluded from capitalization.\n", " Defaults to None.\n", "\n", " Returns:\n", " str: The sentence with capitalized words.\n", "\n", " \"\"\"\n", " if exclude_words is None:\n", " exclude_words = []\n", "\n", " # Split the sentence into words\n", " words = sentence.____\n", "\n", " # Capitalize the words, excluding the specified words\n", " capitalized_words = [word.____ if word.lower() not in exclude_words else word for word in words]\n", "\n", " # Join the words back into a sentence\n", " capitalized_sentence = ' '.____(capitalized_words)\n", "\n", " return capitalized_sentence\n", "\n", "\n", "# Example and assertions\n", "assert capitalize_words(\"this is a sentence\") == \"This Is A Sentence\"\n", "assert capitalize_words(\"this is a sentence\", exclude_words=[\"is\"]) == \"This is A Sentence\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCapitalizeWords(unittest.TestCase):\n", "\n", " def test_capitalize_words_default(self):\n", " # assign\n", " sentence = \"this is a sentence\"\n", "\n", " # act\n", " actual_result = capitalize_words(sentence)\n", "\n", " # assert\n", " expected_result = \"This Is A Sentence\"\n", " self.assertEqual(actual_result, expected_result)\n", "\n", " def test_capitalize_words_exclude_words(self):\n", " # assign\n", " sentence = \"this is a sentence\"\n", " exclude_words = [\"is\"]\n", "\n", " # act\n", " actual_result = capitalize_words(sentence, exclude_words)\n", "\n", " # assert\n", " expected_result = \"This is A Sentence\"\n", " self.assertEqual(actual_result, expected_result)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Split sentence into words, capitalize each word (excluding specified words), and join them.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### str.replace" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def censor_words(sentence, words):\n", " \"\"\"\n", " Censors specified words in a sentence with asterisks.\n", "\n", " Args:\n", " sentence (str): The input sentence.\n", " words (list): The list of words to be censored.\n", "\n", " Returns:\n", " str: The sentence with censored words.\n", " \"\"\"\n", " # Iterate over each word in the list of words\n", " for ____ in words:\n", " censor = '*' * len(____) # Create a censor string of asterisks with the same length as the word\n", " sentence = sentence.____(____, censor) # Replace the word with the censor string in the sentence\n", "\n", " return sentence\n", "\n", "\n", "assert censor_words(\"Hello, World!\", [\"Hello\", \"World\"]) == \"*****, *****!\"\n", "assert censor_words(\"Python is awesome\", [\"Python\", \"awesome\"]) == \"****** is *******\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCensorWords:\n", " def test_censor_words(self):\n", " # Test case 1: Censoring \"Hello\" and \"World\" in \"Hello, World!\"\n", " sentence = \"Hello, World!\"\n", " words = [\"Hello\", \"World\"]\n", " expected_result = \"*****, *****!\"\n", "\n", " # Act\n", " result = censor_words(sentence, words)\n", "\n", " # Assert\n", " assert result == expected_result\n", "\n", " def test_censor_words_partial_match(self):\n", " # Test case 2: Censoring \"Python\" and \"awesome\" in \"Python is awesome\"\n", " sentence = \"Python is awesome\"\n", " words = [\"Python\", \"awesome\"]\n", " expected_result = \"****** is *******\"\n", "\n", " # Act\n", " result = censor_words(sentence, words)\n", "\n", " # Assert\n", " assert result == expected_result\n", "\n", " def test_censor_words_no_censoring(self):\n", " # Test case 3: No censoring required\n", " sentence = \"Hello, World!\"\n", " words = [\"Love\", \"Python\"]\n", " expected_result = \"Hello, World!\"\n", "\n", " # Act\n", " result = censor_words(sentence, words)\n", "\n", " # Assert\n", " assert result == expected_result" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Iterate over each word in the list and replace it with a censor string of asterisks in the sentence.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### str.format str.join" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def format_person_info(people_info):\n", " \"\"\"\n", " Formats a list of person information into a sentence.\n", "\n", " Args:\n", " people_info (list): A list of dictionaries containing person information. Each dictionary should have 'name' and 'age' keys.\n", "\n", " Returns:\n", " str: A formatted sentence with person information.\n", " \"\"\"\n", " # Format each person's information using a list comprehension\n", " formatted_info = [\"Name: {}, Age: {}\".____(person['name'], person['age']) for person in ____]\n", "\n", " # Join the formatted information using a comma and space\n", " sentence = ', '.____(formatted_info)\n", "\n", " return ____\n", "\n", "\n", "people = [\n", " {'name': 'John Doe', 'age': 30},\n", " {'name': 'Jane Smith', 'age': 25},\n", " {'name': 'David Johnson', 'age': 35}\n", "]\n", "expected_output = \"Name: John Doe, Age: 30, Name: Jane Smith, Age: 25, Name: David Johnson, Age: 35\"\n", "assert format_person_info(people) == expected_output" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestFormatPersonInfo:\n", " def test_format_person_info(self):\n", " # Test case 1: Format person information\n", " people_info = [\n", " {'name': 'John Doe', 'age': 30},\n", " {'name': 'Jane Smith', 'age': 25},\n", " {'name': 'David Johnson', 'age': 35}\n", " ]\n", " expected_result = \"Name: John Doe, Age: 30, Name: Jane Smith, Age: 25, Name: David Johnson, Age: 35\"\n", "\n", " # Act\n", " result = format_person_info(people_info)\n", "\n", " # Assert\n", " assert result == expected_result\n", "\n", " def test_format_person_info_empty_list(self):\n", " # Test case 2: Format person information with an empty list\n", " people_info = []\n", " expected_result = \"\"\n", "\n", " # Act\n", " result = format_person_info(people_info)\n", "\n", " # Assert\n", " assert result == expected_result\n", "\n", " def test_format_person_info_single_person(self):\n", " # Test case 3: Format person information with a single person\n", " people_info = [{'name': 'John Doe', 'age': 30}]\n", " expected_result = \"Name: John Doe, Age: 30\"\n", "\n", " # Act\n", " result = format_person_info(people_info)\n", "\n", " # Assert\n", " assert result == expected_result" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Format each person's information using a list comprehension, then join the formatted information using a comma and space.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### str.split" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import string\n", "\n", "def count_word_occurrences(text):\n", " \"\"\"\n", " Counts the occurrences of each word in a text.\n", "\n", " Args:\n", " text (str): The input text.\n", "\n", " Returns:\n", " dict: A dictionary containing words as keys and their occurrences as values.\n", " \"\"\"\n", " word_counts = {}\n", "\n", " # Split the text into words using split() method\n", " words = text.____\n", "\n", " # Count the occurrences of each word\n", " for word in ____:\n", " # Remove punctuation using translate() method and string.punctuation\n", " word = word.translate(str.maketrans('', '', string.punctuation))\n", "\n", " # Convert the word to lowercase\n", " word = word.____\n", "\n", " # Update the word count\n", " if word in word_counts:\n", " word_counts[word] ____ 1\n", " else:\n", " word_counts[word] ____ 1\n", "\n", " return word_counts\n", "\n", "\n", "input_text = \"This is a sample text. This text is just an example.\"\n", "expected_output = {\n", " \"this\": 2,\n", " \"is\": 2,\n", " \"a\": 1,\n", " \"sample\": 1,\n", " \"text\": 2,\n", " \"just\": 1,\n", " \"an\": 1,\n", " \"example\": 1\n", "}\n", "assert count_word_occurrences(input_text) == expected_output" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCountWordOccurrences:\n", " def test_count_word_occurrences(self):\n", " # Test case 1: Count word occurrences in input text\n", " input_text = \"This is a sample text. This text is just an example.\"\n", " expected_output = {\n", " \"this\": 2,\n", " \"is\": 2,\n", " \"a\": 1,\n", " \"sample\": 1,\n", " \"text\": 2,\n", " \"just\": 1,\n", " \"an\": 1,\n", " \"example\": 1\n", " }\n", "\n", " # Act\n", " result = count_word_occurrences(input_text)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_count_word_occurrences_empty_text(self):\n", " # Test case 2: Count word occurrences in an empty text\n", " input_text = \"\"\n", " expected_output = {}\n", "\n", " # Act\n", " result = count_word_occurrences(input_text)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_count_word_occurrences_same_word_repeated(self):\n", " # Test case 3: Count word occurrences with the same word repeated\n", " input_text = \"word word word word\"\n", " expected_output = {\"word\": 4}\n", "\n", " # Act\n", " result = count_word_occurrences(input_text)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Split the text into words using the split() method, remove punctuation using translate() method and string.punctuation, convert words to lowercase using the lower() method, and update the word count in a dictionary.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Numbers" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "### Creating formulas\n", "\n", "Write the following mathematical formula in Python:\n", "\n", "$result = 6a^3 - \\frac{8b^2 }{4c} + 11$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "tags": [] }, "outputs": [], "source": [ "def calculate(a, b, c):\n", " \"\"\"\n", " Calculate the value of the formula: (6 * a^3) - (8 * b^2) / (4 * c) + 11.\n", "\n", " Args:\n", " a (float or int): The value of 'a'.\n", " b (float or int): The value of 'b'.\n", " c (float or int): The value of 'c'.\n", "\n", " Returns:\n", " float: The result of the formula.\n", "\n", " \"\"\"\n", " return (6 * a ____ 3) - (8 * b ____ 2) ____ (4 * c) + 11\n", "\n", "\n", "# Testing calculate function\n", "assert calculate(2, 3, 4) == 54.5, \"calculate test failed\"\n", "assert calculate(0, 5, 2) == -14.0, \"calculate test failed\"" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCalculate(unittest.TestCase):\n", "\n", " def test_calculate_happy_case(self):\n", " # assign\n", " a = 2\n", " b = 3\n", " c = 4\n", "\n", " # act\n", " actual_result = calculate(a, b, c)\n", "\n", " # assert\n", " assert actual_result == 54.5, \"calculate test failed\"\n", "\n", " def test_calculate_with_str_input(self):\n", " # assign\n", " a = '2'\n", " b = 3\n", " c = 4\n", "\n", " # act & assert\n", " with pytest.raises(TypeError):\n", " calculate(a, b, c)\n", "\n", " def test_calculate_with_none_input(self):\n", " # assign\n", " a = 2\n", " b = None\n", " c = 4\n", "\n", " # act & assert\n", " with pytest.raises(TypeError):\n", " calculate(a, b, c)\n", "\n", " def test_calculate_with_invalid_c_input(self):\n", " # assign\n", " a = 2\n", " b = 3\n", " c = 0\n", "\n", " # act & assert\n", " with pytest.raises(ZeroDivisionError):\n", " calculate(a, b, c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### list.append, list.remove, mutable" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def permutations(elements):\n", " \"\"\"\n", " Generate all permutations of a list of elements.\n", "\n", " Args:\n", " elements (list): List of elements.\n", "\n", " Returns:\n", " list: List of permutations.\n", " \"\"\"\n", " if len(elements) <= 1:\n", " return [elements]\n", "\n", " result = []\n", " for i in range(len(elements)):\n", " remaining = elements[____i] + elements[i+____]\n", " for perm in ____(remaining):\n", " result.____([elements[i]] + perm)\n", "\n", " return result\n", "\n", "\n", "assert permutations([1, 2, 3]) == [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]\n", "assert permutations(['a', 'b', 'c']) == [['a', 'b', 'c'], ['a', 'c', 'b'], ['b', 'a', 'c'], ['b', 'c', 'a'], ['c', 'a', 'b'], ['c', 'b', 'a']]" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestPermutations:\n", " def test_permutations(self):\n", " # Test case 1: Permutations of [1, 2, 3]\n", " elements = [1, 2, 3]\n", " expected_output = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]\n", "\n", " # Act\n", " result = permutations(elements)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_permutations_single_element(self):\n", " # Test case 2: Permutations of a single element\n", " elements = ['a']\n", " expected_output = [['a']]\n", "\n", " # Act\n", " result = permutations(elements)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_permutations_empty_list(self):\n", " # Test case 3: Permutations of an empty list\n", " elements = []\n", " expected_output = [[]]\n", "\n", " # Act\n", " result = permutations(elements)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Generate all permutations of a list of elements by recursively swapping elements and generating permutations of the remaining list.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": false }, "outputs": [], "source": [ "def remove_duplicates(lst):\n", " \"\"\"\n", " Remove duplicates from a list using the `list.remove()` method.\n", "\n", " Args:\n", " lst (list): The list to remove duplicates from.\n", "\n", " Returns:\n", " list: The list with duplicates removed.\n", " \"\"\"\n", " unique_list = lst[____] # Create a copy of the original list\n", " for item in lst:\n", " while unique_list.count(item) ____ 1:\n", " unique_list.____(item)\n", "\n", " return unique_list\n", "\n", "\n", "assert remove_duplicates([1, 2, 2, 3, 4, 4, 5]) == [1, 2, 3, 4, 5]\n", "assert remove_duplicates(['a', 'b', 'b', 'c', 'd', 'd']) == ['a', 'b', 'c', 'd']" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestRemoveDuplicates:\n", " def test_remove_duplicates(self):\n", " # Test case 1: Remove duplicates from [1, 2, 2, 3, 4, 4, 5]\n", " lst = [1, 2, 2, 3, 4, 4, 5]\n", " expected_output = [1, 2, 3, 4, 5]\n", "\n", " # Act\n", " result = remove_duplicates(lst)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_remove_duplicates_no_duplicates(self):\n", " # Test case 2: Remove duplicates from a list with no duplicates\n", " lst = ['a', 'b', 'c', 'd']\n", " expected_output = ['a', 'b', 'c', 'd']\n", "\n", " # Act\n", " result = remove_duplicates(lst)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_remove_duplicates_empty_list(self):\n", " # Test case 3: Remove duplicates from an empty list\n", " lst = []\n", " expected_output = []\n", "\n", " # Act\n", " result = remove_duplicates(lst)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Create a copy of the original list, iterate over the list items, and remove any duplicate occurrences using the list.remove() method. Return the resulting unique list.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Slice\n", "\n", "Create a new list without modifiying the original one." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": false }, "outputs": [], "source": [ "original = ['I', 'am', 'learning', 'hacking', 'in']" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Your implementation here\n", "modified = ____" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": false }, "outputs": [], "source": [ "assert original == ['I', 'am', 'learning', 'hacking', 'in']\n", "assert modified == ['I', 'am', 'learning', 'lists', 'in', 'Python']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### list.extend" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def flatten_nested_lists(nested_lists):\n", " \"\"\"\n", " Flatten a list of nested lists into a single list using the `list.extend()` method.\n", "\n", " Args:\n", " nested_lists (list): The list of nested lists.\n", "\n", " Returns:\n", " list: The flattened list.\n", " \"\"\"\n", " flattened_list = []\n", " ____ sublist in nested_lists:\n", " flattened_list.____(____)\n", "\n", " return flattened_list\n", "\n", "\n", "assert flatten_nested_lists([[1, 2, 3], [4, 5], [6, 7, 8, 9]]) == [1, 2, 3, 4, 5, 6, 7, 8, 9]\n", "assert flatten_nested_lists([[1], [2], [3], [4], [5]]) == [1, 2, 3, 4, 5]" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestFlattenNestedLists:\n", " def test_flatten_nested_lists(self):\n", " # Test case 1: Flatten [[1, 2, 3], [4, 5], [6, 7, 8, 9]]\n", " nested_lists = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]\n", " expected_output = [1, 2, 3, 4, 5, 6, 7, 8, 9]\n", "\n", " # Act\n", " result = flatten_nested_lists(nested_lists)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_flatten_nested_lists_empty_lists(self):\n", " # Test case 2: Flatten [[]]\n", " nested_lists = [[]]\n", " expected_output = []\n", "\n", " # Act\n", " result = flatten_nested_lists(nested_lists)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_flatten_nested_lists_no_nested_lists(self):\n", " # Test case 3: Flatten [1, 2, 3, 4, 5]\n", " nested_lists = [1, 2, 3, 4, 5]\n", " expected_output = [1, 2, 3, 4, 5]\n", "\n", " # Act\n", " result = flatten_nested_lists([nested_lists])\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Initialize an empty list called flattened_list. Iterate over each sublist in the nested_lists using a loop. Extend flattened_list with each sublist using the list.extend() method. Finally, return flattened_list.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dictionaries" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Populating a dictionary\n", "\n", "Create a dictionary by using all the given variables." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": false }, "outputs": [], "source": [ "first_name = 'John'\n", "last_name = 'Doe'\n", "favorite_hobby = 'Python'\n", "sports_hobby = 'gym'\n", "age = 82" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Your implementation\n", "my_dict = ____" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "editable": false }, "outputs": [], "source": [ "assert my_dict == {\n", " 'name': 'John Doe',\n", " 'age': 82,\n", " 'hobbies': ['Python', 'gym']\n", " }" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "Populating a Dictionary with Element Occurrences" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def count_occurrences(lst):\n", " \"\"\"\n", " Count the occurrences of elements in a list and store the counts in a dictionary.\n", "\n", " Args:\n", " lst (list): The input list.\n", "\n", " Returns:\n", " dict: A dictionary with elements as keys and their occurrences as values.\n", " \"\"\"\n", " occurrences = {}\n", " for item in lst:\n", " if item in ____:\n", " occurrences[item] ____ 1\n", " else:\n", " occurrences[____] = 1\n", " return occurrences\n", "\n", "\n", "assert count_occurrences([1, 2, 2, 3, 3, 3]) == {1: 1, 2: 2, 3: 3}\n", "assert count_occurrences(['a', 'b', 'a', 'c', 'c']) == {'a': 2, 'b': 1, 'c': 2}" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCountOccurrences:\n", " def test_count_occurrences(self):\n", " # Test case 1: Count occurrences in [1, 2, 2, 3, 3, 3]\n", " lst = [1, 2, 2, 3, 3, 3]\n", " expected_output = {1: 1, 2: 2, 3: 3}\n", "\n", " # Act\n", " result = count_occurrences(lst)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_count_occurrences_empty_list(self):\n", " # Test case 2: Count occurrences in an empty list []\n", " lst = []\n", " expected_output = {}\n", "\n", " # Act\n", " result = count_occurrences(lst)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_count_occurrences_strings(self):\n", " # Test case 3: Count occurrences in ['a', 'b', 'a', 'c', 'c']\n", " lst = ['a', 'b', 'a', 'c', 'c']\n", " expected_output = {'a': 2, 'b': 1, 'c': 2}\n", "\n", " # Act\n", " result = count_occurrences(lst)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Iterate over the list, check if each item is already a key, and update its occurrence count.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### Removing Duplicate Values from a Dictionary using 'del'" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def remove_duplicates(dictionary):\n", " \"\"\"\n", " Remove duplicate values from a dictionary by using the `del` keyword.\n", "\n", " Args:\n", " dictionary (dict): The input dictionary.\n", "\n", " Returns:\n", " dict: The dictionary with duplicate values removed.\n", " \"\"\"\n", " unique_values = set()\n", " duplicate_keys = []\n", " for key, value in dictionary.items():\n", " if ____ in unique_values:\n", " duplicate_keys.append(____)\n", " else:\n", " unique_values.add(____)\n", " for key in duplicate_keys:\n", " ____ dictionary[key]\n", " return dictionary\n", "\n", "\n", "assert remove_duplicates({'a': 1, 'b': 2, 'c': 1, 'd': 3}) == {'a': 1, 'b': 2, 'd': 3}\n", "assert remove_duplicates({'x': 'abc', 'y': 'def', 'z': 'abc'}) == {'x': 'abc', 'y': 'def'}" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestRemoveDuplicates:\n", " def test_remove_duplicates(self):\n", " # Test case 1: Remove duplicates from {'a': 1, 'b': 2, 'c': 1, 'd': 3}\n", " dictionary = {'a': 1, 'b': 2, 'c': 1, 'd': 3}\n", " expected_output = {'a': 1, 'b': 2, 'd': 3}\n", "\n", " # Act\n", " result = remove_duplicates(dictionary)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_remove_duplicates_empty_dict(self):\n", " # Test case 2: Remove duplicates from an empty dictionary {}\n", " dictionary = {}\n", " expected_output = {}\n", "\n", " # Act\n", " result = remove_duplicates(dictionary)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_remove_duplicates_strings(self):\n", " # Test case 3: Remove duplicates from {'x': 'abc', 'y': 'def', 'z': 'abc'}\n", " dictionary = {'x': 'abc', 'y': 'def', 'z': 'abc'}\n", " expected_output = {'x': 'abc', 'y': 'def'}\n", "\n", " # Act\n", " result = remove_duplicates(dictionary)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Use a set to track unique values, iterate over the dictionary items, and remove duplicate keys using the del keyword.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### Counting Occurrences of Elements using dict.get()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def count_occurrences(lst):\n", " \"\"\"\n", " Count the occurrences of elements in a list and store the counts in a dictionary using `dict.get()`.\n", "\n", " Args:\n", " lst (list): The input list.\n", "\n", " Returns:\n", " dict: A dictionary with elements as keys and their occurrences as values.\n", " \"\"\"\n", " occurrences = {}\n", " for item in lst:\n", " occurrences[item] = occurrences.____(item, 0) ____ 1\n", " return occurrences\n", "\n", "\n", "assert count_occurrences([1, 2, 2, 3, 3, 3]) == {1: 1, 2: 2, 3: 3}\n", "assert count_occurrences(['a', 'b', 'a', 'c', 'c']) == {'a': 2, 'b': 1, 'c': 2}" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestCountOccurrences:\n", " def test_count_occurrences(self):\n", " # Test case 1: Count occurrences in [1, 2, 2, 3, 3, 3]\n", " lst = [1, 2, 2, 3, 3, 3]\n", " expected_output = {1: 1, 2: 2, 3: 3}\n", "\n", " # Act\n", " result = count_occurrences(lst)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_count_occurrences_empty_list(self):\n", " # Test case 2: Count occurrences in an empty list []\n", " lst = []\n", " expected_output = {}\n", "\n", " # Act\n", " result = count_occurrences(lst)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_count_occurrences_strings(self):\n", " # Test case 3: Count occurrences in ['a', 'b', 'a', 'c', 'c']\n", " lst = ['a', 'b', 'a', 'c', 'c']\n", " expected_output = {'a': 2, 'b': 1, 'c': 2}\n", "\n", " # Act\n", " result = count_occurrences(lst)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Use the dict.get() method to retrieve the current count of an element from the dictionary and increment it by 1. Initialize the count as 0 if the element is not yet in the dictionary.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### Grouping Items by Category using dict.setdefault()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def group_by_category(items):\n", " \"\"\"\n", " Group items by category using `dict.setdefault()`.\n", "\n", " Args:\n", " items (list): The input list of items.\n", "\n", " Returns:\n", " dict: A dictionary with categories as keys and lists of items as values.\n", " \"\"\"\n", " categories = {}\n", " for item in items:\n", " category = ____.get('category')\n", " categories.____(category, []).____(item)\n", " return categories\n", "\n", "\n", "items = [\n", " {'name': 'Item 1', 'category': 'Category A'},\n", " {'name': 'Item 2', 'category': 'Category B'},\n", " {'name': 'Item 3', 'category': 'Category A'},\n", " {'name': 'Item 4', 'category': 'Category B'},\n", " {'name': 'Item 5', 'category': 'Category A'},\n", "]\n", "\n", "result = group_by_category(items)\n", "expected_result = {\n", " 'Category A': [\n", " {'name': 'Item 1', 'category': 'Category A'},\n", " {'name': 'Item 3', 'category': 'Category A'},\n", " {'name': 'Item 5', 'category': 'Category A'}\n", " ],\n", " 'Category B': [\n", " {'name': 'Item 2', 'category': 'Category B'},\n", " {'name': 'Item 4', 'category': 'Category B'}\n", " ]\n", "}\n", "\n", "assert result == expected_result" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestGroupByCategory:\n", " def test_group_by_category(self):\n", " # Test case 1: Group items by category\n", " items = [\n", " {'name': 'Item 1', 'category': 'Category A'},\n", " {'name': 'Item 2', 'category': 'Category B'},\n", " {'name': 'Item 3', 'category': 'Category A'},\n", " {'name': 'Item 4', 'category': 'Category B'},\n", " {'name': 'Item 5', 'category': 'Category A'},\n", " ]\n", " expected_output = {\n", " 'Category A': [\n", " {'name': 'Item 1', 'category': 'Category A'},\n", " {'name': 'Item 3', 'category': 'Category A'},\n", " {'name': 'Item 5', 'category': 'Category A'}\n", " ],\n", " 'Category B': [\n", " {'name': 'Item 2', 'category': 'Category B'},\n", " {'name': 'Item 4', 'category': 'Category B'}\n", " ]\n", " }\n", "\n", " # Act\n", " result = group_by_category(items)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_group_by_category_empty_input(self):\n", " # Test case 2: Empty input list\n", " items = []\n", " expected_output = {}\n", "\n", " # Act\n", " result = group_by_category(items)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_group_by_category_single_category(self):\n", " # Test case 3: Only one category present\n", " items = [\n", " {'name': 'Item 1', 'category': 'Category A'},\n", " {'name': 'Item 2', 'category': 'Category A'},\n", " {'name': 'Item 3', 'category': 'Category A'}\n", " ]\n", " expected_output = {\n", " 'Category A': [\n", " {'name': 'Item 1', 'category': 'Category A'},\n", " {'name': 'Item 2', 'category': 'Category A'},\n", " {'name': 'Item 3', 'category': 'Category A'}\n", " ]\n", " }\n", "\n", " # Act\n", " result = group_by_category(items)\n", "\n", " # Assert\n", " assert result == expected_output\n", "\n", " def test_group_by_category_no_category(self):\n", " # Test case 4: No category present in items\n", " items = [\n", " {'name': 'Item 1'},\n", " {'name': 'Item 2'},\n", " {'name': 'Item 3'}\n", " ]\n", " expected_output = {\n", " None: [\n", " {'name': 'Item 1'},\n", " {'name': 'Item 2'},\n", " {'name': 'Item 3'}\n", " ]\n", " }\n", "\n", " # Act\n", " result = group_by_category(items)\n", "\n", " # Assert\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Use the dict.setdefault() method to retrieve the list of items for a category. If the category doesn't exist in the dictionary, it will be added with an empty list as the default value. Append the current item to the list of items for the corresponding category.\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false }, "source": [ "### Accessing and Merging Dictionaries into a Single Dictionary" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def merge_dicts(*dicts):\n", " \"\"\"\n", " Merge multiple dictionaries into a single dictionary.\n", "\n", " Args:\n", " *dicts: Multiple dictionaries to merge.\n", "\n", " Returns:\n", " dict: The merged dictionary.\n", " \"\"\"\n", " merged_dict = {}\n", " for dictionary in dicts:\n", " for key, value in dictionary.items():\n", " if ____ in ____:\n", " if isinstance(value, dict) and isinstance(merged_dict[____], dict):\n", " merged_dict[____] = merge_dicts(merged_dict[____], value)\n", " elif isinstance(value, list) and isinstance(merged_dict[____], list):\n", " merged_dict[____].____(value)\n", " else:\n", " merged_dict[key] = ____\n", " else:\n", " merged_dict[key] = ____\n", " return merged_dict\n", "\n", "\n", "dict1 = {'a': 1, 'b': 2}\n", "dict2 = {'b': 3, 'c': 4}\n", "dict3 = {'c': 5, 'd': 6}\n", "\n", "result = merge_dicts(dict1, dict2, dict3)\n", "expected_result = {'a': 1, 'b': 3, 'c': 5, 'd': 6}\n", "\n", "assert result == expected_result" ] }, { "cell_type": "markdown", "metadata": { "jp-MarkdownHeadingCollapsed": true, "tags": [] }, "source": [ "
Check result by executing below... 📝
\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true }, "tags": [ "hide-input" ] }, "outputs": [], "source": [ "%%ipytest -qq\n", "\n", "class TestMergeDicts:\n", "\n", " def test_merge_two_dicts(self):\n", " # Test case 1: Merge two dictionaries\n", " dict1 = {'a': 1, 'b': 2}\n", " dict2 = {'b': 3, 'c': 4}\n", " expected_output = {'a': 1, 'b': 3, 'c': 4}\n", "\n", " result = merge_dicts(dict1, dict2)\n", "\n", " assert result == expected_output\n", "\n", " def test_merge_three_dicts(self):\n", " # Test case 2: Merge three dictionaries\n", " dict1 = {'a': 1, 'b': 2}\n", " dict2 = {'b': 3, 'c': 4}\n", " dict3 = {'c': 5, 'd': 6}\n", " expected_output = {'a': 1, 'b': 3, 'c': 5, 'd': 6}\n", "\n", " result = merge_dicts(dict1, dict2, dict3)\n", "\n", " assert result == expected_output\n", "\n", " def test_merge_nested_dicts(self):\n", " # Test case 3: Merge dictionaries with nested dictionaries\n", " dict1 = {'a': 1, 'b': 2}\n", " dict2 = {'b': 3, 'c': 4}\n", " dict4 = {'e': {'f': 7}}\n", " dict5 = {'e': {'g': 8}}\n", " expected_output = {'a': 1, 'b': 3, 'c': 4, 'e': {'f': 7, 'g': 8}}\n", "\n", " result = merge_dicts(dict1, dict2, dict4, dict5)\n", "\n", " assert result == expected_output\n", "\n", " def test_merge_dicts_with_lists(self):\n", " # Test case 4: Merge dictionaries with lists\n", " dict1 = {'a': 1, 'b': 2}\n", " dict2 = {'b': 3, 'c': 4}\n", " dict6 = {'h': [9, 10]}\n", " dict7 = {'h': [11, 12]}\n", " expected_output = {'a': 1, 'b': 3, 'c': 4, 'h': [9, 10, 11, 12]}\n", "\n", " result = merge_dicts(dict1, dict2, dict6, dict7)\n", "\n", " assert result == expected_output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": { "tags": [ "hide-input" ] }, "source": [ "
\n", " \n", "
👩‍💻 Hint\n", "\n", "Use nested loops to iterate over the dictionaries and their key-value pairs. Check if the key already exists in the merged dictionary using the in operator. Handle the conflict based on the types of values using isinstance().\n", "\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Acknowledgments\n", "\n", "Thanks to below awesome open source projects for Python learning, which inspire this chapter.\n", "\n", "- [learn-python](https://github.com/trekhleb/learn-python) and [Oleksii Trekhleb](https://github.com/trekhleb)\n", "- [ultimate-python](https://github.com/huangsam/ultimate-python) and [Samuel Huang](https://github.com/huangsam)\n", "- [learn-python3](https://github.com/jerry-git/learn-python3) and [Jerry Pussine](https://github.com/jerry-gitq )\n", "- [chatgpt](https://openai.com/product/chatgpt)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.5" }, "vscode": { "interpreter": { "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" } } }, "nbformat": 4, "nbformat_minor": 4 }