Skip to content

Commit

Permalink
A bunch of fixes and some additions
Browse files Browse the repository at this point in the history
  • Loading branch information
meatball133 committed Dec 30, 2022
1 parent 2605588 commit 8817012
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 83 deletions.
36 changes: 18 additions & 18 deletions concepts/itertools/about.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# About

Itertools is a module in the Python standard library that provides a number of functions that create iterators for efficient looping.
Iterators are objects that can be irretated over.
Iterators are objects that can be iterated over.
For example a `for <variable> in <iterator>:` loop.

There are a number of functions in the itertools module that are useful for looping over data.
These functions often are also able to enchant the readability and/or maintainabillity of the code.
These functions often are also able to enchant the readability and/or maintainability of the code.

This concept will cover these functions and how to use them:

Expand Down Expand Up @@ -33,16 +33,16 @@ There are more functions in the itertools module, like:
- `dropwhile()`
- `filterfalse()`

These functions will be coverd in a later concept.
These functions will be covered in a later concept.

`count()`, `cycle()`, and`repeat()` is cataogorized as infinite iterators.
`count()`, `cycle()`, and`repeat()` is categorized as infinite iterators.
These iterators will never terminate and will keep looping forever.

## Iterators terminating on the shortest input sequence

### Chain()

`chain(iterable1, iterable2...)` creates an irretator of values from the iterables in the order they are given.
`chain(iterable1, iterable2...)` creates an iterator of values from the iterables in the order they are given.

```python
>>> import itertools
Expand Down Expand Up @@ -72,7 +72,7 @@ Using `tuple()`:

### chain.from_iterable()

Works like chain but takes a single nested iterable
`chain.from_iterable()` works like `chain` but takes a single nested iterable.
Then the method unpack that iterable into individual iterables.

```python
Expand Down Expand Up @@ -131,7 +131,7 @@ e c
If you are using the online editor then you don't need to worry about this.
```

`Pairwise(iterable)` was intruduced in Python 3.10 and returns an iterator of overlapping pairs of values from the input iterable.
`Pairwise(iterable)` was introduced in Python 3.10 and returns an iterator of overlapping pairs of values from the input iterable.

```python
>>> import itertools
Expand All @@ -147,7 +147,7 @@ Talk with Bethany about

### Zip_longest()

#### Explaning zip
#### Explaining zip

```exercism/caution
Pythons `zip()` function should not be confused with the zip compression format.
Expand All @@ -172,10 +172,10 @@ If the iterables are not the same length, then the iterator will stop when the s
[('x', 1, True),('y', 2, False)]
```

#### Explaning zip_longest
#### Explaining zip_longest

`zip_longest(iterator, <fillvalue=None>)` is a function from the `itertools` module.
Unlink `zip()`, it will not stop when the shortest iterable is exhausted.
Unlike `zip()`, it will not stop when the shortest iterable is exhausted.
If the iterables are not the same length, `fillvalue` will be used to pad missing values.
By the default the `fillvalue` is `None`.

Expand Down Expand Up @@ -244,10 +244,10 @@ You can also give it multiple iterables.
('A', 'x') ('A', 'y') ('B', 'x') ('B', 'y') ('C', 'x') ('C', 'y') ('D', 'x') ('D', 'y')
```

Here is an example of doing it wihout `product()`.
It looks similliar to the last example but since we have two iterables we need to nest the for loops.
Even though the proudct is given repeat=1.
The reasson to why it is only 2 for loops earlier was because we only had one iterable.
Here is an example of doing it without `product()`.
It looks similar to the last example but since we have two iterables we need to nest the for loops.
Even though the product is given repeat=1.
The reason to why it is only 2 for loops earlier was because we only had one iterable.
If we had two iterables and gave it repeat=2 we would need 4 for loops.
Since 2 \* 2 = 4.

Expand All @@ -262,7 +262,7 @@ Since 2 \* 2 = 4.
### Permutations()

`permutations(iterable, <r=None>)` creates an iterator of tuples.
It works like `product()` but it doesnt repeat values from a specific positoon from the iterable and can only take one iterable.
It works like `product()` but it doesn't repeat values from a specific position from the iterable and can only take one iterable.
The "r" keyword argument can be used to specify the number of times the input iterables are repeated.
By default the "r" keyword argument is None.
If "r" is None then the length of the iterable is used.
Expand Down Expand Up @@ -313,7 +313,7 @@ The difference between this and `combinations()` is that it can repeat values.
## Infinite iterators

Most of iterator from the `itertools` module get exhausted after a time.
But there are some that are infinite, these are known as infinte iterators.
But there are some that are infinite, these are known as infinite iterators.
These iterators will will keep producing values until you tell them to stop.

```exercism/note
Expand Down Expand Up @@ -351,7 +351,7 @@ Giving `count()` a negative step size will produces values in a descending order

