Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
fe9334b
add secrets draft
Steffan153 Sep 17, 2021
20c6eac
Fix secret_multiply to use * instead of -
Steffan153 Sep 17, 2021
55023ee
Add secret_combine tests
Steffan153 Sep 17, 2021
12e98dd
Update exercises/concept/secrets/.docs/instructions.md
Steffan153 Sep 17, 2021
4d752cc
Change rest of instructions to REPL format
Steffan153 Sep 17, 2021
9a18303
Update exercises/concept/secrets/.docs/introduction.md
Steffan153 Sep 17, 2021
3246a8d
unassign lambda to variable
Steffan153 Sep 17, 2021
a14891a
lambdas are nameless
Steffan153 Sep 17, 2021
e967452
Add hints
Steffan153 Sep 17, 2021
cf2bcbc
design.md
Steffan153 Sep 17, 2021
0fe7bd9
remove unnecessary parts of design.md
Steffan153 Sep 17, 2021
e6220bb
remove random comma
Steffan153 Sep 17, 2021
ef970ad
Add config.json
Steffan153 Sep 17, 2021
d7e457e
Changed concept meta for wrong concept. Smh
Steffan153 Sep 17, 2021
682d45f
Add meta to correct concept
Steffan153 Sep 17, 2021
a43ba2e
Add forked_from to config.json
Steffan153 Sep 17, 2021
b08cca1
add concept exercise to python config.json and write concept introduc…
Steffan153 Sep 17, 2021
ab6a5ba
Add blurb to concept config.json
Steffan153 Sep 17, 2021
3e9f0a7
Add sorting thing
Steffan153 Sep 17, 2021
7649703
Update config.json
Steffan153 Sep 18, 2021
2e6e50e
Update config.json
Steffan153 Sep 18, 2021
94b255e
add docstrings
Steffan153 Sep 18, 2021
2895771
Merge branch 'main' of https://github.com/Steffan153/python into main
Steffan153 Sep 18, 2021
d9761b3
fix config.json
Steffan153 Sep 18, 2021
61d6014
Update exercises/concept/secrets/.meta/config.json
Steffan153 Sep 18, 2021
7727da6
Move secrets in config.json to concept
Steffan153 Sep 18, 2021
0f069b2
Merge branch 'main' of https://github.com/Steffan153/python into main
Steffan153 Sep 18, 2021
33db8cd
add messages to tests
Steffan153 Sep 18, 2021
1b4a4a8
remove random paren
Steffan153 Sep 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions concepts/anonymous-functions/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"blurb": "TODO: add blurb for this concept",
"authors": ["bethanyg", "cmccandless"],
"blurb": "A lambda expression, or an anonymous function, is a shorter way to create functions than using def.",
"authors": ["Steffan153"],
"contributors": []
}
6 changes: 5 additions & 1 deletion concepts/anonymous-functions/introduction.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
#TODO: Add introduction for this concept.
# Anonymous Functions / Lambdas

A [`lambda`][lambdas] expression (also called an anonymous function) is a shorter way to create functions than using `def`. Unlike `def`, they are nameless, or **anonymous**, which means it is created without a name.

