From 0f020dd3d777f558b51ad6c55356ee5509d76ceb Mon Sep 17 00:00:00 2001 From: Victor Payno Date: Thu, 4 Apr 2024 18:38:26 -0700 Subject: [PATCH 1/4] python/plane-tickets: download exercise --- python/plane-tickets/.exercism/config.json | 23 ++ python/plane-tickets/.exercism/metadata.json | 1 + python/plane-tickets/HELP.md | 130 +++++++++ python/plane-tickets/HINTS.md | 24 ++ python/plane-tickets/README.md | 265 +++++++++++++++++++ python/plane-tickets/generators.py | 60 +++++ python/plane-tickets/generators_test.py | 137 ++++++++++ 7 files changed, 640 insertions(+) create mode 100644 python/plane-tickets/.exercism/config.json create mode 100644 python/plane-tickets/.exercism/metadata.json create mode 100644 python/plane-tickets/HELP.md create mode 100644 python/plane-tickets/HINTS.md create mode 100644 python/plane-tickets/README.md create mode 100644 python/plane-tickets/generators.py create mode 100644 python/plane-tickets/generators_test.py diff --git a/python/plane-tickets/.exercism/config.json b/python/plane-tickets/.exercism/config.json new file mode 100644 index 00000000..12228348 --- /dev/null +++ b/python/plane-tickets/.exercism/config.json @@ -0,0 +1,23 @@ +{ + "authors": [ + "J08K" + ], + "contributors": [ + "BethanyG", + "kytrinyx", + "meatball133" + ], + "files": { + "solution": [ + "generators.py" + ], + "test": [ + "generators_test.py" + ], + "exemplar": [ + ".meta/exemplar.py" + ] + }, + "icon": "new-passport", + "blurb": "Learn about generators by assigning seats to passengers on Anaconda Airlines." +} diff --git a/python/plane-tickets/.exercism/metadata.json b/python/plane-tickets/.exercism/metadata.json new file mode 100644 index 00000000..9745fcd4 --- /dev/null +++ b/python/plane-tickets/.exercism/metadata.json @@ -0,0 +1 @@ +{"track":"python","exercise":"plane-tickets","id":"64bebba2c2354807b821de9b93c9cfab","url":"https://exercism.org/tracks/python/exercises/plane-tickets","handle":"vpayno","is_requester":true,"auto_approve":false} \ No newline at end of file diff --git a/python/plane-tickets/HELP.md b/python/plane-tickets/HELP.md new file mode 100644 index 00000000..3ed49f32 --- /dev/null +++ b/python/plane-tickets/HELP.md @@ -0,0 +1,130 @@ +# Help + +## Running the tests + +We use [pytest][pytest: Getting Started Guide] as our website test runner. +You will need to install `pytest` on your development machine if you want to run tests for the Python track locally. +You should also install the following `pytest` plugins: + +- [pytest-cache][pytest-cache] +- [pytest-subtests][pytest-subtests] + +Extended information can be found in our website [Python testing guide][Python track tests page]. + + +### Running Tests + +To run the included tests, navigate to the folder where the exercise is stored using `cd` in your terminal (_replace `{exercise-folder-location}` below with your path_). +Test files usually end in `_test.py`, and are the same tests that run on the website when a solution is uploaded. + +Linux/MacOS +```bash +$ cd {path/to/exercise-folder-location} +``` + +Windows +```powershell +PS C:\Users\foobar> cd {path\to\exercise-folder-location} +``` + +
+ +Next, run the `pytest` command in your terminal, replacing `{exercise_test.py}` with the name of the test file: + +Linux/MacOS +```bash +$ python3 -m pytest -o markers=task {exercise_test.py} +==================== 7 passed in 0.08s ==================== +``` + +Windows +```powershell +PS C:\Users\foobar> py -m pytest -o markers=task {exercise_test.py} +==================== 7 passed in 0.08s ==================== +``` + + +### Common options +- `-o` : override default `pytest.ini` (_you can use this to avoid marker warnings_) +- `-v` : enable verbose output. +- `-x` : stop running tests on first failure. +- `--ff` : run failures from previous test before running other test cases. + +For additional options, use `python3 -m pytest -h` or `py -m pytest -h`. + + +### Fixing warnings + +If you do not use `pytest -o markers=task` when invoking `pytest`, you might receive a `PytestUnknownMarkWarning` for tests that use our new syntax: + +```bash +PytestUnknownMarkWarning: Unknown pytest.mark.task - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html +``` + +To avoid typing `pytest -o markers=task` for every test you run, you can use a `pytest.ini` configuration file. +We have made one that can be downloaded from the top level of the Python track directory: [pytest.ini][pytest.ini]. + +You can also create your own `pytest.ini` file with the following content: + +```ini +[pytest] +markers = + task: A concept exercise task. +``` + +Placing the `pytest.ini` file in the _root_ or _working_ directory for your Python track exercises will register the marks and stop the warnings. +More information on pytest marks can be found in the `pytest` documentation on [marking test functions][pytest: marking test functions with attributes] and the `pytest` documentation on [working with custom markers][pytest: working with custom markers]. + +Information on customizing pytest configurations can be found in the `pytest` documentation on [configuration file formats][pytest: configuration file formats]. + + +### Extending your IDE or Code Editor + +Many IDEs and code editors have built-in support for using `pytest` and other code quality tools. +Some community-sourced options can be found on our [Python track tools page][Python track tools page]. + +[Pytest: Getting Started Guide]: https://docs.pytest.org/en/latest/getting-started.html +[Python track tools page]: https://exercism.org/docs/tracks/python/tools +[Python track tests page]: https://exercism.org/docs/tracks/python/tests +[pytest-cache]:http://pythonhosted.org/pytest-cache/ +[pytest-subtests]:https://github.com/pytest-dev/pytest-subtests +[pytest.ini]: https://github.com/exercism/python/blob/main/pytest.ini +[pytest: configuration file formats]: https://docs.pytest.org/en/6.2.x/customize.html#configuration-file-formats +[pytest: marking test functions with attributes]: https://docs.pytest.org/en/6.2.x/mark.html#raising-errors-on-unknown-marks +[pytest: working with custom markers]: https://docs.pytest.org/en/6.2.x/example/markers.html#working-with-custom-markers + +## Submitting your solution + +You can submit your solution using the `exercism submit generators.py` command. +This command will upload your solution to the Exercism website and print the solution page's URL. + +It's possible to submit an incomplete solution which allows you to: + +- See how others have completed the exercise +- Request help from a mentor + +## Need to get help? + +If you'd like help solving the exercise, check the following pages: + +- The [Python track's documentation](https://exercism.org/docs/tracks/python) +- The [Python track's programming category on the forum](https://forum.exercism.org/c/programming/python) +- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5) +- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) + +Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. + +Below are some resources for getting help if you run into trouble: + +- [The PSF](https://www.python.org) hosts Python downloads, documentation, and community resources. +- [The Exercism Community on Discord](https://exercism.org/r/discord) +- [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community. +- [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners. +- [#python on Libera.chat](https://www.python.org/community/irc/) this is where the core developers for the language hang out and get work done. +- [Python Community Forums](https://discuss.python.org/) +- [Free Code Camp Community Forums](https://forum.freecodecamp.org/) +- [CodeNewbie Community Help Tag](https://community.codenewbie.org/t/help) +- [Pythontutor](http://pythontutor.com/) for stepping through small code snippets visually. + +Additionally, [StackOverflow](http://stackoverflow.com/questions/tagged/python) is a good spot to search for your problem/question to see if it has been answered already. + If not - you can always [ask](https://stackoverflow.com/help/how-to-ask) or [answer](https://stackoverflow.com/help/how-to-answer) someone else's question. \ No newline at end of file diff --git a/python/plane-tickets/HINTS.md b/python/plane-tickets/HINTS.md new file mode 100644 index 00000000..e00e7f76 --- /dev/null +++ b/python/plane-tickets/HINTS.md @@ -0,0 +1,24 @@ +# Hints + +## 1. Generate seat letters + +- The returned value should be of _type_ `generator`. +- You can have a sequence of letters from `A` to `D` and cycle through them. +- Use `yield` to return the next letter. + +## 2. Generate seats + +- The returned value should be of _type_ `generator`. +- Row `13` should be skipped, so go from `12` to `14`. +- Keep in mind that the returned values should be ordered from low to high. `1A, 1B, 2A, ...` +- Here it might be good to reuse or call functions you have already defined. + +## 3. Assign seats to passengers + +- Make sure your seat numbers do not have any spaces in them. +- Here it might be good to reuse or call functions you have already defined. + +## 4. Ticket codes + +- You can use `len()` to get the length of a string. +- You can use `"" * ` to repeat a string. \ No newline at end of file diff --git a/python/plane-tickets/README.md b/python/plane-tickets/README.md new file mode 100644 index 00000000..f793315d --- /dev/null +++ b/python/plane-tickets/README.md @@ -0,0 +1,265 @@ +# Plane Tickets + +Welcome to Plane Tickets on Exercism's Python Track. +If you need help running the tests or submitting your code, check out `HELP.md`. +If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :) + +## Introduction + +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 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_). +When the generator resumes, it picks up state from the suspension - unlike regular functions which reset with every call. + + +## Constructing a generator + +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. + +An example is a function that returns the _squares_ from a given list of numbers. +As currently written, all input must be processed before any values can be returned: + +```python +>>> def squares(list_of_numbers): +... squares = [] +... for number in list_of_numbers: +... squares.append(number ** 2) +... return squares +``` + +You can convert that function into a generator like this: + +```python +>>> def squares_generator(list_of_numbers): +... for number in list_of_numbers: +... yield number ** 2 +``` + +The rationale behind this is that you use a generator when you do not need to produce all the values _at once_. +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. + +To use the `squares_generator()` generator: + +```python +>>> squared_numbers = squares_generator([1, 2, 3, 4]) + +>>> for square in squared_numbers: +... print(square) +... +1 +4 +9 +16 +``` + +Values within a `generator` can also be produced/accessed via the `next()` function. +`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: + +```python +>>> squared_numbers = squares_generator([1, 2]) + +>>> next(squared_numbers) +1 +>>> next(squared_numbers) +4 +``` + +When a `generator-iterator` is fully consumed and has no more values to return, it throws a `StopIteration` error. + +```python +>>> next(squared_numbers) +Traceback (most recent call last): + File "", line 1, in +StopIteration +``` + + +~~~~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 +~~~~ + + +## The yield expression + +The [yield expression][yield expression] is very similar to the `return` expression. +_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. +When `yield` is evaluated, it pauses the execution of the enclosing function and returns any values of the function _at that point in time_. +The function then _stays in scope_, and when `__next__()` is called, execution resumes until `yield` is encountered again. + + +~~~~exercism/note +Using `yield` expressions is prohibited outside of functions. +~~~~ + +```python +>>> def infinite_sequence(): +... current_number = 0 +... while True: +... yield current_number +... current_number += 1 + +>>> lets_try = infinite_sequence() +>>> lets_try.__next__() +0 +>>> lets_try.__next__() +1 +``` + + +## Why Create a Generator? + +Generators are useful in a lot of applications. + +When working with a potentially large collection of values, you might not want to put all of them into memory. +A generator can be used to work on larger data piece-by-piece, saving memory and improving performance. + +Generators are also very helpful when a process or calculation is _complex_, _expensive_, or _infinite_: + +```python +>>> def infinite_sequence(): +... current_number = 0 +... while True: +... yield current_number +... current_number += 1 +``` + +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 +[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 + +## Instructions + +Conda Airlines is the programming-world's biggest airline, with over 10,000 flights a day! + +They are currently assigning all seats to passengers by hand; this will need to be automated. + +They have asked _you_ to create software to automate passenger seat assignments. +They require your software to be memory efficient and performant. + +## 1. Generate seat letters + +Conda wants to generate seat letters for their airplanes. +An airplane is made of rows of seats. +Each row has _4 seats_. +The seats in each row are always named `A`, `B`, `C`, and `D`. +The first seat in the row is `A`, the second seat in the row is `B`, and so on. +After reaching `D`, it should start again with `A`. + +Implement a function `generate_seat_letters()` that accepts an `int` that holds how many seat letters to be generated. +The function should then return an _iterable_ of seat letters. + +```python +>>> letters = generate_seat_letters(4) +>>> next(letters) +"A" +>>> next(letters) +"B" +``` + +## 2. Generate seats + +Conda wants a system that can generate a given number of seats for their airplanes. +Each airplane has _4 seats_ in each row. +The rows are defined using numbers, starting from `1` and going up. +The seats should be ordered, like: `1A`, `1B`, `1C`, `1D`, `2A`, `2B`, `2C`, `2D`, `3A`, `3B`, `3C`, `3D`, ... + +Here is an example: + +| x | 1 | 2 | +| :---------: | :-: | :-: | +| Row | 5 | 21 | +| Seat letter | A | D | +| Result | 5A | 21D | + +Many airlines do not have _row_ number 13 on their flights, due to superstition amongst passengers. +Conda Airlines also follows this convention, so make sure you _don't_ generate seats for _row_ number 13. + +Implement a function `generate_seats()` that accepts an `int` that holds how many seats to be generated. +The function should then return an _iterable_ of seats given. + +```python +>>> seats = generate_seats(10) +>>> next(seats) +"1A" +>>> next(seats) +"1B" +``` + +## 3. Assign seats to passengers + +Now that you have a function that generates seats, you can use it to assign seats to passengers. + +Implement a function `assign_seats()` that accepts a `list` of passenger names. +The function should then return a _dictionary_ of `passenger` as _key_, and `seat_number` as _value_. + +```python +>>> passengers = ['Jerimiah', 'Eric', 'Bethany', 'Byte', 'SqueekyBoots', 'Bob'] + +>>> assign_seats(passengers) +{'Jerimiah': '1A', 'Eric': '1B', 'Bethany': '1C', 'Byte': '1D', 'SqueekyBoots': '2A', 'Bob': '2B'} +``` + +## 4. Ticket codes + +Conda Airlines would like to have a unique code for each ticket. +Since they are a big airline, they have a lot of flights. +This means that there are multiple flights with the same seat number. +They want you to create a system that creates a unique ticket that is _12_ characters long string code for identification. + +This code begins with the `assigned_seat` followed by the `flight_id`. +The rest of the code is appended by `0s`. + +Implement a function `generate_codes(, )` that accepts a `list` of `seat_numbers` and a `string` with the flight number. +The function should then return a `generator` that yields a `ticket_number`. + +```python +>>> seat_numbers = ['1A', '17D'] +>>> flight_id = 'CO1234' +>>> ticket_ids = generate_codes(seat_numbers, flight_id) + +>>> next(ticket_ids) +'1ACO12340000' +>>> next(ticket_ids) +'17DCO1234000' +``` + +## Source + +### Created by + +- @J08K + +### Contributed to by + +- @BethanyG +- @kytrinyx +- @meatball133 \ No newline at end of file diff --git a/python/plane-tickets/generators.py b/python/plane-tickets/generators.py new file mode 100644 index 00000000..2f88c061 --- /dev/null +++ b/python/plane-tickets/generators.py @@ -0,0 +1,60 @@ +"""Functions to automate Conda airlines ticketing system.""" + + +def generate_seat_letters(number): + """Generate a series of letters for airline seats. + + :param number: int - total number of seat letters to be generated. + :return: generator - generator that yields seat letters. + + Seat letters are generated from A to D. + After D it should start again with A. + + Example: A, B, C, D + + """ + + pass + + +def generate_seats(number): + """Generate a series of identifiers for airline seats. + + :param number: int - total number of seats to be generated. + :return: generator - generator that yields seat numbers. + + A seat number consists of the row number and the seat letter. + + There is no row 13. + Each row has 4 seats. + + Seats should be sorted from low to high. + + Example: 3C, 3D, 4A, 4B + + """ + + pass + +def assign_seats(passengers): + """Assign seats to passengers. + + :param passengers: list[str] - a list of strings containing names of passengers. + :return: dict - with the names of the passengers as keys and seat numbers as values. + + Example output: {"Adele": "1A", "Björk": "1B"} + + """ + + pass + +def generate_codes(seat_numbers, flight_id): + """Generate codes for a ticket. + + :param seat_numbers: list[str] - list of seat numbers. + :param flight_id: str - string containing the flight identifier. + :return: generator - generator that yields 12 character long ticket codes. + + """ + + pass diff --git a/python/plane-tickets/generators_test.py b/python/plane-tickets/generators_test.py new file mode 100644 index 00000000..12a3532a --- /dev/null +++ b/python/plane-tickets/generators_test.py @@ -0,0 +1,137 @@ +import inspect +import unittest +import pytest + +from generators import ( + generate_seat_letters, + generate_seats, + assign_seats, + generate_codes +) + +class PlaneTicketsTest(unittest.TestCase): + @pytest.mark.task(taskno=1) + def test_task1_returns_generator(self): + """Test if generate_seat_letters() returns a generator type.""" + + number = 5 + error_message = (f'Called generate_seat_letters({number}). ' + f'The function returned a {type(generate_seat_letters(number))} type, ' + f"but the tests expected the function to return a type.") + + self.assertTrue(inspect.isgenerator(generate_seat_letters(number)), msg=error_message) + + @pytest.mark.task(taskno=1) + def test_generate_seat_letters(self): + test_data = [1, 2, 3, 4, 5] + result_data = [["A"], + ["A", "B"], + ["A", "B", "C"], + ["A", "B", "C", "D"], + ["A", "B", "C", "D", "A"]] + + for variant, (number, expected) in enumerate(zip(test_data, result_data), start=1): + with self.subTest(f"variation #{variant}", number=number, expected=expected): + actual_result = list(generate_seat_letters(number)) + error_message = (f'Called generate_seat_letters({number}). ' + f'The function returned {actual_result}, but the tests ' + f'expected {expected} when generating {number} seat(s).') + + self.assertEqual(actual_result, expected, msg=error_message) + + @pytest.mark.task(taskno=2) + def test_task2_returns_generator(self): + """Test if generate_seats() returns a generator type.""" + + number = 7 + error_message = (f'Called generate_seats({number}). ' + f'The function returned a {type(generate_seats(number))} type, ' + f"but the tests expected the function to return a type.") + + self.assertTrue(inspect.isgenerator(generate_seats(number)), msg=error_message) + + @pytest.mark.task(taskno=2) + def test_generate_seats(self): + test_data = [1, 2, 3, 4, 5] + result_data = [["1A"], + ["1A", "1B"], + ["1A", "1B", "1C"], + ["1A", "1B", "1C", "1D"], + ["1A", "1B", "1C", "1D", "2A"]] + + for variant, (number, expected) in enumerate(zip(test_data, result_data), start=1): + with self.subTest(f"variation #{variant}", number=number, expected=expected): + actual_result = list(generate_seats(number)) + error_message = (f'Called generate_seats({number}). ' + f'The function returned {actual_result}, but the tests ' + f'expected {expected} when generating {number} seat(s).') + + self.assertEqual(actual_result, expected, msg=error_message) + + @pytest.mark.task(taskno=2) + def test_generate_seats_skips_row_13(self): + test_data = [14 * 4] + result_data = [["1A", "1B", "1C", "1D", "2A", "2B", "2C", "2D", + "3A", "3B", "3C", "3D", "4A", "4B", "4C", "4D", + "5A", "5B", "5C", "5D", "6A", "6B", "6C", "6D", + "7A", "7B", "7C", "7D", "8A", "8B", "8C", "8D", + "9A", "9B", "9C", "9D", "10A", "10B", "10C", "10D", + "11A", "11B", "11C", "11D", "12A", "12B", "12C", "12D", + "14A", "14B", "14C", "14D", "15A", "15B", "15C", "15D"]] + + for variant, (number, expected) in enumerate(zip(test_data, result_data), start=1): + with self.subTest(f"variation #{variant}", number=number, expected=expected): + actual_result = list(generate_seats(number)) + error_message = (f'Called generate_seats({number}). ' + f'The function returned {actual_result}, but the tests ' + f'expected: {expected}, when generating {number} seat(s).') + + self.assertEqual(actual_result, expected, msg=error_message) + + @pytest.mark.task(taskno=3) + def test_assign_seats(self): + test_data = [["Passenger1", "Passenger2", "Passenger3", "Passenger4", "Passenger5"], + ["TicketNo=5644", "TicketNo=2273", "TicketNo=493", "TicketNo=5411", "TicketNo=824"]] + result_data = [{"Passenger1": "1A", "Passenger2": "1B", + "Passenger3": "1C", "Passenger4": "1D", "Passenger5": "2A"}, + {"TicketNo=5644": "1A", "TicketNo=2273": "1B", + "TicketNo=493": "1C", "TicketNo=5411": "1D", "TicketNo=824": "2A"}] + + for variant, (passengers, expected) in enumerate(zip(test_data, result_data), start=1): + with self.subTest(f"variation #{variant}", passengers=passengers, expected=expected): + actual_result = assign_seats(passengers) + error_message = (f'Called assign_seats({passengers}). ' + f'The function returned {actual_result}, but the tests ' + f'expected {expected}, when assigning seats.') + + self.assertEqual(actual_result, expected, msg=error_message) + + @pytest.mark.task(taskno=4) + def test_task4_returns_generator(self): + """Test if generate_codes() returns a generator type.""" + + seat_numbers, flight_id = "11B", "HA80085" + error_message = (f'Called generate_codes({seat_numbers}, {flight_id}). ' + f'The function returned a {type(generate_codes(seat_numbers, flight_id))} type, ' + f"but the tests expected the function to return a type.") + + self.assertTrue(inspect.isgenerator(generate_codes(seat_numbers, flight_id)), msg=error_message) + + + @pytest.mark.task(taskno=4) + def test_generate_codes(self): + test_data = [(["12A", "38B", "69C", "102B"],"KL1022"), + (["22C", "88B", "33A", "44B"], "DL1002")] + result_data = [['12AKL1022000', '38BKL1022000', '69CKL1022000', '102BKL102200'], + ['22CDL1002000', '88BDL1002000', '33ADL1002000', '44BDL1002000']] + + for variant, ((seat_numbers, flight_id), expected) in enumerate(zip(test_data, result_data), start=1): + with self.subTest(f"variation #{variant}", seat_numbbers=seat_numbers, + flight_id=flight_id, expected=expected): + + actual_result = list(generate_codes(seat_numbers, flight_id)) + error_message = (f'Called generate_codes({seat_numbers}, {flight_id}). ' + f'The function returned {actual_result}, but the tests ' + f'expected {expected} when generating ticket numbers.') + + self.assertEqual(list(generate_codes(seat_numbers, flight_id)), expected, msg=error_message) From 002a1713191700f7f5d202bded88333c97a0698b Mon Sep 17 00:00:00 2001 From: Victor Payno Date: Thu, 4 Apr 2024 20:21:55 -0700 Subject: [PATCH 2/4] python/plane-tickets: 1st iteration - py3.12 --- python/README.md | 1 + python/plane-tickets/.coverage | Bin 0 -> 53247 bytes python/plane-tickets/.coverage.xml | 57 ++ python/plane-tickets/.coveragerc | 2 + python/plane-tickets/.pylintrc | 1 + python/plane-tickets/README.md | 7 +- python/plane-tickets/generators.py | 73 ++- python/plane-tickets/generators.py,cover | 105 ++++ python/plane-tickets/pytest.ini | 5 + python/plane-tickets/run-tests-python.txt | 502 ++++++++++++++++++ .../src/plane_tickets/__init__.py | 0 .../src/plane_tickets/generators.py | 1 + python/plane-tickets/test/__init__.py | 0 python/plane-tickets/test/generators_test.py | 1 + 14 files changed, 740 insertions(+), 15 deletions(-) create mode 100644 python/plane-tickets/.coverage create mode 100644 python/plane-tickets/.coverage.xml create mode 100644 python/plane-tickets/.coveragerc create mode 120000 python/plane-tickets/.pylintrc create mode 100644 python/plane-tickets/generators.py,cover create mode 100644 python/plane-tickets/pytest.ini create mode 100644 python/plane-tickets/run-tests-python.txt create mode 100644 python/plane-tickets/src/plane_tickets/__init__.py create mode 120000 python/plane-tickets/src/plane_tickets/generators.py create mode 100644 python/plane-tickets/test/__init__.py create mode 120000 python/plane-tickets/test/generators_test.py diff --git a/python/README.md b/python/README.md index 691f7eb4..01486a22 100644 --- a/python/README.md +++ b/python/README.md @@ -38,3 +38,4 @@ - [saddle-points](./saddle-points/README.md) - [leap](./leap/README.md) - [mecha-munch-management](./mecha-munch-management/README.md) +- [plane-tickets](./plane-tickets/README.md) diff --git a/python/plane-tickets/.coverage b/python/plane-tickets/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..e3ac405cfdb598035cd4f30f8b90f5df744ea808 GIT binary patch literal 53247 zcmeI4UrZdw9mjV$xMAUL26B)y!Gv`P92gEv>^N#cI8YF>6V-K~AQa4bIrfgNxm&!u z2S!yCkwkLUDi3{VAKI#Ys4KNn)2ga!sg>H7JmjU7ng>)>l`5rDl~{d9D>YK3q@pvk zvmDqa%0m%O`(53i@BVgX_BWsT&CJd2X=koH?*z74aJ`Zhm}j*nP1m(&O;gh}gTIsf z9c_e*+GvM=>-+R!($EI;dXmj)iTLXpTS{JL*~E8}J&kWCO2$_kze_A5&ktY&0T2KI z5cvNluze*#(rs<}D=!7s@|qoZR^Il)&*bM`m>Qp*GH1spo}V&9o7vl7@-3S+$4$@O zG}mp6BNTycIa*q8Y5(QR<3suZW3`+xS!`5)R7zLgkzlo-446yohzrDOui@ zdEMR`kO|b;0{dnV8h9bLQ!I-VX0OWLXL@$Q_Uv-r_Cqgvot3_ZzE@vvAn8;}zh%oh zSzeyM8V}Tl8>&^gSl|WaU2jErzwBA%{HpB_nATnm^Dg)EW)Rlab4x>kYpywES}v+9Ql_jrFGFbJV$uqz&$MIVR-{rRrV9N%>&x9THgcB86g)f8s@5$of{Q< zuki=WYR&;!jj}snic0VZ=x&UsKa5#!sugYdB+N>-?p^P;Qxq7Hd?!}hGAJ*bX` z!@_X~5)YkWBc7h>JS=qfLLfK1CmXig;w0VPuD@c)FjB3hzQ}UeOwPOa z7hKtdW}xR`oD&~qp|n-2R0A@0T2KI5C8!X009sH0T2KI5CDNsCxJvwtb;{=@fc=$ ztUay%1n|t@xxq6HyjC^rJ&nD`KKOK25MF}-2!H?xfB*=900@8p2!H?xfB*t_SU3R!AOHd&00JNY0w4eaAOHd&00KuvAg0H(@b>>l8vE#|&Vq7500ck)1V8`; zKmY_l00ck)1V8`;j*~zvmNdlef34{_y}-Fa00ck)1V8`;KmY_l00ck)1V8`;j+%hD z|Bvu#{R|r&faBzW;^V+>`nG7 z_A~ZF_C5AZ_BwlweVKX8Vb|C^`#hUsqwFj@%}%isjIlWVH~lC58~qFYBmF&ni~ffG zg8rC(pMHyeoqmPBOgCtWuFx0h3-ls=mOeuVX*WL^HV^;-5C8!X009sH0T2KI5CDOP ziU2uZXBfKf6v)$36mFAqQWPC>HnbGUQ&QY6kYOnncgYzkmKMoSXjvkIQe0gm+0b&8 z3`ntXhxAJ^w?IxyF+WH8Ld!hqm11^|WTcpxB|TEynIYX$Tv{YgN-;e~x}=zzCQnE) zIYmx|Vw#vzj8BqIDJCY#(H7y1GfT6nDEwlN9NG!lY@D_d_H*_leih&w>}zbBZL$)}v&(FlUjrCn z8P>rJx=Y`oAMo}6ALyI(cl4+9m-Gkp+kEZ+67{J=zescRIod|YX_l}3yORH)b;%F; z$*_R{2!H?xfB*=900@8p2!H?x92Eg0E>`k1+v!m1!uZL^cA;IV(Xq#r8X0Xqx zQvH|GO7(U>s#N#gR;7A+TOwOeN~x~yN0hqT)vQ#yze%Z + + + + + /home/vpayno/git_vpayno/exercism-workspace/python/plane-tickets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/plane-tickets/.coveragerc b/python/plane-tickets/.coveragerc new file mode 100644 index 00000000..883531db --- /dev/null +++ b/python/plane-tickets/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = __init__.py, *_test.py diff --git a/python/plane-tickets/.pylintrc b/python/plane-tickets/.pylintrc new file mode 120000 index 00000000..30b33b52 --- /dev/null +++ b/python/plane-tickets/.pylintrc @@ -0,0 +1 @@ +../.pylintrc \ No newline at end of file diff --git a/python/plane-tickets/README.md b/python/plane-tickets/README.md index f793315d..7070fade 100644 --- a/python/plane-tickets/README.md +++ b/python/plane-tickets/README.md @@ -262,4 +262,9 @@ The function should then return a `generator` that yields a `ticket_number`. - @BethanyG - @kytrinyx -- @meatball133 \ No newline at end of file +- @meatball133 + +### My Solution + +- [my solution](./generators.py) +- [run-tests](./run-tests-python.txt) diff --git a/python/plane-tickets/generators.py b/python/plane-tickets/generators.py index 2f88c061..b795cb26 100644 --- a/python/plane-tickets/generators.py +++ b/python/plane-tickets/generators.py @@ -1,26 +1,49 @@ """Functions to automate Conda airlines ticketing system.""" +from typing import Any, Generator -def generate_seat_letters(number): +type index_t = int # type: ignore[valid-type] +type quantity_t = int # type: ignore[valid-type] + +type letter_t = str # type: ignore[valid-type] +type letters_t = list[letter_t] # type: ignore[valid-type] + +type row_t = int # type: ignore[valid-type] +type seat_t = str # type: ignore[valid-type] +type seats_t = list[seat_t] # type: ignore[valid-type] + +type name_t = str # type: ignore[valid-type] +type passengers_t = list[name_t] # type: ignore[valid-type] +type seat_assignments_t = dict[name_t, seat_t] # type: ignore[valid-type] + +type code_t = str # type: ignore[valid-type] +type flight_id_t = str # type: ignore[valid-type] + + +def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any]: """Generate a series of letters for airline seats. - :param number: int - total number of seat letters to be generated. + :param quantity: int - total number of seat letters to be generated. :return: generator - generator that yields seat letters. Seat letters are generated from A to D. After D it should start again with A. Example: A, B, C, D - """ - pass + letters: letters_t = ["A", "B", "C", "D"] + + for pos in range(0, quantity): + index: index_t = pos % len(letters) + + yield letters[index] -def generate_seats(number): +def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: """Generate a series of identifiers for airline seats. - :param number: int - total number of seats to be generated. + :param quantity: int - total number of seats to be generated. :return: generator - generator that yields seat numbers. A seat number consists of the row number and the seat letter. @@ -31,30 +54,52 @@ def generate_seats(number): Seats should be sorted from low to high. Example: 3C, 3D, 4A, 4B - """ - pass + letter: Generator[letter_t, Any, Any] = generate_seat_letters(quantity) + row: row_t = 0 + + for _ in range(1, quantity + 1): + seat: seat_t = next(letter) -def assign_seats(passengers): + if seat == "A": + row += 1 + + if row == 13: + row += 1 + + yield f"{row}{seat}" + + +def assign_seats(passengers: passengers_t) -> seat_assignments_t: """Assign seats to passengers. :param passengers: list[str] - a list of strings containing names of passengers. :return: dict - with the names of the passengers as keys and seat numbers as values. Example output: {"Adele": "1A", "Björk": "1B"} - """ - pass + seat_assignments: seat_assignments_t = {} + seat: Generator[seat_t, Any, Any] = generate_seats(len(passengers)) -def generate_codes(seat_numbers, flight_id): + for passenger in passengers: + seat_assignments[passenger] = next(seat) + + return seat_assignments + + +def generate_codes( + seat_numbers: seats_t, flight_id: flight_id_t +) -> Generator[code_t, Any, Any]: """Generate codes for a ticket. :param seat_numbers: list[str] - list of seat numbers. :param flight_id: str - string containing the flight identifier. :return: generator - generator that yields 12 character long ticket codes. - """ - pass + for seat in seat_numbers: + code: code_t = f"{seat}{flight_id}" + + yield f"{code:012}" diff --git a/python/plane-tickets/generators.py,cover b/python/plane-tickets/generators.py,cover new file mode 100644 index 00000000..f7688e05 --- /dev/null +++ b/python/plane-tickets/generators.py,cover @@ -0,0 +1,105 @@ +> """Functions to automate Conda airlines ticketing system.""" + +> from typing import Any, Generator + +> type index_t = int # type: ignore[valid-type] +> type quantity_t = int # type: ignore[valid-type] + +> type letter_t = str # type: ignore[valid-type] +> type letters_t = list[letter_t] # type: ignore[valid-type] + +> type row_t = int # type: ignore[valid-type] +> type seat_t = str # type: ignore[valid-type] +> type seats_t = list[seat_t] # type: ignore[valid-type] + +> type name_t = str # type: ignore[valid-type] +> type passengers_t = list[name_t] # type: ignore[valid-type] +> type seat_assignments_t = dict[name_t, seat_t] # type: ignore[valid-type] + +> type code_t = str # type: ignore[valid-type] +> type flight_id_t = str # type: ignore[valid-type] + + +> def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any]: +> """Generate a series of letters for airline seats. + +> :param quantity: int - total number of seat letters to be generated. +> :return: generator - generator that yields seat letters. + +> Seat letters are generated from A to D. +> After D it should start again with A. + +> Example: A, B, C, D +> """ + +> letters: letters_t = ["A", "B", "C", "D"] + +> for pos in range(0, quantity): +> index: index_t = pos % len(letters) + +> yield letters[index] + + +> def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: +> """Generate a series of identifiers for airline seats. + +> :param quantity: int - total number of seats to be generated. +> :return: generator - generator that yields seat numbers. + +> A seat number consists of the row number and the seat letter. + +> There is no row 13. +> Each row has 4 seats. + +> Seats should be sorted from low to high. + +> Example: 3C, 3D, 4A, 4B +> """ + +> letter: Generator[letter_t, Any, Any] = generate_seat_letters(quantity) +> row: row_t = 0 + +> for _ in range(1, quantity + 1): +> seat: seat_t = next(letter) + +> if seat == "A": +> row += 1 + +> if row == 13: +> row += 1 + +> yield f"{row}{seat}" + + +> def assign_seats(passengers: passengers_t) -> seat_assignments_t: +> """Assign seats to passengers. + +> :param passengers: list[str] - a list of strings containing names of passengers. +> :return: dict - with the names of the passengers as keys and seat numbers as values. + +> Example output: {"Adele": "1A", "Björk": "1B"} +> """ + +> seat_assignments: seat_assignments_t = {} +> seat: Generator[seat_t, Any, Any] = generate_seats(len(passengers)) + +> for passenger in passengers: +> seat_assignments[passenger] = next(seat) + +> return seat_assignments + + +> def generate_codes( +> seat_numbers: seats_t, flight_id: flight_id_t +> ) -> Generator[code_t, Any, Any]: +> """Generate codes for a ticket. + +> :param seat_numbers: list[str] - list of seat numbers. +> :param flight_id: str - string containing the flight identifier. +> :return: generator - generator that yields 12 character long ticket codes. +> """ + +> for seat in seat_numbers: +> code: code_t = f"{seat}{flight_id}" + +> yield f"{code:012}" diff --git a/python/plane-tickets/pytest.ini b/python/plane-tickets/pytest.ini new file mode 100644 index 00000000..8dc12a49 --- /dev/null +++ b/python/plane-tickets/pytest.ini @@ -0,0 +1,5 @@ +[pytest] +pythonpath = . +addopts = --doctest-modules +markers = + task: exercise task/step diff --git a/python/plane-tickets/run-tests-python.txt b/python/plane-tickets/run-tests-python.txt new file mode 100644 index 00000000..64e2d6b9 --- /dev/null +++ b/python/plane-tickets/run-tests-python.txt @@ -0,0 +1,502 @@ +Running automated test file(s): + + +=============================================================================== + +Running: ../../.github/citools/python/python-lint-pylint + +Running Python Lint - PyLint + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +Running: pylint --version + +pylint 3.0.3 +astroid 3.0.2 +Python 3.12.1 (main, Dec 28 2023, 08:22:05) [GCC 10.2.1 20210110] + +real 0m0.249s +user 0m0.164s +sys 0m0.088s + + + ============================================================================== + +Running: pylint ./src + +************* Module plane_tickets.generators +src/plane_tickets/generators.py:63:23: R1708: Do not raise StopIteration in generator, use return statement instead (stop-iteration-return) + +------------------------------------------------------------------- +Your code has been rated at 9.74/10 (previous run: 10.00/10, -0.26) + + +real 0m0.784s +user 0m0.693s +sys 0m0.079s + + + ============================================================================== + +Exit code: -1 + +real 0m1.980s +user 0m1.504s +sys 0m0.483s + +real 0m1.986s +user 0m1.506s +sys 0m0.486s + +=============================================================================== + +Running: ../../.github/citools/python/python-lint-ruff + +Running Python Lint - Ruff + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +Running: ruff --version + +ruff 0.3.5 + +real 0m0.091s +user 0m0.038s +sys 0m0.055s + + + ============================================================================== + +Running: ruff check --ignore E501 ./src + +All checks passed! + +real 0m0.127s +user 0m0.044s +sys 0m0.087s + + + ============================================================================== + +Exit code: 0 + +real 0m1.183s +user 0m0.762s +sys 0m0.443s + +real 0m1.185s +user 0m0.762s +sys 0m0.444s + +=============================================================================== + +Running: ../../.github/citools/python/python-lint-pyright + +Running Python Lint - PyRight + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +Running: pyright --version + +pyright 1.1.357 + +real 0m0.717s +user 0m0.519s +sys 0m0.130s + + + ============================================================================== + +Running: pyright --stats ./src + +Found 2 source files +pyright 1.1.357 +0 errors, 0 warnings, 0 informations +Completed in 0.596sec + +Analysis stats +Total files parsed and bound: 20 +Total files checked: 2 + +Timing stats +Find Source Files: 0sec +Read Source Files: 0sec +Tokenize: 0.05sec +Parse: 0.05sec +Resolve Imports: 0.04sec +Bind: 0.04sec +Check: 0.07sec +Detect Cycles: 0sec + +real 0m1.284s +user 0m1.341s +sys 0m0.179s + + + ============================================================================== + +Exit code: 0 + +real 0m2.974s +user 0m2.516s +sys 0m0.639s + +real 0m2.977s +user 0m2.517s +sys 0m0.642s + +=============================================================================== + +Running: ../../.github/citools/python/python-lint-bandit + +Running Python Lint - Bandit + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +Running: bandit --version + +bandit 1.7.7 + python version = 3.12.1 (main, Dec 28 2023, 08:22:05) [GCC 10.2.1 20210110] + +real 0m0.283s +user 0m0.222s +sys 0m0.062s + + + ============================================================================== + +Running: bandit --verbose --recursive ./src + +[main] INFO profile include tests: None +[main] INFO profile exclude tests: None +[main] INFO cli include tests: None +[main] INFO cli exclude tests: None +[main] INFO running on Python 3.12.1 +Run started:2024-04-05 03:21:16.068009 +Files in scope (2): + ./src/plane_tickets/__init__.py (score: {SEVERITY: 0, CONFIDENCE: 0}) + ./src/plane_tickets/generators.py (score: {SEVERITY: 0, CONFIDENCE: 0}) +Files excluded (2): + ./src/plane_tickets/__pycache__/__init__.cpython-312.pyc + ./src/plane_tickets/__pycache__/generators.cpython-312.pyc + +Test results: + No issues identified. + +Code scanned: + Total lines of code: 67 + Total lines skipped (#nosec): 0 + Total potential issues skipped due to specifically being disabled (e.g., #nosec BXXX): 0 + +Run metrics: + Total issues (by severity): + Undefined: 0 + Low: 0 + Medium: 0 + High: 0 + Total issues (by confidence): + Undefined: 0 + Low: 0 + Medium: 0 + High: 0 +Files skipped (0): + +real 0m0.232s +user 0m0.169s +sys 0m0.064s + + + ============================================================================== + +Exit code: 0 + +real 0m1.502s +user 0m1.077s +sys 0m0.441s + +real 0m1.506s +user 0m1.080s +sys 0m0.441s + +=============================================================================== + +Running: ../../.github/citools/python/python-lint-refurb + +Running Python Lint - Refurb + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +Running: refurb --version + +Refurb: v1.26.0 +Mypy: v1.9.0 + +real 0m0.202s +user 0m0.136s +sys 0m0.068s + + + ============================================================================== + +Running: refurb ./src + + +real 0m1.158s +user 0m1.063s +sys 0m0.095s + + + ============================================================================== + +Exit code: 0 + +real 0m2.284s +user 0m1.859s +sys 0m0.440s + +real 0m2.286s +user 0m1.859s +sys 0m0.442s + +=============================================================================== + +Running: ../../.github/citools/python/python-test-with-doctests + +Running Python DocTests + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +PYTHONPATH="./src" + + ============================================================================== + +Running: python -m doctest -v ./src/plane_tickets/generators.py ./src/plane_tickets/__init__.py + +5 items had no tests: + generators + generators.assign_seats + generators.generate_codes + generators.generate_seat_letters + generators.generate_seats +0 tests in 5 items. +0 passed and 0 failed. +Test passed. +1 items had no tests: + __init__ +0 tests in 1 items. +0 passed and 0 failed. +Test passed. + +real 0m0.120s +user 0m0.075s +sys 0m0.047s + + + ============================================================================== + +Exit code: 0 + +real 0m1.094s +user 0m0.724s +sys 0m0.386s + +real 0m1.095s +user 0m0.725s +sys 0m0.386s + +=============================================================================== + +Running: ../../.github/citools/python/python-test-with-coverage + +Running Python Tests With Coverage + +Python versions: + + Python 3.12.1 + pyenv 2.3.36-21-g7e550e31 + pip 24.0 from /home/vpayno/.pyenv/versions/3.12.1/lib/python3.12/site-packages/pip (python 3.12) + PDM, version 2.13.2 + + + ============================================================================== + +Running: rm -rf ./coverage + + +real 0m0.001s +user 0m0.001s +sys 0m0.000s + + + ============================================================================== + +Running: pytest --version + +pytest 7.4.3 + +real 0m0.832s +user 0m0.885s +sys 0m0.838s + + + ============================================================================== + +PYTHONPATH="./src" + + ============================================================================== + +Running: pytest --verbose --cov=. --cov-branch --cov-report=term-missing --cov-report=xml:.coverage.xml -p no:randomly ./test + +============================= test session starts ============================== +platform linux -- Python 3.12.1, pytest-7.4.3, pluggy-1.3.0 -- /home/vpayno/.pyenv/versions/3.12.1/bin/python +cachedir: .pytest_cache +hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase(PosixPath('/home/vpayno/git_vpayno/exercism-workspace/python/plane-tickets/.hypothesis/examples')) +rootdir: /home/vpayno/git_vpayno/exercism-workspace/python/plane-tickets +configfile: pytest.ini +plugins: anyio-4.2.0, libtmux-0.25.0, pylama-8.4.1, cov-4.1.0, datafiles-3.0.0, docker-2.0.1, subprocess-1.5.0, typeguard-4.1.5, hypothesis-6.98.17, snapshot-0.9.0 +collecting ... collected 8 items + +test/generators_test.py::PlaneTicketsTest::test_assign_seats PASSED [ 12%] +test/generators_test.py::PlaneTicketsTest::test_generate_codes PASSED [ 25%] +test/generators_test.py::PlaneTicketsTest::test_generate_seat_letters PASSED [ 37%] +test/generators_test.py::PlaneTicketsTest::test_generate_seats PASSED [ 50%] +test/generators_test.py::PlaneTicketsTest::test_generate_seats_skips_row_13 PASSED [ 62%] +test/generators_test.py::PlaneTicketsTest::test_task1_returns_generator PASSED [ 75%] +test/generators_test.py::PlaneTicketsTest::test_task2_returns_generator PASSED [ 87%] +test/generators_test.py::PlaneTicketsTest::test_task4_returns_generator PASSED [100%] + +---------- coverage: platform linux, python 3.12.1-final-0 ----------- +Name Stmts Miss Branch BrPart Cover Missing +----------------------------------------------------------- +generators.py 38 0 12 0 100% +----------------------------------------------------------- +TOTAL 38 0 12 0 100% +Coverage XML written to file .coverage.xml + + +============================== 8 passed in 0.37s =============================== + +real 0m1.215s +user 0m1.072s +sys 0m0.143s + + + ============================================================================== + +Running: coverage report --show-missing + +Name Stmts Miss Branch BrPart Cover Missing +----------------------------------------------------------- +generators.py 38 0 12 0 100% +----------------------------------------------------------- +TOTAL 38 0 12 0 100% + +real 0m0.142s +user 0m0.096s +sys 0m0.047s + + + ============================================================================== + +Running: coverage annotate + + +real 0m0.158s +user 0m0.098s +sys 0m0.062s + + + ============================================================================== + +Line Coverage: 100.0% +Branch Coverage: 100.0% + + ============================================================================== + +Exit code: 0 + +real 0m3.329s +user 0m2.833s +sys 0m1.405s + +real 0m3.331s +user 0m2.834s +sys 0m1.405s + +=============================================================================== + +tail -n 10000 ./*,cover | grep -E -C 3 '^> def |^! ' + +> def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any]: +> """Generate a series of letters for airline seats. +-- + +> def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: +> """Generate a series of identifiers for airline seats. +-- + +> def assign_seats(passengers: passengers_t) -> seat_assignments_t: +> """Assign seats to passengers. +-- + +> def generate_codes( +> seat_numbers: seats_t, flight_id: flight_id_t + +=============================================================================== + +Running: misspell ./src/plane_tickets/generators.py ./src/plane_tickets/__init__.py + +real 0m0.018s +user 0m0.020s +sys 0m0.010s + +=============================================================================== + diff --git a/python/plane-tickets/src/plane_tickets/__init__.py b/python/plane-tickets/src/plane_tickets/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/plane-tickets/src/plane_tickets/generators.py b/python/plane-tickets/src/plane_tickets/generators.py new file mode 120000 index 00000000..7bd19289 --- /dev/null +++ b/python/plane-tickets/src/plane_tickets/generators.py @@ -0,0 +1 @@ +../../generators.py \ No newline at end of file diff --git a/python/plane-tickets/test/__init__.py b/python/plane-tickets/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/plane-tickets/test/generators_test.py b/python/plane-tickets/test/generators_test.py new file mode 120000 index 00000000..bf11ad55 --- /dev/null +++ b/python/plane-tickets/test/generators_test.py @@ -0,0 +1 @@ +../generators_test.py \ No newline at end of file From 3aad757e43995c9cf64af8cb93699787e5dcb105 Mon Sep 17 00:00:00 2001 From: Victor Payno Date: Thu, 4 Apr 2024 20:25:35 -0700 Subject: [PATCH 3/4] python/plane-tickets: 2nd iteration - py3.11 --- python/plane-tickets/.coverage.xml | 2 +- python/plane-tickets/generators.py | 50 +++--- python/plane-tickets/generators.py,cover | 50 +++--- python/plane-tickets/run-tests-python.txt | 206 +++++++++++----------- 4 files changed, 154 insertions(+), 154 deletions(-) diff --git a/python/plane-tickets/.coverage.xml b/python/plane-tickets/.coverage.xml index ddef66e8..3f2f5f39 100644 --- a/python/plane-tickets/.coverage.xml +++ b/python/plane-tickets/.coverage.xml @@ -1,5 +1,5 @@ - + diff --git a/python/plane-tickets/generators.py b/python/plane-tickets/generators.py index b795cb26..29e46ac5 100644 --- a/python/plane-tickets/generators.py +++ b/python/plane-tickets/generators.py @@ -2,25 +2,25 @@ from typing import Any, Generator -type index_t = int # type: ignore[valid-type] -type quantity_t = int # type: ignore[valid-type] +IndexT = int +QuantityT = int -type letter_t = str # type: ignore[valid-type] -type letters_t = list[letter_t] # type: ignore[valid-type] +LetterT = str +LettersT = list[LetterT] -type row_t = int # type: ignore[valid-type] -type seat_t = str # type: ignore[valid-type] -type seats_t = list[seat_t] # type: ignore[valid-type] +RowT = int +SeatT = str +SeatsT = list[SeatT] -type name_t = str # type: ignore[valid-type] -type passengers_t = list[name_t] # type: ignore[valid-type] -type seat_assignments_t = dict[name_t, seat_t] # type: ignore[valid-type] +NameT = str +PassengersT = list[NameT] +SeatAssignmentsT = dict[NameT, SeatT] -type code_t = str # type: ignore[valid-type] -type flight_id_t = str # type: ignore[valid-type] +CodeT = str +FlightIdT = str -def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any]: +def generate_seat_letters(quantity: QuantityT) -> Generator[LetterT, Any, Any]: """Generate a series of letters for airline seats. :param quantity: int - total number of seat letters to be generated. @@ -32,15 +32,15 @@ def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any] Example: A, B, C, D """ - letters: letters_t = ["A", "B", "C", "D"] + letters: LettersT = ["A", "B", "C", "D"] for pos in range(0, quantity): - index: index_t = pos % len(letters) + index: IndexT = pos % len(letters) yield letters[index] -def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: +def generate_seats(quantity: QuantityT) -> Generator[SeatT, Any, Any]: """Generate a series of identifiers for airline seats. :param quantity: int - total number of seats to be generated. @@ -56,11 +56,11 @@ def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: Example: 3C, 3D, 4A, 4B """ - letter: Generator[letter_t, Any, Any] = generate_seat_letters(quantity) - row: row_t = 0 + letter: Generator[LetterT, Any, Any] = generate_seat_letters(quantity) + row: RowT = 0 for _ in range(1, quantity + 1): - seat: seat_t = next(letter) + seat: SeatT = next(letter) if seat == "A": row += 1 @@ -71,7 +71,7 @@ def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: yield f"{row}{seat}" -def assign_seats(passengers: passengers_t) -> seat_assignments_t: +def assign_seats(passengers: PassengersT) -> SeatAssignmentsT: """Assign seats to passengers. :param passengers: list[str] - a list of strings containing names of passengers. @@ -80,8 +80,8 @@ def assign_seats(passengers: passengers_t) -> seat_assignments_t: Example output: {"Adele": "1A", "Björk": "1B"} """ - seat_assignments: seat_assignments_t = {} - seat: Generator[seat_t, Any, Any] = generate_seats(len(passengers)) + seat_assignments: SeatAssignmentsT = {} + seat: Generator[SeatT, Any, Any] = generate_seats(len(passengers)) for passenger in passengers: seat_assignments[passenger] = next(seat) @@ -90,8 +90,8 @@ def assign_seats(passengers: passengers_t) -> seat_assignments_t: def generate_codes( - seat_numbers: seats_t, flight_id: flight_id_t -) -> Generator[code_t, Any, Any]: + seat_numbers: SeatsT, flight_id: FlightIdT +) -> Generator[CodeT, Any, Any]: """Generate codes for a ticket. :param seat_numbers: list[str] - list of seat numbers. @@ -100,6 +100,6 @@ def generate_codes( """ for seat in seat_numbers: - code: code_t = f"{seat}{flight_id}" + code: CodeT = f"{seat}{flight_id}" yield f"{code:012}" diff --git a/python/plane-tickets/generators.py,cover b/python/plane-tickets/generators.py,cover index f7688e05..bbaecc30 100644 --- a/python/plane-tickets/generators.py,cover +++ b/python/plane-tickets/generators.py,cover @@ -2,25 +2,25 @@ > from typing import Any, Generator -> type index_t = int # type: ignore[valid-type] -> type quantity_t = int # type: ignore[valid-type] +> IndexT = int +> QuantityT = int -> type letter_t = str # type: ignore[valid-type] -> type letters_t = list[letter_t] # type: ignore[valid-type] +> LetterT = str +> LettersT = list[LetterT] -> type row_t = int # type: ignore[valid-type] -> type seat_t = str # type: ignore[valid-type] -> type seats_t = list[seat_t] # type: ignore[valid-type] +> RowT = int +> SeatT = str +> SeatsT = list[SeatT] -> type name_t = str # type: ignore[valid-type] -> type passengers_t = list[name_t] # type: ignore[valid-type] -> type seat_assignments_t = dict[name_t, seat_t] # type: ignore[valid-type] +> NameT = str +> PassengersT = list[NameT] +> SeatAssignmentsT = dict[NameT, SeatT] -> type code_t = str # type: ignore[valid-type] -> type flight_id_t = str # type: ignore[valid-type] +> CodeT = str +> FlightIdT = str -> def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any]: +> def generate_seat_letters(quantity: QuantityT) -> Generator[LetterT, Any, Any]: > """Generate a series of letters for airline seats. > :param quantity: int - total number of seat letters to be generated. @@ -32,15 +32,15 @@ > Example: A, B, C, D > """ -> letters: letters_t = ["A", "B", "C", "D"] +> letters: LettersT = ["A", "B", "C", "D"] > for pos in range(0, quantity): -> index: index_t = pos % len(letters) +> index: IndexT = pos % len(letters) > yield letters[index] -> def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: +> def generate_seats(quantity: QuantityT) -> Generator[SeatT, Any, Any]: > """Generate a series of identifiers for airline seats. > :param quantity: int - total number of seats to be generated. @@ -56,11 +56,11 @@ > Example: 3C, 3D, 4A, 4B > """ -> letter: Generator[letter_t, Any, Any] = generate_seat_letters(quantity) -> row: row_t = 0 +> letter: Generator[LetterT, Any, Any] = generate_seat_letters(quantity) +> row: RowT = 0 > for _ in range(1, quantity + 1): -> seat: seat_t = next(letter) +> seat: SeatT = next(letter) > if seat == "A": > row += 1 @@ -71,7 +71,7 @@ > yield f"{row}{seat}" -> def assign_seats(passengers: passengers_t) -> seat_assignments_t: +> def assign_seats(passengers: PassengersT) -> SeatAssignmentsT: > """Assign seats to passengers. > :param passengers: list[str] - a list of strings containing names of passengers. @@ -80,8 +80,8 @@ > Example output: {"Adele": "1A", "Björk": "1B"} > """ -> seat_assignments: seat_assignments_t = {} -> seat: Generator[seat_t, Any, Any] = generate_seats(len(passengers)) +> seat_assignments: SeatAssignmentsT = {} +> seat: Generator[SeatT, Any, Any] = generate_seats(len(passengers)) > for passenger in passengers: > seat_assignments[passenger] = next(seat) @@ -90,8 +90,8 @@ > def generate_codes( -> seat_numbers: seats_t, flight_id: flight_id_t -> ) -> Generator[code_t, Any, Any]: +> seat_numbers: SeatsT, flight_id: FlightIdT +> ) -> Generator[CodeT, Any, Any]: > """Generate codes for a ticket. > :param seat_numbers: list[str] - list of seat numbers. @@ -100,6 +100,6 @@ > """ > for seat in seat_numbers: -> code: code_t = f"{seat}{flight_id}" +> code: CodeT = f"{seat}{flight_id}" > yield f"{code:012}" diff --git a/python/plane-tickets/run-tests-python.txt b/python/plane-tickets/run-tests-python.txt index 64e2d6b9..cf27e604 100644 --- a/python/plane-tickets/run-tests-python.txt +++ b/python/plane-tickets/run-tests-python.txt @@ -23,9 +23,9 @@ pylint 3.0.3 astroid 3.0.2 Python 3.12.1 (main, Dec 28 2023, 08:22:05) [GCC 10.2.1 20210110] -real 0m0.249s -user 0m0.164s -sys 0m0.088s +real 0m0.241s +user 0m0.193s +sys 0m0.050s ============================================================================== @@ -33,28 +33,28 @@ sys 0m0.088s Running: pylint ./src ************* Module plane_tickets.generators -src/plane_tickets/generators.py:63:23: R1708: Do not raise StopIteration in generator, use return statement instead (stop-iteration-return) +src/plane_tickets/generators.py:63:22: R1708: Do not raise StopIteration in generator, use return statement instead (stop-iteration-return) -------------------------------------------------------------------- -Your code has been rated at 9.74/10 (previous run: 10.00/10, -0.26) +------------------------------------------------------------------ +Your code has been rated at 9.74/10 (previous run: 9.74/10, +0.00) -real 0m0.784s -user 0m0.693s -sys 0m0.079s +real 0m0.892s +user 0m0.833s +sys 0m0.061s ============================================================================== Exit code: -1 -real 0m1.980s -user 0m1.504s -sys 0m0.483s +real 0m2.286s +user 0m1.839s +sys 0m0.469s -real 0m1.986s -user 0m1.506s -sys 0m0.486s +real 0m2.292s +user 0m1.843s +sys 0m0.472s =============================================================================== @@ -76,9 +76,9 @@ Running: ruff --version ruff 0.3.5 -real 0m0.091s -user 0m0.038s -sys 0m0.055s +real 0m0.071s +user 0m0.029s +sys 0m0.043s ============================================================================== @@ -87,22 +87,22 @@ Running: ruff check --ignore E501 ./src All checks passed! -real 0m0.127s -user 0m0.044s -sys 0m0.087s +real 0m0.068s +user 0m0.025s +sys 0m0.046s ============================================================================== Exit code: 0 -real 0m1.183s -user 0m0.762s -sys 0m0.443s - real 0m1.185s -user 0m0.762s -sys 0m0.444s +user 0m0.858s +sys 0m0.343s + +real 0m1.187s +user 0m0.859s +sys 0m0.344s =============================================================================== @@ -124,8 +124,8 @@ Running: pyright --version pyright 1.1.357 -real 0m0.717s -user 0m0.519s +real 0m0.778s +user 0m0.639s sys 0m0.130s @@ -136,7 +136,7 @@ Running: pyright --stats ./src Found 2 source files pyright 1.1.357 0 errors, 0 warnings, 0 informations -Completed in 0.596sec +Completed in 0.653sec Analysis stats Total files parsed and bound: 20 @@ -144,30 +144,30 @@ Total files checked: 2 Timing stats Find Source Files: 0sec -Read Source Files: 0sec +Read Source Files: 0.01sec Tokenize: 0.05sec Parse: 0.05sec -Resolve Imports: 0.04sec -Bind: 0.04sec -Check: 0.07sec +Resolve Imports: 0.06sec +Bind: 0.05sec +Check: 0.08sec Detect Cycles: 0sec -real 0m1.284s -user 0m1.341s -sys 0m0.179s +real 0m1.357s +user 0m1.366s +sys 0m0.186s ============================================================================== Exit code: 0 -real 0m2.974s -user 0m2.516s -sys 0m0.639s +real 0m3.313s +user 0m2.927s +sys 0m0.587s -real 0m2.977s -user 0m2.517s -sys 0m0.642s +real 0m3.315s +user 0m2.928s +sys 0m0.588s =============================================================================== @@ -190,9 +190,9 @@ Running: bandit --version bandit 1.7.7 python version = 3.12.1 (main, Dec 28 2023, 08:22:05) [GCC 10.2.1 20210110] -real 0m0.283s -user 0m0.222s -sys 0m0.062s +real 0m0.305s +user 0m0.250s +sys 0m0.057s ============================================================================== @@ -204,7 +204,7 @@ Running: bandit --verbose --recursive ./src [main] INFO cli include tests: None [main] INFO cli exclude tests: None [main] INFO running on Python 3.12.1 -Run started:2024-04-05 03:21:16.068009 +Run started:2024-04-05 03:25:06.323258 Files in scope (2): ./src/plane_tickets/__init__.py (score: {SEVERITY: 0, CONFIDENCE: 0}) ./src/plane_tickets/generators.py (score: {SEVERITY: 0, CONFIDENCE: 0}) @@ -233,22 +233,22 @@ Run metrics: High: 0 Files skipped (0): -real 0m0.232s -user 0m0.169s -sys 0m0.064s +real 0m0.267s +user 0m0.195s +sys 0m0.074s ============================================================================== Exit code: 0 -real 0m1.502s -user 0m1.077s -sys 0m0.441s +real 0m1.572s +user 0m1.210s +sys 0m0.377s -real 0m1.506s -user 0m1.080s -sys 0m0.441s +real 0m1.575s +user 0m1.212s +sys 0m0.378s =============================================================================== @@ -271,9 +271,9 @@ Running: refurb --version Refurb: v1.26.0 Mypy: v1.9.0 -real 0m0.202s -user 0m0.136s -sys 0m0.068s +real 0m0.253s +user 0m0.181s +sys 0m0.074s ============================================================================== @@ -281,22 +281,22 @@ sys 0m0.068s Running: refurb ./src -real 0m1.158s -user 0m1.063s -sys 0m0.095s +real 0m1.337s +user 0m1.253s +sys 0m0.086s ============================================================================== Exit code: 0 -real 0m2.284s -user 0m1.859s -sys 0m0.440s +real 0m2.585s +user 0m2.186s +sys 0m0.414s -real 0m2.286s -user 0m1.859s -sys 0m0.442s +real 0m2.587s +user 0m2.187s +sys 0m0.415s =============================================================================== @@ -335,22 +335,22 @@ Test passed. 0 passed and 0 failed. Test passed. -real 0m0.120s -user 0m0.075s -sys 0m0.047s +real 0m0.155s +user 0m0.083s +sys 0m0.075s ============================================================================== Exit code: 0 -real 0m1.094s -user 0m0.724s -sys 0m0.386s +real 0m1.104s +user 0m0.807s +sys 0m0.313s -real 0m1.095s -user 0m0.725s -sys 0m0.386s +real 0m1.106s +user 0m0.807s +sys 0m0.315s =============================================================================== @@ -382,9 +382,9 @@ Running: pytest --version pytest 7.4.3 -real 0m0.832s -user 0m0.885s -sys 0m0.838s +real 0m0.844s +user 0m0.909s +sys 0m0.826s ============================================================================== @@ -422,11 +422,11 @@ TOTAL 38 0 12 0 100% Coverage XML written to file .coverage.xml -============================== 8 passed in 0.37s =============================== +============================== 8 passed in 0.39s =============================== -real 0m1.215s -user 0m1.072s -sys 0m0.143s +real 0m1.244s +user 0m1.100s +sys 0m0.146s ============================================================================== @@ -439,9 +439,9 @@ generators.py 38 0 12 0 100% ----------------------------------------------------------- TOTAL 38 0 12 0 100% -real 0m0.142s -user 0m0.096s -sys 0m0.047s +real 0m0.169s +user 0m0.107s +sys 0m0.063s ============================================================================== @@ -449,9 +449,9 @@ sys 0m0.047s Running: coverage annotate -real 0m0.158s -user 0m0.098s -sys 0m0.062s +real 0m0.173s +user 0m0.119s +sys 0m0.055s ============================================================================== @@ -463,40 +463,40 @@ Branch Coverage: 100.0% Exit code: 0 -real 0m3.329s -user 0m2.833s -sys 0m1.405s +real 0m3.448s +user 0m2.940s +sys 0m1.415s -real 0m3.331s -user 0m2.834s -sys 0m1.405s +real 0m3.451s +user 0m2.942s +sys 0m1.415s =============================================================================== tail -n 10000 ./*,cover | grep -E -C 3 '^> def |^! ' -> def generate_seat_letters(quantity: quantity_t) -> Generator[letter_t, Any, Any]: +> def generate_seat_letters(quantity: QuantityT) -> Generator[LetterT, Any, Any]: > """Generate a series of letters for airline seats. -- -> def generate_seats(quantity: quantity_t) -> Generator[seat_t, Any, Any]: +> def generate_seats(quantity: QuantityT) -> Generator[SeatT, Any, Any]: > """Generate a series of identifiers for airline seats. -- -> def assign_seats(passengers: passengers_t) -> seat_assignments_t: +> def assign_seats(passengers: PassengersT) -> SeatAssignmentsT: > """Assign seats to passengers. -- > def generate_codes( -> seat_numbers: seats_t, flight_id: flight_id_t +> seat_numbers: SeatsT, flight_id: FlightIdT =============================================================================== Running: misspell ./src/plane_tickets/generators.py ./src/plane_tickets/__init__.py -real 0m0.018s -user 0m0.020s -sys 0m0.010s +real 0m0.021s +user 0m0.018s +sys 0m0.014s =============================================================================== From c757a5fee0c217cd47cea9e881a1272ad2f57bcd Mon Sep 17 00:00:00 2001 From: Victor Payno Date: Thu, 4 Apr 2024 20:41:51 -0700 Subject: [PATCH 4/4] python/plane-tickets: 3rd iteration - py3.11 - pylint fix --- python/plane-tickets/.coverage | Bin 53247 -> 53247 bytes python/plane-tickets/.coverage.xml | 22 +-- python/plane-tickets/generators.py | 5 +- python/plane-tickets/generators.py,cover | 5 +- python/plane-tickets/run-tests-python.txt | 218 +++++++++++----------- 5 files changed, 120 insertions(+), 130 deletions(-) diff --git a/python/plane-tickets/.coverage b/python/plane-tickets/.coverage index e3ac405cfdb598035cd4f30f8b90f5df744ea808..824ef023d4e30c4678c7dfa0d6c0671992c77b72 100644 GIT binary patch delta 651 zcmXxgJ4gZn7{KvF@=NNzl!mf=zw`Zq207*Az@bGs6HbSQ6QQ{|92=VA#)e$NF~RAU z8d_Q!C1`7I4g!Zuzx!_c@gM)@qtkqJ&Ye?d4GX$!dbRL+UW5tMw%u-rW2`}ypv|B{ z7>%K9l@XK(GYyIa)r10Js6yTW2AZ3*vOp>Io0trH= z3vq(cff%8!LX^;wAwrNv2ot0hgb3mif>x0sKxjzdCp0BEu}Tw;31S0$gt`bv9@4T7 zhlFffuRp)<)P&U*#_&Pkoma~rXyPw^;}5>!CqAQrPk4{Fc!O7XjhC3m3zYC2&u|-k zxG${MWAB8C+qL<+9$RB+vnp#euGno3=W6p4d3% RS{HTi>w%-aNW6Y|{sH!eU|j$J delta 684 zcmXxgKS%;$7{~F%>`CgLiiXmxG_x}EPnk9-C(6lzjoOKD+IDiYb2v7~jSV^&v?&Ne zOARe8jS{pqMKm=uHC+1KbK8gS3lF?Mv*R>7&VjS*Ory`3>*})@Lf>#@`Ce#4+U0gT z9J&T6g4TmmLQ{vNRhn=@=xK0FP)$e>8Y;xC(tsGDu0qr*bvPo_Mi3z=H8>OZXE$Cv&%iwtH^6_GIofOY5arP5snv%_OU*ov>8% znAK1dc5B30bv0(UdX!Zg9kG;Jgw?Jphjy%nSrz4gRj%x_M&&(LNe!`NahFw;gDk1I sV@nRO@{*rbkhbks*qX{U`MWqaz8-yxS<%aHnXIw$wCX4gLr?F^|86j4%K!iX diff --git a/python/plane-tickets/.coverage.xml b/python/plane-tickets/.coverage.xml index 3f2f5f39..b4c28f03 100644 --- a/python/plane-tickets/.coverage.xml +++ b/python/plane-tickets/.coverage.xml @@ -1,5 +1,5 @@ - + @@ -31,24 +31,22 @@ - + - - + - - + + + - - + - - - - + + + diff --git a/python/plane-tickets/generators.py b/python/plane-tickets/generators.py index 29e46ac5..aea5e48e 100644 --- a/python/plane-tickets/generators.py +++ b/python/plane-tickets/generators.py @@ -56,12 +56,9 @@ def generate_seats(quantity: QuantityT) -> Generator[SeatT, Any, Any]: Example: 3C, 3D, 4A, 4B """ - letter: Generator[LetterT, Any, Any] = generate_seat_letters(quantity) row: RowT = 0 - for _ in range(1, quantity + 1): - seat: SeatT = next(letter) - + for seat in generate_seat_letters(quantity): if seat == "A": row += 1 diff --git a/python/plane-tickets/generators.py,cover b/python/plane-tickets/generators.py,cover index bbaecc30..3cc7f56c 100644 --- a/python/plane-tickets/generators.py,cover +++ b/python/plane-tickets/generators.py,cover @@ -56,12 +56,9 @@ > Example: 3C, 3D, 4A, 4B > """ -> letter: Generator[LetterT, Any, Any] = generate_seat_letters(quantity) > row: RowT = 0 -> for _ in range(1, quantity + 1): -> seat: SeatT = next(letter) - +> for seat in generate_seat_letters(quantity): > if seat == "A": > row += 1 diff --git a/python/plane-tickets/run-tests-python.txt b/python/plane-tickets/run-tests-python.txt index cf27e604..96f7eb91 100644 --- a/python/plane-tickets/run-tests-python.txt +++ b/python/plane-tickets/run-tests-python.txt @@ -23,38 +23,36 @@ pylint 3.0.3 astroid 3.0.2 Python 3.12.1 (main, Dec 28 2023, 08:22:05) [GCC 10.2.1 20210110] -real 0m0.241s -user 0m0.193s -sys 0m0.050s +real 0m0.238s +user 0m0.158s +sys 0m0.082s ============================================================================== Running: pylint ./src -************* Module plane_tickets.generators -src/plane_tickets/generators.py:63:22: R1708: Do not raise StopIteration in generator, use return statement instead (stop-iteration-return) ------------------------------------------------------------------- -Your code has been rated at 9.74/10 (previous run: 9.74/10, +0.00) +------------------------------------------------------------------- +Your code has been rated at 10.00/10 (previous run: 9.74/10, +0.26) -real 0m0.892s -user 0m0.833s -sys 0m0.061s +real 0m0.768s +user 0m0.685s +sys 0m0.084s ============================================================================== -Exit code: -1 +Exit code: 0 -real 0m2.286s -user 0m1.839s -sys 0m0.469s +real 0m1.992s +user 0m1.511s +sys 0m0.501s -real 0m2.292s -user 0m1.843s -sys 0m0.472s +real 0m1.997s +user 0m1.512s +sys 0m0.505s =============================================================================== @@ -76,9 +74,9 @@ Running: ruff --version ruff 0.3.5 -real 0m0.071s -user 0m0.029s -sys 0m0.043s +real 0m0.070s +user 0m0.032s +sys 0m0.039s ============================================================================== @@ -87,22 +85,22 @@ Running: ruff check --ignore E501 ./src All checks passed! -real 0m0.068s -user 0m0.025s -sys 0m0.046s +real 0m0.126s +user 0m0.055s +sys 0m0.074s ============================================================================== Exit code: 0 -real 0m1.185s -user 0m0.858s -sys 0m0.343s +real 0m1.149s +user 0m0.754s +sys 0m0.415s -real 0m1.187s -user 0m0.859s -sys 0m0.344s +real 0m1.151s +user 0m0.756s +sys 0m0.415s =============================================================================== @@ -124,9 +122,9 @@ Running: pyright --version pyright 1.1.357 -real 0m0.778s -user 0m0.639s -sys 0m0.130s +real 0m0.676s +user 0m0.500s +sys 0m0.128s ============================================================================== @@ -136,7 +134,7 @@ Running: pyright --stats ./src Found 2 source files pyright 1.1.357 0 errors, 0 warnings, 0 informations -Completed in 0.653sec +Completed in 0.601sec Analysis stats Total files parsed and bound: 20 @@ -144,30 +142,30 @@ Total files checked: 2 Timing stats Find Source Files: 0sec -Read Source Files: 0.01sec -Tokenize: 0.05sec +Read Source Files: 0sec +Tokenize: 0.06sec Parse: 0.05sec -Resolve Imports: 0.06sec -Bind: 0.05sec -Check: 0.08sec +Resolve Imports: 0.05sec +Bind: 0.06sec +Check: 0.06sec Detect Cycles: 0sec -real 0m1.357s -user 0m1.366s -sys 0m0.186s +real 0m1.269s +user 0m1.421s +sys 0m0.188s ============================================================================== Exit code: 0 -real 0m3.313s -user 0m2.927s -sys 0m0.587s +real 0m2.930s +user 0m2.579s +sys 0m0.658s -real 0m3.315s -user 0m2.928s -sys 0m0.588s +real 0m2.933s +user 0m2.581s +sys 0m0.659s =============================================================================== @@ -190,9 +188,9 @@ Running: bandit --version bandit 1.7.7 python version = 3.12.1 (main, Dec 28 2023, 08:22:05) [GCC 10.2.1 20210110] -real 0m0.305s -user 0m0.250s -sys 0m0.057s +real 0m0.285s +user 0m0.220s +sys 0m0.067s ============================================================================== @@ -204,7 +202,7 @@ Running: bandit --verbose --recursive ./src [main] INFO cli include tests: None [main] INFO cli exclude tests: None [main] INFO running on Python 3.12.1 -Run started:2024-04-05 03:25:06.323258 +Run started:2024-04-05 03:39:46.246487 Files in scope (2): ./src/plane_tickets/__init__.py (score: {SEVERITY: 0, CONFIDENCE: 0}) ./src/plane_tickets/generators.py (score: {SEVERITY: 0, CONFIDENCE: 0}) @@ -216,7 +214,7 @@ Test results: No issues identified. Code scanned: - Total lines of code: 67 + Total lines of code: 65 Total lines skipped (#nosec): 0 Total potential issues skipped due to specifically being disabled (e.g., #nosec BXXX): 0 @@ -233,22 +231,22 @@ Run metrics: High: 0 Files skipped (0): -real 0m0.267s -user 0m0.195s -sys 0m0.074s +real 0m0.237s +user 0m0.166s +sys 0m0.071s ============================================================================== Exit code: 0 -real 0m1.572s -user 0m1.210s -sys 0m0.377s +real 0m1.526s +user 0m1.063s +sys 0m0.482s -real 0m1.575s -user 0m1.212s -sys 0m0.378s +real 0m1.529s +user 0m1.064s +sys 0m0.484s =============================================================================== @@ -271,9 +269,9 @@ Running: refurb --version Refurb: v1.26.0 Mypy: v1.9.0 -real 0m0.253s -user 0m0.181s -sys 0m0.074s +real 0m0.200s +user 0m0.143s +sys 0m0.058s ============================================================================== @@ -281,22 +279,22 @@ sys 0m0.074s Running: refurb ./src -real 0m1.337s -user 0m1.253s -sys 0m0.086s +real 0m1.110s +user 0m1.029s +sys 0m0.082s ============================================================================== Exit code: 0 -real 0m2.585s -user 0m2.186s -sys 0m0.414s +real 0m2.249s +user 0m1.830s +sys 0m0.434s -real 0m2.587s -user 0m2.187s -sys 0m0.415s +real 0m2.252s +user 0m1.830s +sys 0m0.436s =============================================================================== @@ -335,22 +333,22 @@ Test passed. 0 passed and 0 failed. Test passed. -real 0m0.155s -user 0m0.083s -sys 0m0.075s +real 0m0.146s +user 0m0.087s +sys 0m0.061s ============================================================================== Exit code: 0 -real 0m1.104s -user 0m0.807s -sys 0m0.313s +real 0m1.088s +user 0m0.759s +sys 0m0.344s -real 0m1.106s -user 0m0.807s -sys 0m0.315s +real 0m1.090s +user 0m0.759s +sys 0m0.347s =============================================================================== @@ -372,8 +370,8 @@ Running: rm -rf ./coverage real 0m0.001s -user 0m0.001s -sys 0m0.000s +user 0m0.000s +sys 0m0.001s ============================================================================== @@ -382,9 +380,9 @@ Running: pytest --version pytest 7.4.3 -real 0m0.844s -user 0m0.909s -sys 0m0.826s +real 0m0.862s +user 0m0.914s +sys 0m0.836s ============================================================================== @@ -416,17 +414,17 @@ test/generators_test.py::PlaneTicketsTest::test_task4_returns_generator PASSED [ ---------- coverage: platform linux, python 3.12.1-final-0 ----------- Name Stmts Miss Branch BrPart Cover Missing ----------------------------------------------------------- -generators.py 38 0 12 0 100% +generators.py 36 0 12 0 100% ----------------------------------------------------------- -TOTAL 38 0 12 0 100% +TOTAL 36 0 12 0 100% Coverage XML written to file .coverage.xml -============================== 8 passed in 0.39s =============================== +============================== 8 passed in 0.37s =============================== -real 0m1.244s -user 0m1.100s -sys 0m0.146s +real 0m1.209s +user 0m1.049s +sys 0m0.161s ============================================================================== @@ -435,13 +433,13 @@ Running: coverage report --show-missing Name Stmts Miss Branch BrPart Cover Missing ----------------------------------------------------------- -generators.py 38 0 12 0 100% +generators.py 36 0 12 0 100% ----------------------------------------------------------- -TOTAL 38 0 12 0 100% +TOTAL 36 0 12 0 100% -real 0m0.169s -user 0m0.107s -sys 0m0.063s +real 0m0.172s +user 0m0.105s +sys 0m0.069s ============================================================================== @@ -449,9 +447,9 @@ sys 0m0.063s Running: coverage annotate -real 0m0.173s -user 0m0.119s -sys 0m0.055s +real 0m0.162s +user 0m0.102s +sys 0m0.061s ============================================================================== @@ -463,13 +461,13 @@ Branch Coverage: 100.0% Exit code: 0 -real 0m3.448s -user 0m2.940s -sys 0m1.415s +real 0m3.377s +user 0m2.849s +sys 0m1.437s -real 0m3.451s -user 0m2.942s -sys 0m1.415s +real 0m3.379s +user 0m2.850s +sys 0m1.437s =============================================================================== @@ -494,9 +492,9 @@ tail -n 10000 ./*,cover | grep -E -C 3 '^> def |^! ' Running: misspell ./src/plane_tickets/generators.py ./src/plane_tickets/__init__.py -real 0m0.021s -user 0m0.018s -sys 0m0.014s +real 0m0.020s +user 0m0.021s +sys 0m0.008s ===============================================================================