Saturday, March 30, 2019

  • Withdrew cash from my Robinhood account as well. Backing to checking. Only about $600.
  • Watched a ton of franklin bbq videos.
  • Supercontest. Added line graph for cumulative scores. PRed and closed #37.
    • Charts.js is a standard clientside choice. You just pass the data structures to JS and it can plot. I chose to do server-side with plotly.
    • Removed week 18 from the leaderboard views (table and graph).
    • Deployed to prod. Told Greg.
    • Defaulted to show only the current user's trace. They can still select others.
  • Finished C++ tutorial on sololearn, google doc with notes as usual. I love this language. I love how explicit you have to be in declaration: datatypes, memory allocation, etc.
  • Covered California replied and said that I might be eligible for Medi-Cal, and the office in my count will contact me soon.

Friday, March 29, 2019

  • Lyft IPOed at $72 (for a total valuation of 20b) and opened at $87.
  • All of my limit sales in Ally executed, so I withdrew the rest to BOA. The only remaining securities I have in Ally are Tesla/Microsoft/Apple (about 10k total).
  • Securities by definition are the superset, including stocks, bonds, and others. Shares are units of stock.
  • HN/M
    • AMP = Accelerated Mobile Pages. Fast and mobile-supported.
    • Just reminders. Let for block scoped. Const for unchanging. Var for execution-context scoped.
  • Submitted the application for Covered California and Medical. I should qualify, since the termination makes me eligible outside of open enrollment (Fall) and current income is 0. This will be a lot cheaper than COBRA ($439/mo for just healthcare, dental is $42 more and vision is $7 more.
    • If the application is approved, my enrollment/coverage begins 5/1.
    • Their web interface was not great. I had to submit multiple times. I hope everything got through, as I made sure it did.
  • Connected Lumin, a decent online PDF editor, to my Google Drive account.
  • Swift tutorial on sololearn. Added doc to Google Drive.
  • More march madnesss. All s16 games done.
  • Collected feedback from folks for the supercontest. Added some color to the lb and all-user pick views, and made a ticket for the remaining items: https://github.com/brianmahlstedt/supercontest/issues/37.

Thursday, March 28, 2019


  • Added up all utilities (so calif edison) and internet (time warner) for the last 24 months with briley, which includes through the March 2019 bills. Check gmail for the total. It's not settled yet, he's gonna cover internet for a while and we'll actually settle these 2 years later.
  • FW/PW.
  • Softball.
  • March madnesssssssssss. Sweet sixteen.
  • Emailed the supercontest app out to the sbsc18 players for feedback.

Wednesday, March 27, 2019


  • Organized the final remaining prep items before interviews start! Moved from Google Keep to here, for posts in the next few days.
  • Making lists of monthly costs for awareness:
    1. $1075 Rent
    2. $450 Food
    3. $150 Car Insurance
    4. $80 Cell Phone
    5. $40 Utilities
    6. $40 Internet
    7. $20 Gas
    8. $15 Amex
    9. $5 Mobile app subscriptions (Spotify, Calm, etc)
  • Almost $2000/month for basics (no bars, no shopping, no trips). Right now, I have a few more out-of-pocket expenses that an employer would usually cover ($250 for health insurance and $40 for gym).
    • Historically, I pay much more than this (about double!) due to restaurants, Amazon, and more. I'll certainly be a bit more observant.
  • About half of my Ally limit sales have been met and fulfilled. Transferred 5k from my investment account to BOA. As I reinvest this money later, I will do so through Robinhood instead of Ally.
  • Set my Mint account back up. I will start regularly checking this as the aggregator. Got familiar with it again. Feels good.
    • Added https://raw.githubusercontent.com/synthead/mint-adfree/master/mint-adfree.txt to the uBlock filter list so the Mint dashboard is adfree and skips all the cards I don't wanna see.
  • Scrubbed my Chrome account and removed the majority of saved passwords (SpaceX, old sites, college accounts).
  • Watched Candyman, an old (92) horror classic I had never seen.
  • Smoked ribs. Incredible.

Friday, March 22, 2019

  • Instead of adding `style="display: none;"` to an element, you can just add `hidden`. It's a global html attribute, like class or id.
  • IIS (Internet Information Services) is a Windows server.
  • Ember, Glimmer, and Aurelia are alternative js framework to react/vue.
  • D3 is a very popular JS framework for visualizing data. Graphs and much more.
  • Lodash (and Underscore) are utilities libraries for JS that offer convenient functions like map and filter. As native javascript expands with similar built-ins, these become less and less necessary.
  • Lottttts of March Madness in the background today, love it.
  • Liquidated about 7k in personal investments to give me a little buffer as I conclude this sabbatical. Exelixis and Take Two Software were my cows, each returning over 400%. My basis years ago was a few hundred for each. Now they're both thousands. Left about 10k across Apple/Microsoft/Tesla, trending well still. Small transactions just to move enough around right now with a low market to give me some security. SpaceX is long overdue a purchase offer.
  • HN/PW/M. Skimmed some stuff this week, but nothing grabbed my attention for a deepdive.

Wednesday, March 20, 2019


  • Did TONS of Seattle trip prep. Weird places to go, cool sights, fun tours, museums, ghost stuff, car, hotel! It was $750 for flights/car/hotel for 4d/3n. Not bad. We'll see how much is added for food/tickets/etc.
  • Groceries and cleaned the whole house: kitchen, bathroom, vacuum, more.
  • Dinner with Alex and Spencer. I miss my dudes! We built a great product in a tough environment.

Tuesday, March 19, 2019

  • Twitch is the external chat client you can embed. I always forget the name so I'm typing it here again.
  • Gbro pooped on the carpet again. The standard pace was too fast, so about 6 weeks ago I slowed it down considerably. I duct taped the center hole fully, then opened it up about half a centimeter every week. Even this proved too much - we're in the 1% here! Holes make cats forget years of bathroom recognition. Giving up and going back to the dome.
  • Did some research in Traeger and Yoder smokers.
  • Went to Bludso's bbq in Hollywood, only a few blocks from Allie's house. Supposedly has some of the best BBQ in LA. I got 1/4lb brisket point, a chicken quarter of dark meat, and 3 spare pork ribs. Overall, I give it a 7. The chicken was the best. The brisket wasn't tender enough for a point, and the bark was underformed. Very small smoke ring. The ribs had great flavor but could have been silkier off the bone. They probably didn't crutch.
  • Filled out two march madness brackets, one for a blake street league and one with the spacex dudes.
  • You can use the <label for="id" ... to make the text on an input checkbox clickable. You can also do it with javascript click events, obviously.
  • SELinux is security-enhanced linux. It's an add-on suite of tools to add security, like disabling network access, etc. It's disabled by default.
  • Besides nginx logs and other app targets, you can always check /var/log/syslog. I forget the obvious sometimes.
  • UFW BLOCK in your syslog is ufw blocking a connection, as it's supposed to. UFW is uncomplicated firewall, ubuntu's built-in.
  • Remember that journalctl also has logs, different from the ones in /var/log.
  • If you type `curl icanhazip.com` you can get your ipv6 address at the command line. Pass -4 for ipv4.
  • If you want to empty a file but keep its location and permissions, run `cat /dev/null > /file/you/want/to/wipe-out`.
  • SC
    • Added winner col to the matchup table and points col to the pick table. Migrated and upgraded.
    • Added leaderboard view! Updated layout, etc.
    • Created a ticket to make the matchups and picks views piggyback on the serverside calculation of winners, rather than doing it clientside: https://github.com/brianmahlstedt/supercontest/issues/33.
    • Wrote Python functions to parse Petty's excel master. One adds (registers) all the users to the User table. The other scrapes all the sheets for each week and adds the picks.
    • Deleted myself and the example users before adding all the 2018 players.
    • Remember, bad transactions will require a rollback() before the same session can be used properly again.
    • Had to do some reverse engineering to figure out how Petty handled duplicate submissions (eg. 5 picks twice) and >5 pick single submissions (he chose the last five, not the first five). This won't be a problem for the app since I enforce it properly, but in order to be accurate in backreference, I made them match.
    • PR, merged, closed ticket #30. Closed the MVP milestone! Moving on to some final items in the next milestone before sending it out for beta.
    • Researched and closed most of the remaining tickets in the "before 2019 season" milestone.
    • Got familiar with flask-assets and flask-cache, for bundling static files and for making expensive routes only run once every N time periods.
    • Spent HOURS trying to resolve issues on the production server. ERR_CONNECTION_REFUSED, site can't be reached. Thought it was nginx, uwsgi, some of my source changes, DNS, digitalocean, reboot, the chrome cache clientside, much more. Checked all logs and many other attempted solutions. Ultimately was certs. Ugh. Just run `sudo certbot --nginx -d southbaysupercontest.com -d www.southbaysupercontest.com` and request/renew new certs (choosing 2 for the https redirect as usual).
    • Some other changes on the production server: Installed xlrd into the venv (which you still have to do with any env changes -_-) and symlinked the service files (which you don't have to do anymore, the links will stay up to date now). Docker will make all this a lot easier.
    • Sent the app to the guys in whatsapp for limited beta testing before forwarding to the whole sbsc email chain.

Monday, March 18, 2019

  • SC
    • Moved the js files around so they're only loaded on the pages that need them.
    • Did the same for css files. Much easier to keep the templates/stylesheets/scripts separate for their various views, consistently named and applied.
    • Added function for get_team_abv for the 3-letter code.
    • Styled the all-picks table. Vertical text was nontrivial.
    • My repo has functional structure currently - an alternative design is divisional structure, where there's a subdir for each route and the static files (templates/js/css) are all alongside it.
    • Closed the blueprint ticket for the next milestone, doing it for the week/picks view nesting. Learned quite a bit here. Reorganized for blueprints.
    • Added a url_value_preprocessor to determine requested_week and available_weeks before passing that information on to the routes in the week blueprint that need it. You're basically just taking it out of the native 'values' dict and putting it into the g object for your own use. Then you don't have to type week<week> in all the routes, and add the week arg to all functions, etc.
    • Added url_defaults as well so that it queries the db for the most recent week on the site's homepage.
    • Organized all the weekX/picks subpages, and added the links for them.
    • Created ticket for the "don't show all picks till sunday" enforcement, to be done at the beginning of next year.
    • Started the LB work.

Sunday, March 17, 2019

  • The template extensions are relative to the template root dir, not local (you have to prepend main/ etc).
  • You can use a <th> tag in place of <td> to get header formatting outside of the header row, like for a left bold column.
  • Stack overflow was offline tonight for maintenance (<1hr).
  • .replace is JS is only for the first occurrence. It's dumb. To replace all, change the first string (the one to change from) "example" to /example/g. You have to remove the quotes, which introduces further dumb requirements. If your string contains special characters, you need to escape them. For example, to remove all periods from an email, you'd do email.replace(/\./g, '').
  • jquery selectors for ID can't have special characters like periods and such.
  • SC
    • Worked on #30, the pick view. Moved templates around to generalize the week header dropdown.
    • Got the pick view basically done. I was surprised how nontrivial it was to handle the table. One of the biggest takeaways: give IDs to all cells in the table, named after the variables (x and y axis headers) passed through jinja. Then jquery can select them easily, rather than trying to find them on the fly.
    • Remaining: some styling, and then generic abstraction of the static content. I basically had views/templates/js for the main table of a week's matchups, but now i need to separate all that for another table so that each has the appropriate scope.

Saturday, March 16, 2019

  • Flask servers persist (or restart after) ubuntu suspension, fyi. If you close your laptop with the app running, it will continue when you reopen.
  • You can have branches in alembic (just like git) for when multiple people are working on changes that modify the models. I accidentally created a branchpoint a while back on the production server. To resolve, you merge the versions (just like git). This creates a new version and migration script (mine was empty, as expected). Then you can migrate and upgrade as usual.
  • For future reference - my net worth exceeded 1m at around age 28. Vested and exercised. Probably age 26 unexercised. The biggest hindrance? Taxes on illiquid assets. AMT traps are real. I paid hundreds of thousands of dollars before even seeing a cent of it. IRC 83(i) will help considerably, but the finance department shucked this novelty due to a clause where purchase offers make employees ineligible. Even...when the purchase offers are inconsistent (nondeterministic schedule), limited (you are severely capped in share sales), unknown (you have no idea when your trap hits), and infrequent (gaps longer than a year apart).
  • The pycharm db browser is buggy if you start manually modifying data.
  • HN
    • Ya, the cookies warnings need to stop.
    • "communicate in the language of options, not demands or preferences" https://news.ycombinator.com/item?id=19349676. I agree. This applies outside the workplace as well. Social issues like racism and other political debates largely stem from personal bias. A withdrawn, impartial view of options and their pros/cons would serve everyone well.
    • This is really cool - basically a sed alternative for find/replace, but with machine learning. https://github.com/Inventitech/strans.
    • The median age of Google/Amazon employees (software in general) is 30. The median age of american workers is 42.
  • Error handlers are pretty easy in Flask. If the exception (or other code, or custom handler) is to be reached in an ajax call, however, you must do something different.
  • SC
    • Removed the backref from the picks table (to users). Left the FK constraint.
    • Removed the points col. This will be a separate table.
    • Added utilities.add_user for easy creation of new users (for testing). This obviously must be invoked from a db context (python manage.py shell), not just any old python console.
    • Created and few users and made sure they were distinct.
    • Moved some test dbs to backups. Merged an old db version, migrated, then upgraded my local dev db.
    • Played with moving html <script> tags around to the proper template to avoid Undefined Variable errors.
    • Did the ajax/flask error handling. If any of the common pick mistakes occur serverside (>5, started game, etc), it will return the traceback and flash the client! All are grouped in the InvalidPicks exception class within the view.
    • Added clientside verification of "game already started" and "can only pick wed-sat". Changed the allowable pick back from status=F to P (the proper one, pregame).
    • Closed ticket #4, created #30 for the last items in the mvp: the pick view and the leaderboard view (then back population from last season's data).
    • Moved the logic for coloring to js (from html). Only applies to picks now, not all.
    • Added an 18th week to the db so that people can play with the pick interface before next season.

Thursday, March 14, 2019

  • PW
    • Watched another tutorial on hidden API manipulation. You really can do some deep inspection with just chrome alone. Adding x-csrf-token headers, scraping for routes, etc. Remember, just run a single get in the same session to grab the token before adding it to headers in subsequent requests. https://www.youtube.com/watch?v=6zge0N962aw.
    • Single page applications, server side rendering, and nuxt.js (for universal vue apps) - https://scotch.io/tutorials/building-a-universal-application-with-nuxtjs-and-django. next.js is React's framework for this.
  • Few small improvements to my bbq game. Ordered a spice dispenser for even rubs, as well as 24" butcher paper for single-sheet wrapping (it was leaking through my separate 12" sheets). Also going to try using the coffee grinder next time for pepper - the hand crank is way too slow.
  • You can access jinja template variables within javascript if you use the html rendering as a proxy. Put this in your template: <script>const myVar = '{{ my_var }}';</script>. This doesn't work if you put it in a separate javascript file, because that isn't rendered.
  • Continued Altered Carbon. While a great show, I still don't like this genre. It's unsatisfying as a viewer to not be able to trust any scene you're presented. It's a deus ex machina on steroids, favoring the show instead of the audience. It's a complexity which hurts the viewer experience rather than adding depth and substance to its plot. Climaxes and resolutions in such worlds aren't clever; they're easy.
  • Template variables are cast into objects (not just strings). This can cause complications between python datatypes and javascript datatypes. Strings are easy. For lists, use the tojson filter {{var|tojson}}. For others, look it up.
  • Multiple elements within the same DOM cannot have the same ID. Use classes to group different elements together, if desired (even if there's no associated styling).
  • SC
    • Worked on commit_picks, parsing the data from the request all the way through writing it to the db.
    • Updated the descriptions on some existing tickets based off new realizations.
    • Serverside and clientside verification of all picks.
    • Emails the user upon pick submission (optionally). Checks and balances, baby. At least until people trust the interface.
    • Changed the table to use classes to group matchup rows and identify the specific columns. Previously, I was using js to find the header and do string matching, or explicitly stating column index. Ridiculous.
    • Handled the submit button logic. Disappears during the ajax call, and reappears if any changes to the picks are made. The user is notified if the picks were committed successfully.

Wednesday, March 13, 2019


  • Blogger's editor uses <br> and <div> tags instead of <p>, hence all the inconsistent formatting in these posts. Sometimes it will inject a newlines at the beginning of a post, sometimes at the end, and sometimes both. It changes all the time, even for a single post that hasn't been edited. Oh well, I can live with this. I've been happy with the other functionality.
  • FW, MD.
  • Registered for the Oct 5 Sonoma tough mudder with Eric!
  • Even if the piece of info is as simple as a single variable, a (hidden) form is still the canonical way to send data to the server. You can do it through ajax, alternatively.
    • If you are using ajax, and you're using flask-wtf csrf protection, you have to send the token (or exempt that route). Incredible help from Martijn Pieters: https://stackoverflow.com/a/22929593.
  • Started watching altered carbon in the background.
  • Supercontest
    • Lots of work on the picks. Played with different methods of sending the pick array to the service. Ultimately went with ajax.
    • Added the csrf token as metadata to the clientside.

Tuesday, March 12, 2019


  • Back from Havasu.
  • Smoked a 10lb pork butt.
  • Verified mileage on all three motorcycles for AAA.
  • Returned Amazon package at Kohl's.
  • Booked Seattle trip with the companion pass for Allie's bday.
  • HN
    • Much better CLI prompts in Python: https://github.com/Mckinsey666/bullet
    • Crunchbase is a cool site that shows lots of internal information about a company. For example, all of SpaceX' funding rounds: https://www.crunchbase.com/organization/space-exploration-technologies/funding_rounds/funding_rounds_list#section-funding-rounds.

Thursday, March 7, 2019

  • Stanford Aero/Astro is starting an alumni newsletter now. There are 17 people in the new aero/astro undergraduate program already! Per Enge died :(
  • I wonder how hard it would be to write a program that parses Ryan’s footage to extract stats like catches and hits. Amazon’s Rekognition tool can do action detection and pathing and such. That would work.
  • Blogger is wayyyy less resource-consuming in chrome than Drive.
  • Caught up on new season of Brooklyn 99. Didn't know it started back up again!
  • Talked to 24 yesterday (Luis). He said that I get a free month but you still have to pay for two months. I assumed that meant that the first month was free, then I could just cancel before paying anything. Sneakily, it meant that you pay for the first and last month, and the middle month is free. I should have pressed harder.
  • Netflix has a heavy ML and experimentation platform. There's a large team working on data science and research. I read their tech blog post about it.
  • To discover private or hidden APIs on a website, just use the network tab of chrome devtools. It will tell you the url routes, the http method, and the data. Then just use it for you own purposes in whatever custom way you want! requests.post(url, data). It can get more complicated with cookies and auth, but you can copy that as well because devtools shows it!
    • A shortcut - just right click the request in devtools and copy it as cURL, or convert it to python, or whatever you want. Very easy export method to repeat requests.
  • sudo apt install gnome-tweaks to get more settings. Removed trash icon, added battery percentage, and a few more small improvements.

Wednesday, March 6, 2019


  • Read a few more Netflix tech blog posts. Encryption, streaming, etc.
  • Read some from Brendan Gregg. Pantastic perf resource http://www.brendangregg.com/.
  • Moved blog to blogger! Better search interface (for my own posts) than Medium. Domain hosted by blogspot (free).
  • Perf records total system activity over a time, then outputs files of the data for something else to analyze. Flamescope is the netflix (open source) tool to visualize this output and determine what was going on. Like a heatmap, it highlights areas of high activity with colors.
  • Periodic railing - could be garbage collection. Periodic idling - could be blocking on i/o, or one thread has a mutex.
  • Strace for system calls/signals, ftrace for kernel function calls, perf for general cpu profiling.

Tuesday, March 5, 2019

  • MySQL is from Oracle.
  • Read an interesting non-binary article that didn’t just discuss gender identity as a new thing, but race identity and age identity. It’s a new perspective to consider trans-gender like trans-race and trans-age.
  • Told Petty about modern db explorers (he was going to build an asp.net application from scratch to read the db lol). Showed him desktop and web versions, lite sqlitebrowser and sqliteonline.
  • Rather than 31+ years, I’ve been alive for 374 months, or 1629 weeks, or 11405 days!
  • Netflix Tech Blog posts.
    • Canary analysis. Deploy new version of software to canary systems to detect bugs. Basically diverting real traffic to a small canary cluster on the side of the production cluster, then comparing metrics and performance.
    • Spinnaker is the continuous delivery stack. They developed it at Netflix, but now it’s used at Google, MS, Amazon, Oracle, many places.
    • Kayenta is the platform that pulls both together. It makes canary deployments autonomous so users don’t have to do these tests manually.
    • Chaosmonkey is public.
    • Public repos!

Monday, March 4, 2019


  • “Disable Cache” is on the network tab of Chrome’s devtools. It only disables the cache while the devtools are open.
  • The em unit is usually the default browser font size.
  • $() is jquery. Much better than the old getElement* syntax.
  • Commas in css selectors means apply the rule to all. Spaces means hierarchy - only applies the rules to the latter elements that are children of the former elements.
  • Css classes aren’t applied in the order you put them on the element, they’re applied in the order they’re defined in the source css document!
  • Removing an element from an array by value is way more complex than it needs to be.
  • Jinja injects newlines stupidly!
  • Remember, var is function-scoped. The new ones for es6, const and let, are block scoped. Const is constant. Let can be reassigned (different than mutable).
  • Supercontest
    • I’m running Bootstrap 3.3.7.
    • Fixed the rounded corners in the table.
    • Smartly added the click functionality, restricted to the team columns, integrated with a submit button.
    • Submit button now smartly appears and disappears based on picks.
    • Used notify.js instead of flash.js to use the less-imposing messages rather than alerts.
    • Warnings appear on >5 picks and opposing-team picks now.

Sunday, March 3, 2019


  • Supercontest
    • The local db was busted so I had to scp it from the prod server and upgrade to the schema with the user table again. Registered my one account to tinker. Copied the db to expedite this if it happens again.
    • Moved the flask_user_layout template to my repo (instead of in the venv flask-user installation) to customize the year and company name, while making everything more consistent. My supercontest layout.html now uses the css classes header-div and clearfix and with-margins and stuff.
    • Remember, if PyCharm is connected to the local db, the app won’t be able to write to it.

Saturday, March 2, 2019


  • Talked with Levi! He’s working at a company called BetterUp. Loves it. Ruby app stack, but still does some Python.
  • Twitch has chat clients that you can embed into your website. Looks to be an easy integration.

Friday, March 1, 2019

  • Checked with Rebecca Balayan, my SpaceX HR coordinator, if I had any outstanding mission patches.
  • Opened the exercise request for my shares. I have 3 days to make the check payment. I’ll send it with Allie or Briley on Monday. Called home and asked for the 30k transfer. BOA has limitations so we may have to wire.
  • There was an $86 charge from 24hr fitness on feb 8. I’ll dispute this back in Hermosa next chance I get.
  • Instead of just instantiating a flask app, having a function return the app is called the “application factory pattern” for future reference.
  • Docker-compose is often used to orchestrate two containers: one for the service and one for the database.
  • Changed my default editor with sudo update-alternatives --config editor.
  • When rebasing, the bottom section of the <<<< ==== >>>> is the newer commit. It will show the hash. The top says head. It’s the older one.
  • When rebasing, “us” is the branch you’re rebasing on (master, usually). “Theirs” is the current branch.
  • HN:
  • Supercontest
    • Deleted branches #2 and #7, they were folded into #3. Rebased #3 and merged. There was some nasty conflicting history. Closed the ticket!
    • Started ticket #4, picks.
    • Created a stripe account to process payments (https://dashboard.stripe.com/test/dashboard). Created a ticket to finish this work later (https://github.com/brianmahlstedt/supercontest/issues/29).