• TSS stands for Transportation Software Solutions. Let Stacey, Roubik, and Art know that my intentions are to move back to the Bay Area.
    • Remy and Katilin got sick on Monday too! It wasn’t the prime rib, because everyone had that and only 3 of us reacted. I’ve also had it a few times since with no problem. Possibilities: dip, cheese, gravy? The latenight snack after stuff had been sitting out could have been it.
    • There’s a paradox about predictability; that once something becomes predictable, entropy naturally makes it move away toward unpredictable again. I half-buy it. I’m a believer in determinism superseding free will in the longggg future.
    • Your body can actually burn an incredible number of calories while sedentary (comparable to rigorous physical exercise), if you are highly stressed/concentrated: https://www.espn.com/espn/story/_/id/27593253/why-grandmasters-magnus-carlsen-fabiano-caruana-lose-weight-playing-chess.
    • Agreed. Personal websites are wonderful tools. https://www.vanschneider.com/a-love-letter-to-personal-websites.
    • GitLab is a company I had seriously considered about 2 years ago: https://www.forbes.com/sites/alexkonrad/2019/09/17/gitlab-doubles-valuation-to-nearly-3-billion. They’re doing very well, and my professional experience matches their mission absurdly well. Their IPO is in 1 year.
    • Chrome’s devtools has a “device toolbar” that you can toggle on and off by clicking the little button that looks like a phone. You can specify any custom viewport, standard phones, and it will show your how your responsive view is displayed. Great for testing.
    • Hahaha AB released from the Pats. What a roller coaster.
    • Supercontest.
      • Added mx-auto to all nav cols so that they’d center on smaller viewports, tested in devtools. Looks much better.
      • The lb totals and percentages will now show as ints if they’re whole numbers (even if source data is X.0). If they’re floats, they’ll continue to show as floats.
      • Webassets.
        • Moved all third-party cdn js to the toplevel template.
        • Moved all variables (that were passed through jinja from flask to javascript) to the toplevel template.
        • Bundled and minified all supercontest js, added in the toplevel template.
        • Cleaned some of the iteration in jinja, setting variables properly.
        • At this point, all templates are just templates. It’s a lot cleaner. All variable injection is collocated, which is easier to understand as well.
        • Made all js in the bundle distinct. Some required more specific ID selectors. Some needed to check on array length. Some needed to condition on typeof <x> !== undefined. This whole exercise was a good practice in forcing explicit javascript.
        • Minifying with jsmin.
      • Package the service.
        • I don’t just want to copy an ambiguous directory over to be able to use the app. It should have explicit boundaries. This will keep it slim, also.
        • Therefore, I made the service a self-sufficient package. It can’t run without an accompanying database already existing, but the app layer itself is self-sufficient.
        • This was a pretty lengthy, iterative process to get to work.
        • MANIFEST only tells it what to build the dist with; not necessarily what to install. You have to be explicit about those as data files in setup.py.
      • Overall, working with bundled assets and wheel pkgs should make the app non-noticeably faster.
      • Closed https://github.com/brianmahlstedt/supercontest/issues/81.
    • Docker.
      • If you built an image successfully but it failed to run the start command or entrypoint for some reason or another, perform the following to test.
        • docker ps -a
        • docker commit <ID> test_image
        • docker run -ti –entrypoint=sh test_image
      • To force a rebuild, even if nothing has changed:
        • docker-compose build –no-cache <service>
        • Then you can start the service at will.
    • tar -xzvf (I can never remember anyway – this is a worthless comment).
    • Remember to build wheels in the same environment that you’ll install them in. Not the same instance, but the same system. There are many underlying system libs that are baked into bdist wheels, and the build/deploy envs should be identical to prevent clashes for this.
    • find_packages() returns a list like this: [‘supercontest’, ‘supercontest.core’, ‘supercontest.views’, ‘supercontest.dbsession’, ‘supercontest.commands’, ‘supercontest.models’, ‘supercontest.graphql’]
    • Supercontest.
      • Datetime, picks, leaderboard:
        • Updated all the datetimes in the database to pacific. Updated the database timezone to pacific.
        • Updated the url defaults. Season is current or max. Week is current or 17.
        • Added g.current_season next to the existing g.season (which is the requested season) and g.is_current_season. Same for weeks.
        • Switched everything to be perfectly clear: all datetimes in the database are utc, all westgate lines are written after conversion from pacific time, and all sqlalchemy reads convert to local.
        • Debug toolbar is helping a lot. Noticed that on RESULTS_DAYS, it was bloated by about 500ms due to excessive queries.score_exists/get_score calls. Consolidated all of them. You could even go further by conditioning commit_scores not just on RESULTS_DAYS, but on time as well to tighten the range in which the extra calls are made. Call fetch_scores protected by results_days, then only call commit if any of the statuses aren’t P/F/FO.
          • Reduced total db queries for the endpoint by >30 and profile reduced by ~400ms.
        • Completed redefined the pick view and how it’s sorted, including the core/results backend to calculate as such. Now returns number of picks, current total points, current possible points, etc. Looks very good now.
        • LB and graph only show completed games in the total now. I added a col for in-progress games so you call still check “what if it all ended right now” status.
        • Percentages are now based on the picks that you have submitted, not the total (5 per week).
        • Combined a lot of the route logic, keeping the endpoints as thin as possible. Most of them outsource to functions in the core.results module now.
        • Added tooltips all over leaderboard for submitted picks, help, more.
        • Universal color for a lot of things.
        • Renamed the matchups tab to your picks. Renamed the picks tab to all picks.
        • Graph and leaderboard are now bulletproof for completed games.
        • Added req compilation back as a requirement of the test step, and ensured that compreqs were installed into the testenv.
      • My make test-python recipe is heavy-handed; it will compile all reqs and recreate the testenv. On subsequent runs, just use tox.
      • Got the bandit tests running again. Pytest is still obsolete.
      • App behaved well over TNF.
      • Closed https://github.com/brianmahlstedt/supercontest/issues/84.
      • Closed https://github.com/brianmahlstedt/supercontest/issues/94.
      • Dashboard.
        • Added a conditional (on my account) navtab for the flask monitor.
    • Bools have to be filtered |tojson to pass through jinja from flask to js. They’ll be properly typeof() = boolean in js.
    • Forcing NBA owners to change their titles to governors due to historical implications is the same false equivalence as telling a German that they can’t use ovens. It’s offensive. It’s irrelevant. Race is being used as glue to compare situations which have absolutely no relation.  It’s not just a “doesn’t affect you” situation – it’s discriminatory, and should not be ok to concede. Finding these parallels with your lens of virtuous sensitivity is not progressive; it’s an overshot of true equality, which slows resolution (if it doesn’t destabilize entirely).
    • Nested dicts are fine to pass through jinja’s |tojson filter for use in js.
    • Fed mouse. First time she’s ever been snappy when I opened the terrarium. Used a broomstick to move her to the feeding tank.
    • My digital ocean droplet is in Santa Clara.
    • Supercontest.
    • Followup appointment with PCP. Got the referrals approved for both ortho and for PT.
      • The x-ray results:
        • Soft tissues: Unremarkable.
        • Bones: No acute fracture or subluxation. No lytic or blastic lesion.
        • Joints: The joint spaces are preserved. Articular surfaces are unremarkable.
      • So x-ray is fine. I’ll probably need to do an MRI, since this would imply that the muscle is the source of injury.
      • Called the ortho place, made an appointment in Van Nuys for next wednesday.
      • I’m going to hold off on scheduling the PT until after the ortho evaluation is done. Stim, stretching, strengthening, etc – I can do that all on my own. The referral won’t expired for 3 months, so I can schedule PT after ortho if need be.
    • Got adjusted at chiro (bought the 3/$90), then went to the new Chick-Fil-A.
    • For the last time: snake_case and camelCase and PascalCase.
    • Reminder for ISO8601: https://www.cl.cam.ac.uk/~mgk25/iso-time.html. All dates should be in the format YYYY-MM-DD.
    • A pipe | in a makefile is for order-only prerequisites. If you change any of those files, the parent recipe does not deem them necessary to rerun.
    • Postgres.
      • To get datatypes:
        • select column_name, data_type from information_schema.columns where table_name = ‘<mytable>’;
        • select pg_typeof(<mycol>) from <mytable> limit 1;
      • I was very pleasantly surprised with postgresql’s ability to internally parse timestamps. It correctly converted the type ‘text’ to ‘timestamp with time zone’ for every single datetime string from westgate. I thought I would have to use the python logic I had written to do this, but it was dead easy using sql in the migration instead.
      • lag() is a window function that allows you to update a row based on a previous row.
    • You can use direct sqlalchemy inside of an alembic migration if you want. This might be easier to (add, modify, etc) your data in python rather than doing it in sql. https://stackoverflow.com/questions/13676744/using-the-sqlalchemy-orm-inside-an-alembic-migration-how-do-i/
    • KFC is rolling out a chicken sandwich that uses glazed donuts instead of buns: https://www.cnn.com/2019/09/17/us/kfc-donut-chicken-sandwich-trnd/index.html.
    • Remember https://www.pngtosvg.com/ is the right place for free online vector conversion with color.
    • Just print(locals()) to show all args/kwargs passed to a function.
    • Changed my default text editor for git to vim: git config –global core.editor “vim”
    • Rob Zombie was on JRE a couple days ago. Cool dude. Just directed another movie, 3 from Hell.
    • Stomach was torn up all yesterday, couldn’t do much. Worse than the ER trip in the bay, but stuck it out. Didn’t sleep, lasted about 24 hrs, but feel better now. Ordered imodium, pedialyte, and pepto bismol on amazon fresh and it arrived within 8 hrs!
    • Lost both FF games. Went 1/5 in supercontest.
    • Supercontest.
      • Went through my giant migration and verified it with pure sql incrementally. Made sure the season/week change were good, user_season_association, then on to picks and scores etc. Made it a lot easier to chunk on the pure db side rather than debugging through the application layer.
      • The problem ended up being the FKs back to week and season for the lines and picks tables. They were matching those two numbers, but not joining lines/weeks/seasons on their id conditions so lines and picks were going to multiple places. Simply added a couple join conditions to restrict this properly.
      • Removed some of the smaller tasks of 68 to a followup ticket 86: https://github.com/brianmahlstedt/supercontest/issues/86.
      • Since the leaderboard iterates over picks, it only shows players who have made picks at all that season. The same is now true for the picks tab.
      • Closed an old ticket: https://github.com/brianmahlstedt/supercontest/issues/33.
      • User registration defaults to add you to the most recent season, but we’ll need a way to do this efficiently at each season rollover. I guess for the 2020-2021 season, I’ll just run quick sql to add everyone who was in 2019-2020 over, then we can prune after week 2-3 like usual.
      • Made determine_current_pick_points() modular to not just require a Pick row. Now, you can provide a Matchup row (line/scores) and a team string, simulating a pick.
      • Picks can be made by any user at any time, no matter if they’re “active” for that year or not. That’s just for our records, and requires the script be run to sync that data based on the existence of picks that year.
      • Finished and closed all the gigantic model changes. https://github.com/brianmahlstedt/supercontest/issues/68. On to the fun stuff.
      • Fixed datetime and improved the lb: https://github.com/brianmahlstedt/supercontest/issues/86.
      • Added a request tracking dashboard: https://github.com/brianmahlstedt/supercontest/issues/77. Useful for timing and profiling over time, and by version. This will be used for production.
      • Added a debug toolbar: https://github.com/brianmahlstedt/supercontest/issues/78. This does a huge superset of the dashboard. You can see sqlalchemy queries, http headers, profiling, total times, etc; a plethora of information for a single request (every time).
      • Made the all-picks view show the team name abbreviations throughout the table so that when you scroll down you’re not lost. Added tooltips for the lines as well. https://github.com/brianmahlstedt/supercontest/issues/83.
    • lol: https://www.youtube.com/watch?v=4sqYEmAy9Dg.
    • “If you go to jail for tax evasion, you’re living off of taxes as a result of not paying taxes.” – Joe Rogan
    • For more complicated boolean queries in sqlalchemy, use not_ and_ etc.
    • Remember, with csrf enabled globally for an app, a lot of plugins might get tangled. You can specifically call csrf.exempt(view_or_blueprint), but this often means going into the source code for an extension to find out how to import the view/blueprint for exemption.
    • For rgb colors, if all 3 numbers match, then it will produce a color in grayscale. All zeros is black. all 255s is white.
      • Supercontest:
        • Backed up the supercontest db, made sure everything worked (with old db models still today).
        • If a user honestly misses lockdown, but wants to pick before kickoff, you can manually add their picks (if you deem their case ok). Just `python manage.py shell` then import and run `commit_picks(…, verify=False)` for the user id and week id and teams, etc.
      • NFL Sunday. Remilins all day.
      • Smoked the 16lb ribeye roast.
      • Made gravy out of the trimmings:
        • Stock: Salt the trimmings in a pan, sear them with olive oil until very brown, deglaze with wine, add herbs/onions/whatever and water, simmer for hours (reduce) then filter.
        • Gravy: Whisk in flour (like 2tbsp per cup of liquid), boil, then turn off.
      • Moved bbq_log from docs to sheets. Lot cleaner now. Froze top row and left two columns during scrolling to make everything a lot easier to see. This was my 32nd smoke on the WSM today!
      • Stack is always lifo, way faster, every thread gets a stack, etc. Heap has much less restriction- it’s bigger and slower. It’s usually across multiple threads (usually one for whole app), data can be written/read in different orders, etc.
      • Quadruple-filtered the batch of oat milk today. Made an ok difference. Each time removes a bit of the suspension. Also added 6 pitted dates. Not the biggest change for half a gallon of milk. Gonna save the dates for the next round of protein bars: pecan butter, tahini, oats, dates, protein powder.
      • Really interesting story about Nick Diaz’ life: https://www.mmafighting.com/2015/9/14/9327767/nick-diaz-opens-old-wounds-on-a-dark-day-in-his-career. Didn’t graduate middle school, been fighting all his life. Biggest motivation was his girlfriend killing herself in high school. Now suspended for 5 years for having marijuana in his system. Frustrated that he can’t be there for his brother.
      • Bought round-trip flight to the bay for the tough mudder, oct 4-7. 15k miles and $11 in fees.
      • Significant rework on a lot of vim shortcuts, mostly.
        • Use on full tmux terminal for vim, and have vim handle the grid between panes for editing multiple files at once. This allows you to copy between files easily. Then keep other grids in tmux for different shell contexts, like python, bash, psql, git, logs, etc.
        • tmux:
          • ctrl-a then c to create tab
          • ctrl-a then n to move to next tab
          • ctrl-a then p to move to previous tab
          • ctrl-a then – to split window horizontally
          • ctrl-a then to split window vertically
          • ctrl-a then arrow to move windows
          • ctrl-a then x to close window, or tab if no more windows (confirm with y)
        • vim:
          • ctrl-w then c to create tab (with filetree explorer)
          • ctrl-w then n to move to next tab
          • ctrl-w then p to move to previous tab
          • ctrl-w then – to split window horizontally (with filetree explorer)
          • ctrl-w then to split window vertically (with filetree explorer)
          • ctrl-w then arrow to move windows
          • ctrl-w then x to close window, or tab if no more windows
        • ctags
          • ctrl-] to jump to def
          • ctrl-t to jump back
          • ctrl- to open def in new vim tab
        • There’s no great way to maximize the current window in vim, like ctrl-a then z does in tmux.
      • Good UFC card. Pereira is one of the craziest fighters I have ever seen. So much capoeira. He did a straight backflip on a downed opponent.
      • Supercontest.
        • Finished updating the core modules for the new db and model structure. Now just need to test with the live app.
        • Removed the read/commit from excel from source. This was a one-team use to pull from petty’s old data. If I need to reference it again, I can scrape the vcs archives. Nominally it won’t be needed ever again.