<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Usba Usman</title>
    <description>The latest articles on DEV Community by Usba Usman (@usba_usman).</description>
    <link>https://dev.to/usba_usman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4199488%2Fb1383546-8312-4ef1-8626-cb93cf33de5b.jpg</url>
      <title>DEV Community: Usba Usman</title>
      <link>https://dev.to/usba_usman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/usba_usman"/>
    <language>en</language>
    <item>
      <title>I Built a Python Bot That Types at 200 WPM. Then I Made It Type Like a Human.</title>
      <dc:creator>Usba Usman</dc:creator>
      <pubDate>Mon, 02 Nov 2026 01:33:01 +0000</pubDate>
      <link>https://dev.to/usba_usman/i-built-a-python-bot-that-types-at-200-wpm-then-i-made-it-type-like-a-human-3elk</link>
      <guid>https://dev.to/usba_usman/i-built-a-python-bot-that-types-at-200-wpm-then-i-made-it-type-like-a-human-3elk</guid>
      <description>&lt;p&gt;Automating a typing test is easy. Making a machine type like someone who actually makes mistakes? That's where things get interesting.&lt;/p&gt;

&lt;p&gt;A few days ago, I had a ridiculous thought.&lt;/p&gt;

&lt;p&gt;What if I could build a Python program that types faster than almost everyone I know?&lt;/p&gt;

&lt;p&gt;Not an AI that writes essays.&lt;/p&gt;

&lt;p&gt;Not another ChatGPT wrapper.&lt;/p&gt;

&lt;p&gt;Just a simple bot that opens a typing test, reads the text, and starts typing.&lt;/p&gt;

&lt;p&gt;No fingers. No fancy mechanical keyboard. No late-night practice sessions.&lt;/p&gt;

&lt;p&gt;Just Python.&lt;/p&gt;

&lt;p&gt;The first version was almost embarrassingly easy. Give the program some text, tell it where to type, and let the computer do the rest.&lt;/p&gt;

&lt;p&gt;It could theoretically produce hundreds of words per minute.&lt;/p&gt;

&lt;p&gt;But then I started thinking.&lt;/p&gt;

&lt;p&gt;A program typing at an impossibly consistent speed isn't particularly interesting.&lt;/p&gt;

&lt;p&gt;What if it occasionally hesitated?&lt;/p&gt;

&lt;p&gt;What if it made spelling mistakes?&lt;/p&gt;

&lt;p&gt;What if it typed familiar words quickly but slowed down on difficult ones?&lt;/p&gt;

&lt;p&gt;Could we make a typing bot that behaves more like an actual human?&lt;/p&gt;

&lt;p&gt;That's the experiment we're going to build.&lt;/p&gt;

&lt;p&gt;And along the way, we'll learn a few useful things about Python, browser automation, timing, and why typing speed is more complicated than it looks.&lt;/p&gt;

&lt;p&gt;First, Why Automate a Typing Test?&lt;/p&gt;

&lt;p&gt;Let's address the obvious question.&lt;/p&gt;

&lt;p&gt;Why would anyone automate something designed to measure human typing ability?&lt;/p&gt;

&lt;p&gt;Fair question.&lt;/p&gt;

&lt;p&gt;If your goal is to improve your real typing speed, using a bot to generate an impressive score accomplishes absolutely nothing.&lt;/p&gt;

&lt;p&gt;Your keyboard skills remain exactly the same.&lt;/p&gt;

&lt;p&gt;But as a programming experiment, typing automation is surprisingly interesting.&lt;/p&gt;

&lt;p&gt;It combines several concepts that developers regularly encounter in real projects:&lt;/p&gt;

&lt;p&gt;Browser interaction and automation&lt;/p&gt;

&lt;p&gt;Keyboard event simulation&lt;/p&gt;

&lt;p&gt;Timing and delays&lt;/p&gt;

&lt;p&gt;Randomized behavior&lt;/p&gt;

&lt;p&gt;Performance measurement&lt;/p&gt;

&lt;p&gt;Basic human-behavior modeling&lt;/p&gt;

&lt;p&gt;These concepts apply to automated testing, accessibility experiments, user-interface research, and software quality assurance.&lt;/p&gt;

&lt;p&gt;We'll build our experiment on a local typing-test page rather than manipulate scores on a public leaderboard.&lt;/p&gt;

&lt;p&gt;That keeps the project focused on learning how browser automation works.&lt;/p&gt;

&lt;p&gt;And it means we can experiment as much as we want without affecting anyone else's results.&lt;/p&gt;

&lt;p&gt;Step 1: Give Python Control of a Browser&lt;/p&gt;

&lt;p&gt;We'll use Playwright.&lt;/p&gt;

&lt;p&gt;If you've never used it, Playwright is a browser automation framework that allows code to interact with websites.&lt;/p&gt;

&lt;p&gt;It can open pages, click buttons, fill forms, simulate keyboard activity, and inspect content.&lt;/p&gt;

&lt;p&gt;It's commonly used for testing web applications.&lt;/p&gt;

&lt;p&gt;Install it using:&lt;/p&gt;

