I Like Kill Nerds: Recent Episodes

None

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

View Details

If you’ve been following along, a figure known as Strawberry Man, or @iruletheworldmo on X, has become the harbinger of what might be the most significant update in AI since the inception of conversational bots.

tomorrow, everything changes. project strawberry isn’t just another ai upgrade—it’s a revolution. we’re talking about an intelligence so advanced, it will outthink, outcreate, and outlast anything we’ve ever known. imagine debating with history’s greatest minds, creating…

— (@iruletheworldmo) August 14, 2024

The Hype and the Man

Strawberry Man, not just a name but a phenomenon, has been at the forefront of AI speculation. His posts on X have ranged from cryptic to bold, like his recent declaration that “tomorrow, everything changes.” This statement, wrapped around the enigmatic “Project Strawberry,” has fueled the tech community’s imagination. As per the grapevine, Project Strawberry isn’t just another AI upgrade; it’s described as a revolution promising an intelligence that could outthink, outcreate, and outlast any current model.

thursday. gpt5

a bigger leap than 1 2 4. https://t.co/Hkuaaf7JqI

— (@iruletheworldmo) August 14, 2024

While OpenAI has been characteristically silent, or at least not overly forthcoming, about its next moves, the community has pieced together information from various sources. Business Insider’s reports, among others, hinted at a summer release for what could be significantly better than GPT-4, with capabilities that might include autonomous internet navigation and advanced reasoning, thanks to Project Strawberry.

Some have speculated that Strawberry Man is powered by GPT-5 (or some new agent OpenAI has developed) or could be operated by multiple people over at OpenAI to stir excitement. If you’re on X and following people in the AI space, you’ve probably seen a lot of strawberries these past few weeks.

It’s interesting to see Strawberry Man’s very specific prediction. Although his posts have historically been very cryptic and vague, saying that GPT-5 is coming tomorrow is about as specific as it gets. If GPT-5 doesn’t drop tomorrow, many people will unfollow and block this account.

If Strawberry Man’s posts are to be taken at face value, GPT-5 isn’t just an incremental update. It’s described as “remarkably better” than anything we’ve seen, suggesting a leap in AI capabilities that could redefine what we expect from AI.

$1,000 per month for at least the first six months for the model rolling out tomorrow. it’s slow. it’s expensive. it’s god.

gpt5 arrives.

— (@iruletheworldmo) August 14, 2024

The mention of a $1,000 per-month price tag for the initial rollout period underscores the model’s anticipated value, hinting at capabilities that might be worth the steep cost for early adopters. I think the $1k price tag seems a bit too high.

The Community’s Reaction

The X posts from Strawberry Man have stirred excitement and scepticism. The AI community, always looking for the next big thing, has mixed feelings. Some are outright bullish, seeing this as the dawn of a new era in AI, where models like Grok from xAI might face stiff competition. Others, like those who’ve unfollowed Strawberry Man for what they perceive as overhyping, suggest a more cautious approach, reminding everyone of the importance of waiting for official announcements.

Beyond the immediate excitement, Strawberry Man’s proclamations touch on broader themes in AI development: the quest for AGI (Artificial General Intelligence), the ethical implications of such advanced AI, and the economic impacts of a model that could perform tasks autonomously across various domains. This isn’t just about a new chatbot; it’s about redefining what AI can do for humanity or, perhaps, what it might do without human intervention.

Whether or not tomorrow brings the launch of GPT-5, as Strawberry Man has foretold, his posts have undeniably captured the zeitgeist of AI’s rapid evolution.

The post Allegedly GPT-5 Is Launching Tomorrow appeared first on I Like Kill Nerds.

View Details

Aussie Broadband has just unveiled a new line-up of NBN plans that Aussie power users and professionals have been asking for a while. Dubbed the “PRO” plans, these offerings cater to those who need high download speeds and larger upload capabilities—something that has been sorely lacking in many NBN plans to date.

The plans include:

NBN 250/100 at $139 per month

NBN 500/200 at $169 per month

NBN 1000/400 at $199 per month

I was excited to see a 400mb up (I would have preferred a 1000/1000 plan, but we won’t have that for a long time). So as soon as I saw the new plans, I immediately upgraded to the 1000/400 plan and after a few NTD restarts and port resets, it became apparent the improved upload speeds weren’t coming yet.

But, as is often the case with the NBN, the excitement of new plans has been overshadowed by yet another failure on their part – this time, an outage that has rendered their ordering system inoperable for over 24 hours. This means anyone trying to upgrade to these new plans is out of luck until NBN gets its act together.

Yesterday’s failure involved NBN’s ordering system, which has been down for over 24 hours. This outage prevents any new orders, including plan upgrades, from processing. Customers looking to take advantage of Aussie Broadband’s new PRO plans are finding their orders stuck in “Acknowledged” status, with no clear timeline for when they might see their service upgraded.

NBN has provided an estimated restoration time (ETR) for 10:00 AEST on August 14, 2024, but there’s little confidence that this deadline will be met. Even Aussie Broadband’s representative on the Whirlpool forums, James Di, has expressed scepticism, suggesting that the ETR is likely to be pushed back further (which appears to be the case).

A History of Letdowns

NBN’s latest mishap is just one more chapter in its long history of failures. The National Broadband Network was supposed to be Australia’s answer to the internet demands of the 21st century. It was meant to bring fast, reliable internet to every corner of the country, levelling the playing field for rural and urban Australians. Instead, it has been plagued by mismanagement, political interference, and technological shortcomings.

The rollout has been a mess, with a mixed-technology approach that left many areas stuck with subpar connections. And now, even when a company like Aussie Broadband tries to deliver a better service with new speed tiers for power users, NBN’s incompetence throws a wrench into the works.

For many Australians, the NBN has been a source of frustration rather than the digital revolution it was promised to be. While companies like Aussie Broadband are doing their best to work within the constraints of the NBN’s infrastructure, there’s only so much they can do when the network’s very backbone is so unreliable.

This latest outage is a stark reminder of the ongoing issues with the NBN. It’s not just about slow speeds or poor connections anymore—it’s about the systemic failures plaguing the entire system. NBN Co. still can’t maintain a reliable ordering system in 2024, emblematic of the deeper problems present since the network’s inception.

Not long after publishing, Aussie Broadband sent out an email acknowledging the delay

The post Aussie Broadband Launches PRO Plans – But NBN’s System Fails to Deliver, Again appeared first on I Like Kill Nerds.

View Details

AI tools are incredibly useful. They assist with debugging, problem-solving, and even serve as a high-tech rubber duck for discussing problems. However, there’s a growing trend that I’ve noticed both in myself and within the developer community.

The Comfort Zone TrapIt’s easy to fall into the trap. You encounter a roadblock, and instead of working through it or consulting the documentation, you ask ChatGPT or Claude. Problem solved instantly. While it feels efficient, it raises a question: are we compromising our long-term development skills

More posts are appearing on forums like Reddit from developers worried about losing their edge. They report forgetting fundamentals or struggling with problems that used to be straightforward. I understand their concern. I’ve also found myself reaching for AI assistance prematurely at times.

Use It or Lose ItThink about how we used to memorise phone numbers, but now struggle to recall even close friends’ numbers due to smartphones. Our coding skills are similar. Skills and knowledge we don’t regularly use or challenge can deteriorate.

AI can bridge those gaps, but dependency isn’t ideal. Imagine being in a code review or an interview, unable to rely on AI. This scenario underscores the need to maintain our core skills.

Finding the BalanceThis isn’t a call to abandon AI tools. They are powerful resources that can enhance productivity and facilitate learning. The key is balance.

Here’s my approach:

  • Solve first, ask later: I give myself time to tackle problems before turning to AI, keeping my problem-solving skills sharp.
  • Use AI to learn, not just to solve: When using AI, I ensure I understand the solution rather than just copying it.
  • Regular skill check-ins: I engage in coding challenges without AI to maintain my skills.
  • Teach others: Explaining concepts to junior developers or writing blog posts reinforces my understanding.
  • Set AI-free days: Once a week, I work without AI tools. It’s challenging but rewarding.

Wrapping UpAI is a valuable addition to our toolkit, but like any tool, it should be used wisely. Our goal should be to enhance our skills, not replace them. Let’s strive to become better developers, not just more efficient ones.

Have you noticed changes in your coding habits with the rise of AI tools? I’d like to hear your thoughts and strategies for maintaining sharp skills in an AI-assisted environment.

The post The Hidden Dangers of Over-Relying on AI as a Developer appeared first on I Like Kill Nerds.

View Details

The TypeScript team has unveiled the beta version of TypeScript 5.6, and it’s brimming with features designed to make our lives easier.

Catching Logical Errors Early: Disallowed Nullish and Truthy ChecksOne of the standout features in TypeScript 5.6 is the stricter handling of nullish and truthy checks. Previously, TypeScript would quietly accept certain logical errors, leading to potential bugs that were hard to catch. Now, the compiler flags expressions that always evaluate to a specific boolean value, such as:

