-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[New Concept Exercise on lambda]: Add Secrets draft
#2589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
fe9334b
add secrets draft
Steffan153 20c6eac
Fix secret_multiply to use * instead of -
Steffan153 55023ee
Add secret_combine tests
Steffan153 12e98dd
Update exercises/concept/secrets/.docs/instructions.md
Steffan153 4d752cc
Change rest of instructions to REPL format
Steffan153 9a18303
Update exercises/concept/secrets/.docs/introduction.md
Steffan153 3246a8d
unassign lambda to variable
Steffan153 a14891a
lambdas are nameless
Steffan153 e967452
Add hints
Steffan153 cf2bcbc
design.md
Steffan153 0fe7bd9
remove unnecessary parts of design.md
Steffan153 e6220bb
remove random comma
Steffan153 ef970ad
Add config.json
Steffan153 d7e457e
Changed concept meta for wrong concept. Smh
Steffan153 682d45f
Add meta to correct concept
Steffan153 a43ba2e
Add forked_from to config.json
Steffan153 b08cca1
add concept exercise to python config.json and write concept introduc…
Steffan153 ab6a5ba
Add blurb to concept config.json
Steffan153 3e9f0a7
Add sorting thing
Steffan153 7649703
Update config.json
Steffan153 2e6e50e
Update config.json
Steffan153 94b255e
add docstrings
Steffan153 2895771
Merge branch 'main' of https://github.com/Steffan153/python into main
Steffan153 d9761b3
fix config.json
Steffan153 61d6014
Update exercises/concept/secrets/.meta/config.json
Steffan153 7727da6
Move secrets in config.json to concept
Steffan153 0f069b2
Merge branch 'main' of https://github.com/Steffan153/python into main
Steffan153 33db8cd
add messages to tests
Steffan153 1b4a4a8
remove random paren
Steffan153 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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": [] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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/" } | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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"], | ||
Steffan153 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "contributors": ["bethanyg"], | ||
| "forked_from": ["elixir/secrets"], | ||
| "files": { | ||
| "solution": ["secrets.py"], | ||
| "test": ["secrets_test.py"], | ||
| "exemplar": [".meta/exemplar.py"] | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| def secret_add(secret): | ||
Steffan153 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
| 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)) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| def secret_add(secret): | ||
Steffan153 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """ | ||
| 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 | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.