&lt;p&gt;pip install playwright&lt;br&gt;
python -m playwright install chromium&lt;/p&gt;

&lt;p&gt;Now create a Python file called typing_bot.py.&lt;/p&gt;

&lt;p&gt;Let's start with something simple:&lt;/p&gt;

&lt;p&gt;from playwright.sync_api import sync_playwright&lt;/p&gt;

&lt;p&gt;with sync_playwright() as p:&lt;br&gt;
    browser = p.chromium.launch(headless=False)&lt;br&gt;
    page = browser.new_page()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;page.set_content("""
    &amp;lt;h2&amp;gt;Python Typing Experiment&amp;lt;/h2&amp;gt;
    &amp;lt;textarea id="typing-box"
              rows="6"
              cols="60"&amp;gt;&amp;lt;/textarea&amp;gt;
""")

page.locator("#typing-box").click()
page.keyboard.type("Hello from Python!")

input("Press Enter to close...")
browser.close()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the file.&lt;/p&gt;

&lt;p&gt;A browser window opens with a text area.&lt;/p&gt;

&lt;p&gt;Without touching your keyboard, the program types:&lt;/p&gt;

&lt;p&gt;Hello from Python!&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;We've just automated keyboard input.&lt;/p&gt;

&lt;p&gt;Admittedly, the result isn't particularly impressive yet.&lt;/p&gt;

&lt;p&gt;But we now have the foundation for something more interesting.&lt;/p&gt;

&lt;p&gt;Step 2: Make the Bot Type at a Specific Speed&lt;/p&gt;

&lt;p&gt;A computer doesn't naturally type like a person.&lt;/p&gt;

&lt;p&gt;If you give it a string and ask it to enter the characters immediately, it can complete the task extremely quickly.&lt;/p&gt;

&lt;p&gt;That makes its typing performance almost meaningless.&lt;/p&gt;

&lt;p&gt;Instead, let's control how long it waits between characters.&lt;/p&gt;

&lt;p&gt;Typing speed is commonly measured in words per minute, or WPM.&lt;/p&gt;

&lt;p&gt;For standardized measurements, a word is often treated as five characters, including spaces and punctuation.&lt;/p&gt;

&lt;p&gt;That gives us a simple formula:&lt;/p&gt;

&lt;p&gt;Delay per character = 60 / (WPM × 5)&lt;/p&gt;

&lt;p&gt;At 60 WPM, the average interval is approximately 0.2 seconds per character.&lt;/p&gt;

&lt;p&gt;At 120 WPM, it's approximately 0.1 seconds.&lt;/p&gt;

&lt;p&gt;At 200 WPM, it's approximately 0.06 seconds.&lt;/p&gt;

&lt;p&gt;We can translate this into Python.&lt;/p&gt;

&lt;p&gt;import time&lt;/p&gt;

&lt;p&gt;def type_at_speed(page, text, wpm):&lt;br&gt;
    delay = 60 / (wpm * 5)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for character in text:
    page.keyboard.type(character)
    time.sleep(delay)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now our bot can target different speeds.&lt;/p&gt;

&lt;p&gt;sample = "Python makes browser automation fun."&lt;/p&gt;

&lt;p&gt;type_at_speed(page, sample, 200)&lt;/p&gt;

&lt;p&gt;The bot attempts to type at 200 WPM.&lt;/p&gt;

&lt;p&gt;Well, approximately.&lt;/p&gt;

&lt;p&gt;There's an important detail here: browser automation and Python execution also take time.&lt;/p&gt;

&lt;p&gt;Every keyboard call has some overhead, so the final measured speed may differ from the requested speed.&lt;/p&gt;

&lt;p&gt;That's a useful reminder that simulated performance and measured performance aren't always identical.&lt;/p&gt;

&lt;p&gt;If we wanted more accurate timing, we'd need to measure elapsed time and account for the overhead.&lt;/p&gt;

&lt;p&gt;For this experiment, though, our simple delay model is enough to demonstrate the concept.&lt;/p&gt;

&lt;p&gt;Step 3: Make It Less Perfect&lt;/p&gt;

&lt;p&gt;Here's where the project gets interesting.&lt;/p&gt;

&lt;p&gt;Real people don't type with mathematically perfect timing.&lt;/p&gt;

&lt;p&gt;Sometimes we pause.&lt;/p&gt;

&lt;p&gt;Sometimes our fingers move quickly through familiar words.&lt;/p&gt;

&lt;p&gt;Sometimes we hesitate before punctuation or unfamiliar combinations.&lt;/p&gt;

&lt;p&gt;Our first bot doesn't do any of that.&lt;/p&gt;

&lt;p&gt;It enters every character using approximately the same delay.&lt;/p&gt;

&lt;p&gt;That makes its behavior extremely predictable.&lt;/p&gt;

&lt;p&gt;Let's introduce randomness.&lt;/p&gt;

&lt;p&gt;import random&lt;br&gt;
import time&lt;/p&gt;