### Cycle()

`cycle(iterable)` produces all values from the iterable in an infinte loop.
`cycle(iterable)` produces all values from the iterable in an infinite loop.
A `list`, `tuple`, `string`, `dict` or any other iterable can be used.

```python
Expand All @@ -369,7 +369,7 @@ A B C A B C A B C A

### Repeat()

`repeat(object, <times>)` produces the same value in an infinte loop.
`repeat(object, <times>)` produces the same value in an infinite loop.
Although if the optional times parameter is given, the value will produces that many times.
Meaning that it is not an infinite loop if that parameter is given.

Expand Down
6 changes: 3 additions & 3 deletions concepts/itertools/links.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[
{
"url": "https://docs.python.org/3/library/itertools.html",
"description": "Offical Python documentation for the itertools module."
"description": "Official Python documentation for the itertools module."
},
{
"url": "http://example.com/",
"description": "TODO: add new link (above) and write a short description here of the resource."
"url": "https://realpython.com/python-itertools/",
"description": "Real python, itertools in python"
},
{
"url": "http://example.com/",
Expand Down
48 changes: 24 additions & 24 deletions exercises/concept/ice-cream-stand/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@ This exercise could be solved with a lot of different approaches.
However, we would like you to practice using methods from the `itertools` module.
```

## 1. All flawors combinations
## 1. All flavors combinations

The ice cream stand wants to make an advertisement for how many different ice creams they can make.
They therefore want a program that can generate all the combinations of flawors they can make.
Each ice cream has a different amount of scoopes of flawors but you can't use the same flawor more than once.
They therefore want a program that can generate all the combinations of flavors they can make.
Each ice cream has a different amount of scoops of flavors but you can't use the same flavor more than once.

Implement a function `flawor_combinations()` that takes a `tuple` with an arbitrary number of flawors and an `int` which says how many scoopes.
Implement a function `ice_cream_combinations()` that takes a `tuple` with an arbitrary number of flavors and an `int` which says how many scoops.
The function should then `return` all combinations in the form of a `tuple`.

```python
>>> flawors = ['vanilla', 'chocolate', 'strawberry']
>>> flavors = ['vanilla', 'chocolate', 'strawberry']
>>> scoops = 2
>>> ice_cream_combinations(flawors, scoops)
>>> ice_cream_combinations(flavors, scoops)
(('vanilla', 'chocolate'), ('vanilla', 'strawberry'), ('chocolate', 'strawberry'))
```

## 2. Sprinkels
## 2. Sprinkles

They also want a program to optimize the process of adding sprinkels to the ice cream.
Currently they have a `list` of all ice cream order numbers and another `list` with `booleans` that say if the ice cream should have sprinkels or not.
They also want a program to optimize the process of adding sprinkles to the ice cream.
Currently they have a `list` of all ice cream order numbers and another `list` with `booleans` that say if the ice cream should have sprinkles or not.
The order numbers and the `booleans` are in the same order.

The ice cream stand has a machine that takes a `list` of orders that should have sprinkels and adds sprinkels to them.
Therefore they want a program that takes away all the orders that should not have sprinkels.
The ice cream stand has a machine that takes a `list` of orders that should have sprinkles and adds sprinkles to them.
Therefore they want a program that takes away all the orders that should not have sprinkles.

