My Assistant explainer

The aim of this puzzle: Use a callback function to change what task myAssistant does.

Walkthrough of the solution: myAssistant is a function that takes 2 inputs: a string that will be stored in the time parameter, and another function that will be stored in the callbackFunction parameter.

When you use a function as the input of another function, it’s called a “callback function” or just a “callback”. This is different from nesting functions like you did with print(pickRandom(10)) or drawBox(pickrandom(color)) becuase the print() and drawBox() are really only using the final output of the pickRandom() call. The assistant is taking the name of the function so that it can run that function inside itself.

The starter code has the command myAssistant('6pm', recordShow). recordShow is the name of a function that’s created in some additional hidden code. '6pm' will be stored in the time parameter, and recordShow will be stored in the callbackFunction parameter.

When myAssistant() runs, it logs a message letting you know it’s started. Then it uses its parameters, time and callbackFunction, to run the command callbackFunction(time). Since we know what’s stored in each of those parameters, the command is the same as recordShow('6pm'). This will call the recordShow() function with the argument '6pm'.

At the bottom of your code, you can make the assistant “set an alarm” or “turn on the lights” by using setAlarm or turnOnLights as the callback function. Just remember that the 1st argument of myAssistant() should be the time (a string) and the 2nd argument is the name of a function (either setAlarm or turnOnLights)

Sample code solution:
(Tap below to reveal)

function myAssistant (time, callbackFunction) {
  console.log('I am your personal assistant, and I am happy to help with your request');
  callbackFunction(time);
}
myAssistant('6pm', recordShow);
myAssistant('10am', setAlarm);

JavaScript Concepts: Callback Functions, Calling Functions, Code Block (function), console.log()

Additional Code (hidden code that runs before the puzzle’s code):

function setAlarm(time) {
    console.log('Your alarm has been set for ' + time);
}
function turnOnLights(time) {
    console.log('Your lights will be turned on at ' + time);
}
function recordShow(time) {
    console.log('Your show will be recorded at ' + time);
}
3 Likes

Did the tutorial, but none of it made sense. Honestly, none of the function tutorials have made any sense so far. I’ve just been filling in answers as expected.

I don’t get recursive gunctions, I don’t understand the idea of calling one function with another function like in the tutorial.

Is just frustrating.

What does this even mean? :frowning:

2 Likes

This puzzle actually doesn’t have recursion, but it does use a callback (using a function name as an argument).

“The assistantmyAssistant function is taking the name of the functionsetAlarm, turnOnLights, or recordShow so that it can run that functionsetAlarm, turnOnLights, or recordShow inside itselfthe myAssistant function.”


When you create a function:

function sayThings() {
  print('hi');
}

It can be used in 2 ways:

  1. sayThings() : Normal function call. It will run all the code inside the block {} of the sayThings() function definition
  2. sayThings : Used as a callback. Without the parentheses, the sayThings is used like a variable that stores all the information about the function, but doesn’t run it. You want a function in its “variable form” when it’s being used an an argument in some other function.

In this puzzle, setAlarm, turnOnLights, and recordShow are all functions. They could be used directly if you put parentheses after them: setAlarm('1pm') will output 'Your alarm has been set for 1pm'.



Extra info about different ways to combine functions:


drawBox(pickRandom(color))

The pickRandom() function will use the color variable as input, and then output some color as a string. That string is fed directly into drawBox() as input, and then drawBox() outputs a colored box.


function twoBoxes() {
  drawBox('black');
  drawBox('white');
}
twoBoxes();

The twoBoxes() function doesn’t use any inputs, but when you run it using twoBoxes() it will call drawBox() twice. You can imagine replacing twoBoxes(); with the code inside the block {}


function twoSpecificBoxes(color1, color2) {
  drawBox(color1);
  drawBox(color2);
}
twoSpecificBoxes('red','blue');

