@treyhunner@mastodon.social
@treyhunner@mastodon.social avatar

treyhunner

@treyhunner@mastodon.social

#Python & #Django educator & team trainer

I help folks sharpen their Python skills with https://PythonMorsels.com🐍🍪

#pythonoddity

Also a #humanist #YIMBY who is attempting more ethical eating (#vegetarian, not yet #vegan) and thinks #economics is highly underrated, but I don't post about those topics very often.

he/him

This profile is from a federated server and may be incomplete. Browse more on the original instance.

treyhunner, to random
@treyhunner@mastodon.social avatar

New screencast: How to make a context manager 📺🐍🎛

I've taught this topic for years, but this is the first time I've whittled this all down to just 5 minutes.

https://pym.dev/creating-a-context-manager/

treyhunner,
@treyhunner@mastodon.social avatar

@siddhantgoel agreed! Hoping to do a separate screencast on that.

treyhunner, to python
@treyhunner@mastodon.social avatar

Lists, strings, numbers, functions, modules, and classes are all objects in Python.

In , everything is an object. ♾️

https://youtu.be/_0lGCQvieV8

treyhunner, to python
@treyhunner@mastodon.social avatar

What feature would you have trouble explaining to a new programmer?

(If you think you CAN explain that feature, feel free to reply to replies with your own new-programmer-oriented explanation)

treyhunner,
@treyhunner@mastodon.social avatar

@adamchainz good one! 😅 I have found some non-trivial uses for match/case but there are some corners that I would really struggle to explain. 😬

treyhunner,
@treyhunner@mastodon.social avatar

@orsinium yup. There is more to arguments than is worth learning/teaching in an introductory course. I always include a preview of some of the more complex stuff and a disclaimer that you don't need to know most of it to get started and you shouldn't try to memorize most of it beyond positional vs keyword and defaults (until you find yourself needing it...).

treyhunner,
@treyhunner@mastodon.social avatar

@kleaders great one!

Comprehensions are one of those features where throwing a few explanations at the wall can be helpful because different mental models work better for different folks.

Here's one explanation of comprehensions:

The original comprehensions from other languages come from set builder notation in math.

[ x*2 | x <- numbers, x%2==1 ]

But we don't like symbols in so we instead write that as:

[x*2 for x in numbers if x%2 == 1]

treyhunner,
@treyhunner@mastodon.social avatar

@kleaders here's another explanation of 's comprehensions.

If you have a "for" loop that consist solely of an append, an optional "if" that the append is within, and maybe a nested "for" loop in your loop, you can copy-paste your way into a comprehension.

The expression you're appending comes first. Every other expression remains in the same order.