Implement a function `sprinkels()` that takes a `list` of order numbers and a `list` of `booleans` and returns a `list` of order numbers that should have sprinkels.
Implement a function `sprinkles()` that takes a `list` of order numbers and a `list` of `booleans` and returns a `list` of order numbers that should have sprinkles.

```python
>>> ice_creams = ['ice_cream_1', 'ice_cream_2', 'ice_cream_3']
Expand All @@ -44,33 +44,33 @@ Implement a function `sprinkels()` that takes a `list` of order numbers and a `l

## 3. Fill out ice cream menu

Currently the ice cream has to manualy write down the ice cream menu.
Currently the ice cream has to manually write down the ice cream menu.
Since they often make new ice creams they want a program that can generate the menu for them.

The menu is built up like this:

| Flavors | Toping | Sprinkels |
| Flavors | Toping | Sprinkles |
| ---------- | --------- | --------- |
| Strawberry | Cherry | Licorice |
| Choclate | Raspberry | Caramel |
| Chocolate | Raspberry | Caramel |
| Mint | Blueberry | None |
| Vanilla | None | None |

The ice cream stand has a `tuple` with all the ice cream flavors, a `tuple` with all the topings and a `tuple` with all the sprinkels.
They have set it up so the `tuple` of ice cream flavors, topings and sprinkels are in the same order.
The ice cream stand has a `tuple` with all the ice cream flavors, a `tuple` with all the toppings and a `tuple` with all the sprinkles.
They have set it up so the `tuple` of ice cream flavors, toppings and sprinkles are in the same order.

They want a program that takes **i**th index of the `tuple` of ice cream flavors, topings and sprinkels and returns a `tuple` with the ice cream menu.
They want a program that takes **i**th index of the `tuple` of ice cream flavors, toppings and sprinkles and returns a `tuple` with the ice cream menu.

All ice creams flavors doesn't have to have a toping or sprinkels.
If an ice cream doesn't have a toping or sprinkels the value should be `"None"`.
All ice creams flavors doesn't have to have a toping or sprinkles.
If an ice cream doesn't have a toping or sprinkles the value should be `"None"`.

Implement a function `fill_out_ice_cream_menu()` that accepts a `tuple` with ice cream flavors, a `tuple` with topings, and a `tuple` sprinkels.
Implement a function `fill_out_ice_cream_menu()` that accepts a `tuple` with ice cream flavors, a `tuple` with toppings, and a `tuple` sprinkles.
The function should `return` a `list` of `tuples` with the ice cream menu.

```python
>>> flavors = ('vanilla', 'chocolate', 'strawberry')
>>> topings = ('cherry', 'raspberry')
>>> sprinkels = ('licorice')
>>> fill_out_ice_cream_menu(flavors, topings, sprinkels)
>>> toppings = ('cherry', 'raspberry')
>>> sprinkles = ('licorice')
>>> fill_out_ice_cream_menu(flavors, toppings, sprinkles)
[('vanilla', 'cherry', 'licorice'), ('chocolate', 'raspberry', 'None'), ('strawberry', 'None', 'None')]
```
2 changes: 1 addition & 1 deletion exercises/concept/ice-cream-stand/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
]
},
"icon": "custom-set",
"blurb": "Learn about unpacking and multiple assignment in Python while helping Linus with his train control system."
"blurb": "Learn about itertools while helping the local ice cream stand"
}
73 changes: 45 additions & 28 deletions exercises/concept/ice-cream-stand/.meta/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,70 @@

## Goal

This concept exercise is meant to teach an understanding/use of `unpacking` and the `*` (splat) and `**` (double splat) operators in Python.

<br>
The goal of the concept exercise described in this issue is to teach understanding/use of the itertools module in Python.

## Learning objectives

