Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 13 additions & 8 deletions concepts/binary-octal-hexadecimal/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ A snippet from the base 2 system looks like this, although it continues infinite
| -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
| 2 \*\* 7 | 2 \*\* 6 | 2 \*\* 5 | 2 \*\* 4 | 2 \*\* 3 | 2 \*\* 2 | 2 \*\* 1 | 2 \*\* 0 |

So if we want to represent the number 6, it would in binary be: 110
So if we want to represent the number 6 in binary, it would be 110.

| Place value | 4 | 2 | 1 |
| ------------- | --- | --- | --- |
Expand All @@ -41,7 +41,6 @@ In Python, we can represent binary literals using the `0b` prefix.
If we write `0b10011`, Python will interpret it as a binary number and convert it to base 10.

```python
# 0b10011
>>> 0b10011
19

Expand Down Expand Up @@ -86,6 +85,8 @@ However, the usual mathematical operator rules apply: dividing two binary numbe

>>> 0b10011/3
6.333333333333333
```


### Converting to and from Binary Representation

Expand Down Expand Up @@ -133,6 +134,9 @@ For example, `bit_count()` on '0b11011' will return 4:
```python
>>> 0b11011.bit_count()
4
```


~~~~exercism/note
If you are working locally, `bit_count()` requires at least Python 3.10.
The Exercism online editor currently supports all features through Python 3.11.
Expand All @@ -148,7 +152,6 @@ In Python, we can represent octal numbers using the `0o` prefix.
As with binary, Python automatically converts an octal representation to an `int`.

```python
# 0o123
>>> 0o123
83
```
Expand All @@ -157,14 +160,15 @@ As with binary, octal numbers **are ints** and support all integer operations.
Prefixing a number with `0o` that is not in the octal system will raise a `SyntaxError`.

### Converting to and from Octal Representation


To convert an `int` into an octal representation, you can use the built-in [`oct()`][oct] function.
This acts similarly to the `bin()` function, returning a string:

```python
>>> oct(83)
'0o123'
```


To convert an octal number to an integer, we can use the `int()` function, passing an octal string representation and the base (8) as arguments:

Expand All @@ -175,22 +179,21 @@ To convert an octal number to an integer, we can use the `int()` function, passi

As with binary, giving the wrong base will raise a `ValueError`.

### Hexadecimal
## Hexadecimal

[Hexadecimal][hexadecimal] is a base 16 numeral system.
It uses the digits 0 - 9 and the letters A, B, C, D, E, and F.
A is 10, B is 11, C is 12, D is 13, E is 14, and F is 15.

We can represent hexadecimal numbers in Python using the `0x` prefix.
As with binary and octal, Python will automatically convert hexadecimal literals to `int`.
As with binary and octal, Python will automatically convert hexadecimal literals to `int`s.

```python
# 0x123
>>> 0x123
291
```

As with binary and octal - hexadecimal literals **are ints**, and you can perform all integer operations.
As with binary and octal hexadecimal literals **are ints**, and you can perform all integer operations with them.
Prefixing a non-hexadecimal number with `0x` will raise a `SyntaxError`.


Expand All @@ -202,6 +205,8 @@ This acts similarly to the `bin()` function, returning a string:
```python
>>> hex(291)
'0x123'
```


To convert a hexadecimal representation to an integer, we can use the `int()` function, passing a hexadecimal string with the base (16) as arguments:

Expand Down
2 changes: 1 addition & 1 deletion concepts/binary-octal-hexadecimal/introduction.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# binary, octal, hexadecimal
# Binary, Octal, Hexadecimal

Binary, octal, and hexadecimal (_also known as hex_) are different [numeral systems][numeral-systems] with different bases.
Binary is base 2, octal is base 8, and hexadecimal is base 16.
Expand Down
29 changes: 27 additions & 2 deletions concepts/generators/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,33 @@ The rationale behind this is that you use a generator when you do not need all t

This saves memory and processing power, since only the value you are _currently working on_ is calculated.


## Using a generator

Generators may be used in place of most `iterables` in Python. This includes _functions_ or _objects_ that require an `iterable`/`iterator` as an argument.
Generators (_technically [`generator-iterator`s][generator-iterator] — see the note below._) are a type of `iterator` and can be used anywhere in Python where an `iterator` or `iterable` is expected.
This includes _functions_ or _objects_ that require an `iterable`/`iterator` as an argument.
For a deeper dive, see [How to Make an Iterator in Python][how-to-iterator].


~~~~exercism/note

Generator-iterators are a special sub-set of [iterators][iterator].
`Iterators` are the mechanism/protocol that enables looping over _iterables_.
Generator-iterators and the iterators returned by common Python [`iterables`][iterables] act very similarly, but there are some important differences to note:

- They are _[lazily evaluated][lazy evaluation]_; iteration is _one-way_ and there is no "backing up" to a previous value.
- They are _consumed_ by iterating over the returned values; there is no resetting or saving in memory.
- They are not sortable and cannot be reversed.
- They are not sequence types, and _do not_ have `indexes`.
You cannot reference a previous or future value using addition or subtraction and you cannot use bracket (`[]`) notation or slicing.
- They cannot be used with the `len()` function, as they have no length.
- They can be _finite_ or _infinite_ - be careful when collecting all values from an _infinite_ `generator-iterator`!