[lambdas]: https://docs.python.org/3/howto/functional.html?highlight=lambda%20expression#small-functions-and-the-lambda-expression
23 changes: 7 additions & 16 deletions concepts/anonymous-functions/links.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
[
{
"url": "http://example.com/",
"description": "TODO: add new link (above) and write a short description here of the resource."
},
{
"url": "http://example.com/",
"description": "TODO: add new link (above) and write a short description here of the resource."
},
{
"url": "http://example.com/",
"description": "TODO: add new link (above) and write a short description here of the resource."
},
{
"url": "http://example.com/",
"description": "TODO: add new link (above) and write a short description here of the resource."
}
{ "description": "Python Docs: Defining Functions", "url": "https://docs.python.org/3/tutorial/controlflow.html#defining-functions" },
{ "description": "Python Docs Tutorial: Lambda Expressions", "url": "https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions" },
{ "description": "Functions as Objects in Python", "url": "https://medium.com/python-pandemonium/function-as-objects-in-python-d5215e6d1b0d" },
{ "description": "Composing Programs: Higher-Order Functions", "url": "https://composingprograms.com/pages/16-higher-order-functions.html" },
{ "description": "Learn by Example: Python Lambda Function", "url": "https://www.learnbyexample.org/python-lambda-function/" },
{ "description": "Real Python: How to Use Python Lambda Fuctions", "url": "https://realpython.com/python-lambda/" },
{ "description": "Trey Hunner: Overusing Lambda expressions in Python", "url": "https://treyhunner.com/2018/09/stop-writing-lambda-expressions/" }
]
26 changes: 26 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,32 @@
"concepts": ["sets"],
"prerequisites": ["basics", "dicts", "lists", "loops", "tuples"],
"status": "beta"
},
{
"slug": "secrets",
"name": "Secrets",
"uuid": "1e636fd3-6143-484e-a4fc-0ed6157fdfa1",
"concepts": ["anonymous-functions", "lambdas"],
"prerequisites": [
"basics",
"booleans",
"comparisons",
"dicts",
"dict-methods",
"functions",
"function-arguments",
"higher-order-functions",
"iteration",
"lists",
"list-methods",
"numbers",
"sequences",
"sets",
"strings",
"string-methods",
"tuples"
],
"status": "wip"
}
],
"practice": [
Expand Down
33 changes: 33 additions & 0 deletions exercises/concept/secrets/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

# Hints

## General

- Make use of [lambdas][lambdas].

## 1. Create an adder

- Return a lambda which adds the argument from the lambda to the argument passed in to `secret_add`.

## 2. Create a multiplier

- Return a lambda which multiplies the argument from the lambda to the argument passed in to `secret_multiply`.

## 3. Create a "max"-er

- Return a lambda which returns either the argument from the lambda or the argument passed in to `secret_max`, whichever one's product is bigger.
- Use the `key` argument with the [`max`][max] function.

## 4. Create a sorter

- Return a lambda which takes one argument, a list of lists of an unknown amount of numbers. The lambda should return the list of lists, but sorted by `sublist[secret_index]`.
- Use the `key` argument with the [`sorted`][sorted] function.

## 5. Create a function combiner

- Return a lambda which [composes the functions][fn-composition] passed in to `secret_combine`.

[fn-composition]: https://en.wikipedia.org/wiki/Function_composition_(computer_science)
[lambdas]: https://docs.python.org/3/howto/functional.html?highlight=lambda%20expression#small-functions-and-the-lambda-expression
[max]: https://docs.python.org/3/library/functions.html#max
[sorted]: https://docs.python.org/3/library/functions.html#sorted
59 changes: 59 additions & 0 deletions exercises/concept/secrets/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Instructions

In this exercise, you've been tasked with writing the software for an encryption device that works by performing transformations on data. You need a way to flexibly create complicated functions by combining simpler functions together.

For each task, return a function (using a `lambda`).


## 1. Create an adder

Implement `secret_add`. It should return a function which takes one argument and adds to it the argument passed in to `secret_add`.

```python
>>> adder = secret_add(2)
>>> adder(2)
4
```

## 2. Create a multiplier

Implement `secret_multiply`. It should return a function which takes one argument and multiplies it by the secret passed in to `secret_multiply`.

```python
>>> multiplier = secret_multiply(7)
>>> multiplier(3)
21
```

## 3. Create a "max"-er

Implement `secret_max`. It should return a function which takes one argument (a list of exactly two numbers) and returns either the secret passed into `secret_max`, or the argument passed into the function that `secret_max` returns, whichever one's **product** is bigger.

```python
>>> maxer = secret_max([7, 3])
>>> maxer([2, 11])
[2, 11]
```

## 4. Create a sorter

Implement `secret_sort`. It should take a number, `secret_index`, and return a lambda which takes one argument, a list of lists of an unknown amount of numbers. The lambda should return the list of lists, but sorted by `sublist[secret_index]`.

```python
>>> sorter = secret_sort(0)
>>> sorter([[3, 120, 5], [1, 5, 2], [8, 2, 23]])
[[1, 5, 2], [3, 120, 5], [8, 2, 23]]
```

## 5. Create a function combiner

Implement `secret_combine`. It should return a lambda which takes one argument and applies to it the two functions passed in to `secret_combine` in order.

```python
>>> multiply = secret_multiply(7)
>>> divide = secret_add(3)
>>> combined = secret_combine(multiply, add)

>>> combined(6)
25
```
24 changes: 24 additions & 0 deletions exercises/concept/secrets/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Lambdas

Python has a [`lambda`][lambdas] expression, which is a shorter way to create functions than using `def`. They are nameless, or **anonymous**, which means it is created without a name, unlike `def`. Since they are nameless, you can pass them directly into another function without giving it a name. It looks like this:

```python
lambda num: num + 1
```

In short, a `lambda expression` starts with the keyword `lambda`, followed by parameters (_separated by a comma, as you would do with a `def`-defined function_), a colon, and a `return` value.

```exercism/caution
Be warned: unlike functional-first programming languages, Python's [lambdas][lambdas] are quite limited. They can only contain code that is computable as a single expression, and be written on a single line. [They can't contain statements.][statements]
```

It is customary to only use them in very constrained situations -- most often as [`sort`][sort], [`min`][min], or [`max`][max] keys, or as arguments to [`map()`][map], [`filter()`][filter] and [`functools.reduce()`][reduce]. They also execute in their own frame, which makes error handling and stack traces more effort, and often slows code execution if you're not careful.

[lambdas]: https://docs.python.org/3/howto/functional.html?highlight=lambda%20expression#small-functions-and-the-lambda-expression
[statements]: https://docs.python.org/3/faq/design.html#why-can-t-lambda-expressions-contain-statements
[sort]: https://realpython.com/python-sort/
[min]: https://docs.python.org/3/library/functions.html#min
[max]: https://docs.python.org/3/library/functions.html#max
[map]: https://realpython.com/python-map-function/
[filter]: https://realpython.com/python-filter-function/
[reduce]: https://realpython.com/python-reduce-function/
11 changes: 11 additions & 0 deletions exercises/concept/secrets/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"blurb": "Learn about lambdas by writing the software for an encryption device.",
"authors": ["Steffan153"],
"contributors": ["bethanyg"],
"forked_from": ["elixir/secrets"],
"files": {
"solution": ["secrets.py"],
"test": ["secrets_test.py"],
"exemplar": [".meta/exemplar.py"]
}
}
59 changes: 59 additions & 0 deletions exercises/concept/secrets/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Design

