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