CSCI 141 Project 2: Part 1 (Project 2A)
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
CSCI 141 Project 2: Part 1 (Project 2A)
We already know that images are made up of pixels. We can represent pixels computationally with numbers. The simplest form of this is one number per pixel. If we consider black and white
images, the pixel value of 0 represents black and 255 represents white. On other color scales, 0 will represent one end of the color scale and 255 the other end.
We can randomly generate images by randomly generating pixel values. For example the 2D list of pixels: [[0,255,0,0,255,255,0,0]] produces this image in black and white:
Here’s the same image using a color map (a set of colors) called winter:
Image files can be large. We can compress them using a technique called run-length encoding (RLE). The idea behind this is that if we have several of the same pixel values in a row, we can represent them in a compressed form. Consider 8 black pixels: 0 0 0 0 0 0 0 0 – we could represent this as: B8 - one character for the value and one character for the count. The randomly generated pixel string above could be represented as B1W1B2W2B2 – as you can see the compression works better when there are longer runs, i.e. sequences of the same value. There are many different versions and implementations of RLE but we will use this one: a character for B or W and then an integer representing how many contiguous pixels of the value there are before the value changes.
Both of the examples given here are 8x1 (8 by 1) – that is 8 pixels by one pixel, i.e. one row of 8 pixels.
Assignment
You have been given a file called Project_2A.py that contains import lines for random and matplotlib, a constant called DIMENSION that represents the number of pixels per row and/or column of an image, and the constants B and W which correspond to the values 0 and 255 respectively, as well as several input lines, print lines, visualization code (see below), and comments to help you as you fill in your code. You will fill all of your code into this file, and you are not permitted to change the content of any of the lines given, though you will need to change the indentation of some of them.
Your task is to write a program that either decodes a small (8 x 1) image or generates a slightly larger (8x8) random image depending on user input. Your program will also display the image using a color map of the user’s choice. There are MANY ways to do this, but you are required to follow the specifications below. Read them carefully, and read through them AT LEAST TWICE before you begin formulating your code. You should expect to consult them many times while you are working. If you choose to complete this project in some other way, you may receive no credit for your work.
Task 1: Process the user’s choice
You have been given an input line that prompts the user to enter either: 1) a string of characters that represents pixels in an image (this should be 8x1 but may not be) or 2) the string 'random'.
Set up logic in your code to handle these two cases – there will ONLY be two cases. They will only either enter 'random' or a string that represents an image in the compressed format shown above – we will do some error checking to determine if the string actually represents an 8x1 pixel image later on in the project.
The code you write in Tasks 2 and 3 will fit inside of this logic. What this means is that your code should not look like this:
#my lines
for Task1
But might look something more like this:
#part of Task1
Use good programming style. What do we mean? Don’t have extraneous conditions. Don’t cast
variables that don’t need to be cast. Follow Python conventions. You should be writing a very small amount of code here.
Task 2: Randomly generated image
This task deals with the case where the user enters 'random' – you may choose to invert the order of this task and the next one. The code you write for this task will create a randomly generated 8x8 image (64 pixels) represented as a 2-dimensional list. Read the instructions carefully – this should require very few lines of code, but will require many more if you don’t follow the instructions.
Generate the 2-dimensional list as follows:
• Start with an empty list
• Generate a list of 8 randomly selected pixels – there is one very short and straightforward way to do this using the random module as discussed in class, and there are several much more difficult ways to do this if you choose to go in another direction
• Add the list you just made as an item to the empty list you created
• Repeat until you’ve created a total of 8 lists of 8 randomly selected pixels
A 2-dimensional list means a list that contains other lists, like this:
[[1,2,3],[4,5,6]]
The outer brackets in blue represent the list that contains two other lists – this is like your empty list that you add each new randomly generated list to. The lists shown in the black brackets are inside of the blue list – these are like the lists that you randomly generate.
Your result will be an 8x8 list, that is a list containing 8 individuals lists with 8 items each. The values of the items will be 0 and 255. Here is an example of what you might get (remember this is random, so your results will not match this):
[[0, 0, 0, 0, 255, 255, 255, 255], [255, 0, 0, 255, 255, 0, 255, 0], [255, 0,
255, 255, 255, 255, 0, 0], [255, 255, 0, 0, 255, 255, 0, 255], [255, 255, 255,
255, 255, 255, 0, 0], [255, 255, 255, 255, 255, 0, 255, 0], [255, 0, 255, 0, 255,
0, 255, 0], [255, 255, 0, 0, 255, 255, 0, 0]]
Notice that there are 8 lists of 8 items enclosed inside of another list. Store your result in a variable called pixels. You should use the print line provided to print out pixels. (Think carefully though – read task 3 and consider if you need to print pixels separately for each case….)
Be aware that for this task and all of the other tasks, you are not permitted to use append or any other string or list methods. Functions from the random module, built-in functions, indexing, and anything else we’ve actually covered in class as part of Module 2 are not methods.
Task 3: Processing an image string
The other option is for the user to enter a string representing an 8x1 pixel image, for example, 'B4W2B2'. We will assume that the user is always trying to do this, i.e., that they always enter a string with some Bs, Ws, and single digit integers in it, however, they might not get it exactly right in terms of specifying an 8x1 pixel image.
Read what follows carefully, it tells you exactly what to do. Remember: we can assume that all of the numbers in the string are single digit, e.g. 'B7W1'. We will never see something like
'B17W2'.
We will first do a quick check to make sure that the input looks reasonable – we would expect an even number of characters since they occur in pairs, one value (B or W) and one number (e.g. 2 or 4 etc.). As long as the user’s input has an even number of characters, we will proceed with decoding. If the user’s input DOES NOT have an even number of characters, print out the error message: 'Cannot process this input'. The message has already been provided for you in the skeleton file. Think carefully about how this might fit in with and/or change the logic you set up in Task 1.
In the case where we have an even number of characters, we will next decode the image. It should work like this:
• Start with an empty list
• Get the first two characters. In your actual implementation you might choose to get them one at a time instead of both at once. There are valid implementations that use both
approaches.
• Look at the first character in the pair, it will be B or W. Find the corresponding numerical value (0 or 255).
• Look at the second character in the pair, it will be a number. Add the 0 or 255 to the list the number of times specified by the number (i.e. the second character).
• Get the next two characters.
• Look at the first character in the pair, it will be B or W. Find the corresponding numerical value (0 or 255).
• Look at the second character in the pair, it will be a number. Add the 0 or 255 to the list the number of times specified by the number (i.e. the second character).
Stop when you run out of characters.
Here’s an example with some actual data. Suppose the input string is 'B4W2B2'
Get the first two characters: B4
Determine that the B represents 0
Add 0 4 times to the list. The list is now: [0,0,0,0]
Get the next two characters: W2
Determine that the W represents 255
Add 255 2 times to the list. The list is now: [0,0,0,0,255,255]
Get the next two characters: B2
Determine that the B represents 0
Add 0 2 times to the list. The list is now: [0,0,0,0,255,255,0,0]
There are no more characters so we stop.
In this example we ended up with 8 pixels. We know this because there are 8 items in the list. But the user could enter a string like this: 'B4W4B2' which would pass our initial check for an even number of characters but actually signifies more than 8 pixels.
So, we need to check one more thing. Did we actually get 8 pixels?
If the answer is yes, then we will take the list we created and put it inside of another list to make it two dimensional. This may seem weird, but we need the list to be 2D in order to draw it. This quite literally means put the list inside of another list. So if we have [0,0,0,0,255,255,0,0], we should end up with [[0,0,0,0,255,255,0,0]]. Do not overthink this. Here is me putting a 3 inside of a list:
3 #this is 3
[3] #this is 3 inside of a list
Here is me putting 4.56 inside of a list:
4.56 #this is 4.56
[4.56] #this is 4.56 inside of a list
Get the idea?
Make sure that the list you end up with is called pixels. Print out pixels.
If we didn’t get 8 pixels, but got more or less than 8 pixels, print out the error message: 'This does not contain 8 pixels' and set pixels to be an empty list. Print out pixels.
Notice that regardless of what happens, we print out pixels. How many print lines do we actually need for this?
Task 4: Visualizing the image
Phew - this is the end! So far, you’ve either generated a random image or processed an input string from the user, making sure it represented a valid 8x1 image. You then printed out whatever you ended up with for the image – a 2D list.
Nearly all of the code has already been provided for you. You are not responsible for writing code that uses matplotlib. Here is what you need to do:
• Check if pixels is empty (remember in Task 3 when we make pixels empty if the input string was not valid?)
• If pixels is not empty, run all of the code that is given in this block
• If pixels is empty, print out an error message: 'No valid data'
You should be writing two lines of code exactly. If you are writing more than that, then you are doing it wrong. You will not need to change the code given, but you should change the indentation of lines as needed.
When this code runs it will prompt the user to enter a color map (if pixels is not empty). There are many different colormaps available – you can see a full list here:
https://matplotlib.org/stable/tutorials/colors/colormaps.html
Examples of program execution
The auto-grader will check and score your program based on the printed output. If you do not use the print lines given, your code will fail the tests. The auto-grader will not run the image visualization part of your code. You will need to run that by executing your code from the command line. Here are some examples of what program execution including input lines, user input, and printed/displayed output looks like for some cases. Remember that the auto-grader WILL NOT check the visualization part of your code.
-random image generation
Enter an RLE string for an 8 by 1 image for decoding or random for a randomly generated
[[0, 0, 255, 0, 255, 255, 255, 255], [255, 0, 255, 255, 0, 0, 255, 0], [255, 0, 0, 255,
0, 255, 255, 0], [0, 255, 0, 255, 0, 255, 255, 255], [0, 255, 255, 255, 0, 0, 0, 0],
[255, 255, 0, 255, 0, 0, 0, 0], [255, 0, 0, 0, 255, 255, 255, 0], [0, 255, 255, 0, 255,
255, 255, 0]]
NOT IN GRADESCOPE, but on your computer, something like this will pop up:
-User entered string that is valid
Enter an RLE string for an 8 by 1 image for decoding or random for a randomly generated
[[0, 0, 255, 255, 0, 0, 255, 255]]
NOT IN GRADESCOPE, but on your computer, something like this will pop up:
-User entered string odd number of characters
Enter an RLE string for an 8 by 1 image for decoding or random for a randomly generated
No valid data
-User entered string even characters, not 8 pixels
Enter an RLE string for an 8 by 1 image for decoding or random for a randomly generated
No valid data
Task 5: Two short questions
You will submit a brief write-up with this project. In your write-up include answers to the following two questions. You may not receive assistance from consultants and TAs on these questions. The answers are straightforward if you understand the code you have written and you have read the instructions, looked at the examples, and considered the test cases provided in Gradescope. Your answers should be no more than 2-3 sentences.
1) When we do our initial check of the user entered string, we just check for an even number of characters. Why can’t we just check that the number of characters is 16 to verify the string? That is, why wouldn’t that work?
2) After our initial check, we process the user’s string and then we check that there are 8 pixels. Why do we have to check this separately? How is it that we could correctly process a user input string that passes the first check, but then it fails the second check?
SUBMISSION EXPECTATIONS
Project_2A.py Your implementation of the program as described above. No changes should be made to the lines of code that were already given to you in the file.
Project_2A.pdf A PDF document containing the answers to the two questions posed above, and your reflections on the project. You must also cite any sources you use. Please be aware that you can consult sources, but all code written must be your own.
N.B.: You must use the structures we have learned in this class so far to complete this assignment.
Implementations using structures we have not covered may receive no credit. Please note that
the assignment is not asking you to write functions. If there are def lines in your code anywhere, that is incorrect. This also means NO LIST AND STRING METHODS.
POINT VALUES AND GRADING RUBRIC
This part of the assignment is worth 20 of the 40 total points for Project 2. 13.5 of the points will be auto-graded and 6.5 points will be manually graded including the questions in the write-up. Be sure to test your code by running from the command line. Don’t rely only on the Gradescope tests.
Appropriateness |
RUBRIC FOR MANUAL GRADING Style |
Code uses current structures and modules discussed in class; meaningful variable names; commented as appropriate; any references used cited in write-up |
Follows Python style guidelines to include appropriate naming of variables, spacing, and use of single quotations; Proper use and naming of constants |
Only contains structures necessary to accomplish the task at hand; Uses the most concise implementation possible
Code uses structures and modules discussed in class; variable names meaningful; references cited in write-up
Code uses structures and modules discussed in class with minor additions from outside sources (e.g. string formatting) appropriately cited; most variable names meaningful
Code uses some structures and modules taken from outside sources with citations; variable names and code structure hard to decipher
Code uses structures and modules largely from outside sources only; variable names hard to decipher; code written in other programming languages or Python 2.7
Largely follows Python style guidelines but may be a few minor deviations
Several deviations from Python style guidelines; constants not used properly
Only loosely follows Python style guidelines
Code appears to have been written with no consideration for style
Only contains structures necessary to accomplish the task at hand; Implementation is generally concise
Contains a small number of unnecessary structures such as casts that are not needed; Implementation somewhat concise
Contains a large number of unnecessary structures such as unused variables and casts; Implementation somewhat concise but could be improved, code may be hard to follow
Contains many unnecessary
structures; Code is difficult to follow and overly verbose
2022-02-18