{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "source": [
        "**Name:**\n",
        "\n",
        "**Date:**\n",
        "\n",
        "**Description of activity:**\n"
      ],
      "metadata": {
        "id": "sczaGya92i48"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Mount Google Drive\n"
      ],
      "metadata": {
        "id": "mv3Oarmb2zRK"
      }
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "1i3bvglG2d8z"
      },
      "outputs": [],
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/drive')"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Import Libraries"
      ],
      "metadata": {
        "id": "GXNipdi-3F1Z"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "from PIL import Image, ImageDraw, ImageFont\n",
        "from matplotlib import pyplot as plt"
      ],
      "metadata": {
        "id": "8Nmg8IhE3KfV"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Exercises\n",
        "\n",
        "In this activity you will gain practice defining your own functions, using the <code>range</code> function and <code>for loops</code> in Python through drawing on images and by changing the color of pixels in an image.\n",
        "\n",
        "**Testing the range function**\n",
        "\n",
        "The following code shows examples using each version of the <code>range</code> function.  Run this code.  (Note: The * before the range specifies that we want to see the contents of the list that gets created.)"
      ],
      "metadata": {
        "id": "MJ8VoPpTy-mD"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# 1-parameter\n",
        "print(*range(3))\n",
        "\n",
        "# 2-parameter\n",
        "print(*range(1, 4))\n",
        "\n",
        "# 3-parameter\n",
        "print(*range(1, 5, 2))\n",
        "print(*range(10, 0, -1))\n"
      ],
      "metadata": {
        "id": "8WMLzD5bAQxP"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Add your own range tests**\n",
        "\n",
        "Add statements to the Code cell above that uses the range function to print out the following lists of numbers:\n",
        "\n",
        "\n",
        "*   The numbers from 0 to 50, including 0 and 50.\n",
        "*The numbers from 1 to 10.\n",
        "*   The odd numbers between 0 and 100.\n",
        "*The even numbers from 100 down to 0 (including 0).\n",
        "\n",
        "\n",
        "\n"
      ],
      "metadata": {
        "id": "S6Mg9BgzAdC6"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Drawing Lines**\n",
        "\n",
        "The following code (from the [Pictures and Loops reading](http://www.cs.kzoo.edu/cs103/Readings/PicturesAndLoops.pdf)) defines a function that uses a loop to draw lines spaced 10 rows apart on an image.  Run this Code cell.  (If there are no errors you will not see anything happen yet, since we haven't invoked (called) the function with an actual image.)"
      ],
      "metadata": {
        "id": "ahvRleAABi5s"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def drawLines(picture):\n",
        "  # Duplicate the original picture\n",
        "  newPic = picture.copy()\n",
        "  d = ImageDraw.Draw(newPic)\n",
        "\n",
        "  # draw the lines\n",
        "  for y in range(0, newPic.height, 10):\n",
        "    # draw a line from the left edge of the image to the right edge, at row y\n",
        "    d.line([0, y, newPic.width -1, y], 'blue')\n",
        "\n",
        "  # Return the new picture\n",
        "  return newPic"
      ],
      "metadata": {
        "id": "peXqXT_jCcX-"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "We should now test that this function behaves like we think it should.  The next code segment creates an empty yellow image, then invokes the <code>drawLines</code> with this image.  The function returns the newly created image, without changing the original image."
      ],
      "metadata": {
        "id": "a92yyIooCzeW"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "myImage = Image.new('RGB',(300,300),\"Yellow\")\n",
        "myImage.show()\n",
        "newImage = drawLines(myImage)\n",
        "newImage.show()"
      ],
      "metadata": {
        "id": "FOgwUiHNzInJ"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Showing images together and saving images**\n",
        "\n",
        "Sometimes it will be nice to show the original image side-by-side with the new image.  To do this, we will think of the images as graphs and will plot them next to each other.  The following code creates a plot with two images as subplots.  (It shows the images side-by-side.). The subplots function allows us to specify how many rows and columns will be in the figure.  Lines 2 and 3 will show the images, and line 4 will save the figure in your Google drive.  You should replace the path in line 4 with the path to your CS103 folder on your Google drive."
      ],
      "metadata": {
        "id": "sgDLeqxCDxDQ"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "fig, pics = plt.subplots(1,2)\n",
        "pics[0].imshow(myImage)\n",
        "pics[1].imshow(newImage)\n",
        "fig.savefig('/content/drive/MyDrive/ColabNotebooks/pairOfPics.jpg')"
      ],
      "metadata": {
        "id": "Uo4Tn4TGDyJX"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Experiment with drawing lines**\n",
        "\n",
        "Modify the <code>drawLines</code> function above so that instead of drawing lines 10 rows apart, it draws lines in every other row.  What does the result look like?  (After modifying the function, you will need to run that Code cell again, and then also run the Code cell with the statements to test the function again.)\n",
        "\n",
        "Modify it again to draw lines 20, or 30, or 50 (or choose your own value bigger than 10) pixels apart.  What does the result look like?"
      ],
      "metadata": {
        "id": "HUjKXo8JzhiZ"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Write your own function**  \n",
        "\n",
        "In the Code cell below, define a new function, <code>drawVertLines</code> that draws vertical lines on an image, spaced 10 pixels apart.  The function should take a picture as a parameter.  It should copy the original picture into a new picture, and then draw on the new picture.  It should then return the new picture.  Think about how you might copy the <code>drawLines</code> function and modify it to draw vertical lines instead of horizontal lines.  How will the endpoints of the lines change?  How will the <code>range</code> change?\n",
        "\n",
        "\n",
        "\n"
      ],
      "metadata": {
        "id": "lGhTaVgZ0AHx"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# This following code defines a function to draw vertical lines on a picture\n",
        "# PUT YOUR CODE HERE"
      ],
      "metadata": {
        "id": "INL6ahJQzfXH"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Here you should test your function. Replace the lines below with real code.\n",
        "# CREATE A NEW IMAGE\n",
        "# CALL YOUR NEW FUNCTION ON THIS IMAGE AND SAVE THE RESULT IN A VARIBLE\n",
        "# SHOW THE ORIGINAL IMAGE AND THE NEW IMAGE"
      ],
      "metadata": {
        "id": "4jVEynKV8vqK"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Combining functions**\n",
        "\n",
        "In the Code cell below, define a new function, <code>bothLines</code>, that draws horizontal and vertical lines on a picture.  This function should take a picture as a parameter.  It should first copy the original picture and save it in a new variable.  Then it should call the <code>drawLines</code> function on this new (copied) picture, saving the picture that the function returns into another new variable, say <code>newPic1</code>.  It should then call the <code>drawVertLines</code> on this new variable, saving the result in another new variable, say <code>newPic2</code>.  The function should then return this last result.\n",
        "\n",
        "Then add another Code cell to test this function.  To test this function, create a new picture and call the <code>bothLines</code> function, passing it your new picture.  You should save the result of the <code>bothLines</code> function call in a new variable.  Then show the resulting picture.\n"
      ],
      "metadata": {
        "id": "mJ27vuhd1aBO"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# Define your function here"
      ],
      "metadata": {
        "id": "qDuagMJSU8wE"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "# Test your function here"
      ],
      "metadata": {
        "id": "xq4oHfcGVFXR"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Experiment with making the functions more general**\n",
        "\n",
        "Modify the <code>drawLines</code> and <code>drawVertLines</code> functions above so that the user can specify how far apart they would like the lines, and what color they would like the lines.  These two functions should take the spacing of the lines and the color as additional parameters.  (The functions will each now have 3 parameters instead of 1.) You should use the spacing parameter in place of the step of 10 in the range, and you should use the color parameter in place of the <code>'blue'</code> in the <code>line</code> function.  Remember that when you test your functions, you will also need to pass three values to the functions, a picture, a spacing value, and a color value.  (So the call to the <code>drawLines</code> function might look something like <code>funPic = drawLines(myPic, 25, 'purple')</code>.)\n",
        "\n",
        "Experiment with different spacings and colors.\n"
      ],
      "metadata": {
        "id": "1LWncgOz85L6"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Drawing lines by modifying pixels**\n",
        "\n",
        "Now that we are stsrting to get familiar with using the range function and working with loops, let's draw lines by modifying individual pixels in a picture.\n",
        "\n",
        "The following function (from the reading) changes the first 20 pixels in row 5 to black.  Run the Code cell to define the function and then run the Code cell to test the function.  Do you see the little line in the upper left corner?\n"
      ],
      "metadata": {
        "id": "xH4tZdeNWyK8"
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def makeSomeBlack(picture):\n",
        "  # duplicate the original picture\n",
        "  newPic = picture.copy()\n",
        "\n",
        "  # change the pixels\n",
        "  for x in range(20):\n",
        "    newPic.putpixel((x,5), (0,0,0))\n",
        "\n",
        "  # return the new picture\n",
        "  return newPic"
      ],
      "metadata": {
        "id": "Qe5Pb2C_0VoN"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "myImage = Image.new('RGB', (200,200), 'aqua')\n",
        "newImage = makeSomeBlack(myImage)\n",
        "newImage.show()"
      ],
      "metadata": {
        "id": "plnkTS42X8Z8"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "How would you make this line go all the way across the picture?  Modify the range to make this happen and run the test again.  If you didn't get the result you expected, modify your function again.\n",
        "\n",
        "How would you make this line go halfway across the picture?  Modify the range to make this happen and run the test again.\n",
        "\n",
        "**Analysis Question:** What happens if you replace the (0,0,0) in the <code>putpixel</code> function call on line 7 with <code>'black'</code>?  (Put your answer here)"
      ],
      "metadata": {
        "id": "id0HARjpYRWe"
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "**Draw a vertical line by changing pixels**\n",
        "\n",
        "In the Code cell below, define a new function <code>verticalLine</code> that draws a vertical line on a picture, with the column and color specified by the user. This new function will take a picture, a column number, and a color as parameters. It should duplicate the original picture, use a loop to change pixel colors, and then returns the resulting image. Then test your function and show your result.  Remember that the <code>putpixel</code> function need the color to be specified as a tuple with red, green, and blue values."
      ],
      "metadata": {
        "id": "Xu8P3rx5_vYL"
      }
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "W8EpLFR8A4Up"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "**(OPTIONAL) If you have time**\n",
        "\n",
        "Instead of drawing on a blank images, try testing your new function on an image that you have on your computer instead of new blank images.  \n",
        "Remember, to use an image from your computer, you will need a statement similar to <code>myImage = Image.open(\"/drive/My Drive/CS103Labs/someImage.jpg\")</code> to open your image.\n",
        "\n"
      ],
      "metadata": {
        "id": "7Su4WNMTDhWg"
      }
    },
    {
      "cell_type": "code",
      "source": [],
      "metadata": {
        "id": "M9S7-YYQEdsW"
      },
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Saving and Submitting\n",
        "\n",
        "Once you have created results that you are pleased with, go to Runtime and choose Run all.  Skim through your notebook and make sure everything looks the way you expect.  If it all looks good, save this notebook as a .ipynb file.  (Go to Download -> Download .ipynb)\n",
        "\n",
        "Submit your .ipynb file on Kit."
      ],
      "metadata": {
        "id": "m8jTI0_OBDRM"
      }
    }
  ]
}