💾 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

View Raw

More Information

⬅️ Previous capture (2022-06-04)

➡️ Next capture (2023-01-29)

-=-=-=-=-=-=-

 .-----.   .----.   .-----.  .-----.  
/ ,-.   \ /  ..  \ / ,-.   \/ ,-.   \ 
'-'  |  |.  /  \  .'-'  |  |'-'  |  | 
   .'  / |  |  '  |   .'  /    .'  /  
 .'  /__ '  \  /  ' .'  /__  .'  /__  
|       | \  `'  / |       ||       | 
`-------'  `---''  `-------'`-------' 

journal home

tinylog feed

reply via email

May

13

18:36 TIL - diff unsaved changes in vim

:w !diff % -

08

18:06 journal meta

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.

07

15:00 spartan:// on lagrange

Lagrange v1.13 supports spartan!

12:34 TIL - indexing substring and list elements in python

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

January

02

21:34 hello!

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!