OnEvents as Functions then Functions inside of Functions

So OnEvents are functions and students love them. Now do they try to put them inside another in order to answer 2c? Is there another way to refer to these onEvent functions or are their names just whatever the name of the element? I am walking around and that’s the main thing I am seeing is lots of onEvents.

@carmichaelc

I told students that the event listeners are part of the API and therefore cannot be written about in Prompt 2C. I used the code in Stage 10’s Color Picker as an example of how the event listener calls a function I wrote which then calls other functions I wrote. BTW, this code could also be used to discuss abstraction.

onEvent(“button1”, “click”, function() {
checkCorrect(“button1”);
});
onEvent(“button2”, “click”, function() {
checkCorrect(“button2”);
});
onEvent(“button3”, “click”, function() {
checkCorrect(“button3”);
});
onEvent(“button4”, “click”, function() {
checkCorrect(“button4”);
});
function checkCorrect(buttonId) {
console.log("Checking: " + buttonId);
if (buttonId == randButtonId) {
console.log(“You got it!”);
updateScoreBy(1);
} else {
console.log(“WRONG”);
updateScoreBy(-3);
}
hideElement(“player1Win_label”);
hideElement(“player2Win_label”);
checkWinner();
setBoard();
switchPlayer();
}
function updateScoreBy(amt) {
if (currentPlayer == 1) {
p1Score = p1Score + amt;
setText(“score1_label”, p1Score);
} else {
p2Score = p2Score + amt;
setText(“score2_label”, p2Score);
}
}

Andrea

1 Like

I would remind students/clarify the directions for prompt 2c. They must paste their most complex algorithm, and it must integrate several mathematical and logical concepts.

Could someone take a look at this code? https://studio.code.org/projects/applab/UTMvIF53n3vXDVlArBtVXg He has onEvents inside a Function (Startover) I know this one doesn’t have logic. He has another - button1 where he combined a bunch of buttons, several with logic and math. Could this one be both his answer to 2C and 2D? Many of my students have one main algorithm that has it all. @baker

My suggestion would be to ask the student to create some functions and put the code that he has for updating the score or checking for game over in functions and call the functions from the event handlers. Questions 2c asks students to include an algorithm that integrates other algorithms and integrates mathematical and/or logical concepts. So it sounds to me that they need to have some math or logic and a function call inside a function. Then the same piece of code could be used to answer both 2c and 2d.

1 Like

Quick technical note. We don’t address it directly in the curriculum, but you can’t really embed event handlers inside a function. The event handlers are triggered no matter what. For the startover funciton in that student’s code, they’ve actually got it inverted. They should break out the code to startover into a separate function and then have two event handlers for the buttons that call the function. Here’s the diff…

Student’s code:

function startOver() {
  onEvent("playagainBtn", "click", function() {
    setScreen("startScrn");
    score = 0;
    lives = 3;
    setText("total_score", 0);
    setText("total_lives", 3);
  });
  onEvent("retryBtn", "click", function() {
    setScreen("startScrn");
    score = 0;
    lives = 3;
    setText("total_score", 0);
    setText("total_lives", 3);
  });
}

What it should be:

function startOver() {
 setScreen("startScrn");
    score = 0;
    lives = 3;
    setText("total_score", 0);
    setText("total_lives", 3);
}

onEvent("playagainBtn", "click", function() {
   startOver();   
});

onEvent("retryBtn", "click", function() {
  startOver();
});

The latter solution is “better” because you don’t have duplicate code to the startOver(). BTW this would be a GREAT example for abstraction.

Thank you both for clarifying. The students have gone crazy with buttons and are building amazing apps. I think they will get it. I know I do now!

First I think this totally counts as math and logic:

 onEvent("hitter", "click", function(event) {
    score = score - 1;       <----- MATH!
    setText("total_score", score);
    
    if (score == -3) {       <------ LOGIC!
      setScreen("lostScrn");
      setText("label9", score);
    }
  });

Second, I agree with @bhatnagars. Some of this code could be refactored and broken out into functions which would support abstraction along with algorithms. See the ColorSleuth project for similar examples. Exemplars are in (U5 L10 puzzle 23).

If you can break code that repeats out into a named function, that function is sort of like a little mini algorithm that you combine in your code. For example, Take the code above and break into:

 onEvent("hitter", "click", function(event) {
    changeScoreBy(-1);
    checkIfLost();
  });

 function changeScoreBy(amt){
     score = score + amt;   
    setText("total_score", score);
}

function checkIfLost(){    // would be better if this actually checked for both 
                                       // win and loss conditions and acted accordingly.  
                                      // I just refactored the student's code.
   if (score == -3) {   
      setScreen("lostScrn");
      setText("label9", score);
    }
}

To pseudo-quote Donald Knuth: “There may be bugs in the code above. I have only proved it correct, not tried it”

In some other forum post I also remarked on (1) the difficulty of identifying algorithms in event-driven programs, because any control flow logic, which is a typical candidate because it involves loops and if-statemetns, is embedded in the event-handling and (2) that it’s likely what you’ll want to identify as the algorithm and the abstraction may be the same piece of code, you just write about it differently. Again, I point to the ColorSleuth project as a perfectly acceptable low bar that meets the algorithm requirements