The twoSpecificBoxes() function will take in 2 values and store them in the parameters: color1 and color2. Those values will be used in the 2 drawBox() calls, so that the final output is a box with the 1st color ('red') and a box with the 2nd color ('blue'). Again, you could imagine replacing the function call with the code inside the block. But this time, you also need to replace the parameter names with the argument values. Parameters are just placeholders for the argument values.


function oneThing(typeOfThing, valueForTheThing) {
  typeOfThing(valueForTheThing);
}
oneThing(print, 'hello');

The oneThing() function takes in 2 arguments: the name of another function, and a value to use as the arugment for that other function. The “other function” is called a callback. Imagine replacing the function call oneThing(print, 'hello'); with the code block {}, and remember to change all the parameters with the aguments. You end up with print('hello'). The cool thing about the oneThing() function is that it can use different callback functions. If you wanted to make a yellow box, you could do oneThing(drawBox, 'yellow').


function decrease(value) {
  if (value > 0) {
    decrease(value-1);
  }
  print(value);
}
decrease(2);

The decrease() function here is recursive. Inside of its code block {}, there is a decrease() call. Let’s replace the function call with the code block to expand out the code.

Starting with the function call:

decrease(2);

Substitute with the code block, and change the value parameter to be the argument

if (2 > 0) {
  decrease(2-1);
}
print(2);

Notice how there’s still a decrease() call. We can expand that out again, but be careful to use the right argument: (2-1) or just 1.

if (2 > 0) {

  if (1 > 0) {
    decrease(1-1);
  }
  print(1);

}
print(2);

There’s still a decrease() in there. We can replace it again, and use (1-1) as the argument value. 1-1===0

if (2 > 0) {
  if (1 > 0) {

    if (0 > 0) {
      decrease(0 - 1);
    }
    print(0);

  }
  print(1);
}
print(2);

There’s still a decrease() call, but look at where it is. It’s inside of an If Statement that is false, because 0 is not greater than 0, it’s equal. Since the If Statement is false, the code inside its block won’t run. Let’s remove it.

if (2 > 0) {
  if (1 > 0) {
    
    print(0);
  }
  print(1);
}
print(2);

No more decrease() calls! We can finish running our code now. It will print out 0, then 1, then 2, and then it’s done.


–Frankie

5 Likes

To my understanding, it is like flexible function, the result is depend on what kind of callback function we use as an argument, is that correct?

2 Likes

That’s right!

–Frankie

1 Like

I feel the same way! I pass the tutorials just fine by following the instructions, but I don’t really understand what I’m doing :weary:

1 Like

Yes, this is getting hard to grasp, even with your explanations…

Hey there,

The myAssistant function takes a time, and the name of another function:

function myAssistant(time, aFunction) {
  console.log('I am your assistant...');
  aFunction(time);
}

The 1st line of the function prints a message.
The 2nd line calls the function you passed in, with the time as an argument.

If you were to call it like myAssistant('6pm', recordShow), the function will print a message, then call recordShow('6pm')

If you called it like myAssistant('8am', setAlarm) the function will print a message, then call setAlarm('8am').

Let me know if you have any questions!
Ben

2 Likes

Why On myAssitant, call back function as parameter have no argument ? Different when i try to make my own callback function…

Hey there, good question!

In this example:

function myAssistant(time, aFunction) {
  console.log('I am your assistant...');
  aFunction(time);
}

myAssistant('7pm', orderPizza)

orderPizza and the argument it needs ('7pm') are both being passed as arguments to myAssistant.

myAssistant is going to run its console.log() statement first, and print 'I am your assistant'. Then it is going to run orderPizza('7pm').

If you were to try to call the function like this: myAssistant(orderPizza('7pm')), this is telling the computer “Run the orderPizza() function first, then use whatever is returned as an argument for myAssistant().”

Hope that helps! Let me know if you have any questions.
Ben

3 Likes

None of the function tutorials make much sense to me. i just find out what I’m suppose to fill and fill it. I don’t like that . i feel like concepts were not properly broken down like in the first fundamental.