- Understand/use `unpacking` through the use of `*` and `**` _prefix_ operators in various scenarios
- `*` and `**` as _prefixes_ ..... not to be confused with `*` (_multiply_) and `**` (_exponentiation_) as _infix_, or mathematical operators (**consider a link in the links doc or a mention in dig deeper.**)
- use in arguments to `functions`
- use in argument _capture_ for `functions` (_aka passing an arbitrary number of arguments -- *args * & \*\*kwargs_)
- use in iterable (_mainly `tuple` and `list`_) unpacking & packing
- use in `dict` unpacking & packing
- Understand/use `unpacking` via `multiple assignment`
- using `multiple assignment ` in place of `indexing`
- using `multiple assignment` + `*` in place of `slicing`
- unpacking plus "leftovers" via `*`
- Differences between straight `multiple assignment` and `*` & `**`
- Deep unpacking
Learn more about iteration tools the Python Standard Library provides through the itertools module.

Build and understanding of and use the following functions from the module, as well as practicing some of the recipes included:

At least one of the infinite itertators: `count()`, `cycle()`, or `repeat()`

- `accumulate()`
- `product()`
- `chain() & chain.from_iterable()`
- `groupby()`
- `islice()`
- `zip_longest() and the zip() built-in`
- `permutations()`
- `combinations()`

## Concepts

- `unpacking`
- `unpacking generalizations`
- `multiple assignment`
- iteration
- iterators
- itertools

## Topics that are Out of scope

- `classes`
- `comprehensions`
- `classes` & `class customization` beyond the use of the `itertools` methods.
- `class-inheritance` beyond what is needed to customize iteration using `itertools`
- `comprehensions` beyond what is needed to work with itertools
- `comprehensions` in `lambdas`
- `map()`, `filter()` or `functools.reduce()` in a `comprehension`
- `function-arguments` beyond explaining briefly how `*`, `**` work in function arguments.
- `functools` beyond `functools.reduce()`(_this will get its own exercise_)
- `generators`
- using an `assignment expression` or "walrus" operator (`:=`) alone or in a `lambda`
- coroutines
- `decorators` beyond what is needed to work with `itertools`
- functions and higher-order functions beyond what might be needed to work with itertools
- `functools` and related `map`, `filter()` and `functools.reduce()`(they have their own exercise which is a prerequisite to this one)
- `generators` beyond what might be needed to work with itertools (they have their own exercise which is a prerequisite to this one)
- `lambdas` beyond what might be needed to work with `itertools`
- using an assignment expression or "walrus" operator (:=)
- class decorators
- enums

## Prerequisites

- `basics`
- `bools`
- `booleans`
- `comparisons`
- `dicts`
- `rich-comparisons`
- **dicts**
- **dict-methods**
- **functions**
- **functional tools**
- _generators_
- **higher-order functions**
- **Identity methods is and is not**
- `iteration`
- `lists`
- `list-methods`
- `loops`
- `numbers`
- `sequences`
- **sets**
- `strings`
- `string-methods`
- `tuples`
- `loops`

## Representer

Expand Down
10 changes: 5 additions & 5 deletions exercises/concept/ice-cream-stand/.meta/exemplar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

import itertools

def ice_cream_combinations(flawors, scoops):
def ice_cream_combinations(flavors, scoops):
"""Return a tuple of all possible combinations without repetition.
:param flawors: list - aributary number of flawors.
:param flavors: list - arbitrary number of flavors.
:param scoops: int - number of scoops.
:return: tuple - tuple of all possible combinations.
"""

return tuple(itertools.combinations(flawors, scoops))
return tuple(itertools.combinations(flavors, scoops))


def sprinkles(ice_creams, selector):
"""Get the ice cream with sprinkles.
:param ice_creams: list - ice_cream_orders.
:param selector: list - which ice creams that needs sprinkels.
:param selector: list - which ice creams that needs sprinkles.
:return: list - ice creams that needs sprinkles.
"""
return list(itertools.compress(ice_creams, selector))
Expand All @@ -27,7 +27,7 @@ def fill_out_ice_cream_menu(flavors, toping, sprinkles):
"""Fill out ice cream menu.
:param flavors: tuple - ice cream flavors.
:param toping: tuple - ice cream topings.
:param toping: tuple - ice cream toppings.
:param sprinkles: tuple - ice cream sprinkles.
:return: list - ice cream menu filled out.
"""
Expand Down
Loading

0 comments on commit 8817012

Please sign in to comment.