Trey Hunner ๐Ÿ

@treyhunner
2.5K Followers
310 Following
4.4K Posts

#Python & #Django educator & team trainer

I help folks sharpen their Python skills with https://PythonMorsels.com๐Ÿ๐Ÿช

#pythonoddity

Also: ostrovegan, sentientist, YIMBY, and I think economics is highly underrated. I don't post about any of those topics very often.

he/him

๐Ÿ’Œ My Weekly Newsletterhttps://pym.dev/newsletter
๐Ÿ Python Exerciseshttps://www.pythonmorsels.com
๐Ÿ“บ YouTubehttps://www.youtube.com/@PythonMorsels
๐Ÿ•ธ Personal Bloghttps://treyhunner.com

The reversed function only gives us the next item as we need it.

Read more ๐Ÿ‘‰ https://trey.io/ur7l4g

#Python

Looping in reverse

Any reversible iterable can be reversed using the built-in reversed function whereas Python's slicing syntax only works on sequences.

Of course, you could instead take an "Easier to Ask Forgiveness Than Permission" approach:

try:
number = int(value)
except ValueError:
is_numeric = False
else:
is_numeric = True

This is all just to say "don't use those 3 string methods because it's too easy to mix them up and there are better options".

Convert to a number and catch the exception or use a regex to match the specific kind of number you need.

This week's tips will all be on regular expressions.

๐Ÿงต (6/6)

If you use a regular expression with "\d", it'll work the same way as isdecimal().

It'll match b, but not the other 2:

>>> import re
>>> re.fullmatch(r"\d+", b)
<re.Match object; span=(0, 1), match='๏ผ•'>

Want to be more strict and match only "0" through "9"?

Use an explicit "[0-9]" character class:

>>> re.fullmatch(r"[0-9]+", b)

Or you could match negative numbers or numbers with a ".":

>>> re.fullmatch(r"-?[0-9]+\.?[0-9]*", "-5.0")
<re.Match object; span=(0, 4), match='-5.0'>

๐Ÿงต (5/6)

"\N{fullwidth digit five}" can be converted to a number:

>>> int(b)
5

The other two would raise a ValueError exception.

So, if you're going to use one of those 3 string methods, I'd use isdecimal().

The isdigit() and isnumeric() methods will match strings that aren't valid numbers (by Python's own definition of "number").

So... did you guess isdecimal() is the strictest of those 3?

No??

That's why I recommend against all of them.

๐Ÿงต (4/6)

>>> print(a, a.isnumeric(), a.isdecimal(), a.isdigit())
โ…ค True False False
>>> print(b, b.isnumeric(), b.isdecimal(), b.isdigit())
๏ผ• True True True
>>> print(c, c.isnumeric(), c.isdecimal(), c.isdigit())
โ“น True False True

Roman numeral matches 1, double circle digit 2, and fullwidth digit 3!

Okay... so some obscure characters return True for some of those methods and False for others.

But why do we care?

Well, which can be converted to a number using the built-in int function?

๐Ÿงต (3/6)

All 3 methods return True for the first one only:

>>> print(a, a.isnumeric(), a.isdecimal(), a.isdigit())
5 True True True
>>> print(b, b.isnumeric(), b.isdecimal(), b.isdigit())
5.0 False False False
>>> print(c, c.isnumeric(), c.isdecimal(), c.isdigit())
-5 False False False

Huh.

Of the 3 symbols โ…ค, ๏ผ•, and โ“น, which will one will each of those match?

>>> a = "\N{roman numeral five}"
>>> b = "\N{fullwidth digit five}"
>>> c = "\N{double circled digit five}"
>>> print(a, b, c)
โ…ค ๏ผ• โ“น

๐Ÿงต (2/6)

Python Tip #89 (of 365):

Avoid string methods for number validation

Avoid the str class's isdigit(), isdecimal(), and isnumeric() methods.

Instead use an explicit regular expression or convert the string to a number.

Of these 3 strings:

>>> a = "5"
>>> b = "5.0"
>>> c = "-5"

Which of them will each of the 3 isnumeric(), isdecimal(), and isdigit() methods return True for?

If you have no idea, don't worry... it's a bit confusing.

๐Ÿงต (1/6)

#Python #DailyPythonTip

Python Tip #88 (of 365):

When assigning multiple variables to the same initial immutable value, use multiple assignment

Instead of this:

x = 0
y = 0

You can do this:

x = y = 0

That's safe as long as the value is immutable (numbers, strings, booleans, or None).

#Python #DailyPythonTip

โ€œBut classes can sometimes make your code easier to read, and more importantly, when used well, classes can sometimes make code that uses your code easier to read.โ€

Read more ๐Ÿ‘‰ https://pym.dev/when-are-classes-used/

#Python #classes

When to make a class in Python

While you don't often need to make your own classes in Python, they can sometimes make your code reusable and easier to read.

Or maybe you'll just reference the same variable(s) on both sides of an assignment while using tuple unpacking.

For example, here's an implementation of the Fibonacci sequence in Python:

def fibonacci():
a, b = 0, 1
while True:
a, b = b, a+b
yield a

Note that "a, b = b, a+b" assignment.

It's not quite variable swapping, but it relies on the same idea.

So while "swap 2 variables in one line" is likely pointless, the idea behind the trick does come in handy.

๐Ÿงต (2/2)