&lt;p&gt;def type_naturally(page, text, wpm=80):&lt;br&gt;
    base_delay = 60 / (wpm * 5)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for character in text:
    variation = random.uniform(0.75, 1.25)
    delay = base_delay * variation

    if character in ".,!?":
        delay += random.uniform(0.1, 0.3)

    time.sleep(delay)
    page.keyboard.type(character)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now our bot behaves a little differently on every run.&lt;/p&gt;

&lt;p&gt;Some characters arrive faster.&lt;/p&gt;

&lt;p&gt;Others arrive slower.&lt;/p&gt;

&lt;p&gt;Punctuation introduces an occasional pause.&lt;/p&gt;

&lt;p&gt;It's still not a realistic model of human motor behavior, but it no longer produces perfectly uniform timing.&lt;/p&gt;

&lt;p&gt;And that distinction matters.&lt;/p&gt;

&lt;p&gt;A machine can imitate certain observable characteristics of human activity without actually reproducing the mental and physical processes behind it.&lt;/p&gt;

&lt;p&gt;We're modeling timing patterns, not building a genuine digital typist.&lt;/p&gt;

&lt;p&gt;Step 4: Add Something Every Human Understands — Typos&lt;/p&gt;

&lt;p&gt;Nobody types perfectly all the time.&lt;/p&gt;

&lt;p&gt;Even experienced typists make mistakes.&lt;/p&gt;

&lt;p&gt;Sometimes they hit a neighboring key.&lt;/p&gt;

&lt;p&gt;Sometimes they enter the same character twice.&lt;/p&gt;

&lt;p&gt;And sometimes their fingers seem to invent an entirely new spelling.&lt;/p&gt;

&lt;p&gt;Let's make our bot occasionally do the same thing.&lt;/p&gt;

&lt;p&gt;def type_with_mistakes(page, text, wpm=80):&lt;br&gt;
    base_delay = 60 / (wpm * 5)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for character in text:
    time.sleep(base_delay)

    if (
        character.isalpha()
        and random.random() &amp;lt; 0.03
    ):
        wrong_key = random.choice("abcdefghijklmnopqrstuvwxyz")

        page.keyboard.type(wrong_key)
        time.sleep(0.15)

        page.keyboard.press("Backspace")
        time.sleep(0.1)

    page.keyboard.type(character)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now there's roughly a 3% probability of an intentional mistake before each alphabetic character.&lt;/p&gt;

&lt;p&gt;When that happens, the bot enters an incorrect letter, briefly pauses, deletes it, and types the intended character.&lt;/p&gt;

&lt;p&gt;The result is much more entertaining to watch.&lt;/p&gt;

&lt;p&gt;Instead of flawlessly producing text, our program occasionally stumbles and corrects itself.&lt;/p&gt;

&lt;p&gt;But here's something worth noticing.&lt;/p&gt;

&lt;p&gt;Those mistakes consume time.&lt;/p&gt;

&lt;p&gt;So even if we configure the bot's basic character delay for 80 WPM, its actual completed-text speed will be lower once corrections are included.&lt;/p&gt;

&lt;p&gt;That's exactly why typing speed and typing accuracy are closely related.&lt;/p&gt;

&lt;p&gt;Step 5: Measure the Bot Instead of Trusting It&lt;/p&gt;

&lt;p&gt;It's easy to tell a program to type at 100 WPM.&lt;/p&gt;

&lt;p&gt;It's another thing to verify that it actually achieves that speed.&lt;/p&gt;

&lt;p&gt;Let's measure the elapsed time.&lt;/p&gt;

&lt;p&gt;start = time.perf_counter()&lt;/p&gt;

&lt;p&gt;type_with_mistakes(page, sample, wpm=80)&lt;/p&gt;

&lt;p&gt;elapsed = time.perf_counter() - start&lt;/p&gt;

&lt;p&gt;actual_wpm = (len(sample) / 5) / (elapsed / 60)&lt;/p&gt;

&lt;p&gt;print(f"Time taken: {elapsed:.2f} seconds")&lt;br&gt;
print(f"Measured speed: {actual_wpm:.1f} WPM")&lt;/p&gt;

&lt;p&gt;Now we have a measurable result.&lt;/p&gt;

&lt;p&gt;The calculated WPM uses the final text length and total elapsed time, including corrections.&lt;/p&gt;

&lt;p&gt;This isn't a complete typing-test scoring system. It doesn't separately report gross speed, uncorrected errors, or accuracy.&lt;/p&gt;

&lt;p&gt;But it's a reasonable starting point.&lt;/p&gt;

&lt;p&gt;We can experiment with different delays, typo probabilities, and punctuation pauses to see how they affect the final speed.&lt;/p&gt;

&lt;p&gt;And unlike simply assigning the bot a target WPM, we're measuring what happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Compare the Machine With Yourself
&lt;/h2&gt;

&lt;p&gt;Now comes the interesting part: finding out how your actual typing ability compares with a Python script.&lt;/p&gt;

&lt;p&gt;Before running another automated experiment, try taking an online &lt;a href="https://www.checkmywpm.com/" rel="noopener noreferrer"&gt;typing speed test&lt;/a&gt; to measure your words per minute (WPM) and typing accuracy.&lt;/p&gt;