Thanks Baker. This is making it easier to explain.

@baker I am starting to go through the 79 projects to check code segments for citations. I am also using their projects for a 4th mp grade. I am still struggling with abstraction. I am pretty sure this student did not use abstraction. I hate to give them no credit at all. Could you look at their responses. What do you think? I repeated said no onEvents for algorithms too but they were too into making apps and could not understand they couldn’t use on events. See https://docs.google.com/document/d/1DTBhQlpkXFcTX26u2FdMtZtsuuMnCTnfuHxl3kLWAVk/edit

Hi, sorry. didn’t see this. Briefly, your student is using abstractions there (calling system functions) but they didn’t really develop any by my book. Fortunately, or unfortunately, I think the jury is out on whether/how this will be scored as abstraction by the college board. Argument for: the callback function of an event handler is (a) a function (b) does get repeated use because it can handle every occurrence of an event. Argument against: the student didn’t have to apply any abstract thinking skills to produce this solution - the callback function of an event handler is just how you have to do it to get interactivity in your app. I would want to see clearer demonstration that the student recognized an abstraction was needed and developed something beyond what’s built into the system.

Any easy example that I just personally ran into: I want two different events (let’s say two different buttons) to do the same thing. Rather than copy/paste my code once into each event handler, I should move that code into a new function, and then just have each event handler call that function. Make sense?

–B

Yeah, I thought so. So many of my students did this. I almost don’t want to use the design mode for next year unless I can get through to them. I am grading these after the 30th. I will probably be pretty lenient compared to the college board.

I have a question about this - I’m not super versed in event driven programming, but I’ve had students that have been really clever in doing this so that they can use parameters to make code a lot less repetitive.

Here’s what they’ve done:

Blockquote

//calling the color changing function
colorChange("#EFACAC",18,"#000000");

//the function of changing the color of the dropdwon input
function colorChange(backColor,fontSize,fontColor){
  //when the mouse up in the position dropdown, its background color would change to red, indicated the change of the condition
  //when the mouse up in the position dropdown, its font size would get more bigger, indicated the change of the condition
  //when the mouse up in the position dropdown, its font color would change more black, indicated the change of the condition
  onEvent("positionDropDown","mouseup",function(){
    setProperty("positionDropDown","background-color",backColor);
    setProperty("positionDropDown","font-size",fontSize);
    setProperty("positionDropDown","text-color",fontColor);
  });
  //when the mouse up in the ages dropdown, its background color would change to red, indicated the change of the condition
  //when the mouse up in the ages dropdown, its font size would get more bigger, indicated the change of the condition
  //when the mouse up in the ages dropdown, its font color would change more black, indicated the change of the condition
  onEvent("timePeriodsDropDown","mouseup",function(){
    setProperty("timePeriodsDropDown","background-color",backColor);
    setProperty("timePeriodsDropDown","font-size",fontSize);
    setProperty("timePeriodsDropDown","text-color",fontColor);
  });
}

Can anyone tell me if this is a sound way of coding? I’ve seen several students take down the amount of code they’ve needed by doing this.

Thanks in advance!

You can do that. It works.

The first question to ask is are they calling colorChange() more than once? If you call it more than once then you have more than one event handler on those two buttons. It works because they run in the same order you add them. The last one will set the color, font, font color that you see. Whatever color, font, font color set before that won’t be seen.

App Lab aficionados will advise against that for reasons that can cause misunderstanding or confusion.

  • If you have an event handler with a cumulative effect like say score++; then adding multiples of those will change how your program functions. Students may find that confusing.
  • App Lab Javascript is slow. It runs 200 times slower than any other Javascript. If you add lots of event handlers all doing the same thing you may find your program getting sluggish and not know why.
  • The code you cite as an example uses an advanced Javascript concept called closure. That isn’t covered in AP CSP.

If you just want to save on duplicate code you can do this

// indicate a selection was made by changing background color, font size and text color
onEvent("positionDropDown","mouseup", mouseupEventCallback);
onEvent("timePeriodsDropDown","mouseup",mouseupEventCallback);

function mouseupEventCallback (event) {
  setProperty(event.targetId,"background-color","#EFACAC");
  setProperty(event.targetId,"font-size",18);
  setProperty(event.targetId,"text-color","#000000");
}

Personally, I would not add that code at all. I would instead go into Design mode and make the top choice of the drop down be “Choose…”. I can see if a choice for all the drop downs was made without turning them all red. More importantly I can test if a choice was made from my program and pop up an appropriate error message.

Thanks so much, jdonwells! This makes tons of sense. I didn’t know about the event keyword and being able to use event.idName. I will definitely show students this so that they can cut back on code in a smart way.

I actually teach AP Comp Sci A, not the CS Principles. I really like how principles looks at how to apply computer science, but I’m not actually using the CS Principles curriculum. My background is almost solely in object oriented programming, so this idea of events still kinda blows my mind.

Thanks for the sample code - big help!