[iterator]: https://docs.python.org/3.11/glossary.html#term-iterator
[iterables]: https://wiki.python.org/moin/Iterator
[lazy evaluation]: https://en.wikipedia.org/wiki/Lazy_evaluation
~~~~


To use the `squares_generator()` generator:

Expand Down Expand Up @@ -140,7 +164,8 @@ Generators are also very helpful when a process or calculation is _complex_, _ex
Now whenever `__next__()` is called on the `infinite_sequence` object, it will return the _previous number_ + 1.


[generator-iterator]: https://docs.python.org/3.11/glossary.html#term-generator-iterator
[generator-iterator]: https://docs.python.org/3/glossary.html#term-generator-iterator
[how-to-iterator]: https://treyhunner.com/2018/06/how-to-make-an-iterator-in-python/#Generators:_the_easy_way_to_make_an_iterator
[iterables]: https://wiki.python.org/moin/Iterator
[iterator]: https://docs.python.org/3.11/glossary.html#term-iterator
[lazy iterator]: https://en.wikipedia.org/wiki/Lazy_evaluation
Expand Down
6 changes: 3 additions & 3 deletions concepts/unpacking-and-multiple-assignment/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A very common example of this behavior is `for item in list`, where `item` takes
This allows for code to be more concise and readable, and is done by separating the variables to be assigned with a comma such as `first, second, third = (1,2,3)` or `for index, item in enumerate(iterable)`.

The special operators `*` and `**` are often used in unpacking contexts.
`*` can be used to combine multiple `lists`/`tuples` into one `list`/`tuple` by _unpacking_ each into a new common `list`/`tuple`.
`*` can be used to combine multiple `list`s/`tuple`s into one `list`/`tuple` by _unpacking_ each into a new common `list`/`tuple`.
`**` can be used to combine multiple dictionaries into one dictionary by _unpacking_ each into a new common `dict`.

When the `*` operator is used without a collection, it _packs_ a number of values into a `list`.
Expand Down Expand Up @@ -73,7 +73,7 @@ Since `tuples` are immutable, you can't swap elements in a `tuple`.
The examples below use `lists` but the same concepts apply to `tuples`.
~~~~

In Python, it is possible to [unpack the elements of `list`/`tuple`/`dictionary`][unpacking] into distinct variables.
In Python, it is possible to [unpack the elements of a `list`/`tuple`/`dict`][unpacking] into distinct variables.
Since values appear within `lists`/`tuples` in a specific order, they are unpacked into variables in the same order:

```python
Expand All @@ -94,7 +94,7 @@ If there are values that are not needed then you can use `_` to flag them:

### Deep unpacking

Unpacking and assigning values from a `list`/`tuple` inside of a `list` or `tuple` (_also known as nested lists/tuples_), works in the same way a shallow unpacking does, but often needs qualifiers to clarify the values context or position:
Unpacking and assigning values from a `list`/`tuple` inside of a `list` or `tuple` (_also known as nested lists/tuples_), works in the same way a shallow unpacking does, but often needs qualifiers to clarify the value's context or position:

```python
>>> fruits_vegetables = [["apple", "banana"], ["carrot", "potato"]]
Expand Down
2 changes: 1 addition & 1 deletion concepts/unpacking-and-multiple-assignment/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A very common example of this behavior is `for item in list`, where `item` takes
This allows for code to be more concise and readable, and is done by separating the variables to be assigned with a comma such as `first, second, third = (1,2,3)` or `for index, item in enumerate(iterable)`.

The special operators `*` and `**` are often used in unpacking contexts.
`*` can be used to combine multiple `lists`/`tuples` into one `list`/`tuple` by _unpacking_ each into a new common `list`/`tuple`.
`*` can be used to combine multiple `list`s/`tuple`s into one `list`/`tuple` by _unpacking_ each into a new common `list`/`tuple`.
`**` can be used to combine multiple dictionaries into one dictionary by _unpacking_ each into a new common `dict`.

When the `*` operator is used without a collection, it _packs_ a number of values into a `list`.
Expand Down
6 changes: 2 additions & 4 deletions exercises/concept/plane-tickets/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Generators

A `generator` is a function or expression that returns a special type of [iterator][iterator] called [generator iterator][generator-iterator].
`Generator-iterators` are [lazy][lazy iterator]: they do not store their `values` in memory, but _generate_ their values when needed.
A `generator` is a function or expression that returns a special type of [iterator][iterator] called a [`generator iterator`][generator-iterator].
`Generator-iterator`s are [lazy][lazy iterator]: they do not store their `values` in memory, but _generate_ their values when needed.

A generator function looks like any other function, but contains one or more [yield expressions][yield expression].
Each `yield` will suspend code execution, saving the current execution state (_including all local variables and try-statements_).
Expand Down Expand Up @@ -144,8 +144,6 @@ Now whenever `__next__()` is called on the `infinite_sequence` object, it will r


[generator-iterator]: https://docs.python.org/3.11/glossary.html#term-generator-iterator
[iterables]: https://wiki.python.org/moin/Iterator
[iterator]: https://docs.python.org/3.11/glossary.html#term-iterator
[lazy evaluation]: https://en.wikipedia.org/wiki/Lazy_evaluation
[lazy iterator]: https://en.wikipedia.org/wiki/Lazy_evaluation
[yield expression]: https://docs.python.org/3.11/reference/expressions.html#yield-expressions
Loading