💾 Archived View for hedy.flounder.online › journal › 2022 captured on 2022-07-16 at 16:10:25. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2022-06-04)
-=-=-=-=-=-=-
.-----. .----. .-----. .-----. / ,-. \ / .. \ / ,-. \/ ,-. \ '-' | |. / \ .'-' | |'-' | | .' / | | ' | .' / .' / .' /__ ' \ / ' .' /__ .' /__ | | \ `' / | || | `-------' `---'' `-------'`-------'
:w !diff % -
My script that parses this journal page and dumps out the content in tinylog format had hardcoded the year to 2021. Can't believe I'd only found out about this 5 months into 2022, anyways it's fixed now.
The CGI scripts that is supposed to run that ^ on demand and deploy any changes to my tinylog.gmi feed doesn't work still because CGI is run by a single user in gemserv. I'll think about how I can (safely) fix that soon.
Lagrange v1.13 supports spartan!
I always thought there were two list methods to find the index of an element in python - find and index. find would raise an IndexError when the item isn't found in the list, whereas index would return -1 in that same case.
Nope, that's completely wrong.
First, there's only .index for lists:
>>> ['a', 'b', 'c'].index('a') 0
And it raises a ValueError if the item isn't found:
>>> ['a', 'b', 'c'].index(404) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 404 is not in list
Method signature:
index(self, value, start=0, stop=9223372036854775807, /) Return first index of value. Raises ValueError if the value is not present.
Second, the "find vs. index" is for strings, not lists - both find and index methods exist for strings:
>>> 'abc'.index('a') 0 >>> 'abc'.find('a') 0
So what are the differences? Turns out my previous understanding of how find/index handles non-existent items had been mixed up. When attempting to index a substring that isn't actually in the string, index raises a ValueError, and find returns -1:
>>> 'abc'.index('z') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: substring not found >>> 'abc'.find('z') -1
(Note that you can use either to search for "substrings" - i.e: `'abc'.index('bc')`)
Method signatures:
index(...) S.index(sub[, start[, end]]) -> int Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation. Raises ValueError when the substring is not found.
find(...) S.find(sub[, start[, end]]) -> int Return the lowest index in S where substring sub is found, such that sub is contained within S[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure.
Just for fun, I also went ahead and tested out the performance of the two methods
$ python3 -m timeit "'abcdefghijklmnopqrstuvwxyz'.index('p')" 2000000 loops, best of 5: 131 nsec per loop $ python3 -m timeit "'abcdefghijklmnopqrstuvwxyz'.find('p')" 2000000 loops, best of 5: 103 nsec per loop
For cases where the item isn't found:
$ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "try: s.index('Z')" \ "except: pass" 1000000 loops, best of 5: 310 nsec per loop $ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "try: s.find('Z')" \ "except: pass" 2000000 loops, best of 5: 110 nsec per loop
python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if s.find('Z') == -1: pass" 2000000 loops, best of 5: 119 nsec per loop
Seems like .find() clearly wins on speed.
Here's an example of searching for the index of a substring in a string, then doing something with it:
$ python3 -m timeit -s "s = 'abcdefghijklmnopqrstuvwxyz'" \ "if 'z' in s:" \ " index = s.find('z')" \ " print('do stuff with', index)" \ "else:" \ " print('not found')" |tail -n1 500000 loops, best of 5: 700 nsec per loop
$ python3 -m timeit -s "s = 'abcdefghijklmnopqrstuvwxyz'" \ "if index := s.find('z') != -1:" \ " print('do stuff with', index)" \ "else:" \ " print('not found')" | tail -n1 500000 loops, best of 5: 686 nsec per loop
Interesting! The second method does seem more idiomatic and "clean", but can .find() truly beat python's native operator?
$ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if 'Z' not in s: pass" 10000000 loops, best of 5: 31 nsec per loop $ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if 'xyz' not in s: pass" 5000000 loops, best of 5: 40.3 nsec per loop $ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if 'xyZ' not in s: pass" 5000000 loops, best of 5: 39.6 nsec per loop
$ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if s.find('Z') == -1: pass" 2000000 loops, best of 5: 119 nsec per loop $ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if s.find('xyz') == -1: pass" 2000000 loops, best of 5: 137 nsec per loop $ python3 -m timeit -s "s='abcdefghijklmnopqrstuvwxyz'" \ "if s.find('xyZ') == -1: pass" 2000000 loops, best of 5: 140 nsec per loop
Nope :) It does cost a method call.
---
Python version used: 3.8.12
Further exploration:
gemini://hedy.tilde.cafe/help/py?list.index
gemini://hedy.tilde.cafe/help/py?str.index
gemini://hedy.tilde.cafe/help/py?str.find
https://docs.python.org/3/tutorial/datastructures.html
https://docs.python.org/3/library/stdtypes.html#str.index
https://docs.python.org/3/library/stdtypes.html#str.find
https://docs.python.org/3/library/timeit.html
I took quite a long (forced, unavoidable) break to focus on my studies. Thankfully I've updated by tinylog-gen script so it can merge my 2021 and 2022 files now. Speaking of which, happy new year :)
I generally don't care about it though -- I mean it's just another revolution around the sun plus about 3/4th of a day, right? Also more or less beginning from a rather arbitrary point in the orbit anyway.
It's amazing coming back to my inbox reading mailing list archives to read what I'd missed. By the way, I'm surprised I still remember all my shortcuts and keybinds I've set up in nvim, tmux etc.
Most likely for another day to start working on my projects again, sadly. Bye!