# CS61A Lab 2:

## Functions - Higher Order, Lambdas

### Exercise 1: Higher Order Functions

For every line that is marked with a "# ?" symbol, try to determine what Python would print in the interactive interpreter. Then check to see if you got the answer right.

```>>> def square(x):
return x*x

>>> def neg(f, x):
return -f(x)
# Q1
>>> neg(square, 4)
_______________
>>> def first(x):
...	x += 8
...	def second(y):
...		print('second')
...		return x + y
...	print('first')
...	return second
...
# Q2
>>> f = first(15)
_______________
# Q3
>>> f(16)
_______________

>>> def foo(x):
...	def bar(y):
...		return x + y
...	return bar

>>> boom = foo(23)
# Q4
>>> boom(42)
_______________
# Q5
>>> foo(6)(7)
_______________

>>> func = boom
# Q6
>>> func is boom
_______________
>>> func = foo(23)
# Q7
>>> func is boom
_______________
>>> def Troy():
...  abed = 0
...  while abed < 10:
...    britta = lambda: abed
...    abed += 1
...  abed = 20
...  return britta
...
>>> jeff = Troy()
>>> shirley = lambda : jeff
>>> pierce = shirley()
# Q8
>>> pierce()
________________
```

### Exercise 2: Returning Functions

In your Hog project, you will have to work with strategies and functions that make strategies. Let's start with defining what a strategy is: a function that takes two arguments (your score and the opponent's score) and returns the number of dice to toll.

Make a strategy function that always rolls `5` dice. This is the strategy that is the computer's default strategy. Call this default_strategy. Now, let's define a function that will return this default_strategy when it's evaluated. Call this function make_default_strategy.

Now try implementing a strategy maker called make_weird_strategy that will take one argument called num_rolls. The strategy it returns will return the higher of num_rolls or the total number of points scored in the game thus far divided by `20`, throwing away any remainder.

### Exercise 3: Lambdas

Now, we will visit the idea of lambda functions. These are functions that are one line functions, and that line just specifies the return value. The format of a lambda function is as follows:

```lambda [parameters]: [return value]
```

Another bit of syntax that we introduce in this exercise is the conditional expression. It has the following format:

```[true-value] if [conditional] else [false-value]
```

It is almost equivalent to the if statement that you have already seen. If the conditional evaluates to True then the conditional expression evaluates to [true-value]. If it's false, then it evaluates to [false-value].

Knowing this, go back to Exercise 1 and make sure you understand the lambda question. Now, fill in the blanks as to what Python would do here:

```>>> doctor = lambda : "who"
# Q1
>>> doctor()
_______________
>>> ninth = lambda x: "Fantastic!" if x == 9 else tenth
>>> tenth = lambda y: "Allons-y!" if y == 10 else eleventh
>>> eleventh = lambda z: "Geronimo!" if z == 11 else ninth
# Q2
>>> ninth(9)
_______________
# Q3
>>> ninth(2)(10)
_______________
# Q4
>>> tenth(10)
_______________
# Q5
>>> tenth(12) is eleventh
_______________
# Q6
>>> eleventh(10)(11)(9)(11)
_______________
```

As a final challenge, try to rewrite the previous exercise using solely lambdas.

### Exercise 4: I Heard You Liked Functions So I Put Functions In Your Functions

Define a function cycle which takes in three arguments and returns another function. The returned fuction should take in an integer argument n such that if the argument is 0, a function is returned that takes in an argument x and simply returns that argument x. If the argument is 1, the first function given to cycle should be applied to x. If it's 2, the first is applied to x and then the second argument is applied. Likewise, if it's 3, it's the first, then second, then third. For 4, you do the first, second, third, then the first again. For higher numbers you repeat this cycle.

Hint: most of the work goes inside the most nested function.

```def cycle(f1, f2, f3):
""" Returns a function that is itself a higher order function
>>> add1 = lambda x: x+1
>>> times2 = lambda x: 2*x
>>> add3 = lambda x: x+3
>>> identity = my_cycle(0)
>>> identity(5)
5
4
>>> do_all_functions = my_cycle(3)
>>> do_all_functions(2)
9
>>> do_more_than_a_cycle = my_cycle(4)
>>> do_more_than_a_cycle(2)
10
>>> do_two_cycles = my_cycle(6)
>>> do_two_cycles(1)
19
"""

" *** YOUR CODE HERE *** "
```

Fin.