Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for walrus operator #51

Merged
merged 3 commits into from
Mar 8, 2024
Merged

Add test for walrus operator #51

merged 3 commits into from
Mar 8, 2024

Conversation

brocla
Copy link
Contributor

@brocla brocla commented Mar 7, 2024

Hello Bethany,
I followed the steps to add a test for the walrus operator. Here is the PR.

The normalized code in representation.out looks right to me. I was able to run pytest locally, but your are right, the golden tests are a bit fiddly. I had to get the matching versions of black, pytest, and python, otherwise, no.

If this PR is what you want, I'll go write up tests for the other cases. Else, nudge me in the right direction and I'll update this one until correct.

Thanks
Kevin

This comment was marked as resolved.

@BethanyG
Copy link
Member

BethanyG commented Mar 7, 2024

@brocla -- Thank you for this! Apologies for the shock of the auto-close. It's a bot, so I can't make exceptions ahead of time. If all goes well, we can look at adding you as a contributor so that these don't auto-close in the future.

But rest assured, I get notified -- so I can easily re-open these and review them.

Apologies for your struggle with Black, Python, et. al. I probably need to do some documentation updates....
And maybe you and I can have a discussion around how we make these a bit less fiddly. Now that we actually have the tests! 😆
I am going to go ahead and take a look at this, and will get back to you shortly. 😄

@BethanyG BethanyG reopened this Mar 7, 2024
Copy link
Member

@BethanyG BethanyG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a great start!

The paranoid developer in me might add two/three more "walrus" scenarios:

  1. The use of a walrus in a list comprehension
  2. The use of a walrus in a generator expression/generator.

Only because those particular forms have caused issues in the past (we were dropping generator expressions at one point 😱 ), so we know they're a bit of an issue. But again -- that's me being a tad paranoid.

Let me see if I can find some quick samples to suggest. Otherwise, this looks good. 😄

@BethanyG
Copy link
Member

BethanyG commented Mar 7, 2024

BTW: If you want to see the existing tests in action, you can view the CI run here. 😄

@BethanyG
Copy link
Member

BethanyG commented Mar 7, 2024

Oh, MAN. I am an utter idiot! Totally missed the comprehension in the first function. Wow. Definitely need more coffee!

I will go find a genex/generator. No need for another comprehension. 🤦🏽‍♀️

@brocla
Copy link
Contributor Author

brocla commented Mar 7, 2024

Here's a generator example. It is a bit of a stretch. When short circuiting a generator with any(), the walrus allows you to keep the value where the short circuit happened. But the boolean result from any() is still available too.

def first_item_greater_than_N(iterable, N):
    if any((item := x) > N for x in iterable):
        return item
    return None

Does something like,

>>> numbers = [ 1, 5, 9, 12, 21, 42]
>>> first_item_greater_than_N(numbers, 10)
12

@BethanyG
Copy link
Member

BethanyG commented Mar 8, 2024

Yeah. I was about to write that i haven't seen any true generator/generator exp examples. Yes -- using any() or all() or join() or where you might use a lambda (like when you are doing something complicated for accumulate()). But not any that directly use a stand-alone generator (with a yield) /genexp. 🤔

So - maybe I'm over-thinking things here.

There is this horror:

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
  
      """

    letters = generate_seat_letters(number)
    
    return (f'{str(row)}{next(letters)}' 
            for seat in range(number + 4 if number >= 13 else number) 
            if (row := seat // 4 + 1) != 13)

But it is rather contrived, and I can't seem to re-write it as a non-genexp, which tells me that the use of := is more than likely superfluous.

and there is this one as well:

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.

    """

    return (base.ljust(12, '0') for 
            seat in seat_numbers if 
            (base := f'{seat}{flight_id}'))

Thoughts?

@brocla
Copy link
Contributor Author

brocla commented Mar 8, 2024

I like the second one better than the first. But I have to remind myself that this isn't about code that I would write, it is about whether the Representer can parse the code that other people write.

So unusual examples are probably good for this.

BTW, thanks for spending the time to get me up to speed. I'm hoping it pays off for you as I plow through the other cases.

@BethanyG
Copy link
Member

BethanyG commented Mar 8, 2024

I like the second one better than the first. But I have to remind myself that this isn't about code that I would write, it is about whether the Representer can parse the code that other people write.

Hee hee. Yup. I have to remind myself of that about 1000x a day.

Confession: I wrote the second one in my solution to that concept exercise (which I had completely forgotten about! Could have saved me a LOT of googling if I had remembered.). And specifically because I wanted to use a walrus in some random way. I have no defense for it at all - if I saw that coming from someone else, I'd probably throw a fit. 😬

BTW, thanks for spending the time to get me up to speed. I'm hoping it pays off for you as I plow through the other cases.

💙

I am happy to help. 😄 I don't usually accept contributors to the test runner, representer, or analyzer -- but you've done great with this first PR, and I am excited to see your additional test cases.

@BethanyG
Copy link
Member

BethanyG commented Mar 8, 2024

Let's add your any() example and that second genexp example and call it a day for this PR. I think this (more than) covers all the bases. 😉

     for use in generators
@brocla
Copy link
Contributor Author

brocla commented Mar 8, 2024

Agree. Here is an updated PR with those two tests added.
Also, I ran pytest to make sure the tests pass.

I'm going to start working on tests for the other 3.9+ features.
😃

@BethanyG
Copy link
Member

BethanyG commented Mar 8, 2024

sigh. We've got some subtle difference between the CI container and the container used to run the original test code.
At least enough that the CI is failing. 😦

I can't look at it right now, but can in an hour or so. I don't think its a big difference, so I think you can start on the 3.9 features -- just keep in mind we may need to fiddle them a bit based on what I find.

It would appear that the alpine docker container is off by one line from what was submitted for golden files.  Re-ran the representations in the hope that the CI will accept them.
@BethanyG
Copy link
Member

BethanyG commented Mar 8, 2024

This has got to be one of the most annoying CI fails ever. The before/after files are off by one line. Here is a screengrab of part of the diff:

image

and the representation.txt partial file:

image

TL;DR? The golden files have to be run using the run-in-docker.sh script, which uses the docker.io/library/python:3.11.5-alpine3.18 image that the CI uses.

At least that's what it looks like, since that's what I did on my machine (an Intel Mac running MacOS Ventura). Grrr.

@BethanyG
Copy link
Member

BethanyG commented Mar 8, 2024

I am going to approve and merge this test now. Apologies for the being pecked to death by ducks thing.

Copy link
Member

@BethanyG BethanyG left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@BethanyG BethanyG merged commit 6e0467e into exercism:main Mar 8, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants