From b24e30b4ef5c027a325278f185e9ed06b7bf2b53 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Wed, 31 Jan 2024 12:59:58 -0500 Subject: [PATCH 01/14] fixed_micro_blogs_1 citation 2 --- content/blog/micro_blogs.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/blog/micro_blogs.md b/content/blog/micro_blogs.md index fa6640a..991df03 100644 --- a/content/blog/micro_blogs.md +++ b/content/blog/micro_blogs.md @@ -39,4 +39,5 @@ I've never thought about this before but how long should I make blogs? How long ## Footnotes 1 - I started off in a fan-fic of the stormlight archive where a character I inserted into the story was putting up a bounty for themselves by promising "a shardblade in addition to any shardblades or shardplate $character has on them" rather than with money + 2 - If you noticed that the blog example was specific that's because this post was incited by a blog with whitespace which didn't shrink the whitespace when I zoomed. Also at time of writing I checked to make sure my site adheres to this. From e637c421421941bb1dc39894e147c5bd9a08311e Mon Sep 17 00:00:00 2001 From: Pagwin Date: Tue, 6 Feb 2024 21:02:07 -0500 Subject: [PATCH 02/14] learn programming incorrectly article --- content/blog/learn_programming_incorrectly.md | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 content/blog/learn_programming_incorrectly.md diff --git a/content/blog/learn_programming_incorrectly.md b/content/blog/learn_programming_incorrectly.md new file mode 100644 index 0000000..02d3434 --- /dev/null +++ b/content/blog/learn_programming_incorrectly.md @@ -0,0 +1,41 @@ +--- + +title: "How to not learn programming" + +description: "Inspired by an unfortunate soul who tried to use chatgpt for help in an operating systems lab" + +date: "2024-02-06" + +draft: true + +--- + +# Why am I writing this? + +Well today (the first day of writing this post) after I got done with my operating systems lab on my way out I noticed someone trying to use ChatGPT to help them with the lab. The lab was pretty simple (relatively speaking) all you had to do was modify a version xv6 to print a message while in kernel mode and to have an additional userland program that did the same thing that echo did. However while the lab was simple the nature of why it was simple made it so using ChatGPT to help was almost certainly harder than just doing the lab. And that is why I want to write this. While other people more popular who are better at writing and understand this phenomenon better have definitely written about this before and it's somewhat "obvious"1 when you think about it I still want to write about it because it's a little depressing that people fail to learn and get dependent on crutches. + +# Why ChatGPT is unreliable + +Before I go into why using ChatGPT teaches such a small amount I first want to address an idea. That idea being that you can get by using ChatGPT and don't need to learn programming properly. This is false, while ChatGPT can be used for common things it will fall apart the instant you try to do anything that's seriously novel. That example of trying to make "easy" changes in xv6 being one example but for one that's a bit less intimidating let's look at how things went when I tried to use it for something once. Specifically I wanted to make a project in a relatively unpopular lang called [Erlang](https://www.erlang.org/) not for any particular reason just to learn. So the first thing I did was read a book2 (😱) from my university library. Unfortunately the build system the book explains or maybe the explanation (but probably the build system) sucks. So I decided fuck it I'll check with ChatGPT. Long story short it did not give a working answer for how to setup an Erlang project but it did alert me to the existance of [Rebar3](https://rebar3.org/docs/getting-started/) which had a command to set everything up and made building an Erlang project not terrible (yipee). Right what was I talking about right ChatGPT failed here because it isn't common place for people to put up Erlang project files online (relatively speaking) so it made stuff up. This combination of lacking information sometime + making things up makes ChatGPT unreliable unless you're doing something that's been a million times before. Will that often be the case yes but sometimes it isn't so relying on ChatGPT is a bad idea. + +# How to not learn programming (and end up in over your head) + +Simple just outsource the actual programming but still succeed. There are a few ways to do this with varying degrees of effectiveness (effectiveness being measured inversely to how much you learn). + +First you can try to get other people to do things for you rather than struggling and figuring out how to do something for yourself. This technique is about as old as the internet if not older unfortunately people who are helpful often want to see you learn something and will if possible try to do things to make you learn rather than just vomitting up a solution [assuming they don't just tell you to fuck off](http://www.catb.org/%7Eesr/faqs/smart-questions.html). Serious note: click the link at the end of the previous sentence it is more strict than is generally expected or required nowadays but + +Second you can search for an answer to your problem and blindly copy and paste a result without getting any more understanding on what the code you copied does though maybe changing some names to match your domain. This technique is also old (in internet time) maybe as old or older than Google I'm too young to know. What I do know is that this technique of not learning has the upside of not having someone who's trying to make you learn instead you just have the solution and you copy it albeit at the cost of some difficulty in finding it. Serious note: for the people who copy sometimes but do know what they're doing most of the time relax: 1) sometimes code is repetive and annoying so being able to use what someone else has done to save effort is good as long as it's substituting for effort and not knowledge 2) sometimes the answer is arbitrary or arcane within the domain of knowledge that's relevant to you and copy pasting is a nececity. Ideally you'll go back and understand what you copied out later, especially since it probably is or will be in the domain of knowledge that is relevant to you. That said if you copy code you should cite it via a commented link for future convenience and understanding. A variant of technique 2 being to just use a library, framework etc that does everything for you with both the caveats I previously mentioned still applying. + +Third and most recently is the recent wave of synthetic text generators powered by Large Language Models(LLMs). Examples of these at time of writing being ChatGPT, Falcon, LLaMa, Github Copilot, etc. These are perfect for not learning programming because if you have trouble you just ask the chat bot and it gives an answer no difficulty or making you learn. Serious note: If you are learning programming do not use Chat bots to help you at all. If you do then how confident can you be that you'll be able to do what the chat bot is doing without assistance? The answer is that unless you try without that help you can't. And odds are that if you're making heavy usage of a chat bot that you'll barely get anything out of the programming experience learning wise. The first two methods at least involve other humans or learning how to search (which is useful to learn) but this involves no such learning based caveat. That said they can be useful if 1) the model was trained on data with an acceptable legal license for what you're doing. If the model was trained on the internet and you're intending to share what you did as open source then you should assume internet training isn't acceptable, likewise if you're getting paid. 2) The work the model is doing should either be doable within 5 minutes of work on your part, some template file(s), or it should be unreliable google search on focused steroids3. + +To restate though **DO NOT USE A CHATBOT WHILE LEARNING** you will learn more without it and know you aren't reliant on it... + +# Conclusion? + +Uuuuh well I just had a thought that there's a whole separate phenomenon of tutorials but I don't have enough experience to comment on that soooo yeah. + +1 - What's obvious to me isn't obvious to everyone because I am weird. + +2 - title: Learn you some Erlang for great good! a beginner's guide author: Fred Hébert isbn: 1-59327-435-1 + +3 - I'm aware of this use case due to one specific person you know who you are you Pythonic eldritch deity. ~~I'm not squeamish normally but an image of "Ehlers Danlos Syndrome" made me squirm noticably~~ From 22653beccfca130f25b48488dadd5ed2208ad528 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Thu, 8 Feb 2024 13:51:09 -0500 Subject: [PATCH 03/14] ooooh multiple rants in draft at once --- not_broadly_competent.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 not_broadly_competent.md diff --git a/not_broadly_competent.md b/not_broadly_competent.md new file mode 100644 index 0000000..dd1813b --- /dev/null +++ b/not_broadly_competent.md @@ -0,0 +1,36 @@ +--- + +title: "Haven't figured everything out yet" + +description: "Some people who interact with me online view me as broadly competent or as having a lot or everything figured out I do not and this blog post explains why" + +date: "2024-02-08" + +draft: true + +--- + +# Some people think I'm broadly competent + +This is mostly an online phenomenon (it may be just one person) and I don't know where this comes from but it also seems to filter into how old they think I am (leading to an overestimation of somewhere between a couple and several years). Regardless this is false though I will clarify that in terms of math and programming I am relatively competent. I chose those words carefully to reduce the probability of my ego crucifying me, notably I consider relatively competent a low bar. + +# Writing + +Read these blog posts and tell me I'm competent at writing while keeping a straight face. + +# Time management + +Gotten better but still bad + +# Presentations + +simple advice + +# Misc life things + +Need to talk to people more, my diet sucks, I don't have a partner, I need to get better at not accidentally taking the lead in group work, I spend to much time watching youtube videos, I don't have an internship and no idea how to get one or how I should get a job. I have a bunch of stories I've come up with that I want to write down but I haven't written yet. I have no idea how to make a machine learning thing. I have multiple projects that I could maybe sell that I haven't even started yet. + +# Conclusion + +Scot why do you think I look competent if it's confidence please readjust your view of competence + From 8904c23fc42333fd66a2383f331514a9db556a10 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Fri, 9 Feb 2024 09:12:47 -0500 Subject: [PATCH 04/14] moved not_broadly competent to a folder where I won't publish --- .../article_purgatory/not_broadly_competent.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename not_broadly_competent.md => content/article_purgatory/not_broadly_competent.md (100%) diff --git a/not_broadly_competent.md b/content/article_purgatory/not_broadly_competent.md similarity index 100% rename from not_broadly_competent.md rename to content/article_purgatory/not_broadly_competent.md From 5e769352850ed90c20d8af6f2d289c327258ec6d Mon Sep 17 00:00:00 2001 From: Pagwin Date: Fri, 9 Feb 2024 09:36:34 -0500 Subject: [PATCH 05/14] I think the competence rant is done --- content/article_purgatory/not_broadly_competent.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/content/article_purgatory/not_broadly_competent.md b/content/article_purgatory/not_broadly_competent.md index dd1813b..21b588d 100644 --- a/content/article_purgatory/not_broadly_competent.md +++ b/content/article_purgatory/not_broadly_competent.md @@ -10,25 +10,27 @@ draft: true --- +I have decided to make this blog a draft indefinitely to minimize it's publicity. I leave the reasoning behind this as something for the reader to infer from the title and content of the article. + # Some people think I'm broadly competent This is mostly an online phenomenon (it may be just one person) and I don't know where this comes from but it also seems to filter into how old they think I am (leading to an overestimation of somewhere between a couple and several years). Regardless this is false though I will clarify that in terms of math and programming I am relatively competent. I chose those words carefully to reduce the probability of my ego crucifying me, notably I consider relatively competent a low bar. # Writing -Read these blog posts and tell me I'm competent at writing while keeping a straight face. +Read my blog posts and tell me I'm competent at writing while keeping a straight face. # Time management -Gotten better but still bad +Time management has been something I've struggled with for some years now. Frankly the fact that my grades in college are decent is a miracle (I had such a close shave with my econ class though lmao). I spend way to much time on youtube and I'm not sure how to deal with that to be honest. Regardless I'm at least in a state where things are better at the moment but who knows how long that will last. # Presentations -simple advice +Okay so the reason I'm putting this is because the person who's comment induced this writing readily accepted my advice on a presentation for unknown reasons. But seriously when making a presentation all I do is just have the bullet points be maximally short sentence fragments and trust in the speaker to be competent at speaking. Longer bullets make the speaker redundant, animations are distracting and you'll know when you need an image (assignments which mandate a minimum amount of images suck). # Misc life things -Need to talk to people more, my diet sucks, I don't have a partner, I need to get better at not accidentally taking the lead in group work, I spend to much time watching youtube videos, I don't have an internship and no idea how to get one or how I should get a job. I have a bunch of stories I've come up with that I want to write down but I haven't written yet. I have no idea how to make a machine learning thing. I have multiple projects that I could maybe sell that I haven't even started yet. +Need to talk to people more, my diet sucks, I don't have a partner and no idea how I'd change that if it becomes a higher priority, I need to get better at not accidentally taking the lead in group work, I don't have an internship and no idea how to get one or how I should get a job. I have a bunch of stories I've come up with that I want to write down but I haven't written yet. I have no idea how to make a machine learning thing. # Conclusion From 78f761b75d46dff63e7710e2ebc58e153e9a3462 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Fri, 9 Feb 2024 09:50:51 -0500 Subject: [PATCH 06/14] made a sentence less ??? --- content/blog/learn_programming_incorrectly.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/learn_programming_incorrectly.md b/content/blog/learn_programming_incorrectly.md index 02d3434..00e71d7 100644 --- a/content/blog/learn_programming_incorrectly.md +++ b/content/blog/learn_programming_incorrectly.md @@ -12,7 +12,7 @@ draft: true # Why am I writing this? -Well today (the first day of writing this post) after I got done with my operating systems lab on my way out I noticed someone trying to use ChatGPT to help them with the lab. The lab was pretty simple (relatively speaking) all you had to do was modify a version xv6 to print a message while in kernel mode and to have an additional userland program that did the same thing that echo did. However while the lab was simple the nature of why it was simple made it so using ChatGPT to help was almost certainly harder than just doing the lab. And that is why I want to write this. While other people more popular who are better at writing and understand this phenomenon better have definitely written about this before and it's somewhat "obvious"1 when you think about it I still want to write about it because it's a little depressing that people fail to learn and get dependent on crutches. +Well today (the first day of writing this post) after I got done with my operating systems lab on my way out I noticed someone trying to use ChatGPT to help them with the lab. The lab was pretty simple (relatively speaking) all you had to do was modify a version xv6 to print a message while in kernel mode and to have an additional userland program that did the same thing that echo did. However while the lab was simple the nature of why it was simple made it so using ChatGPT to help was almost certainly harder than just doing the lab. And that is why I want to write this. While other people more popular who are better at writing and understand this phenomenon better have definitely written about this before and it's somewhat "obvious"1 when you think about it I still want to write about it for not entirely rational reasons. # Why ChatGPT is unreliable From 0118ed4e181f1660a18a661aeb19c95c2e9fcd7f Mon Sep 17 00:00:00 2001 From: Pagwin Date: Sat, 10 Feb 2024 22:45:27 -0500 Subject: [PATCH 07/14] another footnote not sure what I need to edit at this point --- content/blog/learn_programming_incorrectly.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/content/blog/learn_programming_incorrectly.md b/content/blog/learn_programming_incorrectly.md index 00e71d7..f69c89d 100644 --- a/content/blog/learn_programming_incorrectly.md +++ b/content/blog/learn_programming_incorrectly.md @@ -32,10 +32,12 @@ To restate though **DO NOT USE A CHATBOT WHILE LEARNING** you will learn more wi # Conclusion? -Uuuuh well I just had a thought that there's a whole separate phenomenon of tutorials but I don't have enough experience to comment on that soooo yeah. +Uuuuh well I just had a thought that there's a whole separate phenomenon of tutorials but I don't have enough experience to comment on that4 soooo yeah. 1 - What's obvious to me isn't obvious to everyone because I am weird. 2 - title: Learn you some Erlang for great good! a beginner's guide author: Fred Hébert isbn: 1-59327-435-1 3 - I'm aware of this use case due to one specific person you know who you are you Pythonic eldritch deity. ~~I'm not squeamish normally but an image of "Ehlers Danlos Syndrome" made me squirm noticably~~ + +4 - Really I don't have suffiecient understanding or experience to write this blog post either but I did anyways so oh well From 74ef702a611cd96fdef0072d19f7d520ec765e5b Mon Sep 17 00:00:00 2001 From: Pagwin Date: Tue, 20 Feb 2024 13:23:08 -0500 Subject: [PATCH 08/14] oop --- content/blog/rust_enums.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/rust_enums.md b/content/blog/rust_enums.md index 7ca9d64..267a81e 100644 --- a/content/blog/rust_enums.md +++ b/content/blog/rust_enums.md @@ -4,7 +4,7 @@ title: "Rust Match and Enums" description: "A blog article I wrote to win a dumb argument" -date: 2022-09-06 +date: "2022-09-06" draft: false From 7f2b13897d2b85a1e016c40b995c311e028a0098 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Tue, 20 Feb 2024 13:23:18 -0500 Subject: [PATCH 09/14] working on hackbu blog --- content/blog/HackBU2024.md | 103 +++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 content/blog/HackBU2024.md diff --git a/content/blog/HackBU2024.md b/content/blog/HackBU2024.md new file mode 100644 index 0000000..34eb1e6 --- /dev/null +++ b/content/blog/HackBU2024.md @@ -0,0 +1,103 @@ +--- + +title: "Bits bobs and notes from HackBU 2024" + +description: "A summary of my experience, lessons and thoughts on the HackBU 2024 hackathon" + +date: "2024-24-02" + +draft: true + +--- + +As the description of this article says I wrote this to try and probably fail to win an argument. Namely, a friend ~~argued~~ asked "Why use rust enums just use an interface and manual type checks?" specifically the context was me advocating for the use of rust enums instead of C's union types. Example: +```dart +String anything(Object something) { + if(something is bool){ + if(something) return "fizz"; + return "buzz"; + } + if(something is int){ + if(something < 10) return "smol"; + if(something < 20) return "Mcdonald's medium"; + return "LARGE"; + } + return "$something"; +} +``` +Personally, I think this is a bad solution to the problem of having multiple valid types for something generally speaking. Specifically speaking taking an argument which we only know implements some interface can be good. + +## Rust enum example + +But I haven't made any arguments for my position yet I've just specified how you can go without C's unions which are terrible and you should never use them outside of the implementation of something that solves the problem in a better way. What makes rust enums great for this use case is that we are explicitly limiting what can be passed in at compile time and are being explicit about what we want and why. The rust equivalent to that example is +```rs +//why a 128 bit integer and not just a 64 bit? Well because I wanted to show off that rust has that that's why +enum OurEnum{InterviewQuestion(bool), FastFoodOrder(u128), Other(Box)} +fn anything(something:OurEnum)->String{ + match OurEnum{ + InterviewQuestion(true)=>{ + "fizz" + }, + InterviewQuestion(false) => { + "buzz" + } + FastFoodOrder(size_index) => { + if size_index < 10 { + "smol" + } + else if size_index < 20 { + "McDonald's medium" + } + else { + "LARGE" + }.into() + }, + Other(displayable) => { + format!("{}", displayable) + } + } +} +``` +Now you might be saying "oh my god that's way more verbose why would I want that?!?!". The reason you want that is because all that verbosity provides more information to people who have to deal with this code in the future ~~and also partially due to rust having &str and String as different things as well as me showing off a bit~~. So what new information do we get with this code that we don't get with the Dart code? + +## Each case has a name + +As the section title says each case has a name, now someone reading this code knows that our boolean case corresponds to InterviewQuestion whatever that may mean in a larger context. This also means that if we want different things for the same type under certain conditions we just need to add something to the enum. + + +## Happy little compiler errors + +In addition to the whole deal of enums helping self-document they also make it so if we fuck up we get a compiler error unless we use if let or _ but if you use those you are your own worst enemy. This also makes it so if we add a case we can't compile the code unless we handle that case everywhere we're doing stuff with our Enum. What this also means is that if we only wanted to handle booleans and unsigned integers we could do that without runtime errors. + +## Oh hey I implement your interface now fuck you + +Oh yeah also with dart interfaces nothing is stopping someone from just implementing the interface you take as an argument and just sending that to your function that takes that interface which would just completely mess everything up. + +## Bonus points + +These are more cool things with this code but they aren't as closely related to enums. + +### Match being awesome + +So you may notice that OurEnum::InterviewQuestion is referred to twice, the reason for that is that match allows you to rather than capture the value in an enum in a variable, just check if the value inside that case of the enum is some specified value, in this case, it'd be more convenient to just capture and use if else but it's still cool that we don't have to. + +### Hello Interface my old friend + +So remember how I said we shouldn't use an interface for this but interfaces can be useful in other cases. Well, the Other case for OurEnum is using an interface. Oh sorry, it's using a "trait", more specifically a trait object but the details of that go over my head so yeah it's an interface. In this case, we're specifying that we only want things that implement [Display](https://doc.rust-lang.org/std/fmt/trait.Display.html). What this means is that we can display it as a string. That may seem obvious but some datatypes may for some reason or another not play nicely with the idea of being displayed like that which won't implement the Display trait meaning it can't be given as an input to this function. + +## Conclusion + +Accept it person I'm arguing with Rust enums are superior, if anyone complains about a lack of C Unions in Dart maybe consider suggesting Rust enums... or just copy [typescript's unions](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) which is probably what these people are actually advocating for and tbh while technically inferior to rust enums has its own merits. + +## Is how I would've ended it + +But arguments/discussions aren't one sided like that and I chatted with the person shortly after writing this article and they made an interesting point. + +## If the type fits you should accept it +This is a rebuke to my "Oh hey I implement your interface now, fuck you" and is simply asking how that's a problem. After all the interface should specify what you need from some data type to be able to use it in some application. This also moves the control flow of which code to run outside of the method taking in data. Combined with the idea that the interface setup can also give compiler errors where it makes sense the question has to be now be asked why are rust enums preferable? + +## welll uuuuuuuuuuuuh +When you have a finite number of states which may contain state within themselves and aren't just representing different input types they're pretty nice. + +## Conclusion 2(Electric boogaloo) +Use interfaces when you want certain garantees about a type, use rust enums when you want a finite set of states. From 725fafa3e79484a3ae94f4d8dd32fee94a9fa990 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Tue, 20 Feb 2024 13:26:00 -0500 Subject: [PATCH 10/14] actually fixed something oop --- content/blog/HackBU2024.md | 93 +------------------------------------- content/blog/pogo_again.md | 2 +- 2 files changed, 2 insertions(+), 93 deletions(-) diff --git a/content/blog/HackBU2024.md b/content/blog/HackBU2024.md index 34eb1e6..a3be72a 100644 --- a/content/blog/HackBU2024.md +++ b/content/blog/HackBU2024.md @@ -4,100 +4,9 @@ title: "Bits bobs and notes from HackBU 2024" description: "A summary of my experience, lessons and thoughts on the HackBU 2024 hackathon" -date: "2024-24-02" +date: "2024-02-20" draft: true --- -As the description of this article says I wrote this to try and probably fail to win an argument. Namely, a friend ~~argued~~ asked "Why use rust enums just use an interface and manual type checks?" specifically the context was me advocating for the use of rust enums instead of C's union types. Example: -```dart -String anything(Object something) { - if(something is bool){ - if(something) return "fizz"; - return "buzz"; - } - if(something is int){ - if(something < 10) return "smol"; - if(something < 20) return "Mcdonald's medium"; - return "LARGE"; - } - return "$something"; -} -``` -Personally, I think this is a bad solution to the problem of having multiple valid types for something generally speaking. Specifically speaking taking an argument which we only know implements some interface can be good. - -## Rust enum example - -But I haven't made any arguments for my position yet I've just specified how you can go without C's unions which are terrible and you should never use them outside of the implementation of something that solves the problem in a better way. What makes rust enums great for this use case is that we are explicitly limiting what can be passed in at compile time and are being explicit about what we want and why. The rust equivalent to that example is -```rs -//why a 128 bit integer and not just a 64 bit? Well because I wanted to show off that rust has that that's why -enum OurEnum{InterviewQuestion(bool), FastFoodOrder(u128), Other(Box)} -fn anything(something:OurEnum)->String{ - match OurEnum{ - InterviewQuestion(true)=>{ - "fizz" - }, - InterviewQuestion(false) => { - "buzz" - } - FastFoodOrder(size_index) => { - if size_index < 10 { - "smol" - } - else if size_index < 20 { - "McDonald's medium" - } - else { - "LARGE" - }.into() - }, - Other(displayable) => { - format!("{}", displayable) - } - } -} -``` -Now you might be saying "oh my god that's way more verbose why would I want that?!?!". The reason you want that is because all that verbosity provides more information to people who have to deal with this code in the future ~~and also partially due to rust having &str and String as different things as well as me showing off a bit~~. So what new information do we get with this code that we don't get with the Dart code? - -## Each case has a name - -As the section title says each case has a name, now someone reading this code knows that our boolean case corresponds to InterviewQuestion whatever that may mean in a larger context. This also means that if we want different things for the same type under certain conditions we just need to add something to the enum. - - -## Happy little compiler errors - -In addition to the whole deal of enums helping self-document they also make it so if we fuck up we get a compiler error unless we use if let or _ but if you use those you are your own worst enemy. This also makes it so if we add a case we can't compile the code unless we handle that case everywhere we're doing stuff with our Enum. What this also means is that if we only wanted to handle booleans and unsigned integers we could do that without runtime errors. - -## Oh hey I implement your interface now fuck you - -Oh yeah also with dart interfaces nothing is stopping someone from just implementing the interface you take as an argument and just sending that to your function that takes that interface which would just completely mess everything up. - -## Bonus points - -These are more cool things with this code but they aren't as closely related to enums. - -### Match being awesome - -So you may notice that OurEnum::InterviewQuestion is referred to twice, the reason for that is that match allows you to rather than capture the value in an enum in a variable, just check if the value inside that case of the enum is some specified value, in this case, it'd be more convenient to just capture and use if else but it's still cool that we don't have to. - -### Hello Interface my old friend - -So remember how I said we shouldn't use an interface for this but interfaces can be useful in other cases. Well, the Other case for OurEnum is using an interface. Oh sorry, it's using a "trait", more specifically a trait object but the details of that go over my head so yeah it's an interface. In this case, we're specifying that we only want things that implement [Display](https://doc.rust-lang.org/std/fmt/trait.Display.html). What this means is that we can display it as a string. That may seem obvious but some datatypes may for some reason or another not play nicely with the idea of being displayed like that which won't implement the Display trait meaning it can't be given as an input to this function. - -## Conclusion - -Accept it person I'm arguing with Rust enums are superior, if anyone complains about a lack of C Unions in Dart maybe consider suggesting Rust enums... or just copy [typescript's unions](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types) which is probably what these people are actually advocating for and tbh while technically inferior to rust enums has its own merits. - -## Is how I would've ended it - -But arguments/discussions aren't one sided like that and I chatted with the person shortly after writing this article and they made an interesting point. - -## If the type fits you should accept it -This is a rebuke to my "Oh hey I implement your interface now, fuck you" and is simply asking how that's a problem. After all the interface should specify what you need from some data type to be able to use it in some application. This also moves the control flow of which code to run outside of the method taking in data. Combined with the idea that the interface setup can also give compiler errors where it makes sense the question has to be now be asked why are rust enums preferable? - -## welll uuuuuuuuuuuuh -When you have a finite number of states which may contain state within themselves and aren't just representing different input types they're pretty nice. - -## Conclusion 2(Electric boogaloo) -Use interfaces when you want certain garantees about a type, use rust enums when you want a finite set of states. diff --git a/content/blog/pogo_again.md b/content/blog/pogo_again.md index 681a955..c422e36 100644 --- a/content/blog/pogo_again.md +++ b/content/blog/pogo_again.md @@ -4,7 +4,7 @@ title: "" description: "I swear I'm going to finish it this time" -date: 2023-00-00 +date: 2023-01-01 draft: true From 434d2fc4623291d5eccf8c7c57724baee3e0d847 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Tue, 20 Feb 2024 13:27:19 -0500 Subject: [PATCH 11/14] apology to nobody --- content/blog/pogo_again.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/blog/pogo_again.md b/content/blog/pogo_again.md index c422e36..07ff363 100644 --- a/content/blog/pogo_again.md +++ b/content/blog/pogo_again.md @@ -1,8 +1,8 @@ --- -title: "" +title: "Pogo again" -description: "I swear I'm going to finish it this time" +description: "I swear I'm going to finish it this time (I'd borked the format for this post in hugo previously so sorry if you noticed)" date: 2023-01-01 From b707be9a455c83f65023e5f79178cf6da284b249 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Tue, 20 Feb 2024 15:21:47 -0500 Subject: [PATCH 12/14] hackathon article --- content/blog/HackBU2024.md | 204 +++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/content/blog/HackBU2024.md b/content/blog/HackBU2024.md index a3be72a..3a6ed6f 100644 --- a/content/blog/HackBU2024.md +++ b/content/blog/HackBU2024.md @@ -10,3 +10,207 @@ draft: true --- +# Hi :) + +Over the last weekend I went to [HackBU 2024](https://hackbu.org/2024/). This blog post is me writing about it (maybe not fully coherently). Also as an aside I went to the 2023 hackathon as well but I didn't write about it, oh well. + +## A reminder that I can do things quickly + +As with last year1 I worked on a project solo. Also like last year I was able to successfully get out a prototype of that project though unlike last year the prototype didn't completely work. But I'm getting ahead of myself, I should probably describe what I built before going into detail about my dissapointments in it. + +## What I built + +In Binghamton there are 2 bus systems, 1 is provided by the county and the other is provided by the university. The university buses were not in google maps meaning google maps wouldn't show routes involving them. As such I was going to build a system to make it easy to get a route using either or both bus systems. + +This might seem ambitious at first but it was actually quite simple, all I had to do was reverse engineer 2 live maps to get the data on bus routes from their apis, use google's route api to get the travel time of the buses through their routes, calculate the best route from point A to point B with the retrieved bus routes and learn google's map api to visualize the data and build a simple frontend to overlay on that for the user to give input into... + +I swear it sounds harder than it was. + +## Oops a bit too much scope + +Did I mention that I was planning on being even more ambitious than what I just described by using the live bus positions and past history to try and calculate when a bus would arrive at a particular bus stop and that point A and point B would've been proper addresse if I hadn't cut back on scope? + +So yeah before anything I wasted an hour or 2 working on setting up an ORM that I didn't use. But after that I got to work on useful stuff. + +## Work begins + +First things first, I had to get the data. Now you'd think that reverse engineering a bus live map would be hard but as it turns out it's pretty easy at least for what I'm doing. It was literally just + +1. go to live map website + +2. open up the network tab of the browser dev tools + +3. refresh the page and search for the words "bus", "route" and "stop" in the requests + +4. click on the obvious results and use brain to figure out what json fields like "name" and "stops" and "lat" and "lon" could possibly mean + +conveniently the Hackathon can't really prevent prior work that isn't code so all of the api reverse engineering was done the day before the hackathon so the time wasted on ORM stuff canceled out. + +## Why yes I do prefer non-linear story telling + +That reminds me I should probably mention why I was working on this solo as well as what I'm even using to build it. So unlike last year I did try a little bit more to get a group to work on something with but none of the other ideas were interesting and the people I was hoping to group with assumed I'd be fine on my own. Which they were right but I'd have liked the help if only so I could've increase the scope a bit. + +But yeah once it was clear I'd be working on my own I decided to go with a language I was comfortable with and that I knew had all the tools I needed. That language being [Rust](https://www.rust-lang.org/). [Tide]() for the http server backend, [Reqwest]() for making http requests to various apis, [SerDe]() for serializing and deserializing json, and some other libraries which aren't interesting to list out2. +## Corners cut + +I'm not going to talk about the overall development process because it's boring and mostly obvious stuff. However due to being solo and only having 24 hours I did need to cut some corners. + +First at the start of actual work I only expected to get an api done but no frontend, however the main bulk of the api was done before I started really getting tired so I had plenty of time to get a frontend with google maps out. + +However I did have to cut many corners for finding an optimal route. Firstly I didn't do a graph search at all. If the optimal path used more than 2 buses or had more than 1 bus without stopping at either the university or the greyhound station then my system wouldn't find it. The reason for this was because my system only checked 3 types of route to get from where you started to your destination. Single bus, bus to Binghamton university then transfer to another bus and bus to the greyhound station then transfer to another bus. This was because having used the buses myself I know that those 3 methods will work pretty well for getting you from point A to point B and doing a proper search seemed like a lot of work. + +Another corner I cut was on the heuristic for how good I considered a route. A good heuristic would take into acount walking distance, waiting time and bus transit time. My heuristic was to minimize euclidean distance from the starting position to the bus stop added to the distance between the bus stop they got off at to the destination. Which leads to both obvious and subtle incorrectness in measuring how good routes are but it works well enough so whatever. + +An accidental corner I cut was that uuuh I might have forgotten/ran out of time to put logic in to make sure we aren't trying to go backwards along a bus route. 90% of the time this doesn't matter though so eeeh. + +The time estimate for travel is divided by 3. I don't know why Google Routes gave me time estimates which were higher than necessary. + +I was going to deploy this with docker/docker-compose instead of messing with CORS but more on that in the stories. + +Broome county buses visually have straight lines between the bus stops instead of following the road. I'll talk about this a bit more when I get into the stories but for now all you need to know is that the reverse engineered live map doesn't give me the path and using google routes was something I thought I didn't have time for until right now as I'm writing this... Fuck. + +## Story time + +### The fucking s + +I haven't run into someone who's tried to claim Google is really good at software yet but if I do I will bring this up. So when I was using the google routes api to figure out how long it would take I noticed that the time format looked something like "250s", so for about a minute I was panicking because "oh god am I going to have to parse out time units and standardize it" but after sending a request for a route frome LA to NYC I got back another time with an s so it's in seconds but dammit if google's documentation doesn't say that. + +### prematurely closes your connection, refuses to elaborate + +Here's a docker compose file + +```yml +version: "3.3" +services: + backend: + build: . + ports: + - 9090:80 + restart: unless-stopped + frontend: + build: BBB_frontend + restart: unless-stopped + ports: + - 8080:80 + depends_on: + - backend +``` +and here's an nginx config +``` +worker_processes 1; + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + server { + listen 80; + server_name localhost; + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } + location /api/ { + proxy_read_timeout 300s; + proxy_connect_timeout 75s; + proxy_send_timeout 60s; + proxy_pass http://backend/; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } + } +} +``` + +see any problems? no? Neither do I, no idea why I... + +``` +2024/02/18 07:57:20 [error] 30#30: *1 upstream prematurely closed connection while reading response header from upstream, client: 172.31.0.1, server: localhost, request: "GET /api/ HTTP/1.1", upstream: "http://172.31.0.2:80/", host: "localhost:8080" +``` + +Oh yeah that's right, I got this error when I tried to set this up in docker-compose and I still have no idea why. I can only guess that something fucked up is going on between Tide and Nginx, oh well that wasted crucial time that could've been better spent noticing and fixing + +### The Polyline encoding fuckup + +Okay I didn't say this outright before so I'll say it now. Google's documentation sucks [here](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)'s the page describing the polyline encoding in the off chance that's a dead link here's the part that I read, assuming that the rest was context I didn't need +``` +The steps for encoding such a signed value are specified below. + + 1. Take the initial signed value: + -179.9832104 + 2. Take the decimal value and multiply it by 1e5, rounding the result: + -17998321 + 3. Convert the decimal value to binary. Note that a negative value must be calculated using its two's complement by inverting the binary value and adding one to the result: + 00000001 00010010 10100001 11110001 + 11111110 11101101 01011110 00001110 + 11111110 11101101 01011110 00001111 + 4. Left-shift the binary value one bit: + 11111101 11011010 10111100 00011110 + 5. If the original decimal value is negative, invert this encoding: + 00000010 00100101 01000011 11100001 + 6. Break the binary value out into 5-bit chunks (starting from the right hand side): + 00001 00010 01010 10000 11111 00001 + 7. Place the 5-bit chunks into reverse order: + 00001 11111 10000 01010 00010 00001 + 8. OR each value with 0x20 if another bit chunk follows: + 100001 111111 110000 101010 100010 000001 + 9. Convert each value to decimal: + 33 63 48 42 34 1 + 10. Add 63 to each value: + 96 126 111 105 97 64 + 11. Convert each value to its ASCII equivalent: + `~oia@ +``` + +here's what I wrote trying to implement that +```rs +fn enc_float(num:f64)->String{ + let mut working:i32 = (num*1e5).round() as i32; + //hopethis does what's needed + working<<=1; + if num < 0.0 { + working = !working; + } + let mut bits:[bool;30] = [false;30]; + for i in 0..30{ + bits[i] = working % 2 == 1; + working >>=1; + } + bits.chunks(5).rev() + .map(|bools|{ + let mut accu:u8 = 0; + for i in 0..5{ + accu += if bools[4-i]{ + 1 + } else {0}; + accu <<=1; + } + accu |= 0x20; + accu +=63; + char::from(accu) + }).collect::() + +} +``` + +nothing about this is obviously wrong although if you read the instructions I showed (and not the blurbs above and below) carefully there's two mistake that I made. First I didn't encode all 30 bits I needed, I only got 25 and second I Or'd every bit chunk with 0x20 rather than all but the last one. In my opinion that bit of the documentation is worded badly "OR each value with 0x20 if another bit chunk follows", compared to "OR all but the last value with 0x20" but that's not my main complaint. My main complaint is that they have step by step instructions which I just showed **in addition** to a critical paragraph block above it which I skipped due to convention being that if you have a step by step guide in either documentation or a tutorial that everything that needs to be done is contained within those steps. I've copied the critical paragraph below with important bit that I messed up boldened. + +> The encoding process converts a binary value into a series of character codes for ASCII characters using the familiar base64 encoding scheme: to ensure proper display of these characters, encoded values are summed with 63 (the ASCII character '?') before converting them into ASCII. The algorithm also checks for additional character codes for a given point by checking the least significant bit of each byte group; if this bit is set to 1, the point is not yet fully formed and additional data must follow. +> Additionally, to conserve space, **points only include the offset from the previous point** (except of course for the first point). All points are encoded in Base64 as signed integers, as latitudes and longitudes are signed values. The encoding format within a polyline needs to represent two coordinates representing latitude and longitude to a reasonable precision. Given a maximum longitude of +/- 180 degrees to a precision of 5 decimal places (180.00000 to -180.00000), this results in the need for a 32 bit signed binary integer value. + +It's also boldened on the page itself but regardless I skipped over it. + +You may be wondering why this matters, why was I implementing polyline and the answer is so I could draw on google maps, and yeah surprise because of that Broome county buses don't show up because I did this wrong. The reason I didn't fix it was because I wasn't able to find out until about 3 hours before submission and didn't notice for the first 1-2 of those hours due to a mixture of sleep deprivation and eating breakfast. + +1 - I built a CI system called [Romance]() last year which has a separate repo with the [frontend](), and it needs even more duct tape and dreams than this years project if you want it to work properly + +2 - [chrono](), [async-std](), and [anyhow]() and I put in and then took out [geo-types](), [tokio]() and [sea-orm]() From ec609c68b7baab7efd71bf548b9e482c80c26649 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Sat, 23 Mar 2024 01:20:10 -0400 Subject: [PATCH 13/14] corrections --- content/blog/speedrun.md | 2 +- content/blog/universal_proc_tut.md | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/content/blog/speedrun.md b/content/blog/speedrun.md index f4a99c9..1553071 100644 --- a/content/blog/speedrun.md +++ b/content/blog/speedrun.md @@ -28,7 +28,7 @@ Lol I redid it again and wrote a blog post on it but didn't publish it so that's ## Music notation -So about a week or go I saw [this tantacrul video](https://www.youtube.com/watch?v=Eq3bUFgEcb4) and towards the start of it I decided to come up with a new music notation for fun. I yeeted the notes because I thought arbitrary symbols seemed dumb made use of color to communicate things like sharps and other symbols while keeping the current number of bars. Here's what I wrote down with little to no influence from the video. +So about a week ago I saw [this tantacrul video](https://www.youtube.com/watch?v=Eq3bUFgEcb4) and towards the start of it I decided to come up with a new music notation for fun. I yeeted the notes because I thought arbitrary symbols seemed dumb made use of color to communicate things like sharps and other symbols while keeping the current number of bars. Here's what I wrote down with little to no influence from the video. ``` rather than arbitrary symbols lets use lines length is encoded via the length of a line diff --git a/content/blog/universal_proc_tut.md b/content/blog/universal_proc_tut.md index 8a385f4..75c2473 100644 --- a/content/blog/universal_proc_tut.md +++ b/content/blog/universal_proc_tut.md @@ -44,7 +44,7 @@ PROC helloProcedure (name) { helloProcedure("World") ``` ## Lists -lists are a methodology of storing multiple data values within a single variable. When you want to store or retrieve a value from a list you need to specify at what position in the list you want to retrieve the value from via a number with the indexing of that list commonly starting from 0 with certain very special languages which choose to start or allow the programmer to start lists from indices other than 0. When declaring a list in our pseudocode I'll use square brackets surrounded comma separated values of the list, the size of the list will not be set in stone for convenience but it should be noted that in most programming languages you need to be explicit when making a list larger. An example of creating and using a list is shown below +lists are a methodology of storing multiple data values within a single variable[[4]](#4). When you want to store or retrieve a value from a list you need to specify at what position in the list you want to retrieve the value from via a number with the indexing of that list commonly starting from 0 with certain very special languages which choose to start or allow the programmer to start lists from indices other than 0. When declaring a list in our pseudocode I'll use square brackets surrounded comma separated values of the list, the size of the list will not be set in stone for convenience but it should be noted that in most programming languages you need to be explicit when making a list larger. An example of creating and using a list is shown below ``` someList <- ["First item", "Second item", "meh item"] someList[2] <- "Third item" @@ -64,6 +64,9 @@ WHILE i < 50 { i <- 0 WHILE i < 50 { DISPLAY(dataSet[i]) + "if you saw this article prior to March 2024" + "I forgot to include the line below sorry about that." + i <- i + 1 } FOREACH n <- dataSet { DISPLAY(n) @@ -78,3 +81,5 @@ That should cover the basic syntax features someone trying to learn a procedural 2 - most programming languages have certain specifications on what you can name your variables and there's also reccomended ways you should name your variables and both of these can vary per language so you should probably read their documentation for specifics but for my purposes I'm gonna stick to [camelCase](https://en.wikipedia.org/wiki/Camel_case) using only english letters as I'm unaware of any non-esoteric programing languages which disallow such naming 3 - some programming languages will call foreach loops just for loops but most languages call them foreach loops + +4 - Hello pagwin from March 2024 here, I was reading this back and realized that it's more complicated than this and I forgot to mention that at the time. As you can see from the code below the 4 annotation oftentimes you can assign to elements of a list individually without needing to remake the entire list around it and assign the whole list to the variable again. A more accurate description is a list is a way to hold multiple buckets you can store values in within a single variable. Going beyond that involves talking about references and that's beyond this article's scope. From c54f0d7c35f8a52d913a5430baab08b3a66eb81d Mon Sep 17 00:00:00 2001 From: Pagwin Date: Thu, 11 Apr 2024 10:16:47 -0400 Subject: [PATCH 14/14] a bit of tweaks to unpublished stuff my HACKBU blog is probably fine --- content/blog/HackBU2024.md | 2 +- content/blog/learn_programming_incorrectly.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/blog/HackBU2024.md b/content/blog/HackBU2024.md index 3a6ed6f..7a25001 100644 --- a/content/blog/HackBU2024.md +++ b/content/blog/HackBU2024.md @@ -6,7 +6,7 @@ description: "A summary of my experience, lessons and thoughts on the HackBU 202 date: "2024-02-20" -draft: true +draft: false --- diff --git a/content/blog/learn_programming_incorrectly.md b/content/blog/learn_programming_incorrectly.md index f69c89d..fd7ddec 100644 --- a/content/blog/learn_programming_incorrectly.md +++ b/content/blog/learn_programming_incorrectly.md @@ -12,7 +12,7 @@ draft: true # Why am I writing this? -Well today (the first day of writing this post) after I got done with my operating systems lab on my way out I noticed someone trying to use ChatGPT to help them with the lab. The lab was pretty simple (relatively speaking) all you had to do was modify a version xv6 to print a message while in kernel mode and to have an additional userland program that did the same thing that echo did. However while the lab was simple the nature of why it was simple made it so using ChatGPT to help was almost certainly harder than just doing the lab. And that is why I want to write this. While other people more popular who are better at writing and understand this phenomenon better have definitely written about this before and it's somewhat "obvious"1 when you think about it I still want to write about it for not entirely rational reasons. +Well today (early February 2024) after I got done with my operating systems lab on my way out I noticed someone trying to use ChatGPT to help them with the lab. The lab was pretty simple (relatively speaking) all you had to do was modify a version xv6 to print a message while in kernel mode and to have an additional userland program that did the same thing that echo did. However while the lab was simple the nature of why it was simple made it so using ChatGPT to help was almost certainly harder than just doing the lab. And that is why I want to write this. While other people more popular who are better at writing and understand this phenomenon better have definitely written about this before and it's somewhat "obvious"1 when you think about it I still want to write about it for not entirely rational reasons. # Why ChatGPT is unreliable