Skip to content

Commit

Permalink
Merge branch 'main' into pr/3457
Browse files Browse the repository at this point in the history
  • Loading branch information
BethanyG committed Jul 21, 2023
2 parents d0aa70a + be79419 commit 9d08faf
Show file tree
Hide file tree
Showing 242 changed files with 590 additions and 349 deletions.
40 changes: 27 additions & 13 deletions bin/generate_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,19 @@ def format_file(path: Path) -> NoReturn:


def check_template(slug: str, tests_path: Path, tmpfile: Path):
"""Generate a new test file and diff against existing file.
Note: The timestamp in each test file creates issues with
Python difflib, so it is skipped when being prepped
for diff.
You can see this "skipping" on lines 281 & 283.
However, this rather crude method creates
an empty "false positive" diff. This empty diff is
then skipped in lines 293 & 294, so that it can be
considered a pass..
"""

try:
check_ok = True
if not tmpfile.is_file():
Expand All @@ -271,24 +284,25 @@ def check_template(slug: str, tests_path: Path, tmpfile: Path):
check_ok = False
if check_ok and not filecmp.cmp(tmpfile, tests_path):
with tests_path.open() as f:
for line in range(4):
next(f)
current_lines = f.readlines()
current_lines = f.readlines()[3:]
with tmpfile.open() as f:
for line in range(4):
next(f)
rendered_lines = f.readlines()
diff = difflib.unified_diff(
rendered_lines = f.readlines()[3:]

diff = list(difflib.unified_diff(
current_lines,
rendered_lines,
fromfile=f"[current] {tests_path.name}",
tofile=f"[generated] {tmpfile.name}",
)
logger.debug(f"{slug}: ##### DIFF START #####")
for line in diff:
logger.debug(line.strip())
logger.debug(f"{slug}: ##### DIFF END #####")
check_ok = False
lineterm="\n",
))
if not diff:
check_ok = True
else:
logger.debug(f"{slug}: ##### DIFF START #####")
for line in diff:
logger.debug(line.strip())
logger.debug(f"{slug}: ##### DIFF END #####")
check_ok = False
if not check_ok:
logger.error(
f"{slug}: check failed; tests must be regenerated with bin/generate_tests.py"
Expand Down
12 changes: 6 additions & 6 deletions concepts/unpacking-and-multiple-assignment/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ This is often used in multiple assignment to group all "leftover" elements that
It is common in Python to also exploit this unpacking/packing behavior when using or defining functions that take an arbitrary number of positional or keyword arguments.
You will often see these "special" parameters defined as `def some_function(*args, **kwargs)` and the "special" arguments used as `some_function(*some_tuple, **some_dict)`.

```exercism/caution
~~~~exercism/caution
`*<variable_name>` and `**<variable_name>` should not be confused with `*` and `**`. While `*` and `**` are used for multiplication and exponentiation respectively, `*<variable_name>` and `**<variable_name>` are used as packing and unpacking operators.
```
~~~~

## Multiple assignment

Expand Down Expand Up @@ -69,9 +69,9 @@ Since `tuples` are immutable, you can't swap elements in a `tuple`.

## Unpacking

```exercism/note
~~~~exercism/note
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.
Since values appear within `lists`/`tuples` in a specific order, they are unpacked into variables in the same order:
Expand Down Expand Up @@ -305,13 +305,13 @@ c = 3
You can also write parameters before `*args` to allow for specific positional arguments.
Individual keyword arguments then have to appear before `**kwargs`.

```exercism/caution
~~~~exercism/caution
[Arguments have to be structured](https://www.python-engineer.com/courses/advancedpython/18-function-arguments/) like this:
`def my_function(<positional_args>, *args, <key-word_args>, **kwargs)`
If you don't follow this order then you will get an error.
```
~~~~

```python
>>> def my_function(a, b, *args):
Expand Down
4 changes: 2 additions & 2 deletions concepts/unpacking-and-multiple-assignment/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ This is often used in multiple assignment to group all "leftover" elements that
It is common in Python to also exploit this unpacking/packing behavior when using or defining functions that take an arbitrary number of positional or keyword arguments.
You will often see these "special" parameters defined as `def some_function(*args, **kwargs)` and the "special" arguments used as `some_function(*some_tuple, **some_dict)`.

```exercism/caution
~~~~exercism/caution
`*<variable_name>` and `**<variable_name>` should not be confused with `*` and `**`. While `*` and `**` are used for multiplication and exponentiation respectively, `*<variable_name>` and `**<variable_name>` are used as packing and unpacking operators.
```
~~~~

[multiple assignment]: https://www.geeksforgeeks.org/assigning-multiple-variables-in-one-line-in-python/
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"highlightjs_language": "python"
},
"test_runner": {
"average_run_time": 2.0
"average_run_time": 2
},
"files": {
"solution": ["%{snake_slug}.py"],
Expand Down
31 changes: 31 additions & 0 deletions config/complexnumbers_template.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

import math
{{ macros.header(imports=imports, ignore=ignore) }}

{%- macro test_cases_recursive(cases) -%}
{% for case in cases -%}
{% if "cases" in case %}
# {{ case["description"] }}
{{ test_cases_recursive(case["cases"]) }}
{% else %}
{{ test_case(case) }}
{% endif -%}
{% endfor -%}
{% endmacro %}

{% if not additional_tests -%}
{%- macro additional_tests() -%}
{{ test_cases_recursive(additional_cases) }}
{% endmacro %}
{%- endif %}

class {{ exercise | camel_case }}Test(unittest.TestCase):
{{ test_cases_recursive(cases) }}

{% if additional_cases | length -%}
# Additional tests for this track
{{ additional_tests() }}
{%- endif %}

9 changes: 0 additions & 9 deletions config/generator_macros.j2
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
{%- endmacro %}

{% macro header(imports=[], ignore=[]) -%}
{{ canonical_ref() }}

import unittest

Expand All @@ -38,14 +37,6 @@ from {{ exercise | to_snake }} import ({% if imports -%}
return self.assertRaisesRegex(exception, r".+")
{%- endmacro %}

{% macro footer(_has_error_case) -%}
{% if has_error_case or _has_error_case %}
{{ utility() }}
{% endif %}
if __name__ == '__main__':
unittest.main()
{%- endmacro %}

{% macro empty_set(set, list, class_name) -%}
{%- if list|length > 0 -%}
{{ set }} = {{ class_name }}({{ list }})
Expand Down
3 changes: 2 additions & 1 deletion config/master_template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header(imports=imports, ignore=ignore) }}

{%- macro test_cases_recursive(cases) -%}
Expand All @@ -25,4 +27,3 @@ class {{ exercise | camel_case }}Test(unittest.TestCase):
# Additional tests for this track
{{ additional_tests() }}
{%- endif %}
{{ macros.footer() }}
8 changes: 4 additions & 4 deletions exercises/concept/locomotive-engineer/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Your friend Linus is a Locomotive Engineer who drives cargo trains between citie
Although they are amazing at handling trains, they are not amazing at handling logistics or computers.
They would like to enlist your programming help organizing train details and correcting mistakes in route data.

```exercism/note
~~~~exercism/note
This exercise could easily be solved using slicing, indexing, and various `dict` methods.
However, we would like you to practice packing, unpacking, and multiple assignment in solving each of the tasks below.
```
~~~~

## 1. Create a list of all wagons

Expand Down Expand Up @@ -75,9 +75,9 @@ The first `dict` contains the origin and destination cities the train route runs
The second `dict` contains other routing details such as train speed, length, or temperature.
The function should return a consolidated `dict` with all routing information.

```exercism/note
~~~~exercism/note
The second `dict` can contain different/more properties than the ones shown in the example.
```
~~~~

```python
>>> extend_route_information({"from": "Berlin", "to": "Hamburg"}, {"length": "100", "speed": "50"})
Expand Down
12 changes: 6 additions & 6 deletions exercises/concept/locomotive-engineer/.docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Unpacked values can then be assigned to variables within the same statement, whi

The special operators `*` and `**` are often used in unpacking contexts and with multiple assignment.

```exercism/caution
~~~~exercism/caution
`*<variable_name>` and `**<variable_name>` should not be confused with `*` and `**`. While `*` and `**` are used for multiplication and exponentiation respectively, `*<variable_name>` and `**<variable_name>` are used as packing and unpacking operators.
```
~~~~

## Multiple assignment

Expand Down Expand Up @@ -57,9 +57,9 @@ Since `tuples` are immutable, you can't swap elements in a `tuple`.

## Unpacking

```exercism/note
~~~~exercism/note
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.
Since values appear within `lists`/`tuples` in a specific order, they are unpacked into variables in the same order:
Expand Down Expand Up @@ -293,13 +293,13 @@ c = 3
You can also write parameters before `*args` to allow for specific positional arguments.
Individual keyword arguments then have to appear before `**kwargs`.

```exercism/caution
~~~~exercism/caution
[Arguments have to be structured](https://www.python-engineer.com/courses/advancedpython/18-function-arguments/) like this:
`def my_function(<positional_args>, *args, <key-word_args>, **kwargs)`
If you don't follow this order then you will get an error.
```
~~~~

```python
>>> def my_function(a, b, *args):
Expand Down
5 changes: 4 additions & 1 deletion exercises/practice/acronym/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header()}}

{% macro test_case(case) -%}
{%- set input = case["input"] -%}
Expand All @@ -8,7 +11,7 @@
"{{ case["expected"] }}"
)
{%- endmacro %}
{{ macros.header()}}


class {{ exercise | camel_case }}Test(unittest.TestCase):
{% for case in cases %}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/acronym/acronym_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/acronym/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
5 changes: 3 additions & 2 deletions exercises/practice/affine-cipher/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header()}}

{% macro test_supercase(supercase) %}
{% for case in supercase["cases"] -%}
Expand All @@ -25,8 +28,6 @@ def test_{{ case["description"] | to_snake }}(self):
{% endif -%}
{%- endmacro %}

{{ macros.header() }}

class {{ exercise | camel_case }}Test(unittest.TestCase):
{% for supercase in cases -%}
{{ test_supercase(supercase) }}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/affine-cipher/affine_cipher_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/affine-cipher/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
5 changes: 3 additions & 2 deletions exercises/practice/all-your-base/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header()}}

{%- macro func_call(case) -%}
{{ case["property"] }}(
Expand All @@ -22,8 +25,6 @@
{%- endif %}
{% endmacro %}

{{ macros.header() }}

class {{ exercise | camel_case }}Test(unittest.TestCase):
{% for case in cases -%}
{{ test_case(case) }}
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/all-your-base/all_your_base_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/all-your-base/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
2 changes: 2 additions & 0 deletions exercises/practice/allergies/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header(imports=[ exercise | camel_case ]) }}

class {{ exercise | camel_case }}Test(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/allergies/allergies_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/allergies/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
2 changes: 2 additions & 0 deletions exercises/practice/alphametics/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header() }}

class {{ exercise | camel_case }}Test(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/alphametics/alphametics_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/alphametics/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
1 change: 1 addition & 0 deletions exercises/practice/anagram/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header() }}

Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/anagram/anagram_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/anagram/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
2 changes: 2 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header() }}

class {{ exercise | camel_case }}Test(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/armstrong-numbers/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
2 changes: 2 additions & 0 deletions exercises/practice/atbash-cipher/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}

{{ macros.header() }}

class {{ exercise | camel_case }}Test(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion exercises/practice/atbash-cipher/atbash_cipher_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/atbash-cipher/canonical-data.json
# File last updated on 2023-07-16
# File last updated on 2023-07-20

import unittest

Expand Down
Loading

0 comments on commit 9d08faf

Please sign in to comment.