From 0a65bcc0e7b5ac43c1642a0b1dafda037c877054 Mon Sep 17 00:00:00 2001
From: Auke Klazema <klazema@astron.nl>
Date: Fri, 19 Nov 2021 15:25:56 +0100
Subject: [PATCH] Added example program to discuss

---
 IntroProgrammingInPython.ipynb | 297 ++++++++++++++++++++++++++++++---
 1 file changed, 275 insertions(+), 22 deletions(-)

diff --git a/IntroProgrammingInPython.ipynb b/IntroProgrammingInPython.ipynb
index be52844..0ac9382 100644
--- a/IntroProgrammingInPython.ipynb
+++ b/IntroProgrammingInPython.ipynb
@@ -386,7 +386,7 @@
    "source": [
     "## First broken programs\n",
     "\n",
-    "Your programs will be broken a lot, especially in the beginning, so lets see how to deal with that."
+    "Your programs will be broken a lot, especially in the beginning, so lets see how to deal with that. If your program is broken most of the time you will be confronted with an exception. Exceptions are a way of informing the user or programmer that something is wrong."
    ]
   },
   {
@@ -406,7 +406,7 @@
    "id": "95082acd-7c8b-4138-9189-84af128a0a93",
    "metadata": {},
    "source": [
-    "This program will give a NameError."
+    "This program will give a NameError exception."
    ]
   },
   {
@@ -426,7 +426,7 @@
    "id": "93564fff-c8c9-4059-89f2-82d29453f28e",
    "metadata": {},
    "source": [
-    "This program will give an IndentationError. Indentation is very important in a Python program."
+    "This program will give an IndentationError exception. Indentation is very important in a Python program."
    ]
   },
   {
@@ -446,7 +446,21 @@
    "id": "7b84478e-b8c8-48ad-b6b5-b29d4b21ad3d",
    "metadata": {},
    "source": [
-    "This program will give a SyntaxError"
+    "This program will give a SyntaxError exception."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d77d3d4e-f0ca-4df2-82b6-198bc61a3995",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#!/bin/env python3\n",
+    "\n",
+    "# lets raise some exception ourselves to tell that there is something wrong.\n",
+    "\n",
+    "raise Exception(\"Something is wrong\")"
    ]
   },
   {
@@ -1514,6 +1528,26 @@
     "print(hello)"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "6c95d9cf-4370-47b4-b6da-1933f0333a5e",
+   "metadata": {},
+   "source": [
+    "We can also generate strings by multiplying strings or characters. Very useful if you need a specific amount."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "606c5a7a-767e-43a7-81e0-04a2d17dae54",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print('+' * 79)\n",
+    "print('|', \" Hello \" * 11, '|', sep=\"\")\n",
+    "print('+' * 79)"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "ef7b8b6e-cf56-4e5f-ac49-528f88e1f183",
@@ -2167,7 +2201,7 @@
    "id": "d5ec52d1-7e41-4439-b4a8-a46caf0de825",
    "metadata": {},
    "source": [
-    "### Exercise\n",
+    "#### Exercise\n",
     "\n",
     "Create a program where you ask the user for a multiple items where you ask for some properties for each item. The properties can be stored in a dictionary and be added to a list. Print the list in the end. Try to use functions as well."
    ]
@@ -2199,7 +2233,9 @@
     "print(1 <= 2)\n",
     "print(1 >= 2)\n",
     "print(False is True)\n",
-    "print(False is not True)"
+    "print(False is not True)\n",
+    "print('a' in \"abc\")\n",
+    "print('A' in \"abc\")"
    ]
   },
   {
@@ -2339,6 +2375,27 @@
     "    print(\"Bye\")"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "30376e08-b2ce-4b07-8d69-c152d9ad28d1",
+   "metadata": {},
+   "source": [
+    "We can also negate a truth statement by using \"not\":"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a3e06ca4-510f-4a35-ba88-876a46209159",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "if not False:\n",
+    "    print(\"True\")\n",
+    "else:\n",
+    "    print(\"False\")"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "77804c8d-4a6b-4322-82a9-60696df3be31",
@@ -2369,7 +2426,7 @@
    "id": "97a513bc-26ba-471e-ae3a-67b674bde3a9",
    "metadata": {},
    "source": [
-    "### Exercise\n",
+    "#### Exercise\n",
     "\n",
     "Create a text menu with options. Let the user enter a selection and print something out specific for that option. Use the else to catch an option that you didn't provide. Think about uppercase and lowercase if you don't use numbers as options."
    ]
@@ -2418,7 +2475,7 @@
    "id": "102f9376-db7e-4beb-855c-bbbf36fde65e",
    "metadata": {},
    "source": [
-    "### Exercise\n",
+    "#### Exercise\n",
     "\n",
     "Create a program to calculate the Fibonacci series till a maximum of say 100. https://en.wikipedia.org/wiki/Fibonacci_number"
    ]
@@ -2449,11 +2506,125 @@
    "id": "f56444df-a1d6-4413-b1e7-ac0b259ad5be",
    "metadata": {},
    "source": [
-    "### Exercise\n",
+    "#### Exercise\n",
     "\n",
     "Loop over a list or tuple with numbers and print out the square of it. You could create a function for the square calculation if you want."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "0d2014c1-fc60-4af6-862c-a08cef58cbaf",
+   "metadata": {},
+   "source": [
+    "#### Range\n",
+    "\n",
+    "We sometime want to loop based up on a sequence of numbers. We can do this with a range."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c166c501-25ed-4cea-9e6b-f1849df8d090",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(range(5))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "eae49e01-f8b9-4571-a769-75badfd83765",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(list(range(5)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "870ec3b2-4adb-4be1-83b2-cd5e873e6df8",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for i in range(5):\n",
+    "    print(i)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "f77a3494-dcc3-41dd-827f-7145a550c7b7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "greeting = \"Hello World\"\n",
+    "\n",
+    "for i in range(len(greeting)):\n",
+    "    print(i, greeting[i])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "beb40a6a-2468-4fe5-8b9d-8dbd693365d9",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "greeting = \"Hello World\"\n",
+    "\n",
+    "for i in range(0, len(greeting)):\n",
+    "    print(greeting[i])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b7ebf73d-a58d-4ca5-8a00-b5519c847793",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "greeting = \"Hello World\"\n",
+    "\n",
+    "for i in range(0, len(greeting), 2):\n",
+    "    print(greeting[i])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ba7f4e9f-51c9-4516-975b-a6365aee1b86",
+   "metadata": {},
+   "source": [
+    "#### Enumerate\n",
+    "\n",
+    "We see that we had to do the indexing of the letter in the range examples. This is a repeating patter that used so often it got its own abstraction. Its the enumerate. It returns a tuple with the index and item."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "6f049e8a-3915-4dca-a37f-ceeda4261f89",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(enumerate(\"Hello\"))\n",
+    "print(list(enumerate(\"Hello\")))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "68e2e358-dbcd-4a24-a525-9ed5115a2b99",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "greeting = \"Hello World\"\n",
+    "\n",
+    "for i, char in enumerate(greeting):\n",
+    "    print(i, char)"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "0d025fb4-d651-431b-96fc-2605d2c18385",
@@ -2543,7 +2714,7 @@
     "\n",
     "angle = 44\n",
     "\n",
-    "if angle > 30 and angle < 180:\n",
+    "if angle >= 30 and angle <= 180:\n",
     "    turn_to(angle)\n",
     "else:\n",
     "    print(\"Unsafe angle:\", angle)"
@@ -2556,23 +2727,24 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "def turn_to(angle):\n",
-    "    print(\"Turning to angle:\", angle)\n",
-    "\n",
-    "def is_safe_angle(angle):\n",
-    "    return angle > 30 and angle < 180\n",
-    "\n",
-    "def report_unsafe_angle(angle):\n",
-    "    print(\"Unsafe angle:\", angle)\n",
-    "    \n",
-    "# ------------------------------------\n",
+    "MIN_ALLOWED_ANGLE = 30\n",
+    "MAX_ALLOWED_ANGLE = 180\n",
     "\n",
     "def turn_telescope(angle):\n",
     "    if is_safe_angle(angle):\n",
     "        turn_to(angle)\n",
     "    else:\n",
     "        report_unsafe_angle(angle)\n",
-    "        \n",
+    "\n",
+    "def is_safe_angle(angle):\n",
+    "    return angle >= MIN_ALLOWED_ANGLE and angle <= MAX_ALLOWED_ANGLE\n",
+    "\n",
+    "def turn_to(angle):\n",
+    "    print(\"Turning to angle:\", angle)\n",
+    "\n",
+    "def report_unsafe_angle(angle):\n",
+    "    print(\"Unsafe angle:\", angle)\n",
+    "    \n",
     "turn_telescope(angle=44)"
    ]
   },
@@ -2583,7 +2755,72 @@
    "source": [
     "## How to solve problems with programming\n",
     "\n",
-    "Breaking up and composing"
+    "In one small sentence its about breaking up the problem into pieces that can be solved and then composing the small solutions to bigger solutions until the main problem is solved. Easy right? Not really.\n",
+    "\n",
+    "Some problems can be solved by connecting existing solutions in libraries together. So for example I need to collect all the log files from all the servers running in Dwingeloo. There are libraries that can copy files from machines using SSH. So now we only need to know which servers are running in Dwingeloo. This could be a simple list we hard code. In that case we are almost done with a small loop over a list. We might need to think about when things go wrong. Server could be down. Network could have a glitch. The file might be locked. We could decide to ignore it because we run the script often enough and we don't mind a older file. But maybe we do care and we need to record any issues. Is it part of an automated system or can we report to a human that then can take action?\n",
+    "\n",
+    "Some problems are more of the type that does not have a library for it. Then we might need to implement our own algorithm or set of more detailed functions.\n",
+    "\n",
+    "Lets have a look at a relative simple problem of converting a string representing a binary number into a string that represents a hexadecimal number. We allow negative numbers. We raise an exception on empty strings.\n",
+    "\n",
+    "https://github.com/TheAlgorithms/Python/blob/master/conversions/binary_to_hexadecimal.py"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ce80b7da-75e3-42e1-a28e-9405a54094c0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def bin_to_hexadecimal(binary_str):\n",
+    "    BITS_TO_HEX = {\n",
+    "        \"0000\": \"0\",\n",
+    "        \"0001\": \"1\",\n",
+    "        \"0010\": \"2\",\n",
+    "        \"0011\": \"3\",\n",
+    "        \"0100\": \"4\",\n",
+    "        \"0101\": \"5\",\n",
+    "        \"0110\": \"6\",\n",
+    "        \"0111\": \"7\",\n",
+    "        \"1000\": \"8\",\n",
+    "        \"1001\": \"9\",\n",
+    "        \"1010\": \"a\",\n",
+    "        \"1011\": \"b\",\n",
+    "        \"1100\": \"c\",\n",
+    "        \"1101\": \"d\",\n",
+    "        \"1110\": \"e\",\n",
+    "        \"1111\": \"f\",\n",
+    "    }\n",
+    "\n",
+    "    # Sanitising parameter\n",
+    "    binary_str = str(binary_str).strip()\n",
+    "\n",
+    "    # Exceptions\n",
+    "    if not binary_str:\n",
+    "        raise ValueError(\"Empty string was passed to the function\")\n",
+    "    is_negative = binary_str[0] == \"-\"\n",
+    "    if is_negative:\n",
+    "        binary_str = binary_str[1:]\n",
+    "    if not set(binary_str) == {'0', '1'}:\n",
+    "        raise ValueError(\"Non-binary value was passed to the function\")\n",
+    "\n",
+    "    binary_str = (\n",
+    "        \"0\" * (4 * (len(binary_str) // 4 + 1) - len(binary_str)) + binary_str\n",
+    "    )\n",
+    "\n",
+    "    hexadecimal = []\n",
+    "    for x in range(0, len(binary_str), 4):\n",
+    "        hexadecimal.append(BITS_TO_HEX[binary_str[x : x + 4]])\n",
+    "    hexadecimal_str = \"0x\" + \"\".join(hexadecimal)\n",
+    "\n",
+    "    if is_negative:\n",
+    "        hexadecimal_str = \"-\" + hexadecimal_str\n",
+    "        \n",
+    "    return hexadecimal_str\n",
+    "\n",
+    "\n",
+    "bin_to_hexadecimal(input(\"Provide a binary number:\"))"
    ]
   },
   {
@@ -2621,6 +2858,22 @@
     "* Reddit /r/learnpython\n",
     "* Reddit /r/dailyprogrammer/"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cb10d0e1-165c-4025-926b-0fac27423f75",
+   "metadata": {},
+   "source": [
+    "# Bonus: Using files"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8642ab98-424f-4edb-9463-a40ba9e428f0",
+   "metadata": {},
+   "source": [
+    "# Bonus: Using libraries"
+   ]
   }
  ],
  "metadata": {
-- 
GitLab