Skip to content

Add approaches for the Eliud’s Eggs exercise #4227

Closed

Description

@Yrahcaz7

From this forum thread.

As an easy exercise that is linked to in learning mode, I think it is important that the Eliud's Eggs exercise gets a Dig Deeper section with approaches. I offer to create a PR with approach docs for the following approaches:

Approaches/variants that may or may not be worth adding:

  • An even more extreme variant of the "cheating" approach, using function aliasing.

  • An approach that converts to a binary string and uses regular expressions to count the ones. Regexes would definitely over-complicate things, but it might be an opportunity to show how regexes are not suitable for everything.

  • A variant of the binary modification variant that I can't really understand. If I added this, I would need some help in understanding it.

New ideas (things that weren't on the forum post):

Activity

  1. github-actions commented on May 31, 2026

    @github-actions
  2. BethanyG commented on May 31, 2026

    @BethanyG
    Member

    This looks excellent! Thank you for logging it here. Another thing on the to-do list, but well worth it. 😄

  3. Yrahcaz7 commented on Jun 1, 2026

    @Yrahcaz7
    ContributorAuthor

    @BethanyG, I've added some more things to the "New ideas" section since the initial post. How do you feel about these, and the things in the "Approaches/variants that may or may not be worth adding" section?

    I'm not sure whether all possible approaches/variants should be included, or if something like a regex approach or a multi-function approach wouldn't be worth it.

  4. BethanyG commented on Jun 2, 2026

    @BethanyG
    Member

    Apologies. I got busy yesterday, and didn't get to things here.

    _@BethanyG, I've added some more things to the "New ideas" section since the initial post. How do you feel about these, and the things in the "Approaches/variants that may or may not be worth adding" section?

    I'm not sure whether all possible approaches/variants should be included, or if something like a regex approach or a multi-function approach wouldn't be worth it._

    As you can see from my wordy and reverse-string approaches, I tend to take a maximalist approach to these things. 😄 My general rule is to include approaches that would alert the student (at the progression they're at) to some new-to-them strategy or technique — and depending on the progression — exciting-looking but perhaps ill advised or superfluous strategies or techniques. Maybe they've heard a "functional approach" is always better — so we demonstrate "functional" tools or techniques and explain how they're worse/better for readability or speed or something else. Maybe they are in love with breaking things down into teeny-tiny functions ... so we show them benefits and pitfalls. Maybe it's recursion — so we point out that anything recursive can be done via loop (and vice versa) — but that Python doesn't perform tail-call optimization and has a sharp recursion limit. Maybe we show memoization techniques for getting around that recursion limit.

    It really depends on how much energy and engagement is there for the authors of said approaches. Writing all of them can be really tedious and really draining — which is why I don't do very many of them very quickly. And keep in mind that these can also be added to, so trying to capture everything, everywhere, all at once is likely to burn you out.

    One thing we should take care to do is to organize them in a way that helps the student see similarities in strategy and technique — that's why you see some of my approach docs will group into approaches with variants in them. Throwing everything at a student without context is likely to drive them away. Not sure I've always done a good job of organizing, but we do need to try. 😄

    So ...

    • I am not sure that two flavors of recursion are really needed . Since Python does nothing to optimize tail-call recursion, tail-call vs non-tail-call is more readability than anything else. But if we go further, it's arguable (this being linked to the loops concept) that recursion doesn't belong here at all.

      My personal thought is that it's of great benefit for folx to think of loops and recursion as accomplishing the same goal: iterating through a task. Sometimes it's easier to structure things one way — and sometimes, the other. The sooner they make that association, the less time they waste clinging to one strategy over the other, and the more time they spend getting really good at both and really good at determining what to use when.

    • I think the same can be said of swapping in map() or functools.reduce() for other things — on one hand, why?. On the other hand, these tools exist and students should know their benefits and pitfalls.

    • As for the function aliasing? You could include it as an interesting variant of cheating (if you really want to dig into why it works the way it does) ... but its an awful lot of effort to go to — especially when there are very few professional places that would be entertained at all. It's a clever-looking trick that has no real benefit.

    • The bit modification would be worth going through, just because very few programmers these days understand bit shifting unless they're in a specialized corner of the biz.

    • Regex might be good here because of what you say: not everything can and should be a regex. 😉

    More thoughts a little later after I've thought some more. 😄

  5. BethanyG commented on Jun 3, 2026

    @BethanyG
    Member

    Another quick thought:

    The "cheating" way (with a warning that this isn't the intended solution!), with an int.bit_count() variant and a str.count() variant.

    Yes, these violate the "original intent". The int.bit_count especially. But thinking about this, I get a tad conflicted. This exercise was put together originally for the C++ track, which tends to emphasize doing things at a "lower level". This is sort of the opposite of what a lot of Python emphasizes (lots of stuff in the standard lib, lots of methods of convenience, lots of high-level methods, lots of "magic").

    Many newcomers to Python get confused by things like implicitly converting int to float when adding the two types together or doing division. And Python's arbitrary precision and lack of "overflow" when numbers get "big" (great way to pick out Java programmers 😉) . And the whole "sure you can see that int in bin or hex or octal format, but it's still an int" can really confuse folx.

    And yes - this exercise is supposed to encourage programmers to "think in binary" a bit. But is it cheating to use what a language gives you (as long as you understand what it is)? If all ints are binary (and octal and hex) - why not use Python's tools of representation to help yourself not make mistakes?

    Apologies - this is probably not helpful, but there it is. 🙂

  6. BethanyG commented on Jun 3, 2026

    @BethanyG
    Member

    Oh -- and we should definitely link to 0.30000000000000004.com. In the introduction docs. That site is great. Especially for those who get on their high horse about how Python sucks because of the way it does math. Turns out, all programming languages have to make some sort of compromise.

    As you know, we do go over some of this in the numbers Concept, so we can also link that.

  7. BethanyG commented on Jun 3, 2026

    @BethanyG
    Member

    Ok - last thought for now (I am procrastinating...can you tell?). We have a deprecated exercises binary, octal, and hexadecimal that all cover this same territory.

    Are these worth bringing out of retirement as additional "easy" looping or numbers exercises? I originally retired them because of Python's built in and number converting utilities. But maybe they are worth it for some students? Something to think on.

  8. BethanyG commented on Jun 3, 2026

    @BethanyG
    Member

    (I lied). Last last thought. All your base covers a more generalized version of this problem. It also could be considered an approach here. If a student already has a "base converter", it could be called to convert, then they could count up the 1's.

    Yeah -- totally crazy-pants. But. 😆

  9. BethanyG commented on Jun 9, 2026

    @BethanyG
    Member

    Hi @Ff6lYo6XD0B,

    Could we clarify how to define the boundaries between essential and optional approaches, especially for the int.bit_count() and str.count() methods, since including too many could dilute the focus on core concepts in the Dig Deeper section?

    Not sure what you mean here? Do you have an example/critique of what you are talking about based on current approaches for this track?

    Since this is a practice exercise about counting bits and is attached to the loops concept, none of these approaches are really "essential". Python (and most other programming languages) provide tools, builtins, and "automatic" processes for dealing with bits and also with iteration. So the approaches here are all about the tradeoffs of how/why/when you loop, and how/why/when you would calculate bits instead of using something like int.bit_count().

  10. BethanyG commented on Jun 17, 2026

    @BethanyG
    Member

    Putting this here and ... backing away. TIL that f-string mini format language does the bin() conversion for you (because bin is just another int format) dunno how I missed that, but. SO:

    def egg_count(display_value):
        return sum(int(item) for item in f'{display_value:b}')
  11. BethanyG commented on Jun 17, 2026

    @BethanyG
    Member

    ....and why clean things up when you can double down on the wrongness??

    def egg_count(display_value):
        return sum((temp := display_value & 1, display_value := display_value >> 1)[0] for _ in f'{display_value:b}')

    And the non bit-shift version:

    def egg_count(display_value):
        return sum((temp:= display_value % 2, display_value := display_value//2)[0]
                  for _ in f'{display_value:b}')
  12. Yrahcaz7 commented on Jun 17, 2026

    @Yrahcaz7
    ContributorAuthor

    ....and why clean things up when you can double down on the wrongness??

    😱 That's such a crazy solution... But with a few modifications, it can become even stranger:

    def egg_count(display_value):
        return sum(
            next(iter((value & 1, display_value := value >> 1)))
            for value in iter(lambda: display_value, 0)
        )
  13. BethanyG commented on Jun 17, 2026

    @BethanyG
    Member

    OOOH. Now that is deliciously offensive. lambda with a walrus in a comprehension FTW! 💥 13/10

  14. BethanyG commented on Jun 17, 2026

    @BethanyG
    Member

    do we need a "bad ideas" section in these approaches?? They're so fun! 😆

  15. Yrahcaz7 commented on Jun 18, 2026

    @Yrahcaz7
    ContributorAuthor

    Consider it done! Too fun to resist adding it 😆

  16. added a commit that references this issue on Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions