{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assume <b>L</b> is a list with at least two elements. Which of the following program finishes with <b>L</b> having the same elements in the same order it had at the beginning of the program? Comment your answers "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "L.append(3)\n",
    "L.pop()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x=L.pop()\n",
    "L.append(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x=L.pop()\n",
    "y=L.pop()\n",
    "L.append(x)\n",
    "L.append(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x=L.pop()\n",
    "y=L.pop()\n",
    "L.append(y)\n",
    "L.append(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Lists"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a list, called \"Numbers\". Let it contain the numbers 10, 25, 40, and 50."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print the second element from the list.\n",
    "<br>Note that \"second\" means \"second\" in English, not in Pythonic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print the second-last element. Suppose that you do not have any idea of the length of Numbers and cannot use len function (*this  clarification is written because several of you enjoy themselves perverting any easy and straightforward way of solving this task*)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Substitute the number in the first position (in English, not in Pythonic) with the string \"blabla\". Use only one statement (*also this one is here because students pervert my requests :-(*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Delete the number in second position (always English and not Pythonic) from the Numbers list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List Slicing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Slicing is a technique which can be applied to strings and to lists to extract a part of them, exactly the same that you do for strings. \n",
    "<br>You just specify two numbers separated by a colon and get the elements from the index of the first number and up to the second one excluded. If the first number is omitted it is assumed to be 0. If the second number is omitted it is assumed to be the length of the list/string. If a number is negative, it counts from the end (-1 is the last one, -2 is the second last one)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "Numbers = [15, 40, 50, 100, 115, 140]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using list slicing, obtain the numbers 100 and 115."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using slicing, extract the first four elements from the list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using slicing, extract all the elements from the list from the 3rd position (in English, not Pythonic) onwards. Suppose that you do not know the length of the list and cannot use the len function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using slicing, extract the last 4 elements from the list supposing that you do not know how many elements does the list have and cannot use the len function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which is the position of the value 15? I want a program telling it, not you."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a list, called \"Two_Numbers\". Let its elements be the values 1 and 2. Then, create a new one, named \"All_Numbers\", that will contain all the elements from both the \"Numbers\" and the \"Two_Numbers\" lists together (not a list of lists)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using the <b>.sort</b> method, sort all the numbers in the \"Numbers\" list from the largest to the smallest."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Append the number 100 to the Numbers list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Numbers = [15, 40, 50]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With the help of the <b>.extend</b>, add the numbers 115 an 140 to the list."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print \"The fourth element of the Numbers list is:\" followed by the value of the fourth element. Do this <b>using two different print instructions</b>, but the <b>output must stay only on one line</b>. \n",
    "<p><font color=PURPLE>Click here for a little suggestion\n",
    "    <details>Remember the <b>end=</b> parameter for print function</details>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "How many elements are there in the Numbers list? I want a program telling it, not you."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loops"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a For loop that prints every digit on a new line."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "digits = [0,1,2,3,4,5,6,7,8,9]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Adjust the code, so the digits are all printed on the same line."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the range() function to create a list with all numbers from 1 to 10."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the range() function to create a list with all numbers from 0 to 19."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use the range function to create a list with all even numbers from 0 to 30 included."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a For loop that will print all the variables from a given list multiplied by 2. Let the list contain all numbers from 1 to 10. Create it with the help of the range() function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create a little program that runs a loop over all values from 1 to 30. Let it print all Odd numbers, and in the place of the even numbers, it should print \"Even\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You have the following list of numbers. Iterate over this list, printing out each list value multiplied by 10. Find two solutions of this problem, one with while and one with for."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "n = [7,12,23,14,-5,6]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You are provided with the 'nums' list. Use a loop to count the number of values lower than 20, without using method **.sort()**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "nums = [1,200,12,3,24,31,33,51,70,-4,100]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create function <font color=BLUE>myAverage</font> that accepts as parameter a list and a limit. It calculates the average of the list for the values below the limit. The function must warn the user through a print command in case there are no elements for the average and in this case it does not return anything."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Build a loop that goes through this list of strings and prints a <b>string</b> with all the strings, with a length smaller than 5, <b>concatenated</b> together.\n",
    "\n",
    "<font color=PURPLE>Strategy: set up an empty string. Loop and when an element has the correct length concatenate it to your string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "s = [\"Sebastian\", \"John\", \"Jack\", \"Federica\", \"Mara\", \"Philip\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Build a for loop which counts the amount of strings with length equal to 4 and if there is at least one it prints \"Urrah\" one time only. The \"Urrah\" must be printed inside the loop (it is too easy to print it after). Then it prints the number of strings with legth equal to 4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### findElement"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a function <font color=BLUE>findElement</font> that takes as input a list of elements (can be strings, int, whatever) and an element (can be any type) and returns the index of the first position of that element in the list. As usual, it should return -1 if the element is not in the list. \n",
    "<br>Write <b>two</b> functions, one which uses while loop and another one which uses for loop.\n",
    "<br>Do not use the <b>.index(< Number>)</b> method and do not use the <b>in</b> operator to check whether something is inside the list (you may still use it for a for loop).\n",
    "    \n",
    "For example, findElement([\"Albert\",\"John\",\"Mara\"],\"Mara\") returns 2 and find([7,0,\"blabla\",6.7],\"bloblo\") returns -1.\n",
    "\n",
    "<p><font color=PURPLE>Strategy: As usual, think how would you solve it manually, without worrying about the -1 and without worrying about which kind of loop do you use (probably starting with while is much easier).  There are dozens of different ways to solve it. Do it really!!! Once you have written it, fix it for the case in which the element is not in the list, also here there are several ways for doing it. And finally convert the loop into the other type and see which one is easier in this case."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## index method and in operator"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In Python there exist list method **.index(e)** which accepts as parameter an element and returns the position of that element in the list. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n"
     ]
    }
   ],
   "source": [
    "L=[3,7,2,0]\n",
    "print(L.index(7))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Unfortunately this method gives an error whenever the element is not in the list (try please). But luckily there exist operator **in** which returns a boolean telling you whether an element is in a list and operator **not in** which returns exactly the opposite. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "L=[3,7,2,0]\n",
    "print(7 in L)\n",
    "print(8 in L)\n",
    "print(8 not in L)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that you know these method and operators, rewrite function <font color=BLUE>findElement</font> using them instead of using a loop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Union"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Define a function <font color=BLUE>Union</font> which takes as input two lists A and B and returns a list consisting in the union of the two lists without insering the duplicated elements twice. The function must skip also the duplicated elements in the same list.\n",
    "\n",
    "For example, Union([1,2,3,4],[4,9,2,7]) should return [1,2,3,4,9,7] and  Union([1,1,1,2],[3,3,3,2]) should return [1,2,3]\n",
    "\n",
    "<p><font color=PURPLE>Strategy: As always, think at how would you, human, solve it on paper. Write down all the steps slowly, one by one, carefully, with easy steps that a stupid computer can do using the tools described above without any superior knowledge or intuition. Do it really, or you will produce a mess or a highly inefficient program. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Determine **Union**'s complexity supposing that the two lists have length N and M.\n",
    "\n",
    "Supposing that checking whether element <b>x in L</b> has a complexity equal to <b>len(L)</b> comparisons (you are not required to use the <b>in</b> operator, I write here its complexity in case you do), while <b>for x in L</b> does not have any complexity (in fact in this case it goes through the elements and it is much easier that a <b>x in L</b>). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### splitting strings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font color=ORANGE><b>DIFFICULT and OPTIONAL</b></font>\n",
    "\n",
    "Without using the .split() method, define a function <font color=BLUE>splitString</font> that takes as input a string and splits it at any ortographic symbol (space, comma, point, question mark, exclamation mark, semicolon, colon). It returns the split words into a list.\n",
    "<br>For example: splitString(\"This is my day! Why? Not: this isn't\") returns [\"This\",\"is\",\"my\",\"day\",\"Why\",\"Not\",\"this\",\"isn't\"]\n",
    "<p><font color=PURPLE>Strategy: after having thought at the problem, if you can't come up with a working algorithm click below to reveal it. I said <b>after having thought</b>\n",
    "<details>Do I have to say it? Think how you would do it on paper. Even better, do it slowly slowly on paper, imagining that you were so dumb that you could look only at one character at the time. Then do it again. TAnd then again, until you have a method which works for a 2 years old child. Perhaps it can be helpful bulding a function that takes as input a character and returns True whenever it is an ortographic symbol. At the beginning do not worry too much about what happens when you have twoconsecutive ortographic symbols, you will deal with it at the end.\n",
    "    \n",
    "I have a YouTube video which explains this with pencil and paper: https://youtu.be/mz-B9TUeeG8</details>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Lists are objects"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Suppose that **R** is a list with at least 2 elements. What do these functions do to list **R** outside the function? Justify your answer.\n",
    "\n",
    "Warning: these exercises are not easy, many students answer wrongly. Think carefully at how the pointers work and which objects are in the memory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def proc1(p):\n",
    "    p[0]=p[1]\n",
    "proc1(R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "def proc2(p):\n",
    "    p=p+[1]\n",
    "proc2(R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "def proc3(p):\n",
    "    q=copy.deepcopy(p)\n",
    "    q.pop()\n",
    "    p=q\n",
    "proc3(R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def proc4(p):\n",
    "    q=p\n",
    "    q.append(3)\n",
    "proc4(R)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "..."
   ]
  }
 ],
 "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.8.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