## Goal

This concept exercise is meant to teach an understanding/creation/use of `lambda` or `anonymous functions` in python.

## Learning objectives

- Understand what an `anonymous function` is, and how to create one
- The syntax of creating a `lambda`
- Using different `function argument` flavors with `lambda`
- Understand the differences between `lambdas` and Pythons "regular" `functions`
- Understand what problems are solved by using a `lambda`
- The pitfalls of `lambdas`, and when to avoid them
- Using `lambdas` as `key functions` in other situations such as `sort()` , `sorted()`, `min()`, and `max()`
- Applying arguments to a `lambda` via IIFE (_immediately invoked function expression_)
- Anti-patterns when using `lambdas`

## Out of scope

- `comprehensions`
- `comprehensions` in `lambdas`
- using a `decorator` on a `lambda`
- `functools` (_this will get its own exercise_)
- `generators`
- `map()`, `filter()`, and `reduce()` (_these will get their own exercise_)
- using an `assignment expression` or "walrus" operator (`:=`) in a `lambda`

## Concepts

- `anonymous-functions`
- `lambdas`
- `functions`
- `higher-order functions`
- `functions as arguments`
- `functions as returns`
- `nested funcitons`

## Prerequisites

These are the concepts/concept exercises the student needs to complete/understand before solving this concept exercise.

- `basics`
- `booleans`
- `comparisons`
- `dicts`
- `dict-methods`
- `functions`
- `function-arguments`
- `higher-order functions`
- `iteration`
- `lists`
- `list-methods`
- `numbers`
- `sequences`
- `sets`
- `strings`
- `string-methods`
- `tuples`
45 changes: 45 additions & 0 deletions exercises/concept/secrets/.meta/exemplar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
def secret_add(secret):
"""
Return a lambda that adds the argument from the lambda to the argument passed into secret_add.

:param secret: secret number to add (integer)
:return: lambda that takes a number and adds it to the secret
"""
return lambda addend: secret + addend

def secret_multiply(secret):
"""
Return a lambda that multiplies the argument from the lambda to the argument passed into secret_multiply.

:param secret: secret number to multiply (integer)
:return: lambda that takes a number and multiplies it to the secret
"""
return lambda multiplicand: secret * multiplicand

def secret_max(secret):
"""
Return a lambda that returns either the argument from the lambda or the argument passed in to secret_max, whichever one's product is bigger.

:param secret: secret list of two numbers (list)
:return: lambda that takes a list of two numbers
"""
return lambda num: max(secret, num, key=lambda l: l[0] * l[1])

def secret_sort(secret_index):
"""
Return a lambda that takes one argument, a list of lists of an unknown amount of numbers. The lambda should return the list of lists, but sorted by sublist[secret_index].

:param secret_index: secret index to sort by (integer)
:return: lambda that takes a list of lists of numbers and sorts them
"""
return lambda l: sorted(l, key=lambda x: x[secret_index])

def secret_combine(secret_function1, secret_function2):
"""
Return a lambda that takes one argument and applies to it the two functions passed in to secret_combine in order.

:param secret_function1: function
:param secret_function2: function
:return: lambda that composes the two functions
"""
return lambda x: secret_function2(secret_function1(x))
45 changes: 45 additions & 0 deletions exercises/concept/secrets/secrets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
def secret_add(secret):
"""
Return a lambda that adds the argument from the lambda to the argument passed into secret_add.

:param secret: secret number to add (integer)
:return: lambda that takes a number and adds it to the secret
"""
pass

def secret_multiply(secret):
"""
Return a lambda that multiplies the argument from the lambda to the argument passed into secret_multiply.

:param secret: secret number to multiply (integer)
:return: lambda that takes a number and multiplies it to the secret
"""
pass

def secret_max(secret):
"""
Return a lambda that returns either the argument from the lambda or the argument passed in to secret_max, whichever one's product is bigger.

:param secret: secret list of two numbers (list)
:return: lambda that takes a list of two numbers
"""
pass

def secret_sort(secret_index):
"""
Return a lambda that takes one argument, a list of lists of an unknown amount of numbers. The lambda should return the list of lists, but sorted by sublist[secret_index].

:param secret_index: secret index to sort by (integer)
:return: lambda that takes a list of lists of numbers and sorts them
"""
pass

def secret_combine(secret_function1, secret_function2):
"""
Return a lambda that takes one argument and applies to it the two functions passed in to secret_combine in order.

:param secret_function1: function
:param secret_function2: function
:return: lambda that composes the two functions
"""
pass
Loading