From 5d859372ceee4357960d3939195bb66866f57e3f Mon Sep 17 00:00:00 2001 From: AnaP2020 Date: Tue, 19 May 2026 12:35:44 +0100 Subject: [PATCH] Lab 1 extra unit 2 done --- lab-python-list-comprehension.ipynb | 510 ++++++++++++++++++++++++++++ 1 file changed, 510 insertions(+) create mode 100644 lab-python-list-comprehension.ipynb diff --git a/lab-python-list-comprehension.ipynb b/lab-python-list-comprehension.ipynb new file mode 100644 index 0000000..b2d37ad --- /dev/null +++ b/lab-python-list-comprehension.ipynb @@ -0,0 +1,510 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e", + "metadata": {}, + "source": [ + "# Lab | List, Dict and Set Comprehension" + ] + }, + { + "cell_type": "markdown", + "id": "6f8e446f-16b4-4e21-92e7-9d3d1eb551b6", + "metadata": {}, + "source": [ + "Objective: Practice how to work with list, dict and set comprehensions to improve the efficiency and clarity of your Python code." + ] + }, + { + "cell_type": "markdown", + "id": "7b3b329e-c56a-4009-b6f2-8849c02c0cb8", + "metadata": {}, + "source": [ + "Hint: If you're having trouble writing a solution using a comprehension, try writing it out in a more traditional way first. This can help you break the problem down into smaller steps and better understand what you need to do. Once you have a working solution, you can then try to transform it into a comprehension if desired. Comprehensions can often be more concise and readable, but it's important to prioritize clarity and correctness over brevity." + ] + }, + { + "cell_type": "markdown", + "id": "20c3e882-9625-471e-afb4-48a4f40c5d1b", + "metadata": { + "tags": [] + }, + "source": [ + "## Challenge 1 - Katas" + ] + }, + { + "cell_type": "markdown", + "id": "75f816bf-f5a2-49a4-89de-89d8a533155f", + "metadata": {}, + "source": [ + "Do the following katas using list, dict or set comprehension." + ] + }, + { + "cell_type": "markdown", + "id": "0cdcc026-2830-4db5-9ec3-76d71833df93", + "metadata": {}, + "source": [ + "### Katas - 1\n", + "\n", + "The Western Suburbs Croquet Club has two categories of membership, Senior and Open. They would like your help with an application form that will tell prospective members which category they will be placed.\n", + "\n", + "To be a senior, a member must be at least 55 years old and have a handicap greater than 7. In this croquet club, handicaps range from -2 to +26; the better the player the lower the handicap.\n", + "\n", + "**Input**\n", + "\n", + "Input will consist of a list of pairs. Each pair contains information for a single potential member. Information consists of an integer for the person's age and an integer for the person's handicap.\n", + "\n", + "**Output**\n", + "\n", + "Output will consist of a list of string values stating whether the respective member is to be placed in the senior or open category.\n", + "\n", + "**Example**\n", + "\n", + "```python\n", + "input = [[18, 20], [45, 2], [61, 12], [37, 6], [21, 21], [78, 9]]\n", + "output = [\"Open\", \"Open\", \"Senior\", \"Open\", \"Open\", \"Senior\"]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "21625526-3fae-4c55-bab5-f91940070681", + "metadata": {}, + "outputs": [], + "source": [ + "#two categories : Senior and Open\n", + "#Senior : 55 years old or more and handicap greater than 7\n", + "#Handicap ranges from -2 to +26 (inclusive)\n", + "#Input : list of pairs (age, handicap)\n", + "#Output : list of categories (Senior or Open)\n", + "#If age >= 55 and handicap > 7 : Senior\n", + "#Otherwise : Open\n", + "# Prompt for input\n", + "def age_handicap_data():\n", + " age_handicap_pairs = []\n", + " while True:\n", + " member_age = input(\"Enter your age: \")\n", + " member_handicap = input(\"Enter your handicap: \")\n", + " age_handicap_pairs.append(member_age + \",\" + member_handicap)\n", + " more = input(\"Do you want to enter another pair? (yes/no): \")\n", + " if more.lower() != 'yes':\n", + " break\n", + " participants = [[int(x), int(y)] for x, y in (pair.split(',') for pair in age_handicap_pairs)]\n", + " categories = [\"Senior\" if age >= 55 and handicap > 7 else \"Open\" for age, handicap in participants]\n", + " print(f\"input: {participants}\")\n", + " print(f\"output: {categories}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "20915efd", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "input: [[18, 20], [45, 2], [61, 12], [37, 6], [21, 21], [78, 9]]\n", + "output: ['Open', 'Open', 'Senior', 'Open', 'Open', 'Senior']\n" + ] + } + ], + "source": [ + "#input = [[18, 20], [45, 2], [61, 12], [37, 6], [21, 21], [78, 9]]\n", + "#output = [\"Open\", \"Open\", \"Senior\", \"Open\", \"Open\", \"Senior\"]\n", + "age_handicap_data()" + ] + }, + { + "cell_type": "markdown", + "id": "ad8758b7-bc71-4af8-999c-5e4def116906", + "metadata": {}, + "source": [ + "### Katas - 2\n", + "\n", + "If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.\n", + "\n", + "Write a solution so that it returns the sum of all the multiples of 3 or 5 below the number passed in. Additionally, if the number is negative, return 0.\n", + "\n", + "Note: If the number is a multiple of both 3 and 5, only count it once." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "c9b80d4a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "10\n", + "Sum of multiples (comprehension): 23\n" + ] + } + ], + "source": [ + "#Determine multiples of 3 or 5 below a given number.\n", + "#Ensure not to double-count numbers that are multiples of both 3 and 5.\n", + "#Handle negative numbers by returning 0.\n", + "number = int(input(\"Enter a number: \"))\n", + "Sum_of_multiples_comprehension = sum([i if i % 3 == 0 or i % 5 == 0 else 0 for i in range(1, number)])\n", + "print(number)\n", + "print(f\"Sum of multiples (comprehension): {Sum_of_multiples_comprehension}\")" + ] + }, + { + "cell_type": "markdown", + "id": "bed9c59d-159a-41c4-86c0-d02b131d7070", + "metadata": {}, + "source": [ + "### Katas - 3\n", + "\n", + "Given a non-negative integer, return an array / a list of the individual digits in order.\n", + "\n", + "Examples:\n", + "\n", + "```python\n", + "\n", + "123 => [1,2,3]\n", + "\n", + "1 => [1]\n", + "\n", + "8675309 => [8,6,7,5,3,0,9]\n", + "\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "a8cb1579-7065-4fc0-bd53-f91c2ad1dad9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Digits of the number: [2, 4, 5, 5, 6, 6, 8, 9]\n" + ] + } + ], + "source": [ + "# convert each digit of a given integer into an element of a list\n", + "number = int(input(\"Enter a number: \"))\n", + "digits_comprehension = sorted([int(digit) for digit in str(number)])\n", + "print(f\"Digits of the number: {digits_comprehension}\")" + ] + }, + { + "cell_type": "markdown", + "id": "ab3f6eaa-c74d-45fa-a84a-516ae6ff6e0f", + "metadata": {}, + "source": [ + "### Katas - 4\n", + "\n", + "Given a set of numbers, create a function that returns the additive inverse of each. Each positive becomes negatives, and the negatives become positives.\n", + "\n", + "```python\n", + "invert([1,2,3,4,5]) == [-1,-2,-3,-4,-5]\n", + "invert([1,-2,3,-4,5]) == [-1,2,-3,4,-5]\n", + "invert([]) == []\n", + "```\n", + "\n", + "You can assume that all values are integers. Do not mutate the input array/list.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86ebe759-76d8-4012-8590-c48a473a6099", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-1, -2, -3, -4, -5]\n", + "[-1, 2, -3, 4, -5]\n", + "[]\n" + ] + } + ], + "source": [ + "#list of integers.\n", + "#For each integer in the list:\n", + "#. If the integer is positive, make it negative.\n", + "#. If the integer is negative, make it positive.\n", + "#The function must return a new list, ensuring the original list is not mutated.\n", + "def invert(numbers):\n", + " inverted_numbers = [-n for n in numbers]\n", + " return inverted_numbers\n", + "\n", + "print(invert([1, 2, 3, 4, 5]))\n", + "print(invert([1, -2, 3, -4, 5]))\n", + "print(invert([]))" + ] + }, + { + "cell_type": "markdown", + "id": "3a9f2c20-48d2-4d08-a8c5-76bb53caaafb", + "metadata": { + "tags": [] + }, + "source": [ + "## Challenge 2 - exercises" + ] + }, + { + "cell_type": "markdown", + "id": "1c3bfaae-d514-4d9d-adab-59b66af621c9", + "metadata": {}, + "source": [ + "Do the following exercises using list, dict or set comprehension." + ] + }, + { + "cell_type": "markdown", + "id": "f5471e4a-a939-4626-9715-ad45f32c2487", + "metadata": {}, + "source": [ + "### Exercise 1\n", + "\n", + "Create a dictionary whose keys (`key`) are integers between 1 and 15 (both inclusive) and the values (`value`) are the square of the key (`key`)." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "6711881b-450a-44cb-a3d0-367b2c6a4464", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100, 11: 121, 12: 144, 13: 169, 14: 196, 15: 225}\n" + ] + } + ], + "source": [ + "# I have to use a loop to iterate through each number in the range 1 to 15.\n", + "# For each number, determine the square of that number.\n", + "#comprehension way\n", + "squares_comprehension = {i: i ** 2 for i in range(1, 16)}\n", + "print(squares_comprehension)" + ] + }, + { + "cell_type": "markdown", + "id": "47dafbe6-5f2c-4f51-94d9-ca52f6d11492", + "metadata": {}, + "source": [ + "### Exercise 2\n", + "\n", + "Write a program that takes two lists of integers, and returns a list of all possible pairs of integers where the first integer is from the first list, and the second integer is from the second list.\n", + "\n", + "Example:\n", + "\n", + "```python\n", + "Input: [1, 2], [3, 4]\n", + "Output: [(1, 3), (1, 4), (2, 3), (2, 4)]\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1d55cea-96c3-4853-8220-17c0904a8816", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]\n" + ] + } + ], + "source": [ + "# two lists of integers\n", + "# I have to use a loop to iterate through each number in the first list and a nested loop to iterate through each number in the second list.\n", + "# Return a list of tuples, with all possible pairs of integers where the first element of the tuple is from the first list and the second element is from the second list.\n", + "list1 = [1, 2, 3]\n", + "list2 = [4, 5, 6]\n", + "pairs_comprehension = [(x, y) for x in list1 for y in list2]\n", + "print(pairs_comprehension)" + ] + }, + { + "cell_type": "markdown", + "id": "03110a8a-0dd9-4eb4-b6ce-116233b4d6cf", + "metadata": {}, + "source": [ + "### Exercise 3\n", + "\n", + "Write a program that takes a dictionary of lists as input, and returns a list of all possible key-value pairs, where the key is from the dictionary, and the value is from the corresponding list.\n", + "Example:\n", + " \n", + "```python\n", + "Input: {\"a\": [1, 2], \"b\": [3, 4]}\n", + "Output: [(\"a\", 1), (\"a\", 2), (\"b\", 3), (\"b\", 4)]\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "0175239c-87fa-4ba0-8776-d62567256db7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[('a', 1), ('a', 2), ('b', 3), ('b', 4)]\n" + ] + } + ], + "source": [ + "# One dictionary with string keys and list os integers as values.\n", + "# I have to use a loop to iterate through each key-value pair in the dictionary and a nested loop to iterate through each integer in the list of integers.\n", + "# Return a list of all possible combinations of the string key and the integer value as a tuple.\n", + "my_dict = {\"a\": [1, 2], \"b\": [3, 4]}\n", + "combinations_comprehension = [(key, value) for key, values in my_dict.items() for value in values]\n", + "print(combinations_comprehension)" + ] + }, + { + "cell_type": "markdown", + "id": "0cd7ff45-52eb-409c-9805-f838cdd95cc1", + "metadata": {}, + "source": [ + "# Bonus exercises" + ] + }, + { + "cell_type": "markdown", + "id": "16d1e67a-6bd7-4932-a998-4542f06f029a", + "metadata": {}, + "source": [ + "### Exercise 1\n", + "\n", + "Write a program that takes a list of tuples, where each tuple contains two lists of integers, and returns a list of all possible pairs of integers where the first integer is from the first list in a tuple, and the second integer is from the second list in the same tuple.\n", + "\n", + "Example:\n", + "```python\n", + "Input: [([1, 2], [3, 4]), ([5, 6], [7, 8])]\n", + "Output: [(1, 3), (1, 4), (2, 3), (2, 4), (5, 7), (5, 8), (6, 7), (6, 8)]\n", + "\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "248918d0-f082-40a8-9d5c-c7b4ffd2bfca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[(1, 3), (1, 4), (2, 3), (2, 4), (5, 7), (5, 8), (6, 7), (6, 8)]\n" + ] + } + ], + "source": [ + "# A list of tuples\n", + "# Each tuple contains two lists of integers\n", + "# The function have to return a list of all possible pairs of integers\n", + "# The first integer is from the first list in a tuple and the second integer is from the second list in the same tuple.\n", + "list_of_tuples = [([1, 2], [3, 4]), ([5, 6], [7, 8])]\n", + "pairs_comprehension = [(x, y) for list1, list2 in list_of_tuples for x in list1 for y in list2]\n", + "print(pairs_comprehension)\n", + "#normal way\n", + "pairs = []\n", + "for list1, list2 in list_of_tuples:\n", + " for x in list1:\n", + " for y in list2:\n", + " pairs.append((x, y))\n", + "print(pairs)" + ] + }, + { + "cell_type": "markdown", + "id": "737478d3-2e93-445f-b732-00043f9e0541", + "metadata": {}, + "source": [ + "### Exercise 2\n", + "\n", + "Write a program that takes a list of strings, and returns a set of all possible pairs of characters where the first character is from the first string, and the second character is from the second string.\n", + "\n", + "Example:\n", + " \n", + "```python\n", + "Input: [\"ab\", \"cd\"]\n", + "Output: {('a', 'b'), ('c', 'd'), ('a', 'd'), ('c', 'b')}\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "c57d9e77-6859-45dd-a2e6-2c1898f1baa2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{('a', 'd'), ('a', 'c'), ('b', 'd'), ('b', 'c')}\n", + "{('a', 'd'), ('a', 'c'), ('b', 'd'), ('b', 'c')}\n" + ] + } + ], + "source": [ + "# A list of strings\n", + "# The function have to return a set of all possible pairs of characters\n", + "# The first character is from the first string in the list and the second character is from the second string in the list.\n", + "list_of_strings = [\"ab\", \"cd\"]\n", + "#normal way\n", + "pairs = set()\n", + "for char1 in list_of_strings[0]:\n", + " for char2 in list_of_strings[1]:\n", + " pairs.add((char1, char2))\n", + "print(pairs)\n", + "#comprehension way\n", + "pairs_comprehension = {(char1, char2) for char1 in list_of_strings[0] for char2 in list_of_strings[1]}\n", + "print(pairs_comprehension)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "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.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}