&lt;p&gt;Type naturally. Don't rush to beat a particular score, and don't worry if you make a few mistakes.&lt;/p&gt;

&lt;p&gt;Once you've finished, compare your results with the bot's performance.&lt;/p&gt;

&lt;p&gt;You'll probably notice something interesting. Your speed changes depending on the words, punctuation, and how comfortable you feel with the keyboard. You might fly through familiar sentences but slow down when you encounter unusual letter combinations.&lt;/p&gt;

&lt;p&gt;Our Python bot doesn't experience any of that naturally. It follows programmed delays and simulated mistakes.&lt;/p&gt;

&lt;p&gt;And that's what makes the comparison interesting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A typing test measures your speed, but understanding why that speed changes tells you much more about your actual typing skills.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a person trying to improve their keyboard ability, consistency, accuracy, and honest measurement matter much more than producing an enormous number.&lt;/p&gt;

&lt;p&gt;What This Experiment Actually Teaches Us&lt;/p&gt;

&lt;p&gt;We started with a simple idea.&lt;/p&gt;

&lt;p&gt;Make Python type faster than a human.&lt;/p&gt;

&lt;p&gt;Then we made it slower.&lt;/p&gt;

&lt;p&gt;Then we introduced random pauses.&lt;/p&gt;

&lt;p&gt;Then we deliberately made it commit mistakes.&lt;/p&gt;

&lt;p&gt;And suddenly, the project became more interesting than a speed contest.&lt;/p&gt;

&lt;p&gt;We began exploring the difference between automation and behavior.&lt;/p&gt;

&lt;p&gt;That difference appears throughout software engineering.&lt;/p&gt;

&lt;p&gt;A test script can click a button.&lt;/p&gt;

&lt;p&gt;But that doesn't mean it understands why a user clicks it.&lt;/p&gt;

&lt;p&gt;An automated agent can fill out a form.&lt;/p&gt;

&lt;p&gt;But that doesn't mean it knows whether the form is confusing.&lt;/p&gt;

&lt;p&gt;A program can generate realistic-looking activity.&lt;/p&gt;

&lt;p&gt;But that doesn't automatically make the underlying experience realistic.&lt;/p&gt;

&lt;p&gt;This is why automated testing is most useful when developers understand what they're trying to validate.&lt;/p&gt;

&lt;p&gt;A typing bot can test whether a text field receives input correctly.&lt;/p&gt;

&lt;p&gt;It can help investigate timing behavior.&lt;/p&gt;

&lt;p&gt;It can reproduce certain input sequences.&lt;/p&gt;

&lt;p&gt;But it cannot replace genuine human evaluation of how comfortable or intuitive a typing interface feels.&lt;/p&gt;

&lt;p&gt;Those are different kinds of testing.&lt;/p&gt;

&lt;p&gt;And good developers know when to use each one.&lt;/p&gt;

&lt;p&gt;Could We Take This Project Further?&lt;/p&gt;

&lt;p&gt;Absolutely.&lt;/p&gt;

&lt;p&gt;Our current bot is intentionally simple.&lt;/p&gt;

&lt;p&gt;A more advanced version could include a small local dashboard displaying target WPM, measured WPM, typing duration, and correction count.&lt;/p&gt;

&lt;p&gt;We could create multiple simulated typing profiles.&lt;/p&gt;

&lt;p&gt;One could imitate a careful beginner, using slower character intervals and frequent corrections.&lt;/p&gt;

&lt;p&gt;Another could imitate an experienced typist with steadier pacing.&lt;/p&gt;

&lt;p&gt;A third could emphasize short bursts of speed followed by occasional pauses.&lt;/p&gt;

&lt;p&gt;We could also experiment with realistic error models.&lt;/p&gt;

&lt;p&gt;Instead of choosing a completely random incorrect letter, the bot could use neighboring keys from the QWERTY keyboard layout.&lt;/p&gt;

&lt;p&gt;For example, accidentally pressing r instead of t is more physically plausible than accidentally pressing z instead of t.&lt;/p&gt;

&lt;p&gt;That would make our typo simulation more meaningful.&lt;/p&gt;

&lt;p&gt;We could measure how much time each correction adds, how typing speed changes across longer passages, and which timing patterns produce the greatest variation.&lt;/p&gt;

&lt;p&gt;For legitimate browser testing, these experiments could help developers evaluate text-entry components under different input conditions.&lt;/p&gt;

&lt;p&gt;Just remember that randomizing delays isn't the same as accurately simulating a human.&lt;/p&gt;

&lt;p&gt;It's a simplified model.&lt;/p&gt;

&lt;p&gt;And simplified models are useful precisely when we understand their limitations.&lt;/p&gt;

&lt;p&gt;The Funny Thing About Making Computers Type Like Humans&lt;/p&gt;

&lt;p&gt;There's something almost backwards about this entire experiment.&lt;/p&gt;

&lt;p&gt;Computers were created to help us perform tasks more efficiently.&lt;/p&gt;

&lt;p&gt;Now we're deliberately slowing one down so it behaves more like us.&lt;/p&gt;

&lt;p&gt;We're adding hesitation.&lt;/p&gt;