I recommend folks start their comprehension journey by writing the "for" loop first (since it's familiar) and then copy-pasting into it.

treyhunner,
@treyhunner@mastodon.social avatar

@kleaders It may seem odd to copy-paste your way from a loop, but it's not meant to be a permanent technique.

The idea is to anchor what you're less familiar with (the comprehension) on the syntax of what you know (the loop).

The syntax is weird! It uses the keywords "for" and "if", which makes it look like an inside-out "for" loop, even though it's really something separate.

More:
• Short: https://pym.dev/turning-loop-list-comprehension/
• Longer: https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
• Longer-er: https://trey.io/comprehensions

treyhunner,
@treyhunner@mastodon.social avatar

@kleaders you're welcome!

treyhunner,
@treyhunner@mastodon.social avatar

@kleaders @meejah big +1 to breaking over multiple lines. I pretty much always prefer that.

Something to note is that unfortunately using the Black autoformatter will turn them back to one-liners unless they're over the maximum like length you have set. 😢

mborus, to random
@mborus@mastodon.social avatar

Had a lot more "fun" with today. Main problem was that I can't make a div element behave like a button inside a form. (Which I needed to refactor a JavaScript mess without changing the CSS too much)

The current solution: Writing vanilla JavaScript (see https://htmx.org/api/) - then tacking hx-on="click: myJSfunc(...)" onto the divs and doing the htmx.ajax request from my custom JS code.

Feels very hacky, but it seems to work so far.

treyhunner,
@treyhunner@mastodon.social avatar

@mborus yikes. That's a weird issue. That seems like it should be possible to do. 🤔 Any idea whether that's a known bug?

treyhunner,
@treyhunner@mastodon.social avatar

@mborus I'm also really liking . I use it in a handful of places throughout the pythonmorsels.com app, along with Alpine.js for non-server actions and quite a bit of custom JavaScript for more complex things that neither Alpine nor HTMX can replace.

Initially I replaced a few non-HTMX widgets with HTMX ones and the HTMX version was SO much more maintainable.

treyhunner, to python
@treyhunner@mastodon.social avatar

Python tip 💡

If you just ran an expression in the REPL and you'd like to capture its value into a variable, you don't need to run it again!

You can use the _ variable to get the value of the last REPL output!

You'll also sometimes see _ used as a throwaway variable:

>>> from random import randint
>>> numbers = [randint(1, 5) for _ in range(10)]

_ works in the built-in Python REPL and pretty much all third-party REPLs.

Try _ out yourself in a REPL: https://pym.dev/repl

random.randint used in a list comprehension to generate a range with _ used as a throwaway variable. See code at https://pym.dev/p/3328x

treyhunner, to random
@treyhunner@mastodon.social avatar

TIL you can use a dict for slots in Python 💡

https://fosstodon.org/@orsinium/110780666371693920

cenbe, to python
@cenbe@mastodon.sdf.org avatar

Just learning ... it doesn't have constants? Really? And you're supposed to simulate them by using a naming convention? You're kidding me, right?

treyhunner,
@treyhunner@mastodon.social avatar

@diji @cenbe the fact that variables are pointers throws a wrench into the ability to have useful constants.

JavaScript has the same problem but they decide to make constant variables anyway. So in JavaScript you can have a constant variables whose value can change. 😬

I prefer Python's decision. Either way is a trade-off (as was the initial "variables are pointers" decision). ⚖️

treyhunner, to python
@treyhunner@mastodon.social avatar

Need a multi-line string in but don't want to include a big block of manually dedented text?

Use textwrap.dedent! 🎁⬅️

Here's some code that does NOT use dedent:

def copyright():
print("""\
Copyright (c) 1991-2000 ACME Corp

Copyright (c) 2000-2030 Cyberdyne"""
)

Here's the same code with dedent:

from textwrap import dedent

def copyright():
print(dedent("""\
Copyright (c) 1991-2000 ACME Corp

Copyright (c) 2000-2030 Cyberdyne\
"""))

Better, right?

treyhunner, to python
@treyhunner@mastodon.social avatar

You can use a docstring to add documentation to any function, class, or module you make in

https://youtu.be/R6diu-uMUi4

treyhunner, to python
@treyhunner@mastodon.social avatar

If you were to mentor a beginner coder, what would be your first lesson?

treyhunner, to python
@treyhunner@mastodon.social avatar

All iteration is equivalent in .

If you loop over a dictionary, you get keys:

>>> d = {'A': 0, 'B': 0}
>>> for x in d: print(x)
...
A
B

Same if you convert it to a list:

>>> list(d)
['A', 'B']

Or use the string join method on it:

>>> " ".join(d)
'A B'

Or use the enumerate function:

>>> for item in enumerate(d):
... print(item)
...
(0, 'blue')
(1, 'red')

Or a comprehension:

>>> [x+'!' for x in d]
['blue!', 'red!']

Or even tuple unpacking:

>>> a, b = d
>>> b
'B'

treyhunner, to python
@treyhunner@mastodon.social avatar

I often see my students use the split method with a single space character:

>>> x.split(" ")

Usually using the split method without any arguments is preferable:

>>> x.split()

Why?

Well, the default string delimiter for splitting in isn't "space" but "any amount of consecutive whitespace":

>>> x = "Python is
\tneat."
>>> print(x)
Python is
neat.
>>> x.split()
['Python', 'is', 'neat.']

Plus split without any delimiter strips whitespace from the ends of a string!

treyhunner, to python
@treyhunner@mastodon.social avatar

I don't know whether the universe is finite. 🌌

I do know that allows for infinitely recursive data structures. 🔁

>>> name = "Python"
>>> name[0][0][0][0][0][0][0][0]
'P'
>>> turtles = []
>>> turtles.append(turtles)
>>> turtles[0][0][0][0][0][0][0]
[[...]]
>>> type(type(type(type(type(type(type))))))
<class 'type'>

treyhunner, (edited ) to random
@treyhunner@mastodon.social avatar

It may be obvious that these are classes:

• tuple
• list
• dict
• set
• str
• int
• float
• bool

But did you know these "functions" are also classes?

• enumerate
• range
• zip
• reversed
• map
• filter
• super
• type
• property
• classmethod

Classes are callable, just as functions are: Python has no "new" keyword!

Callables may be classes or functions. And it's acceptable to refer to function-like callables as "functions", even if they're actually classes.

https://www.pythonmorsels.com/callables/

treyhunner,
@treyhunner@mastodon.social avatar

@Stark9837 yup 👍

Over two dozen of python's built-in functions are implemented as classes.

treyhunner, to python
@treyhunner@mastodon.social avatar

The two primary ways to combine strings in Python:

• string concatenation: gluing/smooshing strings together
• string interpolation: injecting strings into other strings

This week's screencast covers both of these techniques.

https://m.youtube.com/watch?v=GLNYlX_1vX0&feature=youtu.be

  • All
  • Subscribed
  • Moderated
  • Favorites
  • JUstTest
  • ngwrru68w68
  • thenastyranch
  • osvaldo12
  • cubers
  • InstantRegret
  • DreamBathrooms
  • cisconetworking
  • magazineikmin
  • Youngstown
  • Durango
  • mdbf
  • slotface
  • rosin
  • provamag3
  • kavyap
  • tacticalgear
  • modclub
  • khanakhh
  • anitta
  • ethstaker
  • tester
  • everett
  • GTA5RPClips
  • normalnudes
  • megavids
  • Leos
  • lostlight
  • All magazines