if (inputString => "hello") { // This condition is always true, but it's likely a mistake.} These stricter checks help catch logical errors early, making your code more robust and less prone to subtle bugs. It’s like having an extra pair of eyes scrutinising your logic, ensuring you don’t overlook potential issues.

Making Iterators More Powerful: Iterator Helper MethodsIterators in JavaScript are great, but wouldn’t it be fantastic if they had the same handy methods as arrays? TypeScript 5.6 brings iterator helper methods, so now you can do things like this:

function* generateNumbers() { let num = 1; while (true) { yield num++; }}const squaredNumbers = generateNumbers().map(n => n * n);console.log([...squaredNumbers.take(5)]); // Outputs: [1, 4, 9, 16, 25] These methods make working with iterators as intuitive as working with arrays, simplifying complex operations and making your code cleaner and more readable.

Ensuring Type Safety: Strict Builtin Iterator ChecksTypeScript 5.6 introduces the BuiltinIterator type and the --strictBuiltinIteratorReturn flag to enforce stricter checks on iterators:

class NumberStream extends Iterator<number> { next() { return { value: Math.random(), done: false }; }}const numbers = new NumberStream().map(n => n * 2);console.log(numbers.next().value); // Outputs a random number multiplied by 2 This enhances type safety, reducing the risk of runtime errors and ensuring that your iterators behave as expected.

Embracing Flexibility: Arbitrary Module IdentifiersEver wanted to use quirky module names but found it challenging? TypeScript 5.6 makes it possible:

export { default as "" } from "./keyModule";import { "" as key } from "./keyModule";key.doSomething(); This feature allows for better interoperability with other languages and tools, making TypeScript more versatile in different environments, including WebAssembly.

Catching Typos in Imports: The –noUncheckedSideEffectImports OptionTypeScript 5.6 introduces the --noUncheckedSideEffectImports option to catch typos and unexpected behavior in side-effect imports:

import "nonexistent-module"; // This will now throw an error if the module doesn't exist. This option ensures that your imports are intentional and correct, preventing subtle bugs caused by unnoticed typos.

Speeding Up Development: The –noCheck OptionFor those times when you need faster builds, TypeScript 5.6 offers the --noCheck option to skip type checking:

tsc --noCheck This can significantly speed up your development process, allowing you to iterate faster by separating type checking from code emission.

Better Project Management: Allow –build with Intermediate ErrorsIn larger projects, TypeScript 5.6 allows the --build mode to continue even if there are errors in dependencies:

This enables developers to work on different parts of a project simultaneously without being blocked by upstream errors, improving productivity and flexibility in large codebases.

Faster Feedback in Editors: Region-Prioritized DiagnosticsTypeScript 5.6 introduces region-prioritised diagnostics, providing quicker feedback for the part of the code you’re currently working on.

This makes the editing experience smoother, especially in large files, as you get immediate feedback on your changes without waiting for the entire file to be checked.

Smarter Configuration Management: Search Ancestor Configuration FilesTypeScript 5.6 enhances how editors find the relevant tsconfig.json file, allowing more flexibility in project organisation:

This simplifies project setup and maintenance, making it easier to manage large and complex codebases.

Notable Behavioural ChangesSeveral noteworthy changes and bug fixes are included in TypeScript 5.6, such as always writing the .tsbuildinfo file and respecting file extensions and package.json configurations within node_modules.

These changes enhance the overall stability and predictability of the TypeScript compiler, ensuring smoother upgrades and fewer surprises during development.

ConclusionTypeScript 5.6 is more than just an update; it’s a substantial improvement in making our development processes smoother, faster, and more reliable. From stricter type checks and enhanced iterator methods to faster build processes and better editor support, TypeScript 5.6 is set to make a significant impact on our coding experience.

The post TypeScript 5.6 Is a Game-Changer appeared first on I Like Kill Nerds.

View Details

Look, we’ve all been there. You’re knee-deep in JavaScript code and suddenly have this brilliant idea: “If I just tweak this bit here, surely it’ll run faster!” Before you know it, you’re down a rabbit hole of micro-optimisations, convinced you’re crafting the most efficient code known to humankind.

The Optimisation Itch

It’s tempting. The thought that with just a few clever tricks, you can make your code zoom along at lightning speed. But here’s the kicker: more often than not, these early optimisation efforts are a bit like rearranging deck chairs on the Titanic. They might make you feel productive, but they’re not addressing the real issues. Because if you haven’t even built your app yet, what are you optimising?

Take this simple example:

const numbers = [1, 2, 3, 4, 5];let sum = 0;for (let i = 0; i < numbers.length; i++) { sum += numbers[i];} “Aha!” you might think. “I’ll cache the length and use a while loop instead. That’ll speed things up!”

const numbers = [1, 2, 3, 4, 5];let sum = 0;let i = 0;const len = numbers.length;while (i < len) { sum += numbers[i++];} But hold your horses. In modern JavaScript engines, the difference is negligible at best. You’ve just made your code harder to read for no real gain.

The Cost of Cleverness

Now, don’t get me wrong. Optimisation isn’t inherently bad. But when we rush into it, we often end up with code that’s harder to understand and maintain. It’s like those people who insist on speaking in nothing but obscure idioms – sure, it might make them feel clever, but it’s annoying for everyone else.

Consider this little gem:

const isEven = num => !(num & 1); Clever, right? It uses a bitwise operation to check if a number is even. But it’s unclear what this does unless you’re intimately familiar with bitwise operations. Compare that to:

const isEven = num => num % 2 === 0; It might be a little slower, but it’s crystal clear what’s happening. And in the grand scheme, that clarity is worth far more than any microscopic performance gain.

The Real Cost

The danger of premature optimisation isn’t just that it makes your code harder to read. It’s that it distracts you from the real issues. While you’re fussing about micro-optimisations, you might be missing the actual performance bottlenecks in your application.

It’s like trying to save money by switching to cheaper tea bags when you’re haemorrhaging cash on a yacht you never use. You’re focusing on the wrong thing.

So, What’s the Answer?

Look, I’m not saying never optimise. But before you dive in, ask yourself:

  1. Is there a performance problem?
  2. If there is, have I identified where it’s coming from?
  3. Will this optimisation make a meaningful difference?

If you can’t answer “yes” to all three questions, step away from the optimisation toolkit and focus on writing clear, maintainable code first. Trust me, your future self (and your poor colleagues) will thank you.

Remember, premature optimisation is like Christmas decorations in October—it might seem like a good idea at the time. Still, it will probably annoy everyone and create more work in the long run.

The post The Perils of Premature Optimization in JavaScript: Why Rushing to Optimise Can Hurt Your Code appeared first on I Like Kill Nerds.

View Details

On July 19, 2024, a seemingly routine software update became a global nightmare. CrowdStrike, a cybersecurity giant trusted by countless organisations worldwide, inadvertently released a faulty update that brought systems crashing across the globe. As someone who relies on technology daily, personally and professionally, I couldn’t help but feel a chill run down my spine as I watched the chaos unfold.

Let’s be clear: this wasn’t a cyberattack. It was an honest mistake, a “logic error” in the code that slipped through testing. But that’s precisely what makes it so terrifying. Imagine what a coordinated, malicious attack could do if a simple update can cause this much havoc.

The scale of the disruption was staggering. Airlines grounded, hospitals scrambled, and supermarkets closed their doors—it felt like scenes from a disaster movie. But this was our reality for several hours. And while CrowdStrike worked tirelessly to fix the issue, the ripple effects continued for days.

Here’s the sobering truth: our world is incredibly fragile. We’ve built a digital house of cards, and it doesn’t take much to bring it all down. This incident exposed just how interconnected and vulnerable our systems are. One faulty line of code, and suddenly, millions of people can’t access their bank accounts, board their flights, or even get emergency medical care.

Now, let’s take a moment to consider a chilling “what if” scenario. What if this wasn’t an accident? What if it was an intentional attack designed to cripple our infrastructure for weeks or even months? The economic impact would be devastating. Businesses would shutter, supply chains would grind to a halt, and the very fabric of our society would be tested.

We talk about attacks on critical infrastructure, such as the water supply, internet, or electricity distribution networks, but not so much the other things entrenched in our daily lives. The COVID-19 pandemic also showed how vulnerable we are when supply chains are tested, compounded by Russia’s invasion of Ukraine.

This isn’t fear-mongering; it’s a wake-up call. The CrowdStrike incident has shown us the cracks in our digital foundation, and we need to take action before those cracks widen into chasms.

So, what can we do? For starters, we need to rethink our approach to cybersecurity. It’s not just an IT problem; it’s a fundamental business and societal risk. We need redundancy in our systems, better testing protocols, and more robust incident response plans.

On a personal level, we all need to be more aware of our digital dependencies and have backup plans. Do you know how you’d access your important documents or communicate with loved ones if the internet went down for an extended period?

This incident should spark serious conversations about digital resilience for businesses and governments. We need to invest in diversifying our technological infrastructure, much like we diversify financial investments to spread risk. Relying too heavily on a single vendor or system is a recipe for disaster.

The CrowdStrike incident was a glimpse into a potential future we must work hard to avoid. It’s a future where our digital vulnerabilities become our Achilles’ heel, capable of bringing entire nations to their knees.

But it’s not all doom and gloom. This wake-up call can be the catalyst for positive change. By acknowledging our vulnerabilities and taking proactive steps to address them, we can build a more resilient digital world—one that can withstand not just accidental glitches but intentional attacks as well.

As we move forward, let’s remember the July 19, 2024 lessons. Let’s use this experience to strengthen our defences, improve our systems, and ensure that our digital future is built on a foundation of resilience, not fragility. The clock is ticking, and the stakes couldn’t be higher. It’s time to act.

The post The CrowdStrike Incident: A Wake-Up Call appeared first on I Like Kill Nerds.

View Details

If you think dumping a bag of charcoal into your Weber kettle barbecue is the key to BBQ nirvana, you’re about to get a wake-up call hotter than your overloaded barbecue.

Let’s start with a hard truth: your grill isn’t a dumpster fire, so stop treating it like one. That “more is more” mentality? It’s turning your steaks into hockey pucks and your wallet into a sad, empty leather pouch.

When I first started charcoal BBQ, I fell into the same trap as many others. You want it hot to get a good sear on your steaks and meats. But here’s the dirty secret Big Charcoal doesn’t want you to know: you’re probably using too much. It’s like finding out your dog has been lying about needing two breakfasts.

The “Less is More” Revolution

So, how much charcoal do you need? A single layer covering about 2/3 of your grill’s bottom will do the trick. I can hear the gasps from here. “But how will I achieve the temperature of the sun’s surface?” you ask. Trust me, unless you’re trying to smelt iron, you’ll be just fine.

Temperature Control: Become the Grill Whisperer

Now that we’ve curbed your charcoal addiction, let’s talk about becoming a temperature-taming wizard:

  1. Vent Magic: Those little holes aren’t just for looks. They’re like the volume knobs on your BBQ. More open = hotter. More closed = cooler.
  2. The Two-Zone Tango: Pile your charcoal on one side and leave the other bare. Congrats, you’ve just created a hot zone for searing and a cool zone for gentle cooking. It’s like having a mullet for your grill – business on one side, party on the other.
  3. Lid Logic: That lid isn’t just to keep birds from pooping in your food. Use it to trap heat and smoke, creating an oven-like environment. Just lift it occasionally unless you’re going for that “surprise cremation” flavour profile.

Pro Tips to Make You Look Like You Know What You’re Doing

  1. The Waiting Game: Let your charcoal ash over before cooking. Use this time to practice your “I meant to do that” face for when you inevitably drop something.
  2. Grate Expectations: Clean your grates. It’s not just for show – it prevents your meat from turning into charcoal-flavored Velcro.
  3. Flip Off: Stop flipping your meat more often than a UFC fighter changing their stance in the octagon. Let it be. Your food will tell you when it’s ready to turn – usually right after you’ve walked away to grab another beer.
  4. Thermometer Thaumaturgy: Invest in a good meat thermometer. Unless you’ve got thermal vision, it’s the only way to know if your meat is done. I use the Meater probe, which does the trick nicely and connects via Wifi to an app.
  5. Rest and Relaxation: Let your meat rest after cooking. It’s been through a lot and needs a moment to collect itself. Use this time to bask in your guests’ adoration or frantically hide any evidence of your cooking mishaps.

The Smoky Bottom Line

Remember, BBQ isn’t just about the destination but the journey. A journey that involves fire, meat, and the constant threat of singed arm hair. Embrace the chaos, learn from your charred mistakes, and ease up on the charcoal. If you need more charcoal, you can always add it, but it’s a pain (figuratively and literally) to go into a hot BBQ and remove charcoal.

Now, if you’ll excuse me, I have a date with a brisket that’s been eyeing me seductively from the fridge.

The post Charcoal BBQ: The Art of Doing More with Less (And Not Setting Your Eyebrows on Fire) appeared first on I Like Kill Nerds.

View Details

Let’s chat about everyone’s favourite corporate euphemism: the Performance Improvement Plan, or PIP for short. If you’ve ever been on the receiving end of one, you know it’s about as pleasant as a root canal without anaesthesia. But today, we’re going to peel back the layers of this bureaucratic onion and expose the tears-inducing truth.

First off, let’s dispense with the notion that PIPs are a well-meaning attempt by your company to help you improve. That’s as believable as your manager’s claim that they’re “not micromanaging, just checking in”. While some companies might have well meaning intentions, the truth is for most, once you’re on the PIP, you’re already gone.

PIPs are, in reality, a carefully crafted exit strategy designed to protect the company, not you. It’s the corporate equivalent of saying, “It’s not you, it’s me,” while simultaneously changing the locks on the door.

Here’s how it typically plays out:

  1. The Setup: You’re called into a meeting. Your manager looks concerned, like they’ve just discovered their dog ate their performance review notes. They tell you they’re “worried about your performance”. Translation: “We’ve already decided you’re out, but we need to cover our arses legally”.
  2. The Plan: You’re presented with a document outlining impossible goals and unrealistic timelines. It’s as achievable as finishing a marathon in flip-flops. The company knows this, but hey, they need to show they gave you a “fair chance”.
  3. The Monitoring: Suddenly, your every move is scrutinised more closely than a celebrity’s rubbish bins. Did you take an extra minute on your lunch break? Was your commit message too long or did you name a function wrong?That’s going in the file, mate.
  4. The Inevitable Conclusion: After weeks or months of stress and sleepless nights, you’re told you haven’t met the goals. Shock horror! Who could have seen that coming?

The truth is, PIPs are rarely about improvement. They’re about documentation. The company is building a case for your dismissal that’s more watertight than a submarine. It’s not personal, it’s just business – the business of covering their legal backsides.

But, let’s talk about the elephant in the room that PIPs conveniently ignore: your actual life circumstances.

Imagine this scenario:

Your manager: “Hey Billy, your performance is shit.”

What they should be saying: “Hey Billy, we’ve noticed your performance has slipped these last few months and you’ve been here for a couple of years now. Is everything okay?”

But no, that would require actual human empathy and understanding. Heaven forbid a company acknowledge that employees are real people with lives outside of work.

PIPs operate in a bizarre parallel universe where personal and health issues simply don’t exist. Going through a divorce? Dealing with a chronic illness? Caring for an elderly parent? Have cancer and undergoing chemotherapy? Sorry, mate, that’s not in the PIP handbook. Your KPIs don’t care about your personal crises.

It’s as if companies believe that the moment you clock on for work hours, you transform into an emotionless productivity robot, impervious to the trials and tribulations of human existence. Got depression? Have you tried not being sad and hitting your targets instead? Brilliant solution, that.

The cold, hard truth is that PIPs are designed to be one-size-fits-all solutions in a world where one size, quite frankly, fits no one. They’re the corporate equivalent of putting a band-aid on a broken leg and expecting you to run a marathon.

So, the next time you hear those dreaded words “performance improvement plan”, know that it’s likely not an opportunity, but an obituary for your time at the company. It’s not a life raft; it’s a lead weight disguised as a flotation device.

Remember, PIPs are less about Personal Improvement and more about Preparing for Imminent Pruning. They’re certainly not about understanding or addressing the root causes of performance issues. Stay cynical, stay sane, and maybe start polishing that CV – preferably while job hunting on company time. After all, if they’re not considering your circumstances, why should you consider theirs?

The post The Ugly Truth About Performance Improvement Plans: Your Employer’s Last Laugh appeared first on I Like Kill Nerds.

View Details

Well, things are starting to make sense to me. Have you ever had a revelation that was confronting but then made complete sense? That’s where I am at.

I’ve been a programmer for 15 years and counting. I love what I do. Even after all this time, I still wake up excited and enthusiastic about my job and the industry. But over the last couple of years, coinciding with a big move and losing my usual support network, moving away from family; something shifted.

Hyperfocus Hero, Everyday ZeroI became aware of a strange pattern. I could hyperfocus, obsessing over complex coding challenges for hours, forgetting to eat or drink, and losing track of time. Yet, the simplest tasks, like adding a button or writing a test case, felt like pulling teeth. Even with looming deadlines, I’d tinker endlessly with perfectly functional features, sometimes breaking things right before release. It was as if my brain had two gears: hyperdrive and neutral, nothing in between.

This is how I have always worked. And fortunately, I have mostly always worked in ADHD friendly environments where I am not forced to confine myself to a neurotypical environment and work style. My work style has been very compatible with most of the places I’ve worked at because I always get there in the end and people seem to trust the process, even if I make little mistakes.

Until now.

Missing Pieces and Mental Traffic JamsIt wasn’t just work. I noticed other quirks. In meetings, I’d struggle to absorb information, even when I was trying to pay attention. Later, I’d be left with gaps in my understanding. I have a graveyard of unfinished side projects – bursts of inspiration followed by a loss of interest. And my brain is a constant idea factory, always churning.

I have notebooks that are full of ideas. I have a notebook that goes as far back as 2007 with ideas, some I started, some I didn’t. But, the ideas factory in my brain has always kept on churning, even when there are more pressing things to worry about. It’s something I have never been able to turn off.

Conversations are another challenge. I interrupt people, finishing their sentences, even when they’re the experts on the topic. I’ve always been like this, but it feels more pronounced lately. It’s hard to switch gears once I’m deep in a problem. People try to pull me away, and I get agitated.

The Impostor in the RoomMaybe it’s the ADHD, or maybe it’s just me, but another struggle I’ve faced is the nagging feeling of impostor syndrome. I’m on the Aurelia core team and work with it daily, but sometimes I feel like I’m faking it and that others know more than I do.

I feel like people see me as the “Aurelia guy,” expecting me to have all the answers. It’s a lot of pressure, and I often shoulder problems alone, afraid to admit when I’m stumped. It’s a vicious cycle of self-doubt. Despite knowing Aurelia well and Javascript, the stupidest and smallest things can cause me to trip and fall flat on my face.

I might know a thing or two, but the brain fog and being human means I don’t know everything.

The Details That DerailMy attention to detail isn’t always perfect and is not intentional. I’ve improved in the past few weeks as I’ve become more aware and actively worked on myself. But I can stare at a design for hours, meticulously checking measurements and text sizes, only to miss something obvious, like a border or font weight or changed wording.

To others, I might seem lazy or inattentive, but the truth is, I am trying to get the details right. Sometimes, things don’t click or compute for me. Sometimes, important steps get missed in the process (the context around a UI feature is the way it is or steps to get there). Even the times when I spend a lot of effort to make sure the details are right, there is a good chance something will be missed.

The downside is that despite self-implementing some coping strategies, my psychologist says that because I think differently, adapting a neurodivergent brain to neurotypical processes is not sustainable in the long term. Things are going to have to change, and the processes around me need to accommodate how I work.

I need specifics for my tasks, checklists, and details for any task that relies on remembering a meeting or previous task.

Sadly, a lot of places are not ADHD friendly. The processes and style of working are oriented towards neurotypical people who can work with little detail, who can get things done in a timely manner, who can remember information from meetings and not be so forgetful. We live in a world where some assume everyone else is like them.

The Fog of ForgetfulnessMy short-term memory is a sieve. I forget things people tell me moments later. If I’m not actively working on a task, it might as well not exist. My wife will ask me to bring laundry downstairs, and I’ll completely forget. It’s frustrating for both of us.

I leave the car keys in the car when I get out of it. I lose my wallet and phone all the time. My wife can tell me things about the morning routine I will forget. Just the other day she asked me to give the kids breakfast, she even got it out for me. What I forgot was she said it was frozen and needed to be heated in the microwave. I gave it to them frozen.

Even sleep is a struggle. I’ll lie in bed, wanting to rest, but my mind races with everything I “need” to do. It’s exhausting. Even if I don’t have much caffeine.

The Diagnosis and a Glimmer of HopeFinally, realising I couldn’t go on like this, I sought help. I thought maybe I was burned out or had a work addiction. But my psychologist had another idea: ADHD.

At first, it was a shock. But the more she explained, the more pieces clicked into place. She reassured me that this wasn’t a flaw, just a different way of thinking. Many workplaces, with their rigid structures, aren’t built for ADHD brains. We’re not broken, just different.

She fast-tracked me for an assessment, and we’re starting to explore coping strategies. I’m hesitant about medication because my number one concern is losing who I am (I’ve been like this forever; I can’t imagine being different or my personality changing), so we’re focusing on non-medication approaches first. It’s early days, but I already feel relieved that I am not alone.

And honestly, I didn’t want it to be ADHD. It’s not that I hate labels, it’s just everyone says they have ADHD now and it makes me not want to be one of those people that says they have it (even if they do). But, despite how lucky I’ve been in my career, I need help to manage this, because I’ve learned it’s not normal. My psychologist says it’s, “your normal”, but many of these traits are not normal.

And being honest, I feel like my entire life persona and personality traits have been built around ADHD symptoms. My ability to talk until people go deaf, to talk so much that I sound insane, to go an entire day without eating or drinking. And then similarly, binge like I’ve been lost in the wilderness for days.

I just hope I get the strategies and treatment I need before I self-sabotage and jeopardise everything I’ve worked so hard for, because ADHD tends to make you self-sabotage, even if you don’t mean too.

If This Sounds Familiar…If any of this resonates with you, please reach out for help. Please don’t wait until it feels overwhelming. I wish I hadn’t. You’re not alone, and there’s support out there. ADHD isn’t a life sentence; it’s just another part of your identity. And that impostor? It doesn’t have to have a permanent seat at your table.

The post When Code Clicks, but Life Glitches: My ADHD Revelation appeared first on I Like Kill Nerds.

View Details

In this blog post, we’ll explore the concept of deep observation in TypeScript and learn how to create a deep observer using proxies. Deep observation allows you to track changes made to an object, including its nested properties, providing a powerful way to monitor and react to modifications in your data structures.

Understanding Deep ObservationDeep observation involves monitoring changes made to an object and its nested properties. When a property is modified, whether it’s a top-level property or a deeply nested one, you can capture and respond to those changes. This is particularly useful when working with complex data structures where changes can occur at various levels of nesting.

Leveraging Proxies for Deep ObservationTo implement deep observation in TypeScript, we can leverage the power of proxies. Proxies are a feature introduced in ECMAScript 6 that allows you to intercept and customise an object’s behaviour. By creating a proxy for an object, you can define traps that intercept and handle operations such as property access and modification.

Implementing the Deep ObserverLet’s dive into the implementation of the deep observer in TypeScript. We’ll start by defining a Callback type that represents the function to be called whenever a property is modified:

type Callback<T> = (obj: T, key: keyof T, value: any) => void; The Callback type is now generic, taking a type parameter T that represents the type of the observed object. This allows for better type safety and inference when defining the callback function.

Next, we’ll create the observe function that takes an object and a callback function and returns a new proxy for that object:

function observe<T extends object>(obj: T, callback: Callback<T>): T { const proxyCache = new WeakMap<object, T>(); function createProxy(target: T): T { if (proxyCache.has(target)) { return proxyCache.get(target)!; } const proxy: T = new Proxy(target, { set(target, key, value, receiver) { if (typeof value === 'object' && value !== null) { value = createProxy(value as T); } const result = Reflect.set(target, key, value, receiver); if (result) { callback(target, key as keyof T, value); } return result; }, get(target, key, receiver) { const value = Reflect.get(target, key, receiver); if (typeof value === 'object' && value !== null && !proxyCache.has(value)) { return createProxy(value as T); } return value; }, }); proxyCache.set(target, proxy); return proxy; } return createProxy(obj);} We create a WeakMap called proxyCache to cache the created proxies. This avoids creating multiple proxies for the same object, which can lead to unexpected behaviour. The WeakMap uses the original object as the key and the corresponding proxy as the value.

Inside the observe function, we define the createProxy function that takes the target object of type T and returns its proxy. Before creating a new proxy, it checks if a proxy for the target object already exists in the proxyCache. If it does, it returns the cached proxy instead of creating a new one.

The set trap uses Reflect.set to set the value on the target object, ensuring that the default behaviour is preserved. It also checks the result of Reflect.set before invoking the callback function to ensure that the property was successfully set.

The get trap uses Reflect.get to retrieve the value from the target object. If the value is an object and doesn’t have a corresponding proxy in the proxyCache, it calls createProxy to create a new proxy for the nested object.

After creating the proxy, it is stored in the proxyCache using proxyCache.set(target, proxy). This ensures that subsequent accesses to the same object will reuse the existing proxy.

Usage ExampleNow, let’s see how we can use the deep observer in action:

interface Person { name: string; age: number; address: { street: string; city: string; };}const data: Person = { name: 'John', age: 30, address: { street: '123 Main St', city: 'New York', },};const observedData = observe(data, (obj, key, value) => { console.log(`Property "${key}" changed to:`, value);});observedData.name = 'Jane'; // Logs: Property "name" changed to: JaneobservedData.age = 31; // Logs: Property "age" changed to: 31observedData.address.city = 'Los Angeles'; // Logs: Property "city" changed to: Los Angeles In the usage example, we define an interface Person to represent the structure of the observed object. We then create an instance of Person called data and pass it along with a callback to the function.

The observe function infers the type of data as Person based on the provided type annotation. This ensures that the obj parameter in the callback function is of type Person, and the key parameter is of type keyof Person, providing strong typing and type safety.

ConclusionCreating a deep observer in TypeScript using proxies provides a powerful way to track changes in objects, including nested properties. By leveraging proxies and incorporating the suggested improvements, we can enhance the deep observation implementation’s type, safety, performance, and correctness.

Feel free to experiment with the improved deep observer implementation and explore further possibilities of proxies in your TypeScript projects.

The post Creating a Deep Observer in TypeScript appeared first on I Like Kill Nerds.

View Details

With the release of Aurelia 2 Beta 15, there are some important changes to be aware of regarding decorators. This update brings Aurelia 2 into compliance with the Stage 4 TC39 decorators proposal, resulting in significant differences in how decorators work compared to previous versions.

One notable change is that inline decorators for injection on constructors are no longer supported. For example, the following syntax is no longer valid:

constructor(@IApi readonly api: IApi, @IRouter private router: IRouter) { } Instead, to handle injection, you can define a class property and use the resolve function from the aurelia package. Here’s an example:

readonly api = resolve(IApi); Make sure to import the resolve function from the aurelia package at the top of your file.

Another important note for TypeScript users: remove the following lines from your tsconfig.json file:

"emitDecoratorMetadata": true,"experimentalDecorators": true, These settings are no longer necessary with the updated decorator implementation in Aurelia 2 Beta 15.

The post PSA: Aurelia 2 Beta 15 Introduces Breaking Changes to Decorators appeared first on I Like Kill Nerds.

View Details

Let’s face it: React’s popularity is a classic example of being in the right place at the right time.

When it first hit the scene, the web development world desperately needed a saviour. Developers were drowning in the complexities of AngularJS, with its notorious digest cycle and performance issues that made building with Angular a nightmare. Along came React, with its fancy virtual DOM and declarative approach, and suddenly, everyone was singing its praises.

With its unidirectional data flow and simplistic approach to building component-driven UIs, React was much better than what AngularJS or other frameworks were selling us at the time.

But let’s be real; if React were launched in 2024, it wouldn’t stand a chance. The web has evolved, and we now have native solutions like web components supported in all major browsers. Libraries like Lit have emerged, offering a lightweight, standards-based approach to building UIs. React’s once-revolutionary features are now just par for the course.

So why is React still so popular? It’s simple: the community.

React has cultivated a massive ecosystem of packages, tools, and resources that developers can’t seem to live without. It’s like a drug dealer who has gotten everyone hooked on their product. The React ecosystem has something for every need, from state management libraries to testing frameworks. And with so many subject domain experts contributing their knowledge, it’s no wonder developers are reluctant to break free from React’s grip.

But here’s the thing: React’s community has also become its own worst enemy. As it has grown, the ecosystem has become a bloated, complicated mess. Hooks once hailed as game-changers, allow developers who don’t fully understand them to shoot themselves in the foot.

And don’t even get me (or countless others in the community) started on React Server Components. The controversy surrounding this new addition has divided the community, with some hailing it as the future of React and others seeing it as an unnecessary complication.

The truth is that React has become a victim of its own success. It has grown into a behemoth that is becoming increasingly difficult to tame. And yet, developers continue to cling to it like a security blanket, afraid to venture into the unknown.

Let’s be honest: React is still a worthwhile option for many projects. It has a proven track record and a vast ecosystem that can make development faster and easier. It’s like that reliable old car that gets you from point A to point B, even if it’s not the flashiest ride on the block. But just because something is reliable doesn’t mean it’s the best choice forever.

There are other options, and it’s time for developers to open their eyes and embrace them. Web components and libraries like Lit offer a simpler, more standards-based approach to building UIs. They may not have the same hype and buzz as React, but they get the job done just as well, if not better. Despite its complexity, Angular offers comfort with its more verbose, rigid guardrails for developing apps. And, of course, arguably one of the best options around right now: Svelte. Of course, there are many others.

But here’s a thought: Would web components be as widely supported as they are today, or would competing libraries be as good if React hadn’t come along and shaken things up? It’s a chicken-and-egg situation. React’s popularity undoubtedly pressured browser vendors to improve their native solutions for building UIs and competing libraries to improve performance and APIs.

In a way, React’s success may have inadvertently paved the way for its own potential demise. It’s like the artist who inspires a new generation of musicians, only to be overshadowed by them later on.

So, is React’s popularity deserved? I’ll let you be the judge. But one thing is certain: if React were launched today, it would have a harder time convincing developers to jump on its bandwagon.

The post React’s Popularity: A Product of its Time or Enduring Success? appeared first on I Like Kill Nerds.

View Details

It’s a question that has haunted the minds of philosophers, scientists, and conspiracy theorists for ages: are we truly native to Planet Earth, or could we be the extraterrestrial visitors we’ve been searching the stars for all along? While it may sound like an outlandish theory from the depths of science fiction, there are some astonishing pieces of evidence that suggest the possibility of humans being the real aliens. Buckle up and prepare to have your worldview shattered as we dive deep into this mind-bending hypothesis.

It’s a question that has haunted the minds of philosophers, scientists, and conspiracy theorists for ages: are we truly native to Planet Earth, or could we be the extraterrestrial visitors we’ve been searching the stars for all along? These are the kind of thoughts that pop into my head from time to time.

While it may sound like an outlandish theory from the depths of science fiction, there are some astonishing pieces of evidence that suggest the possibility of humans being the real aliens. Usually I would let these strange thoughts dissipate, but ultimately decided to explore this more and write them down.

Are humans the aliens?

Firstly, let’s look at our planet from an outsider’s perspective. Earth is teeming with an incredible diversity of life, from the tiniest microbes to the gargantuan blue whales. Every creature seems to fit perfectly into the intricate web of ecosystems that blanket our world. Every species has evolved to thrive in its specific niche, except one glaring outlier: humans. We’ve spread to every corner of the globe, adapting to environments far outside our biological comfort zone through sheer ingenuity and technology. No other creature has achieved such planetary dominance. It’s almost as if we aren’t built for this world, but rather learned to bend it to our will as resourceful outsiders.

Secondly, our intellectual capabilities far exceed the demands of mere survival. We wield complex language, create art and music, ponder our existence, and reach for the stars. All of this brainpower seems overkill for just another Earth-dwelling creature. Why would evolution grant us such immense cognitive abilities if our sole purpose was to live and die on this lonely rock? Perhaps our minds were shaped by a more challenging origin, one that required us to be smart enough to traverse the cosmos itself.

Furthermore, many ancient civilizations worldwide have origin stories depicting their ancestors coming from the heavens or descending from the sky. These tales have been dismissed as primitive mythology, but what if they are actually distant echoes of our true extraterrestrial heritage? Could these legends be preserving a kernel of truth from a time when our alien ancestors first set foot on Earth?

Some proponents of this theory even suggest that our genetic code could hold clues to our unearthly origins. The human genome contains numerous segments of “junk DNA” that don’t seem to serve any clear biological purpose. Could they be remnants of an alien genetic engineering program, perhaps designed to help us adapt to Earth’s environment? As we continue to decode our DNA, we may uncover more evidence that we aren’t quite as homegrown as we believe.

Of course, extraordinary claims require extraordinary evidence, and the notion of humans being extraterrestrial colonizers is far from proven. It remains a fringe theory in scientific circles. But the fact remains that we are a peculiar outlier among Earth’s lifeforms, wielding capabilities and aspirations that seem to reach beyond the confines of our blue marble.

As we continue to scour the universe for signs of intelligent life, perhaps we should also look inward and question our own origins. The truth may be far stranger and more incredible than we ever dared to imagine. In our relentless search for aliens, we could end up finding ourselves.

I have joked about the possibility Elon Musk is an alien and the reason he is building satellites and rockets is because he is trying to get back home. Maybe Elon is just more in touch with his inner alien than the rest of us.

Next time you gaze up at the stars, ponder this mind-bending possibility: what if we’re the aliens we’ve been searching for all along?

The post Humans: The Extraterrestrial Invaders of Planet Earth? appeared first on I Like Kill Nerds.

View Details

Remember the 1990s when Microsoft was the big bad wolf of the tech world? Their iron-fisted control over the PC ecosystem led to a massive antitrust case and made Bill Gates public enemy #1 for a while.

Well, it looks like Apple didn’t learn from Microsoft’s mistakes because it’s now following the same playbook with the iPhone. And surprise, surprise—the antitrust cops are knocking on Cupertino’s door.

Glorious leader Tim Cook

Apple runs the iPhone like Kim Jong-un runs North Korea. It’s their way or the labour camp highway. Want to offer an app that competes with an Apple service? Get ready for your app to mysteriously get “caught in review” or be banished from the App Store. Want to let users install apps from outside the walled garden? Ha! Not a chance, comrade. The App Store is the only game in town, and Apple gets a juicy 30% cut for everything that happens there.

For years, Apple has argued this dictatorial control is for our own good. That it keeps the iPhone “safe and trusted.” But let’s be real. Having a single gatekeeper pick the winners and losers is fucking terrible for competition and innovation. And you know what happens when competition and innovation get choked out? Prices go up, quality goes down, and consumers get screwed.

It’s the same playbook that got Microsoft into so much hot water. Remember when they forced PC makers to bundle Internet Explorer and squash Netscape? How they deliberately broke compatibility with non-Microsoft products? It’s deja vu all over again, except this time, it’s happening on the device in your pocket instead of your desk.

But the jig may finally be up for Emperor Cook and his merry band of single-party apparatchiks. The Department of Justice has seen enough and is reportedly about to sue Apple for antitrust violations

. This comes on the heels of Apple being slapped with a $1.8 billion fine in Europe for squeezing out Spotify and other streaming music providers. The wall around Apple’s garden is starting to crumble.

Look, I’m not saying Apple is actually the Chinese Communist Party (although have you seen those Apple Stores? The minimalism is a bit eerie). And there are legit arguments for why some level of control can benefit users. But when your grip squeezes so tightly that you’re breaking the fingers of competitors, it’s clearly gone too far. Imagine if the government was the only party allowed to approve what books you could read! We’d call that censorship. When Apple does it for apps, it’s just “curation.”

Just like the Soviet Union eventually fell, the Apple regime will need to open up. They’re on the wrong side of history here. Developers are fed up, the government has smelled blood, and users are starting to question whether being stuck behind Apple’s Great Firewall is worth that blue iMessage bubble. Something’s gotta give.

The next few years are going to be a wild ride as the last superpower of the tech world faces its reckoning. It’s 1989 all over again, and Apple is the Berlin Wall. Tear down this wall, Tim Apple!

The post Tim Cook’s Little Red App Store: A Manifesto for Monopoly appeared first on I Like Kill Nerds.

View Details

JavaScript has been around for over 25 years, yet it’s more popular and dominant than ever. Some love to hate it, others grudgingly put up with it, but let’s cut through the bullshit – JavaScript has firmly cemented itself as the one true king of programming languages. And its reign looks set to continue for a long time yet.

First, there’s the ubiquity. JavaScript is fucking EVERYWHERE. It runs in every browser on every device. It’s the default language of the web. And with Node.js, it’s busted out of the browser to conquer the server side, too. You can’t swing a cat without hitting some JavaScript. It’s like the Starbucks of programming – inescapable but also weirdly comforting in its consistency.

Then there’s the ecosystem. Holy moly, the JavaScript ecosystem is a vast universe unto itself. There are more open-source packages on npm than grains of sand on a beach. Need to left-pad a string? There’s a package for that. Need a framework or library to build an app? Take your pick from React, Vue, Angular, Svelte, and god knows how many more. Half of them will probably be abandoned by the time you finish your project, but hey, that’s just the JavaScript way!

JavaScript is also stupidly versatile and flexible. You can write quick and dirty scripts, complex web apps, mobile apps, desktop apps, server backends, and even control IoT devices, all with JavaScript. Sure, it may not be the most elegant or efficient language for some of those use cases, but that’s not the point. Sometimes quantity has a quality all of its own. And JavaScript has quantity in spades.

The best proof of JavaScript’s kingly status is that it won’t die, no matter how much some devs wish it would. Some have tried to come for the crown, but JavaScript saw them off one by one. Even WebAssembly, which some thought would finally dethrone JS, has effectively been pressed into service as JavaScript’s plucky servant instead. Resistance is futile.

So, let’s give JavaScript its dues. Like it or loathe it, this scrappy little language has fought its way to the top and reigns supreme. It may not be the hero we wanted, but it’s the one we deserved. Long live the king, baby!

The post Hail to the King, Baby: Why JavaScript Reigns Supreme appeared first on I Like Kill Nerds.

View Details

I’m always looking for fun little coding challenges that are not full projects, and I thought I would do a fun little licence key generator using Typescript.

Step 1: Setting Up the Project

First, create a new directory for your project and navigate into it using your terminal. Then, initialise a new TypeScript project by running the following command:

npm init -ynpm install --save-dev typescript Step 2: Configuring TypeScript

To configure TypeScript, create a tsconfig.json file in your project’s root directory and add the following configuration:

{ "compilerOptions": { "target": "es6", "module": "commonjs", "outDir": "dist", "strict": true, "esModuleInterop": true }, "include": ["src"]} This configuration sets the target ECMAScript version to ES6, uses CommonJS modules, and specifies the output directory as dist, enables strict type checking, and includes the src directory for TypeScript files.

Step 3: Implementing the Licence Key Generator

Now, let’s write the code for the license key generator. Create a new file named licence-key-generator.ts inside the src directory and add the following code:

export const generateLicenceKey = (format: string): string => { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; const getRandomChar = (placeholder: string): string => { switch (placeholder) { case "X": return chars[Math.floor(Math.random() * chars.length)]; case "N": return String(Math.floor(Math.random() * 10)); default: return placeholder; } }; return Array.from(format, getRandomChar).join("");}; In this code, we define a generateLicenceKey a function that takes a format parameter representing the format placeholder for the license key. It uses a getRandomChar function to generate a random character based on the placeholder. The Array.from method is used to create an array of characters based on the format, and the join method is used to concatenate the characters into a single string.

Step 4: Using the Licence Key Generator

To use the licence key generator, create a new file named index.ts in the src directory and add the following code:

import { generateLicenceKey } from './licence-key-generator';const formatPlaceholder1 = "XXXNXN-NXXNN-XXXXX-XXXNN-XXXNN";const formatPlaceholder2 = "NNNNNN-NNNNN-NNNN-XXXNN";const licenseKey1 = generateLicenceKey(formatPlaceholder1);const licenseKey2 = generateLicenceKey(formatPlaceholder2);console.log(`Licence Key 1: ${licenceKey1}`);console.log(`Licence Key 2: ${licenceKey2}`); In this code, we define two format placeholders and generate licence keys based on those formats. Finally, we log the generated licence keys to the console.

Step 5: Compiling and Running the Code

To compile the TypeScript code, run the following command in your terminal:

npx tsc This command compiles the TypeScript files in the src directory and outputs the JavaScript files in the dist directory.

To run the code, use the following command:

node dist/index.js You should see the generated license keys printed in the console.

And there you have it! You’ve successfully built a licence key generator using TypeScript. Feel free to customise the format placeholders and experiment with variations to suit your needs.

The code in action

You can see the above code in action below.

The post Generating Licence Keys with TypeScript appeared first on I Like Kill Nerds.

View Details

Let’s talk about the elephant in the room—or, should I say, the AI in the code editor.

Recently, NVIDIA’s big cheese, Jensen Huang, made waves with his take on the future of coding at the World Government Summit in Dubai. His hot take? In the face of AI’s rise, maybe kids shouldn’t learn to code. Instead, they should focus on fields where humans still have the upper hand, like biology or even farming.

Now, before we all trade in our keyboards for tractors or start majoring in photosynthesis, let’s take a step back to evaluate the potential impact of AI properly. Things have been blown way out of proportion.

AI and Coding: Friends or Foes?First, let’s get straight: AI is pretty smart. It can whip up a piece of code and debug faster than you can say “syntax error,”. What AI can do is remarkable; it is already saving developers time. It already has this remarkable ability to scaffold code for you.

But here’s the kicker: AI, for all its tricks, still can’t grasp the big picture. It might give you a piece of code that looks good on paper but lacks the nuance of understanding project complexities, dependencies, or why that one line of code is more poetry than prose. That’s where the human touch comes in—because sometimes, you need to read between the lines (of code).

We are still not at the point where AI can even contextually understand an entire codebase. While you could argue many devs don’t either, after working with a codebase for a while, you tend to learn over time where everything is. AI is getting better at context, but it’s still limited and probably will continue to be limited until they can get the cost down.

Imagine you’re trying to solve a Rubik’s Cube that changes colour every two seconds. That’s what coding is like—solving puzzles that don’t play fair. AI can spot patterns and follow rules, but when it comes to out-of-the-box thinking or genuine eureka moments, it’s still sitting in the audience, not performing on stage.

What Jensen Really MeantNow, back to Jensen and his leather jacket wisdom. Perhaps what he’s getting at isn’t that coding is going extinct but rather that the landscape is changing. It’s not about coding less; it’s about thinking more—leveraging AI to do the heavy lifting so we can focus on the problems that need a human touch. Think of it as upgrading from a bicycle to a motorcycle. Sure, it’s faster and does some of the work for you, but you still need to know how to ride it.

Remember when calculators first hit the scene, and everyone thought math teachers were done for? Spoiler alert: math is still around, and so are math teachers. The same goes for computers. They didn’t replace jobs; they made new ones. And let’s face it, they also made binge-watching a thing (blessing or curse? You decide).

AI: The Ultimate SidekickSo, is AI going to replace coders? Nah. It’s more like Batman and Robin. Sure, Batman gets the spotlight, but Robin’s got his back, making the dynamic duo unbeatable. AI is here to take the grunt work off our plates, leaving us free to tackle the bigger, badder problems. And who knows? With AI as our sidekick, maybe we’ll all find a bit more time to rock those leather jackets that Jensen loves to wear.

Wrapping Up: The Future Is CollaborativeIn the grand scheme of things, coding isn’t going anywhere. It’s just getting a facelift. AI is the new tool in our kit, not a replacement worker. As we move forward, it’s all about collaboration—humans and AI working together to create, innovate, and maybe save the world a little.

So, don’t hang up your coding hat just yet. Instead, maybe consider adding a leather jacket to your wardrobe. If Jensen’s right about one thing, the future of coding will be one stylish ride. And who knows? Maybe leather jackets will become the new coder uniform. If that’s the case, sign me up!

The post Why AI Won’t Make Devs Obsolete: Navigating the Future of Code, Creativity, and Maybe a Leather Jacket appeared first on I Like Kill Nerds.

View Details

WordPress, a flexible content management system, allows various customisations to enhance user experience and streamline site management. One common requirement is to provide users with an easy and intuitive way to log out. This guide explores a best practice approach to adding a logout link directly within a WordPress menu, utilizing hooks and filters for a clean and efficient implementation.

Opting for a menu item logout link over a separate logout page or relying on plugins offers several advantages:

  • Seamless User Experience: Integrates directly with the site’s existing navigation, making it intuitive for users.
  • Performance: Reduces server load by avoiding additional page loads.
  • Maintainability: Leverages WordPress core functions, ensuring compatibility and ease of updates.

How to Implement1. Adding a Placeholder Link to Your MenuFirst, navigate to Appearance > Menus in your WordPress dashboard. Create a custom link with the URL set to #logout and the link text as “Logout”. Add this to your menu and save.

  1. Modifying functions.phpNext, enhance your theme’s functions.php file to dynamically replace the placeholder link with the WordPress logout URL and handle redirection post-logout.

function custom\_logout\_link($items, $args) { foreach ($items as &$item) { if ($item->url === '#logout') { $item->url = wp\_logout\_url(home\_url()); // Redirect to home after logout } } return $items;}add\_filter('wp\_nav\_menu\_objects', 'custom\_logout\_link', 10, 2); This snippet searches the menu items for the placeholder URL and replaces it with a dynamic logout URL that WordPress generates. The wp_logout_url() function is used here to ensure that the logout process is handled securely, with a redirection to the homepage after the user logs out.

Best Practices and Considerations Security: This method uses WordPress’s functions, ensuring that logout actions are secure and follow best practices. * Customization: You can modify the redirection URL in wp_logout_url() to point to a custom page or external URL after logout, offering flexibility in how you manage user flow. * Theme Updates*: If you’re modifying a third-party theme, consider creating a child theme for these changes to prevent losing customizations on theme updates.

ConclusionIntegrating a logout link within your WordPress menu is a straightforward, user-friendly, and efficient method to enhance your site’s navigation and user experience. By following WordPress best practices and utilizing its built-in functions, you create a robust and maintainable solution, keeping your site clean, user-friendly, and secure.

The post Implementing a Logout Feature in WordPress Menus appeared first on I Like Kill Nerds.

View Details

The wait is finally over. Google has debuted Gemini Ultra 1.0, its GPT-4 competing model powering Gemini (formerly Bard), and it’s time to dig in and see if it lives up to the promise of being on the same level as GPT-4 or falls short.

I have been anticipating Gemini Ultra since it was announced in December 2023. I’ve grown frustrated with the lack of stability and constant issues with GPT-4. I use ChatGPT and the GPT-4 API. I also use Microsoft Copilot Pro (my AI subscriptions are starting to add up now).

It’s possible the rebranding might just be lagging behind, but my first use of Gemini Ultra, the Bard naming, is still being used under the moniker Bard Advanced. So, I’m not sure if I jumped in earlier than Google flipping the switch, but the name Bard is still around. As we knew in the leaks prior, Bard Advanced is bundled in with a Google One 2tb subscription.

Sure enough, I was early. It changed to Gemini from Bard shortly after posting this.

The first noticeable difference in Gemini Advanced is its blazing speed. My queries are met with an instant, nearly seamless flow of text. Compared to GPT-4, there’s less sense of waiting for a response. Instead, Gemini Advanced feels like it’s genuinely thinking alongside me. The way it responds also feels softer and humanlike, something I noticed with Gemini Pro.

The refinement that shines through in Gemini Advanced is, frankly, impressive. It flawlessly adapts to my prompts, whether I’m requesting a lighthearted joke or a complex technical explanation. This fluidity in tone and complexity feels a significant step forward in AI development. The polished language and well-structured output leave little room for misunderstanding or misinterpretation.

The coding prompts I ran through Gemini Ultra resulted in code that ran the first time without issue. It seems to accurately produce code that uses modern best practices and how I would write my code for code like Typescript and Javascript.

One of the frustrations with GPT-4 was the usage caps. Long, in-depth conversations would suddenly hit a wall. To my delight, this was nowhere to be found with Gemini Advanced. Unless Google has set this high, I hit Gemini with more than 40 prompts, and I didn’t hit a wall. That is where OpenAI dropped the ball: usage caps.

It’s not all sunshine and rainbows. Gemini does appear to be quite prudish, but having said that, so is ChatGPT 4 these days, too.

When it said “absolutely not”, I pictured it in a British private school teacher’s voice, like a character from Harry Potter. “Absolutely not, Mr Potter!”

Fortunately, I primarily use AI for writing and ideas, sometimes code, so these safety alignment guardrails don’t affect me. I’m not using AI to push boundaries or do anything that would cause strong restrictions to be a concern. But for some, I can understand why the strict nature of not complying with certain prompts would be a hindrance.

For giggles, I asked ChatGPT the same thing, and while I wasn’t lectured as much as Gemini Advanced did, it didn’t comply either (as expected):

While Gemini Ultra is impressive, there are downsides.

  1. A 32k context window. In GPT-4 Turbo, the context length is 128k. The extra context length can make it nice to work with multiple pages and files.
  2. Gemini Advanced seems to excel in creativity, but it hallucinates quite a bit. While GPT-4 hallucinates too, it feels like Gemini is prone to more hallucinations.
  3. Image generation is terrible. While Gemini is a step above what Google previously had, the image generation is on par with DALL-E 2, but nowhere near DALL-E 3.
  4. Image recognition is also terrible. Despite the focus in their initial marketing showcasing amazing image recognition, Gemini Ultra 1.0 is nowhere near that level. It’s so bad it makes me wonder if Gemini Ultra is being used for the image generation yet. ChatGPT wins in this department. You also cannot upload multiple images for recognition at once.
  5. Gemini Ultra is not very good at reasoning. I find GPT-4 is exceptional at reasoning tasks, it is still the standard. And while Gemini Ultra is arguably a huge step up from Pro, it doesn’t feel like the gigantic game changing leap we expected.
  6. It’s too censored and safe. The inappropriate adult joke aside, anything involving violence, political, religious or spiritual content even within the bounds of creative expression like a poem or short story will trigger Gemini and give you a lecture. Either it thinks you’re trying to produce political propaganda to interfere with elections, spread hate or self harm.
  7. It’s too expensive for what it is right now. Gemini Advanced is priced similarly to ChatGPT Plus and while Google does not have usage caps (as far as I can tell), it falls short of what ChatGPT offers for the same price. It’s not quite the ChatGPT killer, so don’t cancel your subscription just yet. To Google’s credit, they do offer a two month trial through Google One and you get other nice things like 2tb of storage. If Google integrated this into Google suite apps like Sheets and Docs (like Microsoft Copilot) it might be more value for month and I don’t doubt those are coming, just right now it’s the chat app you’re paying for.

It is still early days, but I can confidently say that Google appears to have delivered on multiple fronts. As long as they don’t go down the path of OpenAI and handicap themselves with model tweaks and limitations, I can see myself using Gemini more and ChatGPT less.

Time will tell.

The post A Review of Gemini Advanced (powered by Gemini Ultra 1.0) appeared first on I Like Kill Nerds.

View Details

I switched from using Vercel for my new web projects to Railway a while ago.

When the AI space heated up, vector databases became the new hotness. And a lot of the available choices are quite expensive or restricted. Pinecone is probably one of the better-known vector database providers and the favoured choice of many GPT users.

Finally, Railway now supports pgvector for PostgreSQL. You can use PostgreSQL as a vector database on Railway and ditch using multiple providers, as I was. I was using Supabase, which did the job nicely, but not having all my infrastructure in one dashboard was annoying.

The post Railway Now Has pgvector Support appeared first on I Like Kill Nerds.

View Details

I saw my favourite band, Thrice, recently at their Brisbane show, and unlike other Australian tours, they did a VIP thing where you could pay extra to meet the band, a Q&A, and a couple of songs.

Naturally, one of the questions that came up at the Q&A (presumably at all of their VIP meet and greets) is the subject of Horizons/West, the long-awaited sister record to Horizons/East, released in 2021.

Sadly, Dustin said the record is currently in pieces, and they’re trying to put it all together and that it most likely won’t be out until late 2024. This would mean possibly three years since Horizons/East was released.

And seeing the boys play The Artist In The Ambulance in its entirety was also an awesome experience and a few fan favourites. Dustin is sounding better than ever. the accousticy version of Stare At The Sun he played with Teppei at the VIP pre-show was goosebump worthy.

So, we know Horizons/West is coming, but sadly, it looks like it won’t be in 2023 like most were expecting.

The post An Update On Thrice’s Horizons/West Record From Their Recent VIP Meet & Greet appeared first on I Like Kill Nerds.

View Details

The prospect of an AI tool that could learn from my blog and writing style and then write like me was tantalising. So, when I was being aggressively advertised reword.com – my curiosity was peaked. Sadly, reword is a typical GPT wrapper. It’s a great idea, but it’s not anything special. It’s akin to those […]

The post Don’t Bother With Reword.com appeared first on I Like Kill Nerds.

View Details

The realm of web development is teeming with choices, each technology vying for developers’ attention. On one hand, powerful libraries like React have revolutionised how we build web applications. On the other, there are Web Components—although not as “foundational” as one might think, given that they’ve been universally supported by browsers only since 2020. Yet, […]

The post Stop Comparing Web Components to React: The Trap of Library-Centric Criticism appeared first on I Like Kill Nerds.

View Details

The Aurelia 2 Task Queue is a robust scheduler designed to address various challenges associated with timing issues, memory leaks, race conditions, etc. Unlike its predecessor in Aurelia 1, the Task Queue offers advanced control over synchronous and asynchronous tasks. Comparison with Aurelia 1 While the term “task queue” may be familiar to those who […]

The post Exploring The Aurelia 2 Task Queue appeared first on I Like Kill Nerds.

View Details

In Aurelia 2, lambda expressions bring a breath of fresh air to templating by enabling developers to write concise and expressive code directly within templates. A significant advantage of lambda expressions is that they allow developers to perform various operations without needing value converters, leading to cleaner and more maintainable code. This article explores lambda […]

The post Getting To Know Lambda Expressions in Aurelia 2 appeared first on I Like Kill Nerds.

View Details

As someone who’s spent countless hours behind the glow of my computer screen, weaving retro-futuristic textures and creating beats on FL Studio, music production isn’t new to me (even if I am not that good at it). So, when I decided to step out of my comfort zone and into the world of physical music […]

The post A Review of The Akai MPC Live 2 appeared first on I Like Kill Nerds.

View Details

In modern web development, managing reactivity—how parts of an application respond to changes in data—is paramount. Aurelia 2, a robust JavaScript framework, introduces an elegant way to handle reactivity through effect-based observation. This guide will explore what effect-based observation is, why you might want to use it, and how to implement it in your Aurelia […]

The post Harnessing the Power of Effect-Based Observation in Aurelia 2 appeared first on I Like Kill Nerds.

View Details

Aurelia 2, a modern front-end JavaScript framework, introduces a powerful feature called enhance that allows developers to breathe life into static HTML by binding Aurelia behaviours to existing DOM elements. If you worked with Aurelia 1, you might already be familiar with enhance functionality. This isn’t a new feature added to Aurelia. What is enhance […]

The post Working with enhance in Aurelia 2: A Comprehensive Guide appeared first on I Like Kill Nerds.

View Details

Playwright is exceptional for end-to-end testing. It can do so much, from interacting with forms to mocking server requests and a heap of other things. In this article, we’ll go over 12 tips and tricks (some you might already be aware of). 1. Parallel Testing Playwright makes it easy to run multiple tests in parallel. […]

The post 12 Playwright Tips and Tricks appeared first on I Like Kill Nerds.

View Details

I have been working with the web for a long time now. And like every other developer, I use frameworks and libraries to build most of my web applications. Over the years as web standards have emerged and solidified over the years, the web platform has become much more capable. One such standard is Web […]

The post Embracing Web Components appeared first on I Like Kill Nerds.

View Details

Custom web components have revolutionised web development by enabling encapsulation, reusability, and dynamic functionality. Combined with Aurelia 2, a robust and extensible framework, the possibilities for building rich, sophisticated applications are endless. A key feature of Aurelia 2 is its extensible Attribute Mapper, which bridges HTML attributes and JavaScript properties, enabling significant customization to meet […]

The post Extending Aurelia 2’s Attribute Mapper for Custom Web Components appeared first on I Like Kill Nerds.

View Details

Ah, the Neural DSP Quad Cortex, the proverbial golden child of the guitar modelling world. As we approach the two-year anniversary of my ownership, I find myself in a love-hate relationship with this awesome device. Let’s start with the good bits. The touchscreen and rotary stomps are nothing short of a revelation. Navigating through the […]

The post I Am Getting Fed Up With the Neural DSP Quad Cortex appeared first on I Like Kill Nerds.

View Details

Aurelia 2, the latest incarnation of the Aurelia framework, is packed with improvements and new features. Among these, the revamped template compiler stands out for its potential to significantly boost your productivity. This article takes a deep dive into the template compiler, focusing on functionality that allows developers to intercept and modify the compilation process […]

The post Become An Unstoppable Templating Wizard With Aurelia 2’s Template Compiler appeared first on I Like Kill Nerds.

View Details

In Aurelia 2 the @watch decorator allows you to react effectively to data changes in your application, from simple properties to complex expressions. Think of it as computedFrom (if you’re coming from Aurelia 1) but on steroids. Basics of @watch The @watch decorator in Aurelia 2 lets you define a function that will execute whenever […]

The post Unleashing the Power of the @watch Decorator in Aurelia 2 appeared first on I Like Kill Nerds.

View Details

Aurelia 2 has some awesome templating features that make creating dynamic and replaceable components a breeze. One of these features is the au-slot tag. This magic tag, combined with expose.bind and repeaters brings about a new level of control and flexibility for developers to create customizable components. In Aurelia 2 there are two types of […]

The post Working with au-slot in Aurelia 2: Creating a Repeater with Replaceable Components appeared first on I Like Kill Nerds.

View Details

Meta has released version 2 of its open-source Llama AI model and has caught many’s attention – but not entirely for the right reasons. Coming in a broad spectrum of sizes, from the 7 billion to an impressive 70 billion parameter models, Llama 2 certainly stands out. If you’re curious, you can experience the different […]

The post Unleashing the Llama: Is Meta’s Llama 2 Too Safe? appeared first on I Like Kill Nerds.

View Details

Since its launch, OpenAI’s GPT-4 has been the talk of the town, marking yet another milestone in artificial intelligence. However, over the past few months, there’s been a rising suspicion within the AI community that GPT-4 has been “nerfed” or subtly downgraded. Despite these concerns, OpenAI maintains its stance that nothing has changed that would […]

The post The Curious Case of GPT-4’s Drop In Quality: An In-depth Look into Recent Changes and Speculations appeared first on I Like Kill Nerds.

View Details

In the cutthroat world of web development, trends come and go faster than a blink of an eye. Yet amidst this constant churn, there has been one relentless narrative: the supposed downfall of PHP and its offspring, WordPress. But here’s the twist—despite the years of criticism, proclamations of their death, and the rise of shinier, […]

The post PHP and WordPress: The Undying Underdogs of Web Development appeared first on I Like Kill Nerds.

View Details

Have you ever found yourself startled by the uncanny resemblance between the smartphone in your hand and that of your mate’s, despite them being from entirely different manufacturers? You are not alone. This unsettling sameness is a symptom of a broader ailment plaguing the tech industry: homogenisation. Like a relentless tide, homogenisation has washed over […]

The post The Homogenised Hive Mind: The Detrimental Impact of Tech’s Uniformity appeared first on I Like Kill Nerds.

View Details

The knowledge cut-off for ChatGPT (including GPT-3.5 and GPT-4) is September 2021. This means that GPT is not aware of Midjourney. However, due to how large language models (LLMs) like GPT work, they can be trained with some prompts and produce the desired output. This means you can teach GPT what you want it to […]

The post How To Use ChatGPT to Create Exceptional Midjourney Prompts appeared first on I Like Kill Nerds.

View Details

Since OpenAI released its long-awaited Code Interpreter plugin for ChatGPT, I have been playing with it extensively. Throwing everything at it, from a zip file of a large repository and asking it questions to uploading spreadsheets and generating imagery. It appears that most people are using Code Interpreter for what it was intended for, working […]

The post Is ChatGPT Code Interpreter GPT-4.5 In Disguise? appeared first on I Like Kill Nerds.

View Details

As developers, we are always looking for ways to make our lives easier, and that often means bringing in third-party libraries and tools that abstract away the nitty-gritty details of specific tasks. Langchain is one such tool that aims to simplify working with AI APIs (in reality, it doesn’t). However, as we’ll discuss in this […]

The post You Probably Don’t Need Langchain appeared first on I Like Kill Nerds.

View Details

Prep time: 10 minutesCook time: 30 minutesCooling Time: 1 hourYield: Makes about 10-12 sticks I love the Darrell Lea Batch 37 liquorice. It’s distinctively liquorice, but the texture and flavour seem to be different to any other I have ever tasted. Looking at the ingredients, it seems to be a traditional liquorice recipe with a […]

The post Homemade Darrell Lea Batch 37 Inspired Liquorice Recipe appeared first on I Like Kill Nerds.

View Details

As whispers of an impending recession grow louder, it’s natural to feel a sense of trepidation. Economic downturns can be challenging, but they also harbour a less-told narrative of resilience, innovation, and opportunity. History has shown us that some of the most groundbreaking companies were born amidst economic turmoil. These tales of triumph serve as […]

The post Recession: A Golden Opportunity in Disguise appeared first on I Like Kill Nerds.

View Details

There has been a bit of talk about Lanchain lately regarding the fact it is creating a walled garden around AI apps and results in lock-in. In this post, we’ll debate the differences between Langchain and just using an official SDK. I assume you’re working with OpenAI, but we also have Anthropic and Hugging Face […]

The post Langchain vs OpenAI SDKs appeared first on I Like Kill Nerds.

View Details

In Aurelia 1, you could access the controller of an Aurelia component by accessing au.controller of an element. In Aurelia 2, there is a better way using the CustomElement.for method, which provided an element with a controller that will return it. You can also access a property on the element if you prefer using: element.$au['au:resource:custom-element'] […]

The post How to Access the Controller and Viewmodel of an Aurelia 2 Component appeared first on I Like Kill Nerds.

View Details

When will companies learn that despite some people wanting to be in an office, many people who have been given a taste of remote work during the pandemic don’t want to return to the office? One of Australia’s largest banks, Commonwealth Bank, conjured a storm of epic proportions last month when it announced it wanted […]

The post CommBank Employees Are Threatening to Quit if the Forced Return to the Office Mandate Goes Through appeared first on I Like Kill Nerds.

View Details

One of my favourite additions to Aurelia 2 is app tasks. These are framework-level entry points designed to allow you to run code at different points of the framework life cycle. Recently, while porting over an Aurelia 1 application to Aurelia 2, I encountered a unique use case where code was being run inside configureRouter […]

The post How to Programmatically Set Routes in Aurelia 2 Using AppTask appeared first on I Like Kill Nerds.

View Details

When migrating an Aurelia 1 application to Aurelia 2 recently, I had to deal with many routes I needed to convert tediously. As you might have discovered, the Aurelia 2 @aurelia/router is different to the Aurelia 1 router. Not wanting to change 50+ manual PLATFORM.moduleName values, I opted for a regular expression. I hate RegEx […]

The post A Regular Expression to Convert PLATFORM.moduleName in Aurelia to Aurelia 2 Compatible Route Syntax appeared first on I Like Kill Nerds.

View Details

There is a growing divide in a world filled with out-of-touch billionaires and misguided wannabes who follow their words as if they were holy scripture. On one side, we have the tech titans like Elon Musk, who believes that people are more productive in person and criticises those who advocate for work-from-home as being on […]

The post Remote Work Is a Hiring Advantage More Companies Should Capitalise On appeared first on I Like Kill Nerds.

View Details

Who else had this on their 2023 bingo card? In the midst of a global cost of living crisis, two tech titans have presented us with an unexpected yet entertaining proposition: a cage fight. Elon Musk, the audacious CEO of SpaceX and Tesla, has indirectly challenged Facebook’s Mark Zuckerberg to a cage fight. And funnily […]

The post Billionaire Brawl Alert: Musk vs Zuckerberg, Who Will Reign Supreme in the Octagon? appeared first on I Like Kill Nerds.

View Details

Well, this is sad news. Nestle has announced they will no longer be producing the beloved chocolate-covered chewy caramel treat Fantales, which have been around for almost a century. I have fond memories of eating these as a kid, and I still buy them occasionally. They are being discontinued because of declining sales and upgrades […]

The post Homemade Fantales Clone Recipe appeared first on I Like Kill Nerds.

View Details

In a move that caught everyone by surprise, Google recently announced the sale of Google Domains to Squarespace. To many, this strategic realignment came out of left field, providing a glaring clue about the shape of Google’s new vision. The seismic shift to prioritise artificial intelligence (AI) has raised questions about the fate of Firebase, […]

The post Google Sells Google Domains to Squarespace, is Firebase On the Chopping Block Next? appeared first on I Like Kill Nerds.

View Details

In Aurelia 1, you could access the controller and ViewModel of an element using au.controller and in Aurelia 2, it’s more of the same (except the properties are different). Here is how you get the controller and ViewModel of an element in Aurelia 2.

The post How to Get the Viewmodel of an Aurelia 2 Component appeared first on I Like Kill Nerds.

View Details

Recently while using the Material Components Web components in an Aurelia 2 application with Sass, I encountered an annoying issue where a warning would appear in my app. The warning appears to be harmless, but it’s annoying. The error appears as: Module Warning (from ./node_modules/sass-loader/dist/cjs.js): both $level and $color are required; received $level: ‘0’, $color: […]

The post How to Fix the Required $level and $color Parameters Warning in Webpack When Using Material Components Web appeared first on I Like Kill Nerds.

View Details

One of the most annoying things as a developer setting up a Mac is that files with a dot are hidden by default. Here is how to set them always to be visible: You can toggle them in Finder by using Command + Shift + . but having them show by default is a lot […]

The post How to Always Show Hidden Files in macOS Finder appeared first on I Like Kill Nerds.

View Details

Well, well, well, what do we have here? The guardians of Stack Overflow, those volunteer moderators who’ve turned the site into their personal fiefdom, are having a tantrum. As of June 5th, 2023, they’ve gone on a historic general moderation strike, joined by over 850 contributors and users​. Their beef? Stack Overflow, Inc. isn’t giving […]

The post I Have No Sympathy For The Stack Overflow Moderator Strike appeared first on I Like Kill Nerds.

View Details

Hold the phone, everyone. Martha Stewart, yes, that Martha Stewart, has decided to grace us with her hot take on remote work. Spoiler alert: she’s not a fan. Apparently, she believes you can’t possibly get everything done working part-time in the office and part-time from home. Martha, I hate to break it to you, but […]

The post Martha Stewart comes out swinging against remote work appeared first on I Like Kill Nerds.

View Details

It’s been a while since we’ve seen something completely new from Apple, and after years of speculation that Apple would launch a headset of some kind, it has finally been announced (one of the worst kept secrets ever because we knew it was coming). The Vision Pro is undeniably impressive. With 4K displays, infrared cameras, […]

The post Apple announces Vision Pro, and yep, it’s expensive appeared first on I Like Kill Nerds.

View Details

The Metaverse, a term coined from Neal Stephenson’s 1992 techno-dystopian novel “Snow Crash,” has been a topic of discussion in the tech industry for years. It was envisioned as a new frontier, a virtual reality space where users could interact in a simulated universe. Meta, formerly known as Facebook, aimed to lead this virtual revolution by building a future where work and social interactions could be conducted from anywhere in an immersive 3D world.

However, in 2023, the company that championed the Metaverse is ironically pushing its employees out of the virtual world and back into the office. The irony is stark, as the company that boasted about creating a revolutionary technology now seems to be forcing its employees to revert to old ways of working.

As part of Mark Zuckerberg’s plan to cut costs, shake up the company culture, and redirect focus in response to a slower growth in the tech industry, Meta has laid off a total of 21,000 employees in 2023 during its “year of efficiency.” Unfortunately, the layoffs have had a negative impact on employee morale, leaving many uncertain about their futures and some reportedly unsure of what to focus on. This uncertainty also extends to the company’s return-to-office plans, which have been described as providing “consistent expectations and guidelines” for when and how often employees need to be in the office in person.

Starting this fall, Meta employees, who are assigned to a specific office, are expected to work on site at least three days per week. While Zuckerberg insists that the company is “committed to distributed work,” the new office policy might exacerbate the already existing morale crisis at Meta.

All of this is happening while the Metaverse, Meta’s virtual reality-fueled dream, appears to be failing. Since Facebook’s rebranding to Meta and its big bet on the Metaverse, Meta’s value has plummeted. The Metaverse itself has been criticized for its apparent lack of innovation. Celia Pearce, an associate professor of game design at Northeastern, even compared it to the virtual worlds of the mid-90s. She calls out Meta’s “lack of awareness of what’s actually going on now and what happened before” in non-game virtual spaces. This suggests that the company missed the mark in terms of creating something that would appeal to the right audience.

Meta’s insistence on returning employees to physical offices while the Metaverse, a concept that was supposed to eliminate the need for physical presence, is failing, paints a picture of a company at odds with itself. The irony is certainly not lost on those of us observing from the sidelines. Despite the missteps, the core idea of the Metaverse remains appealing, with the potential for creating special connections and communities. It’s just a matter of figuring out how to get there, something that Meta seems to be struggling with thus far. However, rumors of an Apple augmented/virtual reality headset might revive the concept.

The post Meta’s Irony: From Metaverse to Mass Layoffs appeared first on I Like Kill Nerds.

View Details

It’s 2023, and a war rages on. On one side are businesses and mega-corporations, and on the other are the workers. While everyone argues about the future of work and the benefits of having employees back in the office (even in a hybrid capacity), the world around us is figuratively burning.

Despite inflation peaking in most countries, it remains quite high. In Australia, the CPI rose to 6.8 per cent in March. While this is not as high as the 30-year record set at the end of 2022, when it hit 8.4 per cent, it is still stubbornly high. To put this into context, the Reserve Bank of Australia has a target of 2 to 3 per cent, which we are far from achieving. The current cash rate is 3.8%, combined with a rental crisis and inflated house prices.

As companies mandate full-time or even part-time return to the office, the ongoing cost of living crisis shows no signs of subsiding. Employees who are being forced back to the office will now have to spend more on their commutes, effectively taking a pay cut of around 2-3%. This is in addition to increased costs for goods and services.

Commuting can be a significant expense for many people. The cost of commuting includes expenses such as fuel, tolls, and public transportation fees, which can add up quickly. In Australia, public transportation is notoriously expensive. Additionally, there is the added cost of wear and tear on your vehicle if you drive, as well as the lost time of the commute itself.

When you work in an office, there is often pressure to participate in social activities, such as going out to lunch with coworkers and buying coffee or other hot beverages. As someone who has worked in an office for a significant portion of their career before transitioning to remote work, I can attest that this cultural pressure is real and can be costly.

As a homeowner, you may feel the pinch of increased mortgage payments, skyrocketing electricity bills, and rising grocery prices. Many companies use inflation as an excuse to raise prices, a phenomenon known as “greedflation.” Even if you’re a renter, you must pay for electricity and water.

The world is currently on shaky economic ground. Companies are ending their once-permanent remote work policies, causing workers to effectively take a pay cut on top of their already stagnant wages (real wage figures in Australia are not great). If having your workers back in the office is important to you, it’s time to start giving them meaningful pay increases. Otherwise, you’re just asking them to make even more sacrifices.

Isn’t it ironic that companies experienced record levels of productivity and profit during the pandemic when everyone was working remotely, but now that it’s apparently a problem? Something doesn’t add up here.

The post Want Workers Back in the Office? Pay Them More appeared first on I Like Kill Nerds.

View Details

Reading the latest update from StackOverflow’s CEO, I can’t help but feel a sense of disconnect. StackOverflow and the broader StackExchange network are facing a tidal wave of change with the rise of AI, and it seems like they’re just treading water.

For many of us, AI tools like ChatGPT have become go-to resources. They’re efficient, user-friendly, and, most importantly, not judgemental. On the other hand, StackOverflow has become notorious for its hostile environment, particularly towards newcomers. It’s as if you need to pass a test of fire to ask a question, and that’s if you’re brave enough to ask in the first place.

Yet, in their latest update, the CEO largely glosses over this. There’s no mention of the toxicity issue nor acknowledge of the challenges AI-generated content is causing on their platform. Instead, we’re treated to a marketing spiel that seems to dance around these elephants in the room.

Furthermore, the update reveals that they’ve had to lay off 10% of their workforce, while another 10% are working on developing AI features. This doesn’t signal a company confidently charting its course; it paints a picture of a ship in a storm, with the crew scrambling to plug the leaks. StackOverflow is panicking.

But the most glaring omission is the lack of a clear plan to address the existential threat of AI. Advanced tools like ChatGPT and GitHub Copilot are not just competition but potential game-changers. They provide fast, reliable answers without the risk of being chastised for asking a ‘stupid’ question. And yet, there’s no sign that StackOverflow is taking concrete steps to counter this threat.

We get a bunch of marketing speak, a lot of vague words and generalities, but no specifics. The entire update reads like panicked rhetoric rather than the CEO’s confident vision for the future.

StackOverflow’s update leaves a lot to be desired. It’s high time they faced the music: the landscape is shifting, and they need to adapt or risk being left behind. We need to see a clear plan of action, a genuine effort to improve their community culture, and a commitment to tackling the challenges posed by AI head-on. Anything less just won’t cut it. For StackOverflow, I think we’re witnessing the beginning of the end.

The post Ignoring the Inevitable: StackOverflow’s Blind Spot on AI appeared first on I Like Kill Nerds.

View Details

When Apple released the M1 chip in 2020, it caused a significant shift in the industry—by abandoning Intel, Apple’s silicon achieved impressive benchmark numbers that widened the gap between Apple and its competitors.

The laptop game was changed again, and Apple was leading the charge.

With the M2 chip, not much has changed since the introduction of the M1. The design and specs are mostly the same, except for a small bump in performance. You still get blistering performance, just a bit faster than the M1. It’s nothing to sing from the hilltops about but nothing to complain about.

I was deciding between the MacBook Air M2 and the MacBook Pro M2. The obvious difference between them is price. The MacBook Air is considerably cheaper but can’t be as high spec’d. I almost pulled the trigger on a blue MacBook Air with 24 GB of RAM and 1 TB of storage.

Even though 24 GB is plenty, I run VMs, and Google Chrome with many tabs. I do video editing and music production. The extra 8 GB can make the world of difference when a bunch of Docker containers are using almost 8 GB of ram.

Before deciding on the MacBook Pro, I explored other options, such as the Thinkpad, Dell XPS, and even a MacBook Pro with an M1 chip (which is still an excellent and much cheaper alternative). In fact, I would highly recommend the M1 MacBook Pro in many cases. However, I prefer the added future-proofing of the newer chip.

The deciding factor in choosing a MacBook Pro over a cheaper alternative was the quality of Apple devices. Not only are you purchasing hardware built to high-quality assurance standards, but Apple Care is unparalleled. No other manufacturer offers a device care program that compares to Apple’s.

The longevity of an Apple laptop is reflected in its price. While they are expensive, even after three years, the resale value of these laptops remains high. No Windows PC comes close to retaining its value like a Mac. They are a solid investment and are known to last for years.

In this review, I won’t discuss screen brightness nits or other inconsequential things most users don’t care about. It’s a Mac, you know the screen is great before you even buy it. I will be talking about the MacBook Pro 14” with the M2 Max chip from the perspective of a front-end developer.

Here is a quick overview of the specs:

  • 14-inch display
  • Apple M2 Max 12-Core CPU 30-Core GPU
  • 32 GB RAM
  • 1 TB SSD

Initially, I grappled with whether 512 GB would be sufficient for development purposes. However, if you’re buying this device with the intention of development, the 512 GB should suffice. That being said, I personally opted for the 1 TB option due to the space taken up by my numerous open-source projects, which can add up astronomically fast.

The MacBook Pro M2 is one of the fastest laptops I’ve ever used. Even when I am not doing anything performance-intensive, the speed is noticeable. It boots instantly. When I log in, everything runs without hesitation.

Opening up apps is like watching lightning strike the ground. Instant.

The MacBook Pro is designed for professionals who need to perform intensive tasks. While the MacBook Air with the M2 chip can handle many of these tasks, the advantages of extra memory, CPU, and GPU cores become apparent. For example, some audio projects I work on require many VST plugins. For instance, one of my current songs has over 20 tracks, most of which include VSTs such as the Neural DSP Archetype plugins for bass and guitars, Superior Drummer for drums, and various equalisers and compressors. These plugins require not only CPU performance but also a lot of RAM.

Unless you’re training artificial intelligence large language models or trying to mine cryptocurrency, you will never hit a performance wall. The M2 chip allows the MacBook Pro M2 to top out at a whopping 96 GB of ram. Which is obviously way more than any sane-minded person would ever need, but it’s there.

My average day-to-day with my MacBook Pro is:

  • Running Docker containers
  • Running Node.js servers
  • Working with Node.js dependencies (those npm installs can be mammoth)
  • Coding in Microsoft Visual Studio Code
  • Google Chrome with 20+ tabs open
  • Listening to music through Spotify
  • Running a Git GUI (Gitkraken)
  • Working inside the Terminal
  • Slack
  • Microsoft Teams
  • Notion
  • Discord

To be honest, most of my daily development activities don’t require a MacBook Pro. However, Docker for Mac is the most resource-intensive item on my list. It uses a lot of memory when working on one of my main projects and drains my battery quickly when I’m not plugged in.

Outside of this, I also work with Reaper for audio projects, using many VST plugins and tracks (as mentioned above). I also edit Adobe Premiere Pro, sometimes working with large video files and editing YouTube and Twitch stream clips. The MacBook doesn’t break a sweat opening up large files in Premiere Pro.

Here’s the thing: if you’re a developer, the two most important factors are memory and storage. In most cases, 16 GB of memory is plenty for development needs, and the CPU is less important because most development tasks aren’t CPU or GPU-intensive.

Storage is one of the most crucial considerations. While 512 GB would suffice, having 1 TB to focus on your work is better than worrying about space. 1 TB is the sweet spot, but more storage is always better. However, going above 2 TB is probably unnecessary, as you’ll likely never reach that limit unless you’re working on 1000 projects at once (GitHub exists for a reason, right?).

Once again, I could have purchased a high-end Windows laptop. However, some caveats can make the process painful when it comes to developing on Windows (despite Microsoft making it easier). Compatibility with some tooling is still turbulent.

Although Microsoft has made great strides with Windows Subsystem for Linux, there are still some serious issues. I previously tried to get Docker to work efficiently with WSL, but it proved to be a gargantuan task. Eventually, I decided to rip off the bandaid and install Linux.

One benefit of using a Mac is that it is built on a Unix operating system, which perfectly aligns with Linux. Many of the commands in the Terminal are the same or very similar, making it easier to use. If you’re a developer, you’re probably already accustomed to working on a Unix command line.

And then there is the one compelling reason to buy a Mac: battery life.

The battery life of modern Apple Silicon laptops is unbeatable. No other PC laptop comes close to matching the battery life of a MacBook Pro or Air. While running Docker does hurt battery life, under normal usage, the battery can last a full day without recharging.

Arguably, the battery life was the deciding factor in purchasing the MacBook Pro. The 14-inch screen size is also the sweet spot for a development laptop. It’s not too big to dominate everything but not too small to hinder your ability to code.

At the end of the day, the M2 chip is just the newer and shinier evolution of Apple’s modern silicon devices—performant, unrivalled battery life and aesthetically pleasing.

The post MacBook Pro 14-inch review (2023) appeared first on I Like Kill Nerds.

View Details

Something interesting has happened with the famed GPT-4 model from OpenAI lately, and it’s not just me that has noticed. Many people have been talking about how GPT-4 lately feels broken. Some say it’s nerfed, and others are saying it’s possibly just broken due to resource constraints. There was a discussion recently on Hacker News in this thread which received 739 comments.

All signs indicated that OpenAI had changed something significant with ChatGPT lately and its GPT-4 model. Users reported that questions relating to code problems were producing generic and unhelpful answers.

An OpenAI employee on Twitter claims that all models have been static since March 2023.

Notice the wording? Logan says the API does not change, and the models are static. The noticeable reduction in quality people report is with ChatGPT, not the GPT-4 API directly. That is still producing desired results.

I tend to use the API for a lot of my prompting. I use the Chatbot UI app and plug in my GPT-4 API key. I still use ChatGPT to keep my API costs down. And I have noticed the quality of the answers has changed. While the models might not have changed, the context window appears to have changed. So, even though some complaints seem to be about ChatGPT, the API is acting differently, too. I’ve got an app with the temperature set to zero that has started acting weird recently.

ChatGPT is doing things I haven’t seen it do before with GPT-4 like correct itself mid-generation (which is cool), and the speed for ChatGPT with GPT-4 is noticeably faster (almost as fast as 3.5-turbo from my observations). OpenAI appears to be messing with the middleware and parameters and not being honest about it.

It’s apparent that maybe OpenAI is paying the alignment tax. The more they try and make it safer and faster, the worse the results get.

The post Has OpenAI Nerfed GPT-4? appeared first on I Like Kill Nerds.

View Details

Designers and developers have had a very long and complicated relationship with Adobe. Over the years, we have seen scrappy upstarts come and take a bite out of Adobe’s lunch: inVision, SketchApp, Figma (which Adobe acquired in 2022) and countless others. Despite numerous attempts, Adobe is still standing. Here we are in 2023, and another […]

The post I’m Bearish on The Future of Adobe appeared first on I Like Kill Nerds.

View Details

Let me cut to the chase here – I love this mouse. I mean, I really, really love this mouse. It’s the Logitech MX Master 3S, the latest version of the MX Master series, and let me tell you, Logitech has managed to make an already fantastic mouse even better. The moment you hold this […]

The post My Thoughts on the Logitech MX Master 3S Mouse appeared first on I Like Kill Nerds.

View Details

Apple is known for introducing innovative products to the market and revolutionising the tech industry, most notably with the iPod and then the iPhone. The latest buzz is about the upcoming Apple augmented reality (AR) glasses being dubbed Apple Glasses. AR technology superimposes digital elements in the real world, creating an interactive and immersive experience.

The idea of AR glasses is not new, but Apple’s entry into the market could be a game-changer if they do it right. The company has a loyal fan base, and its products have a reputation for being high-quality and user-friendly.

Apple is no stranger to augmented reality. They’ve dabbled with it for years now but leveraging existing devices like the iPad and iPhone. Never a pair of glasses or headset device. At the WWDC (Worldwide Developers Conference) on June 5, 2023, Apple is rumoured to announce their new device (after years of speculation).

However, the question remains, will Apple AR glasses be a hit?

There are several factors to consider. Firstly, the price point. Apple’s products are known for being premium, and the AR glasses are expected to be no different. The world is currently experiencing a cost of living crisis. Although inflation has peaked, goods and services remain expensive, and prices are not decreasing.

Secondly, the functionality of the glasses. Apple needs to ensure that the AR glasses offer something that other devices, such as smartphones or tablets, cannot. It needs to be an experience that users cannot get elsewhere. Apple has historically prided itself on this when Jobs was at the helm.

Lastly, the design of the glasses. Apple is renowned for sleek and stylish designs, and the AR glasses must be no different. They must be comfortable to wear and not look too bulky or cumbersome. Aesthetics matter for Apple products, and if they can find a way to make their glasses a part of daily life, things could get interesting.

Aimed at professionals and developers

Apparently, Apple’s foray into augmented reality glasses is aimed at developers and professionals, with rumours that the glasses will cost possibly around $3000. Well outside the realm of affordability for a consumer device unless it’s magical.

If the rumours of this being a professional device are true, it would put it into Microsoft HoloLens territory, and many of those consumer concerns listed above would be irrelevant. Interestingly, Microsoft laid off an unspecified number of employees from its HoloLens team, and there are rumours the product has been canned.

If Apple throws itself into AR and pulls it off, we might see Microsoft make a 360 and reignite HoloLens development again. Although Microsoft has had great success with artificial intelligence and its involvement with OpenAI, it may have shifted priorities.

Interesting times ahead.

The post Will Apple Augmented Reality Glasses Be a Hit? appeared first on I Like Kill Nerds.

View Details

Despite the monumental leaps in artificial intelligence (AI) we’ve witnessed in recent years, the prospect of Artificial General Intelligence (AGI)—machines possessing the ability to understand, learn, and perform any intellectual task precisely as a human can—remains a far-off goal. Yes, advancements have been made with tools like GPT-4, Alpha Go, and Gato, contributing to the foundation of AGI. However, these are still considered early examples of AGI and not fully formed AGI systems.

The journey towards AGI is riddled with significant challenges and roadblocks. The task of developing AGI is compared to the mammoth task of understanding and replicating the complexity of the human brain, which is far from complete despite decades of research in neuroscience, psychology, and cognitive science.

And yet, the leap between GPT-3 and GPT-4 feels significant. It happened in a very short timeframe. We’ve also seen other models achieve equally impressive results, including some open-source AI model efforts. Still, as exciting and fast as things are, AGI is a different beast we are nowhere near solving.

One of the fundamental challenges we face is defining the scope of AGI. It’s crucial to establish the limits of what AGI machines can and cannot do to prevent negative consequences. Alongside this, we grapple with ensuring that these machines adhere to human ethics and morality, a nuanced and complex field in and of itself. Without this, AGI machines could pose real risks to society if they make decisions that do not align with human values, morals, or interests.

The issues extend beyond the technical and into the regulatory. Developing frameworks to govern the use of AGI, including data security standards, ethical behaviour guidelines, and regulations for developing AGI machines, is a challenge yet to be fully met. As AI systems become more intelligent and potentially more autonomous, the question of responsibility arises, particularly if an AGI system causes harm.

But the challenges aren’t just philosophical; they’re also computational. We need significant breakthroughs in machine learning, natural language processing, and computer vision to achieve AGI. We need new algorithms, techniques, and architectures that enable AGI to learn, reason, and adapt similarly to human intelligence. Furthermore, AGI requires access to higher computing resources than currently available, including more processing power, data storage, management, optimized computing architecture, and increased energy efficiency. The development of such resources is resource-intensive and could have significant environmental impacts.

The current roadblock that AI faces is the cost. OpenAI reportedly pays upwards of $700,000 USD daily to run ChatGPT. Can you imagine AI even more powerful, requiring more processing power and resources? You could theoretically be looking at tens of millions a day to run an AGI system at current resource prices.

Despite these hurdles, AGI holds immense potential and could surpass human intelligence and capabilities. It could lead to advancements in machine learning, neural networks, AI, natural language processing, and more. But we need to tread carefully, ensuring responsible development to benefit society and advance human progress.

We will eventually see some form of AGI, and as good as GPT-4 and other models are at making you believe it’s just around the corner, other problems must be solved before we get to that point. Some of these problems might be solved with the aid of AI itself.

In the meantime, enjoy the other possibilities we’ll witness due to AI, particularly scientific and medical breakthroughs. We are already seeing new drug combinations and potential cancer treatments being discovered thanks to AI. Another exciting area is new antibiotics research, where AI can once again reduce the time and failure rate of such research.

The post The Long Road to AGI: Why Artificial General Intelligence Is Further Than We Think appeared first on I Like Kill Nerds.

View Details

Introduction

In data science and machine learning, cosine similarity is a measure that calculates the cosine of the angle between two vectors. This metric reflects the similarity between the two vectors, and it’s used extensively in areas like text analysis, recommendation systems, and more. This post delves into the intricacies of implementing cosine similarity checks using TypeScript.

Understanding Cosine Similarity and Its Applications in AI

Cosine similarity measures two non-zero vectors of an inner product space. It is defined as the cosine of the angle between them, which is calculated using this formula:

d = 1.0 - sum(Ai*Bi) / sqrt(sum(Ai*Ai) * sum(Bi*Bi)) Here, Ai and Bi are components of vector A and B, respectively.

In Artificial Intelligence, cosine similarity has a wide range of applications. Natural Language Processing (NLP) often uses it to measure the similarity between documents or sentences. This can be useful in systems like search engines, where you want to rank documents by their relevance to a query.

In recommendation systems, cosine similarity can suggest items “similar” to what a user has already liked or purchased. This is often seen in e-commerce platforms where the “You might also like” section is populated using similarity measures.

Implementing Cosine Similarity in TypeScript

Now that we understand what cosine similarity is and its applications in AI, let’s dive into how we can implement this in TypeScript.

// Define the function to calculate cosine similarityfunction cosineSimilarity(A: number[], B: number[]): number { // Initialize the sums let sumAiBi = 0, sumAiAi = 0, sumBiBi = 0; // Iterate over the elements of vectors A and B for (let i = 0; i < A.length; i++) { // Calculate the sum of Ai*Bi sumAiBi += A[i] * B[i]; // Calculate the sum of Ai*Ai sumAiAi += A[i] * A[i]; // Calculate the sum of Bi*Bi sumBiBi += B[i] * B[i]; } // Calculate and return the cosine similarity return 1.0 - sumAiBi / Math.sqrt(sumAiAi * sumBiBi);} In this function, we’re iterating over the elements of vectors A and B, calculating the sums of Ai*Bi, Ai*Ai, and Bi*Bi, and then using these sums to calculate the cosine similarity.

Applying Cosine Similarity in Real-World Scenarios

Cosine similarity can be used in a variety of real-world scenarios. Let’s explore a few examples.

Example 1: Document Similarity

Let’s say we have two documents and want to measure their similarity. First, we need to convert these documents into vectors. For simplicity, we’ll use a basic bag-of-words model for text representation.

// Function to get all unique words from multiple textsfunction getUniqueWords(...texts: string[]): string[] { let words = new Set<string>(); texts.forEach(text => text.split(/\b/).forEach(word => words.add(word.toLowerCase()))); return Array.from(words);}// Modified bag-of-words model for text representationfunction textToVector(text: string, uniqueWords: string[]): number[] { let wordMap = new Map<string, number>(); uniqueWords.forEach(word => wordMap.set(word, 0)); text.split(/\b/).forEach(word => wordMap.set(word.toLowerCase(), (wordMap.get(word.toLowerCase()) || 0) + 1)); return Array.from(wordMap.values());}// Function to calculate cosine similarity between all pairs of documentsfunction calculateDocumentSimilarities(docVectors: number[][]): number[][] { let similarities: number[][] = []; for (let i = 0; i < docVectors.length; i++) { let docSimilarities: number[] = []; for (let j = 0; j < docVectors.length; j++) { docSimilarities.push(cosineSimilarity(docVectors[i], docVectors[j])); } similarities.push(docSimilarities); } return similarities;}// Function to find the most similar document to a given documentfunction findMostSimilarDocument(docIndex: number, docSimilarities: number[][]): number { let maxSimilarity = -Infinity, mostSimilarDocIndex = -1; for (let i = 0; i < docSimilarities[docIndex].length; i++) { if (i !== docIndex && docSimilarities[docIndex][i] > maxSimilarity) { maxSimilarity = docSimilarities[docIndex][i]; mostSimilarDocIndex = i; } } return mostSimilarDocIndex;}// Convert the documents to vectorslet doc1 = "The quick brown fox jumps over the lazy dog";let doc2 = "The dog is brown and the fox is quick";let doc3 = "The fox is quick and the dog is lazy";let doc4 = "The lazy dog is jumped over by the quick fox";let uniqueWords = getUniqueWords(doc1, doc2, doc3, doc4);let docVectors = [doc1, doc2, doc3, doc4].map(doc => textToVector(doc, uniqueWords));// Calculate the cosine similarity between all pairs of documentslet docSimilarities = calculateDocumentSimilarities(docVectors);// Find the most similar document to Doc 1let mostSimilarDocIndex = findMostSimilarDocument(0, docSimilarities);console.log(`The most similar document to Doc 1 is: Doc ${mostSimilarDocIndex + 1}`); In this example, we first convert all documents to vectors. Then, we calculate the cosine similarity between all pairs of documents. Finally, we find the most similar document to a given document.

Please note that this is still a simplified example. In a real-world scenario, you would likely use more sophisticated methods for text representation (like TF-IDF or word embeddings) and similarity calculation (like adjusting for document length).

Example 2: Recommendation Systems

In recommendation systems, cosine similarity can suggest items “similar” to what a user has already liked or purchased. Here’s a simplified example:

// User-item matrix (for simplicity, we're using a binary preference: 1 for liked, 0 for not liked)let userItemMatrix = [ [1, 0, 1, 0, 1, 0, 1, 0, 1, 0], // User 1 [1, 1, 0, 1, 0, 0, 1, 0, 1, 1], // User 2 [0, 1, 1, 1, 0, 1, 0, 1, 0, 1], // User 3 [1, 0, 1, 0, 1, 1, 0, 1, 0, 0], // User 4 [0, 1, 0, 1, 0, 0, 1, 1, 1, 1] // User 5];// Calculate the cosine similarity between all userslet userSimilarities: number[][] = [];for (let i = 0; i < userItemMatrix.length; i++) { let similarities: number[] = []; for (let j = 0; j < userItemMatrix.length; j++) { similarities.push(cosineSimilarity(userItemMatrix[i], userItemMatrix[j])); } userSimilarities.push(similarities);}// Function to recommend items for a user based on the preferences of similar usersfunction recommendItems(userIndex: number, userSimilarities: number[][], userItemMatrix: number[][]): number[] { let recommendations: number[] = []; let similarUsers = userSimilarities[userIndex]; for (let i = 0; i < userItemMatrix[0].length; i++) { if (userItemMatrix[userIndex][i] === 0) { // If the user hasn't liked the item yet let weightedSum = 0, sumSimilarities = 0; for (let j = 0; j < userItemMatrix.length; j++) { if (j !== userIndex) { // Don't include the user himself/herself weightedSum += userItemMatrix[j][i] * similarUsers[j]; sumSimilarities += similarUsers[j]; } } if (weightedSum / sumSimilarities > 0.5) { // If the average preference of similar users is more than 0.5 recommendations.push(i); } } } return recommendations;}// Recommend items for User 1let recommendations = recommendItems(0, userSimilarities, userItemMatrix);console.log(`Recommended items for User 1: ${recommendations}`); In this example, we first calculate the cosine similarity between all users. Then, we define a function to recommend items for a user based on similar users’ preferences. If the average preference of similar users for an item (weighted by their similarity to the user) is more than 0.5, and the user hasn’t liked it yet, we recommend it.

Example 3: Social Media Feed-Like Algorithm

This algorithm aims to show posts from users that are similar to the current user. We’ll use cosine similarity to measure user similarity based on liking patterns.

// Define the function to calculate cosine similarityfunction cosineSimilarity(A: number[], B: number[]): number { // Initialize the sums let sumAiBi = 0, sumAiAi = 0, sumBiBi = 0; // Iterate over the elements of vectors A and B for (let i = 0; i < A.length; i++) { // Calculate the sum of Ai*Bi sumAiBi += A[i] * B[i]; // Calculate the sum of Ai*Ai sumAiAi += A[i] * A[i]; // Calculate the sum of Bi*Bi sumBiBi += B[i] * B[i]; } // Calculate and return the cosine similarity return 1.0 - sumAiBi / Math.sqrt(sumAiAi * sumBiBi);}// Users and postslet users = [ { id: 1, name: "User 1" }, { id: 2, name: "User 2" }, { id: 3, name: "User 3" }, { id: 4, name: "User 4" }, { id: 5, name: "User 5" }];let posts = [ { id: 1, content: "Post 1" }, { id: 2, content: "Post 2" }, { id: 3, content: "Post 3" }, { id: 4, content: "Post 4" }, { id: 5, content: "Post 5" }, { id: 6, content: "Post 6" }, { id: 7, content: "Post 7" }, { id: 8, content: "Post 8" }, { id: 9, content: "Post 9" }, { id: 10, content: "Post 10" }];// User-post interaction matrix (for simplicity, we're using a binary preference: 1 for liked, 0 for not liked)let userPostMatrix = [ [1, 0, 1, 0, 1, 0, 1, 0, 1, 0], // User 1 [1, 1, 0, 1, 0, 0, 1, 0, 1, 1], // User 2 [0, 1, 1, 1, 0, 1, 0, 1, 0, 1], // User 3 [1, 0, 1, 0, 1, 1, 0, 1, 0, 0], // User 4 [0, 1, 0, 1, 0, 0, 1, 1, 1, 1] // User 5];// Calculate the cosine similarity between all userslet userSimilarities: number[][] = [];for (let i = 0; i < userPostMatrix.length; i++) { let similarities: number[] = []; for (let j = 0; j < userPostMatrix.length; j++) { similarities.push(cosineSimilarity(userPostMatrix[i], userPostMatrix[j])); } userSimilarities.push(similarities);}// Function to generate a feed for a user based on the posts liked by similar usersfunction generateFeed(userIndex: number, userSimilarities: number[][], userPostMatrix: number[][]): any[] { let feed: any[] = []; let similarUsers = userSimilarities[userIndex]; for (let i = 0; i < userPostMatrix[0].length; i++) { if (userPostMatrix[userIndex][i] === 0) { // If the user hasn't liked the post yet let weightedSum = 0, sumSimilarities = 0; for (let j = 0; j < userPostMatrix.length; j++) { if (j !== userIndex) { // Don't include the user himself/herself weightedSum += userPostMatrix[j][i] * similarUsers[j]; sumSimilarities += similarUsers[j]; } } if (weightedSum / sumSimilarities > 0.5) { // If the average preference of similar users is more than 0.5 feed.push(posts[i]); } } } return feed;}// Generate a feed for User 1let feed = generateFeed(0, userSimilarities, userPostMatrix);console.log(`Feed for User 1:`, feed); In this example, each user and post is represented as a JSON object with an id and a name or content field, respectively. The generateFeed function returns a feed consisting of post objects that the user hasn’t liked yet, but are liked by similar users. The posts are included in the feed if the average preference of similar users (weighted by their similarity to the user) is more than 0.5.

Please note that this is a very simplified example. In a real-world scenario, a social media feed algorithm would consider many other factors, such as the recency of the posts, the interactions between the users, the overall popularity of the posts, and so on. The algorithm would also likely use more sophisticated methods for user representation and similarity calculation.

Conclusion

Cosine similarity is a powerful tool in data science and artificial intelligence. It allows us to quantify the similarity between vectors, representing a wide range of entities, from documents in a text analysis task to users in a recommendation system.

In this post, we’ve explored how to implement cosine similarity checks in TypeScript. We’ve also delved into some practical applications of cosine similarity, including document similarity checks, recommendation systems, and even a simplified social media feed algorithm.

It’s important to note that while these examples provide a good starting point, real-world applications often require more sophisticated methods and considerations. For instance, text analysis tasks may benefit from more advanced text representation methods like TF-IDF or word embeddings, and recommendation systems may use techniques like collaborative filtering or matrix factorization.

Nevertheless, understanding the basics of cosine similarity and how to implement it in code is a crucial first step. As you continue your journey in data science and AI, you’ll find that this concept is a valuable tool in your toolkit.

The post Crafting Cosine Similarity Calculations in TypeScript: A Comprehensive Guide appeared first on I Like Kill Nerds.

View Details

While working on an AI-related app recently using vectors, I found myself with a 115MB file in my repository. While attempting to push to GitHub, I got an error in GitKraken about a hook failing. I didn’t have any hooks locally or remotely, so the issue was a bit perplexing. After trying a few things, I resorted to command-line Git, and that’s when I saw the problem.

GitHub blocks files larger than 100 megabytes. They recommend using Git Large File Storage, but I decided maybe I shouldn’t be adding large vector files into my repository anyway.

So, I deleted the offending file from my repository, committed and attempted to push. It failed again. Same error and complaining about the same large file. Then it dawned on me that when you delete a file in Git, it doesn’t delete delete it. Because you can revert commits, it still exists in the repo’s history.

This is where the filter-branch command saves our bacon

git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch path/to/your-file' \ --prune-empty --tag-name-filter cat -- --all This should result in an output that indicates the file was successfully removed from your history. The important thing to note is you must provide the full path to your file. If it lives in myfolder/anotherfolder/somefolder/myfile.jpg that is the value you provide in the above command.

A Quick Check-In With .gitignore

Now that you’ve dealt with the oversized file, it’s important to protect yourself against accidentally committing it again in the future. Enter .gitignore. If you haven’t already, update your

file to ignore the one you removed​.Use the force… push

If the file you’re deleting already exists in your repo remotely (say on GitHub), you must do a forced push because you’ve messed with the history.

git push origin --force --all Also, note that space might not be adjusted right away. You might have to wait for the garbage collection to run to clean up your repository. In my instance, I couldn’t even push because my file was larger than GitHub’s limit, and it rejected my push.

The post How to Remove Large Files From Your Git Commit History appeared first on I Like Kill Nerds.

View Details

I’ve got a confession to make. I miss buttons. You know, the kind in cars, where you press one and something actually happens. No swiping, no squinting, no guessing if you hit the right part of the screen. Just good old-fashioned, satisfying, clicky buttons.

Remember when touchscreens started becoming a thing in cars? There was this sense of “Wow, it’s like driving in the future!” But after the novelty wore off, we were left playing a dangerous game of ‘Whack-A-Mole’ on the highway. You just wanted to adjust the fan speed, but instead found yourself in a high-stakes game of find-the-menu, all while keeping an eye on the road. Not exactly the stress-free driving experience we were promised.

Touchscreens, while flashy and modern, aren’t exactly ideal for a task that requires, you know, watching the road. Unlike buttons, they demand your full attention, turning a simple task like turning up the radio into an obstacle course of menus and sliders.

Here’s the funny part: we all agree that using phones while driving is risky. But then, we ended up in cars that asked us to tap and swipe on a screen while navigating through traffic. A bit of a mixed message, don’t you think?

But it seems like the tide is turning. Car companies are starting to realise that maybe, just maybe, touchscreens aren’t the perfect solution for everything in a car. Case in point: Porsche. They’ve decided to bring back buttons in their new Cayenne model. Sure, there’s still a touchscreen, but it’s no longer the gatekeeper for every single function in the car.

Porsche isn’t alone in this renaissance of common sense. Hyundai, Nissan, and Volkswagen have also expressed interest in bringing back physical controls. In fact, Volkswagen even said goodbye to excessive touchscreen controls on their steering wheels after customers made their preferences pretty clear.

But let’s not get ahead of ourselves. Some manufacturers are still clinging to their beloved touchscreens like a kid to a security blanket. But hey, old habits die hard, right?.

And then there’s Toyota. Amid the touchscreen madness, they’ve been quietly sticking to their guns. Take the Landcruiser for example. Sure, it’s got a touchscreen, but it’s not the control center for everything. Crucial functions like climate control still have physical controls, letting drivers make adjustments without taking a sightseeing tour on the infotainment screen.

So here’s the takeaway: buttons are making a slow but steady comeback in our cars, and it’s a change we should welcome. For those of us who’ve been grumbling about this for years, it feels like a small victory. But we’re not there yet. Here’s hoping more car manufacturers get on board with this ‘back-to-basics’ approach. Until then, drive safe and don’t forget to appreciate the buttons in your life.

The post Clicks Over Swipes: The Resurgence of Physical Controls in Cars appeared first on I Like Kill Nerds.

View Details

Picture this: It’s 3 AM, and you’re staring at your computer screen, bleary-eyed, as you struggle to solve that pesky bug in your code. You can almost feel the weight of the digital cobwebs piling up on StackOverflow as you sift through outdated answers and snarky comments. But what if I told you that the days of scouring through StackOverflow’s seemingly endless abyss might be numbered? Enter ChatGPT, Google Bard, and a whole new breed of AI-powered chatbots revolutionising how developers find answers to their coding conundrums.

A Love-Hate Relationship: StackOverflow and Developers

Developers and StackOverflow have always shared a tumultuous relationship. On the one hand, it has been an invaluable resource, providing much-needed answers to countless coding questions. On the other hand, it’s become notorious for its trigger-happy moderators, outdated answers, and, of course, the dreaded “I solved it” posts without any explanation.

As a developer, I can relate to the frustration of desperately trying to find a solution, only to be met with closed questions, unanswered threads, and the haunting silence following the infamous “I solved it” statement. What did you see, indeed, mysterious poster?

The AI Revolution: ChatGPT and Google Bard to the Rescue

With the rise of AI chatbots like ChatGPT and Google Bard, we may finally have found the light at the end of the StackOverflow tunnel. These intelligent, ever-learning machines are designed to cut through the clutter and deliver quick, accurate solutions to our coding woes.

Now that ChatGPT is gaining internet access, and with Microsoft’s Bing Chat and Google Bard in the mix, we’re witnessing a new era in programming support. Instead of trawling through pages of StackOverflow discussions that may or may not hold the key to your coding conundrum, you can ask your friendly neighbourhood chatbot and watch as it conjures up a solution.

Furthermore, you can copy and paste your code into these tools and ask them to debug it or write documentation—something a traditional Q&A platform like StackOverflow could never do. Sometimes the problem is user error, not because the package you’re using or the browser is the problem.

But Will AI Chatbots Really Kill StackOverflow?

Before we start writing StackOverflow’s obituary, let’s consider a few points. While AI chatbots are undeniably impressive, they still have limitations. For example, they may struggle to understand the context behind certain questions or provide overly generic answers.

Furthermore, StackOverflow’s strength lies in its community. Over the years, it has amassed a vast, ever-growing database of questions, answers, and discussions. This wealth of information is invaluable, and the platform remains a key resource for developers worldwide.

Not all of the information on StackOverflow is of low quality. For the fundamentals stuff, irrespective of versioning, there is a trove of fantastic answers that will continue to serve developers (ironically, probably scraped by OpenAI to train its GPT models and available in ChatGPT anyway).

The Future of Programming Support: A Marriage of AI and Community?

Instead of viewing AI chatbots as StackOverflow’s executioner, we could see them as the catalyst for a more efficient, user-friendly programming support experience. Imagine a world where AI chatbots and platforms like StackOverflow work together, with chatbots providing quick solutions for simple issues and StackOverflow offering more in-depth, community-driven discussions for complex problems.

By integrating AI technology with human insight, we could create a truly powerful, all-encompassing resource that empowers developers to tackle any challenge that comes their way.

At the moment, StackOverflow has a zero-ChatGPT policy—disallowing answers generated from chatbot tools over fears of misinformation and poor quality. Given GPT’s tendency to hallucinate (I’ve seen it make up package names and whatnot before), it’s probably not a bad thing at present.

Conclusion: A Hopeful Future for Coding Support

While it’s too early to predict the death of StackOverflow at the hands of ChatGPT and Google Bard, there’s no denying the impact these AI chatbots have on how we find answers to our coding questions. It’s an exciting time to be a developer, and we can look forward to a future where we spend less time sifting through digital garbage and more time creating, innovating, and pushing the boundaries of what’s possible in the programming world.

The post Rise of the Chatbots: Will AI Behemoths Like ChatGPT and Google Bard Bury StackOverflow in Their Digital Dust? appeared first on I Like Kill Nerds.

View Details

Rate limiting is a crucial aspect of building scalable and secure web applications. It helps prevent abuse and ensures the fair usage of resources. In this blog post, we will explore how to implement token bucket rate limiting in a NestJS application with a reset interval of 24 hours.

What is Token Bucket Rate Limiting?Token bucket rate limiting is an algorithm that controls the rate at which a system processes requests. The main idea is that a fixed number of tokens are added to a bucket regularly. When a request arrives, a token is removed from the bucket. If there are no tokens left, the request is rejected.

Setting up a NestJS ApplicationTo get started, let’s create a new NestJS application. First, you need to install the Nest CLI globally:

npm i -g @nestjs/cli Next, create a new project using the following command:

nest new nestjs-rate-limiter Navigate to the project directory:

cd nestjs-rate-limiter Now, install the required dependencies:

npm install Implementing Token Bucket Rate LimitingBefore we continue: This implementation does not use a database or persist the values in any way. It also relies on the user’s IP address, not a user ID. In a real-world application, you would store token counts in a database and compare them per user.

To implement token bucket rate limiting, we will create a custom RateLimiterInterceptor that will be responsible for managing tokens and limiting requests.

  1. Create a RateLimiterInterceptorFirst, create a new file called rate-limiter.interceptor.ts in the src directory and then open the file up and add in the following:

import { Injectable, NestInterceptor, ExecutionContext, CallHandler, HttpException, HttpStatus,} from '@nestjs/common';import { Observable } from 'rxjs'; Next, define the RateLimiterInterceptor class:

@Injectable()export class RateLimiterInterceptor implements NestInterceptor { // ...} 2. Implement the Token Bucket AlgorithmInside the RateLimiterInterceptor class, add the following properties:

private readonly bucketSize: number;private readonly tokens: Map<string, number>;private readonly lastRefill: Map<string, number>; Then, initialize these properties in the constructor:

constructor(bucketSize: number) { this.bucketSize = bucketSize; this.tokens = new Map(); this.lastRefill = new Map();} Now, implement a refillTokens method to add tokens to the bucket:

private refillTokens(ip: string, now: number): void { const lastRefillTime = this.lastRefill.get(ip) || now; const elapsedTime = now - lastRefillTime; if (elapsedTime >= 24 * 60 * 60 * 1000) { // 24 hours in milliseconds this.tokens.set(ip, this.bucketSize); this.lastRefill.set(ip, now); }} Finally, implement the intercept method to handle incoming requests:

intercept(context: ExecutionContext, next: CallHandler): Observable<any> { const httpContext = context.switchToHttp(); const request = httpContext.getRequest(); const ip = request.ip; const now = Date.now(); if (!this.tokens.has(ip)) { this.tokens.set(ip, this.bucketSize); } this.refillTokens(ip, now); const tokens = this.tokens.get(ip); if (tokens > 0) { this.tokens.set(ip, tokens - 1); return next.handle(); } else { throw new HttpException( 'Too many requests', HttpStatus.TOO\_MANY\_REQUESTS, ); }} 3. Register the RateLimiterInterceptorNow, let’s register the RateLimiterInterceptor in the AppModule. Open src/app.module.ts and import the RateLimiterInterceptor:

import { RateLimiterInterceptor } from './rate-limiter.interceptor'; Then, add the interceptor to the providers array. Also, make sure you import APP_INTERCEPTOR from @nestjs/core as well:

providers: [ { provide: APP\_INTERCEPTOR, useValue: new RateLimiterInterceptor(5), },], In this example, we set the bucket size to 5 tokens and the refill rate to one token per 24 hours.

Testing the ApplicationTo test the rate-limiting functionality, start the application:

npm run start Now, in your browser, your NestJS application should be running on port 3000 so visit http://localhost:3000 and refresh the page more than 5 times. You should eventually get a rate-limiting 429 response.

Further ImprovementsAs mentioned in the implementation section, we’ve implemented an idea, but not something you would deploy into production. The flaw is everything is stored in memory, and IP addresses can be spoofed. In a real application, usage would be restricted on a per-user token basis.

  • Implement a UserService, which contains a method for getting the user’s available tokens. It would accept a user ID.
  • In the UserService, there would be an update method to update the number of tokens.
  • You would get the token count from the request > user object inside the interceptor. You would also update the count every time a request is made.

ConclusionIn this blog post, we have successfully implemented token bucket rate limiting in a NestJS application. We created a custom RateLimiterInterceptor to manage the token buckets and limit requests based on the client’s IP address. We also configured the interceptor to reset the token bucket every 24 hours.

By implementing rate limiting, you can protect your application against abuse and ensure a fair distribution of resources among your users. The token bucket algorithm provides a flexible and efficient way to control the rate at which requests are processed. You can easily adjust the bucket size and refill rate to suit the needs of your application.

The post How to Implement Token Bucket Rate Limiting In NestJS appeared first on I Like Kill Nerds.

View Details

Remote work, or working from home, has become increasingly popular. With the COVID-19 pandemic, remote work has become the new norm for many employees. However, remote work had gained traction even before the pandemic due to its numerous benefits.

While remote work has many benefits, it’s important to note that it may not be suitable for every job or company. Some jobs require in-person collaboration or access to specialised equipment only available in a traditional office setting.

Increased ProductivityOne of the most significant benefits of remote work is its ability to increase productivity. Working from home allows employees to avoid the distractions and interruptions that often come with a traditional office setting. With fewer distractions, remote workers can focus better on their work and finish more quickly. Studies have shown that remote workers are more productive than their office counterparts. They take fewer breaks, have fewer sick days, and are less likely to be distracted by office politics. Employees who work remotely are often more engaged and satisfied with their work, which can further boost productivity.

It’s worth noting that not everyone is productive from home. Some people don’t have the space or desire to work remotely. They should have that right to be in an office.

Working from home can be challenging for some due to the lack of structure and social interaction. However, companies can provide tools and resources to help remote workers stay connected with their colleagues and maintain a healthy work-life balance. This can include regular check-ins with managers or team members, virtual team-building activities, and flexible work hours. By addressing these concerns and providing support, companies can help remote workers thrive and enjoy the many benefits of working from home.

Recession Proof and InclusiveAnother significant benefit of remote work is that it is recession-proof. When the economy begins to slide into the dark abyss, companies with remote workers can often weather the storm better than those without. Remote workers don’t require as much office space or equipment, which can save companies money. Additionally, remote workers can work from anywhere, so companies can hire the best talent regardless of location. This can be particularly helpful during a recession, when companies may need to downsize or restructure.

As we have seen with a wave of layoffs at the beginning of 2023, the amount of talent available due to more prominent companies like Meta and Twitter laying off people means the talent pool gets more extensive—an advantage for remote-friendly companies.

Companies should also consider the benefits of remote work for diversity and inclusion. Remote work allows companies to tap into a global talent pool, which can help diversify their workforce and bring new perspectives. Additionally, remote work can be more accessible for people with disabilities who may have difficulty commuting to a traditional office setting.

Other BenefitsRemote work also has many other benefits. For employees, it can save money on commuting and other work-related expenses. It can also improve work-life balance by allowing employees to spend more time with their families and pursue hobbies and interests outside work. Remote work can be particularly beneficial for parents, caregivers, and people with disabilities who may have difficulty commuting to a traditional office setting. For companies, remote work can reduce overhead costs, increase employee retention, and improve morale and job satisfaction.

Remote work can also be better for the environment, as it reduces the need for commuting and office space. This can have a significant impact on reducing carbon emissions and helping companies to meet their sustainability goals. Additionally, remote work can help to diversify the workforce and promote inclusivity and accessibility.

Remote work has also reduced stress levels and improved mental health. Employees can better balance their work and personal lives without a commute or the need to adhere to strict office hours. This can lead to reduced burnout and increased job satisfaction. Additionally, remote work can offer more flexibility for employees with other responsibilities, such as caring for children or elderly relatives.

Remote-friendly job boardsWhile it may seem like companies are turning their backs on remote work, many are embracing it.

Now, many job boards cater specifically to remote workers, making it easier than ever to find a job that allows remote work. Some popular remote-friendly job boards include Remote.co, We Work Remotely, and FlexJobs. These job boards offer job opportunities across various industries, making it easier for remote workers to find work that suits their skills and experience. Unlike other job sites, they are oriented explicitly towards remote work, and the quality of the listings is high.

ConclusionRemote work has numerous benefits for both employees and companies. It increases productivity, is recession-proof, and has many other benefits. While it may not be suitable for every job or company, remote work is worth considering for those who want to improve their work-life balance and enjoy the many benefits of working from home.

It’s disappointing to see some larger companies forcing employees back into the office, especially as many experts say we will enter a recession soon.

The post Remote Work is Recession Proof appeared first on I Like Kill Nerds.

View Details

In the past year, a surge of AI tools has hit the market, with many identifying as AI startups. The advent of OpenAI’s ChatGPT, including GPT-3.5 and GPT-4 models, has revolutionised how we interact with technology. However, amidst this excitement, a trend needs addressing: the phenomenon of “API wrappers” masquerading as AI startups.

While it’s true that many of these products utilize the power of OpenAI’s GPT APIs, it’s essential to take a step back and consider the implications of relying solely on an external API for your business. Does wrapping GPT APIs and selling a service based on them warrant the label of an AI startup? Let’s take a closer look at the potential downsides of this approach.

Control Issues: The Risks of API Dependency

First and foremost, basing a company on an API you don’t control is inherently risky. Here are a couple of scenarios that could threaten the stability of such a business:

  1. License terms change: If OpenAI alters its licensing terms, and your “startup” violates these new terms, your business could face severe consequences.
  2. Increasing costs: If OpenAI increases its API usage costs, your business may no longer be able to operate, resulting in potential collapse. The GPT-4 model right now is a lot more powerful, but it’s expensive compared to GPT-3.5.

Remember when Twitter altered their API access, leaving several popular apps built around it in a lurch? That’s a prime example of the risks of building a business around an external API.

Redefining AI Startups: More Than Just API Wrappers

With a constant stream of AI products appearing on platforms like producthunt.com, it’s evident that people are excited about AI, and that’s fantastic! However, we must address the elephant in the room: should we call these products AI startups if they’re just wrapping the GPT APIs?

The AI ecosystem should foster genuine innovation and encourage businesses to develop unique algorithms, models, and solutions. By merely wrapping the GPT API, these “startups” may be stretching the definition of what it means to be an AI company.

In Conclusion: Embrace Innovation, But Be Wary of Hype

While there is nothing inherently wrong with using GPT APIs to build a product or service, it’s crucial to understand the limitations and risks associated with this approach. Entrepreneurs and investors should be cautious not to get swept up in AI hype and maintain a discerning eye when evaluating these AI startups.

I would also caution people signing up to these slapped-together AI startups to evaluate what they’re signing up for. Given how easy it is to create an AI tool now, you could open yourself up to possible data leaks. This rings true for any service or software, but a quickly thrown-together API wrapper built to capitalise on the AI hype and make some money could be a risk.

By acknowledging the potential pitfalls and encouraging true innovation, the AI community can continue to grow and thrive sustainably.

The post Don’t Get Wrapped Up in AI Hype: Why GPT API-Based Startups Need a Reality Check appeared first on I Like Kill Nerds.

View Details

The end of Succession is near its fourth and final season. Arguably, one of the greatest TV shows in recent years. A perfect mixture of comedy, drama and suspense. After the emotionally charged second last episode, “Church and State”, fans are left to guess how they will end the show.

Oh, also: spoiler alert. Stop reading if you haven’t seen season 4 or are behind.

Things are shaping up for the finale after the funeral episode featuring an incredible performance by Kieran Culkin (give the man an Emmy already). We saw Roman completely break; after saying he had already “pre-grieved”, he fell apart. This pinnacle moment of the episode saw the threads of power unravel.

We are used to seeing Kendall in a situation like this like we did when he killed that waiter (that daddy covered up). However, in this episode, we saw Kendall being more Logan Roy-like than ever. After filling in for Roman and finishing the speech, we saw a brief glimpse of a chillingly cold Kendall telling a visibly broken Roman he fucked up. Roman seemed sensitive to the criticism (a stark difference between episodes and seasons prior).

We also saw Kendall doing a very Logan thing where he berated his ex-wife over custody but fell short of the mark while trying to stop her from leaving, something we know Logan would have accomplished in the same situation. This highlights that while Kendall might be stepping up, his children are weak imitations of the once great, feared and respected man Logan Roy.

Like every other Succession season finale before it, the Season 4 finale takes its name from the poem “Dream Song 29” by John Berryman, originally published in 1964. The finale is titled “With Open Eyes” – John Berryman’s ‘Dream Song 29’ delves into the psyche of a profoundly sorrowful and distressed character named Henry. In the confines of this brief verse, Berryman’s narrator illustrates Henry’s melancholy as an unshakeable burden resting heavily upon his heart. At its core, the poem speaks of an overwhelming onslaught of guilt.”

You could argue that everyone is dealing with guilt right now. Roman is dangerously lost and broken, which could be a liability. His influence and sway with Mencken appear to have been lost, and Mattson is on the in. Shiv is scheming as usual, but as we’ve seen, when it comes to Shiv wanting to step up, she gets close and pulls the rug beneath her. Shiv has US CEO being dangled in front of her, but we all know she isn’t going to be CEO. We’ve seen this before.

One noticeably absent figure from Succession these past few episodes is Stuey. And we know Stuey has some sway. He’s critical of Kendall being able to lead (they have a complicated relationship), and Kendall has fucked Stuey over before.

This is all leading up to a boardroom fight, which is, once again, something we have seen. I suspect we will see a repeat of an earlier episode where Kendall attempts to challenge his dad and doesn’t get the votes needed to win. Connor is Connor and seems happy getting an international appointment.

Kendall has the whole “killing the waiter” thing hanging over his head. Tom has the whole shredding papers thing over his head, Roman has the sexual assault dick-pics thing with Gerri, and Shiv is probably committing fraud or some other violation by backchanneling the GoJo acquisition.

It’s possible we are going to see the Roy Boys and Shiv The Shiv end up with nothing. The acquisition goes through, Kendall goes to jail, and Roman is so broken that he does something stupid and kills himself. As for Shiv? Maybe she and Tom get into an argument, and he pushes her, and she falls down some stairs.

The ending feels like it will be very Shakespearian, which would align with how this show operates. Or, it’s possible, we’ll see something else happen.

But, there is one person we are forgetting: Greg Hirsch.

Season four has been big for Greg. We’ve seen him go from errand boy to having actual power. He’s also in with Mattson and other key players. Despite coming across as the bumbling cousin, Greg has shown more leadership and cold-calculated corporate shill-like behaviour than any siblings.

Let’s not forget that Greg is one of the few people aware of all these things. I am unsure if he knows about Kendall killing the waiter, but who knows?

In episode eight, Tom said something to Greg that stuck with me:

“Information, Greg. It’s like a bottle of fine wine. You store it, you horde it, you save it for a special occasion — and then you smash someone’s fucking face in with it.”

Was this foretelling what we might see Greg do in the finale? Hirsch is holding onto some seriously juicy information, valuable information that Greg could use to elevate his position even more.

Could we see the GoJo acquisition go through, and the US CEO is Greg Hirsch? We’ve already seen Greg mass-fire people without a shred of emotion. A cold and calculated killing machine willing to follow corporate orders and not think of the humanity behind them. Wouldn’t it be fitting to see Greg become CEO, and his first act is to push out the Roy siblings?

What the ending may be, I think we know it will be discussed in the years to come. Succession is a masterclass in dark comedy, drama and top-tier story writing.

The post How Will Succession End? appeared first on I Like Kill Nerds.

View Details

If you’ve ever found yourself knee-deep in a pile of asynchronous Fetch API calls, you’ll understand the desire to have a method for controlling them — something akin to a dog whistle, but for your code. Enter the Fetch API’s Signals. And no, they’re not Morse code, semaphore flags, or even smoke signals. They’re a mechanism to control our fetch requests but with more grace and finesse than just shouting “STOP!” at your screen.

The Fetch API: A Quick BackstoryFetch API, a JavaScript interface for making requests to the server in the browser, has become quite the darling of the web development scene. However, it had one glaring drawback for the longest time: it was like a rogue puppy. Once you let it off the leash, there was no calling it back.

Luckily for us, the clever folks who look after the Fetch API introduced a way to abort fetch requests. It’s called the AbortController, and its signal property is not nearly as violent as it sounds.

Fetch Signals: A New Leash of LifeLet’s dive into how to use signals in Fetch. First things first, we need to instantiate an AbortController. In TypeScript, we can do it like this:

const controller = new AbortController(); When we create an AbortController, it comes with an attached AbortSignal (controller.signal). This signal can be passed to a fetch request like so:

fetch('https://api.example.com/data', { signal: controller.signal }) .then(response => response.json()) .then(data => console.log(data)) .catch(err => { if (err.name === 'AbortError') { console.log('Fetch aborted'); } else { console.error('Another error', err); } }); Now, if we want to abort this request, we can call controller.abort(). The fetch request will be immediately terminated, and the catch block will log “Fetch aborted”.

A Real-World Scenario: Fetch, Sit, StayImagine you have a search feature on your site. As the user types, you fetch results from the server. If a new key is pressed before the fetch is complete, you want to cancel the old request before starting a new one. Here’s how we might handle that:

let controller = new AbortController();document.querySelector('#search').addEventListener('keyup', (event) => { // Abort any previous fetches controller.abort(); // Create a new AbortController controller = new AbortController(); fetch(`https://api.example.com/search?q=${event.target.value}`, { signal: controller.signal }) .then(response => response.json()) .then(data => console.log(data)) .catch(err => { if (err.name === 'AbortError') { console.log('Fetch aborted'); } else { console.error('Another error', err); } });}); In this code, whenever a keyup event happens, we abort the previous fetch and start a new one. This keeps our fetches aligned with our user’s input and avoids duplicating redundant requests.

ConclusionFetch API’s Signals is a wonderful tool that can help you regain control over your fetch requests. They’re like a well-trained retriever, fetching exactly what you want and dropping it when you say “leave it”.

Remember, with great power comes great responsibility. Don’t become the crazy cat person of fetch requests. Instead, use signals to keep your requests in check.

The post Fetch Signals: The Dog Whistle for Your Asynchronous Fetch API Calls appeared first on I Like Kill Nerds.

View Details

It’s no secret that artificial intelligence is booming. With the advent of ChatGPT in 2022, AI is becoming a hot topic. Naturally, many developers are also increasingly interested in building with AI, and there is no shortage of resources to learn from and reference.

There are a couple of glaring roadblocks of sorts right now. Most AI tutorials and resources are focused on Python and vector databases like Pinecone or Supabase PostgreSQL. These are great options, and I recommend learning them, but what about the TypeScript/Javascript and Node.js crowd who wants to experiment?

So, I set myself a challenge. Could I build an AI-based application that leverages OpenAI GPT APIs, works with vectors and doesn’t require Python or a vector database? It turns out the answer to that challenge is: absolutely.

Going even further, I wanted to avoid libraries like Langchain. The way I’ve done things here is the difficult way. You’d use a library like Langchain (or equivalent) in a real-world application instead. I’ve got an example of a Langchain-based solution I created here.

This is a classic example of doing everything the hard way and is a good introduction to working with OpenAI APIs. Because there are natural language concepts like cosine similarity and other concepts power many of these tools and libraries, like Langchain, do for you.

P.S. If you’re looking for the code to perform the embedding search, scroll down a bit.

Building a scraperThe first port of call was to create a script that scraped my blog (the one you’re reading now) and make a CSV content file.

As you will see in the below file, I load my blog, and then, using Cheerio, I scrape the HTML. It’s a big file because I am a stickler for TypeScript typing. Because we don’t want to send massive bodies of text to the API and incur a huge bill, we scrape the content and chunk it (break large content up into smaller chunks).

/* eslint-disable prettier/prettier */import axios from 'axios';import cheerio from 'cheerio';import { stringify } from 'csv-stringify';import { encode } from 'gpt-3-encoder';import fs from 'fs';const url = (page: number): string => `https://ilikekillnerds.com/page/${page}`;interface ChunkedContent { content: string; tokens: number;}interface PostData { title: string; content: string; tokens: number; url: string; postId: number | null; publishDate: string | null; chunkId: number;}const scrapePage = async (page: number): Promise<string[]> => { const response = await axios.get(url(page)); const $ = cheerio.load(response.data); const articles = $('article'); const postLinks: string[] = []; articles.each((\_i, article) => { const link = $(article).find('.entry-title a').attr('href'); postLinks.push(link); }); return postLinks;};const fetchPostData = async (url: string): Promise<PostData[]> => { const response = await axios.get(url); const $ = cheerio.load(response.data); const title = $('h1.entry-title').text().replace(/\s+/g, ' '); const content = $('.entry-content *') .not('img, iframe, figure, pre > code, code, video, picture') .text() .replace(/\s+/g, ' ') .replace(/\.([a-zA-Z])/g, '. $1'); const chunkedContent = chunkContentByTokens(content, 200); // Extract post ID const bodyClass = $('body').attr('class'); const postIdRegex = /postid-(\d+)/; const postIdMatch = postIdRegex.exec(bodyClass); const postId = postIdMatch ? parseInt(postIdMatch[1], 10) : null; // Extract and format publish date const publishedTime = $('meta[property="article:published\_time"]').attr( 'content', ); const publishDate = formatDate(publishedTime); // Get the title, content, token length, url, post ID and publish date return chunkedContent.map((chunk, index) => ({ title, content: chunk.content, tokens: chunk.tokens, url, postId, publishDate, chunkId: index + 1, }));};// This sub function breaks up content using loose token math to ensure scraped content// isn't too big (or we'll blow out the cost of our AI calls)const chunkContentByTokens = ( content: string, maxTokens: number,): ChunkedContent[] => { const sentences = content.split('. '); const chunkedContent: ChunkedContent[] = []; let currentChunk = ''; let currentTokens = 0; for (const sentence of sentences) { const sentenceTokens = encode(sentence).length; if (currentTokens + sentenceTokens <= maxTokens) { currentChunk += `${sentence}. `; currentTokens += sentenceTokens; } else { chunkedContent.push({ content: currentChunk.trim(), tokens: currentTokens, }); currentChunk = `${sentence}. `; currentTokens = sentenceTokens; } } if (currentChunk) { chunkedContent.push({ content: currentChunk.trim(), tokens: currentTokens, }); } return chunkedContent;};// Could be replaced with a package or simpler codeconst formatDate = (dateString: string | undefined): string | null => { if (!dateString) return null; const date = new Date(dateString); const monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ]; const month = monthNames[date.getMonth()]; const day = date.getDate(); const year = date.getFullYear(); return `${month} ${day}, ${year}`;};(async () => { let page = 1; let processing = true; const results: PostData[][] = []; while (processing && page != 51) { const postLinks = await scrapePage(page); if (postLinks.length === 0) { processing = false; break; } for (const link of postLinks) { const postData = await fetchPostData(link); results.push(postData); }l page++; } const combinedResults: PostData[] = []; for (const result of results) { combinedResults.push(...result); } stringify( combinedResults, { header: true, columns: [ 'title', 'content', 'url', 'tokens', 'postId', 'publishDate', 'chunkId', ], }, (err, output) => { if (err) { console.error(err); return; } fs.writeFileSync('posts.csv', output); }, );})(); As you can see in the generated CSV file in the screenshot below, the same blog post appears multiple times (this is due to our quick and dirty chunking):

Create the vector embeddingsNow that we have the CSV file, the next step is to convert it to vector embeddings. OpenAI provides an API that does this and is quite affordable. I sent up seven years’ worth of blog posts, and I don’t think it cost more than $2 (I think even less).

Once again, I used TypeScript and Node.js to generate the embeddings:

/* eslint-disable prettier/prettier */import fs from 'fs';import csvParser from 'csv-parser';import { Configuration, OpenAIApi } from 'openai';interface DataRow { content: string; url: string; title: string; publishDate: string; postId: string; chunkId: string; [key: string]: string;}interface EmbeddingEntry { embeddings: number[]; content: string; url: string; title: string; publishDate: string; postId: string; chunkId: string;}const config = new Configuration({ apiKey: process.env.OPENAI\_API\_KEY, organization: process.env.OPENAI\_ORG\_ID,});const openai = new OpenAIApi(config);async function loadData(): Promise<DataRow[]> { const data: DataRow[] = []; return new Promise((resolve, reject) => { fs.createReadStream('scraped\_data.csv') .pipe(csvParser()) .on('data', (row: DataRow) => { data.push(row); }) .on('end', () => { resolve(data); }) .on('error', (error: Error) => { reject(error); }); });}async function getEmbedding(text: string): Promise<number[]> { const response = await openai.createEmbedding({ input: text, model: 'text-embedding-ada-002', // We use the embedding model= }); return response.data.data[0].embedding;}async function generateEmbeddings(): Promise<void> { const data = await loadData(); const embeddings: { [key: string]: EmbeddingEntry } = {}; for (const row of data) { const contentEmbedding = await getEmbedding(row.content); const chunkKey = `${row.postId}\_${row.chunkId}`; embeddings[chunkKey] = { embeddings: contentEmbedding, content: row.content, url: row.url, title: row.title, publishDate: row.publishDate, postId: row.postId, chunkId: row.chunkId, }; console.log('Saved embedding for post', row.postId, 'chunk', row.chunkId); await new Promise((resolve) => setTimeout(resolve, 200)); // Add delay between requests } fs.writeFileSync('embeddings.json', JSON.stringify(embeddings)); console.log('Embeddings saved');}generateEmbeddings(); In this step, we iterate over the content in our CSV file and send it to OpenAI to get back the embeddings. You will notice that we then write the contents to a file called embeddings.json which is going to act as our database.

Building the brains of the operationOnce we have the embeddings, we’ll write some TypeScript to take these embeddings and make them searchable. We want users to be able to ask questions about content. I am using my blog posts, but you could make this work with documents or any other type of content. Admittedly, most of the work was getting the content and chunking it.

You will need to make sure the openai package is installed.

import * as fs from 'fs';import { Configuration, OpenAIApi, ChatCompletionRequestMessageRoleEnum,} from 'openai';interface EmbeddingData { embeddings: number[]; content: string; title: string; url: string; publishDate: string; postId: string; chunkId: string;}interface ScoreData { [key: string]: { postId: string; title: string; url: string; publishDate: string; content: string; score: number; };}const SYSTEM\_PROMPT = `You are a blog searching chatbot for ilikekillnerds.com. Only answer the question by using the provided context. If you are unable to answer the question using the provided context, say you do not know the answer. The current year is ${new Date().getFullYear()}. When responding, do not refer to the provided content as 'the context' as it is implied already. Also, instead of author, refer to the author as Dwayne.`;const EMBEDDING\_MODEL = 'text-embedding-ada-002';const COMPLETIONS\_MODEL = 'gpt-3.5-turbo';const OPEN\_AI\_KEY = '';const OPEN\_AI\_ORG = '';const configuration = new Configuration({apiKey: this.openaiKey, organization: this.organizationId,});const openai = new OpenAIApi(configuration);function dotProduct(vectorA: number[], vectorB: number[]): number {return vectorA.reduce((sum, a, index) => sum + a * vectorB[index], 0);}function magnitude(vector: number[]): number {return Math.sqrt(vector.reduce((sum, value) => sum + value * value, 0));}function cosineSimilarity(vectorA: number[], vectorB: number[]): number { const product = this.dotProduct(vectorA, vectorB); const magnitudeA = this.magnitude(vectorA); const magnitudeB = this.magnitude(vectorB); return product / (magnitudeA * magnitudeB);}async function getEmbedding(text: string): Promise<number[]> { const response = await openai.createEmbedding({ input: text, model: EMBEDDING\_MODEL, }); return response.data.data[0].embedding;}// A lot of the contents of this file could be replaced with vector database queriesasync function search(query: string): Promise<any[]> {const embeddingsData = JSON.parse( fs.readFileSync('embeddings.json', 'utf8'),);const queryEmbedding = await getEmbedding(query);const scores = Object.entries(embeddingsData).reduce<ScoreData>( (acc, [chunkKey, data]: [string, EmbeddingData]) => { const contentEmbedding = data.embeddings; const content = data.content; const title = data.title; const url = data.url; const publishDate = data.publishDate; const postId = data.postId; const score = this.cosineSimilarity(queryEmbedding, contentEmbedding); if (acc[postId]) { if (acc[postId].score < score) { acc[postId] = { postId, title, url, publishDate, content, score, }; } } else { acc[postId] = { postId, title, url, publishDate, content, score, }; } return acc; }, {},);const sortedScores = Object.values(scores).sort( (a: { score: number }, b: { score: number }) => b.score - a.score,);return sortedScores.slice(0, 5);}async function getAnswer(query: string): Promise<string> {const mostRelevantItem = (await search(query))[0];const messages = [ { role: ChatCompletionRequestMessageRoleEnum.System, content: `${SYSTEM\_PROMPT} \n\n --- This provided blog post was published at the following URL: ${mostRelevantItem.url} on ${mostRelevantItem.publishDate}. When answering the user, provide a link to this post. --- ${mostRelevantItem.content}`, }, { role: ChatCompletionRequestMessageRoleEnum.User, content: query, },];const response = await openai.createChatCompletion({model: COMPLETIONS\_MODEL, messages, max\_tokens: 2000, temperature: 0.0,});return response.data.choices[0].message.content;} Wow. What a mouthful. Okay, so a few things. Because this is a dependency-free implementation (save for the OpenAI SDK), we are doing some mathematical heavy lifting ourselves. You could replace the cosine similarity and other functions with existing packages, but learning this stuff for yourself is more fun.

What’s with the nerdy math functions?Let’s break down each function (dotProduct, magnitude and cosineSimilarity). Also, please keep in mind I am not an expert. I am a front-end developer still learning how all this AI stuff works. Feel free to correct me if you spot a mistake in my explanations here.

  1. dotProduct(vectorA: number[], vectorB: number[]): number
    This function calculates the dot product of two vectors, vectorA and vectorB. The dot product is the sum of the products of their corresponding components. The function uses the reduce method to calculate this sum, taking an initial value of 0 and then iterating over each element a of vectorA while using its index to access the corresponding element in vectorB. The product of the two elements (a * vectorB[index]) is added to the current sum during each iteration.
  2. magnitude(vector: number[]): number
    This function calculates the magnitude of a vector. A vector’s magnitude (or length) is the square root of the sum of the squares of its components. This function uses the reduce method to calculate the sum of squares, starting with an initial value of 0 and then iterating over each element value of the vector. The square of each element (value * value) is added to the current sum during each iteration. Finally, the square root of the sum is calculated using Math.sqrt.
  3. cosineSimilarity(vectorA: number[], vectorB: number[]): number
    This function calculates the cosine similarity between two vectors, vectorA and vectorB. Cosine similarity is a measure of similarity between two non-zero vectors calculated by dividing the dot product of the vectors by the product of their magnitudes. The function first calculates the dot product of the two vectors using the dotProduct function. Then, it calculates the magnitudes of both vectors using the magnitude function. Finally, it calculates the cosine similarity by dividing the dot product by the product of the magnitudes.

The getEmbedding function is self-explanatory. We converted our content into vectors, but when the user asks a question, we also have to turn that into a vector. This allows us to get the most relevant content, which will be fed to the API later.

The brain brain of the operationMost of the heavy lifting in our code is the search function. It’s intimidating to look at, and I wrote it. Once again, there are most likely better ways to write this stuff and packages you can leverage. This function searches for the most relevant results based on a given text query using cosine similarity.

  1. embeddingsData is created by reading and parsing the ’embeddings.json’ file. The file is assumed to contain an object with keys representing document IDs (postId) and their corresponding embedding data (content, title, URL, publish date, and embeddings).
  2. The queryEmbedding is obtained by calling the getEmbedding function with the input query string. It is responsible for generating an embedding vector for the input query.
  3. The scores object is created by iterating over the embeddingsData using the reduce method. For each entry ([chunkKey, data]), the function calculates the cosine similarity between the query embedding (queryEmbedding) and the content embedding (contentEmbedding) using the cosineSimilarity function. It compares the query to our blog posts.
  4. If there is an existing entry for the current postId in the scores object, the function checks if the new score is higher than the existing score. If the new score is higher, it updates the entry with the new score and related data (postId, title, URL, publish date, content, and score). If there is no existing entry for the current postId, it creates a new entry in the scores object. We do this because we chunk content, so the same blog post might appear multiple times.
  5. The sortedScores object is created by converting the scores object to an array and then sorting the array in descending order based on the cosine similarity scores.
  6. The function returns the top 5 results by slicing the sorted array using sortedScores.slice(0, 5). You can modify this to return more or less. This code here makes a great AI powered search.

This search function can perform a content-based search, returning the top 5 most relevant results based on the input query. The search is performed by comparing the query’s embedding with the precomputed embeddings of the content in the ’embeddings.json’ file using cosine similarity.

Finally the getAnswer function is where we produce our response to the provided query. The function uses the GPT API to generate an answer based on the most relevant content found through the search function.

  1. The function calls search(query) to search for the most relevant content based on the input query string. It then takes the first result (most relevant item) from the returned array.
  2. It creates a messages array with two objects:
  3. The first object has the role of “System” and content that includes a system prompt, the URL and publish date of the most relevant item found and the content of the most relevant item.
  4. The second object has a ” User ” role and content equal to the input query string.
  5. The function calls openai.createChatCompletion with the necessary parameters to generate an answer using the external AI model. The parameters include the model name, the messages array, a maximum token limit of 2000, and a temperature of 0.0. The temperature parameter controls the randomness of the generated text; a value of 0.0 means the model will produce deterministic output (i.e., the same output for the same input). The higher you go towards 1, the more random the results will be, and GPT will hallucinate.
  6. The AI model returns a response object containing generated choices, each containing a message object. The function extracts the content of the message object from the first choice (response.data.choices[0].message.content) and returns it as the answer.

ConclusionThis gives us a functional Node.js application that leverages the OpenAI GPT API and doesn’t have a database or any dependencies. Once again, this is a learning exercise, not the recommended approach. Fortunately, Langchain handles a lot of the complexity we implemented above, and I have an example on GitHub here.

The post Working With AI Using TypeScript and Node.js Without Needing to Use Vector Databases appeared first on I Like Kill Nerds.

View Details

I first wrote about derails of the long awaited desktop editor for the Quad Cortex back in February 2022. At that point, it had been revealed a team had been working on the editor for months. Here we are fourteen months later and we have confirmation of a release.

In their April 2023 update, they revealed they’ll be showing off a beta of Cortex Control at NAMM. On top of that, the QC’s will also be running CorOS 2.1.0 beta as well to support the editor.

Now, we know from community efforts like OpenCortex that the Quad Cortex has been capable of VNC like remote access for a whole now. The QC essentially runs a server. Presumably the desktop editor will work in a similar way to open source efforts. It’ll be interesting if this opens up the possibility of reverse engineering the desktop app and allowing the community to create their own clients.

The remaining question on everyone’s lips is still: when is the Quad Cortex going to get plugin support? A question still don’t have an answer to.

The post The Quad Cortex Desktop Editor is Finally Announced appeared first on I Like Kill Nerds.

View Details

Only a few readers of this blog might know I am a serial Kickstarter backer. Fortunately, I’ve backed tens of projects over the last few years and have yet to back something that didn’t eventually deliver. One of the most recent projects I backed was the SES Ultra Screwdriver. Considering there isn’t much info about it yet, I wanted to share my first impressions and anything you should know about this.

I opted for the non-motion control model. I just wanted a simple adjustable screwdriver, so I got the SES Ultra Plus.

Packaging and first impressionsBefore we get into the features and other bits and pieces, we’ll briefly discuss my first impressions. With Kickstarter projects, you never know if the project pitch will be the same as the final product. Before I even opened the screwdriver, it was nicely boxed in a sturdy white box with exterior branded black packaging. Subtle and not too over the top. My hunch was this would be a quality product before even using it.

Inside the box is a long sturdy zip-up case that resembles a Nintendo Switch travel case, except a little wider. Inside that case is a rugged aluminium case which is impressively built. It feels sturdy, like you could drop it, and it wouldn’t break (I wasn’t game enough to find out). Pressing on the bottom of the case, the charger holding the screwdriver and bits slide out. Strong magnets hold the bits in.

Enough about the packaging, but the packaging is essential. The first time someone experiences your product can make the customer feel like they bought something high-quality or cheap.

Features and specificationsIf you’re just a Kickstarter backer excitingly awaiting your SES Ultra screwdriver to arrive, you already know about these features and can skip to the next section. The MAX model has Bluetooth and Smart Motion Control (not listed), but the other specs are the same for both models.

  • 4 kgf.cm torque force
  • 70 S2 steel bits
  • Five torque modes
  • 500mAh Lithium-ion battery
  • OLED display
  • LED illuminated tip that lights up what you’re screwing
  • Aluminium outer case with interior plastic USB-C charging case. The underside of the aluminium case has a magnetised pad for holding bits. The case also has an in-built magnetiser to keep your bits magnetised
  • It will automatically switch to manual mode allowing you to use it manually if the electric mode can’t provide enough torque.

Putting it to useFirstly, the SES feels premium in your hands. The material’s shape, feel, and square-like edges give you an excellent grip on this. It’s slightly weighted but very light and is comparable to a regular magnetised screwdriver. The little details make this screwdriver feel nice besides the engineer of the screwdriver itself.

The way the screwdriver snaps into the case. It’s surprisingly satisfying. The magnets feel high-quality; you can feel the screwdriver snap into place and hear it. Like an expensive car door being closed, it just sounds pleasant.

Another excellent detail is how easy it is to get the screwdriver out of the tray and the bits. I’ve owned plenty of screwdriver sets and handheld screwdrivers with bits. They’re often clicked into place in moulded plastic and are sometimes a pain to put in and get out. The SES case holds the bits into place using solid magnets, which are solid but easy to get out. I appreciate that Arrowmax had the foresight to leave space around the bits to get your fingers in there to unseat them easily.

And then you have the OLED screen. As you’re holding down the directional buttons, it displays the direction of the screw on the screen, which animates, and it’s a nice touch. The screen is nice and bright (like a good OLED should be). The LEDS at the top where the bits attach are also nice when working in a small space (like a phone or computer tower).

I don’t need a screwdriver that often, but I play guitar and service my guitars. I, fortunately, had a guitar that needed some machine heads replaced, and this is the first thing I used my SES Ultra Screwdriver on. I set the screwdriver torque to the number 3 setting, chose my needed bit and went to work. It didn’t break a sweat; the number 3 setting was more than enough. I could have used setting 2.

Something worth noting is that heads are screwed into the wooden headstock of the guitar and aren’t very loose because they’ve been there since factory assembly. The screwdriver showed no signs of strain.

Using the screwdriver was a lot of fun; it made me look around the house for other things to take apart. I used the lower torque one setting to tighten my glasses (there are some great small bits for glasses). Then I took apart the remote to my ceiling fan (also torque setting one) and, using torque setting five, tried it out on some door hinge screws for the door that leads into my study.

The torque five setting is noticeably powerful. Unless you’re attempting to drill into masonry or something where a drill would be better suited, I honestly can’t see the SES Ultra struggling to achieve most screwdriver-based tasks. It won’t help you assemble flatpack furniture, but if you’re repairing gadgets or need a screwdriver for a quick task, this is what you want. Plus, it’s a lot of fun to use.

Who would have thought a battery-operated screwdriver could be so much fun?

A few shotsIf you’re wanting a few shots of what it looks like, see below for a few basic photos. I didn’t photograph the packaging, just the screwdriver and the case. The photos don’t do it justice; the lighting was terrible. But you can see, it’s very much a real product.

ConclusionOverall, the SES Ultra is way better than I was expecting it to be. If you’re using the SES Ultra for what it is intended for (small electronics and other things), it does the job impressively. I can’t speak for the MAX version with the motion control feature and Bluetooth, but given how impressive the Ultra is, I am tempted to buy another one. And that should tell you all you need to know about this screwdriver: it’s worth buying again.

If you’re interested in getting one yourself, they’re currently being sold on Indiegogo here.

The post A Review of The Arrowmax SES Ultra Plus Screwdriver appeared first on I Like Kill Nerds.

View Details

As developers, we often find ourselves forking open-source projects on GitHub to contribute or to modify for our specific needs. While creating a fork is a simple process, keeping it up-to-date with the original repository can sometimes be confusing. In this blog post, we will explore the steps required to keep your GitHub fork updated with the latest changes from the upstream repository.

Step 1: Configure the Upstream RepositoryTo keep your fork updated, you must first configure the upstream repository – the original project from which you created your fork. This ensures you can easily fetch the latest changes from the upstream repository.

  1. Navigate to your forked repository on GitHub.
  2. Open a terminal and change to the local directory containing your fork’s cloned repository.
  3. Run the following command to list the current configured remote repositories: git remote -v
  4. If you don’t see an upstream repository listed, add one using the following command (replacing ‘upstream-url’ with the original repository’s clone URL): git remote add upstream upstream-url

Step 2: Fetch Upstream ChangesNow that you have the upstream repository configured, you can fetch the latest changes from it. To do this, run the following command: git fetch upstream

This command fetches the latest changes from the upstream repository without merging them into your local branch. You can now see the changes by running: git log upstream/main

Replace ‘main’ with the appropriate branch name if the upstream repository uses a different default branch.

Step 3: Rebase Your Local BranchFirst, ensure you’re on the correct branch:

git checkout main Replace ‘main’ with the appropriate branch name if needed.

Next, rebase your local branch with the upstream changes:

git rebase upstream/main This command will apply your commits on top of the latest changes from the upstream repository, resulting in a linear commit history.

If you encounter any conflicts during the rebase, Git will pause the process and ask you to resolve them. Edit the conflicting files, save your changes, and then stage the resolved files with the following:

git add path/to/conflicting/file Continue the rebase process with:

git rebase --continue Repeat the conflict resolution process until all conflicts have been resolved and the rebase is complete.

Step 4: Push Changes to Your ForkAfter rebasing, you must force-push the changes to your fork on GitHub, as the commit history has been modified. Use the following command to do this:

git push -f origin main Replace ‘main’ with the appropriate branch name if needed. Your fork is now up-to-date with the latest changes from the upstream repository.

ConclusionRebasing is an excellent alternative to merging when keeping a GitHub fork updated. It creates a cleaner, linear commit history that can be easier to understand and manage. However, be cautious when using git push -f, as it can overwrite remote changes if not used correctly. Ensure you push to the correct branch and remote repository to avoid potential issues.

The post Keeping a GitHub Fork Updated appeared first on I Like Kill Nerds.

View Details

In recent years, we’ve seen an unprecedented rise in the development and adoption of artificial intelligence (AI) tools, such as OpenAI’s ChatGPT. As AI becomes increasingly integrated into our daily lives, it’s essential to ask whether governments should step in and regulate these technologies.

While some argue that ChatGPT is a glorified sentence constructor and poses no real threat, others believe that regulation is necessary to prevent misuse and ensure ethical practices. In this article, we’ll explore both perspectives and attempt to determine whether AI regulation is needed.

I talk about ChatGPT in this article, but the argument applies to all emerging AI tools that work similarly to GPT.

Why Regulation Seems Silly: The Sentence Constructor ArgumentAt its core, ChatGPT is a language model designed to process and generate human-like text. Some argue that regulating such tools is unnecessary since they’re nothing more than advanced sentence constructors. Here are a few reasons to support this view:

  1. Limited Sentience: Unlike humans, ChatGPT doesn’t possess consciousness, emotions, or the ability to think critically. It relies on pre-trained data to generate responses, lacking genuine understanding and intent.
  2. User Control: The output of AI tools like ChatGPT is primarily determined by the user’s input. The responsibility lies with the user rather than the technology itself.
  3. Precedent for Self-Regulation: Historically, emerging technologies have often adapted and evolved through self-regulation. Tech companies and AI developers may be better equipped to address ethical concerns and implement best practices without government interference.

Why Regulation Might Be Necessary: The Potential Threat ArgumentOn the other hand, there are valid concerns about the potential negative impacts of AI tools like ChatGPT, which could justify government regulation. These concerns include the following:

  1. Misuse and Malicious Intent: While AI tools may not have their own intentions, they can be misused by users with malicious goals, such as spreading disinformation, hate speech, or engaging in cybercrime. ChatGPT has been used to create malware before or find exploits in software.
  2. Bias and Discrimination: AI models like ChatGPT are trained on vast datasets containing human-generated content, which can inadvertently introduce biases into the generated responses. Regulation may be necessary to ensure AI tools are transparent and designed to reduce potential bias.
  3. Ethical and Privacy Concerns: AI tools like consent and data privacy can raise ethical questions. Regulation may be required to establish ethical guidelines and protect user privacy. This is why ChatGPT is currently blocked in Italy over privacy concerns.

The Middle Ground: Striking a BalanceAs with many emerging technologies, there’s no one-size-fits-all answer to whether AI tools like ChatGPT should be regulated. It’s essential to strike a balance that acknowledges the potential risks while not stifling innovation.

A possible approach involves creating regulatory frameworks focusing on specific AI aspects, such as data privacy, transparency, and accountability. This approach would allow governments to address valid concerns without hindering the development and growth of AI technologies.

One of the problems is this is all emerging. AI is a relatively new thing. It’s like the emergence of the internet or social media all over again. If we do implement a regulatory framework, how is it enforced, and are governments even equipped to regulate such things while ensuring the essence of a free market remains?

ConclusionThe debate surrounding AI regulation is complex and multifaceted. While AI tools like ChatGPT can be seen as glorified sentence constructors, it’s essential to recognize their potential risks and ensure responsible use. Striking a balance between innovation and regulation is key to fostering a thriving AI ecosystem that benefits society. Ultimately, the decision to regulate AI tools should be informed by ongoing dialogue, research, and a thorough understanding of the technology’s potential impacts.

The post ChatGPT: A Glorified Sentence Constructor or a Potential Threat? Should Governments Regulate AI? appeared first on I Like Kill Nerds.

View Details

I’ve heard about Notion for years, and admittedly, I wrote it off as a fancy writing application until recently when I used it at work and got exposed to everything it can do. I’m also averse to overhyped things (it wasn’t until Breaking Bad was in its third season I succumbed to the hype and watched the show).

As a developer, I have a lot on my plate. Between the consulting and freelancing work I do, there are numerous things that I have to manage daily. That’s why I’m always looking for productivity tools that can help me streamline my work and keep me on track.

I have tested countless apps in the past that promised to enhance productivity and workflow, but most of them required a significant change in the way I worked or thought. Adapting to new methodologies and systems was quite difficult, so I reverted to my tried and tested approach of using Trello, which has always been a reliable tool.

However, with the advent of Notion, a multifunctional app that claims to be capable of performing a plethora of amazing tasks, I can’t help but wonder if it is truly a game-changing app or just another hyped-up application. Can it deliver on its promises and revolutionise the way we work?

Existing apps that Notion can replaceAt a glance, Notion can replace the following popular apps (and even more with its integrations support)

  • Trello
  • Evernote
  • Google Docs
  • Google Sheets
  • Asana
  • Airtable

Notion’s ability to integrate with other apps and services, such as Slack and Google Drive, adds to its appeal as a productivity tool. Its customisability and flexibility make it a powerful tool for managing tasks, notes, and projects all in one place.

I don’t know about you, but it’s a red flag to me when a restaurant has too many items on the menu and an app with too many features and promises.

AI WritingOne of my favourite features in Notion is the AI writing functionality. This feature allows you to leverage the ChatGPT-like functionality to generate original context, rewrite existing content and more. The AI functionality is incredibly versatile and can be used for various tasks. For example, you can brainstorm ideas for your next project, generate content for your website or social media channels, or even proofread your work.

I have used the AI functionality to write and proofread parts of this post you are reading. I was thoroughly impressed with the results, as the AI-generated high-quality content quickly and efficiently. While I am not sure if Notion is using GPT behind the scenes, it is clear that their AI functionality is top-notch and can help you save time and effort on a variety of tasks.

It is, sadly, an additional upgrade of $10 per month to get unlimited functionality, but I can tell you that it is well worth it.

For BloggingIf you’ve visited my blog before, you know I’ve been actively blogging for over 13 years. Writing a blog post can take hours, sometimes weeks, of effort before you hit the publish button.

My approach to drafting blog posts is to create a draft post in WordPress and then slowly work on it. However, this method can result in tens or hundreds of draft posts, making it easy to lose sight of older content.

With Notion, I now draft my blog posts and leverage AI features to expand dot points into fully-fledged sections. I then build upon those foundational sections to create complete posts. I’ve been able to come up with content ideas faster but still, stay true to my core as a blogger and not lose my tone of voice.

For Project ManagementSo, with Notion, you can create KanBan boards and other cool project management structures that help you keep track of all your project tasks and collateral (like marketing and tech specifications).

Notion’s Kanban board feature is especially useful for managing projects, allowing you to visualise your workflow and track task progress intuitively. With Notion, you can collaborate with team members in real time, assign tasks, and leave comments on specific items. While it may take some time to learn all of the app’s features, once you do, you’ll find that Notion is a powerful and flexible tool that can help you work smarter, not harder.

For WikisNotion provides a great platform for organising and sharing knowledge within your team for wikis. You can create a knowledge base containing articles, guides, and other resources your team can access and contribute to. Notion’s customisability means you can organise your wiki in a most useful way to your team, making it easy to find and share information.

Furthermore, you can set up tags and access to restrict who can access and edit parts of your wiki. It saves the hassle of using something else, like MediaWiki, with nothing to install.

For Technical Specification DocumentsNotion provides an excellent platform for technical documentation that allows you to create and share technical specification documents with your team. You can create tables, diagrams, and other visual aids to help illustrate your ideas and specifications. If you are scoping a technical project most likely comprised of multiple components, Notion allows you to divide those parts up and then collaboratively work with others to build it.

For Managing Your Personal LifeFor managing your personal life, Notion provides a great platform for organising your personal tasks, notes, and projects. You can create to-do lists, track habits, and journal your day. Its customisability and flexibility make it useful for keeping your life organised and productive. In our household, we use it to manage daily and weekly chores.

For StudentsWhether you’re learning a new programming language or managing your degree. Notion is an excellent tool for students, providing a platform for organising class notes, tracking assignments and deadlines, and managing study plans. You can create information databases, such as vocabulary lists or research topics, and share them with classmates or study groups. Additionally, Notion’s customisability allows you to tailor your study experience to your needs and learning style. My wife is currently studying, and while it took a bit to set up, she uses it to keep track of her semesters, take notes and more.

ConclusionWhile Notion may have been hyped up, it seems to be the real deal regarding productivity and project management. Its versatility and extensive features make it a valuable tool for individuals and teams.

If you’re looking for a productivity tool that can do it all, Notion may be the answer. With its customizability and flexibility, Notion can replace multiple apps and services, from Trello to Google Docs. Its AI writing functionality is also a game-changer, allowing you to generate high-quality content quickly and efficiently.

Maybe you were on the fence like I was. But I can tell you that you don’t have to be a project manager or writer to get value out of Notion. You can check it out by signing up for free here.

The post Is Notion Hype or The Real Deal? appeared first on I Like Kill Nerds.

View Details

Well, the rumours were true. GPT-4 has been announced, and it’s just as impressive as we had hoped. We’ve heard of big things for GPT-4 for months, so does the latest and greatest version of OpenAI’s hyped model live up to the hype?

For comparison, here is ChatGPT using GPT-3.5:

And here is ChatGPT using GPT-4:

The first thing you notice is reasoning is 5/5. Speed is 2/5, and conciseness is 4/5. The one thing you see before using GPT-4 is how it’s over half as fast as GPT-3.5. This is most likely due to the increased parameters the model deals with as it processes your inputs.

First ImpressionsThere is currently a cap which OpenAI says is a dynamic and temporary cap because it hasn’t been publicly released yet. Because I have ChatGPT Plus, I can access the GPT-4 model early. When writing this, my cap was 100 messages every 4 hours.

The first thing I noticed was GPT-4 is quite slow. I am used to the fast responses I get with GPT-3.5, but GPT-4 is very slow. The words seem to type slower. However, this might be an artificial speed constraint until publicly released. Or, it could be system load as the GPT-4 model might not have the required resources yet. I’ve seen GPT-3.5 respond to this slowly on the free version, so I imagine it will be faster.

But the second thing I noticed is the responses are a lot larger. In GPT-3.5, long responses weren’t uncommon to cut off part of the way through. You could type “continue”, and it would complete, but it was painful if you were generating code. GPT-4 can now handle up to 25,000 words of text.

In terms of tokens, GPT-4 has a context length of 8,192 tokens. Pretty much double the size of GPT-3.5, which is 4,096 tokens. More crazily, OpenAI also has a version of GPT-4, which supports 32,768 tokens. This isn’t available in ChatGPT right now, and I wonder if it will only be reserved for the API and Playground, not ChatGPT.

Quality of responsesDespite being a new model, the dataset is still the same 2021 cut-off data. As such, GPT-4 isn’t bringing any new information. Where things differ between GPT-3.5 and GPT-4 is how it interprets that data and returns it to you based on your inputs.

A simple test of GPT-4 capabilities is to take existing prompts and then re-run them through the new model in ChatGPT. Unbeknownst to some, I use ChatGPT to write satire. While the GPT-3.5 model did a fantastic job producing something, it produced robotic-sounding articles that didn’t meet the brief most of the time. It required some additional prompting and shaping to be something usable.

One problem I would always encounter is it loved to start off with, “In a shocking turn of events”, which gave it away that ChatGPT was being used. It would find another way to say something similar even when I told it not to. And it loved to say “In conclusion” at the end.

With GPT-4, I can tell you the end result is a night and day difference. GPT-3.5 wasn’t terrible, but the results aren’t fantastic. If I were a copywriter, GPT-3.5 would have been scary and GPT-4 terrifying. GPT-4 has reached a point where it can produce good and not only good but long results requiring minimal editing.

OpenAI also says that images can be used as input, and you can ask it to describe things in the image or boost a prompt without typing. Say, for example, take a drawing and some notes of a website, then produce the code for you.

ConclusionThe GPT-4 model is a significant leap in OpenAI’s models. It’s arguably the best model they have right now, which might be partly thanks to Microsoft’s involvement. The BingGPT integration was clearly using GPT-4 as the results were quite good, and now ChatGPT has the same level.

If ChatGPT 3.5 was seen as an assistant, ChatGPT 4 could be seen as a junior-level employee. It doesn’t get everything right, but it produces significantly better results, especially in writing. That should terrify authors, journalists and anyone that makes a living out of writing.

The post A Review of ChatGPT GPT-4 appeared first on I Like Kill Nerds.

View Details

Elon Musk, who needs no introduction, is at it again. This time, he has set his sights on the world of AI language models with his new venture, a competitor to ChatGPT. But before we delve into the nitty-gritty of this latest development, let’s talk about Elon Musk himself and the reputation he has garnered over the years.

Many people know him as the visionary entrepreneur who co-founded PayPal, launched the electric car company Tesla, and is leading the charge on space exploration with SpaceX. But behind the scenes, there are those who question his character and motives. Some have accused him of being a conman with a short attention span, easily losing interest in things once the initial excitement wears off.

One need only look at his recent acquisition of Twitter for $44 billion to see an example of this behaviour. Musk made headlines last year when he purchased the social media giant, only for Twitter to have been subjected to a series of troubling moves that equate to serious red flags, many decisions made without thinking them through and causing some negative fallout. It’s not hard to see why some may view this move as impulsive and lacking foresight.

So, what does all of this have to do with his new AI language model venture to try and compete with ChatGPT? Well, it raises the question of whether Musk’s involvement in this space is driven by genuine interest and commitment or if it’s just another shiny object that caught his eye. After all, this isn’t the first time he’s dabbled in AI, having previously been involved with OpenAI, a research institute focused on artificial intelligence, a company he now criticises.

But regardless of his motives, Musk’s involvement in the AI language model space is significant. ChatGPT, OpenAI’s flagship product, has been hailed as a breakthrough in natural language processing, capable of generating human-like text with startling accuracy. More competition is always good, especially in AI, and we are currently seeing an arms race amongst some of the bigger companies. For OpenAI to have a monopoly would be a bad thing. So, if Elon wants to level the playing field, it’s a good thing (if he can stay focused long enough to launch it).

Microsoft came out swinging with BingGPT, based on ChatGPT and leveraging what many believe to be close to GPT-4. Google has Bard (although it sounds like a garbage product at the moment). Elon has the connections to build a ChatGPT rival, but like his other ventures, will he lose interest when something new and shiny catches his eye?

The post Elon Musk Wants to Build a ChatGPT Competitor, Does He Have the Attention Span to Make It Happen? appeared first on I Like Kill Nerds.

View Details

As some of you know, I am an avid homebrewer. And, I love my IPA’s and Pale Ale style beers. Sadly, they’re often high in ABV (alcoholic content), and as I get older, I want to appreciate what I drink and not have to worry about the hangover the next day if I have too many.

That is where my interest in non-alcoholic beers came from. Not wanting to compromise on taste and mouthfeel, I set out to see if brewing a low-alcohol beer (<0.5%) without compromise was possible.

And that is where I learned about speciality yeasts specifically for brewing non-alcoholic beers. Specifically, the Fermentis SafBrew LA-01. What better way to experiment than an extract recipe? Because who wants to spend a day doing an all-grain brew only for it to fail?

So, I messed around in Brewersfriend to create a non-alcoholic IPA recipe at 0.5% ABV called Lightly Hopped Session IPA. By the way, if you’re a brewer and not already using it, I highly recommend Brewers Friend, a comprehensive recipe and brew app I’ve been using for years.

The speciality yeast gives you quite a bit of grace regarding the ABV, but you must watch the grains you use and how much you use them. 225g for each grain for a 23L fermenter was the sweet spot for this recipe, but you can experiment with different quantities and grains.

In a future post, I will let you know how it turned out.

The post Experimenting With Brewing a Non-alcoholic IPA appeared first on I Like Kill Nerds.

View Details

Being a remote worker, a good tech setup is essential. A comfortable chair, nice desk, well-positioned monitor and a keyboard and mouse you love. Then there are the other parts that people don’t think about as much: webcam and microphone.

Before buying the Microsoft Modern Wireless Headset, I was using an AT2020+ microphone on a boom arm, which I use for streaming and other purposes. Then I got the Blue Yeti X, a great microphone, my primary one. It’s a great microphone, but I have to adjust the audio levels with it through my interface routinely.

However, I realised I sit often and am terrible when taking breaks or leaving my computer. They do say sitting is the new smoking.

Sometimes I don’t need to sit at the computer on a call. Unless I am going over some code with someone, if it’s a meeting where we discuss work, I could be standing and walking around (something a wired headset or microphone doesn’t let you do). My monitor is still visible, but the ability to pace around my study would benefit my developer body.

And that realisation is what made me think of a wireless headset.

My initial search yielded some quite expensive headsets. I was shocked when I saw some for $300+, then even more shocked when the prices kept going up past $1k. I am sure the expensive wireless headsets are great, but I just wanted a comfortable one that won’t bankrupt me and have decent sound quality.

And that’s when I came across the Microsoft Modern Wireless Headset.

It ticked all of the boxes:

  • Good reviews
  • Affordable
  • Built for audio calls
  • It’s a Microsoft product, so it would be easier to replace it if it’s faulty.

Like everything I buy, even the cheap things, I research extensively. The Modern Wireless Headset seems to be a highly-rated headset for the price. While it is marketed as a Microsoft Teams-compatible headset, it will work with any application. Furthermore, you can even use it with your phone if you like. Some say they use it for music, but I am a bit of an audiophile and don’t think I could bring myself to do that.

For the price, I was expecting the headset to leave my head or ears sore, but Microsoft seems to have surprisingly built an affordable headset that doesn’t comprise comfort. I unknowingly leave the headset on even when not on a call or listening to music. The battery life is also surprisingly good. I am not sure of the claim of 50 hours as I am in the habit of charging my devices at the end of the day.

And just when you thought things couldn’t get any better, I tested this headset on Ubuntu Linux, and it worked out of the box. No drivers were needed, as Ubuntu recognised it and allowed me to use it.

Are there better headsets out there? Undoubtedly. But you can’t go wrong if you’re like me and just wanted a headset specifically for audio calls. The Microsoft Modern Wireless headset gets the job done without breaking the bank.

The post Microsoft Modern Wireless Headset Review appeared first on I Like Kill Nerds.

View Details

Australia is a technology backwater, so we are no strangers to being left behind when it comes to the latest in wireless standards and internet speeds. Specifically, 5G promises to be bigger and better than 4G and the other protocols that came before it. I don’t know about you and whether disappointment is a global phenomenon, but I have found 5G quite disappointing.

With 5G, we’re talking about potential speeds of up to 10 Gbps, compared to 4G’s maximum theoretical download speed of 100 Mbps in the real world. That’s a significant improvement, but real-world speeds will vary based on several factors. The reality is nobody is getting anywhere near 10 Gbps outside of a lab.

One of the main advantages of 5G is its low latency. Latency is the delay between when you request data and when it’s actually delivered. With 5G, latency is expected to be as low as one millisecond, significantly faster than 4G’s latency of around 30-50 milliseconds. But if you’re uploading photos to Instagram or watching cat videos on YouTube, you probably don’t notice the latency on 4G anyway.

Another issue with 5G is its coverage. 5G relies on high-frequency millimetre waves, which have a shorter range and can’t penetrate obstacles like buildings and trees as easily as 4G’s lower-frequency waves. This means you must be close to a 5G transmitter to get a good connection, and obstacles can affect the signal. In contrast, 4G uses lower-frequency waves that can penetrate obstacles better, making it more reliable in some cases.

The reality is the only time I have noticed things being faster while on 5G is when I am in the CBD of a major city or, strangely enough, inside a large shopping centre. It seems major shopping centres mostly have good 5G in Australia (probably so the telco stores can sell you a 5G device). However, don’t be surprised once you leave the CBD’s tiny permitter, walk between skyscrapers or walk through the shopping centre doors to your car to see your phone go back to 4G or worse.

There are several reasons for the lacklustre performance of 5G. First, 5G requires more infrastructure than 4G, so telcos must invest in more antennas and base stations to provide widespread coverage. This can be costly and time-consuming, and it’s one of the reasons why 5G coverage is currently limited to certain areas.

Another reason is that the technology is still relatively new, and some teething issues still need to be ironed out. For example, 5G technology is still evolving, and different countries use different frequencies and network technologies, which can cause compatibility issues.

5G is not the game-changer it was hyped up to be, at least not yet. While 5G promises faster speeds and lower latency than 4G, its performance can be affected by several factors, including distance from the transmitter, obstacles, and infrastructure. In contrast, 4G is a reliable and fast option with widespread coverage and better signal penetration in areas with obstacles.

I still encounter numerous dead spots in Australia where I can’t even get 4G. I am not talking about remote regional places without water or electricity. I am talking about suburbs 10-20 kilometres from the CBD. So, even if 5G is improved in the next few years, there will still be parts where you can’t even get 4G.

As much as I would love faster speeds (because faster is always better), I haven’t felt that 4G is not enough. For most uses on your phone or tablet, 4G is plenty fast. You’re not downloading torrents or hosting a web server on your phone, and you’re also not playing competitive games like Dota 2 that require minuscule latency either.

I see 5G playing a significant part in future IOT, virtual and mixed reality applications. We will probably see connected cars that can talk to each other (similar to protocols planes use to notify other planes of their presence.) and other cool things. But, for now, 4G is still the king in my eyes.

The post 5G Is a Bit of a Disappointment So Far appeared first on I Like Kill Nerds.

View Details

I was really rooting for Microsoft with its ChatGPT integration into the Bing search engine. You might have seen the hype, including the hilarious controversy around Bing’s ChatGPT threatening journalists and being easily provoked.

After a few weeks of closed access and insurmountable hype, Microsoft has opened the floodgates to many more people, and Bing’s ChatGPT integration is a dismal disappointment.

Perhaps the passive-aggressive and threatening nature of Microsoft’s ChatGPT integration forced their hand. Still, after trying it for a while, it’s clear it isn’t a rival to the original ChatGPT anymore. Despite having access to up-to-date information, it has been dumbed down as it’s obvious Microsoft has cut both legs off to get it under control.

The BingGPT is very cautious now. If you ask it harmless questions, it gets to the point where it will cut you off and say it can’t talk to you anymore.

Take this interaction I had with BingGPT via the Bing Android app. I asked it what it thought about me. It commented about how I am a developer and write technical articles for the customer service industry (which is incorrect). When I tried to correct Bing, it said it preferred not to continue the conversation and stopped responding. All subsequent attempts to get it to talk were met with silence.

That’s not to say Bing with ChatGPT is entirely terrible. For news, for example, it’s helpful to ask questions if you have heard something happening but were unsure or wanted further context. The Jake Paul vs Tyson Fury fight is a good example. I wanted to know if Bing knew Paul lost, and it did.

There was also an alleged script leak for the fight, which hasn’t been proven true as Bing explained it said Paul was meant to win by knockout in round eight.

I think the early reviews and talk of Bing’s ChatGPT integration made it seem like Bing would be offering an untethered version of ChatGPT, it makes sense that they’re not, as it would compete with ChatGPT, right?

Still, all the talk we got of this intelligent internet-connected algorithmic AI has been tapered somewhat, undoubtedly driven by the fact Microsoft’s version has been routinely described as unhinged and out of control. Allegedly GPT-4 has been delayed, possibly by the Microsoft launch of BingGPT, citing ethical reasons.

Maybe we will see Microsoft turn the dial back up to 11, but I think Microsoft has lost a profound opportunity to go toe-to-toe with Google here and take a chunk of their search dominance. BingGPT for the newcomers is anything but impressive. After seeing all the stories about it fighting with people and even proclaiming to have linked someone to a murder, we got a smart assistant.

Don’t get me wrong, BingGPT is still awesome and a step forward for better search, but it’s not the Google killer I or others thought it would be.

The post BingGPT: Microsoft Trips at the Finish Line appeared first on I Like Kill Nerds.

View Details

I have been dual-booting Ubuntu Linux on my main desktop PC for development. Docker on macOS and Windows with WSL suffers from severe I/O performance issues for “reasons”. Docker is infuriating to use outside of Linux, so I started looking for alternative builds.

My primary 3900x gaming PC feels a little sacrilegious to use as a dedicated Linux machine to run some virtual machines and a Webpack server. I am not solving cryptographic problems here, so I just primarily need storage and ram; a decent CPU helps.

At first, I did consider getting a laptop. However, it’s the same problem. Most decent laptops are expensive and have limited amounts of RAM and storage. Not all laptops these days have replaceable storage or RAM either (thanks, Apple). Interestingly, most mini PCs I found were basically laptops in different cases; the architecture down to the ram and storage slots are the same.

After weighing up the options, I chose the Intel NUC 12 Pro. It’s a barebones mini PC kit from Intel that supports not just Windows but also numerous Linux distributions, including Ubuntu. Perfect. I considered older versions like the NUC 11, but the 12, one of the newest, ticked the right boxes at the right price.

Because it’s a barebones kit, you don’t get any storage or memory. This little kit can support up to 64 GB of ram. So, that’s the first thing I purchased. I went for the maximum of 64 GB of DDR4 ram. I chose Crucial 32 GB DDR ram, two of them.

Finally, I chose the Silicon Power P34A60 2 TB PCIe NVMe storage for storage. You will also want to buy a clover leaf cable, as the box doesn’t have a power lead. The Intel NUC C5 cable will do the job of powering your newfound tiny PC technological beast.

If you have ever installed memory before, installing the ram and NVMe storage is dead simple. You don’t need to be an expert in computer assembly to install them. They slot right in.

As you’re aware, Linux is designed to be performant on low-spec hardware, so Ubuntu on the NUC 12 will be noticeably performant, provided you’re not attempting to play graphically intensive games or do anything that requires massive amounts of power. Another deciding factor on the NUC 12 Pro was that Linux is officially supported.

Impressively, the NUC 12 Pro has 2 x HDMI 2.1 ports and 2 DP 1.4a via type C connectors. Then you have two USB 3.2 ports on the front. It has more connectors than you would think for such a small box. Then you have support for the Wi-Fi 6e protocol, an ethernet port, and integrated Bluetooth.

Furthermore, you can power multiple screens off this tiny little box (depending on the resolution). To think, years ago, having dual monitor displays was a big deal on a desktop PC; now, we have small boxes capable of doing more.

I am discussing the hardware a lot here, but it’s important. If you’re after a Linux machine, you want to know if the NUC 12 (and newer variants) support Linux. A resounding yes. Furthermore, you can affix the NUC because it’s so light to the back of a monitor and create your own makeshift all-in-one iMac. You will want an Intel NUC-compatible VIVO to mount like this one to do that.

In another post, I will detail getting my development environment setup:

  • Installing drivers
  • Installing software like Visual Studio Code
  • Installing and configuring Docker
  • Differences between Windows 11 and Ubuntu Linux
  • What works/what doesn’t

Overall, the NUC is what you’re after if you want a powerful Linux machine, especially as a secondary development machine to complement your gaming PC. I don’t doubt the older NUC variants would also hold their own running a flavour of Linux. I just wanted to buy something that wouldn’t have driver support revoked after buying it.

The post Building an Affordable Dedicated Linux Machine Using Intel NUC appeared first on I Like Kill Nerds.

View Details

The PlayStation VR 2 is Sony’s second attempt at a virtual reality headset. The PlayStation 4 had a PSVR headset, but it was marred by screen door, performance issues, a cacophony of cables and dildo-like move controllers with a convoluted tracking process. The PSVR 1 had some great titles but never felt like an adequately supported device.

My first foray into the PSVR 2 as someone experienced with virtual reality headsets was enjoyable. My point of reference is my HP Reverb G2 headset which is similar in specs to the PSVR 2 but is frustrating to use as I have encountered numerous problems with Steam VR and Windows Mixed Reality software. The PSVR 2 is comfortable, and getting lost for hours is easy.

What’s in the box?Admittedly, not much comes in the box. In line with modern products, the packaging is pretty minimal. You get a headset, two VR 2 Sense controllers, and a USB-A to USB-C cable (the same as the one you already have to charge your PS5 controller). Some pieces of paper and everything has a protective covering over them.

The setup process is also exceptional. You are guided through the setup process that guides you through configuring eye tracking, tethering the controllers to your PS5 and setting up your room play area. It’s one of the nicest VR onboarding experiences I have had.

I won’t bore you with the technical specifics. Sony has an impressive FAQ here, which tells you everything about the PSVR 2, from its resolution to haptic features.

The flagship title for the PlayStation VR 2, Horizon: Call of The Mountain, is what most will play first, and I highly recommend getting it. If you didn’t get the bundle, then the game is a cool AUD 110, but it’s a flagship title that uses everything that PSVR 2 has to offer, and it’s as impressive as the trailers made it seem, I would say it looks better when you experience it for yourself.

This game is an excellent showcase of not only the graphical prowess of the 4K displays in the PSVR 2 but also highlights the capabilities of the VR 2 Sense controllers. You get haptic feedback depending on what you’re doing. In the opening scene, when you’re in the boat, you can look over the edge and scoop your hands in the water. You feel the haptic feedback, and it is incredibly immersive.

When you are climbing, you feel the resistance, and after a while, I found my fingers were getting sore like I had been climbing for real. The Legendary Climbs side-quest will make you feel like you’ve been out for a climb.

And Horizon: Call of The Mountain is where you learn how the VR 2 Sense controllers are an engineering feat and a step forward for VR. While the Sense controllers might look similar to other headsets, they’re some of the best I’ve tried. The controllers are very comfortable to wear, to the point where I was so immersed that I forgot I was holding controllers. The controllers on other headsets I’ve tried have always felt unnatural after extended use.

Another underrated feature of the PSVR 2 headset is eye tracking. Thanks to an embedded camera in the headset, it can track your eye movement. Other VR headsets with this feature are double the price (and more). So, for a consumer VR headset at this price point, to have eye tracking is impressive. And, trust me, eye tracking isn’t a gimmick. It works incredibly well, and you get used to using your eyes to navigate menus.

The headset is also impressively engineered, from the little details to the bigger things. On the face part of the headset, there is a rubber seal that is incredibly effective at blocking outside light; the included headset affixes to the headset band, and the length of the cables are just right, so they’re not too loose and dangly.

Wearing the headset is also very comfortable. Sony engineers put a lot of thought into the design, from the weight of the headset to the distribution of the weight. The adjustment mechanisms, from tightening the band to adjusting the face part, are easy to configure to your face and head. The PSVR 2 is the first VR headset I’ve tried where I felt I could play for hours without experiencing aches or pains.

I would also like to point out that I wear glasses, and the PSVR 2 headset is the first that feels like it took glass wearers into account. My glasses weren’t pressed into the bridge of my nose or face. The headset accommodated them, and no light leaks. Thank you, Sony.

I have concerns over the inability to detach the cable from the headset (a fixed cable) and how resilient it would be if it were pulled too much. While some will decry the need for a cable, it’s one long USB-C cable, and it’s a small price to pay for leveraging the power of the PS5 console. But, for now, I am not overly concerned.

Speaking of immersion, one thing I found wasn’t overly helpful was the haptic feedback of the headset itself. Maybe this can be tweaked in future updates to be more immersive, but I found the headset haptic feedback was more annoying than immersive, and I turned it off.

After playing Horizon: Call of The Mountain for a few hours, I concluded it was an excellent introductory title to PSVR 2 but not a title I would find myself revisiting a lot. I have found other titles to have more replay value, like Tetris Effect: Connected, and I’ve fallen back in love with No Man’s Sky again with the PSVR 2 headset.

The image quality on the headset is clear, and the foveated rendering in Gran Turismo is seamless. Comparatively, graphics quality-wise, I wouldn’t say the PSVR 2 is on the same level as my Reverb G2 headset, but it’s close, and you really have to nitpick to see perceivable differences in the field of view and the textures.

Overall, the PlayStation VR 2 headset is fantastic and promising for the price point. Many have raised the headset’s cost as a downside, but you’ll pay a lot more to get something with the same feature set as the PSVR 2. For this to succeed, Sony must commit to it and get big titles to support it, like Spiderman or Grand Theft Auto (which I would love to play in VR).

The post Sony PSVR 2 Review appeared first on I Like Kill Nerds.

View Details

When hiring front-end developers, there are many ways to evaluate candidates’ skills and abilities. However, some assessment methods can be exclusionary, while others may not accurately reflect the type of work the candidate will do.

In this article, we’ll explore some efficient ways to test front-end developer hires without relying on coding puzzles and algorithms and how to be mindful of inclusivity.

I come from a self-taught background, a time when self-taught invited increased scrutiny because being self-taught in the early to mid-00s wasn’t as common as it is now. We have numerous online courses, boot camps and other resources. When I learned to code, these thick phonebook-like books that came with one or more CD-ROM discs with software and code examples were how many learned.

Pair programmingPair programming is an excellent way to assess a front-end developer’s skills. This involves the candidate and an interviewer working together on a coding problem or feature. The interviewer can observe the candidate’s thought process, coding style, and communication skills while providing real-time guidance and feedback.

This method provides a more accurate representation of the type of work the candidate will do. It also allows the interviewer to understand the candidate’s problem-solving and collaboration skills. As long as the paired programming is relevant to the position and not made up coding puzzles, it’s quite effective.

With the rise of AI tools that can help candidates fake answers to algorithm questions and take-home projects, pair programming can accurately tell you a candidate’s skill level.

Code reviewCode review is an excellent method for assessing a candidate’s ability to work collaboratively with others and can help you identify candidates who can deliver high-quality work.

Another way to evaluate a front-end developer’s skills is to ask them to review an existing codebase and provide feedback or suggestions. This can help you gauge their understanding of coding best practices, attention to detail, and ability to identify and fix issues in code.

Now, something to be aware of here depends on the complexity and structure of your codebase; it might be difficult for a candidate to provide feedback without the context or prior domain knowledge of how things piece together.

Discussion-based assessmentA discussion-based assessment involves asking the candidate about their approach to specific front-end development tasks, their understanding of various front-end technologies, or their experience with specific tools or frameworks.

This method can help you evaluate a candidate’s broader understanding of front-end development and ability to communicate their ideas effectively. Additionally, a discussion-based assessment can be done remotely, which can be a more inclusive evaluation method.

You can tell much about a person based on how they speak about a subject. It’s a red flag if you discuss with someone and they can’t provide you with at least one in-depth opinion on something related to their field of expertise, especially if you let them choose what to talk about.

Project-based assessmentProject-based assessments involve providing the candidate with a real-world project that aligns with the work they would be doing if hired. While project-based assessments can present challenges and barriers for some candidates, they can also effectively evaluate front-end developers.

This can give you a better sense of their ability to practically apply their front-end development skills. However, it’s essential to be mindful of the potential barriers to this assessment method, such as candidates not having the time or resources to complete the project.

Inclusivity and considerationWhen evaluating front-end developer candidates, it’s essential to consider the impact of your assessment methods on different candidates. Some assessment methods, such as requiring candidates to spend their free time working on take-home projects, may be exclusionary. Therefore, it’s essential to be mindful of the potential barriers and to make accommodations for candidates with other responsibilities outside of work.

When designing your hiring process, it’s essential to have a clear set of evaluation criteria and a consistent process for assessing candidates. This can help ensure that you’re evaluating candidates fairly and consistently. It’s also essential to be open to alternative assessment methods that can be more inclusive and effective, such as pair programming or discussion-based assessments.

ConclusionThere are many ways to evaluate front-end developer candidates that don’t rely on coding puzzles and algorithms. By using various assessment methods and being mindful of how they impact different candidates, you can create a more inclusive hiring process that allows you to evaluate candidates effectively while supporting diversity and inclusivity in your workplace.

The upside to all of these ways of hiring is they are remote-friendly and more realistic. Unless you’re hiring the candidate to write algorithms all day, maybe don’t ask those questions, or you risk losing quality talent. Not all developers are equal. Some are academically minded, and others are more practical.

The post How to Interview Front-End Developers Without Coding Puzzles or Algorithms? appeared first on I Like Kill Nerds.

View Details

If you’re distributing a package, say a plugin, you may want to test it against multiple Node versions (especially if you’re using Jest for tests). In my situation, I have a popular plugin for Aurelia called Aurelia Google Maps. It’s for Aurelia 1, but many people use it, so I wanted to test it against the LTS of Node and the latest version.

name: Node.js Jest Testson: [push, pull\_request]jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} cache: 'yarn' - name: Install dependencies run: yarn install - name: Run Jest tests run: yarn test strategy: matrix: node-version: [18.x, 19.x] You will want to save this file in your .github/workflows directory at the root of your project. You can save it as whatever you want: run-tests.yml

As you can see in the on part, the tests will run on every push and pull request. It’s also worth going in and ensuring you have some rules to ensure only pull requests that pass the tests meet the criteria for merging too.

The post Writing a GitHub Actions File To Test Against Multiple Node.js Versions appeared first on I Like Kill Nerds.

View Details

I hate to be “that guy” that publishes a blog post and says, “Stop using X” and “Why you should be using X instead”, but after a recent situation in some code I wrote ages ago and updated, I felt it was worthy writing a blog post about why you should use globalThis instead. That’s not to say if you’re currently using window that you’re wrong (because globalThis aliases window in a browser context). However, by using globalThis, you can save yourself a lot of trouble, especially in unit tests.

If you’re not familiar with globalThis, it’s a new global object that was introduced in ECMAScript 2020. It provides a way to access the global object in any environment, whether a web browser, a Node.js server or a web worker. The main benefit of using globalThis instead of window or global is that it makes your code more consistent and future-proof.

Here are a few examples of how globalThis works in different contexts:

In a browser contextIn a web browser context, globalThis is essentially an alias for the window object. Here’s an example:

console.log(globalThis === window); // trueconsole.log(globalThis.location.href); // same as window.location.href By using globalThis instead of window in your code, you can ensure that it will work in any web browser environment.

In a Node.js contextIn a Node.js context, globalThis is an alias for the global object. Here’s an example:

console.log(globalThis === global); // trueconsole.log(globalThis.setTimeout === global.setTimeout); // true By using globalThis instead of global in your code, you can ensure that it will work in any Node.js environment.

In a web worker contextIn a web worker context, globalThis is the global object for the worker. Here’s an example:

console.log(globalThis === self); // trueconsole.log(globalThis.postMessage === self.postMessage); // true By using globalThis instead of self in your code, you can ensure that it will work in any web worker environment.

In unit testsOne of the benefits of using globalThis in your code is that it can make unit testing easier, especially if you need to mock global objects like window or global.

For example, let’s say you have a function that depends on the window object:

function showMessage(message) { window.alert(message);} To test this function, you might need to mock the window object. However, mocking the window object can be tricky, especially if you want your tests to work in different environments. If you’re using Jest, the default test environment is Node where Window doesn’t exist, but global does.

By using globalThis instead of window, you can make it easier to mock the window object in your tests:

function showMessage(message) { globalThis.alert(message);} Now, when you’re writing tests for this function, you can mock the globalThis object instead of the window object:

it('shows message', () => { const originalAlert = globalThis.alert; globalThis.alert = jest.fn(); showMessage('Hello, world!'); expect(globalThis.alert).toHaveBeenCalledWith('Hello, world!'); globalThis.alert = originalAlert;}); By using globalThis instead of window, you can write code that’s easier to test and works across different environments.

In conclusion, by using globalThis in your code, you can make it more consistent, future-proof, and easier to test. Whether you’re working in a web browser, a Node.js server, or a web worker

The post Why You Should Be Using globalThis Instead of Window In Your Javascript Code appeared first on I Like Kill Nerds.

View Details

If you have an application that has HTML imports like this import template from './my-component.html and then attempt to test this code in Jest 28+ (or previous versions, for that matter), you will get a syntax error similar to this one:

SyntaxError: Unexpected token ‘<‘ HTML

Fortunately, there is an easy fix. Firstly, you need to install the package jest-html-loader. npm install jest-html-loader -D. Then you need to configure your Jest configuration as follows.

"transform": { "^.+\\.tsx?$": "ts-jest", "^.+\\.html?$": "jest-html-loader" }, That is all you need to do. Your HTML imports will work and not throw errors during your test process.

The post How To Configure Jest 28+ To Work With HTML Imports appeared first on I Like Kill Nerds.

View Details

It’s been well over a decade since I started my journey as a front-end developer. I’ve worked on numerous projects, built and maintained websites, and developed applications. I have numerous open-source projects and am on the Aurelia Javascript framework core team. Over the years, I’ve gained experience and learned a lot of things, but there are still times when I feel like I don’t know what I’m doing.

I know I’m not alone in this. As developers, we face a lot of challenges, big and small. From dealing with complex algorithms to fixing simple bugs, obstacles always exist. But despite my experience, I still get caught up in stupid bugs, struggle to install and configure packages and spend hours stuck on things that ultimately have simple solutions.

I could not tell you how many hours I spent; sometimes, days stuck on a problem only to look at what I committed, a few lines of code.

It can be frustrating, to say the least. Sometimes I feel like an imposter, wondering if I’m even cut out for this profession. But then I remind myself this is just part of the learning process. No matter how experienced you are, there will always be new challenges and new things to learn. It ebbs and flows that many experienced developers grapple with.

One of the things that I’ve learned over the years is the importance of asking for help. Sometimes, all it takes is a fresh set of eyes to spot the solution to a problem that has been bugging me for hours. There’s no shame in not knowing everything, and it’s important to remember that there is always someone out there who knows more than you do.

It’s easy to fall into the trap as an experienced developer that you are supposed to have all the answers, and even easier to find yourself stubbornly persisting on a problem someone else might be able to help you solve in a matter of minutes.

I’ve also learned that taking breaks and stepping away from a problem is essential when you get stuck. When you’re staring at the same lines of code for hours, it’s easy to miss something obvious. Sometimes, a fresh perspective is all you need to find the solution, maybe a cup of coffee and a walk to get the blood flowing back to your neglected developer limbs.

Despite the challenges and the moments of self-doubt, I still love being a developer. I love the feeling of finally solving a problem that had been bugging me for hours. I love the satisfaction of building something from scratch and seeing it come to life. And I love the fact that there is always something new to learn.

So if you’re a developer who sometimes feels like they don’t know what they’re doing, know you’re not alone. We all have moments of self-doubt and frustration. But remember that every challenge is an opportunity to learn and grow, and there is always help available if needed. Being a senior developer isn’t about knowing everything or even being the fastest. It’s about knowing your limitations and how to work around them.

The post I Still Sometimes Don’t Know What I Am Doing as a Senior Developer appeared first on I Like Kill Nerds.

View Details

TypeScript is a statically-typed superset of JavaScript introduced by Microsoft in 2012. It’s a language that some developers love to hate, but over the years, TypeScript has won over many sceptics, becoming an essential part of many modern JavaScript projects.

You now have developers that once hated TypeScript liking it. Perhaps one of the most known developer advocates to get their TypeScript stance wrong was Eric Elliott, who published an article where he discusses a TypeScript tax. To Eric’s credit, he doesn’t say not to use TypeScript but attempts to argue against its use.

One of the most significant benefits of TypeScript is static type checking. By enforcing types at compile time, TypeScript can catch errors that might have gone unnoticed until runtime. This can save a lot of headaches and debugging time. It also makes code more maintainable and understandable since the types serve as documentation for the code.

Another benefit of TypeScript is that it offers better IDE integration. With proper configuration, TypeScript enables editors to provide more accurate code completion and documentation, making writing and understanding code easier. This is especially useful in larger codebases with many dependencies.

But it wasn’t always sunshine and rainbows for TypeScript. When it was first introduced, many developers were sceptical. They saw it as an unnecessary layer of complexity that only added more work to their already busy schedules. And while some of these developers are still around, many have since come to the idea that TypeScript has a lot of value.

So, what changed? For starters, Microsoft has been committed to continuously improving TypeScript. Each new release addresses issues adds new features, and refines the language. This has gone a long way in winning over sceptics concerned about using a language they felt was still in its infancy.

But there’s more to it than that. TypeScript has also evolved and become more accessible to developers over time. It’s easier to set up, with straightforward installation and configuration. As more people have started using TypeScript, the community has grown and become more supportive. There are plenty of resources and helpful developers out there who are willing to lend a hand.

Furthermore, TypeScript has significantly increased in popularity with high-profile projects such as Angular, Vue, and Aurelia. These projects have adopted TypeScript, demonstrating its power in real-world applications. Seeing how these projects have benefited from TypeScript has encouraged many developers to try it.

Of course, not everyone loves TypeScript, and that’s perfectly okay. However, for those who are still hesitant to try it out, it’s worth noting that TypeScript offers many benefits and is a tool that can make developers’ lives easier. With its static type checking, better IDE integration, and accessibility, TypeScript has earned its place in the modern JavaScript ecosystem.

The TypeScript haters either started using TypeScript or ran out of valid arguments and had nothing left to say.

The post Where Did All The TypeScript Haters Go? appeared first on I Like Kill Nerds.

View Details

The widespread tech layoffs over the past few months, and in January and February 2023 alone, have been causing concern for some. Is it a sign of a possible recession and economic avalanche that will see the unemployment rate skyrocket in different countries?

I am not an economist, so this is just more observational. But, I don’t believe the widespread tech exodus we are currently witnessing is symptomatic of an economic storm battering down on the tech sector. It’s a correction.

That’s not to say that the economy in many countries isn’t going down the toilet and, inflation despite peaking in many places still being stubbornly high. But, we are not quite at the point where high interest rates and constrained economic circumstances are causing businesses to start laying people off en masse.

During the pandemic, when everyone was forced inside, and everyone could work remotely, tech companies went on a hiring spree. Apps like Zoom saw unprecedented growth. They needed to hire more people to tackle the scale. The same thing happened with Netflix and other companies. All of the big ones hired a lot. Google, in particular, has been on a hiring spree forever.

However, people didn’t want to be stuck inside once the pandemic restrictions were lifted. The shift to virtual changed to physical. Somehow companies like Meta and Zoom thought pandemic hermit living would continue, and so would their profits.

It’s a classic case of over-capitalisation. Companies expanded their workforce too quickly and too much. Mark Zuckerberg even admitted so much himself last year that he got it wrong.

Despite big tech laying people off, smaller, better-run companies are still hiring. The ones that didn’t overextend themselves, naively believing the good times of the pandemic and stupidly high valuations would continue to soar.

It’s one of the reasons that I closed my LinkedIn. My feed was doom and gloom; it was beginning to affect me, making me fear what 2023 would hold for me. It doesn’t help when you have a lot of people from these big tech companies as connections or followers talking about their last day or worse.

The reality is we aren’t at the point where layoffs are happening because of recession fears. That’s not to say it’s not already happening, but it’s not the reason for the widespread layoffs we are currently seeing. Just some unfortunate fat-cutting from bloated big tech companies that have always operated under the illusion they are too big to fail.

The post The Mass Lay Offs Aren’t an Apocalyptic Sign of Recession, They Are a Much Needed Correction appeared first on I Like Kill Nerds.

View Details

Just when you thought the return to office movement was gaining momentum, driven by high-profile companies and out-of-touch boomer CEOs that struggle to adapt to the new paradigm of flexible working, it appears there might be a few bumps in the road.

Some data has come out on productivity from the U.S. Bureau of Labor Statistics since some workers have been forced back into the office, most notably showing that productivity has decreased.

The irony of this is not lost; considering the justification for pushing workers back into the office has been driven by claims of in-person collaboration increasing productivity, the data seems to suggest otherwise.

It also doesn’t help that many companies I have heard of mandating a return to the office have done so rather aggressively. The “return to the office or be fired” approach that some have taken, most notably Elon Musk is a staunch proponent of, could only ever result in decreased productivity. Then you have Amazon announcing a forced return to the office on May 1, 2023.

If you have ever worked in an office before, you would know it’s full of distractions. I wish I had a non-biased way to quantify my productivity, but my productivity has been very high over the years I have worked remotely. I think part of that is I get sick less. I have kids in school, and since working remotely full-time, I’ve noticed I get sick maybe once or twice a year.

Don’t just take my word for it, they have quantified some of this stuff since the 2020 pandemic, and people aren’t just slacking off playing games and watching Netflix while working remotely.

When the Integrated Benefits Institute surveyed workers in October 2022, it found employees who work remotely or in a hybrid environment indicated that they are more productive (21.8%), more satisfied (20.7%), and more highly engaged (50.8%). Those are significant numbers.

And in another October 2022 survey, Slack found that workers forced to return to the office were spending up to four hours on video calls daily. On average, workers were spending two hours in meetings a day.

People are working remotely in offices. Isn’t it ironic during the pandemic, we were all doing video calls remotely, only for some to be forced back into the office and still work like they’re working remotely? It makes no sense.

There are arguments that working remotely devoids employees of human connection. Maybe that’s true; maybe it’s not. In my industry, even working in an office, I had headphones on, and human interaction was reserved for pointless meetings, lunch and coffee trips. Since when do companies care about human connection?

I have always described my in-office experiences to people like this, “I worked remotely in an office” detached from my surroundings, having to be a part of meetings where people were phoning in any way. I’m very fortunate that my job can be done remotely. I acknowledge that not every job can.

Have you noticed that the most outspoken against remote work are primarily in their fifties, white and rich? But, remote work proponents are currently fighting a war against Elon Musk and Marc Andreessen, coincidentally also a billionaire. Andreessen claims that remote work is not a good life for young workers.

Cost of living pandemicThe COVID-19 pandemic might be over, but we are entering a new pandemic with no vaccine—the cost of living. Over the last few months, you might have noticed that a supermarket trip has been more costly than usual.

While inflation is the primary contributing cause of the increased cost of living, despite inflation starting to fall in most places (U.K., USA and Australia especially), the cost of living crisis will continue throughout 2023 and beyond.

The price of eggs in the USA was up 150% from the year prior, prompting some U.S. lawmakers to demand an answer from egg companies as they reap record profits. Not everyone eats eggs, but it’s one of many components of the food chain that feeds into the price of other things and adds to the overall strain on household budgets.

On top of that, companies forcing remote workers back into the office add to those costs—transportation being a big one. If you drive, that’s fuel, tolls, possibly paying for parking, the wear/tear on your vehicle and maintenance costs. Public transport can still add up.

And then you have the social pressure of office lunches (the price of eating out has dramatically risen) and trips to get coffee. When I worked in an office, people often ate out and got coffee, and if you didn’t partake, you missed out on office relationship building and risked being seen as an outlier. Great ways to bond, but at what cost?

Give people the choiceRemote work isn’t some new thing invented during the pandemic. A lot of companies have been successfully been working remotely for years. There are 100% remote work companies like 37 Signals that have been doing it very successfully, profitable and have high retention rates and satisfaction levels.

But here is the thing. Not everyone wants to work remotely, and that’s okay. If you’re applying for a 100% remote company and you hate remote work, then that’s on you. But, if you’re working for a company with an office, it shouldn’t be either all, especially if you offered remote work during the pandemic and now trying to take it away.

There is no reason why companies can’t offer both. Give those that want an office a physical space. Give those that want remote the ability to stay and work remotely. People should be free to work the way they want too. Ultimately, all that matters is people get their work done in a way that works for them.

The post The Forced Return to the Office Has Resulted in Decreased Productivity and Increased Cost of Living Pressure appeared first on I Like Kill Nerds.

View Details

Since taking the helm of Twitter, Chief Twit and manical entrepreneur Elon Musk has ruffled some feathers. From losing advertisers to claims he asked engineers to boost his popularity on the platform, it has been a wild ride.

The latest wild ride is Twitter has announced two factor authentication using text messages will be a Twitter Blue only feature. There is this image circulating and people are upset.

Is Twitter disabling text message two-factor authentication a security threat? Well, it is if you don’t configure something else in its place. Install Authy and spend the 2 minutes configuring it. Problem solved.

Now, here is the thing. Twitter isn’t monetising all forms of 2fa, just text messages. You can still use an authenticator app like Authy or Google Authenticator. That’s what everyone should be using anyway. Twitter are doing users using this insecure form of security a solid here.

Text messaging is very insecure. Over the years, there have been many high-profile attacks because of sim swapping especially. Jack Dorsey (the ex-CEO of Twitter) famously fell victim to a sim-swapping attack that saw hackers gain access to his Twitter account.

Not many people probably realise this, but text messages are highly-insecure forms of communication. They are sent plaintext over cellular networks, and it is possible to intercept them using easily available hardware and software online.

While it hasn’t been said out loud, the reason Twitter appears to be doing this is for cost-related reasons. It costs money to send text messages and based on the intensity of the backlash, it appears a lot of people used this form of 2fa (which I find quite worrying).

So, the irony of this situation is that Twitter is doing non-paid subscribers a favour here by not allowing them to use one of the most insecure forms of 2fa around. Are text messages convenient? Absolutely. But, is it any less steps opening up an authentication app to get a code? No. Instead of a text message, it’s an authenticator app. Am I missing something here?

The post The Twitter Blue 2fa Fiasco appeared first on I Like Kill Nerds.

View Details

After a lengthy free period of constant downtime and unreliability, ChatGPT has opened up its paid Plus plan to more people and wanting to see what the difference was between Plus and free, I signed up.

For some, USD 20 might be too much to reconcile in this current economic climate. If you use ChatGPT as part of your daily tasks like some do, then $20 might be pretty valuable. If you’re a hobbyist user or just curious, $20 might be a cost you’ll have to weigh against your coffee budget.

So, what do you get in ChatGPT for your twenty dollars?

  • Increased reliability (responses don’t stop part way through because the servers are overloaded)
  • Faster responses
  • Higher limits (I seemingly hit the hourly rate a lot easier on the free version)

Here is the thing about ChatGPT Plus, it just feels better. I know it’s hardly a scientific answer, but everything feels faster, and the responses even feel more detailed and accurate (although that could be a side effect of the increased response speed). The reliability is better. Say goodbye to the constant downtime and responses cutting out part way through.

The increased speed, because of the default ChatGPT Plus exclusive turbo option (which is just called default now), gives you 2.5x faster responses.

And one thing with the free version of ChatGPT, I found myself hitting the free hourly limits more than you would expect. If you only need minimal use from it, then free might be fine (if the servers are not melting). However, I have not encountered any hourly limitations with the Plus-paid version.

One thing that ChatGPT does, regardless of whether you’re a paid or non-paid subscriber, it has a response limit. Inevitably for lengthy responses, you’ll notice it finishes but doesn’t complete its response. I have a blog post about this here.

For some, Plus will be a hard sell. Although, if you’re using it to be more efficient in your job (I know many content writers are using it) and if it helps you save $20 in time quantified calculations, the subscription has paid for itself.

I would imagine over time, as ChatGPT gets better, Plus subscribers will have first dibs on new features and improvements before paid users will.

The post A Review of ChatGPT Plus appeared first on I Like Kill Nerds.

View Details

Password generation is something you’re hopefully using a password manager for these days. However, you might not be aware that modern browsers support some great crypto features.

In this quick little tutorial, we will use the Crypto API to create a strong password generator. The code is remarkably simple, and you can adapt this to generate unique values for games and other purposes besides passwords.

/** * Generates a random password of the specified length. * * @param length The length of the password to generate. * @returns A Promise that resolves to a string containing the generated password. * @throws An error if the length argument is less than 1. */const generatePassword = async (length: number): Promise<string> => { if (length < 1) { throw new Error('Length must be greater than 0'); } // Create a new Uint8Array with the specified length. const buffer = new Uint8Array(length); // Get the browser's crypto object for generating random numbers. const crypto = window.crypto || (window as any).msCrypto; // For compatibility with IE11. // Generate random values and store them in the buffer. const array = await crypto.getRandomValues(buffer); // Initialize an empty string to hold the generated password. let password = ''; // Define the characters that can be used in the password. const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; // Iterate over the array of random values and add characters to the password. for (let i = 0; i < length; i++) { // Use the modulus operator to get a random index in the characters string // and add the corresponding character to the password. password += characters.charAt(array[i] % characters.length); } // Return the generated password. return password;}; As you can see, the getRandomValues method does all of the heavy lifting here for generating our password. We also define what characters are allowed in our password, allowing us to remove ambiguous characters if we wish.

TestingWe will write some simple Jest unit tests to ensure our code works. The basics, such as password length and uniqueness.

describe('generatePassword', () => { test('should return a string of the specified length', async () => { const password = await generatePassword(10); expect(typeof password).toBe('string'); expect(password.length).toBe(10); }); test('should throw an error if the length argument is less than 1', async () => { await expect(generatePassword(0)).rejects.toThrow(); await expect(generatePassword(-1)).rejects.toThrow(); }); test('should generate different passwords for different calls', async () => { const password1 = await generatePassword(10); const password2 = await generatePassword(10); expect(password1).not.toBe(password2); }); test('should only contain characters from the defined set', async () => { const password = await generatePassword(10); expect(password).toMatch(/^[A-Za-z0-9]+$/); });}); The post Creating a Secure Password Generator Using TypeScript appeared first on I Like Kill Nerds.

View Details

There are more methodologies than you can shake a stick at. All promise to streamline your workflow and deliver quality software, many of which leverage the same old approach to work: estimation and timelines.

I am not saying that timelines need to be replaced entirely. Because they are a necessary evil. However, in my experience, most companies putting deadlines on features and projects use arbitrary figures, not for a valid reason.

What is a valid reason for a deadline?

  • Complying with a regulatory or legal requirement
  • An event where you’re launching a new feature or product
  • A serious bug in your application that is breaking things for users (allowing you to communicate an approximate timeframe for when it will be fixed)
  • And a few other things

The truth is most companies aren’t using deadlines in this way. They’re using deadlines to push developers to fit their work inside a timed box.

When you place artificial constraints on something, a few things happen.

  • Quality suffers as your developers rush to complete the work
  • Work/life balance can be impacted if your developers are forced to work additional unpaid hours to get things done
  • The work is most likely not being tested properly
  • Your developers are more likely to burn out
  • Your culture is going to be negatively impacted
  • Developers talk, and word ultimately gets out that your company is poorly managed and stopping short of offering way above market price, you’re going to be low on the list of companies people want to work for

This is where the idea of “shipping when it’s done” comes into play. Instead of focusing on arbitrary deadlines, the emphasis should be on ensuring the work is high quality and meets the customer’s needs.

By allowing developers to work at their own pace and focusing on the outcome, you give them the freedom to use their expertise and creativity to deliver something great. This approach is better for the developers’ work/life balance and mental health and encourages collaboration and innovation.

The benefits of shipping when it’s done include:

  • Higher quality work, as developers have the time they need to test and refine the product thoroughly
  • Greater job satisfaction, as developers can take pride in their work and feel supported by their organization
  • Increased productivity, as developers are not constrained by an artificial timeline and can focus on delivering something truly valuable to the customer
  • Reduced technical debt, as developers have the time they need to ensure that the code is clean and maintainable
  • Better communication with customers, as they are kept informed of progress and can offer feedback along the way

Delivering more minor features often is a critical aspect of the “ship when it’s done” approach. This allows companies to focus on delivering value to the customer as quickly as possible rather than waiting until a larger project is complete. It also allows flexibility to adjust priorities based on customer feedback or changing market conditions.

By breaking down projects into smaller features or user stories, teams can focus on delivering working software more frequently. This approach helps identify potential problems earlier in the development cycle, saving time and resources in the long run.

The benefits of continuous delivery include:

  • Greater agility: By delivering smaller features more frequently, companies can respond more quickly to customer needs and market changes.
  • More accurate feedback: Frequent releases allow for more accurate feedback from users, which can help teams make more informed decisions about future development.
  • Reduced risk: Smaller releases are less risky than larger, all-or-nothing releases, as they allow for quick course correction if something goes wrong.
  • Increased motivation: Developers are more likely to be motivated by seeing the results of their work sooner rather than later. This is crucial for new hires especially.
  • Better team collaboration: Frequent releases encourage team collaboration and communication, which can lead to more creative problem-solving and better products.

In conclusion, focusing on delivering smaller features often is a crucial component of the “ship when it’s done” approach. By prioritizing outcomes over time, companies can deliver value to their customers more frequently while fostering greater agility, reducing risk, and improving collaboration within their development teams.

The post It’s Done When It’s Done appeared first on I Like Kill Nerds.

View Details

Samsung is making yearly phone upgrades obsolete. I used my beloved Galaxy Note 10+ Plus until its dying breath. Even when the charging port failed and could only be charged wireless, I persisted until one day; it refused to charge.

I have been using the Samsung Galaxy S21 Ultra for the last couple of years. It’s no Note, but it’s one of the best phones I have ever owned. Even now, the hardware specifications of the S21 hold up against newer devices.

The pandemic dampened innovation as components became more challenging for companies to obtain. Combined with rampant inflation and increased cost of living, people aren’t buying new phones yearly as they used to. Made even more evident by the fact that it’s now commonplace for Australian telcos to offer 36-month plans.

There isn’t much reason to upgrade to the latest smartphone like there used to be.

If you’re upgrading from the Galaxy S22, the S23 might not have much to offer you besides camera improvements and better hardware specs. But, if you’re coming from the S21 or older, the Galaxy S23 comes as close to a modern Galaxy Note as possible.

Since the S21, Samsung has trimmed down what comes in the box. Minimal packaging, a USB-C cable and a metal pin for opening the sim card tray. There are some pieces of paper for the warranty and stuff too. Like other manufacturers, you don’t get a charger anymore, but you probably already have one.

The S23 Ultra is the new Samsung Galaxy Note.The S Pen now ships with the S23 Ultra with a dedicated spot on the phone to hold it. For those like myself that use it, it’s incredible for taking notes and interacting with your device like a boss. Once you get used to the S Pen, you can interact with your phone in ways your fingers could only dream of. It was one of the best things about the Note series.

Essentially, the Galaxy S23 Ultra feels like a Samsung device from the last few models. The interface has had some subtle changes, and Samsung has reduced the preinstalled junk, but there is nothing distinctive from a UI perspective on the S23 that makes it stand out.

Even though the phone isn’t the same as the S22, dimension-wise, they’re essentially the same in almost every other way. The phone is less rounded on the edges and feels more square, which makes more of a difference than you would expect when you hold it. That is one of the criticisms of my S21 Ultra, the rounded corners made it uncomfortable to hold one-handed for long periods.

SpecsWhere things begin to differ from my S21 Ultra is the speed. Specs-wise, it’s a no-brainer that the S23 Ultra is bigger and better on every level. Finally, Samsung is shipping just the Snapdragon chipset to everyone instead of Exynos and Snapdragon. You don’t have to be a hardware geek to know that Snapdragon outperformed Exynos consistently in most benchmarks on previous Samsung Galaxy phones.

Things feel snappier. The battery drains slower, tabbing between browser tabs in Chrome feels faster, and even auto-completing with 1Password into fields when using my favourite password manager feels faster. Maybe it’s just new phone energy, but I suspect it’s because there is more ram and a faster chipset. Things are happening more quickly.

The Camera = wowThe Camera is noticeably better than my S21 Ultra in both photo and video. And let’s be honest, the essential feature of a smartphone isn’t how fast it can run a graphically intensive game; it’s the camera. It’s the thing you use your phone for the most, probably even more than making calls.

It takes better nighttime shots that blur less, has better clarity, and has a monster 200mp camera. Although, you won’t need 200-megapixel photos unless you’re taking photos for print billboards or something. An understated feature they have added is multi-timed photos. Instead of setting a timer to take a single photo, you can take multiple timed photos and set the interval between each photo.

Arguably, the best camera feature is the new Expert RAW feature, and it’s not even shipped with the phone.

If/when you get the S23 Ultra, you will want to download the Expert RAW app. This gives you a powerful new RAW mode that is more configurable than ever. An astrophotography mode is a new feature that can take those long exposure shots of the sky and stars for 10 minutes. You’ll want a tripod, as the lowest exposure is still 4 minutes.

And then you have the video capabilities. With Super Steady, Samsung has finally made the feature worthy of the title. You can take videos with rapid movement, and they’re pretty smooth, with the white balance no longer flickering like a Christmas tree. Finally, 8k is usable on a smartphone, with the S23 Ultra offering 8k video at 30fps, which makes a substantial difference compared to the S22 Ultra and other 8k-capable phones.

The space zoom feature, which promises 100x zoom, is still a gimmick. The photo quality of 100x photos is not usable at all. A cool trick to show your friends, but you wouldn’t post those photos to social media or use them for anything.

The autofocus is perhaps the most significant improvement to the Camera many won’t talk about. Look, the S21 wasn’t terrible, but it had autofocus issues. I read how the S22 also had similar issues with autofocus. To the point where it became a thing synonymous with Samsung cameras. In the S23 Ultra, they stepped things up; autofocus is finally fixed, from what I can see. The autofocus tracking feature works well, up to 4k 60fps video.

Don’t just take my word for it. See the YouTube video that made me decide on the S23 Ultra:

The score given to the S23 Ultra is 7.5 vs the iPhone 14 Pro Max at 4.5. The reviewer in this video highlights how Samsung has seemingly caught up to Apple, which has had the better smartphone camera for years.

ConclusionThe cost of the S23 Ultra is nothing to sneeze at. The total price upfront is a hefty chunk of change. Although, if you shop around, you can get a good discount on the S23 if you go on a plan. I managed to get the 1 TB model for the price of the 512 GB version through Optus here in Australia when I pre-ordered.

If you’re coming from the S22, I won’t rush to upgrade unless you want to. However, I upgraded from the S21 Ultra, and the difference in camera quality and overall improvement of the phone that addresses many outstanding Samsung-esque issues made it worthwhile.

The post Samsung Galaxy S23 Ultra review appeared first on I Like Kill Nerds.

View Details

The ChatGPT tool is possibly part of your everyday workflow. I’ve been using it for research purposes and as a writing assistant, where it thrives at. However, one of the issues with ChatGPT is that it has a limitation on its response length.

You write in a prompt, and ChatGPT starts generating its response. All of a sudden, it stops. I hope OpenAI one day increases the response limit because, besides the fact, there is a way to fix it, it’s still frustrating.

The solution is simple: when it stops, write “continue” (without the double quotes), and it will continue to complete its response.

Now, this isn’t a permanent fix. You will have to do this every time it happens. And if you think paying for ChatGPT Plus will increase the response limit, it doesn’t. The same issue exists for both the free and paid versions of ChatGPT.

The post ChatGPT Stopping Part Way Through a Response? Here Is How You Fix It appeared first on I Like Kill Nerds.

View Details

Valentine’s Day is upon us and this year that heartfelt card you get from your significant other this year might be written using AI. Specifically, ChatGPT which has taken the internet by storm.

In fact, I asked ChatGPT to write a really heartfelt card message and this is what it produced.

My dearest [Wife's Name],On this Valentine's Day, I want to take a moment to express how grateful I am to have you in my life. You are my rock, my support, and my best friend. You have brought so much joy and happiness into my life and I am forever grateful for your love.I remember the moment I first laid eyes on you and I knew that you were the one for me. Every day since then, my love for you has only grown stronger. You make me want to be a better man and I am so proud to call you my wife.You are my everything, my sunshine on a cloudy day, and the beat in my heart. I am so grateful for all the amazing memories we have shared together and I can't wait to make many more in the future.I love you now and always. Happy Valentine's Day, my love.Forever and always,[Your Name] Excuse me for a moment while I dry the tears from my eyes. How heartfelt and sincere.

Admittedly, ChatGPT is an impressive tool, but it doesn’t always get things right. From a writing perspective, it is incredible. I know people out there are using it for everything, but as a writing assistant ChatGPT is impressive. The results it produces are a bit robotic, but with some prompting, it can be made to produce outstanding results.

I am not adverse to AI, but using it to write a heartfelt message for your partner is peak laziness. I understand we all live busy lives, but what kind of life are we living if we can’t stop for ten minutes and think of some nice things to say about those we love without asking an AI tool to do it for us?

On the same hand, Valentine’s Day is a terrible day in itself. One of the most infamous “Hallmark holidays” societal pressure from social media means that these days designed to sell cards, chocolate and flowers will continue. You don’t want your partner seeing others being spoiled and you didn’t get them anything, do you?

If we need a specially marked day in the calendar to tell our partners we love them and buy them flowers, where is the romance? If anything, it means more to surprise someone with chocolate and roses on days that aren’t Valentine’s Day, right?

Celebrate love on days other than Valentine’s Day, it will mean so much more.

The post Happy AI Valentine’s Day appeared first on I Like Kill Nerds.

View Details

The term “googling” is synonymous with searching for things online. For years, Google has enjoyed a monopoly on search, advertising, and other facets of internet life. As Yahoo! fades into the ether and Microsoft’s Bing exists but isn’t used much (who says “binging” or “bing it”?), we are starting to see competition heat up in the search space are decades of Google dominance.

The threat to Google is ironically coming from Microsoft.

In 2019, Microsoft invested $1b into OpenAI and another $10b into OpenAI in January 2023. That’s a serious chunk of change to invest in an economic climate of high-interest rates, layoffs in tech and other uncertainty.

When OpenAI debuted ChatGPT in late 2022, it was a surprising hit—taking just two months to reach 100 million active users. The kind of fear that other companies took years to achieve (TikTok being the exception at nine months).

Suddenly, the success and hype around ChatGPT were starting to look good for Microsoft’s initial investment. But things didn’t end there.

And then Microsoft threw down the gauntlets again when it announced it was integrating ChatGPT into its Bing search engine. Not only was the integrated version of ChatGPT more advanced when Microsoft debuted it, but it could also recommend search results and act as an assistant.

Google was left with an egg on its face. They subsequently announced their own search-assisted AI called Bard. But, when it came time to demo it, it turns out the information in the demo wasn’t accurate and so came tumbling down the share price for Google.

It appears that Google is being challenged in its own kingdom by Microsoft of all companies. AI is shaping up to disrupt traditional industries as we know them.

The post A real threat has emerged to challenge Google and it might be Microsoft appeared first on I Like Kill Nerds.

View Details

You might have noticed that you don’t hear about GraphQL as much as you used to. Some people might have you believe that developers have lost interest in this technology, but that couldn’t be further from the truth. This blog post will explore why GraphQL isn’t as talked about as it used to be and why it’s still a relevant and valuable technology for developers.

Maturity and stabilityGraphQL has come a long way since its introduction a few years ago. As more and more companies adopt GraphQL, the technology has become more mature and stable. The growing number of real-world applications built with GraphQL has resulted in fewer bugs and compatibility issues, making GraphQL a reliable and predictable technology for developers. With its growing popularity, GraphQL has become a well-established technology widely accepted and used in the industry, reducing the need for developers to talk about and evangelize GraphQL.

However, that’s not to say that GraphQL has stopped evolving. The technology continues to evolve and improve, and developers are finding new and innovative ways to use GraphQL to solve complex problems. With its growing popularity and continued evolution, GraphQL is set to remain a valuable and relevant technology for years to come.

It’s no longer new and shinyWhen GraphQL was first introduced, it was a new and exciting technology that developers were eager to talk about and share with others. The novelty and excitement surrounding GraphQL were palpable, and developers were eager to explore the potential of this new technology. However, as GraphQL has become more widely adopted and its use has become more common, the novelty and excitement surrounding GraphQL have diminished.

This is a natural progression for any new technology. As new things like GraphQL become more established and widely used, the need to talk about it decreases, and the focus shifts to practical usage and problem-solving. Despite this shift, GraphQL remains a valuable and relevant technology, and developers continue to find new and innovative ways to use GraphQL to solve real-world problems.

As you can see in the 2022 State of The API report, despite REST being the dominant approach to building APIs, GraphQL is still growing. Growing to 28% usage, up from 24% the year prior in surveyed responded.

Furthermore, the 2022 State of GraphQL report shows that GraphQL is maturing, with many respondents reporting three to five years of experience.

Focus on practical usageGraphQL is now being used in production by many companies, and the focus has shifted from talking about GraphQL to using it to build applications. Developers are now more focused on using GraphQL to solve real-world problems rather than discussing its potential. This shift in focus has contributed to a decrease in the amount of discussion and chatter about GraphQL, but it doesn’t mean that developers have lost interest in the technology.

In fact, as GraphQL becomes more widely used and accepted, developers are becoming increasingly familiar with its capabilities and limitations. This increased familiarity has allowed developers to use GraphQL more creatively and innovatively, leading to new and exciting technology applications. With its growing popularity and continued evolution, GraphQL is set to remain a valuable and relevant technology for years to come.

PayPal was an early adopter of GraphQL. Similarly, GitHub also embraced GraphQL quite early. Both companies are still using GraphQL in production and many others, including; Soundcloud, Netflix and plenty of other known companies.

Just because you don’t hear GraphQL dominate the buzz cycle anymore doesn’t mean it’s dead. If anything, the dying down of the hype is a good thing.

The post Why Don’t You Hear Much About GraphQL These Days? appeared first on I Like Kill Nerds.

View Details

Sentiment analysis is usually a task that requires a specialised dataset and machine-learning techniques to implement properly. However, I thought it might be a nice exercise to try and implement sentiment analysis with TypeScript without training models.

// Define a type for the sentiment resulttype Sentiment = 'positive' | 'neutral' | 'negative';// Class to perform sentiment analysis on a given textclass SentimentAnalysis { // Arrays of positive and negative words to use in the analysis private positiveWords = ["love", "like", "great", "good", "happy", "awesome"]; private negativeWords = ["hate", "dislike", "bad", "angry", "sad", "terrible"]; // Method to perform sentiment analysis on a given text public getSentiment(text: string): { sentiment: Sentiment, positiveWords: number, negativeWords: number, neutralWords: number } { // Convert the text to lowercase to make the analysis case-insensitive const lowerText = text.toLowerCase(); // Sum up the number of times each positive word appears in the text let positiveScore = this.positiveWords.reduce((acc, word) => { // Use a regular expression to match the word in the text return acc + (lowerText.match(new RegExp(word, 'g')) || []).length; }, 0); // Sum up the number of times each negative word appears in the text let negativeScore = this.negativeWords.reduce((acc, word) => { // Use a regular expression to match the word in the text return acc + (lowerText.match(new RegExp(word, 'g')) || []).length; }, 0); // Calculate the number of neutral words by subtracting the positive and negative words from the total number of words let neutralScore = lowerText.split(' ').length - positiveScore - negativeScore; // Compare the number of positive and negative words and return the sentiment result if (positiveScore > negativeScore) { return { sentiment: "positive", positiveWords: positiveScore, negativeWords: negativeScore, neutralWords: neutralScore }; } else if (positiveScore < negativeScore) { return { sentiment: "negative", positiveWords: positiveScore, negativeWords: negativeScore, neutralWords: neutralScore }; } else { return { sentiment: "neutral", positiveWords: positiveScore, negativeWords: negativeScore, neutralWords: neutralScore }; } }}// Create an instance of the SentimentAnalysis classconst sentimentAnalysis = new SentimentAnalysis();// Analyze some sample textconst result = sentimentAnalysis.getSentiment("I love this code and think it is great!");// Log the resultconsole.log(result); This code uses a class called SentimentAnalysis to perform sentiment analysis on a given text. The class has two arrays of positive and negative words and a method called getSentiment that performs the analysis.

The method first converts the text to lowercase and then uses two calls to reduce, to sum up, the number of times each positive and negative word appears in the text. It then calculates the number of neutral words by subtracting the positive and negative words from the total number of words. Finally, it compares the number of positive and negative words and returns a result that includes the sentiment and the number of positive, negative, and neutral words found.

While this code isn’t scientific because it doesn’t perform a deep analysis beyond breaking up a string into words, nor does it account for all positive, negative and neutral words, it’s a cool little implementation you could use for basic purposes.

Testing our codeBecause testing is very important and provides a great way to understand code, we will write some Jest unit tests for our sentiment analysis. It’s a basic implementation, but writing tests is a good habit to get into.

import SentimentAnalysis from "./sentiment-analysis";describe("SentimentAnalysis", () => { let sentimentAnalysis: SentimentAnalysis; beforeEach(() => { sentimentAnalysis = new SentimentAnalysis(); }); test("should return positive sentiment for positive text", () => { const result = sentimentAnalysis.getSentiment("I love this code and think it is great!"); expect(result).toEqual({ sentiment: "positive", positiveWords: 2, negativeWords: 0, neutralWords: 7 }); }); test("should return negative sentiment for negative text", () => { const result = sentimentAnalysis.getSentiment("I hate this code and think it is terrible!"); expect(result).toEqual({ sentiment: "negative", positiveWords: 0, negativeWords: 2, neutralWords: 7 }); }); test("should return neutral sentiment for neutral text", () => { const result = sentimentAnalysis.getSentiment("This code is just okay."); expect(result).toEqual({ sentiment: "neutral", positiveWords: 0, negativeWords: 0, neutralWords: 3 }); });}); Our test cases are basic, but we check that we return the three different types of sentiment from our code. We aren’t handling invalid values or other edge cases you might have in a proper bunch of tests.

The post Sentiment Analysis Using TypeScript Without Dependencies appeared first on I Like Kill Nerds.

View Details

The Fetch API is a modern and efficient way to retrieve resources from a server. It is an interface that provides a unified way to fetch resources from different sources. Fetch makes sending HTTP requests, including GET and POST, easy and handles responses asynchronously.

However, handling errors properly is important when working with the Fetch API. Errors can occur for various reasons, such as a network error, a server-side error, or an invalid URL. Failing to handle these errors can result in unexpected behaviour and break your application.

This article will look at several ways to handle errors using the Fetch API with Async/Await.

  1. Using Try/Catch BlocksTry-catch blocks are one of the most straightforward ways to handle errors when using Fetch. You can wrap the fetch call in a try block and catch any errors that occur in the catch block.

async function fetchData(url) { try { const response = await fetch(url); const data = await response.json(); // Use the data as needed } catch (error) { console.error(error); }} This approach is easy to implement and works well for basic error handling. However, it only works for errors thrown by the fetch function itself. If the response from the server indicates an error, such as a 404 Not Found or 500 Internal Server Error, this approach won’t catch those errors.

  1. Checking the response statusYou can check the response status in the returned Promise to handle server-side errors. The fetch function returns a Promise that resolves to a Response object. This Response object has a status property that indicates the HTTP status code of the response.

async function fetchData(url) { try { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // Use the data as needed } catch (error) { console.error(error); }} In this example, we use the response.ok property, which returns a Boolean indicating whether the HTTP status code is in the 200-299 range (i.e., a success status). If the response is not okay, we throw a new error that includes the HTTP status code.

  1. Handling specific error status codesSometimes, you may need to handle specific HTTP error status codes in a specific way. For example, you may want to show a different error message for a 404 Not Found error than for a 500 Internal Server Error. Sometimes, you may want to check for an authorized error response and handle it differently.

async function fetchData(url) { const response = await fetch(url); if (response.status === 404) { throw new Error('Page not found'); } else if (response.status === 500) { throw new Error('Server error'); } else if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data;} This example uses a series of if statements to handle specific HTTP status codes. We throw different errors for each HTTP status code and catch them in the calling code if needed.

  1. CombineWe can take all the above error-handling techniques and create a function that makes a Fetch request and uses checks alongside a try/catch to handle errors.

async function fetchData(url) { try { const response = await fetch(url); if (response.status === 404) { throw new Error('Page not found'); } else if (response.status === 500) { throw new Error('Server error'); } else if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error(error); }} This function uses a try-catch block to handle errors thrown by the fetch function. It also checks the response status to handle server-side errors and specific HTTP error status codes. If an error occurs, it logs the error to the console.

You can use this function or modify it to fit your specific needs.

For example, you could add additional error-handling logic or display an error message to the user instead of logging the error to the console. Or, use ranges instead of specific status code checks. But, as you can see, error handling with Fetch is a breeze. It’s a lot nicer than the days of using XMLHttpRequest.

The post Handling Errors with the Fetch API appeared first on I Like Kill Nerds.

View Details

I tend to get excited about virtual reality and have wanted to see it succeed for over a decade. While VR has undoubtedly grown, it’s not mainstream due to the barrier to entry. Most notably, requiring beefy PC setups or locked down (like the original PSVR headset). Adding to my growing collection of VR headsets, I preordered the PSVR 2 headset for the PlayStation 5.

There has been work done on untethered VR headsets, failed beginnings with Samsung creating phone VR headsets before Meta struck gold with the Meta Quest. Not only does it support using it by itself, but it can also be connected to a computer. Then you have the heavy, expensive hitters like the HTC Vive Pro 2 for powerful computer VR experiences.

This is why everyone was shocked when Sony announced PSVR 2 and its incredible specs:

  • 2000 x 2040 per eye panel resolution
  • OLED panels
  • Supporting 90Hz and 120Hz refresh rates
  • Four embedded cameras for headset and controller tracking
  • Embedded IR trackers for each eye
  • A vast array of sensors, including proximity sensors
  • Built-in microphone
  • All are driven by a single USB Type-C cable

Now, for a virtual reality headset, these are high-end specs. It puts the PSVR 2 headset right at the top of the list of headsets (spec-wise). All of the reviews so far seem to be highly favourable of the headset, especially with Sony, including haptic feedback and other additions to make the VR experience more immersive.

However, the cost the PSVR 2 headset is expensive. It costs more than the console itself to buy. A luxury that not a lot of people have right now with increasing interest rate increases, spiralling cost of living and uncertainty as the world edges closer to recession.

This is why the PSVR 2 will need the help of PC modders to survive. While I have no doubt those that can afford this headset will love it (myself included when it arrives), the PSVR 2 headset has the advantage of being close to the specs of the coveted HTC Vive Pro 2 headset (which is over double the cost of the PSVR 2 headset).

Support will inevitably come if Sony inevitably caves in and provides an official way to use the PlayStation VR 2 headset on a PC or modders find a way. The fact a single USB-C cable is all you need provides hope that the path to PC support won’t be as difficult as you might think. Better still, imagine if Sony had the foresight to monetise support and provided a paid add-on you could use to use the PSVR 2 headset on PC. It would mean they profit from PC support, which doesn’t diminish its exclusivity on the PS5.

The post The PlayStation VR 2 (PSVR 2) Headset Needs PC Modders to Survive appeared first on I Like Kill Nerds.

View Details

Harry Potter fans have waited for an open-world Harry Potter game for almost two decades, and it’s crazy to think that we may have finally got what we have been asking for. After a lengthy wait and fear of delays, it’s finally here.

So, the question is: does Hogwarts Legacy live up to the expectations, or do we have another No Man’s Sky and Cyberpunk 2077 situation on our hands?

From the beginning of the game, you’re thrown into the action. I won’t spoil the gameplay and storyline. The game does a good job of getting you to move around. At the start, you explore on foot, and then you get to use a broomstick. The game does a good job guiding you through Hogwarts, introducing you to the teachers, your classmates, and the things you need.

It’s Beautiful.From a graphics perspective, the game looks better than the official trailers and clips gave it credit for. Hogwarts Legacy looks incredible, and despite the fact it’s not a massive open world, it’s big enough it feels exciting, and there is plenty to explore. I didn’t test to see what the game looked like with performance mode turned on. I chose to prioritise graphics over performance. And despite that, the game performs well, even during intense battles.

It’s rare for a licenced IP like this to be so well executed. After being burned by other titles promising the world over the years and not delivering, it’s a shock to see a game so well done right out of the gate. There are weird little glitches and things with NPCs, but I have not encountered anything game-breaking like I did when Cyberpunk 2077 launched.

The depth of this game is deep and immersive. Not only does it do the lore of the Harry Potter universe justice, but it’s filled with secrets, puzzles, side questions and magic that keep you wanting to play the game.

Impressive CombatThe combat system is way better than I expected. You start off with basic spells and then learn more advanced ones as you progress. You can duel to practice, even against other groups. Not only can you perform spells, but you can also combo (which becomes quite important as you progress through the game). Once again, the fighting is way better than any official video clips released prior.

You can’t get by just blocking and fighting back when you start to go up in the difficulty levels. A degree of skill is required to win some of the fights you find yourself in, requiring you to choose the right spells and combos.

And complementing the combat is a great use of the PlayStation 5 Duelsense controller. The tactile feedback you get, the vibrations and feeling you get during battle, is surprisingly helpful.

Character CreationDuring the initial character creation, I found all the characters had a same-samey vibe. It’s hard to explain. But, no matter how hard you try to create a unique character, it’ll end up looking like a character you’ll always see.

Where this, fortunately, is fixed is the endless clothing options. You can go wild changing your outfits and style in the game. As you progress, you can get new items and give your character much-needed personalisation that addresses this.

But let’s be honest: who buys this game for the customisation options anyway? You want to fly around the wizarding world of Hogwarts and its surroundings. It’s a tiny insignificant downside.

Great sound designThe voice acting was mostly fantastic. There did appear to be times when some of the characters you meet sounded like they were hired from Fiverr, but for the most part, the game is consistent in its delivery of character voicing from the main character to most of the NPCs.

Surprisingly, the thing I was shocked about the most was the music. Instead of just unoriginally copying music from the Harry Potter films, the game offers a unique take on Harry Potter’s mysterious and magical music you would associate with the films but offers a unique spin on it that makes the music feel like its own thing.

You will also notice the variations in the music during different scenes and battles, like the music was curated for a film and not a game. This is the kind of detail many games overlook and it makes a much bigger difference to the overall atmosphere of the game than you would think.

There is no Quidditch.Before the game was released, we knew there would be no Quidditch. And in the game, there is an explanation for why there is no Quidditch. Oddly enough, despite the reasoning, there is still no Quidditch arena, which seems odd.

Many fans hope we inevitably get a Quidditch DLC of some kind, which would make this game even more perfect. And I have hope that this will happen, perhaps with changes to the storyline that allows Quidditch to return to the game universe. We already have the flying mechanics; let’s get it in there.

ConclusionIf you were on the fence, get down. Hogwarts Legacy has all but cemented it will be a serious game-of-the-year contender, and it will take some serious competition for it to be dethroned. It’s immersive, mysterious, exciting and a solid IP title.

Given the game’s success and how well-received it is from critics and those already playing it, Avalance and Warner Brothers would be crazy not to pump out a few DLC packs for this game. They have a solid foundation here; they can expand with many new things (hopefully Quidditch).

This title was worthy of a pre-order (which I did and got early) and a day-one purchase. Don’t wait for it to go on sale. This game exceeds my expectations and most likely will exceed yours too.

The post Hogwarts Legacy: PlayStation 5 Review appeared first on I Like Kill Nerds.

View Details

I have never understood why FizzBuzz was deemed a means of screening developers. The idea is for multiples of 3; you print Fizz. For multiples of 5, you print Buzz, and for multiples of 3 and 5 (15), you print FizzBuzz.

While this kind of prescreening question might have worked 15 years ago when information wasn’t as accessible as it is now (smartphones, smartwatches. etc.), it seems strange that some companies still ask developers how to write FizzBuzz.

The modulus operator returns the remainder of a division operation between two numbers. Ironically, it’s the kind of operator you don’t see many front-end developers using anyway. Even the most junior developers can easily Google before an interview to know that you use the modulus operator.

Here is a basic FizzBuzz implementation in Javascript

for (let i = 1; i <= 100; i++) { if (i % 15 === 0) { console.log("FizzBuzz"); } else if (i % 3 === 0) { console.log("Fizz"); } else if (i % 5 === 0) { console.log("Buzz"); } else { console.log(i); }} In my experience, non-technical skills are more important than technical skills, and few companies focus on non-technical skills. Generally, I am against technical hiring trivia questions. They tell you nothing about the developer’s skill level if they’re an excellent culture fit, if they have a good attitude.

In the case of the aged old FizzBuzz, companies may ask for variations on FizzBuzz beyond the standard; 3, 5 and 15 divisions, but most likely not. If your company is using FizzBuzz screening questioning, it might be time to reevaluate if it’s effective.

The post Is Asking Developers How to Write FizzBuzz Outdated? appeared first on I Like Kill Nerds.

View Details

ChatGPT is an AI-powered conversational API by Open AI that generates a lot of hype and fear amongst consumers, professionals and experts alike. Depending on who you talk to, ChatGPT will either revolutionise how we work, or it’s coming for our jobs and will taint academia.

You might have seen some news stories, including the impressive feats of ChatGPT passing prestigious law and business exams. And while these stories are understandably concerning, AI is based on learning and is no different from people reading books and learning materials available online to do the same thing.

One area of concern for some is ChatGPT and AI replacing programmers. Can ChatGPT write code? Yes. But it’s not as impressive as you may think. Is AI a threat to programmers? Should we be concerned our once coveted jobs are under threat?

No, ChatGPT is not designed to replace programmers. Instead, it can assist them in the development process. ChatGPT can generate code snippets and suggest solutions based on patterns it has learned from data, but it lacks the creativity and critical thinking skills that human programmers possess. Ultimately, ChatGPT is a tool, and like any other tool, its effectiveness depends on its use.

In my testing of ChatGPT, I found it could generate code for simplistic problem-solving questions quite well. For example, ask ChatGPT to generate a Javascript function that can generate random guid strings, and it will give you code that will probably work. But, as programmers, we don’t work on tiny problems.

Here is what I asked ChatGPT:

Write me a Javascript function that can generate valid guids without using dependencies And here is the code it created:

function generateGuid() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return ( s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4() );} In this situation, it generated code that works. You can take this and run it in the console inside developer tools, and it will generate a guid string in the format of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx — impressive, but you could achieve the same thing using a library of a simple Google search.

Where ChatGPT seems to fail is more complex coding tasks. Sometimes it will comply and generate code, which will probably not be valid (unless you get lucky). Other times it will outright deny generating the code and occasionally provide bullet-point tips telling you how you might be able to do it.

ChatGPT has proved itself in its ability to write boilerplate code. Sometimes you want a primary starting point. Tasks that are simple but time-consuming. If you can offload those to AI tools, you’re saving possibly hours. Like our function above, something an experienced programmer could do, but AI can do faster. More impressively, you can even ask it follow-up questions like, “Now, write me some unit tests for this code,” and it will.

People see ChatGPT as this extraordinary genius AI that can do everything. Still, it becomes less impressive when you realise ChatGPT and all forms of current artificial intelligence are just more intelligent search engines. Think about it.

ChatGPT and all known public AI are based on publicly scraping data. Isn’t this what search engines do? When you perform a search query, it queries that data and returns a result. Where ChatGPT differs from a search engine is its ability to work with context, allowing you to ask follow-up questions or, in some cases, correct it when it is wrong.

And then we come full circle. What is it many programmers do when they get into trouble? They Google. Now, imagine if you had an AI companion; you could provide problematic code or error messages, and because it scraped the documentation, StackOverflow, blogs and other data, it could do the work you would usually do of finding a solution and prevent it to you. That’s where the true power of ChatGPT lies.

And that’s the critical thing that programmers need to understand. While it’s second nature to know what to type into Google or ChatGPT, that’s a skill you learn as a programmer. You learn what to type in to get the result you need. That’s the difference between a junior, midweight and senior developer: your ability to condense a problem down into a Google search query.

It takes skill to be a programmer. You need to know how to code and what prompts to write into Google, ChatGPT or other tools. A solution is only a sum of its parts. And while ChatGPT can handle some of those parts, many facets of programming are beyond the ability of ChatGPT.

While some hysterically decry the end of programmers, lawyers, and other industries, AI will be another tool programmers can use to be better and more efficient at their jobs.

If anyone should be concerned, it’s Google. ChatGPT and other AI tools are a real threat to Google and its search engine. It’s the reason Microsoft invested billions into Open AI and why they’re integrating ChatGPT into Bing. If people choose to use ChatGPT instead of Google, that’s one less set of eyeballs to show ads to (although most developers use an ad blocker anyways).

The post Will ChatGPT Replace Programmers? appeared first on I Like Kill Nerds.

View Details

Have you ever stopped to think about the impact social media has on your peace of mind? It was a realisation that came too late towards the end of 2022. The constant arguing, negativity, and drama on platforms like Facebook and LinkedIn took a toll on my mental health and well-being. I realised I needed to step back and break free from the negative echo chamber.

You might not realise it, but even seemingly harmless platforms like LinkedIn can have a negative impact on your life. What started as a professional networking platform has fallen prey to the negativity that plagues other social media platforms like Facebook. The constant barrage of conflicts and drama was too much for me to handle.

So, I decided to quit most of my social media accounts, except for one – Instagram. I use it to document my life through photos, and I don’t feel compelled to open it all the time as I did with Facebook and LinkedIn. It’s a nice break from the constant negativity that comes with other social media platforms.

Quitting social media was about more than just avoiding drama and negativity. It was about regaining control over my time and energy. I was tired of feeling drawn into arguments and drama on Facebook and the negativity surrounding mass lay-offs and recruiter spam on LinkedIn. I was tired of feeling like I was wasting my time and energy on something that wasn’t productive or meaningful.

So, I leapt and deleted those accounts. And you know what? It was one of the best decisions I’ve ever made. I have more time to focus on the things that are truly important to me, like my relationships and my passions. I’m less likely to be pulled into arguments and have more control over my time and energy.

We have been led to believe that we need LinkedIn to market ourselves, to be in the market. I realised that my GitHub profile speaks for me as a developer much better than any LinkedIn profile ever could. Most of my job opportunities have come from either applying for them or people reaching out to me through my blog.

LinkedIn is probably great if you’re in sales, a recruiter, or a company using it to market yourself. Still, it’s primarily low-value content from self-professed thought leaders and celebrities. I have never applied for a job through LinkedIn nor got a job from a recruiter spamming me an opportunity. Usually, recruiters send me jobs I am not qualified for anyway.

If you’re feeling overwhelmed by social media and the constant negativity, I encourage you to consider taking a break. It’s okay to prioritise your peace of mind and break free from the negative echo chamber. You might be surprised by how much better you feel.

The post Why I Quit Social Media (Almost) – A Journey to Better Mental Health appeared first on I Like Kill Nerds.

View Details

Well, it’s 2023, and many experts are predicting a recession on the horizon. And while no one knows how bad it will be or if many countries will avoid recession, one thing is sure: companies that can weather the storm will be the ones that can adapt quickly and efficiently.

Despite this pending threat of economic meltdown, many companies persist with anti-WFH policies, offering ultimatums to employees: return to the office or quit.

Isn’t it strange that companies would instead force their employees into an office even though inflation has substantially driven up the cost of living? Interest rate increases from central banks have eaten into the budget as mortgage and rent payments skyrocket. It’s not free to catch public transport or drive to work (especially if you have to pay for parking).

Unless you’re willing to offer a company car or subsidised transport, whenever an employee is forced into the office to do a job they can do remotely, they’re losing money.

And the ironic thing about all this is the benefits of remote work are not exclusive to employees. Companies reap the rewards of remote work too.

When employees work remotely, companies don’t have to pay for expensive office space or other physical infrastructure. This can save a significant amount of money, especially if the recession hits hard and budgets are tight. The electricity cost has increased in some countries by over 100%. Offices are not immune to those costs.

Productivity is an important metric to increase to pull an economy out of recession. Despite the unfounded lies that remote workers are slacking off and lazy, studies have shown that remote workers are often more productive than those who work in an office. This can help companies get more done with fewer resources, which is especially important during a recession.

Of course, transitioning to 100% remote work is not without its challenges. Companies must invest in technology and training to ensure employees have the tools and resources to be productive. They also need to find ways to foster collaboration and communication among remote teams.

But, the crazy thing about all of this is these tools have existed for years before WFH became the norm. This isn’t some new problem that has been sprung on employers. Some companies have been offering remote work for well over a decade. I know people who have been working remotely since the late nineties.

We have Asana, Trello, Jira and a bunch of other apps that can make prioritising and streamlining the work pipeline that does not require being in the office. If you prescribe a methodology like Kanban that encourages developers to pick from a pool of work and limits overwhelming your employees, you would be surprised how effective it can be.

And then, we have communication tools like Slack which has a plethora of bots and integrations that can make communication effective. More your daily standup meeting (if you have one) into a Slack channel, and people can post their text updates there. We have Zoom or Google for video calls. Notion for wikis, content organisation and sharing. GitHub and Bitbucket for code.

Think about what your day is like in the office for a moment. You’re sitting at a desk working at a computer. Well, you can do that at home. Loud kitchen conversations, the sound of a coffee machine hissing, the sound of someone torturing milk for their coffee, the constant interruptions of someone coming over to your desk to ask a question they could have Slacked.

It’s so bizarre that some people believe remote workers are slacking off, even though most modern offices are filled with distractions and perks designed to make you leave your desk and use (like beer kegs, coffee, free food, gaming consoles, breakout spaces). I have distractions at home too, but I am less tempted.

And then you have the extended lunch breaks. I can’t tell you the number of times I would go to lunch with coworkers when I worked in an office and had a two-hour lunch break. Not on purpose, but because people would lose track of time. Some would get a beer at lunch (or two). And then you have the coffee runs when someone says they’re getting coffee, and some people feel the need to tag along.

Remotely, most of my working days are spent eating lunch at my desk. I don’t say that because I want praise or an award. I feel more motivated, relaxed and less distracted at home. By forfeiting a lunch break, I’ll finish up early for the day (which I will inform my coworkers about). This coincides with my son getting home from school, and I go outside and kick a soccer ball with him before dinner.

I consider myself a hard worker, but I can tell you, when I worked in an office, I was more distracted and wasted hours a week on non-work related things. Working remotely subconsciously makes you feel you must prove to yourself that you’re contributing. But, once you realise this and work just how you would in an office, you don’t have to prove anything. Let the work speak for itself.

Nothing has been better for me for my mental health than remote work. Sadly, many people who experienced remote work for the first time did so during the pandemic. And let me tell you something: remote work during the pandemic, even for someone who loves it like me, was difficult.

Our kids were at home, much younger than they are now, because schools closed down. We couldn’t go anywhere. Our lives consisted of work, staying home, and working. Sadly, my wife was disproportionately affected by this too.

I wanted to point out that remote work during the pandemic is not indicative of properly implemented remote work. When you force people to stay at home, it’s never a good thing. All workers need is choice. I am not saying companies should shut down their offices completely, but by offering remote work, you can offset some of the costs you would incur.

It’s simple math—fewer overheads = more money saved.

The post Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023 appeared first on I Like Kill Nerds.

View Details

It’s 2023, and we still have no simple way to insert Gutenberg blocks into WordPress using wp_insert_post. You’re out of luck if you want to pull content from an API and insert it dynamically with ease. There are methods like parse_blocks and render_blocks but they still require a lot of messing around to work with.

The way Gutenberg blocks work is strange. They’re not stored as an array or structured data in the database. They are stored in the HTML as HTML comments.

For a YouTube embed, it might look like this:

```

``` You can see how the blocks are handled by viewing the source of your page/post. I can understand why they did it this way for backward compatibility, but it means if you were previously inserting content into your posts, they wouldn’t be Gutenberg blocks by default.

Which is why I ended up creating something that works with the Gutenberg HTML comments. It’s a rather simple function that takes the name, attributes and some content.

function create\_block( $block\_name, $attributes = array(), $content = '' ) { $attributes\_string = json\_encode( $attributes ); $block\_content = '<!-- wp:' . $block\_name . ' ' . $attributes\_string . ' -->' . $content . '<!-- /wp:' . $block\_name . ' -->'; return $block\_content;} Going one step further, I also created a wrapper function called create_blocks which allows you to pass in multiple Gutenberg blocks.

function create\_blocks( $blocks = array() ) { $block\_contents = ''; foreach ( $blocks as $block ) { $block\_contents .= create\_block( $block['name'], $block['attributes'], $block['content'] ); } return $block\_contents;} And here is how you use it.

$blocks = array();$blocks[] = array( 'name' => 'paragraph', 'attributes' => array( 'align' => 'center' ), 'content' => '<p>Hello World!</p>',);$blocks[] = array( 'name' => 'paragraph', 'attributes' => array( 'align' => 'left' ), 'content' => '<p>This is another paragraph.</p>',);$blocks[] = array( 'name' => 'paragraph', 'attributes' => array( 'align' => 'right' ), 'content' => '<p>And this is yet another paragraph.</p>',);$post\_content = create\_blocks( $blocks );$post\_id = wp\_insert\_post( array( 'post\_title' => 'My post title', 'post\_content' => $post\_content, 'post\_status' => 'publish', 'post\_type' => 'post',) ); Is this the best solution you could use? Probably not. Did it work for me? Yes. This saved me the hassle of coming up with a clever solution when all I needed was something that got me out of a pickle.

The post How to Insert Gutenberg Blocks Using wp_insert_post appeared first on I Like Kill Nerds.

View Details

I recently worked with GitHub Actions, where I generated a JSON file and then needed to add it to the repository. I parsed some Markdown files and then dynamically created a manifest JSON file of them, committing it into the repo every time a push was made.

I hit a permissions roadblock I embarrassingly spent over an hour solving, and I hope you don’t make the same mistake.

name: Build Blog JSONon: push: paths: - 'blog-posts/**/*.md'jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 - name: Get list of Markdown files run: | cd blog-posts files=($(ls *.md)) json\_array=() for file in "${files[@]}" do date\_string=$(grep -E '^date: ' "$file" | cut -d' ' -f2) # Use the date command to extract the year, month, and date year=$(date -d "$date\_string" +%Y) month=$(date -d "$date\_string" +%m) day=$(date -d "$date\_string" +%d) json\_array+=($(echo "{\"file\":\"$file\",\"date\":\"$date\_string\",\"year\":\"$year\",\"month\":\"$month\",\"day\":\"$day\"}")) done echo "[$(IFS=,; echo "${json\_array[*]}" | jq -s -c 'sort\_by(.date)')]" > ../static/blog.json - name: Remove trailing comma run: | sed -i '$ s/,$//' static/blog.json - name: Commit changes run: | git config --global user.email "no-reply@github.com" git config --global user.name "GitHub Actions" git add static/blog.json git commit -m "Update blog.json" git remote set-url origin https://x-access-token:${{ secrets.GITHUB\_TOKEN }}@github.com/${{ github.repository }} git push env: GITHUB\_TOKEN: ${{ secrets.GITHUB\_TOKEN }} Now, the important part of my action is the Commit changes action. You need to supply an email and name for the committer. In this instance, I just made up something generic. The first important line is setting the origin URL. We are referencing some variables GitHub creates for us automatically. Notably, GITHUB_TOKEN and repository.

Many of the blog posts and even the documentation alluded to the fact that this is all you have to do. And maybe I was referencing outdated information, but there is an additional step for permissions you need to do.

Under your repository settings, go to “Actions” and then “General”, and scroll right to the bottom until you get to “Workflow permissions”. By default, the GITHUB_TOKEN that is automatically created only has read permission. To commit, you need Read and write permissions.

Without this change, your GITHUB_TOKEN will not have permission and you will keep seeing a permission denied message. That’s all you need to do.

The post How to Create Files in a GitHub Action and Commit Them to Your Repository appeared first on I Like Kill Nerds.

View Details

In a hilarious read in the Australian Financial Review, a propaganda piece disguised as an article on remote work and office perks has been published titled WFH raises the bar for offices. I meant to post this last year, so this has been sitting in my drafts.

Mirvac, a large Australian property developer with a vested interest in getting people back into the office (because it also owns commercial real estate) has set up a trial space for clients and architectural firms. But, showing just how out of touch they are, a paragraph in the linked story reads.

There are pot plants and whiteboards on wheels. Desks that can roll around. Power points that hang from the ceiling. Telephone boxes that bring back memories of Dr Who. Foam blocks that can be stacked like Lego.”

Is this what employees want, do they really want pot plants and whiteboards on wheels? Offices have had these things since the eighties. When deciding to choose an employer, whiteboard on wheels isn’t high on my wishlist of perks.

In other articles disguised as independent think-pieces but really being funded by the commercial real estate lobby, allegedly according to the AFR, some companies are trading up to try and lure people back into the office.

I am not convinced.

While I have no desire to go back into the office, I did ask myself the question; what would it take for me to go back into the office?

In my case;. Nothing.

Now, unlike some other up and coming workers who have never set foot into an office before, I’ve experienced what it is like on the other side.

I’ve worked in open plan offices as well as more traditional room based offices. I then worked hybrid for a few years before the pandemic forced the hand of employers and everyone for a moment in time (those that could) worked remotely.

For some people, the cat was out of the bag. Remote work was an eye opening experience. For some, it was a negative one and for many, a positive one.

The post What Would Get People Back Into the Office? appeared first on I Like Kill Nerds.

View Details

PHP, the programming language that has been declared dead more times than a cat has lives, is still very much alive and kicking. Despite what some elitist developers may say, PHP is not going anywhere anytime soon.

Despite all the naysayers constantly predicting its demise, PHP continues to chug along, powering some of the biggest websites on the internet.

Let’s start by taking a look at the statistics. According to W3Techs, PHP is currently used by 78.9% of all websites with a known server-side programming language. That’s a pretty impressive number, considering that PHP has been around since 1995. To put it in perspective, that’s longer than some developers have been alive. And the reason why it has been around for so long is that it just keeps getting better.

Then you have the big players. Facebook, one of the most visited websites in the world, uses PHP. Wikipedia, the go-to source for all knowledge, also uses PHP. And let’s not forget about WordPress, the content management system that powers over 40% of all websites on the internet. These websites aren’t small, insignificant players. They’re major players in their respective industries and rely on PHP.

I know Facebook (or Meta) has instigated initiatives to increase the performance of PHP, including Hack, but that’s because they face scaling problems that most developers could only dream of.

The fact that these companies still use PHP but also contribute patches and updates has kept the language alive, even as trendier languages like Go or Rust have popped up.

But it’s not just about the big players. PHP has been around for over two decades and has a huge user base. It’s not just a popular language with big corporations and enterprises. Small businesses, independent developers, and hobbyists all use PHP as well. And it’s not just because they’re used to it or because they don’t know any better. PHP has stood the test of time because it’s a solid, stable language that’s easy to learn and use.

And let’s not forget about all the modern features that have been added to PHP in recent years. Things like static types, union types, and other new features have made PHP a much more powerful language. The composer package manager, tooling, and frameworks like Laravel and Symfony have made it even more accessible for developers.

Some might argue that PHP is outdated and that there are newer, better languages. But the truth is that PHP is still relevant and is not going anywhere. Sure, there are other languages that are more popular or trendy right now, but PHP has a proven track record, and it’s not going anywhere.

So, to all the PHP haters out there, I say this: PHP may not be the newest or the coolest kid on the block, but it’s still here, and it’s still kicking. And it’s not going anywhere anytime soon.

The post PHP Will Not Die appeared first on I Like Kill Nerds.

View Details

If you have been a reader of my blog for a while, you would know that I am an avid cryptocurrency enthusiast. I believe in the tech more so than the financial side. I find blockchains fascinating because, despite their perceived complexity, you can implement a blockchain in any programming language; Javascript included.

I thought it would be fun to create a blockchain using TypeScript and then iteratively change the code to offer more flexibility, such as the ability to add metadata into the blocks and query the blocks themselves.

Disclaimer: This is all proof of concept and if you’re planning on using this for actual financial purposes, I would consider making the code better. This is just a bit of fun.

Please also note that the crypto-js package is being used here to handle the sha256 hashes.

import * as CryptoJS from "crypto-js";class Block { public index: number; public timestamp: number; public data: string; public jsonData: any; public previousHash: string; public hash: string; constructor(index: number, data: string, jsonData: any, previousHash: string) { this.index = index; this.timestamp = Date.now(); this.data = data; this.jsonData = jsonData; this.previousHash = previousHash; this.hash = this.calculateHash(); } public calculateHash(): string { // Use SHA256 to generate a hash for the current block return CryptoJS.SHA256(this.index + this.timestamp + this.data + JSON.stringify(this.jsonData) + this.previousHash).toString(); }}class Blockchain { public chain: Block[]; constructor() { this.chain = [this.createGenesisBlock()]; } public createGenesisBlock(): Block { // The first block in the blockchain is called the Genesis Block return new Block(0, "Genesis Block", "0"); } public getLatestBlock(): Block { // Returns the last block in the chain return this.chain[this.chain.length - 1]; } public addBlock(newBlock: Block): void { // Assign the hash of the previous block to the new block's previousHash property newBlock.previousHash = this.getLatestBlock().hash; // Calculate the new block's hash newBlock.hash = newBlock.calculateHash(); // Add the new block to the chain this.chain.push(newBlock); } public isChainValid(): boolean { for (let i = 1; i < this.chain.length; i++) { const currentBlock = this.chain[i]; const previousBlock = this.chain[i - 1]; // Check if the current block's hash is still valid if (currentBlock.hash !== currentBlock.calculateHash()) { return false; } // Check if the previousHash of the current block is still valid if (currentBlock.previousHash !== previousBlock.hash) { return false; } } // If all checks pass, the chain is valid return true; }} We have a simplistic blockchain where the chain and blocks are separate, using classes to clean things up.

And to use our newfound blockchain, here is how we would implement it:

// Import crypto-js libraryimport * as CryptoJS from "crypto-js";// Create a new blockchainconst myBlockchain = new Blockchain();// Add some blocks to the blockchainmyBlockchain.addBlock(new Block(1, "This is block 1", {name: "John", age: 30}, myBlockchain.getLatestBlock().hash));myBlockchain.addBlock(new Block(2, "This is block 2", {name: "Jane", age: 25}, myBlockchain.getLatestBlock().hash));myBlockchain.addBlock(new Block(3, "This is block 3", {name: "Bob", age: 35}, myBlockchain.getLatestBlock().hash));// Check if the blockchain is validconsole.log(myBlockchain.isChainValid()); // Output: true We have a functional blockchain now, but let’s make one more change to make it useful—the ability to get blocks by ID or metadata properties in the block. Inside the Blockchain class we create a method called getBlock which can query for blocks in our chain.

import * as CryptoJS from "crypto-js";class Block { public index: number; public timestamp: number; public data: string; public jsonData: any; public previousHash: string; public hash: string; constructor(index: number, data: string, jsonData: any, previousHash: string) { this.index = index; this.timestamp = Date.now(); this.data = data; this.jsonData = jsonData; this.previousHash = previousHash; this.hash = this.calculateHash(); } public calculateHash(): string { // Use SHA256 to generate a hash for the current block return CryptoJS.SHA256(this.index + this.timestamp + this.data + JSON.stringify(this.jsonData) + this.previousHash).toString(); }}class Blockchain { public chain: Block[]; constructor() { this.chain = [this.createGenesisBlock()]; } public createGenesisBlock(): Block { // The first block in the blockchain is called the Genesis Block return new Block(0, "Genesis Block", "0"); } public getLatestBlock(): Block { // Returns the last block in the chain return this.chain[this.chain.length - 1]; } public addBlock(newBlock: Block): void { // Assign the hash of the previous block to the new block's previousHash property newBlock.previousHash = this.getLatestBlock().hash; // Calculate the new block's hash newBlock.hash = newBlock.calculateHash(); // Add the new block to the chain this.chain.push(newBlock); } public getBlock(searchTerm: string | number, by: 'id' | 'metadata' = 'id'): Block | undefined { if (by === 'id') { const block = this.chain.find((b) => b.index === searchTerm); return block; } else if (by === 'metadata') { // define a function to check if the jsonData of a block contains the searchTerm const checkMetadata = (jsonData: any) => { for (let key in jsonData) { if (jsonData[key] === searchTerm) { return true; } } return false; } // check if jsonData property exists before searching by metadata values const block = this.chain.find((b) => b.jsonData && checkMetadata(b.jsonData)); return block; } } public isChainValid(): boolean { for (let i = 1; i < this.chain.length; i++) { const currentBlock = this.chain[i]; const previousBlock = this.chain[i - 1]; // Check if the current block's hash is still valid if (currentBlock.hash !== currentBlock.calculateHash()) { return false; } // Check if the previousHash of the current block is still valid if (currentBlock.previousHash !== previousBlock.hash) { return false; } } // If all checks pass, the chain is valid return true; }} This method takes two parameters searchTerm and by, where searchTerm is the value you want to search for and by is either ‘id’ or ‘metadata’ to define what you want to search by. By default, it is set to ‘id’, so if you call the method without passing any second parameter, it will search by id.

If by is ‘id’, it uses the Array.prototype.find method to search the chain array for a block with a matching index property. If it finds a match, it returns the block. Otherwise, it returns undefined.

If by is ‘metadata’, it uses the Array.prototype.find method to search the chain array for a block with metadata that matches the searchTerm . It uses a helper function checkMetadata that iterates over the jsonData of the block and checks if any of the values match the searchTerm. If it finds a match, it returns the block. Otherwise, it returns undefined.

You can then use this method to search for blocks by ID or metadata values like this:

console.log(myBlockchain.getBlock(1)); console.log(myBlockchain.getBlock("John", 'metadata')); ConclusionAs you can see, a blockchain is just a collection of objects with hashes. While this is a rather simplistic implementation of a blockchain, it shows that it’s not as complicated as you would think.

The post How to Create a Blockchain With TypeScript appeared first on I Like Kill Nerds.

View Details

In a recent project, I worked with Markdown files that contained metadata at the top for blog posts. I needed to parse the Markdown with JavaScript and make a set of key/value pairs.

As you can see, the metadata is encapsulated in – – – with the metadata contained within.

// Function to parse metadata from a markdown fileconst parseMarkdownMetadata = markdown => { // Regular expression to match metadata at the beginning of the file const metadataRegex = /^---([\s\S]*?)---/; const metadataMatch = markdown.match(metadataRegex); // If there is no metadata, return an empty object if (!metadataMatch) { return {}; } // Split the metadata into lines const metadataLines = metadataMatch[1].split("\n"); // Use reduce to accumulate the metadata as an object const metadata = metadataLines.reduce((acc, line) => { // Split the line into key-value pairs const [key, value] = line.split(":").map(part => part.trim()); // If the line is not empty add the key-value pair to the metadata object if(key) acc[key] = value; return acc; }, {}); // Return the metadata object return metadata;}; You can call this function and pass in the markdown file content. It will return an object with the metadata.

const markdown = `---title: My Blog Postauthor: John Doedate: 2021-01-01---# My Blog PostThis is the content of my blog post.`;var metadata = parseMarkdownMetadata(markdown);console.log(metadata);// Output: { title: "My Blog Post", author: "John Doe", date: "2021-01-01" } The great thing about this solution is it requires no additional libraries. It’s all plain Javascript.

The post Parsing Metadata Inside of Markdown Using JavaScript Without Any Dependencies appeared first on I Like Kill Nerds.

View Details

In a heartwarming holiday tale, a father received the Christmas gift of his dreams: socks.

According to sources close to the family, the dad has been dropping hints about his love for socks for years, but nobody ever seemed to listen. “I always thought he was joking,” said his wife. “But apparently he was dead serious.”

The dad’s eyes lit up on Christmas morning as he tore open the wrapping paper to reveal a gift box filled with colourful socks. “I can’t believe it,” he exclaimed. “Finally, someone got me what I really wanted!

The socks have already become a staple in the dad’s daily attire, and he can’t stop raving about their comfort and style. “I never knew socks could be so fancy,” he said. “I feel like a whole new man.

The family is thrilled to have finally found the perfect gift for the sock-loving dad, and they’re already planning on adding more socks to his collection next year. “We’ll never forget the joy on his face when he opened those socks,” said the wife. “It was truly a Christmas miracle.”

The post Dad Overjoyed with Sock-tastic Christmas Gift: ‘I Feel Like a Whole New Man’ appeared first on I Like Kill Nerds.

View Details

In a WordPress project I am building, I needed a way to programmatically update the post status of a post on the edit screen, specifically in the Gutenberg editor. Before arriving at the solution below, I first struggled to figure this out. I was trying to call the updatePost method with a post object and […]

The post Programmatically Update the Status of a Post Using Gutenberg JS appeared first on I Like Kill Nerds.

View Details

When WordPress introduced the Gutenberg editor, it was a mess, to say the least. Everything was turned upside for developers and things that worked in previous versions were completely broken when Gutenberg was released. One of the things that were broken in WordPress was the ability to hide a meta box on the editor screen. […]

The post How to Hide Meta Boxes in WordPress Gutenberg appeared first on I Like Kill Nerds.

View Details

The Advanced Custom Fields plugin for WordPress is invaluable. It has filled a gap in WordPress for the better part of a decade and is one of the first plugins that I install in a new WordPress installation (I have a lifetime developer licence). The ACF plugin provides a Javascript API available using acf it […]

The post How to programmatically populate a TinyMCE Advanced Custom Fields field in WordPress appeared first on I Like Kill Nerds.

View Details

In the beginning, I was one of the loud developers protesting WordPress Gutenberg. But, now that Gutenberg has been around for a while, I’ve grown to like it. I can’t tell if it’s because of Stockholm syndrome or if it has actually improved. Anyway. One of the looming problems users of WordPress will still face […]

The post Programmatically Clicking the “Convert to Blocks” Button in WordPress Gutenberg on the Edit Screen appeared first on I Like Kill Nerds.

View Details

There are many different ways to solve this use case. You want to wait for an element to exist on the page and when it does, run a callback function. It seems simple enough, but what’s the easiest way? By using some recursion and a setInterval call, we can poll for an element using document.querySelector […]

The post Waiting for an Element to Exist With JavaScript appeared first on I Like Kill Nerds.

View Details

Remote work (also known as WFH) is a hot topic in 2022. As pandemic-era mandates and restrictions come to an end, there has been a new battle forming. In the left corner, we have companies that want their employees to come back into the office, and in the right-hand corner, we have employees who have […]

The post Stop Forcing People Back Into the Office appeared first on I Like Kill Nerds.

View Details

In some use cases, it can be beneficial to pass environment variables into your code. In my case, at build time I pass an environment variable to Webpack in the form of --env production and so forth. I wanted to get this in my code so I could load different configuration files depending on the […]

The post Passing Environment Variables Into Your Code With Webpack appeared first on I Like Kill Nerds.

View Details

As a homeowner with a mortgage, interest rate rises have become an area of interest for my wife and me. As the Reserve Bank of Australia (and the rest of the world) sees continued rate hikes, it’s important to know how much extra money you’ll need to cough up. I wanted a simple tool that […]

The post Rate Rise Calculator appeared first on I Like Kill Nerds.

View Details

For some Quad Cortex users, you will encounter an issue with the WiFi not working. While your first thought might be yoy have a defective unit, the issue might be more simple than you think. The Quad Cortex only operates on the 2.4GHz band of WiFi. This band offers slower speeds than 5GHz WiFi, but […]

The post Fixing WiFi issues with the Neural DSP Quad Cortex appeared first on I Like Kill Nerds.

View Details

In many cases when you’re working with TypeScript, there are type definitions available for almost every package out there. However, in some circumstances, you might find yourself working with a third party that adds a property to the window object. Think a script tag like how Google Analytics works by adding in the ga property […]

The post How to Extend the Window Object in TypeScript appeared first on I Like Kill Nerds.

View Details

The Aurelia 2 makes command ships with the option to scaffold applications and plugins. However, the plugin scaffold uses Webpack and a bunch of dependencies for building plugins. There are reasons that the plugin skeleton uses Webpack. Firstly, HTML imports need to be inlined in bundled code or you’ll encounter issues with HTML files not […]

The post Build Aurelia 2 Plugins and Bundling With Only TypeScript appeared first on I Like Kill Nerds.

View Details

Over the last few years, I have created a few plugins for Aurelia, mostly for Aurelia 1. However, with Aurelia 2 on the horizon (possibly released if you’re reading this in the future), I have decided to clean house and adopt a new strategy. My approach has always been to put my plugins into separate […]

The post Moving All My Aurelia Plugins Into a Monorepo appeared first on I Like Kill Nerds.

View Details

In case you weren’t aware, recently one of Australia’s large telecommunication companies Optus suffered one of the largest cybersecurity breaches to date. While the extent of the data breach has yet to be revealed, Optus has 9.7 million subscribers and the data taken allegedly could go back to 2017 and involves former customers. Allegedly, the […]

The post The Weird Saga of the Optus Cybersecurity Breach appeared first on I Like Kill Nerds.

View Details

A few years ago, I ditched the concept of a dual monitor setup as 30″+ displays started to come down in price, and getting a single large monitor instead of multiple smaller ones made more sense. After using my trusty Samsung SJ55W 34″ widescreen for a while, I recently tired of the widescreen monitor. It’s […]

The post Programming on a Curved Monitor appeared first on I Like Kill Nerds.

View Details

After avoiding Tailwind for such a long time, I finally decided to sit down and see what the hype was all about and use it with Aurelia 2. There are some pros and cons, some complications but it was a surprisingly positive experience.

The post I tried TailwindCSS for the first time appeared first on I Like Kill Nerds.

View Details

In this video, I compare some basics like reactivity, component creation and events in Aurelia 2 and Svelte. You’ll notice some similarities between the two but a few differences in the approach to bindables and component creation.

The post Aurelia 2 vs Svelte — The battle of two front-end underdogs appeared first on I Like Kill Nerds.

View Details

I am an avid reader of Medium, and it’s no secret that the quality of Medium articles has gone downhill over the last couple of years. Clickbait articles are intentionally titled and written to garner a response but lack substance. Amongst the shining gems, is a pile of faeces. One recently caught my eye. An […]

The post It’s 2022. We’ve Suffered Enough: Developers Use Whatever You Want appeared first on I Like Kill Nerds.

View Details

Playwright makes what used to be complicated in end-to-testing almost too easily, especially waiting for network requests. However, in the case of single-page applications (SPA) where a click on a link or button maybe fire a request but not a page load, you can encounter a situation where Playwright encounters a race condition between clicking […]

The post Reliably waiting for network responses in Playwright appeared first on I Like Kill Nerds.

View Details

At work, I’ve been migrating us over from Cypress to Playwright for end-to-end tests. In that time, we’ve enabled two-factor authentication functionality in our application for security. These TOTP tokens are great for security but provide an additional challenge for testing. While Playwright supports saving state, our application tokens have a short expiry. I needed […]

The post How To Test Your Web Applications Using Playwright and Support 2fa Tokens appeared first on I Like Kill Nerds.

View Details

WordPress has a great actions and filters system allowing you to create injection points for modifying parts of your code (especially for plugin authors). However, you probably arrived here because you’re trying to echo or print_r something from within a filter and not seeing the output. Because WordPress operates on a post/redirect approach, it means […]

The post How to debug the output from within WordPress filters appeared first on I Like Kill Nerds.

View Details

Despite doing this front-end thing for over a decade, I still encounter new problems thanks to the ever-evolving web specifications. One of the newer specifications is Web Components. Now, my situation was I wanted to see Bootstrap 5 Javascript components. Because of the closed-wall nature of Shadow DOM means, the global approach Bootstrap takes by […]

The post How to Use Bootstrap JavaScript Components Inside of Shadow DOM Web Components appeared first on I Like Kill Nerds.

View Details

After being deplatformed a little while ago, Donald Trump created his Twitter clone, Truth Social. As you can imagine, Truth Social launched to about as much fanfare as a fart in an elevator. Still, my curiosity got the better of me. For whatever reason, the site is currently restricted to Canada and the United States. […]

The post I Joined Truth Social Using a VPN and Editing Some HTML to Bypass the Phone Verification appeared first on I Like Kill Nerds.

View Details

WordPress is incredibly powerful, and every so often, a new feature gets added that goes under the radar that can dramatically change how you build sites. In WordPress 5.1, an addition of a new WP_Site_Query class was created. It allows you to query your network of sites but goes beyond just getting IDs and making […]

The post Creating Site Meta Search In WordPress Multisite using Site Queries appeared first on I Like Kill Nerds.

View Details

If you have used Flexbox before in CSS, you might have used the shorthand property flex: 1. And if you’re like me, you might have been using it but forgotten or not even known what this is shorthand for. I know to use this shorthand when I have Flexbox items that I want to take […]

The post What is flex: 1 shorthand for? appeared first on I Like Kill Nerds.

View Details

In WordPress, creating new sites from the admin interface can be tedious, especially if you want to add custom metadata to sites/ACF option fields. I had a scenario where I needed to create 1800 sites from a spreadsheet. Doing it one-by-one was not going to cut it, so I needed a code solution where I […]

The post Programmatically Create New Sites In WordPress Multisite appeared first on I Like Kill Nerds.

View Details

After an outage seven days ago, unpkgd.com, a widely used CDN for NPM packages, is again down. This time, the outage is more severe. At the time of writing, unpkgd.com has been down for hours. Even the official status page is down. With two outages in such a short period, I am starting to doubt […]

The post Unpkgd Is Down (Again) appeared first on I Like Kill Nerds.

View Details

If I had a dollar for every time my wife and I discovered a great show on Netflix only to discover it was cancelled after one or two seasons, we would be stupidly rich. Netflix recently revealed they’re losing subscribers. You probably already knew this because you’ve either cancelled your Netflix account, considered cancelling it […]

The post A simple solution to Netflix’s subscriber loss: stop cancelling TV shows appeared first on I Like Kill Nerds.

View Details

As much as I love front-end development, the ecosystem can sometimes inflict unnecessary pain. Given the front-end ecosystem relies on very few packages for a lot of modern development, when something changes and packages that rely on those don’t update: it’s a disaster. One such issue is Autoprefixer. You most likely arrived here searching Google […]

The post Fixing the color-adjust shorthand is currently deprecated warning in Autoprefixer appeared first on I Like Kill Nerds.

View Details

The beauty in WordPress is not only its ecosystem. It’s the ability to customise almost every facet of it using a filter or hook. I had a scenario recently where I wanted to put a web application theme in a less painful directory to access. I wanted a folder called themes in my root directory. […]

The post How to change the theme directory on a WordPress installation appeared first on I Like Kill Nerds.

View Details

Say what you will, but since its introduction in 2009, Node.js has been the undisputed king of server-side Javascript. Created by Ryan Dahl, Node.js had virtually no competition for years. Until recently, the only person to truly challenge Node.js was Ryan Dahl with his runtime Deno that improved upon some of the flaws that Ryan […]

The post Thoughts on Bun appeared first on I Like Kill Nerds.

View Details

I am by no means a database guy. I am barely even a server guy. But, recently, I was tasked with exporting a sizeable database from Amazon RDS for use with local development servers. After running the following mysqldump command: I am asked for the database password and then proceed to get an error complaining […]

The post Fixing mysqldump unknown table COLUMN_STATISTICS appeared first on I Like Kill Nerds.

View Details

There’s been a lot of talk about the metaverse over the last year. According to its advocates, it will be a revolutionary new platform that will let us interact with each other in ways we never could before. But is the metaverse all it’s cracked up to be? I’m not so sure. Admittedly, I don’t […]

The post The metaverse is a scam appeared first on I Like Kill Nerds.

View Details

In my LinkedIn feed of late, I see a lot of layoffs. Most of those layoffs are talent acquisition roles, some development and design, but largely talent acquisition. If you’re not familiar with the role of talent acquisition, it’s a fancy way to describe an internal recruiter, someone who seeks out candidates for a company. […]

The post Is your LinkedIn feed predicting a recession? appeared first on I Like Kill Nerds.

View Details

In recent years, there has been an explosion of front-end development frameworks and libraries. While this has made development more manageable and efficient, it has also led developers to become increasingly reliant on these tools. As a result, when something goes wrong with the library or framework, it can be difficult to determine the source […]

The post Do Developers Rely Too Much on Frameworks and Libraries? appeared first on I Like Kill Nerds.

View Details

Bitcoin was created as a way to bypass the traditional banking system. But can it survive a financial crisis? Cryptocurrencies are still relatively new and haven’t been tested in a significant financial crisis. If a global recession arose and banks started to fail, would people still trust Bitcoin? Would Bitcoin prove its independence from fiat? […]

The post Is Bitcoin prepared for the next financial crisis? appeared first on I Like Kill Nerds.

View Details

The buzzword of 2021 was unmistakenly Web 3.0. Facebook, Instagram, Medium, TikTok, Twitter: Web 3.0 dominated the discourse. Investment funds were flocking to invest in any company loosely affiliated with the hottest new trend on the web. Depending on who you spoke to or what you read, Web 3 would kill Facebook, Twitter and every […]

The post Web 3.0 may have died before it even started appeared first on I Like Kill Nerds.

View Details

After raising a $4,900,000 seed investment back in March 2021, Deno has just announced quite a substantial round of Series A investment of $21 million. The funding round led by Sequoia brings its total investment to $26 million to date. Deno will mainly use the cash to build their commercial offering Deno Deploy. Admittedly, I […]

The post Deno Raises $21M – but is anyone using it yet? appeared first on I Like Kill Nerds.

View Details

As much as I love WordPress, there are some fundamental flaws in how it works. For the average user, WordPress out-of-the-box will do everything you want and can be run on affordable hardware. For the project I have been working on, scaling considerations have reached a code level. I needed to speed up some WordPress […]

The post Speeding Up WordPress Using Local JSON appeared first on I Like Kill Nerds.

View Details

Over one month ago, the DJI Mini 3 Pro drone was launched. Those who got on the order bandwagon right away, fortunately, got their units without delay (like I did). However, one thing that DJI has botched about the launch is the availability of accessories. Most notably, the Fly More and Fly More Plus kits. […]

The post DJI’s botched Mini 3 Pro launch: what went wrong? appeared first on I Like Kill Nerds.

View Details

Bitcoin and other cryptocurrencies are no stranger to meteoric price drops. In the blink of an eye, a coin can increase hundreds of percent and plummet to near zero. Cryptocurrency is an emotional and monetary rollercoaster. Coinbase has just announced it is laying off 18% of its workforce immediately. Although, it is apparent Coinbase executives […]

The post The Great Crypto Collapse Is Upon Us appeared first on I Like Kill Nerds.

View Details

After seeing the Flipper Zero was finally shipping, I tried to get one. Unfortunately, in Australia, getting the Flipper Zero officially was impossible. There seems to be a lot of demand for this little gadget. Fortunately, there were a few on eBay. The original Kickstarter campaign is here if you want to read about it. […]

The post Thoughts on the Flipper Zero appeared first on I Like Kill Nerds.

View Details

This is another of those particular posts that might help one or two people out. If I can save you some time working with the News Industry Text Format in PHP, I’ll be glad that you didn’t experience my frustration. While working with the Associated Press API, I recently ran into a situation where ingested […]

The post Stopping PHP From Stripping out Hyperlinks From a NITF XML Response While Parsing the XML appeared first on I Like Kill Nerds.

View Details

I have always been fascinated by and loved drones but at a distance. Like many reading this, I resisted the temptation to spend $1k+ on a drone that I knew would crash into a tree or into a body of water where it is doomed to rest for eternity. With the DJI Mini 3 Pro, […]

The post DJI Mini 3 Pro Review appeared first on I Like Kill Nerds.

View Details

WordPress ships with a bunch of neat core Gutenberg blocks. However, there may be situations where you need to change the output of a Gutenberg block. In my use case, I needed to modify the core/image block to add an image credit field I created using Advanced Custom Fields. Like most things in WordPress, this […]

The post How To Override WordPress Gutenberg Core Blocks Output appeared first on I Like Kill Nerds.

View Details

When performing intensive or long-running operations on a WordPress website, the admin panel is terrible. Have you tried to delete 100 posts from the posts screen? It’ll time out and delete maybe 10-20 if you’re lucky. This is one example of many. Naturally, I opted for the WP CLI (WordPress CLI), which allows you to […]

The post Speeding Up Slow WordPress CLI Commands appeared first on I Like Kill Nerds.

View Details

Since the release of the Quad Cortex modeller, most people have been asking for a desktop editor for the Quad Cortex. While the interface of the Quad Cortex makes for seamless editing, a desktop editor can speed up the process. In Discord, Doug revealed some details about the highly-anticipated desktop editor. Here is what we […]

The post Neural DSP Reveal Details About the Long-Awaited Quad Cortex Desktop Editor appeared first on I Like Kill Nerds.

View Details

In the lead up to Battlefield 2042, I was genuinely excited, and it looked like a step in a new direction. Despite having more bugs than a cheap motel mattress, I even played the beta briefly and enjoyed it immensely. When launch day finally arrived, I jumped right in and invested quite a few hours […]

The post I am already bored of Battlefield 2042 appeared first on I Like Kill Nerds.

View Details

At present, the Cortex Cloud does not have a marketplace feature. There is no officially supported way to sell your preset creations for preset creators like myself. The process works for sharing private presets is you have to befriend someone, then they can share private captures and presets with you. I have a knack for […]

The post Announcing Cortexpresets.com — Buy custom Quad Cortex Presets appeared first on I Like Kill Nerds.

View Details

The term Web 3.0 is being thrown around a lot, not just those in the crypto sphere, but investors and everyday folk are starting to talk about it. You know, when your Uber driver or barber is talking about Web 3.0, it has permeated the fabric of society. People have differing opinions on Web 3.0, […]

The post Is Web 3.0 Just Another Crypto Hype Scam? appeared first on I Like Kill Nerds.

View Details

In WordPress, you add theme styles and scripts using the trusty wp_enqueue_script and wp_enqueue_style methods. However, by default, your enqueued scripts and styles will be added to your WordPress site as straight scripts. What happens (and the reason you’re probably here) is the browser will cache your scripts, which is what we want to happen. […]

The post Cache Busting WordPress Enqueued Styles and Scripts appeared first on I Like Kill Nerds.

View Details

WordPress is the most popular CMS on the planet, powering over 40% of the internet and continually growing. Despite what you have been told, WordPress isn’t dying, and it’s not the terrible mess some dramatic PHP hating developers make it out to be. I was tasked with building a WordPress capable of sustaining millions of […]

The post Building a High Availability WordPress Website Using AWS and Hyperdb appeared first on I Like Kill Nerds.

View Details

Have you ever been stuck on a problem that makes you feel so stupid, you get a serious case of impostor syndrome? Welcome to another instalment of Amazon Beanstalk bad UX. You go to the listeners section in the load balancer configuration section, you get to this popup: You choose HTTPS, you enter port 443 […]

The post How to Enable HTTPS for Amazon Elastic Beanstalk appeared first on I Like Kill Nerds.

View Details

Neural DSP are hosting one heck of a Black Friday (like years prior) where all of their plugins are 50% off. There is a lot of overlap between their Archetype plugins especially, so what should you buy if you can’t afford them all? TL;DR buy the Gojira, Henson and Fortin Cali plugins (if you can […]

The post Which Neural DSP Archetype Plugins Should You Buy? appeared first on I Like Kill Nerds.

View Details

So, you bought the Quad Cortex. A floor modeller marketed as the most powerful modeller on the planet, but you’ve noticed the delay when switching between presets.

You might not know this, but every competing modeller from the Line 6 Helix through to the Axe-FX suffers from delay when switching presets. The current blocks need to be unloaded, the new ones loaded.

The solution is to use scenes. Think of presets and scenes like this.

  • Preset = song
  • Scene = song part

Although, you can also leverage scenes to build multi-faceted presets where scenes are used as faux presets. On Cortex Cloud, there are some clever all-in-one presets that take this approach which work well.

In most situations, it’s rare you would ever have a need to change presets mid song. The delay, while not huge, would be noticeable. Changes mid performance would definitely be better suited to scenes.

The post Seamless Preset Switching On the Quad Cortex: It’s Complicated appeared first on I Like Kill Nerds.

View Details

The Quad Cortex is great for live use as well as studio settings. If you’re like me, you have the Quad Cortex sitting on your desk, and you interact with it using the screen.

The device isn’t angled, so it can be tricky to adjust things on the screen or get to the inputs and outputs on the back.

Fortunately, the Quad Cortex is similar in size to an Apple Macbook. So, naturally, the solution for a Quad Cortex stand is a laptop stand, specifically, a stand that can be angled and has a flat bottom.

There is a lot to choose from, but, this is the one I opted for and it’s just the right size. I got this exact laptop stand from Amazon here.

Pardon the smudges As you can see the stand is the right size for the Quad Cortex. It doesn’t stick out on the back and it perfectly holds it into place.

The stand without anything on it The only regret that I have buying this stand is getting the black colour. It doesn’t look terrible, but I should have bought this silver one instead. I think it would have matched the colour of the Quad Cortex a lot better.

The post Where to Buy a Stand for Your Neural DSP Quad Cortex appeared first on I Like Kill Nerds.