&lt;p&gt;Introducing mistakes.&lt;/p&gt;

&lt;p&gt;Making it pause at punctuation.&lt;/p&gt;

&lt;p&gt;And spending time designing errors a computer would never naturally need to make.&lt;/p&gt;

&lt;p&gt;But those imperfections are what make the experiment worth exploring.&lt;/p&gt;

&lt;p&gt;A bot that produces 500 WPM with no mistakes is predictable.&lt;/p&gt;

&lt;p&gt;A bot with variable timing and occasional corrections gives us something to investigate.&lt;/p&gt;

&lt;p&gt;Not because it has become human.&lt;/p&gt;

&lt;p&gt;But because studying the differences helps us understand both software automation and human behavior a little better.&lt;/p&gt;

&lt;p&gt;And that's one of the things I enjoy most about programming.&lt;/p&gt;

&lt;p&gt;You can start with a silly question and end up learning something genuinely useful.&lt;/p&gt;

&lt;p&gt;Final Thoughts: The Bot Won, but It Didn't Really Win&lt;/p&gt;

&lt;p&gt;Our Python bot can enter text at speeds that would be difficult for most people to sustain.&lt;/p&gt;

&lt;p&gt;It doesn't need typing lessons.&lt;/p&gt;

&lt;p&gt;It doesn't care which keyboard is attached.&lt;/p&gt;

&lt;p&gt;It doesn't need to remember where the keys are.&lt;/p&gt;

&lt;p&gt;And it never gets tired.&lt;/p&gt;

&lt;p&gt;But none of that makes it a better typist in the human sense.&lt;/p&gt;

&lt;p&gt;It's an automation script doing what it was programmed to do.&lt;/p&gt;

&lt;p&gt;The interesting achievement isn't the simulated WPM.&lt;/p&gt;

&lt;p&gt;It's understanding how to control browser input, model timing, introduce uncertainty, and measure results.&lt;/p&gt;

&lt;p&gt;That's what turns a small coding trick into an actual programming exercise.&lt;/p&gt;

&lt;p&gt;And if the experiment inspires you to test your own typing speed afterward, that's a bonus.&lt;/p&gt;

&lt;p&gt;Because there's one thing our bot won't gain from all this practice.&lt;/p&gt;

&lt;p&gt;An actual skill.&lt;/p&gt;

&lt;p&gt;The computer can imitate typing. You're the one who can learn to do it better.&lt;/p&gt;

&lt;p&gt;Let that sink in.&lt;/p&gt;

&lt;p&gt;Further Reading and Useful Resources&lt;/p&gt;

&lt;p&gt;Playwright for Python — Official documentation covering browser automation, keyboard input, and testing.&lt;/p&gt;

&lt;p&gt;Python's time Module — Timing functions, including sleep() and perf_counter().&lt;/p&gt;

&lt;p&gt;Python's random Module — Tools for adding controlled randomness to programs.&lt;/p&gt;

&lt;p&gt;Check My WPM — Practice and measure real typing speed and accuracy.&lt;/p&gt;

&lt;p&gt;Python Documentation — A reference for understanding and extending the example programs.&lt;/p&gt;

&lt;p&gt;The best programming experiments don't always begin with serious problems. Sometimes they start with asking whether Python can win a typing test.&lt;/p&gt;

</description>
      <category>python</category>
      <category>automation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Kotlin Feature That Changes How You Think About Writing Safer Code</title>
      <dc:creator>Usba Usman</dc:creator>
      <pubDate>Thu, 22 Oct 2026 03:59:48 +0000</pubDate>
      <link>https://dev.to/usba_usman/the-kotlin-feature-that-changes-how-you-think-about-writing-safer-code-21ea</link>
      <guid>https://dev.to/usba_usman/the-kotlin-feature-that-changes-how-you-think-about-writing-safer-code-21ea</guid>
      <description>&lt;p&gt;Null safety looks like a small language feature, but understanding it can completely change how you handle missing data, avoid bugs, and write more reliable applications.&lt;/p&gt;

&lt;p&gt;There's a particular kind of programming bug that's incredibly frustrating.&lt;/p&gt;

&lt;p&gt;Your application works perfectly during testing. The buttons respond, the screens load, and everything seems fine.&lt;/p&gt;

&lt;p&gt;Then someone uses it with slightly different data.&lt;/p&gt;

&lt;p&gt;Maybe a user hasn't uploaded a profile picture. Maybe an API returns an empty field. Or perhaps a database doesn't contain the information your code expects.&lt;/p&gt;

&lt;p&gt;Suddenly, something crashes.&lt;/p&gt;

&lt;p&gt;The problem isn't necessarily complicated. Sometimes, your program simply assumed a value would always exist.&lt;/p&gt;

&lt;p&gt;This is one of the reasons I find Kotlin interesting.&lt;/p&gt;

&lt;p&gt;Instead of leaving developers to remember every possible null check, Kotlin makes missing values part of the language's type system.&lt;/p&gt;

&lt;p&gt;It sounds like a small improvement.&lt;/p&gt;

&lt;p&gt;But once you understand why it works, you start thinking differently about how software should behave.&lt;/p&gt;

&lt;p&gt;The Problem Isn't Null. It's Our Assumptions.&lt;/p&gt;

&lt;p&gt;Imagine you're building an application that displays a user's profile.&lt;/p&gt;

&lt;p&gt;Every user must have a name, but adding a nickname is optional.&lt;/p&gt;

&lt;p&gt;In many programming languages, it's easy to write code assuming both values will always exist.&lt;/p&gt;

&lt;p&gt;Something like:&lt;/p&gt;

&lt;p&gt;val nickname: String? = null&lt;br&gt;
println(nickname.length)&lt;/p&gt;

&lt;p&gt;If you're new to Kotlin, you might expect this to run and fail when it reaches the second line.&lt;/p&gt;

&lt;p&gt;It doesn't.&lt;/p&gt;

&lt;p&gt;Kotlin refuses to compile it.&lt;/p&gt;

&lt;p&gt;The question mark in String? means the variable is allowed to contain either a string or null.&lt;/p&gt;

&lt;p&gt;Because Kotlin knows the value might be missing, it won't let you access .length directly.&lt;/p&gt;

&lt;p&gt;Compare that with:&lt;/p&gt;

&lt;p&gt;val name: String = "Alex"&lt;br&gt;
println(name.length)&lt;/p&gt;

&lt;p&gt;This works because name is declared as a non-nullable string.&lt;/p&gt;

&lt;p&gt;Kotlin's compiler understands the difference.&lt;/p&gt;

&lt;p&gt;That's the first important lesson: your code should express what data is allowed to be missing, rather than hoping every value will be available.&lt;/p&gt;

&lt;p&gt;A Question Mark Can Replace a Lot of Defensive Code&lt;/p&gt;

&lt;p&gt;Let's return to our optional nickname.&lt;/p&gt;

&lt;p&gt;Suppose you want to display its length when it exists.&lt;/p&gt;

&lt;p&gt;You could write:&lt;/p&gt;

&lt;p&gt;val nickname: String? = "Alex"&lt;/p&gt;