It is in this fundamentals II that i found out what the visit support forum meant and its also here the puzzles reminded me what has been chasing me from learning how to code in the first place. Its starting to look like martian.

1 Like

Hey there, glad you found the support forum.

If you have any questions, feel free to ask them here. I can help explain concepts, and hopefully clarify things for you.

Hope this helps!
Ben

1 Like

Ben - I am definitely going to read your explanations until I either understand or have more questions, but only after reading what you’ve posted for us.

Thank you Ben for taking the time to explain in greater detail what we may not be getting from going through the course.

I’m not going to give up!

1 Like

@Grasshopper_Ben
Can I get the definition of the function “callbackFunction” used in this code? I wan’t to know how this function is taking ‘string’ and other function name(in variable form) as arguments and then using the string as an argument for the function passed to it as an argument. Can I get the full source code of this program?
Thank you

Hey there,

The myAssistant() function has 2 parameters: time (which should be a string), and callbackFunction, which is a function to run.

For a refresher on parameters and arguments, let’s look at a simple function that adds two numbers:

function add(num1, num2) { // num1 and num2 are the parameters
    return num1 + num2;
}

add(5, 6) // 5 and 6 are the arguments

num1 and num2 are the parameters for add(). When the function is called like this: add(5, 6), num1 will have the value 5 and num2 will have the value 6. 5 and 6 are the arguments.

In this puzzle, callbackFunction is a parameter. When the myAssistant() function is called, callbackFunction will be whatever is placed 2nd inside the parentheses.

Let’s look at the code for myAssistant():

function myAssistant(time, callbackFunction) {
    console.log('I am your assistant');
    callbackFunction(time);
}

If we were to call the function like this:

myAssistant('6pm', recordShow)

myAssistant() would first run this code:

console.log('I am your assistant');

Then this code:

recordShow('6pm')

Hope that makes sense! Try practicing a bit in the code playground. See if you can make your own callback function!

Good luck,
Ben

1 Like

Thank you @Grasshopper_Ben
I was confused as the function ‘callbackFunction()’ was not declared before using it as a callback function inside the myAssistant function. I’m used to programming in ‘C’ , so I thought ‘callbackFunction()’ is defined somewhere in the additional code part.
Thank you so much

Hey there. Great explanation. Having read it I got a question about decrease function example. As the value variable is updating and eventually gets 0, where are the numbers 1 and 2 stored in to be printed out later, after 0?

Hi there.

I can’t recreate this code in the playground however because it doesn’t let me use the callbackFunction as a function within the myAssistant function. Instead it only lets me call it as an argument but with no brackets. Are you using callbackFunction as a kind of ‘insert here’ parameter, or is it a real thing?

Thanks

Hey there, you’re correct that callbackFunction is a parameter in this puzzle. Whatever function you place 2nd in the parentheses when you call myAssistant() will be used as callbackFunction.

In the playground, when you create a parameter, a key will be added to the keyboard, but the keyboard doesn’t know that it’s a function, so it won’t have () after it.

However, there is a wonky workaround you can use to trick the keyboard into adding it.

First, create your function as you normally would and add the parameter name, like this:

function myAssistant(time, callbackFunction) {

}

Then, create a variable with the same name as the parameter, and make it store a function, like this:

function myAssistant(time, callbackFunction) {

}
let callbackFunction = () => {}
// or
let callbackFunction = function() {

}

This will make the keyboard add callbackFunction() as a selectable key. You can now use it in the function, like this:

function myAssistant(time, callbackFunction) {
  console.log('I am your assistant...');
  callbackFunction(time);
}

Finally, before running the code, delete the variable you created for callbackFunction. They key will still be on the keyboard as long as you’re using it somewhere.

Hope this helps!
Ben

1 Like

now iam confused ,i also thought that there is a callback() declaration and it is hidden in hint or somwhere.
Also use of let as local variable is puzzling me.do you really have to declare a local variable with let and a global variable as var in JS ? because i could not find it anywhere else.