You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Launch plane tickets concept exercise in beta (#3530)
* Tweak plane tickets concept exercise
I did a small pass through to tweak it a bit for
flow and readability.
This exercise is ready to be launched.
* Turn on plane tickets exercise
* (BG) Rather More Edits than Anticipated:
This all started with me re-editing the docstrings to comply with https://peps.python.org/pep-0257/, but then it snowballed.
Turns out that typing.Generator (https://docs.python.org/3/library/typing.html#typing.Generator) has been deprecated as an alias, so the tests needed some love...and that snowballed into reviewing the other docs.
Also renamed the stub and test files to be in line with what we did with other concept exercises.
---------
Co-authored-by: BethanyG <[email protected]>
Copy file name to clipboardExpand all lines: concepts/generators/about.md
+12Lines changed: 12 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,13 @@
1
1
# About
2
2
3
+
A `generator` is a function or expression that returns a special type of [iterator][iterator] called [generator iterator][generator-iterator].
4
+
`Generator-iterators` are [lazy][lazy iterator]: they do not store their `values` in memory, but _generate_ their values when needed.
5
+
6
+
A generator function looks like any other function, but contains one or more [yield expressions][yield expression].
7
+
Each `yield` will suspend code execution, saving the current execution state (_including all local variables and try-statements_).
8
+
When the generator resumes, it picks up state from the suspension - unlike regular functions which reset with every call.
9
+
10
+
3
11
## Constructing a generator
4
12
5
13
Generators are constructed much like other looping or recursive functions, but require a [`yield` expression](#the-yield-expression), which we will explore in depth a bit later.
@@ -131,5 +139,9 @@ Generators are also very helpful when a process or calculation is _complex_, _ex
131
139
132
140
Now whenever `__next__()` is called on the `infinite_sequence` object, it will return the _previous number_ + 1.
A generator in Python is a _callable function_ that returns a [lazy iterator][lazy iterator].
3
+
A generator in Python is a _callable function_ or expression that returns a special type of [iterator][iterator] called [generator iterator][generator-iterator].
4
+
`Generator-iterators` are [lazy][lazy iterator]: they do not store their `values` in memory, but _generate_ their values when needed.
4
5
5
-
_Lazy iterators_ are similar to `lists`, and other `iterators`, but with one key difference: They do not store their `values` in memory, but _generate_ their values when needed.
6
+
A generator function looks like any other function, but contains one or more [yield expressions][yield expression].
7
+
Each `yield` will suspend code execution, saving the current execution state (_including all local variables and try-statements_).
8
+
When the generator function resumes, it picks up state from the suspension - unlike regular functions which reset with every call.
Copy file name to clipboardExpand all lines: exercises/concept/plane-tickets/.docs/introduction.md
+41-25Lines changed: 41 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,18 @@
1
-
# About
1
+
# Generators
2
+
3
+
A `generator` is a function or expression that returns a special type of [iterator][iterator] called [generator iterator][generator-iterator].
4
+
`Generator-iterators` are [lazy][lazy iterator]: they do not store their `values` in memory, but _generate_ their values when needed.
5
+
6
+
A generator function looks like any other function, but contains one or more [yield expressions][yield expression].
7
+
Each `yield` will suspend code execution, saving the current execution state (_including all local variables and try-statements_).
8
+
When the generator resumes, it picks up state from the suspension - unlike regular functions which reset with every call.
9
+
2
10
3
11
## Constructing a generator
4
12
5
13
Generators are constructed much like other looping or recursive functions, but require a [`yield` expression](#the-yield-expression), which we will explore in depth a bit later.
6
14
7
-
An example is a function that returns the _squares_ from a given list of numbers.
15
+
An example is a function that returns the _squares_ from a given list of numbers.
8
16
As currently written, all input must be processed before any values can be returned:
9
17
10
18
```python
@@ -23,13 +31,14 @@ You can convert that function into a generator like this:
23
31
...yield number **2
24
32
```
25
33
26
-
The rationale behind this is that you use a generator when you do not need all the values _at once_.
27
-
34
+
The rationale behind this is that you use a generator when you do not need to produce all the values _at once_.
28
35
This saves memory and processing power, since only the value you are _currently working on_ is calculated.
29
36
37
+
30
38
## Using a generator
31
39
32
-
Generators may be used in place of most `iterables` in Python. This includes _functions_ or _objects_ that require an `iterable`/`iterator` as an argument.
40
+
Generators may be used in place of most `iterables` in Python.
41
+
This includes _functions_ or _objects_ that require an `iterable`/`iterator` as an argument.
33
42
34
43
To use the `squares_generator()` generator:
35
44
@@ -45,8 +54,8 @@ To use the `squares_generator()` generator:
45
54
16
46
55
```
47
56
48
-
Values within a generator can also be produced/accessed via the `next()` function.
49
-
`next()` calls the `__next__()` method of a generator object, "advancing" or evaluating the generator code up to its `yield` expression, which then "yields" or returns the value.
57
+
Values within a `generator` can also be produced/accessed via the `next()` function.
58
+
`next()` calls the `__next__()` method of a generator-iterator object, "advancing" or evaluating the code up to its `yield` expression, which then "yields" or returns a value:
50
59
51
60
```python
52
61
>>> squared_numbers = squares_generator([1, 2])
@@ -57,7 +66,7 @@ Values within a generator can also be produced/accessed via the `next()` functio
57
66
4
58
67
```
59
68
60
-
When a `generator` is fully consumed and has no more values to return, it throws a `StopIteration` error.
69
+
When a `generator-iterator` is fully consumed and has no more values to return, it throws a `StopIteration` error.
`Iterators` are the mechanism/protocol that enables looping over _iterables_.
73
-
Generators and the iterators returned by common Python [`iterables`][iterables] act very similarly, but there are some important differences to note:
74
-
75
-
- Generators are _one-way_; there is no "backing up" to a previous value.
76
-
77
-
- Iterating over generators consume the returned values; no resetting.
79
+
~~~~exercism/note
78
80
79
-
- Generators (_being lazily evaluated_) are not sortable and can not be reversed.
81
+
Generator-iterators are a special sub-set of [iterators][iterator].
82
+
`Iterators` are the mechanism/protocol that enables looping over _iterables_.
83
+
Generator-iterators and the iterators returned by common Python [`iterables`][iterables] act very similarly, but there are some important differences to note:
80
84
81
-
- Generators do _not_ have `indexes`, so you can't reference a previous or future value using addition or subtraction.
85
+
- They are _[lazily evaluated][lazy evaluation]_; iteration is _one-way_ and there is no "backing up" to a previous value.
86
+
- They are _consumed_ by iterating over the returned values; there is no resetting or saving in memory.
87
+
- They are not sortable and cannot be reversed.
88
+
- They are not sequence types, and _do not_ have `indexes`.
89
+
You cannot reference a previous or future value using addition or subtraction and you cannot use bracket (`[]`) notation or slicing.
90
+
- They cannot be used with the `len()` function, as they have no length.
91
+
- They can be _finite_ or _infinite_ - be careful when collecting all values from an _infinite_ `generator-iterator`!
82
92
83
-
- Generators cannot be used with the `len()` function.
- Generators can be _finite_ or _infinite_, be careful when collecting all values from an _infinite_ generator.
86
98
87
99
## The yield expression
88
100
89
101
The [yield expression][yield expression] is very similar to the `return` expression.
90
-
91
102
_Unlike_ the `return` expression, `yield` gives up values to the caller at a _specific point_, suspending evaluation/return of any additional values until they are requested.
92
-
93
103
When `yield` is evaluated, it pauses the execution of the enclosing function and returns any values of the function _at that point in time_.
94
-
95
104
The function then _stays in scope_, and when `__next__()` is called, execution resumes until `yield` is encountered again.
96
105
106
+
97
107
~~~~exercism/note
98
108
Using `yield` expressions is prohibited outside of functions.
99
109
~~~~
@@ -112,11 +122,12 @@ Using `yield` expressions is prohibited outside of functions.
112
122
1
113
123
```
114
124
115
-
## Why generators?
125
+
126
+
## Why Create a Generator?
116
127
117
128
Generators are useful in a lot of applications.
118
129
119
-
When working with a large collection, you might not want to put all of its values into `memory`.
130
+
When working with a potentially large collection of values, you might not want to put all of them into memory.
120
131
A generator can be used to work on larger data piece-by-piece, saving memory and improving performance.
121
132
122
133
Generators are also very helpful when a process or calculation is _complex_, _expensive_, or _infinite_:
@@ -131,5 +142,10 @@ Generators are also very helpful when a process or calculation is _complex_, _ex
131
142
132
143
Now whenever `__next__()` is called on the `infinite_sequence` object, it will return the _previous number_ + 1.
0 commit comments