&lt;p&gt;if (nickname != null) {&lt;br&gt;
    println(nickname.length)&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;There's nothing wrong with that approach.&lt;/p&gt;

&lt;p&gt;In fact, explicit conditions are often easier to understand when you're learning.&lt;/p&gt;

&lt;p&gt;But Kotlin provides a shorter alternative:&lt;/p&gt;

&lt;p&gt;println(nickname?.length)&lt;/p&gt;

&lt;p&gt;This is called a safe call.&lt;/p&gt;

&lt;p&gt;If nickname contains a string, Kotlin returns its length.&lt;/p&gt;

&lt;p&gt;If it's null, the expression returns null instead of attempting to access a property on a missing object.&lt;/p&gt;

&lt;p&gt;Now imagine you're working with information returned by an API.&lt;/p&gt;

&lt;p&gt;A user might have an address, and that address might have a city.&lt;/p&gt;

&lt;p&gt;You could access it like this:&lt;/p&gt;

&lt;p&gt;val city = user.address?.city&lt;/p&gt;

&lt;p&gt;If address is nullable and happens to be missing, the expression safely returns null.&lt;/p&gt;

&lt;p&gt;Of course, this doesn't solve every problem with incomplete data.&lt;/p&gt;

&lt;p&gt;But it removes a category of assumptions that developers would otherwise have to manage manually.&lt;/p&gt;

&lt;p&gt;Sometimes You Need a Fallback, Not Another Null&lt;/p&gt;

&lt;p&gt;Here's where Kotlin becomes especially practical.&lt;/p&gt;

&lt;p&gt;Returning null is safe, but it isn't always useful.&lt;/p&gt;

&lt;p&gt;Suppose you're displaying a greeting.&lt;/p&gt;

&lt;p&gt;If the user has a nickname, you want to use it. Otherwise, their regular name is perfectly fine.&lt;/p&gt;

&lt;p&gt;Kotlin has an operator for exactly this situation.&lt;/p&gt;

&lt;p&gt;val nickname: String? = null&lt;br&gt;
val name = "Alex"&lt;/p&gt;

&lt;p&gt;val displayName = nickname ?: name&lt;/p&gt;

&lt;p&gt;println("Welcome, $displayName!")&lt;/p&gt;

&lt;p&gt;Output:&lt;/p&gt;

&lt;p&gt;Welcome, Alex!&lt;/p&gt;

&lt;p&gt;The ?: symbol is called the Elvis operator.&lt;/p&gt;

&lt;p&gt;It means: use the value on the left if it isn't null; otherwise, use the value on the right.&lt;/p&gt;

&lt;p&gt;This is useful for things like optional descriptions, configuration settings, and default display values.&lt;/p&gt;

&lt;p&gt;But there's something worth understanding before using it everywhere.&lt;/p&gt;

&lt;p&gt;Not every missing value should be replaced with a default.&lt;/p&gt;

&lt;p&gt;If an API doesn't return the user's account balance, replacing that value with zero could display incorrect financial information.&lt;/p&gt;

&lt;p&gt;If a delivery address is missing, inventing a default address would be even worse.&lt;/p&gt;

&lt;p&gt;Sometimes the correct response is to show an error or ask for the missing information.&lt;/p&gt;

&lt;p&gt;Good programming isn't just about preventing crashes.&lt;/p&gt;

&lt;p&gt;It's about deciding what the application should do when reality doesn't match your expectations.&lt;/p&gt;

&lt;p&gt;Let the User Make Mistakes Without Breaking Everything&lt;/p&gt;

&lt;p&gt;Consider another everyday scenario.&lt;/p&gt;

&lt;p&gt;You're building a simple expense calculator.&lt;/p&gt;

&lt;p&gt;The user enters a quantity, and your program needs to convert it into a number.&lt;/p&gt;

&lt;p&gt;A beginner might write:&lt;/p&gt;

&lt;p&gt;val quantity = input.toInt()&lt;/p&gt;

&lt;p&gt;This works when the input is something like "5".&lt;/p&gt;

&lt;p&gt;But what happens when someone enters "five"?&lt;/p&gt;

&lt;p&gt;Kotlin throws a NumberFormatException.&lt;/p&gt;

&lt;p&gt;Instead, you can use:&lt;/p&gt;

&lt;p&gt;val quantity = input.toIntOrNull()&lt;/p&gt;

&lt;p&gt;Now invalid input produces null.&lt;/p&gt;

&lt;p&gt;You can handle that result deliberately:&lt;/p&gt;

&lt;p&gt;fun calculateTotal(input: String): String {&lt;br&gt;
    val quantity = input.toIntOrNull()&lt;br&gt;
        ?: return "Please enter a valid number"&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (quantity &amp;lt;= 0) {
    return "Quantity must be greater than zero"
}

val price = 100
return "Total: ${quantity * price}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;Notice what's happening here.&lt;/p&gt;

&lt;p&gt;The program isn't silently ignoring bad input.&lt;/p&gt;

&lt;p&gt;It's explaining the problem to the user.&lt;/p&gt;

&lt;p&gt;For a small example, that might not seem significant. In an actual application, however, handling unexpected values properly can make the difference between a confusing failure and a useful experience.&lt;/p&gt;

&lt;p&gt;The Dangerous Shortcut Beginners Should Understand&lt;/p&gt;

&lt;p&gt;While learning Kotlin, you'll probably encounter code like this:&lt;/p&gt;

&lt;p&gt;val username: String? = null&lt;br&gt;
println(username!!.length)&lt;/p&gt;

&lt;p&gt;The double exclamation mark, !!, tells Kotlin to treat the value as non-null.&lt;/p&gt;

&lt;p&gt;If the value actually is null, the code throws a NullPointerException.&lt;/p&gt;

&lt;p&gt;In other words, you're overriding the compiler's protection.&lt;/p&gt;

&lt;p&gt;There are situations where developers use !! because they have a strong guarantee that a value exists.&lt;/p&gt;

&lt;p&gt;But it's worth being cautious with it.&lt;/p&gt;

&lt;p&gt;If you find yourself adding !! simply to make compiler errors disappear, there's probably a better way to handle the data.&lt;/p&gt;

&lt;p&gt;Try an explicit null check, a safe call, or a meaningful fallback instead.&lt;/p&gt;

&lt;p&gt;The point of learning Kotlin isn't to find shortcuts around its safety features.&lt;/p&gt;

&lt;p&gt;It's to understand why those protections exist.&lt;/p&gt;

&lt;p&gt;Safer Code Starts With Better Data Models&lt;/p&gt;

&lt;p&gt;One of the most useful habits you can develop is deciding which fields are genuinely optional before writing application logic.&lt;/p&gt;

&lt;p&gt;Consider this simple Kotlin data class:&lt;/p&gt;

&lt;p&gt;data class UserProfile(&lt;br&gt;
    val id: Int,&lt;br&gt;
    val name: String,&lt;br&gt;
    val nickname: String?,&lt;br&gt;
    val bio: String?&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;This model communicates several things immediately.&lt;/p&gt;

&lt;p&gt;Every profile must have an ID and name.&lt;/p&gt;

&lt;p&gt;A nickname and biography are optional.&lt;/p&gt;

&lt;p&gt;Anyone reading the code can understand those rules without searching through dozens of functions.&lt;/p&gt;

&lt;p&gt;And Kotlin will help enforce them.&lt;/p&gt;

&lt;p&gt;This matters as projects grow.&lt;/p&gt;

&lt;p&gt;A small application might contain only a few classes. A larger application can involve data coming from APIs, databases, user input, and external libraries.&lt;/p&gt;

&lt;p&gt;When your types accurately describe that data, other developers have fewer assumptions to make.&lt;/p&gt;

&lt;p&gt;There's one subtle point here: Kotlin's null safety isn't a replacement for validation.&lt;/p&gt;

&lt;p&gt;An empty string isn't the same as null.&lt;/p&gt;

&lt;p&gt;A negative quantity isn't necessarily valid just because it has the correct type.&lt;/p&gt;

&lt;p&gt;And when Kotlin interacts with Java code, some null-related risks still require special attention.&lt;/p&gt;

&lt;p&gt;The language helps you express your expectations, but you still have to decide whether incoming data makes sense.&lt;/p&gt;

&lt;p&gt;How I'd Recommend Learning This Properly&lt;/p&gt;

&lt;p&gt;Reading about a programming concept is useful.&lt;/p&gt;

&lt;p&gt;Actually using it makes the difference.&lt;/p&gt;

&lt;p&gt;If you're learning Kotlin, try building something small enough that you can deliberately experiment with missing values.&lt;/p&gt;

&lt;p&gt;A simple user profile application works well.&lt;/p&gt;

&lt;p&gt;Start by creating a UserProfile data class with a required name and optional nickname.&lt;/p&gt;

&lt;p&gt;Next, write a function that displays the nickname when available and uses the name otherwise.&lt;/p&gt;

&lt;p&gt;Then add a biography field and make your application display "No bio added yet" when appropriate.&lt;/p&gt;

&lt;p&gt;Finally, test your code with different combinations of missing information.&lt;/p&gt;

&lt;p&gt;You don't need Android Studio or an entire mobile application for this exercise. A simple Kotlin console program is enough.&lt;/p&gt;

&lt;p&gt;For anyone starting from the basics, Codevra has a structured Kotlin course that introduces variables, types, null safety, functions, classes, collections, and other topics through examples and exercises.&lt;/p&gt;

&lt;p&gt;It's useful to work through these concepts in order, but don't stop at reproducing the examples.&lt;/p&gt;

&lt;p&gt;Change their inputs. Remove values. Try invalid data. Predict what will happen before running the program.&lt;/p&gt;

&lt;p&gt;That's where the understanding starts to become practical.&lt;/p&gt;

&lt;p&gt;Writing Less Code Isn't Always the Goal&lt;/p&gt;

&lt;p&gt;Kotlin is often praised for its concise syntax.&lt;/p&gt;

&lt;p&gt;And yes, writing fewer lines can be satisfying.&lt;/p&gt;

&lt;p&gt;But fewer lines don't automatically mean better code.&lt;/p&gt;

&lt;p&gt;This:&lt;/p&gt;

&lt;p&gt;val result = value?.trim()?.takeIf {&lt;br&gt;
    it.isNotEmpty()&lt;br&gt;
} ?: "Unknown"&lt;/p&gt;

&lt;p&gt;might be perfectly reasonable once you're comfortable with Kotlin.&lt;/p&gt;

&lt;p&gt;For someone encountering safe calls, lambdas, and the Elvis operator for the first time, however, a longer version with explicit conditions might be easier to follow.&lt;/p&gt;

&lt;p&gt;Readability matters.&lt;/p&gt;

&lt;p&gt;There's no prize for fitting an entire function onto one line.&lt;/p&gt;

&lt;p&gt;Choose the version that communicates your intentions clearly, especially when you're working with other developers.&lt;/p&gt;

&lt;p&gt;You can always simplify your code later when you understand what it's doing.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;One of the biggest changes that comes with programming experience is learning to question your assumptions.&lt;/p&gt;

&lt;p&gt;What happens if this field is missing?&lt;/p&gt;

&lt;p&gt;What if the user enters the wrong value?&lt;/p&gt;

&lt;p&gt;What if an external service returns something unexpected?&lt;/p&gt;

&lt;p&gt;What should the application do next?&lt;/p&gt;

&lt;p&gt;Kotlin's null safety encourages you to ask those questions before a problem reaches the user.&lt;/p&gt;

&lt;p&gt;It won't eliminate every bug, and it certainly won't replace careful testing.&lt;/p&gt;

&lt;p&gt;But it offers something valuable: a way to make important assumptions visible in your code.&lt;/p&gt;

&lt;p&gt;And once you start thinking about missing data as something to design for, rather than something to fix after an application crashes, you begin writing better software.&lt;/p&gt;

&lt;p&gt;Not necessarily more complicated software.&lt;/p&gt;

&lt;p&gt;Just software that's more prepared for the real world.&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;If you want to explore Kotlin beyond the examples in this article, these resources are worth bookmarking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.codevra.org/kotlin" rel="noopener noreferrer"&gt;Kotlin Tutorial for Beginners&lt;/a&gt; — A structured course covering Kotlin fundamentals, null safety, functions, classes, coroutines, and more, with examples, exercises, and quizzes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kotlinlang.org/docs/null-safety.html" rel="noopener noreferrer"&gt;Official Kotlin Documentation — Null Safety&lt;/a&gt; — A detailed explanation of nullable types, safe calls, the Elvis operator, and other language features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://developer.android.com/codelabs/basic-android-kotlin-compose-nullability" rel="noopener noreferrer"&gt;Google Android Developers — Use Nullability in Kotlin&lt;/a&gt; — A hands-on introduction to working with nullable values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kotlinlang.org/docs/basic-syntax.html" rel="noopener noreferrer"&gt;Kotlin Basic Syntax Guide&lt;/a&gt; — A useful reference for learning and revisiting Kotlin fundamentals.&lt;br&gt;
`&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>kotlin</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
