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