home.social

#pythonoddity — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #pythonoddity, aggregated by home.social.

fetched live
  1. RE: mastodon.social/@carapace/1153

    This one's fun!

    An infinite iterable from a finite data structure? 🤔

    It all works because lists can "contain" themselves.

    Remember that lists don't actually contain data in Python but references to data.

    #PythonOddity

  2. RE: mastodon.social/@carapace/1153

    This one's fun!

    An infinite iterable from a finite data structure? 🤔

    It all works because lists can "contain" themselves.

    Remember that lists don't actually contain data in Python but references to data.

    #PythonOddity

  3. In honor of today's date of September 12th, I came up with a #PythonOddity puzzle.

    Can you guess the redacted module from the standard library (no pip install allowed!) such that:

    from ████████ import ████, █████████
    A = ████(12, 12, 12)
    B = █████████(12, 12, 12, 12, 12, 12)
    assert (A + B + B) != (B + B + A) # huh
    assert (A + B + B) != (A + 2 * B) # this also works

  4. In honor of today's date of September 12th, I came up with a #PythonOddity puzzle.

    Can you guess the redacted module from the standard library (no pip install allowed!) such that:

    from ████████ import ████, █████████
    A = ████(12, 12, 12)
    B = █████████(12, 12, 12, 12, 12, 12)
    assert (A + B + B) != (B + B + A) # huh
    assert (A + B + B) != (A + 2 * B) # this also works

  5. Am I the only one who didn't know that #Python list comprehensions (and presumably other types of comprehensions) can accept **multiple** conditional statements at the end?

    [i for i in range(30) if i%2 if i%3 if i%5]

    #PythonOddity

  6. Am I the only one who didn't know that #Python list comprehensions (and presumably other types of comprehensions) can accept **multiple** conditional statements at the end?

    [i for i in range(30) if i%2 if i%3 if i%5]

    #PythonOddity

  7. Python allows for some funny code sometimes.

    >>> numbers = [2, 1, 3, 4, 7]
    >>> numbers[::-1] = reversed(numbers)
    >>> numbers
    [2, 1, 3, 4, 7]
    >>> numbers[::-1] = sorted(numbers)
    >>> numbers
    [7, 4, 3, 2, 1]

    #Python #PythonOddity

  8. Python allows for some funny code sometimes.

    >>> numbers = [2, 1, 3, 4, 7]
    >>> numbers[::-1] = reversed(numbers)
    >>> numbers
    [2, 1, 3, 4, 7]
    >>> numbers[::-1] = sorted(numbers)
    >>> numbers
    [7, 4, 3, 2, 1]

    #Python #PythonOddity

  9. Python's pathlib.Path allows the / operator to be used for joining paths.

    That also allows the /= augmented assignment to work, which allows for some slightly odd-looking code.

    >>> from pathlib import Path
    >>> directory = Path.home()
    >>> directory /= "Documents"
    >>> directory
    PosixPath('/home/trey/Documents')

    #Python #PythonOddity

  10. Python's pathlib.Path allows the / operator to be used for joining paths.

    That also allows the /= augmented assignment to work, which allows for some slightly odd-looking code.

    >>> from pathlib import Path
    >>> directory = Path.home()
    >>> directory /= "Documents"
    >>> directory
    PosixPath('/home/trey/Documents')

    #Python #PythonOddity

  11. @treyhunner Did you know about this #PythonOddity in hte ordering of timedelta's positional arguments?

    from datetime import timedelta
    print(timedelta(1).total_seconds())
    print(timedelta(1, 1).total_seconds())

  12. @treyhunner Did you know about this #PythonOddity in hte ordering of timedelta's positional arguments?

    from datetime import timedelta
    print(timedelta(1).total_seconds())
    print(timedelta(1, 1).total_seconds())

  13. Implementing a singleton in #Python, the wrong way:

    >>> from functools import cache
    >>> @cache
    ... class Thing:
    ... def __init__(self, name):
    ... self‍‍ .name = name
    ...
    >>> x = Thing("x")
    >>> y = Thing("y")
    >>> x is y
    False
    >>> x is Thing("x")
    True
    >>> y is Thing("y")
    True

    I was explaining class decorators today and wondered "what would happen if we used a function decorator on a class?" That thought lead to the above bad idea (bad because Thing isn't a class now). #PythonOddity

  14. Implementing a singleton in #Python, the wrong way:

    >>> from functools import cache
    >>> @cache
    ... class Thing:
    ... def __init__(self, name):
    ... self‍‍ .name = name
    ...
    >>> x = Thing("x")
    >>> y = Thing("y")
    >>> x is y
    False
    >>> x is Thing("x")
    True
    >>> y is Thing("y")
    True

    I was explaining class decorators today and wondered "what would happen if we used a function decorator on a class?" That thought lead to the above bad idea (bad because Thing isn't a class now). #PythonOddity

  15. Do you miss Python2's old print statement?

    No problem, add a space before your parentheses and you can print debug like it's 1991 again:

    >>> print ("is", "that", "retrocomputing?")

    #Python #PythonOddity

  16. Do you miss Python2's old print statement?

    No problem, add a space before your parentheses and you can print debug like it's 1991 again:

    >>> print ("is", "that", "retrocomputing?")

    #Python #PythonOddity

  17. Ever wish you could just negate your index and make it represent the same thing at the end of the list.

    Instead of 0 being first and -1 last we'd use 0 first and -0 last.

    This doesn't work because 0 == -0 and... well, number lines!

    Solution: use a tilde instead of a negative sign!

    ~0 == -1
    ~1 == -2
    and so on.

    You're welcome.

    (also... please don't actually do this 😬)

    #Python #PythonOddity

  18. Ever wish you could just negate your index and make it represent the same thing at the end of the list.

    Instead of 0 being first and -1 last we'd use 0 first and -0 last.

    This doesn't work because 0 == -0 and... well, number lines!

    Solution: use a tilde instead of a negative sign!

    ~0 == -1
    ~1 == -2
    and so on.

    You're welcome.

    (also... please don't actually do this 😬)

    #Python #PythonOddity

  19. Comprehensions have their own scope:

    >>> n = 4
    >>> squares = [n**2 for n in range(9)]
    >>> n
    4

    But loops do NOT have their own scope:

    >>> n = 4
    >>> for n in squares: ...
    >>> n
    81

    This may seem like a gotcha, but there's a good reason for this.

    For convenience, Python lacks variable declarations. Assignments "declare" implicitly. Due to this, function-level scope makes a LOT more sense in Python, so #Python's scope is function-level, not block-level.

    trey.io/function-scope-oddity

    #PythonOddity

  20. Comprehensions have their own scope:

    >>> n = 4
    >>> squares = [n**2 for n in range(9)]
    >>> n
    4

    But loops do NOT have their own scope:

    >>> n = 4
    >>> for n in squares: ...
    >>> n
    81

    This may seem like a gotcha, but there's a good reason for this.

    For convenience, Python lacks variable declarations. Assignments "declare" implicitly. Due to this, function-level scope makes a LOT more sense in Python, so #Python's scope is function-level, not block-level.

    trey.io/function-scope-oddity

    #PythonOddity

  21. Just wrote up an explanation of one of my favorite bits of Python to teach.

    It's a useless bit of code that's nonetheless helpful to understand.

    >>> x = []
    >>> x.append(x)

    The question to ponder: what's x?

    The explanation: github.com/treyhunner/python-o

    #Python #PythonOddity

  22. Just wrote up an explanation of one of my favorite bits of Python to teach.

    It's a useless bit of code that's nonetheless helpful to understand.

    >>> x = []
    >>> x.append(x)

    The question to ponder: what's x?

    The explanation: github.com/treyhunner/python-o

    #Python #PythonOddity

  23. A #PythonOddity from @bcostlow's #PyOhio talk:

    >>> g = a, b, c = (n**2 for n in range(3))
    >>> a
    0
    >>> b
    1
    >>> c
    4
    >>> list(g)
    []

    The generator is empty before we even start looping over it.

    Hint: it's the tuple unpacking. #Python

  24. A #PythonOddity from @bcostlow's #PyOhio talk:

    >>> g = a, b, c = (n**2 for n in range(3))
    >>> a
    0
    >>> b
    1
    >>> c
    4
    >>> list(g)
    []

    The generator is empty before we even start looping over it.

    Hint: it's the tuple unpacking. #Python

  25. Faces in Python 🧐

    >>> O_o = 0_0
    >>> o_o = 0o0
    >>> o_O = 0,0
    >>> O,O = o_O

    What's this? 😳😮

    >>> O_o, o_o, O,O, *o_O

    Explanation: github.com/treyhunner/python-o

    #PythonOddity #Python

  26. Faces in Python 🧐

    >>> O_o = 0_0
    >>> o_o = 0o0
    >>> o_O = 0,0
    >>> O,O = o_O

    What's this? 😳😮

    >>> O_o, o_o, O,O, *o_O

    Explanation: github.com/treyhunner/python-o

    #PythonOddity #Python

  27. I opened an issue: github.com/python/cpython/issu

    I'm always torn on whether an issue like this is noise versus useful.

    I know other #PythonOddity posts I've made have been rendered obsolete after being noticed and fixed as bugs. This one seems pretty minor to me, but fixing the implementation couldn't hurt. 🤷

  28. I opened an issue: github.com/python/cpython/issu

    I'm always torn on whether an issue like this is noise versus useful.

    I know other #PythonOddity posts I've made have been rendered obsolete after being noticed and fixed as bugs. This one seems pretty minor to me, but fixing the implementation couldn't hurt. 🤷

  29. Python's Decimal module allows you to add wings around your numbers:

    >>> from decimal import Decimal
    >>> Decimal("__1__")
    Decimal('1')

    Is this a bug?... or a feature!

    >>> Decimal("____0____.____0____")
    Decimal('0.0')

    #PythonOddity #Python

  30. Python's Decimal module allows you to add wings around your numbers:

    >>> from decimal import Decimal
    >>> Decimal("__1__")
    Decimal('1')

    Is this a bug?... or a feature!

    >>> Decimal("____0____.____0____")
    Decimal('0.0')

    #PythonOddity #Python

  31. This *excellent* #PythonOddity has made me realize that I've been using #pythonoddity in all lowercase for years. 😢

    I'm on-board with HashTagCapitalization for accessibility and readability reasons, but I'm going to need some adjustment time to adopt this capitalization style for this particular hashtag.

    mastodon.social/@glyph/1126280

  32. This *excellent* #PythonOddity has made me realize that I've been using #pythonoddity in all lowercase for years. 😢

    I'm on-board with HashTagCapitalization for accessibility and readability reasons, but I'm going to need some adjustment time to adopt this capitalization style for this particular hashtag.

    mastodon.social/@glyph/1126280

  33. I've been collecting "Python oddities" for years using #pythonoddity on social media.

    I define a Python oddity as behavior that may be surprising to a reader, particularly a newer #Python user.

    This term has ruffled feathers in the past, especially when folks interpret my use of "oddity" as closer to "bug" than "potential gotcha" or "common misunderstanding".

    What should I name the repository where I will collect these?

  34. I've been collecting "Python oddities" for years using #pythonoddity on social media.

    I define a Python oddity as behavior that may be surprising to a reader, particularly a newer #Python user.

    This term has ruffled feathers in the past, especially when folks interpret my use of "oddity" as closer to "bug" than "potential gotcha" or "common misunderstanding".

    What should I name the repository where I will collect these?

  35. This is possibly my least (most?) favorite #PythonOddity :

    ```
    def loop():
    for number in range(10):
    def closure():
    return number
    yield closure

    eagerly = [each() for each in loop()]
    lazily = [each() for each in list(loop())]
    ```

    Understanding why `eagerly` and `lazily` differ is *crucial* to understanding how scopes work in Python, and illustrates a weakness in the otherwise pretty great “you don’t have to declare variables” structure of the language.

  36. This is possibly my least (most?) favorite #PythonOddity :

    ```
    def loop():
    for number in range(10):
    def closure():
    return number
    yield closure

    eagerly = [each() for each in loop()]
    lazily = [each() for each in list(loop())]
    ```

    Understanding why `eagerly` and `lazily` differ is *crucial* to understanding how scopes work in Python, and illustrates a weakness in the otherwise pretty great “you don’t have to declare variables” structure of the language.

  37. Generator #pythonoddity.

    Calling a generator does not run the generator (by design).

    This has caught me before!

    mastodon.social/@zeehio/112624

    #Python

  38. Generator #pythonoddity.

    Calling a generator does not run the generator (by design).

    This has caught me before!

    mastodon.social/@zeehio/112624

    #Python

  39. Python's data structures do NOT contain objects.

    They contain pointers to objects.

    To demonstrate this fact, at the end of this video I show a sort of ouroboros: a list that "contains" itself.

    pythonmorsels.com/data-structu

    #Python #pythonoddity

  40. Python's data structures do NOT contain objects.

    They contain pointers to objects.

    To demonstrate this fact, at the end of this video I show a sort of ouroboros: a list that "contains" itself.

    pythonmorsels.com/data-structu

    #Python #pythonoddity