Lesson 3.12: Calling Procedures

Notes 1

Example (CollegeBoard Pseudocode; this is robot stuff)

PROCEDURE detourRight()
{
    ROTATE_RIGHT()
    MOVE_FORWARD()
    ROTATE_LEFT()
    MOVE_FORWARD()
    MOVE_FORWARD()
    ROTATE_LEFT()
    MOVE_FORWARD()
    ROTATE_RIGHT()
}

Practice 1 (Which is also 3.12 Hacks Part 1)

1) Pick the best procedure based on a real-life calculation: average speed = total time / total distance

i) PROCEDURE calcAvgSpeed (distance, time) { DISPLAY (distance/time) } ii) PROCEDURE calcAvgSpeed (distance) { DISPLAY (distance/time) } iii) PROCEDURE calcAvgSpeed (distance, time) { DISPLAY (time/distance) }

Notes

2) See the given procedure in CollegeBoard Pseudocode

PROCEDURE heightenEmotions(myEmotion)
{ moreEnergy ← CONCAT(myEmotion, "!!!")
moreVolume ← UPPER(moreEnergy)
RETURN moreVolume }

Context given: CONCAT concatenates two strings; UPPER converts string to uppercase only. Suppose the following was run:

heightenEmotions(“im mad”)

Will nothing be displayed?

This question is interesting because I cannot verify the existence of the command UPPER from the college board reference sheet. In fact, this resembles the upper() command from Python. For the purposes of the question, I’ll assume it exists and acts exactly as it does in Python (that is, it does not modify numbers, symbols, and spaces).

From the wording of the prompt “James Hunter then sees this line of code,” it is safe to interpret that the procedure was called after it was defined. As a result, it will execute normally. It will append 3 exclamation marks to the end of the im mad, make the letter characters all uppercase, and return this string to the caller. The procedure did not include any display commands, and there were no display commands after the code. Therefore, nothing will be displayed even though the code is running normally.

Answer: True.

3) This procedure calculates carbon footprint given a set number of miles and set number of passengers for a flight.

PROCEDURE calcFlightFootprint(numMiles, numPassengers) 
{
    CO2_PER_MILE ← 53.29
    carbonPerFlight ← numMiles * CO2_PER_MILE
    carbonPerPassenger ← carbonPerFlight / numPassengers
    RETURN carbonPerPassenger
}

This code will be used to calculate carbon footprint for one passenger on two flights: a 2451 mile flight with 118 passengers and a 3442 mile flight with 252 passengers. Which calculates the total foodprint?

1) totalFootprint ← calcFlightFootprint(2451, 118) + calcFlightFootprint(3442, 252) 2) totalFootprint ← calcFlightFootprint(2451, 118 + 3442, 252) 3) totalFootprint ← calcFlightFootprint((2451, 118) + (3442, 252)) 4)

laNyCarbon ← calcFlightFootprint(2451, 118) 
nyLondonCarbon ← calcFlightFootprint(3442, 252) 
totalFootprint ← laNyCarbon + nyLondonCarbon

Note: The miles parameter goes first, while the passengers parameter goes second. None of the options swap these parameters.

Options 2 and 3 feature strange inputs of the parameters. The parameters must be inputted with the number of miles first, with a comma, a space, then the number of passengers. For syntax, the parameters may not be inputted any other way. As such, options 2 and 3 will not execute the procedure properly.

Options 1 and 4 input the correct corresponding number of miles and number of passengers into the corresponding flights and use the procedure and operators to get the total carbon footprint. Option 4 provides greater clarity as to which flight is responsible for the majority of the carbon footprint through the use of variables for each flight, but both options calculate total carbon footprints successfully.

Notes 2

Practice 2

Example: an item receives a 20% discount then an 8% tax. Find the final cost for an $80 item.

PROCEDURE applyDiscount (cost, percentDiscounted) 
{
    temp ← 100 - percentDiscounted
    temp ← temp / 100
    cost ← cost * temp
    DISPLAY(cost)
    RETURN(cost)
}

PROCEDURE applytax(cost, percentTaxed) 
{
    temp ← 100 + percentTaxed
    temp ← temp / 100
    cost ← cost * temp
    DISPLAY(cost)
}

I fixed the display commands (previously python print() commands) and polished some variable names to ensure they correspond.

In this case, I would execute the commands in this order:

input ← applyDiscount(80, 20)
applytax(input, 8)

Where input will be equivalent to the output of the first command (assuming I’m running these one-by-one in a console and not using a script). If I was to run this as a script, I would be required to add a RETURN(cost) command to end of the applyDiscount procedure. The temp variable that is set to the output of applyDiscount must be distinct from any variables used in the procedures (otherwise, the output will override those variables permanently).

The final cost of the item is $69.12

Temperature: Use the procedure to convert 80 degrees Fahrenheit to Celsius

```PROCEDURE convert_Fahrenheit(temperature) { Celsius ← temperature - 32 Celsius ← Celsius * 5/9 DISPLAY(Celsius) }


I polished up a few issues, including spelling and removing spaces from the procedure name. Anyways, execution should be simple.

`convert_Fahrenheit(80)`

This converts to 26.6666666... degrees celsius.

# Lesson 3.13: Developing Procedures


### Notes 1

- Procedures can return values, execute statements, or both
- Procedures should have descriptive yet concise names
   - Know potential parameters (input)

There was an example I decided not to copy. I'll get on with the practice.

### Practice 1

1) Write a procedure to rotate a robot 180 degrees.

Of course this is pseudocode, so I'll be sure to follow the syntax.

PROCEDURE rotateBack() { ROTATE_RIGHT() ROTATE_RIGHT() }


2) Write a procedure to make the robot take a detour while moving left.

PROCEDURE leftDetour() { ROTATE_LEFT() MOVE_FORWARD() ROTATE_RIGHT() MOVE_FORWARD() MOVE_FORWARD() ROTATE_RIGHT() MOVE_FORWARD() ROTATE_LEFT() }


### Notes 2 (I'll see what I can do with this)

- Important to give each procedure a purpose.
- Using procedures is known as procedural abstraction
- Modularity: Separate a complicated program into simpler modules which can be re-used in varying parts of a program
- Procedures can have multiple functions


Example 1: Update a quiz grade based on a retake

PROCEDURE updateQuiz(quizAverage, currentScore, totalPoints) { tempAverage ← currentScore / totalPoints tempAverage ← tempAverage * 100 tempAverage ← round(tempAverage) IF(tempAverage > quizAverage) { quizAverage ← tempAverage } RETURN(quizAverage) }


This procedure checks if a retake percentage is greater than the first percentage. If so, the quiz grade is updated. A few notes of interest:
- The **round** command does not exist in the [CollegeBoard Pseudocode guide](https://apcentral.collegeboard.org/media/pdf/ap-computer-science-principles-exam-reference-sheet.pdf). For the purpuses of this exercise, I'll assume it functions equivalently to [Python's round()](https://www.w3schools.com/python/ref_func_round.asp).
- There is a logic error in this function, where the new grade is rounded before being compared to the old grade. As such, two scores of 87.5% (for example) would result in the new quiz score being rounded to 88% and inflating grades by at most 0.5% when no performance improvement was observed.

### Practice 2

![](/FastPage/images/fourweeksprint/zig.png "The exercise")

Given procedure: 

PROCEDURE moveSanta() { move_left() move_forward() move_forward() move_right() move_right() move_forward() move_forward() move_left() move_left() move_forward() move_forward() move_right() }

Note: the commands **move_left(** and **move_right()** do not exist. I'll have to come up with a new procedure which accomplishes the intended movements. I'll then execute code under the assumption that reaching the goal terminates execution.

directionList ← [“r”, “l”, “r”]

PROCEDURE zigZag() { FOR EACH item IN directionList { IF(item = “r”) { REPEAT 2 TIMES { ROTATE_RIGHT() MOVE_FORWARD() MOVE_FORWARD() } } ELSE { REPEAT 2 TIMES { ROTATE_LEFT() MOVE_FORWARD() MOVE_FORWARD() } } } }

ROTATE_LEFT() MOVE_FORWARD() zigZag()


This should start by rotating Santa left and moving him forward. The procedure has the character make L-shaped movements depending on the given directions. If the given direction is right, Santa will rotate right and move forward two times, which is effectively two spaces to the right and two spaces backward with perspective to the original direction. Having a left directional input works similarly, except all rotations are to the left.

# Hackathon

![](/FastPage/images/fourweeksprint/procedure1.png "Challenge 1")


This looks like a challenge of making procedures for line courses without repeating **MOVE_FORWARD()**

PROCEDURE forwardMarch(n) { REPEAT n TIMES { MOVE_FORWARD() } }

forwardMarch(5) ROTATE_RIGHT() forwardMarch(3)


Yeah, **forwardMarch(n)** is pretty simplistic. It moves forward the amount of times you want to. Useful if you want to avoid repeating **MOVE_FORWARD()** nine times. For the next challenges including the hacks, I will re-paste **forwardMarch(n)** since it will probably be very useful.

![](/FastPage/images/fourweeksprint/procedure2.png "Challenge 2")

Here I'll paste my procedure and also try something else. I'll always assume the initial direction is up.

PROCEDURE forwardMarch(n) { REPEAT n TIMES { MOVE_FORWARD() } } PROCEDURE moveRight() { ROTATE_RIGHT() MOVE_FORWARD() ROTATE_LEFT() }

moveRight() forwardMarch(5) moveRight() forwardMarch(3) ROTATE_LEFT() forwardMarch(2)


The **moveRight()** procedure does what you would think it does. It also preserves original directionality of the robot.


Here comes a grade challenge. Update the quiz score with these variables:
- Initial Score is 50%
- Retake is 56 of 60 points

This exercise is pretty much a repeat of the updating quiz scores procedure from the lesson. Given procedures are literally meant to be re-used in programs, I'll paste a procedure directly from my notes above (while getting rid of the rounding feature to remove logic errors). Kudos to CollegeBoard for making the procedure (yeah... it was in blocky, so they probably wrote it).

PROCEDURE updateQuiz(quizAverage, currentScore, totalPoints) { tempAverage ← currentScore / totalPoints tempAverage ← tempAverage * 100 IF(tempAverage > quizAverage) { quizAverage ← tempAverage } RETURN(quizAverage) }

newScore ← updateQuiz(50, 56, 60) DISPLAY(newScore)


I explained this procedure in my notes


# Final Hacks

### 3.12 Part 2: Basically pulling a bunch of old procedures from the first 3.12 practice but whatever

1) Find the output of the procedure (polished from the original for your convenience)

PROCEDURE find_a() { c ← 9 b ← 9 * 9 a ← b * c DISPLAY(a) }


Note: **c** is 9, and **b** is 9 times 9 or 81. **a** is **b** times **c**, or 9 times 81. This yields an output of 729. Note that the procedure was not called, however.

2) Find the output of the procedure (assuming it is called)

itemCost ← 173 tax ← 10 PROCEDURE applytax(cost, percentTaxed) { temp ← 100 + percentTaxed temp ← temp / 100 cost ← cost * temp DISPLAY(cost) } applytax(itemCost, tax)


Note: some variable names were changed to prevent conflicts. A line was also added to divide **temp** by 100 (second line in the procedure) to adjust percentages to decimals.

What this procedure does is adds the percent tax to 100 and divides by 100 to get the decimal form. It then multiplies the item's cost by this number to get the final cost, which is displayed. In this case, this calculates a 10% tax/price increase on a $173 item. I also executed the procedure. Running this block of code [here](https://board.dan.onl/) yields an output of 190.3

3) (no prompt given, but I would assume it is) Convert 103 degrees Fahrenheit to Celsius using the given procedure

Temper ← 103 PROCEDURE convert_Fahrenheit(Temper) { Celsius ← Temper - 32 Celsius ← Celsius * 5 / 9 DISPLAY(Celsius) } convert_Fahrenheit(Temper)


This procedure is clearly meant to convert Fahrenheit to Celsius. It uses two facts: 0 degrees Celsius is 32 degrees Fahrenheit, and that a 5 degree increase in Celsius is a 9 degree increase in Fahrenheit. To answer the question, 103 degrees Fahrenheit is 39.44444444... degrees Celsius.

### Hacks 3.13

1) `Create a procedure that is meant to replace the top running backs yards per game in one season if the current running back has more yards per game`

Gotta love that sports jargon. Honestly this doesn't make too much sense to me. But in a generic sense, there's a rate and a competitive scenario. Update the top rate if it's beaten. 

PROCEDURE updateTop(toprbyardspg, currentrbyards, totalGames) { temp ← currentrbyards / totalGames IF(temp > toprbyardspg) { toprate ← temp RETURN(toprate) } }

rate ← updateTop(100, 1260, 12) DISPLAY(rate)


2) Robot Problem 3

![](/FastPage/images/fourweeksprint/homework2.png "Challenge 3")

Not bad. The course was made in such a manner that I can't just use **forwardMarch(n)** to cheese the puzzle. It's not the end of marching though, since I could easily condense left and right marching into their own commands. I'll assume the initial direction is up (since this is not self-evident). Once I set up three procedures, this becomes very easy.

PROCEDURE forwardMarch(n) { REPEAT n TIMES { MOVE_FORWARD() } } PROCEDURE rightMarch(n) { ROTATE_RIGHT() forwardMarch(n) ROTATE_LEFT() } PROCEDURE leftMarch(n) { ROTATE_LEFT() forwardMarch(n) ROTATE_RIGHT() }

rightMarch(1) forwardMarch(2) rightMarch(3) forwardMarch(2) LeftMarch(2) MOVE_FORWARD LeftMarch(2)


**RightMarch(n)** essentially moves right for the specified number of squares (as the parameter), and **LeftMarch(n)** does something similar... but to the left instead. Both preserve original directionality.

3) How to define procedures in [CollegeBoard Pseudocode](https://apcentral.collegeboard.org/media/pdf/ap-computer-science-principles-exam-reference-sheet.pdf)?

Use a PROCEDURE name(param1, param2, param3)...

I assume the PROCEDURE is case-sensitive. As far as I know, you can name them anything you want (functionally), though it is recommended to name them descriptively and concisely.

Option A: PROCEDURE MYLIST
Option B: PROCEDURE MyList
Option C: procedure mylist

Option C has issues since **procedure** is not in all-caps; commands are often in all-caps in CollegeBoard Pseudocode. Options A and B have a difference of capitalization (and quite frankly this doesn't make a difference functionally, though variable names and function names are case-sensitive). Usually, the capitalization of B is followed with actual variables, making the first letter of each word capital. However, all the procedure commands fail to define parameters (or specify there are none using **()**)... so in all technicality, none of the options are correct (though B is the closest to convention).

4) Final robot challenge

![](/FastPage/images/fourweeksprint/homework4.png "Challenge 4")

Someone decided to make a convenient, straight path to the goal. Why not use it? As always, I'll assume the initial direction is up.

PROCEDURE forwardMarch(n) { REPEAT n TIMES { MOVE_FORWARD() } } ROTATE_LEFT() MOVE_FORWARD() ROTATE_RIGHT() forwardMarch(6) ROTATE_LEFT() forwardMarch(2) ```

We’re all getting the hang of this by now. This is simpler than exercise 3 and nothing new has been introduced. That’s it for this one I guess…