• Monday

    • Vscode: "editor.renderWhitespace": "all"
    • Cool agad video search tool: https://agadmator-library.github.io/
    • Private work.
    • SBSC. Absolute rewrite of the results module. It’s so much cleaner now.
    • Split into week results, season results, alltime results. And the underlying libs.
    • Split each view into logical segments: init, check, query, organize, calculate, aggregate, sort, inject, toprow.
    • Updating the typing of the module simultaneously. Much cleaner on that front as well.
  • Sunday

    • Set up HEPA purifier.
    • Finalized v2 charcoal triple rise garden. Only items I may consider ordering in a later seed batch: 2 more nurseries (to total 9) and v2 caps (square extrusion).
    • Superbowl.
    • Aquarium maintenance.
    • Equinox etc.
    • SBSC. Typing.
    • Reread all the docs to freshen up.
    • Remember that an alias is a custom collection of other types. A NewType is a custom subclass of another type.
    • Pep589 for TypedDict, a great structure that is still a dict at runtime but allows types for specific keys: https://peps.python.org/pep-0589/
    • Remember that python uses inference on your code to determine type. This is called (static) duck typing, but the official docs call it “structural subtyping”. It just means that you don’t have to put annotations on EVERY param/arg/return/member/var (nominal subtyping) – it can infer it whenever obvious, and will flag when unknown.
    • Wrote a bit for instantiating type aliases. Long story short: don’t do it.
      • I imagine they’ll fix this in a future release, just like they did with allowing subscription within the builtins, rather than shipping a bunch of generics with the typing module to mirror the containers.
      • It would be really nice to define the (nested) type interface and then just instantiate from that.
      • I guess the rationale is that they want us to define our own custom generic classes for these cases, and then instantiate those classes (all instead of type aliases + subscription), because then instantiation becomes clear (and we’re working in the realm of runtime code instead of types).
    • Num = int | float is possible, but I like the explicit version without the alias much better.
    • Notes on the ticket for TypeVars (define/reference) and Generics (scoping). Also invariance, covariance, contravariance: https://peps.python.org/pep-0483/#covariance-and-contravariance and https://peps.python.org/pep-0484/#covariance-and-contravariance
    • Revisited ParamSpec, Callable, and Concatenate. All useful type features for decorators.
  • Saturday

    • Played with vscode launch.json and tasks.json.
      • You can specify a launch configuration however you’d like, then run it from the IDE’s debugger as desired.
      • This can be an execution on the host machine, OR within docker containers.
      • Tasks also allow you to define the common actions of your project. For SBSC, I have all targets defined in a gnumakefile. I could port them over, and get some nice IDE support, but I’m fine running the tasks directly from the CLI with make.
    • Received the Code V3 with cherry MX blues and set it up. Looks, feels, and sounds amazing. Not too hard to push, feels correctly tactile. Took a minute to get used to the 87 key layout again. I never use the numpad, but keyboard size just subconsciously affects my placement.
      • fn-f12 to turn keyboard backlight on/off. fn-f11 to adjust brightness (appears to be 7 levels, including off).
    • Laundry, cleaning, aquarium water change, mealprep, week planning, all the usual weekend tasks. Also made a 5lb chuck roast.
    • Basically finished param typing for SBSC. Will move onto args, members, vars next. Again, this has been an overall useful exercise.
      • Generic type aliases are very helpful.
      • Also ParamSpec.
  • Friday

    • Added vscode shortcut to shell:startup.
    • Bought an air purifier (levoit core 300). I have the airthings for sense, now this provides a control (along with window).
    • Private work.
    • Airthings masters finished. Winners bracket winner won the grand final in all 3 divisions: magnus, fabi, sevian.
    • Received and setup the wave plus. Pretty cool. Air quality is good to start, but sensors need some time to calibrate.
      • Global radon map is here: https://radonmap.com/
      • To check air quality: open the mobile app, wave your hand in front of the device (only red/yellow/green response), or the web dash: https://dashboard.airthings.com/
    • SBSC. Finished the typing ticket from yesterday.
    • Split the “by user and by week” defaultdicts in the results module into separate dicts, one for pick status counts and one for teams (they were joined before, which just complicated things – readability, default behavior, types, etc).
    • Use dict subscription when all keys have the same type and all values have the same type, eg myDict: dict[str, int]
    • Use typing.TypedDict when known keys have known types. Use typing.NotRequired to specify keys as optional.
    • Black defaults to 88 line length. Pylint defaults to 100. I changed both to 100, and synced my vertical rulers in vscode.
    • Good reference on writing type stubs: https://typing.readthedocs.io/en/latest/source/stubs.html
    • More details on ticket.
  • Thursday

    • Lots of private work.
    • NBA trade deadline. All official transactions here: https://www.nba.com/players/transactions
    • Laser tag at Area 53 in DUMBO.
    • Updated my address (nyc) and payment method (zelle) in the class action for: Yahoo Data Breach Settlement.
    • Watched knock at the cabin. I love single setting movies.
    • Keyboard was working ok today after ~24hrs of drying. I still wanted a new one anyway, so I’ll leave the V2 brown as my backup and set V3 blue as my primary.
    • SBSC. Typechecked and annotated the whole package.
    • https://gitlab.com/bmahlstedt/supercontest/-/issues/183
    • Compared mypy, pytype, pyre, and pyright. Ultimately chose the latter. Has inference, supports py3.11, doesn’t ship with a bunch of deps, and very popular.
    • Used pylance vscode extension (pyre-vscode for pyre).
    • All of these use python’s native typeshed under the hood: https://github.com/python/typeshed
    • All speak LSP (language server protocol), the bridge between the IDE and the running code (provides autocompletion, typechecking, etc). Eg between vscode and a python executable.
    • The pyright cli uses Node.
    • Type stubs are .pyi files. They’re the public contract for a python file.
    • You may run pyright --createstub <import> to generate the stubs, or in vscode just hover->quickfix->createstub. They’re organized by module.
    • The default stubpath is ./typings. If that doesn’t exist, it will try to infer from code usage (if useLibraryCodeForTypes = true). This should be committed to VCS.
    • Some third-party packages ship with them, some don’t. Some have a separate <pkg>-stubs (I don’t like that, just ship with the pkg), some have no typings at all (and you have to generate them for the interfaces that you use, if desired).
    • For first-party packages, you shouldn’t need stubs. Your code should be directly annotated with types. You may do this with the same process as the above, by using pyright to generate the stubs, and then using another tool like merge-pyi or libcst to autoannotate your code from the types in the stubs. But you have direct access to the code – it’s usually best to go through and just incrementally add annotations.
    • Went through and started with very lenient scope, then slowly ratcheted the strictness while adding annotations and fixing bugs.
  • Wednesday

    • Went through google password manager and did a cleanup. 195 passwords. 0 compromised, 0 unused, 7 weak (all from other people).
    • Lots of private work.
    • Looked at AWS devtools:
      • https://gitlab.com/bmahlstedt/supercontest/-/issues/194
      • CodeCommit, CodeBuild, Code Artifact, CodeDeploy, CodePipeline.
      • CodeStar is the quickstart for all of those.
      • Just like gitlab, which has a full source->prod flow (for free).
      • Just like github actions.
      • Just like bitbucket+bamboo in the atlassian world.
      • What AWS devtools does not have is a ticket system. Gitlab/github/jira all do.
    • Whitney testified in congress (the House Committee on Energy and Commerce) for legislation around satellite comms technology: https://www.youtube.com/watch?v=Btx6FUP24jM. David Goldman (Senior Director of Satellite Policy, SpaceX) testified as well.
    • In Biden’s SOTU last night he asked for congress to increase his IRA’s 1% buyback tax to 4%. Absolutely insane.
      • Of the two primary liquidity opportunities for shareholders (dividends and tenders), the act is meant to discourage buybacks and push volume over to dividends as that generates more tax income for the govt (as Levine posted about today).
      • That’s ridiculous though – dividends are taxed as income, buybacks are taxes as cap gains. Both are taxed appropriately, and according to first principles already. To double tax tenders is just silly.
    • Received replacement parts for rise garden and the charcoal v3 extension. Now just missing a single screw (gonna skip this one, the top is stable with the other 3), hole covers, and pump inlet foam. Ordered the latter 2.
    • Poured an entire cup of coffee on my keyboard. I had a Code V2B 104-key, Cherry MX Brown. Don’t need the numpad at all, I can go back down to 87-key.
      • Of the Cherry MX switches (gold standard), first decide linear, tactile, or clicky (order of sound/force).
      • Linears: silver -> red -> nature white -> black -> grey.
      • Tactiles: brown -> clear -> grey
      • Clicky: blue -> green -> white
      • There’s a new brand Zeal that makes a few switches called Zealios. They’re supposed to feel really good.
      • Ended up going with the Code V3, 87-key, and cherry MX blue switches.
    • Could do some customization like the below (lol) if you order directly from the Code (WASM) website.
    • SBSC. Networking.
    • Created a single A record to point to my EC instance’s elastic IP, so there’s a single source of truth. Then any other record that wants to forward to the machine (directly, like for ssh) instead of the root domain name for website access (via the ELB) can just use an A record to point to the IP’s A record.
    • And an A record to point from the www subdomain to the root domain (in supercontest, can do this directly in route53; in privateer, do this through amplify – it creates the route53 A record to amplify’s cloudfront for you).
    • Explicitly added another listener to the load balancer which redirects all http/80 traffic to https/443 (the other listener, which forwards to my target group, which forwards to the EC2 instance). Can’t do this through DNS, of course.
    • Could just have the ELB continue to forward to 80 on the EC2 instance, but remove the nginx container and have the gunicorn app container ports: 80:8000
    • But again, better to front gunicorn with a proxy (other than ELB, which is handling the load balancing and the cert/decryption). Even though I’m not serving static files through nginx (using cloudfront instead), it is still good for buffering and other custom proxy configs.
    • AWS (all accounts). Did some billing analysis.
    • Here’s an average 3 months before the network changes
    • EC2 and route53 are expected and fine.
    • Cloudwatch seems a little expensive. And not sure why it’s only happening in the second half of every month. Maybe it’s free up to a certain number of metrics transmitted, then starts charging.
      • It charges for custom metrics (30c/mo), dashboards ($3/mo), alarms (10c/mo), logs (including the logs from just running the cloudwatch agent), more. Pretty expensive (relatively). Mine is about $2.60/mo.
      • Deleted the dashboard and changed the disk_used_percent to only push for / (it was pushing for all mount points, which is 29 custom metrics!
    • The other surprise is ELB. Over the past two days since starting, it’s charging about 45c per day. It’s the offseason with no traffic. This should be pennies.
      • This is just to HAVE the load balancer active. It’s ~$18/mo just to run one in us-west-1, then traffic costs on top of that.
      • ELB is crazy expensive if you’re just using it for https. It’s just a cert. It only really makes it worth it if you’re serving multiple sites with the same cert, and/or using the actual load balancing functionality to proxy to many many instances.
      • Therefore – if you move the app to serverless (lambda per request, fronted by API gateway) or (eks/ecs with nginx ingress), you don’t have to pay for the load balancer anymore.
    • There are some pretty cool cost anomaly detection and budging-reaching notification services.
    • Updated my root aws account’s default console layout.
  • Tuesday

    • Placed all positions from the td deposits last week, not that they’ve cleared.
      • Remember that (even after a cleared deposit) you go on margin until the trades settle (<=2d), but you don’t accrue interest on that margin.
      • And remember that at the end of every day, they’ll sweep cash automatically into an FDIC insured deposit account which accrues interest for you.
      • Although this account is not covered by SIPC (Securities Investor Protection Corporation), which helps recovery/return of assets when a broker fails.
      • Enabled futures and forex.
    • Bought an airthings device, help support the chess sponsor.
      • And since I work from home every day, would give good insights for window/sleep/etc.
      • Between the wave plus and view plus.
      • The view adds a display, an internal hub (wifi instead of just bluetooth, and connect multiple devices), and particulate matter sensing.
      • You can buy the hub separately, but I have a small home and only need to check it when I’m there, so I don’t need a hub.
      • And I don’t need a display, I’ll just use the app.
      • And PM is less important than the other metrics.
      • Wave plus is $130 after $100 airthingsmasters discount, view plus is $300.
      • So overall, went with wave plus.
    • Lots of private work.
    • SBSC.
    • Lots of cleanup of SBSC from the past 2 days. Finished a ton.
    • Created milestone to finish before the offseason pause: https://gitlab.com/bmahlstedt/supercontest/-/milestones/7. Organized all tickets.
    • Created board to track as well: https://gitlab.com/bmahlstedt/supercontest/-/boards/5334642?milestone_title=2023%20Q1%20Part%202
    • Boards in gitlab are nice because you can order (the hidden “rank” propery in jira). But they don’t have good “status” columns. It’s just open and closed. The “labels” are meant for static ticket properties (like “this is a bug” – basically a jira ticket type).
    • Created milestone for 2023-2024 season: https://gitlab.com/bmahlstedt/supercontest/-/milestones/8
    • Created a bunch of tickets with AWS plans for these cloud splitouts.