-
-
- Private work.
- Japan won WBC.
- DII final four: NSU, West Lib, San Bernardino, Black Hills.
- Bard waitlisted (man, people are addicted to this stuff right now).
- JPow quarter point hike.
- Played with all calendly add-to-website options (embed, button, link) – they’re pretty great. But I don’t want to advertise on my site, already get way too many cold calls and reachouts from random people.
- More gardening.
- SBSC.
- Parametrized the “iterate over” for each dimension. Basically games for all, but wanted to make it variable.
- Also parametrized the aggregation capability. Only average is used right now, and only for line/margin.
-
- Renewed ducati NY registration. $42.
- Gmail notification bubble on iphone wouldn’t go away. 0 unread. Restarted app. Restarted phone. Nothing worked – until a new email came in and was read. That seemed to flush.
- Anemones can live for hundreds of years.
- Spoke with Rise Gardens again. I planted a few new lettuces/herbs today so they’ll be lush by the time the Good Morning America taping occurs. They’re also sending me a few 8-slot lids and will have me rearrange the desired plants to settle before bringing to the studio. If I deliver, they don’t have to fly out.
- SBSC. Great progress on the dynamic looping of the statistical analysis/plotting based on dimension classes.
-
- Private work.
- Vernal equinox, first day of spring.
- UBS bought Credit Suisse, 3.2B.
- FRB still troubled, getting help from other banks.
- Bought another tortilla press.
- SBSC.
- Updated the
progression
graph (plotly scatter) to follow the same format as the hbars of stats. Moved to plotting
module.
- Moved the
calc_percentages
functionality to the form_hbar
plotter. It now assumes a multi-trace bar graph has complementary values.
- Wrote some strategies for the dynamic looping of variables/adjacency/statistics. One using the “by” variable, the other using games directly. So far, the latter is superior.
-
- Private work.
- Lots of gardening.
- Remember that SQLA relationships define the join conditions and allow convenience ORM access to cols on instances (objects). As opposed to classes (tables), which is used for queries – only
has
and any
exist for those.
- Confirmed that alembic’s
alter_column
for a rename
does NOT update the names of constraints (like FKs). Same is true for tables (the default prefix of FK constraints). It does update the references and functional pointers, just not the name.
- SBSC.
- Continued on the rewrite.
- Graphql SQLA2 support coming out “soon” as of 5 days ago: https://github.com/graphql-python/graphene-sqlalchemy/pull/368
- The
Contestant
change made it so line commit doesn’t have to do score commit. It’s just an initial insert of the 1 Game
obj and 2 Contestant
objs.
- Added the functions to the
Game
class: get_contestants_by_prediction/location/coverage
. Also added get_opponent
to the Contestant
class. All useful. Better located here with the models than elsewhere (queries
module, results
module, stats, wherever).
- Removed all the
get_la_matchups
logic of the scores flow. Much simpler now that we can just look it up on the Game and Contestant objects.
- Basically got the app working again after all the model changes.
- Now just need to (1) dynamically loop the stats builders then (2) final optimization.
-
- SBSC. Continued on the model/schema redesigns.
session.refresh(var)
if you’ve committed changes that affect it (like for aggregators/observers).
sqlalchemy_utils.observes
appears to be smart enough to NOT trigger directly on the objects/vars/paths you pass to the decorator, but rather the nested cols you actually use within the function. This is good in 1 way: You can observe the high level, and it will only trigger on changes to the lowest dep (not ANY change to the highest obj tree). This is bad in 1 way: A bit misleading, when you think that the value you pass to the observer explicitly defines the trigger scope.
- Actually I’m not sure about the above^. When I had
observes(game)
, changing game.line
triggered both opponents to update, but changing game.opponents[0].score
only triggered opponent[0]
to update. Overall, I just want to be explicit about what triggers the observer calc.
- You CAN have tables FK to themselves (and be self-referential in sqla): https://docs.sqlalchemy.org/en/20/orm/self_referential.html. This is common for adjacency matrixes, where a Node table might have a parent/child Node.
- Renamed
Opponent
table to Contestant
to avoid confusion.
- Important: Looks like
sqlalchemy_utils.observes
can observe cols of the local table, as well as relationships. But for relationships, it seems to ONLY support aggregation functions. Example: you have a one-to-many relationship. The observer can do a nested calc like child_count = len(parent.children)
. But it CANNOT do something like first_child_plus_decade = parent.children[0].age + 10
and trigger on the children[0].age
change. Unfortunately, that’s exactly what I need for Contestant.score
(for the opponent).
- To fix this, I just denormalized
opponent_score
into every row of the Contestant
table.
- Ended up keeping the change to switch the order of
Game
and Contestant
in the hierarchy. Keeps the purity (standardization) of the many-to-one relationship and removes the hardcoded 1s and 2s. Gonna have some circular referencing in the bidirectional relationship between them, no matter which wraps which. And could have made Pick
only FK to Contestant
no matter what, since they’re bidirectionally related, but kept that change as well. Pick
-> Contestant
-> Game
. No need for Pick FKs to both.
-
- Steph on pace for his 2nd 50/40/90 season. Only happened 13 times. https://en.wikipedia.org/wiki/50%E2%80%9340%E2%80%9390_club
- NY is empire state. CA is golden state. NJ is garden state. All: https://en.wikipedia.org/wiki/List_of_U.S._state_and_territory_nicknames
- The mesh screen in front of mics is called a pop filter. Plosives can cause popping sounds on the record, this slows the fast moving air from speech.
- Any key that can guarantee uniqueness in a db is called a candidate key. In simple tables, this can be the primary key, a integer that autoincrements. But sometimes it’s useful to use other columns. Say, email in a user table. Now imagine you have a locations table. Address alone might not be unique – could be multiple units. You can use a composite key like address + apartment_number to become unique / candidate key.
- SBSC. Wrote the migration for lines->games and teams->opponents. Was one of the more complicated migrations I’ve written for sbsc.
- SBSC. Did some more model/schema redesign. Particularly the hierarchical relationship between
Game
and Opponent
.