• Activity
  • Votes
  • Comments
  • New
  • All activity
    1. Remember the person: Effortposting about Tildes and anti-social UX patterns in social media

      I've been meaning to make this post for a while, and it's actually going to wind up being a series of several posts. It's kind of a long meditation on what it means to socialize online and the...

      I've been meaning to make this post for a while, and it's actually going to wind up being a series of several posts. It's kind of a long meditation on what it means to socialize online and the ways in which the services we use to do that help or hinder us in doing so. Along the way I'm going to be going into some thoughts on how online discourse works, how it should work, and what can be done to drive a more communal, less toxic, and more inclusive of non-traditional (read: non-technical) voices. I'm going to be throwing out a lot of inchoate opinions here, so I'm hoping to pressure test my views and solicit other viewpoints and experiences from the community.

      I mentioned in an introduction thread that I'm a policy analyst and my work is focused on how to structure policies and procedures to build a constructive organizational culture. I've been a moderator in some large PHP forums and IRC channels in the old days, and I've developed some really strong and meaningful friendships through the web. So I've always had a soft spot for socializing on the interwebs.

      Okay, so that's the introduction out of the way. The main point I want to focus on is the title: Remember the Person. This was the something Ellen Pao, former CEO of Reddit, suggested in a farewell message as she stepped down from the role in the wake of a community outcry regarding her changes to Reddit's moderation practices. The gist of it was that online communication makes it too easy to see the people you're interacting with in abstract terms rather than as human beings with feelings. It's a bit of a clichéd thought if we're being honest, but I think we still tend not to pay enough attention to how true it is and how deeply it alters the way we interact and behave and how it privileges certain kinds of interaction over others. So let's dig in on how we chat today, how it's different from how we chatted before in discussion forums, and what we're actually looking for when we gather online.

      Since this is the first in a series, I want to focus on getting some clarity on terms and jargon that we'll be using going forward. I'd like to start by establishing some typologies for social media platforms. A lot of these will probably overlap with each other, and I'll probably be missing a few, but it's just to get a general sense of categories.

      To start with we have the "Content Aggregator" sites. Reddit is the most notable, HackerNews is big but niche, and Tildes is one too. This would also include other sites like old Digg, Fark.com, and possibly even include things like IMGUR or 9Gag. The common thread among all of these is user submitted content, curation and editorial decisions made largely by popular vote, and continued engagement being driven by comment threads associated with the submitted content (e.g. links, images, videos, posts). In any case, the key thing you interact with on these sites is atomized pieces of "content."

      Next up are the "Running Feed" services. Twitter and Mastodon are the classic examples as is Facebook's newsfeed. Instagram is an example with a different spin on it. These services are functionally just glorified status updates. Indeed, Twitter was originally pitched as "What if we had a site that was ONLY the status updates from AOL Instant Messager/GChat?" The key thing with how you interact with these services is the "social graph." You need to friend, follow, or subscribe to accounts to actually get anything. And in order to contribute anything, you need people following or subscribing to you. Otherwise you're just talking to yourself (although if we're being honest, that's what most people are doing anyway they just don't know it). This means the key thing you interact with on these sites is an account. You follow accounts get to put content on your feed. Follower counts, consequently, become a sort of "currency" on the site.

      Then you've got the "Blogs" of old and their descendants. This one is a bit tricky since it's largely just websites so they can be really heterogenous. As far as platforms go, though, Tumblr is one of the few left and I think LiveJournal is still kicking. Lots of online newspapers and magazines also kind of count. And in the past there were a lot more services, like Xanga and MySpace. The key thing you interact with here is the site. The page itself is the content and they develop a distinct editorial voice. Follower counts are still kind of a thing, but the content itself has more persistence so immediacy is less of an issue than in feed based paradigms where anything older than a day might as well not exist. This one gets even trickier because the blogs tend to have comment sections and those comment sections can have a bunch little social media paradigms of their own. It's like a matroishka doll of social platforms.

      The penultimate category is the "Bulletin Board" forum. PHP BB was usually the platform of choice. There are still a few of these kicking around, but once upon a time these were the predominant forms of online discourse. Ars Technica and Something Awful still have somewhat active ones, but I'm not sure where else. These also have user posted content, but there is no content curation or editorial action. As a result, these sites tend to need more empowered and active moderators to thrive. And the critical thing you're interacting with in these platforms is the thread. Threads are discussion topics, but it's a different vibe from the way you interact on a content aggregator. On a site like Reddit or Tildes all discussion under a topic is 1 to 1. Posts come under content. On a bulletin board it works like an actual bulletin board. You're responding under a discussion about a topic rather than making individual statements about an individual post or comment. Another way to put it is on an aggregator site each participant is functionally writing individual notes to each other participant. On a bulletin board each participant is writing an open letter to add to the overall discussion as a whole.

      And finally, you've got the "Chat Clients." This is the oldest form besides email newsletters. This began with Usenet and then into IRC. The paradigm lives on today in the form of instant messaging/group texts, WhatsApp, Discord, Slack, etc. In this system you're primarily interacting with the room(s) as a whole. There isn't really an organizing framework for the conversation, it's really just a free-flowing conversation between the participants. You might be able to enforce on-topic restrictions, but that's about as structured as it gets.

      That about covers the typologies I can think of. Next up I want to delve into the ways in which the UI and design patterns with each of these platforms affects the way users engage with them, what sorts of social dynamics they encourage, and what sorts of interactions they discourage. In the mean time, I'm eager to hear what people think about the way I've divided these up, whether you think I've missed anything, or have any additional thoughts on the ones I put up.

      30 votes
    2. My ginger carrot hot sauce is missing something, but I can't tell what

      Ever since I learned how easy homemade hot sauce is, I try to experiment with a new batch or recipe from time to time. My most recent batch highlights carrot and Ginger, with mild jalapeno heat....

      Ever since I learned how easy homemade hot sauce is, I try to experiment with a new batch or recipe from time to time. My most recent batch highlights carrot and Ginger, with mild jalapeno heat.

      It tastes good, and the ginger is very apparent, but my SO and I feel it's missing something. Of course you can't taste it through the internet, but based on the recipe, can you provide any suggestions for what can help round it out or take it from good to great?

      Ingredients:

      • 3 carrots, 4 oz
      • 1 knob of ginger, peeled, 2.5 oz
      • 4 jalapeños, 8 oz
      • 4 cloves garlic
      • 1/4 of a red onion, didn't weigh
      • 1/2c apple cider vinegar
      • 1/2c water
      • 1/2 tsp kosher salt
      • 1/2 bunch of cilantro, maybe a couple of tsp after chopping

      Method:

      1. Thinly sliced carrots, ginger, peppers, onion, and garlic
      2. Sautee until brown around the edges (carrots and ginger took longer, garlic was just for a minute to avoid burning)
      3. Blend with salt, water, vinegar, and cilantro.
      4. Strain solids

      Any ideas on what it's missing? Some kind of tomato product? Something earthy like cumin? More garlic or onion? Something else entirely?

      EDIT: Thanks for all the great feedback! I poured a few small samples to test various additions based on your suggestions, and I ended up adding another 1/2 tsp of salt (for a total of 1 tsp), 1/2 tsp MSG, the juice of half a small lime, 1 squeeze of honey (estimated just shy of 1 tsp) and then thickened with 1/8 tsp of xanthan gum since it was really thin.

      Next time, I definitely want to try roasting the peppers and veggies, and I'll try a blend of peppers. I'm curious about other ginger preparation methods, too, such as raw, roasted, or powder. But for a mildly hot ginger sauce, I'm calling this experiment a success!

      29 votes
    3. Why Tildes doesn't need to be fully public

      Tildes is currently invite-only. (Thank you redditor u/⎷⎷⎷⎷⎷⎷). Of course, it's in alpha testing, so that makes sense. When do you think tildes will be made public? How will they do it? I don't...

      Tildes is currently invite-only. (Thank you redditor u/⎷⎷⎷⎷⎷⎷). Of course, it's in alpha testing, so that makes sense. When do you think tildes will be made public? How will they do it? I don't think it ever really needs to be made public. The reasons are that:
      1 - Bans are actual bans. Getting beyond a ban is ridiculously hard compared to on Reddit, where someone just makes a second account. On Tildes, if you're banned, you're banned. That's it. It weeds out a lot of trolls.
      2 - Throwaways can't be made. Making a throwaway account on Tildes costs one of your invites, so it's much more annoying to do so.
      Hopefully you enjoyed my little rant.

      29 votes
    4. A variety of beginner home server questions

      I will soon have a home and figured now's the time to do a proper home server, especially since it's going to come with cat 6 run from the main panel to just about every room. I code for a living,...

      I will soon have a home and figured now's the time to do a proper home server, especially since it's going to come with cat 6 run from the main panel to just about every room. I code for a living, but at the same time network is a massive gap in my knowledge, as are servers, and I was hoping to use this as a learning moment as well as just a way to optimize things. I've been doing research for a few weeks now on and off and feel like I've got more questions than I started with, so I'll just vomit them out and if anyone has some guidance I'd really appreciate it.

      Some information:

      1. I'm willing/able to spend to get quality/simplicity. Time is the much bigger crunch for me right now, and I'd much rather buy something that works even if it costs more than cobbling together some deals.

      2. Related to 1, I'd like this to not become my fulltime second job/hobby. I will at some point try to expand to a full home lab, and do want to use this to learn about things I feel I should understand better for general knowledge and my career, but i'd love for core functionality to mostly "just work" after configuring so when I don't have time to do that I'm not stuck telling everyone "oh yeah it'll be broken until I find time to fix it".

      Things I know I want-

      1. Some sort of NAS. From my research Synology comes up a lot as the "it's expensive but it'll just work" option, and I probably want something like a 4 bay of NAS specific several TB HDD's in something like raid 5/6/10. Pricey as hell but I'm most willing to spend on this as the cost might very well be split by the family members who want me to guinea pig all this.

      2. I will have a camera system and would prefer to not have it sending data outside my network. This is the area i've looked at the least, as it's a little farther down the road, but I know others who have things like Arlo and lets just say i'm not super impressed. Obviously this brings up question like remote access to said camera's and where I'm storing the data (nas? Somewhere else?)

      3. I'd like to mess with a media server. Plex/Jellyfin constantly come up in my research, so I'll be looking into those, but I've also got a bunch of audiobooks that I'd love to be able to easily share, and I think there's software for that stuff as well.

      4. Pihole strikes me as the other "well if you're going to do this, you might as well" option that i'm aware of. Realllly need to better understand networking in general, but I hear these days it can kinda be installed and quickly configured and then left to do its job.

      5. Related to all of this, Casa OS keeps coming up as a very good tool for a beginner like me, since it streamlines the handling of docker containers and also file sharing. However it's not really an OS, since it must actually run on Debian (i think?) for now (zima OS still in testing?).

      Stuff I'd like to mess with but doesn't have to happen right away.

      1. Eventually the aforementioned NAS would be backed up offsite to another NAS at another family members house, once I know what the hell I'm doing.

      2. Proxmox constantly comes up as THE tool to use, but it leaves a lot of questions for me. Obviously if I start trying to do lab environments and screw with VM's it's going to be great, but my understanding is that I probably don't, as a beginner, want to say load up a device with proxmox and then have it host debian which installs CasaOS as it'll get a little more tricky to have everything talk right? Unsure on this part.

      3. Anything else I'm forgetting. One issue I keep having with this is a LOT of the information out there is either too complex for me to really grok or just says "well yeah you could do ANYTHING with this" and it just sorta assumes I know what the options are. If there's anything else worth checking out I'd love to know.

      Hardware I've come across-

      1. Synology - Already mentioned but seems like they're a common go to for a "more money than skill/time" situation like mine.

      2. Zimaboard - My understanding is it's underpowered for its price, but the main draws are that it's VERY low power, small, and quiet. What it could actually do from my list above is where i'm unsure. I see people are supposedly using it for Plex servers and what not, and I'm pretty sure it's not going to make any kick ass lab environments, but being quiet, small, and maybe a bit closer to plug and play seems tempting (I know they make the blade and a few other products but it all seems greek to me).

      3. Various mini computers - I've got a minisforum machine from several years ago that I currently use as a living room computer for light gaming and mostly playing movies and the like. Not sure if i could just wipe it and convert it to be the starting point (more on that later). I know used 1 liter mini pc's from companies like HP are also popular.

      4. The MS-01 - Similar pile as the last one but my understanding is this is the kind of thing that's probably really cool if you actually know what the hell you're doing. I'm 99% positive it is vast overkill for my purposes, but I'd like to eventually get to the point where I could understand why I might want something like this. My understanding is if I knew what I was doing I could probably drop proxmox on this and do everything I could ever want and more, but I feel quite far from that.

      Some general questions I have -

      1. The thing that kicked this all off is my new place likely having fiber, and cat 6 drops throughout the building. Architecture is something I'm still a little shaky on. I assume i'm going to need my own modem/router (just because the cox routers are meh and not really configurable from last I checked), and then that routes to the server first???...or something(seems like a must if you want the pihole to do anything)? I've seen lots of niffty network diagrams at this point but they're all from people WAAAAAAAAY beyond my skill level doing much more ambitious stuff, so it gets hard to understand. If anyone has a simple home network diagram/guide to look at I'd really appreciate it.

      2. I'm just in general going to need to learn more about networking, especially in a home environment. Should I eventually get those camera's set up, I want to understand how to let them talk to internal storage and what not ,but not get out to the web...or..something (again remote access seems nice, but also like a massive security concern). I know speed is also a big factor i'm going to need to better understand. Having a fiber connection in only to be bottle necked by a crappy router or a 1gigabit port is just a waste of money, so that's something else I'd like to better understand.

      3. I'm a little unclear on how to deliver the media in a media server to the various screens throughout the building. I've got cat 6 to all of them, but I suspect i'm still going to need, at the very least, a cheap computer to hook up to it and then display the image to the monitor/TV? This is why I assume I can't just wipe my current mini PC and reuse it as a server, because I still need it to receive the data from the home server (or at least a web browser?). A part of me feels like if I got a powerful enough server it should be able to server the media direction to the screen, but then you'd need some sort of HDMI/DP drops as well from the server to all your screens?...or something?

      Sorry for all the rambling but I've got an odd mix of knowledge and ignorance so it's been a little difficult to research when half the video is stuff I already get, and the other half blows past me or just assumes I know about the parts i'm trying desperately to learn about.

      27 votes
    5. Learning and studying things without taking notes

      I'm curious if there's anybody here who's like this. Either doing it without writing things down, or doing it minimally. I don't know why but I find it very difficult to do, and it stops me from...

      I'm curious if there's anybody here who's like this. Either doing it without writing things down, or doing it minimally. I don't know why but I find it very difficult to do, and it stops me from actually learning/studying. I feel like it slows me down, significantly. It also feels like a chore. I feel like part of this may be because I'm in information security? Like, there's a lot of reading and researching going on, then immediate practicing and applying. Even when I have to take tests. I just read and listen or whatever else and that's it. Maybe in other fields, taking notes is a big thing, or maybe it's just me. I also have other interests, but yet still, I simply can't bring myself to write things down. I just prefer to absorb everything, in whatever pace I like, sometimes it's slow, sometimes it's fast. If I ever decide that I'm going to take notes while learning/studying, I'd stare at my notebook/software for a very long time. I'd sit with one chapter/slide for quite awhile. At the same time, I truly admire people who take notes and write stuff. I do wish I was like them sometimes. Is anybody out here the same? Even though I really want to hear from people who are similar, everyone else can join the discussion too. What do you do? How do you do it? What is your preference? Do you think there's a "better" way to do things? Could taking notes be "superior" to the opposite?

      27 votes
    6. Inside the very strange, very expensive race to “de-age”

      Whizy Kim The Rejuvenation Olympics, an online leaderboard launched by tech millionaire Bryan Johnson earlier this year, takes the rivalry of the rich to the next level. The game? “Reversing” your...

      Whizy Kim


      The Rejuvenation Olympics, an online leaderboard launched by tech millionaire Bryan Johnson earlier this year, takes the rivalry of the rich to the next level. The game? “Reversing” your age

      Link to the article


      Participants compete not on physical abilities but on how quickly and by how much they can slow their “biological age.”

      Competitors do this mostly by adjusting their diets (like which macronutrients and supplements they consume), being physically active, and retesting their “age” regularly. They’re not actually reverting to a more youthful version of themselves — that’s not biologically possible. Rather, these competitors are racing to see who can age the slowest; as the Rejuvenation Olympics website quips, “You win by never crossing the finish line.”

      Some participants

      Steve Aoki, the DJ and heir to the Benihana restaurant chain, appears toward the bottom of the site’s “absolute” ranking, which reflects the 25 competitors with the lowest rate of aging.

      The biohacker Ben Greenfield makes the list, too, as does millionaire and longevity science advocate Peter Diamandis. Most of the top 25 names, however, don’t spark immediate recognition, and some are anonymous.

      Right now, tech millionaire Bryan Johnson, who is 46 years old, is leading. But 46 is just what competitors describe as Johnson’s “chronological age,” which means, simply, the years that have passed since his birth date.

      He has claimed that he eats 70 pounds of vegetables per month, most of it pureed. He receives blood transfusions from his 17-year-old son. He wears a red-light cap that’s supposed to stimulate hair growth. His body fat once fell to a dangerous 3 percent (though it has since bumped up a few percentage points).

      Twitter founder Jack Dorsey is renowned for his eccentric wellness habits; he eats one meal a day, meditates for at least two hours daily, and has a penchant for ice baths. For a while, Steve Jobs was a “fruitarian” — as in, only ate fruit.

      Lifestyles of ultrarich

      Such extremes are common among the ultrarich, and particularly the Silicon Valley set, a crowd known for its obsession with making moonshot ideas into reality.

      The wealthy indulge in countless health trends of varying dubiousness, whether it’s getting IV drips to reduce hangovers, hyperbaric oxygen therapy, implanting devices in the body to monitor health and live longer, even injecting themselves with young blood (a treatment called parabiosis, which Johnson is receiving). This year alone, Johnson will reportedly spend at least $2 million on reducing his biological age.

      Society treats them as idols, geniuses whose savvy has vaulted them into the 0.0001 percent of the wealthiest people on Earth. It’s a small hop from there to believing they’d also be savvier than the rest of us about turning back the clock.

      Investing in de-aging

      Last year, according to a report from the news and market analysis site Longevity. Technology, more than $5 billion in investments poured into longevity-related companies worldwide, including from some big-name tech founders and investors. Many of these companies are aiming to prolong life by focusing on organ regeneration and gene editing.

      The buzzy life extension company Altos Labs, which researches biological reprogramming — a way to reset cells to pliable “pluripotent stem cells” — launched last year with a whopping $3 billion investment, and counts internet billionaire Yuri Milner and, reportedly, Amazon founder Jeff Bezos among its patrons. Bezos was also an investor in the anti-aging startup Unity Biotechnology.

      OpenAI founder Sam Altman, meanwhile, recently invested $180 million in Retro Biosciences, a company vying to add a decade to the human lifespan.

      Some of the most famous names in the death-defying sector are old: Calico Labs, a longevity-research subsidiary of Alphabet, was launched by then-Google CEO Larry Page in 2013.

      Tally Health, a new biotech company co-founded by Harvard scientist David Sinclair — who is something of a celebrity in the longevity community — boasts some Hollywood A-list investors: John Legend, Gwyneth Paltrow, Ashton Kutcher, Pedro Pascal, and Zac Efron.

      Possibility of de-aging

      “It’s not possible to reverse your age,” Stuart Jay Olshansky, an aging expert and professor of epidemiology and biostatistics at the University of Illinois Chicago, tells Vox. “There’s validity to some of the work that’s going on in epigenetics that may be telling us something about the rate of aging. It’s not yet telling us about longevity.”

      No two people age in the exact same way. Discrete from chronological age, “biological age” is the attempt to capture the often invisible difference through epigenetic gene expression, the state of someone’s organs, their immune system, and more.

      A 40-year-old with a history of heavy drinking and smoking, for example, may have a higher biological age than someone who never drinks or smokes. (In 2018, a Dutch man even complained that he ought to be able to change his legal age to match his biological age.)

      Johnson again

      Johnson, who made his hundreds of millions after selling a payments platform he developed to eBay in 2013, has become renowned not for what he’s invented, sold, or designed, as is the case for many other Silicon Valley entrepreneurs, but for the unimaginably strict lifestyle he leads.

      According to his website and the many interviews he has given, he exerts constant vigilance over the 78 organs of the human body, consistently tracking everything from BMI to brain white matter. Johnson is often described as the “most measured man in human history.”

      The point isn’t merely being healthy. It’s laser-precision optimization of his health.

      Johnson, for example, never eats pizza or drinks alcohol. It’s simply not a part of his algorithm. “I was just a slave to myself and my passions and my emotions and my next desire,” he said in an interview with Vice Motherboard. That doesn’t mean he never stumbles, but when he does, he calls it an “infraction,” as though he has committed a minor crime.

      Leaderboard

      Johnson tops the Rejuvenation Olympics leaderboard; he created the game along with Oliver Zolman — who leads Johnson’s team of 30-plus doctors and other health experts — and TruDiagnostic, an epigenetics lab based in Kentucky that provides the biological age test kits that participants in the Olympics must submit. The cheaper version costs $229. The more expensive one, at $499, provides more data on your results, including how habits like smoking or drinking alcohol have impacted a person’s aging speed.

      Ultramarathon

      It’s a contest that participants hope never ends — the most ultra of ultramarathons. The most dedicated members in the longevity community are, in essence, spending their lives obsessing over living. Says Lustgarten: “I plan on doing this for at least the next 70-plus years.”

      27 votes
    7. Tildes first Turing Test

      Welcome to Tildes first Turing Test. Rules: Anyone can ask a question in a top level thread if you want to see if you can tell man vs machine. I'll just start with @NaraVara, but feel free to post...

      Welcome to Tildes first Turing Test.

      Rules:

      1. Anyone can ask a question in a top level thread if you want to see if you can tell man vs machine. I'll just start with @NaraVara, but feel free to post up.
      2. Anyone can answer the question in 1.
        a. Respond with two responses. One human. One AI. Add [A] in front of the first response and [B] in front of the second response. Randomly assign which one is the human. Remember your choice and keep it secret.
        b. Your AI should try to pretend it is human. You can decline to respond to any question that exploits GPTs well published weaknesses, or exploits the fact that this is a small community. I suggest you pick a character from https://beta.character.ai/ that is similar to you, or get really good at Jailbreaking ChatGPT so that it will pretend to be a human with a personality similar to yours. Any response where the machine mentions ChatGPT or OpenAI disqualifies that thread, as Turing's machine should be specifically designed to pretend to be a human.
        c. Your human response should be a genuine response. Answer the question without tipping the scales either way. Don't say something impossible for the GPT model to say. Don't mimic ChatGPT. You can always decline to answer any question, just decline for ChatGPT as well.
      3. The original person who asked the question in 1 can now reply with a follow up question based on the responses in 2.
      4. Now the original person who provided the answers in 2, can now answer the new questions in 3.
      5. And so on. After 700 words of questions and answers, the person asking the questions in 1 and 3 must guess which is human and which is AI. 700 words is approximately 5 minutes of Q&A.
      6. If you are asking questions, no peaking if there is activity in another thread. I suggest we use expandable sections with the details tag to hide responses.

      @NaraVara, if this is clear, do you want to give this a go?

      Edit: minor formatting

      27 votes
    8. tildes.net is inaccessible over IPv6?

      When I try to access tildes.net over an IPv6-enabled network, the connection simply times out. Running ping -4 tildes.net responds but ping -6 tildes.net times out. I've tested this on multiple...

      When I try to access tildes.net over an IPv6-enabled network, the connection simply times out.

      Running ping -4 tildes.net responds but ping -6 tildes.net times out. I've tested this on multiple networks (residential and commercial) but it doesn't work on any.

      It looks like tildes.net has an AAAA record but the IP doesn't work.

      Can anyone reproduce?

      27 votes
    9. The West vs Asia: what drivers are taught about motorcycle brakes

      I've studied for motorcycle driving licenses in both my home country in Europe, and my work country in Asia. Something that really stood out to me was what each country said about braking. This...

      I've studied for motorcycle driving licenses in both my home country in Europe, and my work country in Asia. Something that really stood out to me was what each country said about braking. This wasn't just advice or anecdotes, it appeared on each formal theory test.

      Europe: Front brakes are the strongest, they are your go-to in an emergency. Use front brakes to stop, and rear brakes to slow gently.

      Asia: Rear brakes are the strongest, front brakes are deliberately weaker. This is because braking too hard on the front is very dangerous, you'll catapult yourself over the handlebars as the rear half of the bike still has momentum.

      Direct translation of exam question:

      Which of the following is wrong about using a motorcycle brake?

      A use both front And rear brakes

      B Front wheel brake first

      C rear wheel brake first

      D Do not use the front brake too early

      Answer B

      Look at the problem, to choose " wrong approach ", of course, is to choose " first use the front wheel brake ". The car is moving forward, then the use of front wheel brake, in the role of inertia, easy to cause rollover, we should pay attention to safety!

      I guess my overall question is, what are the underlying approaches to brake engineering here? Are either of them 'more correct' or is it a case of different priorities at play?

      26 votes
    10. Advice on setting up home ethernet (with unused cable already in the walls)

      I live in a townhouse (built in 2002, if it matters for context) it has ethernet cables in the walls, that have apparently never been hooked up (yay futureproofing) they’re cat 5e cables (I...

      I live in a townhouse (built in 2002, if it matters for context)

      it has ethernet cables in the walls, that have apparently never been hooked up (yay futureproofing)

      they’re cat 5e cables (I checked on the cable sleeve, because I wanted to make sure it would support gigabit ethernet and not just 100mbit)

      behind each wall plate, the ethernet cable is just coiled there, not terminated in a connector and not connected to anything (along with coax cable and telephone wires which are hooked up to the wall plate, but which I’m not currently using at all)

      the cables run to a wiring box in one of the bedroom closets. here they are also just hanging around, unterminated and unconnected to anything.

      I have a rough idea of how to DIY this, but I've never done it before - the extent of my networking knowledge is layer 2 and above. so I'm looking for any protips of the sort that you figure out after doing it several times but that aren't obvious the first time you do it.

      right now, my shopping list is:

      • a patch panel (I’m eyeing this one) which will terminate the cables in the wiring box
      • a punch down tool (maybe like this one) for…umm…punching the wires, it seems like?
      • a gigabit switch (I have a spare 8 port one that I’ll use, there's only 6 runs of cable total) to go in the wiring box
      • a wall plate (like this) for each of the 6 endpoints

      I really only care about 2 of the 6 - the motivation behind this project is that my modem & router are downstairs, my home office is upstairs, and currently I run powerline ethernet between them. powerline ethernet isn't great, but it sucks especially hard when something like a portable AC unit is running on the same circuit, and that's currently making the internet speeds in my home office suffer. but the 6 cable ends in the wiring box are unlabeled, and so it seems easier to just wire them all up rather than play guessing games to figure out which of them are the 2 I care about.

      the main thing I'm unsure about is the termination of the cables with the punch-down tool. I've crimped ethernet cables, years ago, and hated it, due to having clumsy hands and large, ungainly fingers. this doesn't seem quite as bad, but I'm still cautious about having to do all this in the fairly cramped closet space, and with limited ability for "do-overs" due to the finite amount of cable installed in the walls. I'm thinking I may buy a cheap ethernet cable and sacrifice it for some test runs of the punch-down tool.

      26 votes
    11. My indoor garden setup

      A few people have expressed interest in my indoor, semi-automated growing setup so here's the lowdown.. In a corner of my workshop is a cupboard with a footprint of 1.6x1.2m, 2.2m high. This is...

      A few people have expressed interest in my indoor, semi-automated growing setup so here's the lowdown.. In a corner of my workshop is a cupboard with a footprint of 1.6x1.2m, 2.2m high. This is insulated with a mixture of glasswool, foam board and expanding foam (depending on what I could install where), and lined with diamond pattern aluminumised mylar (the diamond pattern provides diffuse reflection to avoid hotspots).

      Inside the cupboard I have 750W of full-spectrum LED lighting, a 500W oil-filled radiator, and a small fan to keep air moving around. There's a vent which pulls air from the outside and a extractor fan which also vents outside. Being able to pull cool air from the outside (even in summer) is extremely useful as the lights can put out quite a lot of heat.

      My main growsystem is an Amazon low-pressure aeroponics system, and I've also got some airpots to do some soil-based growing in. Aero on the right, pots on the left. If you're not familiar with aeroponics, it's a system where the plants roots hang in open space and nutrient-rich water is sprayed or misted over them. High-pressure aero uses mist and low pressure uses sprayers. High pressure aero is currently one of the best known ways to maximise plant growth but low-pressure is pretty good too and you don't need anywhere near as much gear like pressure vessels and solenoid and so on. I just have an aquarium pump which drives the sprayers. In my experience aero is considerably more efficient than soil, non-soil media or other hydroponics - but on the other hand it's very twitchy. If your nutrient balance is off or your pH is wrong or worse, you pump fails - things can go wrong very quickly.

      The airpots are totally new to me. People say they're good but I have no idea. I have a mixture of compost, perlite and coco coir to go into them so we'll see how that works out. I'm going to use organic nutrients only on them, I have some seaweed derived stuff which should be good throughout the entire grow process.

      So that's the hardware, now on to the fun bit - the automation...

      On top of the cabinet is a board hosting a Raspberry Pi model A - these days I'd use a Zero W but they didn't exist when I built this. In it's mostly-bare state the board looks like this. Quick explanation - the red board is mains-rated relays which let me switch the connections above it on and off using the Pi. This is where the lights, fan and heater are wired to. The small junction block left of the relays is connected to mains.

      The block up and left of the Pi is 5V, which drives the Pi, the relay control electronics and provides power to the junction block on the right. There are various sensors wired in to that block and connected back to the Pi.

      Wired up on my bench for testing it looks like this, and in situ it looks like this (this was on a previous iteration of the cupboard but it's basically the same now). The orange cables on the left are lights, fan and heater. The black cables top are the sensors.

      Temperature is monitored using five DS18B20 sensors, which are cheap and reasonably accurate serial devices so you can run a whole bunch of them off a single pin on the pi. I monitor my water temperature, the temperature at the plant stem, at the wall, inside my workshop (but outside the cupboard) and outside temperature. The wall/stem temperature is the important one, that determines whether heating or cooling is engaged. I monitor the exterior and interior temperatures to know how effective my insulation is being. If water temperature gets too high I might add an agent which protects against microbial infections that like warmer water.

      I do have a DHT22 humidity sensor but they're hella flaky and it's currently not working. I will replace it at some point but past experience suggests humidity is high whatever I do.

      The Pi has a python script which runs every five minutes. It reads all the sensors, decides what (if anything) to do, then logs everything in a sqlite database. If it's 'night' (which is actually day outside, for temperature management reasons) it turns the lights off, if it's 'day' it turns them on. If it's cold it turns the heater on, if it's hot the fan. There's a bit of smartness where it actually aims for a midpoint of temperature because otherwise it's always aiming for highest temperature then immediately cooling again, then heating and so on - a stable temperature is better for the plants. At 'night' I tend to run the fan to drop the temperature: plants often like it cooler during darkness, get some fresh air in and attempt to lower the humidity a bit.

      There is a web interface which lets me see what's going on - current temperature and status, plus some lovely lovely charts (who doesn't love a nice chart?). I can also turn the lights out from here in case I need to go in an do some maintenance for anything. 750W of LED light is painfully bright, it's much more comfortable (and safer!) to turn them off while topping up reservoirs or changing water or whatever.

      It would be relatively trivial to add sensors for moisture or pH to add an auto-watering or auto-adjusting nutrient systems, but I haven't felt the need to do that yet.

      Happy to do my best to answer any questions anyone has.

      26 votes
    12. How do you test your home network security?

      As I'm exploring the idea of hosting my data at home (with offsite backups), I would like to better understand how to test my home network for security vulnerabilities. I have run basic Nmap scans...

      As I'm exploring the idea of hosting my data at home (with offsite backups), I would like to better understand how to test my home network for security vulnerabilities.

      I have run basic Nmap scans and confirmed that there are no open ports. I've confirmed that users have access to what they need but nothing else, and that guests using the network for web access don't have any sort of access to data. All data is encrypted so someone stealing the physical hardware shouldn't have access to the contents, either. But that's about as far as I know what to do.

      What else could and should I try? How do you pentest your home network?

      I feel I'm ok with my understanding of how to set things up so that everything is relatively secure. But I have very little idea how to actually test the setup.

      Edit: Added a sentence about encryption.

      25 votes
    13. I forgot how to have fun

      Like the title says, over the past couple of years, I think I slowly forgot how to have fun. I'm looking for any advice anyone might have (whether you've gone through the same process or not) on...

      Like the title says, over the past couple of years, I think I slowly forgot how to have fun. I'm looking for any advice anyone might have (whether you've gone through the same process or not) on how to have a bit more fun.

      The past 4 years have been transformational and formative for me. At 21 I decided to switch majors and move out from my parents' house to a more urban city. I mentally (depression) and financially struggled for the first 3 years, going broke in my second year of my second chance at undergrad at one point, eating bowls of rice. I identified my shortcomings (lack of achievements and disposable income) and worked on them. In the 3rd year I worked part-time while also taking a TA position with a full engineering course load. Last summer I completed an internship while also working as an independent contractor for a startup and kept the contractor position while being a full-time student up until this year. I signed a full-time offer at a big company this January and have one course left to fully graduate. I'm also correcting exams and tests on a part time basis for a professor. All this to say, I suddenly had a significant boost in income the last couple of months, and even more free time, whereas I was living on ~20k/year previously, with no free time.

      This doesn't mean I don't enjoy or appreciate any fun activity I partake in. When I do go out with my friends I'm having a lot of fun and I'm breathing in every moment. I'm not depressed (not anymore), but I find myself having a more neutral mood outside of hangouts. What I'm struggling with is initiative with regards to fun. What can I do to have fun? I live in a cramped-up studio which I plan on moving out of in spring, but for now I don't have space for a TV let's say. I don't have a gaming pc, because up until now I couldn't afford one. I have a ps4 with a couple of old games, though sometimes I struggle to play them because of a lingering feeling of guilt from using it as a medium of procrastination in my teens. People mention lifestyle creep that follows an income boost, but I think my financial situation in the past has some lingering effect on me that's inhibiting even a small healthy dose of that. It's hard for me to justify upgrading some of my stuff, because they still work. Or buying some items I've wanted, because I'm doing fine without them. The isolation in a studio and the now gone uncertainty that was during the pandemic before I signed a full-time offer also played a role here I think.

      So, having read through all that, I welcome any ideas or suggestions on how to spice my weekly life a bit more. I want to shake off the fight-or-flight phase that I was in. What are some things that you do that you think I could adopt to have a bit more fun by myself?

      25 votes
    14. A brief look at programming paradigms

      Overview If you've spent any significant amount of time programming, then you've probably heard discussions about imperative, functional, and declarative programming. These discussions are often...

      Overview

      If you've spent any significant amount of time programming, then you've probably heard discussions about imperative, functional, and declarative programming. These discussions are often mired in technical knowledge and require a fair amount of intuition when trying to grasp the differences between the examples placed in front of us. These different programming styles, usually called programming "paradigms", are discussed as if they exist within a vacuum with complete and total isolation from one another. This only furthers the confusion and frustration among newer programmers especially, which runs counter to the goal of instructing them.

      In this post I'll be taking a look at the oft-neglected intersections where these paradigms meet with the hope that the differences between them will be better understood by reframing our existing knowledge of programming basics.

      Note: I'll be using PHP for my code examples and will try to provide comments when necessary to point out language quirks.


      Understanding Fundamentals is Imperative

      Let's start by first reviewing the most basic, fundamental programming paradigm: imperative programming. The term is a bit strange, but the important thing to understand about it is that imperative programming refers to writing software as a series of instructions where you tell the computer how to solve a specific task. For example, if we need to add together a bunch of numbers inside of an array, we might write code that looks like this:

      $numbers = [ 8, 31, 5, 4, 20, 78, 52, 18, 96, 27 ];
      $sum = 0;
      foreach($numbers as $number) {
          $sum += $number;
      }
      

      This is a pretty typical example that you've probably encountered in some form or another at some point in your programming studies or career--iterate over an array one element at a time from the first element to the last and add the current element to some accumulating variable that starts at 0. The kind of loop you use may differ, but the general format of the solution looks the same. This is very similar to the way the computer itself performs the task, so the code here is just a relatively human-friendly version of the actual steps the computer performs. This is the essence of imperative programming, the basic building blocks of everything you learn early on.


      Abstract Concepts

      As the software we write gets larger and more complex, we then tend to rely on "abstractions" to simplify our code and make it easier to understand, reuse, and maintain. For example, if we've written a program that adds arrays of numbers together, then we probably aren't doing that in only one place. Maybe we've written a tool that generates reports on large data sets, such as calculating the total number of sales for a particular quarter, gross profit, net profit, remaining inventory, and any number of other important business-related metrics. Summing numbers could be so common that you use it in 30 different places, so to avoid having to maintain 30 separate instances of our number adding code from above, we define a function:

      function sum($numbers) {
          $sum = 0;
          foreach($numbers as $number) {
              $sum += $number;
          }
      
          return $sum;
      }
      

      We do this so frequently in our code that it becomes second nature. We attach so many names and terms to it, too: DRY, abstraction layers, code reuse, separation of concerns, etc. But one thing experienced programmers learn is to write their functions and object and interface methods in such a way that anyone who uses them doesn't need to care about the underlying implementation details, and instead only need to worry about the method name, expected arguments (if any), expected return type (if any), and expected behavior. In other words, they don't need to understand how the function or method completes the intended action, they only need to declare what action they want performed.


      A Declaration of Understanding

      Anyone who has looked into the concept of the declarative programming paradigm should find those last words familiar: "they don't need to understand how the function or method completes the intended action, they only need to declare what action they want performed". This is the oft-touted explanation of what declarative programming is, the difference between detailing "how" and declaring "what", and I believe that it's this great similarity that causes imperative and declarative programming to become heavily entwined in a programmer's mind and makes it difficult to understand. Take this common example that authors tend to use to try to detail the difference between declarative and imperative programming:

      // imperative
      function sum($numbers) {
          $sum = 0;
          foreach($numbers as $number) {
              $sum += 0;
          }
      
          return $sum;
      }
      
      // declarative
      function sum($numbers) {
          return array_reduce($numbers, fn($x, $y) => $x + $y, 0);
      }
      

      The authors will go on to state that in the imperative example, you tell the computer how to sum the numbers, whereas in the declarative example you don't tell the computer how to do it since you don't know anything about the reduce implementation, but intuitively it still feels as if you're telling the computer how to perform its task--you're still defining a function and deciding what its underlying implementation details are, i.e. the steps it needs to take to perform the task, even if its details are abstracted away behind function or method calls that could have varying implementation details of their own. So how the hell is this any different from defining functions like we do in imperative programming?

      The answer is simple: it isn't. We've used so many names and terms to describe functions and methods in our ordinary imperative programming, but the truth is that a well-defined function or method serves as a declarative interface to an imperative implementation. Put differently, declarative programming is defining and utilizing simple interfaces that describe what you want accomplished while the underlying implementation details are inevitably written using imperative code.


      Functional Differences

      Now we can finally tackle one of the biggest trends in programming right now: the functional programming paradigm. But to understand this paradigm, it's important to understand what a "function" is... from a mathematical perspective.

      Yes, I know, math tends to be a enthusiasm sink for many, but don't worry, we're not actually going to be doing math. We only need to understand how math treats functions. Specifically, math functions usually look something like f(x) = {insert expression here}, which is loosely equivalent to the following code:

      function f($x) {
          return {insert expression here};
      }
      

      The important thing to note about functions in math is that you can run them a theoretically infinite number of times on the same input x and still get the same return result. Unlike in a lot of the programs we can write, math functions don't produce side effects. Files aren't written to or destroyed, database entries aren't deleted, some global counter somewhere isn't incremented, and your x doesn't suddenly change. The idea behind functional programming is to embody some of that nature of mathematical functions because they're predictable and always reproducible, and therefore simple to test as well. For example, take the following:

      // not functional
      function increment(&$x) { // pass by reference--$x will be modified outside of this function!
          $x++;
      }
      
      $x = 1;
      increment($x);
      increment($x);
      increment($x);
      
      // functional
      function increment($x) { // pass by value--$x will NOT be modified outside of this function!
          return $x + 1;
      }
      
      $x = 1;
      $y = increment($x);
      $y = increment($x);
      $y = increment($x);
      

      Note that the first example will change the value of $x on each call, meaning each subsequent call of increment($x) produces a different result. Meanwhile the second example doesn't change $x and so the return value of increment($x) is always the same. This may seem like a silly example, but in larger, more complex software this can be significant. So now that we have an understanding of functions from a mathematical perspective, we have everything we need to actually understand what functional programming is.

      Functional programming is a subset of declarative programming. Just like in declarative programming, you use simple interfaces to tell the program what you want to do rather than how to do it. But unlike declarative programming as a whole, functional programming imposes some additional restrictions on what you should and shouldn't do:

      • You should encapsulate behavior in pure functions, which always give a consistent output for a given input and don't have side effects.

      • You should write functions in such a way that you can compose them together, allowing you to combine and chain behavior to produce new functions or use the output of one as the input for another.

      • You should avoid side effects as much as possible.

      • You should avoid mutable state (e.g. changing the values in a variable).

      • You should avoid sharing state between components.

      These restrictions would require an entirely separate post on their own to properly cover and have been covered so many times in so many ways by others elsewhere that it would be superfluous for me to try to add anything more. It's important to note, however, that these restrictions are imposed because they provide some key benefits. By avoiding side effects and by avoiding mutable and shared states, the code you write becomes more predictable and tracing the behavior of an algorithm becomes far simpler. By writing pure, composable functions, you create reusable building blocks that can be strung together in virtually any configuration with predictable results. This makes writing, reading, maintaining, and debugging code easier and less error-prone.

      That said, I feel that it's important to note that in the real world when writing practical software that users can interact with, it's simply not possible to completely avoid side effects or mutable state. The very act of creating and updating database entries is itself an act of mutating state, which runs contrary to functional programming principles and is essential for many important software projects. But even if you can't adhere strictly to functional programming principles, it's possible to benefit significantly from being aware of them and integrating them into your own software development strategies.

      Let's consider a more practical example to illustrate this. Imagine that you've built a social media website and you're trying to test a push notification system that will be triggered when your user receives a new message. Now imagine your code and unit tests look something like this:

      function sendNotification(&$message) { // pass by reference--$message will be modified outside of this function!
          $notification_system = new NotificationSystem();
          if(!$message['sent_push_notification']) {
              $notification_system->sendPushNotification($message);
              $message['sent_push_notification'] = true;
          }
      }
      
      function testSendNotification() {
          $message = [
              'user_id'=>'{some_id}',
              'contents'=>'Hi!',
              'sent_push_notification'=>false
          ];
      
          sendNotification($message);
          sendNotification($message);
      }
      

      At a quick glance you probably wouldn't be aware of why the second message didn't send, but the fact that our sendNotification() function mutates the state of the data provided to it is the culprit. This is code that doesn't adhere to functional programming principles since the data provided to it is mutated. As a result, running the function multiple times on the same variable doesn't result in the same behavior as the first call. If we wanted to work around this without adhering to functional programming principles then we would need to manually set $message['sent_push_notification'] = false; between function calls, which makes our unit tests potentially more error-prone. Alternatively we can make a simple change to adhere better to those functional principles:

      function sendNotification($message) { // pass by value--$message will NOT be modified outside of this function!
          $notification_system = new NotificationSystem();
          if(!$message['sent_push_notification']) {
              $notification_system->sendPushNotification($message);
              $message['sent_push_notification'] = true;
          }
      
          return $message;
      }
      
      function testSendNotification() {
          $message = [
              'user_id'=>'{some_id}',
              'contents'=>'Hi!',
              'sent_push_notification'=>false
          ];
      
          sendNotification($message);
          sendNotification($message);
      }
      

      Now both notifications will be sent out, which is what we would intuitively expect. You should also notice that the above is also a blend of imperative, declarative, and functional programming. Our function definitions have imperative code, our sendNotification() function adheres to the functional programming principle of avoiding mutable state (well, mostly), and our NotificationSystem object provides a declarative interface for sending a push notification for a message.


      Final Thoughts

      By viewing these three paradigms not as completely separate concepts but as layers on top of one another, where functional programming is a type of declarative programming which is implemented using imperative programming, we can stop being confused by their similarities and instead find clarification in them. By understanding that imperative programming is the backbone of everything, that declarative programming is just simplifying that backbone with simple interfaces, and that functional programming is simply adding some additional guidelines and restrictions to the way you write code to make it more consistent, reusable, and predictable, we can start to see that we're not choosing one programming paradigm over another, but instead choosing how much consideration we place on the design of the programs we write. Except in purely functional languages, functional programming isn't some alien concept distinct from imperative or declarative programming, but is instead a natural evolution of the two.

      There are a lot of details I've glossed over here. Each of these programming paradigms is far too detailed to include a proper analysis in an already lengthy post that tries to separate them from each other and clarify their differences. Blog articles exist in a thousand different places that can do each one far more justice than I can, and programming languages exist that completely cut imperative programming out of the picture. But for your average programmer slinging JavaScript, C, Rust, PHP, or what have you, I hope that this serves as a crucial starting pointing to understanding just what in the hell these functional programming enthusiasts are on about.

      25 votes
    15. Code Quality Tip: Cyclomatic complexity in depth.

      Preface Recently I briefly touched on the subject of cyclomatic complexity. This is an important concept for any programmer to understand and think about as they write their code. In order to...

      Preface

      Recently I briefly touched on the subject of cyclomatic complexity. This is an important concept for any programmer to understand and think about as they write their code. In order to provide a more solid understanding of the subject, however, I feel that I need to address the topic more thoroughly with a more practical example.


      What is cyclomatic complexity?

      The concept of "cyclomatic complexity" is simple: the more conditional branching and looping in your code, the more complex--and therefore the more difficult to maintain--that code is. We can visualize this complexity by drawing a diagram that illustrates the flow of logic in our program. For example, let's take the following toy example of a user login attempt:

      <?php
      
      $login_data = getLoginCredentialsFromInput();
      
      $login_succeeded = false;
      $error = '';
      if(usernameExists($login_data['username'])) {
          $user = getUser($login_data['username']);
          
          if(!isDeleted($user)) {
              if(!isBanned($user)) {
                  if(!loginRateLimitReached($user)) {
                      if(passwordMatches($user, $login_data['password'])) {
                          loginUser($user);
                          $login_succeeded = true;
                      } else {
                          $error = getBadPasswordError();
                          logBadLoginAttempt();
                      }
                  } else {
                      $error = getLoginRateLimitError($user);
                  }
              } else {
                  $error = getUserBannedError($user);
              }
          } else {
              $error = getUserDeletedError($user);
          }
      } else {
          $error = getBadUsernameError($login_data['username']);
      }
      
      if($login_succeeded) {
          sendSuccessResponse();
      } else {
          sendErrorResponse($error);
      }
      
      ?>
      

      A diagram for this logic might look something like this:

      +-----------------+
      |                 |
      |  Program Start  |
      |                 |
      +--------+--------+
               |
               |
               v
      +--------+--------+    +-----------------+
      |                 |    |                 |
      |    Username     +--->+    Set Error    +--+
      |    Exists?      | No |                 |  |
      |                 |    +-----------------+  |
      +--------+--------+                         |
               |                                  |
           Yes |                                  |
               v                                  |
      +--------+--------+    +-----------------+  |
      |                 |    |                 |  |
      |  User Deleted?  +--->+    Set Error    +->+
      |                 | Yes|                 |  |
      +--------+--------+    +-----------------+  |
               |                                  |
            No |                                  |
               v                                  |
      +--------+--------+    +-----------------+  |
      |                 |    |                 |  |
      |  User Banned?   +--->+    Set Error    +->+
      |                 | Yes|                 |  |
      +--------+--------+    +-----------------+  |
               |                                  |
            No |                                  |
               v                                  |
      +--------+--------+    +-----------------+  |
      |                 |    |                 |  |
      |   Login Rate    +--->+    Set Error    +->+
      | Limit Reached?  | Yes|                 |  |
      |                 |    +-----------------+  |
      +--------+--------+                         |
               |                                  |
            No |                                  |
               v                                  |
      +--------+--------+    +-----------------+  |
      |                 |    |                 |  |
      |Password Matches?+--->+    Set Error    +->+
      |                 | No |                 |  |
      +--------+--------+    +-----------------+  |
               |                                  |
           Yes |                                  |
               v                                  |
      +--------+--------+    +----------+         |
      |                 |    |          |         |
      |   Login User    +--->+ Converge +<--------+
      |                 |    |          |
      +-----------------+    +---+------+
                                 |
                                 |
               +-----------------+
               |
               v
      +--------+--------+
      |                 |
      |   Succeeded?    +-------------+
      |                 | No          |
      +--------+--------+             |
               |                      |
           Yes |                      |
               v                      v
      +--------+--------+    +--------+--------+
      |                 |    |                 |
      |  Send Success   |    |   Send Error    |
      |    Message      |    |    Message      |
      |                 |    |                 |
      +-----------------+    +-----------------+
      

      It's important to note that between nodes in this directed graph, you can find certain enclosed regions being formed. Specifically, each conditional branch that converges back into the main line of execution generates an additional region. The number of these distinct enclosed regions is directly proportional to the level of cyclomatic complexity of the system--that is, more regions means more complicated code.


      Clocking out early.

      There's an important piece of information I noted when describing the above example:

      . . . each conditional branch that converges back into the main line of execution generates an additional region.

      The above example is made complex largely due to an attempt to create a single exit point at the end of the program logic, causing these conditional branches to converge and thus generate the additional enclosed regions within our diagram.

      But what if we stopped trying to converge back into the main line of execution? What if, instead, we decided to interrupt the program execution as soon as we encountered an error? Our code might look something like this:

      <?php
      
      $login_data = getLoginCredentialsFromInput();
      
      if(!usernameExists($login_data['username'])) {
          sendErrorResponse(getBadUsernameError($login_data['username']));
          return;
      }
      
      $user = getUser($login_data['username']);
      if(isDeleted($user)) {
          sendErrorResponse(getUserDeletedError($user));
          return;
      }
      
      if(isBanned($user)) {
          sendErrorResponse(getUserBannedError($user));
          return;
      }
      
      if(loginRateLimitReached($user)) {
          logBadLoginAttempt($user);
          sendErrorResponse(getLoginRateLimitError($user));
          return;
      }
      
      if(!passwordMatches($user, $login_data['password'])) {
          logBadLoginAttempt($user);
          sendErrorResponse(getBadPasswordError());
          return;
      }
      
      loginUser($user);
      sendSuccessResponse();
      
      ?>
      

      Before we've even constructed a diagram for this logic, we can already see just how much simpler this logic is. We don't need to traverse a tree of if statements to determine which error message has priority to be sent out, we don't need to attempt to follow indentation levels, and our behavior on success is right at the very end and at the lowest level of indentation, where it's easily and obviously located at a glance.

      Now, however, let's verify this reduction in complexity by examining the associated diagram:

      +-----------------+
      |                 |
      |  Program Start  |
      |                 |
      +--------+--------+
               |
               |
               v
      +--------+--------+    +-----------------+
      |                 |    |                 |
      |    Username     +--->+   Send Error    |
      |    Exists?      | No |    Message      |
      |                 |    |                 |
      +--------+--------+    +-----------------+
               |
           Yes |
               v
      +--------+--------+    +-----------------+
      |                 |    |                 |
      |  User Deleted?  +--->+   Send Error    |
      |                 | Yes|    Message      |
      +--------+--------+    |                 |
               |             +-----------------+
            No |
               v
      +--------+--------+    +-----------------+
      |                 |    |                 |
      |  User Banned?   +--->+   Send Error    |
      |                 | Yes|    Message      |
      +--------+--------+    |                 |
               |             +-----------------+
            No |
               v
      +--------+--------+    +-----------------+
      |                 |    |                 |
      |   Login Rate    +--->+   Send Error    |
      | Limit Reached?  | Yes|    Message      |
      |                 |    |                 |
      +--------+--------+    +-----------------+
               |
            No |
               v
      +--------+--------+    +-----------------+
      |                 |    |                 |
      |Password Matches?+--->+   Send Error    |
      |                 | No |    Message      |
      +--------+--------+    |                 |
               |             +-----------------+
           Yes |
               v
      +--------+--------+
      |                 |
      |   Login User    |
      |                 |
      +--------+--------+
               |
               |
               v
      +--------+--------+
      |                 |
      |  Send Success   |
      |    Message      |
      |                 |
      +-----------------+
      

      Something should immediately stand out here: there are no enclosed regions in this diagram! Furthermore, even our new diagram is much simpler to follow than the old one was.


      Reality is rarely simple.

      The above is a really forgiving example. It has no loops, and loops are going to create enclosed regions that can't be broken apart so easily; it has no conditional branches that are so tightly coupled with the main path of execution that they can't be broken up; and the scope of functionality and side effects are minimal. Sometimes you can't break those regions up. So what do we do when we inevitably encounter these cases?

      High cyclomatic complexity in your program as a whole is inevitable for sufficiently large projects, especially in a production environment, and your efforts to reduce it can only go so far. In fact, I don't recommend trying to remove all or even most instances of cyclomatic complexity at all--instead, you should just be keeping the concept in mind to determine whether or not a function, method, class, module, or other component of your system is accumulating technical debt and therefore in need of refactoring.

      At this point, astute readers might ask, "How does refactoring help if the cyclomatic complexity doesn't actually go away?", and this is a valid concern. The answer to that is simple, however: we're hiding complexity behind abstractions.

      To test this, let's forget about cyclomatic complexity for a moment and instead focus on simplifying the refactored version of our toy example using abstraction:

      <?php
      
      function handleLoginAttempt($login_data) {
          if(!usernameExists($login_data['username'])) {
              sendErrorResponse(getBadUsernameError($login_data['username']));
              return;
          }
      
          $user = getUser($login_data['username']);
          if(isDeleted($user)) {
              sendErrorResponse(getUserDeletedError($user));
              return;
          }
      
          if(isBanned($user)) {
              sendErrorResponse(getUserBannedError($user));
              return;
          }
      
          if(loginRateLimitReached($user)) {
              logBadLoginAttempt($user);
              sendErrorResponse(getLoginRateLimitError($user));
              return;
          }
      
          if(!passwordMatches($user, $login_data['password'])) {
              logBadLoginAttempt($user);
              sendErrorResponse(getBadPasswordError());
              return;
          }
      
          loginUser($user);
          sendSuccessResponse();
      }
      
      $login_data = getLoginCredentialsFromInput();
      
      handleLoginAttempt($login_data);
      
      ?>
      

      The code above is functionally identical to our refactored example from earlier, but has an additional abstraction via a function. Now we can diagram this higher-level abstraction as follows:

      +-----------------+
      |                 |
      |  Program Start  |
      |                 |
      +--------+--------+
               |
               |
               v
      +--------+--------+
      |                 |
      |  Attempt Login  |
      |                 |
      +-----------------+
      

      This is, of course, a pretty extreme example, but this is how we handle thinking about complex program logic. We abstract it down to the barest basics so that we can visualize, in its simplest form, what the program is supposed to do. We don't actually care about the implementation unless we're digging into that specific part of the system, because otherwise we would be so bogged down by the details that we wouldn't be able to reason about what our program is supposed to do.

      Likewise, we can use these abstractions to hide away the cyclomatic complexity underlying different components of our software. This keeps everything clean and clutter-free in our head. And the more we do to keep our smaller components simple and easy to think about, the easier the larger components are to deal with, no matter how much cyclomatic complexity all of those components share as a collective.


      Final Thoughts

      Cyclomatic complexity isn't a bad thing to have in your code. The concept itself is only intended to be used as one of many tools to assess when your code is accumulating too much technical debt. It's a warning sign that you may need to change something, nothing more. But it's an incredibly useful tool to have available to you and you should get comfortable using it.

      As a general rule of thumb, you can usually just take a glance at your code and assess whether or not there's too much cyclomatic complexity in a component by looking for either of the following:

      • Too many loops and/or conditional statements nested within each other, i.e. you have a lot of indentation.
      • Many loops in the same function/method.

      It's not a perfect rule of thumb, but it's useful for at least 90% of your development needs, and there will inevitably be cases where you will prefer to accept some greater cyclomatic complexity because there is some benefit that makes it a better trade-off. Making that judgment is up to you as a developer.

      As always, I'm more than willing to listen to feedback and answer any questions!

      25 votes
    16. Eye glasses, especially myopia - what's real what's myth?

      Kid's vision just keeps getting worse: it's -3.0 now in one eye. The rate at which I have to get the kid's vision tested and new glasses (plural because kid) is alarming. My husband and I both...

      Kid's vision just keeps getting worse: it's -3.0 now in one eye. The rate at which I have to get the kid's vision tested and new glasses (plural because kid) is alarming.

      My husband and I both have 20/20, as did both our parents before they got old people eye stuff....so I'm really new to the world of prescription glasses.

      What's real and what are just old wives tales? Go outside more, get sun, limit screen time, don't read in the dark, these are kind of obvious but are they scientifically backed? I take super terrible care of my eyes and eyeballs are nearly touching the screens all day and I still have 20/20.....

      Eye drops that fix your eyes? Omega 3 do anything or just in general a good nutrient for everyone?

      Myopia control lenses (Miyosmart) -- legit or marketing hype? They seem to be a bunch of money and the brochures / site reads a bit like marketing nonsense...... How does a piece of lens fix eyeballs?

      Did you get Lasik? Is it still the thing to do for correction, and has it gotten better? Could my kid reach a point where even Lasik can't help?

      When did you get glasses and did the uh, progression (?) slow down or get better with age?

      Edit: what about blue light lenses?

      24 votes
    17. Which web browser do you use?

      Most of the world seems to be settled around Chrome and Safari these days. I remember using Firefox a long time ago myself but then everyone started switching to Chrome and that also turned out to...

      Most of the world seems to be settled around Chrome and Safari these days. I remember using Firefox a long time ago myself but then everyone started switching to Chrome and that also turned out to be a natural path of least resistance for web developers like me who had to test web apps in local environment.

      This switch happened in circa 2015-16 if I recall correctly, many other browsers have evolved since then and people are looking at alternatives. The Android Kiwi browser, for example, is a great alternative for power users on mobile who need plugins but Chrome won't allow that. Other alternatives have evolved too like Brendan Eich's Brave browser which seems to be promising. Anyone here tried that yet?

      I have half a mind to go back to Firefox but I recently learned about how Mozilla Corp is also funded by Google and that turned me off. Wouldn't you rather want to deal with the Devil directly instead of the Devil's assistant or sidekick!

      And then there are also those who use Garibaldi, Midori, etc. but I can't go that purist way. I'm way too dependent on the digital way of life and sites like amazon and flipkart won't work in those browsers. What do you think should be the right path ahead from here?

      24 votes
    18. Lets take a personality test!

      One of my favorite topics in Psychology is personality and there happens to be a very good Five Factor test that is free to the public domain with all 3,000+ items available for download. Some...

      One of my favorite topics in Psychology is personality and there happens to be a very good Five Factor test that is free to the public domain with all 3,000+ items available for download. Some notes about the IPIP NEO-PI:

      Purpose of this On-Line Inventory

      • The primary purpose of this on line inventory is to educate the public about the five factor model of personality.
      • More specifically, the report explains the likely consequences of one's standing on five broad personality domains.
      • These broad domains cover normal differences in personality that should be obvious to people who know you well.
      • Secondarily, this inventory estimates your standing on the 5 broad domains and 30 subdomains of personality.
      • The inventory does not reveal hidden, secret information about you nor does it assess serious psychological disorders.
      • The report is designed to be objective, not pleasing or flattering.
      • Measurement error, misunderstandings, carelessness, and mischievous responding can invalidate the report.
      • If knowledgeable acquaintances disagree with the test results, then the results are wrong.

      Link to the questionnaire:
      https://www.personal.psu.edu/~j5j/IPIP/

      More about the International Personality Item Pool:

      https://ipip.ori.org/

      24 votes
    19. A layperson's introduction to Homebrewing

      Whats this about? @wanda-seldon started a thread over at ~science in hopes of generating more user created content. My plan is to post some introductions myself, in fields like mechanical...

      Whats this about?

      @wanda-seldon started a thread over at ~science in hopes of generating more user created content. My plan is to post some introductions myself, in fields like mechanical engineering and automation (is anyone interested in it anyways?). But until I feel like I would do it proper, I figured I'd try something similar with a much lower barrier of entry. I'll write about some hobbies of mine, in a way that goes more indepth about the process, but still shallow enough to function as an introduction. And if folks are interested in more in-depth stuff or pointers on where to go, I'll take care of that.

      So on todays topic, homebrewing. What is it, why would you bother, and what's actually involved in it?

      What's Homebrewing?

      Put simply, homebrewing is the art of making beer yourself. It's not really that complicated to be honest.

      Why Homebrewing?

      • It's (relatively) cheap.

      If you got a few basic kitchen items (pots, ladle, cups, etc), you already have most items needed for brewing a small quantity. A few additional tools will be required, like a food grade plastic container, a water lock, etc. but if you treat them proper they can be used for years after years. Ingredient cost is neglible.

      • Quality.

      A common reaction many have with homebrewed beer is how thick and rich in flavour it is, compared to your average supermarket beer. Especially if your experience is with light beers (in which case I believe Monty Python said it best, it's fucking close to water). It's like comparing that sad pie you can buy in the cooler section, compared to something fresh out of the oven with the sweetest fruits and crispiest crust.

      • Easy to learn, hard to master.

      If your goal is to make a good beer, you only need two "skills". Good working hygiene and patience. Beyond that, any complication you want to add is up to you. You can start with a simple ale and work your way towards horribly complicated recipes that seem more like a chemistry exam than a hobby.

      Whats actually involved in it?

      So what do you actually do? I'll keep it short, even though I could write a book if I wanted to cover everything. Brewing is made out of three phases. The actual brewing, the fermenting and the bottling.

      Brewing

      You mix malts (and/or barley, wheat, oats, etc) with water, which you will draw a wort from. The wort will be the basis of your beer. A wort is a bit like a tea from a tea mix in this sense. Also it's sickly sweet (so taste test on your own risk). The sugar from the malt will be what is turned into alcohol during fermentation. In a similar way, that we use fruit sugar for wines/ciders or honey for mead.

      Fun fact: In Sweden and Norway, elks drunk on rotten (fermented) fruit they eat from the ground is a rare but real phenomena.

      Once you have a wort, the wort is boiled up and hops are supplied. Usually hops are divided in two categories. Bitter hops and aroma hops. Though that has more to do with when you add hops in the brewing process. The hops add flavour primarily from the oils (which give the fresh and fruity taste) and the resin (which gives the bitter taste). The resin takes a certain amount of boiling time to properly release, so hops added early in the process will contribute to bitterness.

      The liquid is then cooled and stored in a container with a bit of yeast. That marks the start of the fermentation period.

      Fermentation

      Fermentation is fairly straight forward. Yeast loves sugar. And will keep eating it until most is gone. Alcohol, is a byproduct of this process.

      Bottling

      Once fermentation is (nearly) done, the beer is transferred into bottles. After a few days of waiting, a pressure should have built inside your bottles which will create the nice bubbliness we know from beers. Toss on a label if you wan't to brag and want to make sure that graphical designer education was not for naught.

      Swell, how do I get into it?

      How do you get into it? Technically speaking, you could start with no-mash brewing. Though I would recommend against it, as it takes out the charm of actually brewing, since you just add water and call it a day. Alternatively, there are several good sources on this. The american homebrewers association for instance have a good quick guide for some instructions. Though if you wan't to go serious about it, I recommend to read up on the specific processes, and what influences them.

      Afterwords

      Does it sound interesting? Bring a buddy, and make a day of it. Make your own labels too if you wan't to brag to friends and family. If you have questions, I will answer anything. Need help setting up or want a plan, I can help with that too.

      Edit: Would recommend reading @piratepants comment in the comment section. It expands a lot of the things mentioned here, and goes a lot more into the actual processes while brewing. If you got this far, it's worth continueing.

      24 votes
    20. May 2024 Backlog Burner: Week 1 Discussion

      The blaze has officially ignited! The May 2024 Backlog Burner is officially live. Use this topic to post about the games that you play. Etiquette: It is fine to make multiple top-level posts...

      The blaze has officially ignited!

      The May 2024 Backlog Burner is officially live. Use this topic to post about the games that you play.

      Etiquette:

      • It is fine to make multiple top-level posts throughout the week.

      • It is also fine to respond to your own posts.

      • If you are playing Backlog Bingo, you can share your table either by markdown or through screenshots.

      Gameplay guidelines:

      • Goals for this event (if any) are entirely individual and self-determined.

      • You do NOT need to finish games unless you want to. The point is to try out games and have fun, not force ourselves to play things we're not interested in.


      Backlog Bingo: It's back and better than ever!

      Backlog Bingo is a completely optional way of participating in the Backlog Burner. You can generate a random bingo card with different gaming categories such as Has a fishing minigame or Your friend loves it. You then play a game that meets a given category and fill in that square.

      A conventional bingo win happens when you have filled in a full row, column, or diagonal. If you complete a full bingo with time to spare, you can go for another one on the same card. You can also choose to play with the "blackout" win condition if you're feeling extra adventurous, which means that you need to fill every square on the board to win.

      In order to help out with this, our amazing @Wes has singlehandedly made an open-source Backlog Bingo web app from scratch! (and here's the GitHub repo, for those interested).

      The site will:

      • Generate a random bingo card for you
      • Save your bingo card state as you enter games
      • Export your bingo card to markdown for easy copy/pasting into the discussion thread

      But wait, there's more!

      • It has both Standard and Golf rulesets, as well as completely custom rules
      • It allows for resizing the bingo card, so you can play a 3x3 or a 7x7 if you want
      • You can choose which categories you want to allow on your card
      • The categories now have groupings which limit similar ones from appearing on the same cards

      Wes could have stopped there, but he didn't:

      • The site is private by design; all user data is kept in local storage and does not touch the server
      • The site can import custom JSON files so that people can make their own custom categories
      • Because of this, people can use the tool for other events: a yearly reading challenge; an anime bingo month, etc.

      What's that? You thought Wes was done? Nope. He kept going:

      • It supports "dynamic" entries which allow for randomization within specific categories (e.g. "a game you've had for more than RANDOM[2,7] years")
      • It has both light and dark modes
      • It looks great in screenshots, so if you hate markdown tables you can post pictures of your card instead
      • It has some other fun surprises as well

      We've also updated the category list for this year to hopefully make it even better than the last. So, try it out! Generate a card and get gaming!

      Let's burn through these backlogs!


      Backlog Bingo FAQ

      Important: All data for your Backlog Bingo card is stored on your device, not the server. Clearing your browser data will irrecoverably delete your card.

      Is the Backlog Bingo site privacy-friendly?

      Yes! The site is coded by our very own @Wes who made it private by design. It is open source, all data is stored client-side, and the only information entered is the names of games. It does not require an account nor link to your Tildes username.

      My browser deletes data on exit. How do I save my card between sessions?

      You need to whitelist data from wescook.ca in your browser. PLEASE test this before committing to a card. Once a card is deleted it cannot be recovered.

      What is the difference between the "Standard" and "Golf" modes?

      In Standard Mode, each square on the bingo card corresponds with one single game. Duplicate games cannot be entered into different squares. A winning card would have a row of five different games that each filled in one square.

      In Golf Mode, duplicates are not only allowed -- they are encouraged! The purpose of Golf mode is to try to find a single game that will fill multiple categories at the same time. For example: Stardew Valley might fulfill You got it on sale, A solo-dev project, and Has romanceable characters all at the same time. A winning card would have all twenty five squares filled, but possibly only six or seven different games.

      What is the star space in the middle?

      That is the "wildcard" or "free space."

      In Standard Mode, there are no requirements to fill it. You can choose any game you want! Anything goes!

      In Golf Mode, it does not need to be filled. Because Golf is all about stacking up categories on a single game, any game used in Golf would fill it automatically, meaning it has no real function. As such, the square will be pre-filled for you if you play in Golf mode.

      Can I make my own custom categories?

      Yes! The Backlog Bingo site generates its categories from a JSON file. We prepared a default one for the event that everyone can use, but you are welcome to create your own JSON file with whatever categories you want and use that instead!

      If you are interested in doing this, you can find documentation in the wiki and use an example JSON category file. You can also ask for help in the topic!

      Can I use the Backlog Bingo site for something other than games?

      Yes again! Because it will accept custom categories, you can use it for books, anime, movies, recipes -- anything!

      If you are interested in doing this, you can find documentation in the wiki and use an example JSON category file. You can also ask for help in the topic!


      Backlog Burner FAQ

      What exactly is the Backlog Burner?

      Your "backlog" is all those games you've been meaning to play or get around to, but never have yet. This event is an attempt to get us to collectively dig into that treasure trove of experiences, scratch some long-standing itches, and knock a few titles off our to-play lists.

      How do I participate?

      Once the event starts on May 1st:

      • Choose some games from your backlog and play them.
      • Then tell us about your experiences in the discussion thread for the week.

      That's it!

      Optionally: you can play Backlog Bingo which is a fun way of cutting down the choices you have to make and playing games you might not have normally selected on your own.

      Is Backlog Bingo a requirement to participate?

      No! You can choose or play games however you like.

      Do I need to finish the games that I play?

      Nope! Not at all.

      There aren't really any requirements for the event so much as this is an incentive to get us to play games we've been avoiding starting up, for whatever reason. Play as much or as little as you like of a given game.

      Try out dozens for ten minutes each or dive into one for 40 hours. There's no wrong way to participate!

      What's the timeline?

      The event begins on May 1st and runs through May 31st. I will post an update thread weekly, each Wednesday.

      The next Backlog Burner event will be in November 2024.

      Can I make multiple posts in the same topic?

      Yes! Each discussion thread stays live for a full week, so feel free to make multiple comments in the topic as you play different games. This isn't considered noise -- it's considered valuable participation in the event!

      Do I need to sign up?

      No. You don't have to do anything to officially join or participate in the event other than post in these threads! Participate in whatever way works for you.

      Do I need to wait until May to get started?

      Technically yes but I won't police it. The first official discussion thread will go up on Wednesday the 1st, but feel free to kick things off here if you're wanting to pre-game the month!

      23 votes
    21. Hypothyroidism and me

      A little over a week ago, I got an official diagnosis of hypothyroidism from my GP. Fair warning, this post is going to be a little bit of a rambly discussion of my thoughts and feelings...

      A little over a week ago, I got an official diagnosis of hypothyroidism from my GP. Fair warning, this post is going to be a little bit of a rambly discussion of my thoughts and feelings surrounding my diagnosis and other circumstances surrounding it.

      I'm a US American, but I moved to Germany to do my master's degree in 2018 and have lived here ever since. I've struggled with depression and social anxiety since before I moved to Germany, but my symptoms got notably worse in 2020 (perhaps unsurprisingly). In late summer of 2020 my psychotherapist finally suggested I go on an SSRI, but she wanted me to get a blood test to rule out any physical causes. I went to my then-doctor and got such a blood test. Everything was within the normal range except for my TSH.

      For those unfamiliar, TSH is the hormone your pituitary gland sends to tell your thyroid to get a move on. It doesn't directly measure your thyroid function, but it's a pretty good indicator something's up, so doctors use it to screen for thyroid issues. High TSH is a sign of hypothyroidism, and low TSH is a sign of hyperthyroidism. Your average person with a healthy thyroid will probably have TSH between 1.0 and 2.0, but some variation exists. The normal range that doctors use here has 4.2 as its upper limit. In 2020, my TSH value was 4.8. My doctor then said that people with hypothyroidism have higher numbers than that, so I was fine. She wrote my a prescription for a low dose of an SSRI, which did help me to an extent.

      I've been fat for a long time, to different degrees. After I first moved to Germany in Fall of 2018, I quickly lost a lot of weight. There were likely a lot of factors -- I wasn't living at home where snacks were constantly stocked, I was buying food on a student's budget, I was eating out and ordering takeout less because of my social anxiety and shitty German skills, and I was walking a lot more. When I came back to the US for family vacation in 2019, I constantly got compliments about having lost weight, which felt weird. I was still overweight according to the BMI, but more of a classic midsize chubby at that time. But it wasn't to last, and I did start gaining the weight back. For a while it, I attributed this to my getting more takeout and walking less. But a year or two ago it felt like it stopped being directly attached to my activity or food consumption. I went on medication that suppressed my appetite as a side-effect, but I continued to gain weight. Since I was already fat and had been gaining weight for a while, I didn't mention anything to my doctors because I was already getting lectures about how I needed to lose weight and exercise more. I don't know for sure what I weigh right now because I've avoided weighing myself for months, because I'm scared I weigh over 100kg and I can't handle seeing that triple digit on a scale.

      I've tried and failed to become more active and start an exercise routine several times. I joined a sports course at university with some of my friends, but I quit after a couple sessions because I was hyperventilating before warm-up was over. I've tried to do some basic strength training, but I'd be sore for days after even incredibly beginner-level stuff. More recently, my wife and I tried to take regular walks through the nearby park during last spring and summer. But I'd tire out after an embarrassingly short distance, not even enough to get to where we see the ducks (the highlight of the park for me). As the weather got worse in winter I basically stopped leaving the apartment. It's a struggle to put my shoes on without an extra long shoehorn so I don't have to bend over, and anything that requires me to tie my shoelaces is basically off the table.

      I've been struggling with work for the past several months. I can't seem to focus on it, even if I take my ADHD medication. I look at the computer screen and I just can't mentally handle the work. Every day of work is exhausting, even though I work a pretty cushy job as a data scientist and I work from home. I do way less than 40 hours of actual work a week but I'm still too physically and mentally exhausted all the time to do anything but the most trivial household chores. I haven't cooked dinner for myself in months (thank God for my wife).

      I switched to a new GP at the beginning of 2024 bc I was having trouble getting timely appointments at my last one. We agree to do one big blood test covering everything, since I have a myriad of small complaints and it's been years since I've had one. That test comes back mostly normal, except my cholesterol is a little high and my TSH is a smidge above 5. My new GP then says we should do a follow-up blood test to look at other thyroid measurements (this would be directly measuring the hormones my thyroid produces) to see if I have hypothyroidism. I mention offhandedly the interaction I had with my old GP in 2020 and she says that's not how you're supposed to do that; high TSH means further testing even if it's not that high. A few weeks and another blood test later and I've now got a new diagnosis and a prescription for artificial thyroid hormone.

      It turns out that pretty much everything I've been struggling with for years now? May be because of my underactive thyroid. Your thyroid is apparently pretty damn important and it not working right (in either direction) can result in a truly dizzying amount of things going wrong. Depression, brain fog, fatigue, and weight gain are all pretty classic symptoms, but apparently it can also cause problems with your lungs or even contribute to carpal tunnel syndrome. Everyone with a properly-functioning thyroid, take a moment to thank that lil butterfly-shaped guy in your neck.

      I'm so glad to have something that's basically a "feel better" pill now. But I'm left with a sense of deep frustration that I've had so many problems that even I dismissed to myself because I assumed they were just cause I was a stupid out-of-shape Fatty. It turns out it's actually not normal for someone in their mid-20s at my age to struggle to put on their own shoes without assistance, even when they're obese. Being unable to take a short walk without needing to sit down because I'm exhausted and out of breath isn't just because I'm fat and out of shape. I've had no shortage of symptoms heavily impacting my life, but most of them I hadn't even bothered to mention to my doctor because I assumed they were just Me Being Fat and that all I'd get was (yet another) lecture.

      This is, of course, coupled with a lot of anger at my old doctor for not even running any follow-up tests. I've only been on levothyroxine for about a week and I already feel like I have a little more energy. I could have been spared years of suffering if that doctor had only done what she was supposed to. Fuck that.

      But at the same time, I feel such relief. This all wasn't just me being a bad and lazy person. There was actually something wrong. And, even better, hypothyroidism is pretty easy to treat. I just wish I hadn't gone through over three years of unnecessary suffering when I could have gotten this treatment then.

      23 votes
    22. Tildes CSS and Android accessibility

      Hi all. On my Pixel phone I have the accessibility option for font size and display size turned up a notch or two but noticed that not all of the text in Tildes adheres to this. Some front page...

      Hi all. On my Pixel phone I have the accessibility option for font size and display size turned up a notch or two but noticed that not all of the text in Tildes adheres to this. Some front page topic text is bigger, some of them remain small.

      Is this something that can be quickly tested and fixed if it's a bug? It might drive poor sighted people away from the site.

      I'm assuming it's not me, as my Pixel 7 is quite new .... but I am on the Android beta program.

      Can anyone else try and see if it's a localised issue or more global?

      I can post screen shots of needed but not sure what image sharing sites you prefer to use in here!

      Edit:

      Fixed with a chrome flag....

      the text-scaling is being replaced by the "Accessibility Page Zoom" feature (currently hidden behind the feature flag in chrome://flags)

      23 votes
    23. Productive vs non-productive creativity

      I have a slight struggle that I wonder if anyone else can relate to. I'm a creative "type" in that both my job (scientist) and hobbies (many, over the years) require constant innovation, in...

      I have a slight struggle that I wonder if anyone else can relate to. I'm a creative "type" in that both my job (scientist) and hobbies (many, over the years) require constant innovation, in addition to the usual labor, to keep them going.

      I have a note/journal app where I store my ideas. Sometimes these are ideas with acute utility e.g. an experiment design that I can test out the next day at work or maybe an idea for a paper. Other ideas are what I would consider "highdeas" - insights or thoughts that seem amazing when you're stoned but after you sober up they're kind of nonsense. The former are productive and the latter are non-productive forms of creativity (barring any offshoots of the latter that prove useful later on).

      But then sometimes I get idea in-between. Say, an insight into how certain human behaviors are a certain way or maybe a rant on a topic/issue in my lab work that is interesting but not valuable enough to publish or bring up in a formal meeting. My question / discussion topic for you, is, what do you do with these sort of self-ascribed interesting ideas that have no immediate value? One option is to write them out on a forum, as I am currently doing, but I would end up writing all day. Does anyone else keep track of these? Do you schedule a follow-up with these intermediate ideas for future inspiration? I currently use Joplin which is great but I don't think there are any features to stimulate creativity in this manner.

      23 votes
    24. Code Quality Tip: Wrapping external libraries.

      Preface Occasionally I feel the need to touch on the subject of code quality, particularly because of the importance of its impact on technical debt, especially as I continue to encounter the...

      Preface

      Occasionally I feel the need to touch on the subject of code quality, particularly because of the importance of its impact on technical debt, especially as I continue to encounter the effects of technical debt in my own work and do my best to manage it. It's a subject that is unfortunately not emphasized nearly enough in academia.


      Background

      As a refresher, technical debt is the long-term cost of the design decisions in your code. These costs can manifest in different ways, such as greater difficulty in understanding what your code is doing or making non-breaking changes to it. More generally, these costs manifest as additional time and resources being spent to make some kind of change.

      Sometimes these costs aren't things you think to consider. One such consideration is how difficult it might be to upgrade a specific technology in your stack. For example, what if you've built a back-end system that integrates with AWS and you suddenly need to upgrade your SDK? In a small project this might be easy, but what if you've built a system that you've been maintaining for years and it relies heavily on AWS integrations? If the method names, namespaces, argument orders, or anything else has changed between versions, then suddenly you'll need to update every single reference to an AWS-related tool in your code to reflect those changes. In larger software projects, this could be a daunting and incredibly expensive task, spanning potentially weeks or even months of work and testing.

      That is, unless you keep those references to a minimum.


      A Toy Example

      This is where "wrapping" your external libraries comes into play. The concept of "wrapping" basically means to create some other function or object that takes care of operating the functions or object methods that you really want to target. One example might look like this:

      <?php
      
      class ImportedClass {
          public function methodThatMightBecomeModified($arg1, $arg2) {
              // Do something.
          }
      }
      
      class ImportedClassWrapper {
          private $class_instance = null;
      
          private function getInstance() {
              if(is_null($this->class_instance)) {
                  $this->class_instance = new ImportedClass();
              }
      
              return $this->class_instance;
          }
      
          public function wrappedMethod($arg1, $arg2) {
              return $this->getInstance()->methodThatMightBecomeModified($arg1, $arg2);
          }
      }
      
      ?>
      

      Updating Tools Doesn't Have to Suck

      Imagine that our ImportedClass has some important new features that we need to make use of that are only available in the most recent version, and we're several versions behind. The problem, of course, is that there were a lot of changes that ended up being made between our current version and the new version. For example, ImportedClass is now called NewImportedClass. On top of that, methodThatMightBecomeModified is now called methodThatWasModified, and the argument order ended up getting switched around!

      Now imagine that we were directly calling new ImportedClass() in many different places in our code, as well as directly invoking methodThatMightBecomeModified:

      <?php
      
      $imported_class_instance = new ImportedClass();
      $imported_class_instance->methodThatMightBeModified($val1, $val2);
      
      ?>
      

      For every single instance in our code, we need to perform a replacement. There is a linear or--in terms of Big-O notation--a complexity of O(n) to make these replacements. If we assume that we only ever used this one method, and we used it 100 times, then there are 100 instances of new ImportClass() to update and another 100 instances of the method invocation, equaling 200 lines of code to change. Furthermore, we need to remember each of the replacements that need to be made and carefully avoid making any errors in the process. This is clearly non-ideal.

      Now imagine that we chose instead to use the wrapper object:

      <?php
      
      $imported_class_wrapper = new ImportedClassWrapper();
      $imported_class_wrapper->wrappedMethod($val1, $val2);
      
      ?>
      

      Our updates are now limited only to the wrapper class:

      <?php
      
      class ImportedClassWrapper {
          private $class_instance = null;
      
          private function getInstance() {
              if(is_null($this->class_instance)) {
                  $this->class_instance = new NewImportedClass();
              }
      
              return $this->class_instance;
          }
      
          public function wrappedMethod($arg1, $arg2) {
              return $this->getInstance()->methodThatWasModified($arg2, $arg1);
          }
      }
      
      ?>
      

      Rather than making changes to 200 lines of code, we've now made changes to only 2. What was once an O(n) complexity change has now turned into an O(1) complexity change to make this upgrade. Not bad for a few extra lines of code!


      A Practical Example

      Toy problems are all well and good, but how does this translate to reality?

      Well, I ran into such a problem myself once. Running MongoDB with PHP requires the use of an external driver, and this driver provides an object representing a MongoDB ObjectId. I needed to perform a migration from one hosting provider over to a new cloud hosting provider, with the application and database services, which were originally hosted on the same physical machine, hosted on separate servers. For security reasons, this required an upgrade to a newer version of MongoDB, which in turn required an upgrade to a newer version of the driver.

      This upgrade resulted in many of the calls to new MongoId() failing, because the old version of the driver would accept empty strings and other invalid ID strings and default to generating a new ObjectId, whereas the new version of the driver treated invalid ID strings as failing errors. And there were many, many cases where invalid strings were being passed into the constructor.

      Even after spending hours replacing the (literally) several dozen instances of the constructor calls, there were still some places in the code where invalid strings managed to get passed in. This made for a very costly upgrade.

      The bugs were easy to fix after the initial replacements, though. After wrapping new MongoId() inside of a wrapper function, a few additional conditional statements inside of the new function resolved the bugs without having to dig around the rest of the code base.


      Final Thoughts

      This is one of those lessons that you don't fully appreciate until you've experienced the technical debt of an unwrapped external library first-hand. Code quality is an active effort, but a worthwhile one. It requires you to be willing to throw away potentially hours or even days of work when you realize that something needs to change, because you're thinking about how to keep yourself from banging your head against a wall later down the line instead of thinking only about how to finish up your current task.

      "Work smarter, not harder" means putting in some hard work upfront to keep your technical debt under control.

      That's all for now, and remember: don't be fools, wrap your external tools.

      23 votes
    25. An equitable solution to a problem at work regarding sick leave and staffing?

      Please bear with me as I'm not terribly sure if this is the right place for this, if I'm phrasing it right, or if I'm making a mountain out of a mole hill. I work at a childcare center - a private...

      Please bear with me as I'm not terribly sure if this is the right place for this, if I'm phrasing it right, or if I'm making a mountain out of a mole hill.


      I work at a childcare center - a private school marketed as "the best in the area". By most metrics, we are exactly that. I've worked here for nearly 15 years in a variety of roles, namely as a prek teacher for over half of that time. I have a good relationship with my directors and the schools owners, despite some issues in the past (I'm eager to champion more rights and privileges for employees).

      This week was the sickest I have been in years, and it was the same for several other staffers as well. We couldn't call in, however, because none of us had fevers, vomiting, or diarrhea (the "big three" for what's acceptable to call in for). We all had flu-like symptoms, though those of us who went to the doctor tested negative for anything. Dozens of students had been getting ill with STREP, Influenza A/B, and Fifths in the weeks prior. It just took its time in reaching the staff!

      I co-teach in my class and my co-teacher and I both lost our voices for days. Others had full-body aches, tremendous coughing fits, extreme lethargy... It was terrible. However, almost none of us got the time off that we needed to recover. Why? Staffing. The owners/directors don't want to close a room due to illness, even if both teachers in the room are horrendously sick. I spent days with the kids, barely able to talk or move, just trying to get through the day. My coworkers were the same.

      Does that seem right?

      The directors/owners essentially picked those who were deemed "sickest" to take a day off. While in the moment I understand that decision, it doesn't seem like a terribly good way to handle it either. I want to bring up my grievances about this with the owners (I already have with the directors, they don't disagree with me but "that's just the way it is") but I also know that showing up with a problem and no solution won't go over well. I also know they don't want to close a classroom at all costs, which is my preferred solution. The last time one was closed was when 5/6 teachers in another room had COVID simultaneously and we were mandated to close the room.

      Anyone have any thoughts? Even if it's to show me a side I may not be considering here? Thank you for your insight.

      22 votes
    26. FKCaps launches URSA keycaps for topre switches

      I'm not sure if anyone else here is into topre switch keyboards, but keycaps for topre are notoriously hard to find. Topre is niche within a niche, so options are limited. But for the last year or...

      I'm not sure if anyone else here is into topre switch keyboards, but keycaps for topre are notoriously hard to find. Topre is niche within a niche, so options are limited. But for the last year or so, FKCaps in collaboration with 23_Andreas have been working to launch keycaps in a new profile specifically designed for topre called URSA, compatible with HHKB, Leopold, and Realforce boards. They have now opened for pre-order, scheduled to be delivered in January 2025.

      I don't normally go for pre-orders or group buys, but I couldn't say no to this. The URSA profile and the caps themselves look great, and while I do enjoy the OEM keycaps on my HHKB, I also like having other options and trying new things. I've got a black HHKB Pro Hybrid Type-S, and I went with the black caps with legends. The mock-up image looks beautiful. I'm excited.

      If you're unfamiliar with the HHKB, or Happy Hacking Keyboard, it's a Unix-style board that has been around for 25 years, designed by a Japanese computer scientist because he wanted a more versatile board for programming and working in the command line on multiple operating systems. What makes the layout special, and why I enjoy it, is because the caps lock key has been replaced by a control key, and delete/backspace has been moved down a row for easier reach and to allow the tilde/backtick key to live on the top right. It's designed so you can easily reach everything from the homerow, and keys like the arrows, home, end, page up, page down are on a secondary layer accessed by the function key. Further, you can change board functionality through DIP switches on the bottom of the board. It's just so fun and pleasant to type on. Build quality is superb and these boards are known to stand the test of time.

      So if there are any other topre enthusiasts around here, I urge you to check URSA out. You can read more about the keycaps here.

      Your Happy Hacking Keyboard deserves some fresh caps (Verge)

      22 votes
    27. My computer has lost its mind and I can't even begin to diagnose what's at fault. (It's the power supply.)

      UPDATE: It was the power supply. I've never even heard of such a weirdly anal issue, but after installing a new one, everything is a-okay. So, I've never really had issues with power supplies, and...

      UPDATE: It was the power supply. I've never even heard of such a weirdly anal issue, but after installing a new one, everything is a-okay.

      So, I've never really had issues with power supplies, and generally have always troubleshot (troubleshooted? trouble...shot?) my own issues with no real, well, issues. Until now.

      The other day, I got a helluva deal on a 6800 XT on Facebook Marketplace, the guy had the printout with the receipt, it's still under warranty for two years, whole shebang. So I upgraded from a Vega 56 to it. And there were zero issues. Admittedly, my power supply is only 650 watts, so I thought I might be missing some wiggle room there, and was prepared to need to upgrade. But the other night, it was fine. I stress-tested with a nearly-maxed-out 100+ FPS Cyberpunk 2077 and had zero issues, and followed that up with moderate use 144 FPS board games and things for the next few hours with a friend.

      And sometime after I went to bed (I left the computer on because I'm a bad man who doesn't take care of his things or some other vaguely acceptable excuse), Windows Update occurred. Again. It's been raising hell on me in the middle of the night any time I leave my computer on, but whatever. So in the morning (this was Sunday), I saw it wasn't working right, and just kind of... shitting itself. Had trouble getting out of BIOS, all this other stuff. Eventually, I realized it was ignoring my SSD, and after unplugging everything else and forcing it to boot from my SSD with the Windows 10 install on it, it said the install was borked and asked me to do recovery steps. None of them really worked. So at this point, I was assuming that I might have hit something with the SSD and damaged the SATA controller when moving the power for the GPU or something.

      So today, I got a new NVMe drive, booted from a 16gb flash drive, installed Windows 11 on it, and everything was fine. I was able to create a functional Windows 11 install, and it was fine. Until I got to the login screen. As soon as the screen asking for my PIN (on a complete, 100% valid Windows install) would load, that first frame, it would shut down hard. No BSOD, nothing. Just immediate shutdown. So I thought, "well, this seems like an issue for the POWER SUPPLY!" and removed the GPU, plugging my main monitor directly into the motherboard. Now, it was shutting down and power cycling before it even hit the BIOS, which is... weird as hell? So I thought "well, it gets further when a video card is in, let's put ye olden Vega 56 in and see how far that gets me!" and... it just works. I'm typing this from my fresh Windows 11 install with zero perceivable issues.

      So my question is: How is it that my computer was perfectly fine on Saturday night with my new video card under 100% load, but by the next day would decide seemingly at random based on some sort of schrodinger's cat theory when it would shut down and when it wouldn't.

      So, in summation, the four inconsistent scenarios, in tl;dr form:

      • New RX 6800 XT is installed, computer runs fine at 100% load while stress testing and then for hours afterward
      • 6800 XT installed, Windows won't boot and the power supply seemingly gives up
      • No video card installed, the computer starts power cycling before even reaching the BIOS
      • My old Vega 56 installed, everything is perfectly fine

      So, obviously there's something weird going on with my power supply, but if someone can set my sights on exactly why all of this has happened, and what the proper solution to make sure it doesn't again, or just... I don't know, typing this all out has made the last day and a half of my life feel much more worth it.

      And as an aside, my theory for why Windows was broken and I assumed my SSD was dying is as such: When it did the Windows Update and started trying to install it was the first time it powered down with no warning, which just broke Windows mid-update in a bad way.

      22 votes
    28. What is the biggest change you've ever made to your diet?

      In mid-2012 I decided to become a vegetarian, both for health and ethical reasons. Before then I had mostly been on autopilot when it came to food - I just ate what what was the norm in my family....

      In mid-2012 I decided to become a vegetarian, both for health and ethical reasons. Before then I had mostly been on autopilot when it came to food - I just ate what what was the norm in my family. My choice forced me to get out of my comfort zone, to try out new foods I had never considered before. For this reason, the change has been incredibly positive to me; I'm much more conscious of what I eat now. And by setting a precedent it later helped me make more changes, like cutting down sugar. I'm currently testing to see if the bloating and stomach aches I suffer daily are because I am lactose intolerant; if it is indeed the case, that will require another drastic change, although this particular one will be by necessity rather than choice.

      What is the biggest change you've ever made to your diet? Was it by choice, or did you feel obligated to do so, for example because of health issues? What did you get out of it? How much thought do you put in your daily diet, in general?

      22 votes
    29. I'm Brian. I'm an intellectual property attorney and I moderate some stuff on Reddit, like IAmA. Ask Me Anything.

      Hey! I practice IP law with my brothers in Southern California. I primarily do trademark, copyright and litigation work. My brothers do patents and litigation. I also moderate stuff on Reddit,...

      Hey! I practice IP law with my brothers in Southern California. I primarily do trademark, copyright and litigation work. My brothers do patents and litigation.

      I also moderate stuff on Reddit, like IAmA. Ideally, I'd like to host some AMAs here. This is kind of a test to see how it goes at an early stage.

      Ask me stuff!

      Proof with TruePic

      Edit: This was fun. Thank you guys. I'm headed out for a bit. :)

      22 votes