More about my bike fall since I wrote about it
two weeks ago.
- I saw a neurosurgeon. He explained that I have a
cavernoma,
which is an anomalous collection of blood vessels with thin walls, which can
lead to bleeding. The bleeding leaves behind iron deposits, which can cause a
seizure. My cavernoma is located in a spot especially prone to seizures.
- The neurosurgeon thought it would be a simple operation to remove the
cavernoma, despite literally being brain surgery. He actually used the phrase
“easy-peasy.” Also, his perspective was that this wasn’t a serious incident,
since it wasn’t a stroke or death. I guess in his line of work, a seizure is on
the small side.
- Another perspective on severity: I took my bike to the shop to get it
checked out. I was telling the bike dude about the crash. He said, “You didn’t
need dental work? Then no big deal!”
- I had an electroencephalogram (EEG). This involved having 27 wires pasted
to my head and chest, then lying in a dark room with my eyes closed while they
measured my brain activity. Toward the end, they placed a strobe light over my
closed eyes, and flashed it at various frequencies. I realized, this is a black
box unit test, and my brain is the system under test: provide some inputs, check
the outputs, without being able to see the implementation. The initial report
seemed to be, “nothing unusual,” but I have to check in with the
neurologist.
- After a few failed attempts, I managed to get the name of the person who
called the police for me after my crash. I wrote to him, and he was very
friendly, but didn’t have any more details about what happened. When he first
saw me I was already on the ground, so he can’t explain the cause of the crash.
Still, it felt good to connect with him and find out what he knew.
My energy level is not what it used to be, probably because of the Keppra
(anti-seizure medication). Psychologically, I am not used to the idea that my
brain can just shut off with no notice. I guess over time, I’ll just ignore that
possibility?
One moment I was riding my bike; the next thing I remember, I was sitting on
the ground talking to an EMT from the ambulance parked nearby.
This happened three weeks ago. I went to the emergency room, had a few CT
scans and an MRI. The best theory is that I had a seizure. So now I am on
anti-seizure medication, and am legally forbidden to drive a car for six
months.
I was wearing a helmet, and was on a bike path, not a street. The physical
effects were minimal: a sore shoulder and some road rash.
There was no eye-witness, so doctors guess I fell because I blacked out
rather than the other way around. During the time I don’t remember, I called my
wife and told her where I was, so maybe I was never truly unconscious? No one
knows.
I usually have a low heart rate (a resting pulse of 50 bpm is not unusual),
so maybe it was cardiac-related? I’m wearing a heart monitor to collect
data.
The first week was hard because I felt completely limited in what I could do.
All spring I had been feeling strong and capable in physical activities, and now
I was finding a short walk difficult.
At first the anti-seizure meds made me tired and a bit fuzzy-headed. But
we’ve adjusted them, and/or I’m adjusting to them, and/or my concussion is
wearing off, so I feel more like myself. I’ve gotten back on the bike (though
not alone), and have been swimming in the ocean, same as every summer.
I have more visits coming up with more doctors to try to understand what
happened, and what might happen. I doubt they will be able to completely rule
out a seizure, so I may be on meds for quite some time. Their recommendations
are quite cautious (“Don’t take a bath without supervision”), so now we are
making absurd trade-offs and considerations of risks and possibilities.
It’s unsettling to have lost time without a clear explanation, and especially
unsettling to think that it could happen again at any time. I’m not sure
what to do with that.
60 shows up in lots
of places. It’s the smallest number divisible by 1 through 6, and perhaps
because of that, it’s the basis of our timekeeping and angular measurements.
Of course the angles in an equilateral triangle are 60 degrees. But
60 also appears in solid geometry. There are four Archimedean solids (regular
polyhedra made with any mixture of regular polygons) with 60 vertices. You can
use Nat Alison’s beautiful polyhedra
viewer to explore them:
Yesterday I did my 400th pandemic walk. These started as a way to get
exercise during lockdown with my son Nat, as I wrote about in
Pandemic walks (Feb 2021) and
300 walks (Sept 2021).
Now I’ve done 400 walks starting and ending at the same point, totaling 2318
miles:
The cadence of these walks has slowed quite a bit. Not the pace of the
walking itself, but the number of walks in a week. Nat is only with us one day
a week now, so I don’t have to be out for his sake. I have biking and swimming
as exercise options now, and my toes were getting a bit aggravated by
walking.
Quantifying the walks was a fun project, and motivated me to get out and go,
but it also pushed me to go farther and farther: in February, all the walks were
longer than 7 miles, which might not have been wise. The problem with a
statistic is the unreasonable expectation that it will constantly increase.
I’m not sure what will happen now. I’m going to continue walking as an at
least occasional exercise, but maybe with a different motivator? Or maybe not:
it’s hard to drop a project once you start it...
Now I’m going on a bike ride, and I’m not going to measure my speed.
We had a tricky debugging need at work: we wanted to track how an attribute
on an object was changing. Here’s the unusual solution we used.
The __setattr__ special method (dunder) is called when an attribute is
changed on an object. But like all special methods, it’s not found on the
object, only on the class. We didn’t want to track changes to all objects of
the class because it would produce too much noise in the logs.
So we wanted a per-object special method. The way we came up with was to
define a new class with the special method. The class is derived from the
object’s existing class, so that everything would work the way it should. Then
we changed the object’s class.
Changing an object’s class sounds kind of impossible, but since in Python
everything happens at run-time, you can just assign a new class to
obj.__class__, and now that is the object’s class.
Here’s the code, simplified:
>>> class SomeObject:
... ...
>>> class Nothing:
... """Just to get a nice repr for Nothing."""
... def __repr__(self):
... return "<Nothing>"
>>> obj = SomeObject()
>>> obj.attr = "first"
>>> obj.attr
'first'
>>> def spy_on_changes(obj):
... """Tweak an object to show attributes changing."""
... class Wrapper(obj.__class__):
... def __setattr__(self, name, value):
... old = getattr(self, name, Nothing())
... print(f"Spy: {name}: {old!r} -> {value!r}")
... return super().__setattr__(name, value)
... obj.__class__ = Wrapper
>>> spy_on_changes(obj)
>>> obj.attr = "second"
Spy: attr: 'first' -> 'second'
>>> obj.attr
'second'
>>> obj.another = 'foo'
Spy: another: <Nothing> -> 'foo'
One more detail: the Nothing class lets us use repr() to show an object but
also get a nice message if there wasn’t a value before.
The real code was more involved, and showed what code was changing the
attribute. This is extreme, but helped us debug a problem. As I said in
Machete-mode Debugging, Python’s dynamic nature can get us into trouble,
so we might as well use it to get us out of trouble.
You can define custom search keywords in your browser to make common searches
easier. How to do it isn’t well documented, so I’m showing you how here.
As an example, I have a custom keyword “pypi”, so I can search PyPI for a
package name by typing “pypi some name” in my browser’s address bar, and it
takes me directly to https://pypi.org/search/?q=some name.
You can create your own custom keywords to have shortcuts to all kinds of
searches. You provide a URL with a placeholder %s in it. When you type
the keyword in the address bar, the rest of the entry is plugged into the
placeholder, and you jump to the resulting URL.
Handy keywords
These are some of the custom search keywords I use. You can use them as-is,
adapt them as you need, or create your own. Instructions for creating keywords
are further down the page.
- py: Search Python docs
- https://www.google.com/search?q=site%3Adocs.python.org%20%s
- pep: Find a PEP by number
- https://peps.python.org/pep-0%s
- pypi: Find a PyPI package
- https://pypi.org/search/?q=%s
- gh: GitHub code search
- https://github.com/search?type=Code&q=%s
- gpy: Google search for Python things, but not Monty Python
- http://www.google.com/search?q=%s+python+-monty
- xlate: Translate text, auto-detecting the language
- https://translate.google.com/?sl=auto&tl=en&op=translate&q=%s
How to define a keyword in Firefox
Firefox defines custom keywords as bookmarks:
- Select Bookmarks - Manage Bookmarks from the menu to open the Library dialog.
- In the left-hand sidebar, select Quick Searches. You’ll see a handful of pre-defined searches.
- Using the gear drop-down at the top of the dialog, select Add Bookmark...
- Enter the URL of the search in the URL field. Use %s as the placeholder.
- Put the keyword you want to use in the Keyword field.
- You can give the bookmark a name to make it easier to find it later if you need to.
- Save the bookmark, and close the Library.
- Now you can use your keyword in the address bar.
How to define a keyword in Chrome
Chrome defines custom keywords as search engines in Settings:
- Select Preferences or type chrome://settings in the address bar.
- In the left-hand sidebar, select Search engine and then Manage search engines and site search.
- Scroll down to Site search.
- Click Add.
- Put a description in the Search engine field.
- Enter the URL in the URL field, with %s as a placeholder.
- Put the keyword in the Shortcut field.
- Click Add, then close the Settings tab.
- Now you can use your keyword in the address bar.
Older: