<?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: Tasbi Tasbi </title>
    <description>The latest articles on DEV Community by Tasbi Tasbi  (@tasbi03).</description>
    <link>https://dev.to/tasbi03</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2036576%2Fe72c904a-b905-46d7-a9ed-2a3fc42e98f1.png</url>
      <title>DEV Community: Tasbi Tasbi </title>
      <link>https://dev.to/tasbi03</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tasbi03"/>
    <language>en</language>
    <item>
      <title>The Final Voyage: Conquering Input Validation and Charting New Paths 🌟</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Tue, 10 Dec 2024 04:02:50 +0000</pubDate>
      <link>https://dev.to/tasbi03/the-final-voyage-conquering-input-validation-and-charting-new-paths-2bma</link>
      <guid>https://dev.to/tasbi03/the-final-voyage-conquering-input-validation-and-charting-new-paths-2bma</guid>
      <description>&lt;p&gt;When I embarked on this journey to tackle &lt;a href="https://github.com/React-ChatBotify-Plugins/input-validator/issues/3" rel="noopener noreferrer"&gt;Issue #3&lt;/a&gt; for the &lt;strong&gt;React-ChatBotify-Plugins/input-validator&lt;/strong&gt;, I thought I had a clear course charted. The task? Enhance input validation to make it more efficient and robust. Easy enough, right? I quickly got to work, crafted a pull request, and thought, “This is going pretty smoothly!” 😌&lt;/p&gt;

&lt;p&gt;But, as I soon discovered, the calm seas were deceptive. 🌊 What followed was a whirlwind of unexpected challenges, late-night debugging sessions, and a steep learning curve. Now, with the pull request (&lt;a href="https://github.com/React-ChatBotify-Plugins/input-validator/pull/4" rel="noopener noreferrer"&gt;PR #4&lt;/a&gt;) finally generated, I find myself in the waiting phase as the repo owner reviews my work. 🕰️ While I wait, let me take you on a journey through the highs, the lows, and the lessons that made this release so memorable. 🛠️&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Calm Before the Storm: The Issue at Hand&lt;/strong&gt; ⚓
&lt;/h2&gt;

&lt;p&gt;When I first picked up the issue, it seemed like a fairly straightforward task: refine the input validation logic and make it more intuitive for developers and users alike. 🧩 The initial steps went smoothly, and I managed to get a working solution up and running. The pull request was submitted, and I naively thought, “Wow, I might actually be done early this time!” 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spoiler alert:&lt;/strong&gt; I wasn’t. 🫠&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Perfect Storm: Challenges That Tested My Resolve&lt;/strong&gt; 🌪️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Lint Errors – My New Archenemy&lt;/strong&gt; 🐛
&lt;/h3&gt;

&lt;p&gt;The first major challenge arrived in the form of &lt;strong&gt;lint errors&lt;/strong&gt;. Fix one? Ten more popped up. It was like trying to hold water in a sieve. 🏗️ I’d run the linter, fix a spacing issue, and suddenly be bombarded with new complaints: unused imports, inconsistent indentation, missing semicolons—you name it. 😵‍💫&lt;/p&gt;

&lt;p&gt;Here’s an excerpt of the chaos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ESLint Error: &lt;span class="s1"&gt;'React'&lt;/span&gt; is defined but never used 😤
ESLint Error: Expected consistent spacing 🫠
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After hours of chasing down every error (and resisting the urge to throw my keyboard out the window 😅), I finally had a clean linter run. My victory was short-lived, though, as the real challenges were just beginning. 😬&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. The Phantom Folder: Coverage Files&lt;/strong&gt; 🗂️👻
&lt;/h3&gt;

&lt;p&gt;Just as I was celebrating my linting success, the repo owner pointed out that I’d committed the &lt;code&gt;coverage&lt;/code&gt; folder to the repository. Rookie mistake. 🙈&lt;/p&gt;

&lt;p&gt;Fixing this seemed simple enough:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;coverage&lt;/code&gt; folder to &lt;code&gt;.gitignore&lt;/code&gt; 📄✏️&lt;/li&gt;
&lt;li&gt;Remove the existing folder from version control history 🗑️&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Easy, right? Well, not quite. 🥲 During the process, I accidentally deleted something else and broke the build. It took me a couple of tries (and a LOT of Googling 🕵️‍♀️) to get it right, but in the end, the repo was clean, and I’d learned an important lesson about &lt;strong&gt;attention to detail.&lt;/strong&gt; 👌&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. The Case of the Unnecessary Dependency&lt;/strong&gt; 🕵️‍♂️📦
&lt;/h3&gt;

&lt;p&gt;Another piece of feedback from the repo owner caught me off guard: I’d added an unnecessary package, &lt;code&gt;@types/testing-library__jest-dom&lt;/code&gt;, to the project. To make things worse, in my haste to fix this, I accidentally removed a different dependency instead. 🤦‍♀️&lt;/p&gt;

&lt;p&gt;Here’s a quick snapshot of my internal monologue during this debacle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Wait, which dependency am I supposed to remove again? 🤔"&lt;/li&gt;
&lt;li&gt;"Oh no, I just broke the tests. Undo! Undo! 🚨"&lt;/li&gt;
&lt;li&gt;"Okay, let’s try this again, slowly this time... 😅"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually, I got it right. 🙌 But the experience was a humbling reminder to double-check changes before pushing them. 🚀&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;4. The Surprise Twist&lt;/strong&gt; 🌀🤯
&lt;/h3&gt;

&lt;p&gt;While working on the issue, I stumbled upon a &lt;strong&gt;hidden opportunity for improvement.&lt;/strong&gt; 🕵️‍♀️ Something about the way input validation was being handled sparked an idea: a potential enhancement that could take this plugin to the next level. I excitedly shared the idea with the repo owner, who acknowledged its value but pointed out that it was &lt;strong&gt;too advanced&lt;/strong&gt; to tackle within my current timeline. 🛠️⏳&lt;/p&gt;

&lt;p&gt;Although I couldn’t implement it just yet, this discovery left me inspired. 💡 The best part? The owner and I agreed to revisit the idea in the future, setting the stage for ongoing collaboration even after my semester ends. 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Anchored in Growth: Lessons Learned&lt;/strong&gt; 🌱
&lt;/h2&gt;

&lt;p&gt;This release taught me more than I could have imagined. Here are the key takeaways:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Persistence is Key:&lt;/strong&gt; Debugging is an art of patience. 🎨 Every error is a clue, and every fix brings you closer to the goal. 🏁
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attention to Detail:&lt;/strong&gt; Small things, like &lt;code&gt;.gitignore&lt;/code&gt; files and package dependencies, can have a big impact. Overlooking them can create unnecessary headaches. 🤯
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication Matters:&lt;/strong&gt; Open-source collaboration thrives on clear and open communication. 🗨️ Feedback from the repo owner was invaluable, and asking questions when in doubt saved me from making bigger mistakes. 🤝
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embrace the Unexpected:&lt;/strong&gt; Discovering the potential enhancement was a happy accident that reminded me to always keep an open mind while working on a project. 💭✨
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;On the Horizon: What’s Next?&lt;/strong&gt; 🚀
&lt;/h2&gt;

&lt;p&gt;Although my semester is wrapping up, my journey with &lt;strong&gt;React-ChatBotify-Plugins&lt;/strong&gt; is far from over. The repo owner is involved in several open-source projects, and I’ve expressed interest in continuing to contribute even after my course ends. 🙌 This collaboration has been an incredible opportunity to grow as a developer, and I’m excited to tackle more advanced challenges in the future. 💻💡&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Closing Thoughts&lt;/strong&gt; 📝
&lt;/h2&gt;

&lt;p&gt;This experience wasn’t just about writing code—it was about learning to navigate the complexities of real-world development, collaborating with others, and growing through challenges. 💪 To anyone considering open-source contributions, my advice is simple: &lt;strong&gt;Dive in. You’ll learn more than you ever thought possible.&lt;/strong&gt; 🚀&lt;/p&gt;

&lt;p&gt;As I wait for the final review of my pull request, I’m already looking ahead to new opportunities and the lessons they’ll bring. 🌟 For now, I’ll leave you with this: every challenge is a chance to grow, and every mistake is a step toward mastery. Onward and upward! 🚢✨&lt;br&gt;&lt;br&gt;
**&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Week 2 Blog: Progress Report on 0.4 🚀⛵</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Fri, 06 Dec 2024 04:00:49 +0000</pubDate>
      <link>https://dev.to/tasbi03/week-2-blog-progress-report-on-04-25md</link>
      <guid>https://dev.to/tasbi03/week-2-blog-progress-report-on-04-25md</guid>
      <description>&lt;p&gt;Ahoy, fellow developers! It's time for my Week 2 update on my exciting 0.4 journey. While I’ve made significant strides, there’s a new storm on the horizon: CI issues. Let’s explore what I’ve accomplished so far, the challenges I’m tackling, and my game plan for smooth sailing ahead. 🌊⚓&lt;/p&gt;

&lt;h2&gt;
  
  
  What Have I Accomplished So Far? 🎯
&lt;/h2&gt;

&lt;p&gt;In the first week, I focused on writing comprehensive tests and achieving high coverage for the &lt;code&gt;@rcb-plugins/input-validator&lt;/code&gt;. Here’s the summary of my efforts:&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Testing Key Components:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;validateFile.test.ts&lt;/code&gt;&lt;/strong&gt;: Ensured file validation for different types of uploads (valid, invalid, empty, and null files).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getValidator.test.ts&lt;/code&gt;&lt;/strong&gt;: Verified that the correct validator functions (&lt;code&gt;validateTextInput&lt;/code&gt;, &lt;code&gt;validateFileInput&lt;/code&gt;) are retrieved from the flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mergePluginConfig.test.ts&lt;/code&gt;&lt;/strong&gt;: Confirmed that user configurations merge correctly with default configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;getPromptStyles.test.ts&lt;/code&gt;&lt;/strong&gt;: Checked that dynamic styles apply correctly for error, success, and other prompt types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;useRcbPlugin.test.ts&lt;/code&gt;&lt;/strong&gt;: Focused on the plugin’s core logic, including handling input validation, file uploads, and style restoration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✅ Achieved High Test Coverage:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Most files have &lt;strong&gt;95–100% coverage&lt;/strong&gt;, including edge cases. This was a major win for ensuring plugin reliability. 🎉&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Have I Figured Out? 🧠💡
&lt;/h2&gt;

&lt;p&gt;Through focused efforts, I learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How to Mock and Simulate Complex Scenarios&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Used &lt;code&gt;Jest&lt;/code&gt; and &lt;code&gt;@testing-library/react&lt;/code&gt; to simulate DOM events, file uploads, and style updates.&lt;/li&gt;
&lt;li&gt;Managed to isolate and test plugin logic with precision.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Tackling Dynamic Style Updates&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Successfully verified that styles update dynamically based on validation results.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Clean Code Practices&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Modularized tests into distinct files for clarity and maintainability.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  New Challenges: CI Issues 🚨⚠️
&lt;/h2&gt;

&lt;p&gt;This week, I opened a Pull Request, which included all the tests and updates. While I was excited about the progress, CI (Continuous Integration) issues emerged like a storm cloud:&lt;/p&gt;

&lt;h3&gt;
  
  
  Here’s the error report:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Error&lt;/strong&gt;: Unexpected &lt;code&gt;any&lt;/code&gt;. Specify a different type  &lt;code&gt;@typescript-eslint/no-explicit-any&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error&lt;/strong&gt;: '&lt;code&gt;error&lt;/code&gt; is defined but never used'         &lt;code&gt;@typescript-eslint/no-unused-vars&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warning&lt;/strong&gt;: Unused eslint-disable directive (no problems were reported)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Problems:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Usage of &lt;code&gt;any&lt;/code&gt;&lt;/strong&gt;: Multiple instances of &lt;code&gt;any&lt;/code&gt; in test files caused linting errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unused Variables&lt;/strong&gt;: Some variables like &lt;code&gt;error&lt;/code&gt; were defined but not used, triggering TypeScript warnings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Coverage Report Issues&lt;/strong&gt;: The linter flagged unused ESLint directives in the coverage report.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Despite my efforts, I haven’t been able to fully resolve these CI issues yet. The errors are preventing the PR from passing CI checks, which means I can’t merge it into the main branch. 😞&lt;/p&gt;

&lt;h2&gt;
  
  
  How Will I Adjust? 🛠️⛵
&lt;/h2&gt;

&lt;p&gt;To tackle the current roadblocks and stay on course, here’s my plan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Fix TypeScript Linting Errors&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;any&lt;/code&gt; types with explicit types in all test cases.&lt;/li&gt;
&lt;li&gt;Refactor unused variables or remove them entirely to clean up the code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Debug and Recheck Tests&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure all test cases still run smoothly after fixing the linting issues.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;--fix&lt;/code&gt; option with ESLint to resolve minor warnings automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Collaborate for Feedback&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share the PR with maintainers for guidance on unresolved errors.&lt;/li&gt;
&lt;li&gt;Confirm if my approach aligns with the project’s linting and TypeScript standards.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Stay Flexible&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If linting issues persist, consider breaking down the PR into smaller, manageable parts for better debugging.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thoughts 💭✨
&lt;/h2&gt;

&lt;p&gt;While the CI issues have slowed down my progress, they’ve also taught me the importance of attention to detail. Testing isn’t just about code coverage—it’s about clean, maintainable, and standards-compliant code.&lt;/p&gt;

&lt;p&gt;Despite the hiccups, I’m optimistic about resolving these issues and pushing the PR forward. My next step will be to squash the linting bugs and ensure my work gets merged into the main branch.&lt;/p&gt;

&lt;p&gt;Stay tuned for the final blog post next week, where I’ll reflect on the entire journey and (hopefully) celebrate a successfully merged PR! 🎉🚀&lt;/p&gt;

&lt;p&gt;Until next time, happy coding! 💻🌟&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🛳️ Charting the Course for 0.4 – Setting Sail for Success 🚢</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Thu, 28 Nov 2024 07:10:56 +0000</pubDate>
      <link>https://dev.to/tasbi03/charting-the-course-for-04-setting-sail-for-success-3pcn</link>
      <guid>https://dev.to/tasbi03/charting-the-course-for-04-setting-sail-for-success-3pcn</guid>
      <description>&lt;p&gt;Ahoy there, adventurers! 👋 If you've been following my journey through the &lt;strong&gt;React Chatbotify&lt;/strong&gt; seas, you know that my voyage in 0.3 was nothing short of exhilarating. Remember when I introduced file upload validation with TypeScript and React Chatbotify? &lt;a href="https://dev.to/tasbi03/sailing-the-typescript-seas-my-adventure-adding-file-upload-validation-to-react-chatbotify-3mim"&gt;Here’s a refresher&lt;/a&gt;. Spoiler alert: I lived to tell the tale. 🏴‍☠️&lt;/p&gt;

&lt;p&gt;Now, as I gear up for the 0.4 voyage, it’s time to lay down the map, plan my destination, and gather the tools I'll need for this adventure. This post is a sneak peek into what I'll be doing in 0.4, why I chose this work, and how I’ll ensure my ship stays afloat. 🌊&lt;/p&gt;




&lt;h2&gt;
  
  
  🗺️ The Mission: Fortify and Refine 🛠️
&lt;/h2&gt;

&lt;p&gt;For 0.4, I’ll be doubling down on my work with &lt;strong&gt;React Chatbotify’s input-validator plugin&lt;/strong&gt;. The core focus will be to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expand Test Coverage&lt;/strong&gt;: While file validation is seaworthy, other parts of the plugin—like merging configurations, style generation, and text validation—are still uncharted territory. I'll write comprehensive tests to boost confidence in every nook and cranny of the codebase. 🧪&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimize the Plugin&lt;/strong&gt;: The input-validator plugin is already robust, but I want to ensure it’s bulletproof and easily extendable for developers who rely on it. A treasure chest of maintainability, if you will. 🏴‍☠️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contribute Back&lt;/strong&gt;: My goal isn’t just to complete tasks; it’s to leave the plugin better than I found it. I’ll contribute my work upstream and ensure my code aligns with community standards. 🤝&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🤔 Why This Project?
&lt;/h2&gt;

&lt;p&gt;Great question, matey! Here’s why I picked this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Familiar Waters&lt;/strong&gt;: Having worked on this plugin in 0.3, I’m already familiar with its currents and tides. But there’s so much more to explore! 🧭&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community Impact&lt;/strong&gt;: Plugins like these empower developers to build smarter chatbots. Strengthening it means helping the community sail smoother seas. ⚓&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge Accepted&lt;/strong&gt;: Testing, especially edge cases, can be tricky. But hey, what’s a voyage without a few storms? 🌩️&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚓ The Approach: Staying the Course
&lt;/h2&gt;

&lt;p&gt;Here’s how I’ll navigate this journey:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Step-by-Step Progress&lt;/strong&gt;: I’ll tackle one test case or feature at a time. Slow and steady wins the race. 🐢&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborate&lt;/strong&gt;: I’ll actively seek feedback from maintainers and peers. After all, even the best captains consult their crew. 👩‍✈️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay Organized&lt;/strong&gt;: With clear goals and weekly check-ins, I’ll ensure my ship doesn’t drift off course. 📅&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embrace Challenges&lt;/strong&gt;: Bugs, edge cases, and unexpected hurdles? Bring ‘em on! They make the treasure at the end even sweeter. 🪙&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🏴‍☠️ Goals for 0.4
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;💯 &lt;strong&gt;Achieve Full Test Coverage&lt;/strong&gt;: No uncovered lines shall escape!&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Submit a Stellar PR&lt;/strong&gt;: My work should be clear, concise, and ready to merge.&lt;/li&gt;
&lt;li&gt;🌟 &lt;strong&gt;Learn and Share&lt;/strong&gt;: Document my journey, share lessons, and inspire others to contribute.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A Surprise Twist? Stay Tuned! 🌟
&lt;/h2&gt;

&lt;p&gt;While digging through the repo, I stumbled upon a potential area for improvement—something that could really enhance the user experience. 🤫 I’m keeping it under wraps for now, but I’ve already started brainstorming how to tackle this secret challenge. First, I’ll confirm with the repo owner to see if it’s a valid and impactful task. If all goes well, you’ll hear all about it in my Week 2 update! 🕵️‍♀️✨&lt;/p&gt;




&lt;p&gt;So there you have it, shipmates—a glimpse into the horizon. 🗺️ Stay tuned for updates as I embark on this adventure and bring back tales of testing, code, and maybe a few treasures along the way. Until next time, happy coding! 💻⚓&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🛳️ Charting the Course for 0.4 – Setting Sail for Success 🚢</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Thu, 28 Nov 2024 07:10:56 +0000</pubDate>
      <link>https://dev.to/tasbi03/charting-the-course-for-04-setting-sail-for-success-547c</link>
      <guid>https://dev.to/tasbi03/charting-the-course-for-04-setting-sail-for-success-547c</guid>
      <description>&lt;p&gt;Ahoy there, adventurers! 👋 If you've been following my journey through the &lt;strong&gt;React Chatbotify&lt;/strong&gt; seas, you know that my voyage in 0.3 was nothing short of exhilarating. Remember when I introduced file upload validation with TypeScript and React Chatbotify? &lt;a href="https://dev.to/tasbi03/sailing-the-typescript-seas-my-adventure-adding-file-upload-validation-to-react-chatbotify-3mim"&gt;Here’s a refresher&lt;/a&gt;. Spoiler alert: I lived to tell the tale. 🏴‍☠️&lt;/p&gt;

&lt;p&gt;Now, as I gear up for the 0.4 voyage, it’s time to lay down the map, plan my destination, and gather the tools I'll need for this adventure. This post is a sneak peek into what I'll be doing in 0.4, why I chose this work, and how I’ll ensure my ship stays afloat. 🌊&lt;/p&gt;




&lt;h2&gt;
  
  
  🗺️ The Mission: Fortify and Refine 🛠️
&lt;/h2&gt;

&lt;p&gt;For 0.4, I’ll be doubling down on my work with &lt;strong&gt;React Chatbotify’s input-validator plugin&lt;/strong&gt;. The core focus will be to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expand Test Coverage&lt;/strong&gt;: While file validation is seaworthy, other parts of the plugin—like merging configurations, style generation, and text validation—are still uncharted territory. I'll write comprehensive tests to boost confidence in every nook and cranny of the codebase. 🧪&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimize the Plugin&lt;/strong&gt;: The input-validator plugin is already robust, but I want to ensure it’s bulletproof and easily extendable for developers who rely on it. A treasure chest of maintainability, if you will. 🏴‍☠️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contribute Back&lt;/strong&gt;: My goal isn’t just to complete tasks; it’s to leave the plugin better than I found it. I’ll contribute my work upstream and ensure my code aligns with community standards. 🤝&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🤔 Why This Project?
&lt;/h2&gt;

&lt;p&gt;Great question, matey! Here’s why I picked this project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Familiar Waters&lt;/strong&gt;: Having worked on this plugin in 0.3, I’m already familiar with its currents and tides. But there’s so much more to explore! 🧭&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community Impact&lt;/strong&gt;: Plugins like these empower developers to build smarter chatbots. Strengthening it means helping the community sail smoother seas. ⚓&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Challenge Accepted&lt;/strong&gt;: Testing, especially edge cases, can be tricky. But hey, what’s a voyage without a few storms? 🌩️&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚓ The Approach: Staying the Course
&lt;/h2&gt;

&lt;p&gt;Here’s how I’ll navigate this journey:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Step-by-Step Progress&lt;/strong&gt;: I’ll tackle one test case or feature at a time. Slow and steady wins the race. 🐢&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborate&lt;/strong&gt;: I’ll actively seek feedback from maintainers and peers. After all, even the best captains consult their crew. 👩‍✈️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay Organized&lt;/strong&gt;: With clear goals and weekly check-ins, I’ll ensure my ship doesn’t drift off course. 📅&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embrace Challenges&lt;/strong&gt;: Bugs, edge cases, and unexpected hurdles? Bring ‘em on! They make the treasure at the end even sweeter. 🪙&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🏴‍☠️ Goals for 0.4
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;💯 &lt;strong&gt;Achieve Full Test Coverage&lt;/strong&gt;: No uncovered lines shall escape!&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Submit a Stellar PR&lt;/strong&gt;: My work should be clear, concise, and ready to merge.&lt;/li&gt;
&lt;li&gt;🌟 &lt;strong&gt;Learn and Share&lt;/strong&gt;: Document my journey, share lessons, and inspire others to contribute.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So there you have it, shipmates—a glimpse into the horizon. 🗺️ Stay tuned for updates as I embark on this adventure and bring back tales of testing, code, and maybe a few treasures along the way. Until next time, happy coding! 💻⚓&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🚀 My Aha-Moment-Packed Journey to Releasing ReadCraft 🎉</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Wed, 27 Nov 2024 01:54:37 +0000</pubDate>
      <link>https://dev.to/tasbi03/my-aha-moment-packed-journey-to-releasing-readcraft-3im1</link>
      <guid>https://dev.to/tasbi03/my-aha-moment-packed-journey-to-releasing-readcraft-3im1</guid>
      <description>&lt;p&gt;What’s up, DEV community? 👋 Have you ever felt like you're about to conquer the world, only to realize you’re stuck battling bugs that don’t make any sense? Yeah, same here. Welcome to my &lt;strong&gt;Lab 9&lt;/strong&gt; adventure where I took my humble Python script and turned it into a shiny, installable Python package, &lt;strong&gt;ReadCraft&lt;/strong&gt;! Spoiler alert: it wasn’t smooth sailing, but hey, that’s what makes it fun, right?&lt;/p&gt;




&lt;h2&gt;
  
  
  🌟 The "Wait, I Can Do This?" Realization
&lt;/h2&gt;

&lt;p&gt;Let’s start at the beginning. &lt;strong&gt;ReadCraft&lt;/strong&gt; is a tool that automates creating &lt;code&gt;README.md&lt;/code&gt; files using the Groq API. Sounds fancy, right? I thought so too. But when I started preparing it for release on PyPI, it felt less like fancy magic and more like assembling IKEA furniture without the manual.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 The Tool Arsenal
&lt;/h2&gt;

&lt;p&gt;Here’s the toolkit I used to make the magic happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://pypi.org/project/readcraft/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;&lt;/strong&gt;: The destination for my masterpiece.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://test.pypi.org/project/readcraft/" rel="noopener noreferrer"&gt;TestPyPI&lt;/a&gt;&lt;/strong&gt;: The practice stage where all my mistakes went to die.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twine&lt;/strong&gt;: My trusty messenger to get packages uploaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions&lt;/strong&gt;: My automation buddy to handle testing and (eventually) releases.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧑‍💻 The IKEA Assembly of Packaging
&lt;/h2&gt;

&lt;p&gt;The process was like building a LEGO Death Star but with more yelling at my terminal. Here’s the breakdown:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: "What’s a setup.py?"
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;setup.py&lt;/code&gt; turned out to be the heart of the operation. This magical file describes your project to PyPI. Mine looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;setuptools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;find_packages&lt;/span&gt;

&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;readcraft&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.1.4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A command-line tool to generate README.md files using the Groq API.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;long_description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;README.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;long_description_content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/markdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tasbi Tasbi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/tasbi03/ReadCraft&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;find_packages&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;install_requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;python-dotenv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;toml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;entry_points&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;console_scripts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;readcraft=readcraft.readme_generator:main&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]},&lt;/span&gt;
    &lt;span class="n"&gt;classifiers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Programming Language :: Python :: 3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;License :: OSI Approved :: MIT License&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Operating System :: OS Independent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;python_requires&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;=3.7&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I spent way too much time wondering if I needed &lt;code&gt;python_requires&lt;/code&gt;. (Spoiler: Yes, I did.)&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Building the Package
&lt;/h3&gt;

&lt;p&gt;This part sounded intimidating, but it wasn’t too bad. Running this command did all the heavy lifting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python setup.py sdist bdist_wheel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result? Two shiny new files in the &lt;code&gt;dist/&lt;/code&gt; directory. I felt like a wizard. 🧙‍♂️&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: The Upload That Wasn’t
&lt;/h3&gt;

&lt;p&gt;I confidently ran:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;twine upload dist/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And BAM! &lt;strong&gt;403 Forbidden.&lt;/strong&gt; I double-checked my PyPI token, reread the error message, Googled it, and finally realized… I forgot to configure &lt;code&gt;.pypirc&lt;/code&gt; properly. Rookie move. Fixing it was easy once I knew what I was doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[distutils]
index-servers =
    pypi

[pypi]
username = __token__
password = &amp;lt;your_api_token&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🤦‍♀️ Challenges That Made Me Want to Quit
&lt;/h2&gt;

&lt;p&gt;Here are a few memorable roadblocks I hit (and conquered):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;"Where’s my &lt;code&gt;.env&lt;/code&gt; file?"&lt;/strong&gt;&lt;br&gt;
My tool needs an API key from &lt;code&gt;.env&lt;/code&gt;, but users kept forgetting to create one. Solution? Add a &lt;code&gt;sample.env&lt;/code&gt; and update the README to scream, “DON’T FORGET THIS!”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependencies Gone Wild&lt;/strong&gt;:&lt;br&gt;
An old &lt;code&gt;requests&lt;/code&gt; package version didn’t play well with Python 3.12. Upgrading dependencies was my first real debugging win.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tests Failing for No Reason&lt;/strong&gt;:&lt;br&gt;
Oh, &lt;code&gt;PYTHONPATH&lt;/code&gt;. Why do you exist? Adding it to GitHub Actions saved my tests and my sanity:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.workspace }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎉 Aha Moments Worth Celebrating
&lt;/h2&gt;

&lt;p&gt;Here’s the fun stuff I figured out:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Actions Can Do Magic&lt;/strong&gt;:
Automating my tests and PyPI releases felt like the future. No more manual uploads for me!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publishing Feels Empowering&lt;/strong&gt;:
When my package finally showed up on PyPI, I might’ve done a little dance. Okay, a big dance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Reviews Help&lt;/strong&gt;:
Testing with a partner uncovered gaps in my instructions. Fixing those felt like leveling up.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🛠 How You Can Use ReadCraft
&lt;/h2&gt;

&lt;p&gt;Want to try it? Here’s how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install ReadCraft:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   pip &lt;span class="nb"&gt;install &lt;/span&gt;readcraft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a &lt;code&gt;.env&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   GROQ_API_KEY=your_api_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Run the tool:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   readcraft path/to/your/file.py &lt;span class="nt"&gt;--output-dir&lt;/span&gt; ./output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Releasing ReadCraft wasn’t just about shipping code; it was about learning, struggling, and growing. If you’re thinking about releasing your own package, DO IT. You’ll make mistakes, but that’s the fun part.&lt;/p&gt;

&lt;p&gt;What’s next for me? Probably world domination. Or maybe just more Python packages. Let me know what you think in the comments, and feel free to try &lt;strong&gt;ReadCraft&lt;/strong&gt; for yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;readcraft
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sailing the TypeScript Seas: My Adventure Adding File Upload Validation to React Chatbotify</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Sat, 23 Nov 2024 02:00:24 +0000</pubDate>
      <link>https://dev.to/tasbi03/sailing-the-typescript-seas-my-adventure-adding-file-upload-validation-to-react-chatbotify-3mim</link>
      <guid>https://dev.to/tasbi03/sailing-the-typescript-seas-my-adventure-adding-file-upload-validation-to-react-chatbotify-3mim</guid>
      <description>&lt;p&gt;Ahoy, fellow coders! 🏴‍☠️&lt;/p&gt;

&lt;p&gt;Have you ever felt like a pirate setting sail on the vast ocean of code, only to realize you're navigating a storm without a compass? That's exactly how I felt when I embarked on my latest coding adventure: adding file upload validation to the &lt;a href="https://react-chatbotify.com/" rel="noopener noreferrer"&gt;React Chatbotify&lt;/a&gt; &lt;code&gt;input-validator&lt;/code&gt; plugin.&lt;/p&gt;

&lt;p&gt;As someone who can code in JavaScript in my sleep but is still getting acquainted with TypeScript, I knew I was in for a wild ride. But hey, what's life without a little challenge, right?&lt;/p&gt;

&lt;p&gt;Grab your favorite beverage (mine's a cup of coffee with a splash of excitement), and join me as I recount my journey through TypeScript, React Chatbotify, and the quirks of file upload validation. Let's dive in! 🌊&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 1: Setting Sail Without a Map 🗺️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Quest Begins
&lt;/h3&gt;

&lt;p&gt;It all started when I decided to contribute to the &lt;a href="https://github.com/React-ChatBotify-Plugins/input-validator" rel="noopener noreferrer"&gt;React Chatbotify Plugins&lt;/a&gt; repository. The issue at hand was straightforward—or so I thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Add support for file upload validation&lt;/strong&gt; (&lt;a href="https://github.com/React-ChatBotify-Plugins/input-validator/issues/1" rel="noopener noreferrer"&gt;Issue #1&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The plugin currently supports text input validation, but there's a need to validate file uploads as well. "Simple enough," I mused. Little did I know, I was about to enter uncharted waters.&lt;/p&gt;

&lt;p&gt;Lost in Documentation&lt;br&gt;
First things first, I needed to understand how React Chatbotify and its plugins work. I dived into the documentation and explored the react-chatbotify GitHub repo.&lt;/p&gt;

&lt;p&gt;As someone who hadn't worked with plugins before, I felt like I was reading hieroglyphs. But with patience and copious amounts of caffeine, I began to piece together how everything fit.&lt;/p&gt;


&lt;h2&gt;
  
  
  Chapter 2: The Mysterious Case of the Missing Plugin 🕵️‍♀️
&lt;/h2&gt;

&lt;p&gt;Writing the Validation Logic&lt;br&gt;
I rolled up my sleeves and started coding the file upload validation logic. I added a new event listener for &lt;code&gt;rcb-user-upload-file&lt;/code&gt; in the &lt;code&gt;useRcbPlugin&lt;/code&gt; hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;window.addEventListener&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rcb-user-upload-file"&lt;/span&gt;, handleUserUploadFile&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    window.removeEventListener&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"rcb-user-upload-file"&lt;/span&gt;, handleUserUploadFile&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feeling confident, I fired up the app to test it out. And... nothing happened. The file upload wasn't working at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Aha!" Moment
&lt;/h2&gt;

&lt;p&gt;After hours of frustration and questioning my life choices, I realized that I hadn't actually called the plugin in my main app. 🤦‍♂️&lt;/p&gt;

&lt;p&gt;Here's what I was missing in &lt;code&gt;App.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import ChatBot, &lt;span class="o"&gt;{&lt;/span&gt; Flow &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"react-chatbotify"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import RcbPlugin from &lt;span class="s2"&gt;"./factory/RcbPluginFactory"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const App &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  // Initialize the plugin
  const plugins &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;RcbPlugin&lt;span class="o"&gt;()]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // ... rest of the code
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default App&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once I added the plugin to my app, the file upload functionality sprang to life. Lesson learned: Always remember to include your plugins, folks!&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 3: The Validation Conundrum 🧩
&lt;/h2&gt;

&lt;p&gt;Adding File Validation Logic&lt;br&gt;
With the plugin properly invoked, I set out to write the file validation logic. I created a separate function &lt;code&gt;validateFile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// validateFile.ts

import &lt;span class="o"&gt;{&lt;/span&gt; ValidationResult &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"../types/ValidationResult"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const validateFile &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;file?: File&lt;span class="o"&gt;)&lt;/span&gt;: ValidationResult &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const allowedTypes &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"image/jpeg"&lt;/span&gt;, &lt;span class="s2"&gt;"image/png"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const maxSizeInBytes &lt;span class="o"&gt;=&lt;/span&gt; 5 &lt;span class="k"&gt;*&lt;/span&gt; 1024 &lt;span class="k"&gt;*&lt;/span&gt; 1024&lt;span class="p"&gt;;&lt;/span&gt; // 5MB

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;file&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      success: &lt;span class="nb"&gt;false&lt;/span&gt;,
      promptContent: &lt;span class="s2"&gt;"No file uploaded."&lt;/span&gt;,
      promptDuration: 3000,
      promptType: &lt;span class="s2"&gt;"error"&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I thought I had everything sorted out. But then, another problem reared its head.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 4: When Validation Goes Rogue 🏴‍☠️
&lt;/h2&gt;

&lt;p&gt;The Unexpected Behavior&lt;br&gt;
Upon testing, I noticed that the text input validation wasn't working properly. When I typed in text, it was being blocked by the file upload validator. Wait, what?&lt;/p&gt;

&lt;p&gt;This wasn't supposed to happen. The &lt;code&gt;validateFileInput&lt;/code&gt; should only apply to file uploads, not text inputs.&lt;/p&gt;

&lt;p&gt;Seeking Guidance&lt;br&gt;
Stumped, I reached out to the plugin owner and showed them a screen recording of the issue. They pointed out that the validators were overlapping and suggested that the &lt;code&gt;validateTextInput&lt;/code&gt; and &lt;code&gt;validateFileInput&lt;/code&gt; should be independent of each other.&lt;/p&gt;

&lt;p&gt;They also recommended adding a &lt;code&gt;chatDisabled&lt;/code&gt; property to control when text input should be disabled.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 5: Righting the Ship ⚓
&lt;/h2&gt;

&lt;p&gt;Separating the Validators&lt;br&gt;
I made changes to ensure that each validator only handled its respective input type.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updated InputValidatorBlock Interface:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// InputValidatorBlock.ts

&lt;span class="nb"&gt;export &lt;/span&gt;interface InputValidatorBlock extends FlowBlock &lt;span class="o"&gt;{&lt;/span&gt;
  validateTextInput?: ValidatorFunction&amp;lt;string&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;
  validateFileInput?: ValidatorFunction&amp;lt;File&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;
  // ... rest of the properties
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing Again
&lt;/h3&gt;

&lt;p&gt;With these changes, I ran the app once more. Success! 🎉&lt;/p&gt;

&lt;p&gt;Text inputs were validated using validateTextInput.&lt;br&gt;
File uploads were validated using validateFileInput.&lt;br&gt;
Users could provide a URL or upload a file, offering flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges Post-PR
&lt;/h3&gt;

&lt;p&gt;Once my pull request was submitted, it underwent a rigorous review process. Several changes were requested by the plugin owner, which was both educational and, at times, exhausting. Here are some of the significant updates I made based on the feedback:&lt;/p&gt;

&lt;h3&gt;
  
  
  Emotional Rollercoaster
&lt;/h3&gt;

&lt;p&gt;Each round of feedback was a mix of "aha moments" and "why didn't I think of that?" While the process was tiring, it pushed me to improve the quality of my work. Ultimately, the back-and-forth discussions helped me gain a deeper understanding of the plugin's architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 6: Key Takeaways 📝
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I Learned
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Value of Reviews&lt;/strong&gt;: Code reviews are not just about pointing out mistakes—they're about collaboration and improvement. I came out of this process with a sharper eye for detail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Patience Pays Off&lt;/strong&gt;: Open-source contributions can be challenging, especially when you're new to the technology stack. Taking time to absorb feedback and iterate on your work is essential.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Typescript Confidence&lt;/strong&gt;: This project significantly boosted my confidence in TypeScript. Understanding interfaces, custom types, and type-safe validation was a steep but rewarding learning curve.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Chapter 7: Challenges Faced 🏔️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TypeScript Trials
&lt;/h3&gt;

&lt;p&gt;Being new to TypeScript, I found myself wrestling with type definitions and interfaces. Understanding how to define and use custom types like &lt;code&gt;ValidationResult&lt;/code&gt; and &lt;code&gt;ValidatorFunction&lt;/code&gt; was a steep learning curve.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Handling Headaches
&lt;/h3&gt;

&lt;p&gt;Handling custom events like &lt;code&gt;rcb-user-upload-file&lt;/code&gt; required a deep dive into the event system of React Chatbotify. Ensuring that event listeners were added and removed correctly was crucial to prevent memory leaks and unexpected behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fatigue from Iterations
&lt;/h3&gt;

&lt;p&gt;The repeated back-and-forth for changes in my pull request was draining. While it improved the quality of my work, it also tested my perseverance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Chapter 8: Wrapping Up 🛳️
&lt;/h2&gt;

&lt;p&gt;Contributing to the React Chatbotify plugin was a rewarding experience. Despite the challenges, I walked away with valuable skills and a deeper appreciation for open-source development.&lt;/p&gt;

&lt;p&gt;You can explore the &lt;a href="https://github.com/React-ChatBotify-Plugins/input-validator/pull/2" rel="noopener noreferrer"&gt;pull request here&lt;/a&gt; and view the full commit history. I hope this story inspires others to dive into open source, even if the waters seem intimidating at first.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts 💭
&lt;/h2&gt;

&lt;p&gt;Thanks for joining me on this journey! I hope my experiences can help others who might be navigating similar waters. If you have any questions or want to share your own coding adventures, feel free to leave a comment below.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Navigating the CI Seas: A Tale of Mocking Files and Testing Stranger Code</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Sat, 16 Nov 2024 06:36:51 +0000</pubDate>
      <link>https://dev.to/tasbi03/navigating-the-ci-seas-a-tale-of-mocking-files-and-testing-stranger-code-1nle</link>
      <guid>https://dev.to/tasbi03/navigating-the-ci-seas-a-tale-of-mocking-files-and-testing-stranger-code-1nle</guid>
      <description>&lt;p&gt;Ahoy, fellow developers! 🌊 Ever tried to sail the uncharted waters of someone else's codebase? Well, grab your compasses and let me regale you with my latest adventure in setting up Continuous Integration (CI) and writing tests for a project that wasn't mine. Spoiler alert: it involved a lot of mocking—both the technical kind and, well, the other kind too!&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Sail with GitHub Actions CI Workflow
&lt;/h2&gt;

&lt;p&gt;First things first, I needed to set up a CI workflow for my own repository. I wanted to automate the testing process so that every push would run my tests and ensure everything was shipshape.&lt;/p&gt;

&lt;p&gt;Here's what my &lt;code&gt;.github/workflows/ci.yml&lt;/code&gt; looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Python&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v4&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.x'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install dependencies&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;python -m pip install --upgrade pip&lt;/span&gt;
        &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;python -m unittest discover&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty standard stuff, right? This workflow checks out the code, sets up Python, installs dependencies, and runs the tests. Simple, yet effective—like a trusty compass.&lt;/p&gt;




&lt;h2&gt;
  
  
  Boarding the Ship: Writing Tests for a Stranger's Repo
&lt;/h2&gt;

&lt;p&gt;Now, here's where the real adventure began. I was tasked with writing tests for HTSagara's &lt;code&gt;readme_genie&lt;/code&gt; repository. Imagine being handed a treasure map in a language you only partially understand. Challenge accepted!&lt;/p&gt;




&lt;h3&gt;
  
  
  The Quest for Meaningful Tests
&lt;/h3&gt;

&lt;p&gt;I decided to focus on the &lt;code&gt;read_file_content&lt;/code&gt; function, which, as the name suggests, reads file content. I thought, "What could possibly go wrong with reading files?" Turns out, plenty—if you're testing!&lt;/p&gt;

&lt;p&gt;I wrote tests to handle various scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Empty Files&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Files with Only Comments&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Large Files&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a peek at one of the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;builtins.open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mock_open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;read_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_read_file_content_empty_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Test read_file_content with an empty file.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;file_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_file_content&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;empty_file.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Mocking Files Like a Pro
&lt;/h3&gt;

&lt;p&gt;Since I didn't want to actually create files, I used &lt;code&gt;unittest.mock&lt;/code&gt; to simulate file operations. This was my first time heavily relying on mocking, and it felt like I was crafting illusions—like a code wizard!&lt;/p&gt;

&lt;p&gt;Writing tests for someone else's codebase was like deciphering a coded message. I had to understand the function's intent, its edge cases, and how it handled unexpected input. It was both challenging and exhilarating.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparing Ships: My Repo vs. My Partner's
&lt;/h2&gt;

&lt;p&gt;In my own repo, I had a cozy setup with straightforward tests. In contrast, HTSagara's repo was a grand vessel with intricate details. Their testing setup was minimal, so I had the freedom (and responsibility) to expand it.&lt;/p&gt;

&lt;p&gt;The main differences were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test Coverage&lt;/strong&gt;: My repo had tests covering most functions, while theirs had room for more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexity&lt;/strong&gt;: Their functions handled more edge cases, requiring more thoughtful tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI Integration&lt;/strong&gt;: Both of us used GitHub Actions, but the workflows had slight variations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Treasure of Continuous Integration
&lt;/h2&gt;

&lt;p&gt;After setting up CI, I must say—I'm hooked! Having automated tests run on every push is like having a vigilant lookout who never sleeps. It catches issues early, ensures code quality, and gives peace of mind.&lt;/p&gt;

&lt;p&gt;CI has transformed from a mysterious acronym to an indispensable tool in my development arsenal. It's like upgrading from a rowboat to a schooner.&lt;/p&gt;




&lt;h2&gt;
  
  
  Optional Challenges: Tackling the Behemoth
&lt;/h2&gt;

&lt;p&gt;One of the optional challenges was to test the function's performance with a large file. I simulated a file with 1000 lines to see how the function held up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;builtins.open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_callable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;mock_open&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;read_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;line&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_read_file_content_large_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mock_file&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Test read_file_content with a large file.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;start_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;file_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_file_content&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;large_file.py&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;elapsed_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;end_time&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&lt;/span&gt;

    &lt;span class="n"&gt;expected_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;line&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expected_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertLess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;elapsed_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing large files took too long!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test not only checked if the function could handle large files but also if it did so efficiently. I'm happy to report that it passed with flying colors!&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned and Final Thoughts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Writing Tests for Others&lt;/strong&gt;: It's a fantastic way to deepen your understanding of testing and code structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mocking is Powerful&lt;/strong&gt;: &lt;code&gt;unittest.mock&lt;/code&gt; is now a close friend. It opens up possibilities for testing without relying on actual I/O operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI is Essential&lt;/strong&gt;: Automating tests saves time and reduces errors. It's like having a trusty first mate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, this lab was a thrilling voyage through the seas of CI and testing. I encourage everyone to venture beyond their comfort zones—who knows what treasures you'll find?&lt;/p&gt;

&lt;p&gt;Fair winds and following seas! 🌬️🚢&lt;/p&gt;

&lt;p&gt;Feel free to share your own adventures or ask questions in the comments below. Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Testing ReadCraft: The Epic Adventure of Bugs, Mocks, and Merge Mishaps 🚀🐛🔍</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Sat, 09 Nov 2024 05:41:27 +0000</pubDate>
      <link>https://dev.to/tasbi03/testing-readcraft-the-epic-adventure-of-bugs-mocks-and-merge-mishaps-104j</link>
      <guid>https://dev.to/tasbi03/testing-readcraft-the-epic-adventure-of-bugs-mocks-and-merge-mishaps-104j</guid>
      <description>&lt;p&gt;When I first set out to add automated testing to my ReadCraft project on GitHub, I thought it would be a simple exercise. Just throw in a few test cases, check that everything works, and call it a day, right? 🤔 Little did I know that testing would take me through a winding journey of commit errors, merge conflicts, and some pretty cool discoveries along the way. Here’s the whole story – the good, the bad, and the buggy!&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Picking the Right Testing Tools: Pytest and Mocking Magic
&lt;/h2&gt;

&lt;p&gt;To start, I needed to decide on a testing framework. Enter &lt;strong&gt;&lt;a href="https://docs.pytest.org/en/stable/" rel="noopener noreferrer"&gt;Pytest&lt;/a&gt;&lt;/strong&gt;! Known for its ease of use, it’s perfect for both beginners and seasoned developers. I also included &lt;strong&gt;&lt;a href="https://pypi.org/project/pytest-mock/" rel="noopener noreferrer"&gt;pytest-mock&lt;/a&gt;&lt;/strong&gt; to help me simulate responses from the LLM (Large Language Model). Since ReadCraft relies on these responses, I needed a way to create predictable test cases without actually pinging the LLM every time.&lt;/p&gt;

&lt;p&gt;Why Pytest? 🤷 It’s lightweight, flexible, and integrates well with GitHub Codespaces, where ReadCraft lives. Plus, Pytest’s descriptive output makes debugging a lot easier – a feature that would come in handy more times than I expected!&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠 The Setup: Making Tests Seamless in Codespaces
&lt;/h2&gt;

&lt;p&gt;My first task was to ensure every developer (including future me) could run these tests without any additional setup. That meant adding &lt;strong&gt;Pytest&lt;/strong&gt; and &lt;strong&gt;pytest-mock&lt;/strong&gt; to &lt;code&gt;requirements.txt&lt;/code&gt; and creating a &lt;code&gt;pytest.ini&lt;/code&gt; file to keep settings like verbosity and warnings under control. This setup ensures that anyone opening ReadCraft in a new Codespace can simply run &lt;code&gt;pytest&lt;/code&gt; and have everything work out of the box. 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step for Setting Up Pytest:
&lt;/h3&gt;

&lt;p&gt;Added &lt;code&gt;pytest&lt;/code&gt; and &lt;code&gt;pytest-mock&lt;/code&gt; to &lt;code&gt;requirements.txt&lt;/code&gt;.&lt;br&gt;
Committed and pushed the setup so it would initialize automatically in GitHub Codespaces.&lt;/p&gt;

&lt;p&gt;With these steps done, I was ready to start writing tests – or so I thought.&lt;/p&gt;

&lt;h2&gt;
  
  
  🐙 Challenge #1: The Great Merge Conflict Saga
&lt;/h2&gt;

&lt;p&gt;One day, as I was diligently working on test cases, I ran into a Git dilemma: my local branch and &lt;code&gt;origin/main&lt;/code&gt; had diverged. I had five commits that &lt;code&gt;origin/main&lt;/code&gt; didn’t, and &lt;code&gt;origin/main&lt;/code&gt; had six that I didn’t. Trying to pull in changes only threw errors at me, and I ended up tangled in a merge conflict jungle. Every time I thought I’d resolved the conflicts, Git had more surprises for me. 😅&lt;/p&gt;

&lt;p&gt;In a moment of pure frustration and humor, I made the infamous commit:&lt;br&gt;
&lt;strong&gt;“added my own mess ups”&lt;/strong&gt; &lt;a href="https://github.com/tasbi03/ReadCraft/commit/6c2c7cadc6e4ae5d7bf1955c82b07054b39951c5" rel="noopener noreferrer"&gt;6c2c7ca&lt;/a&gt; 🙈. This was the ultimate “Oops, I did it again” commit, acknowledging my messy merge attempts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lessons Learned:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Commit thoughtfully&lt;/strong&gt; 📝: I learned the hard way that random commits can lead to chaos if you’re not careful with merging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staying calm with conflicts&lt;/strong&gt; 😌: Working through conflicts became a mini-lesson in version control. I made a mental note to double-check branches in the future!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After what felt like a showdown with Git itself, I resolved the conflicts and moved on.&lt;/p&gt;

&lt;h2&gt;
  
  
  🕹 Mocking LLM Responses: How I Kept My Sanity
&lt;/h2&gt;

&lt;p&gt;Since ReadCraft relies on responses from a large language model, I couldn’t afford to make real API calls in every test. That’s where &lt;strong&gt;pytest-mock&lt;/strong&gt; came to the rescue. I used it to simulate responses from the LLM, ensuring consistent outputs in my tests. By mocking these responses, I was able to check how ReadCraft handled everything from a perfectly formatted response to an empty one.&lt;/p&gt;

&lt;p&gt;Setting up mocks was a game-changer. It allowed me to focus on ReadCraft’s functionality rather than the unpredictability of external API responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Writing the Tests: The "Aha!" Moments
&lt;/h2&gt;

&lt;p&gt;As I wrote tests for each function, I started seeing ReadCraft through a new lens. Testing isn’t just about validation; it’s about defining what each function should do under every circumstance. It led to some pretty satisfying “aha!” moments, like realizing that a function could break if the LLM returned a null response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges Faced:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unintended Errors&lt;/strong&gt;: Testing revealed a few hidden bugs, like formatting issues and the occasional crash when dealing with unexpected data from the LLM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge Cases Galore&lt;/strong&gt;: I uncovered scenarios where ReadCraft didn’t handle empty or malformed responses well, leading to crashes. These insights pushed me to add extra error handling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔥 The Joys of Bug-Hunting
&lt;/h2&gt;

&lt;p&gt;One of my favorite discoveries was an edge case where ReadCraft threw an error if the LLM responded with an empty string. Without testing, I’d never have found this, and it helped me make ReadCraft more robust. With every bug I caught, I felt the project becoming stronger and more reliable. 💪🐞&lt;/p&gt;

&lt;h2&gt;
  
  
  🎉 Final Thoughts: Reflections on Testing
&lt;/h2&gt;

&lt;p&gt;This whole process taught me more than I expected. Testing isn’t just a chore – it’s an exploration of your project’s strengths and weaknesses. Before this, I hadn’t fully appreciated the role of testing in making code resilient, but now I’m a convert. Going forward, I’ll absolutely be adding automated testing to my projects from day one.&lt;/p&gt;

&lt;p&gt;So, if you’re considering adding tests to your project, I say go for it. Dive in with Pytest, learn the ropes of mocking, and don’t be afraid to make mistakes. Each misstep (even those dreaded merge conflicts) is just part of the journey, and in the end, your project will be better for it – and so will you.&lt;/p&gt;

&lt;p&gt;Happy testing! 🚀🌟&lt;/p&gt;

</description>
    </item>
    <item>
      <title>📜 Mastering Code Quality in ReadCraft: Formatting, Linting, and Automation Adventure 🚀</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Sun, 03 Nov 2024 05:14:47 +0000</pubDate>
      <link>https://dev.to/tasbi03/mastering-code-quality-in-readcraft-formatting-linting-and-automation-adventure-27da</link>
      <guid>https://dev.to/tasbi03/mastering-code-quality-in-readcraft-formatting-linting-and-automation-adventure-27da</guid>
      <description>&lt;p&gt;Setting up code quality tools in a project can seem intimidating at first, but I took on the challenge with &lt;em&gt;ReadCraft&lt;/em&gt; and had an awesome experience! In this post, I’ll walk you through the tools I picked, the setup process, and the surprising discoveries along the way. I’ll also share the challenges I faced, including a tricky token usage fix, and how I tackled them. Let’s dive in! 🌊&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Tools of the Trade: Why Black and Flake8?
&lt;/h2&gt;

&lt;p&gt;To maintain clean, readable code, I chose two Python tools that make life a lot easier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/psf/black" rel="noopener noreferrer"&gt;Black&lt;/a&gt;&lt;/strong&gt;: Black is a “no-nonsense” code formatter. It decides on a code style and enforces it every time you run it, so you don’t need to worry about formatting. It’s fast, opinionated, and gives you back time that would have gone into tedious formatting debates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://flake8.pycqa.org/" rel="noopener noreferrer"&gt;Flake8&lt;/a&gt;&lt;/strong&gt;: Flake8 is a linter that spots issues and potential bugs in Python code. Think of it as a super-smart friend who catches mistakes before they become headaches. Flake8 goes through the code, highlights errors, and keeps everything consistent. 🎩&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These tools keep code quality high and avoid cluttering up my code with mistakes or inconsistencies. Want to add these to your project? Here’s how I set them up!&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 The Setup Process: Making Magic Happen ✨
&lt;/h2&gt;

&lt;p&gt;Here’s the step-by-step guide to setting up Black and Flake8 for ReadCraft (or any Python project):&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Configuring Black
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Configuration File&lt;/em&gt;: I created a pyproject.toml file to store Black’s settings. This config file specifies the line length, which Black enforces to keep code easily readable.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Ignore Unwanted Files&lt;/em&gt;: I added a .blackignore file to exclude directories like venv/ and output folders. This way, Black only formats the relevant files and skips unnecessary ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Setting Up Flake8
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Configuration File&lt;/em&gt;: I added a .flake8 file to set up the linter. This config file tells Flake8 which issues to ignore, sets a max line length, and specifies folders to exclude (e.g., .git and virtual environments).&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Running the Linter&lt;/em&gt;: Running flake8 . in the terminal checks all Python files in the current directory, identifying errors and stylistic inconsistencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fixing the Token Usage Issue
&lt;/h3&gt;

&lt;p&gt;While setting up the code, I ran into an interesting problem: I was trying to check token usage directly from the API, but I wasn’t handling it correctly in my code. With some guidance (shoutout to the help I received!), I updated the code to ensure that token usage was only calculated once and displayed correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making it Easy with a Script
&lt;/h3&gt;

&lt;p&gt;To simplify running both tools, I created a shell script format.sh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Run Black only on the main project files&lt;/span&gt;
black readme_generator.py 

&lt;span class="c"&gt;# Run Flake8 for linting&lt;/span&gt;
flake8 &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, with a single ./format.sh command, Black and Flake8 will work their magic on the key project files, keeping everything formatted and linted.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔎 What Did I Find? The Surprising Results! 🤯
&lt;/h2&gt;

&lt;p&gt;After running Black and Flake8, I was impressed—and a little surprised. Here’s what each tool found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Black&lt;/em&gt; made my code look sleek and consistent. It fixed indentation issues and adjusted line lengths, making everything cleaner and more readable.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Flake8&lt;/em&gt; flagged a variety of issues: unused imports, variables assigned but not used, and some style inconsistencies. These are easy to overlook but can create confusion or bugs over time. Fixing these made the code more reliable and professional.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎨 Integrating Tools with VSCode: Making It Seamless
&lt;/h2&gt;

&lt;p&gt;To make sure formatting and linting happen automatically, I set up &lt;em&gt;Visual Studio Code (VSCode)&lt;/em&gt; to handle it as I work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting It Up in VSCode:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Open Project: Open the project in **VSCode&lt;/em&gt; or &lt;em&gt;GitHub Codespaces&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Install Extensions: If prompted, I installed the **Python, **Black Formatter, and **Flake8 Linter&lt;/em&gt; extensions.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Auto-Format on Save&lt;/em&gt;: Black now formats my code every time I save a file.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Real-Time Linting&lt;/em&gt;: Flake8 catches issues as I type, which keeps errors from piling up.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks to .vscode configuration files, any contributor who opens the project in VSCode has the same setup, which keeps everything consistent and easy to manage.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Automating with a Git Pre-Commit Hook
&lt;/h2&gt;

&lt;p&gt;To make sure nothing slips through the cracks, I added a &lt;em&gt;Git pre-commit hook&lt;/em&gt;. This hook automatically runs Black and Flake8 on any files that are about to be committed, ensuring all code is clean and properly formatted before it enters the main branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here’s How I Set Up the Hook:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Create the Hook File&lt;/em&gt;: In .git/hooks/pre-commit, I added the following script:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
   black &lt;span class="nb"&gt;.&lt;/span&gt;
   flake8 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Make It Executable&lt;/em&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;chmod&lt;/span&gt; +x .git/hooks/pre-commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, every time I commit, the hook checks for issues and prevents the commit if it finds any problems. No more accidental formatting errors in the main branch!&lt;/p&gt;




&lt;h2&gt;
  
  
  💥 Challenges Along the Way
&lt;/h2&gt;

&lt;p&gt;Setting everything up wasn’t entirely smooth sailing! Here are some of the challenges I ran into and how I solved them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Ignoring Specific Files&lt;/em&gt;: Initially, Black formatted files in my virtual environment and output folders, which I didn’t want. Adding a .blackignore file solved this.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Configuring Linter Rules&lt;/em&gt;: Flake8 was a bit strict out of the box, flagging a lot of minor issues. I customized the rules in .flake8 to ignore warnings that weren’t relevant to the project.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Token Usage&lt;/em&gt;: I learned that tracking token usage required careful handling in the code, which I updated after receiving help, ensuring the usage was displayed correctly.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📚 Lessons Learned
&lt;/h2&gt;

&lt;p&gt;Working through this setup was a great learning experience, and I took away some key insights:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Automating Quality Checks&lt;/em&gt;: Tools like Black and Flake8 are invaluable for ensuring code quality, but automating them with hooks and editor integration takes it to the next level.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Consistency Is Key&lt;/em&gt;: With Black, my code style is consistent across files and contributors. This saves time on code reviews and keeps everything readable.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Catch Issues Early&lt;/em&gt;: Flake8 flags potential problems as I code, which helps avoid bigger issues down the road.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Setting up tools like Black and Flake8 in ReadCraft has made development more enjoyable and less error-prone. If you’re looking to boost code quality in your project, I highly recommend giving these tools a try. Here’s the &lt;a href="https://github.com/tasbi03/ReadCraft/commit/993019dc78fe6aa16c008d20ba5baab927ffa387" rel="noopener noreferrer"&gt;commit with the full setup&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding! 🎉&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>flake8</category>
      <category>python</category>
      <category>black</category>
    </item>
    <item>
      <title>My Hacktoberfest 2024 Journey: A Month of Code, Growth, and Unforgettable Lessons 🚀</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Fri, 01 Nov 2024 22:02:12 +0000</pubDate>
      <link>https://dev.to/tasbi03/my-hacktoberfest-2024-journey-a-month-of-code-growth-and-unforgettable-lessons-2n8e</link>
      <guid>https://dev.to/tasbi03/my-hacktoberfest-2024-journey-a-month-of-code-growth-and-unforgettable-lessons-2n8e</guid>
      <description>&lt;p&gt;October was a rollercoaster of coding, learning, and (let's be real) the occasional struggle. Hacktoberfest 2024 gave me the perfect chance to jump back into open source, armed with a little more resilience and a lot more experience than last year. Here’s the full recap of my month-long adventure: the issues I tackled, the PRs I (mostly) got accepted, and the invaluable lessons I picked up along the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  First Stop: Security Questions for freeCodeCamp’s Developer Quiz Site 🔐
&lt;/h3&gt;

&lt;p&gt;Let’s kick things off with a bit of a confession—my first pull request on the Developer Quiz Site? Closed. That’s right; midterms got the best of me, and I couldn’t follow through. When I returned to see it had been closed, I felt a pang of regret, but it only made me more determined to succeed this time around.&lt;/p&gt;

&lt;p&gt;Fast-forward to Hacktoberfest 2024, and I came back to freeCodeCamp’s repository, ready to add new security questions on topics like SQL Injection and CSRF. This PR taught me a lot about attention to detail (no duplicates allowed!) and perseverance, especially when I had to work through merge conflicts with recent updates. Lesson learned: balancing life and code is tricky, but I’m here to stick with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Unit Tests to React Chatbotify: A Journey Through Jest 🧪
&lt;/h3&gt;

&lt;p&gt;Next up was &lt;strong&gt;react-chatbotify&lt;/strong&gt;, where I took on the challenge of adding unit tests for the &lt;code&gt;ChatBotButton&lt;/code&gt; component. Testing was new to me, and Jest became both a friend and a formidable challenge. I dug into the tests for the &lt;code&gt;AudioButton&lt;/code&gt; as my guide and wrote tests for rendering, CSS classes, and visibility toggling with React Testing Library.&lt;/p&gt;

&lt;p&gt;This experience showed me the importance of thorough testing and the satisfaction that comes when your code is confidently covered. Oh, and the PR was approved on the first try—win! 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Sprucing Up Terminal Cricket with CLI Flair 🏏️
&lt;/h3&gt;

&lt;p&gt;The third project took me into the world of command-line interfaces with &lt;strong&gt;terminal-cricket&lt;/strong&gt;. My mission? Add a bit of flair to the CLI with animations, loading screens, and structured displays. I added quit functionality and animations to make gameplay more engaging—because who doesn’t want a bit of visual fun in a cricket game?&lt;/p&gt;

&lt;p&gt;This was my chance to dive into ASCII art, experiment with terminal boundaries, and create a more polished, interactive experience for users. Seeing my changes come to life on the screen was incredibly rewarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Predicting the Weather with Python and OpenWeatherMap ☁️
&lt;/h3&gt;

&lt;p&gt;For &lt;strong&gt;100LinesOfPythonCode&lt;/strong&gt;, I created a mini weather app that fetches current weather details using the OpenWeatherMap API. Working on this project taught me the magic of combining Python with APIs, and with a little help from the &lt;code&gt;rich&lt;/code&gt; library, I added some nice terminal styling for better readability.&lt;/p&gt;

&lt;p&gt;This pull request was a straightforward but fulfilling contribution. It was exciting to deliver a functional, visually enhanced tool that users can enjoy right from their terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Long Road with TranspilerX: Floating Action Buttons and Endless Tweaks 😅
&lt;/h3&gt;

&lt;p&gt;Ah, &lt;strong&gt;TranspilerX&lt;/strong&gt;. The project that tested my patience and persistence! My task was to implement a Floating Action Button (FAB) for mobile-friendly actions like clearing the code editor and toggling the theme. It sounded simple, but this one went through multiple iterations.&lt;/p&gt;

&lt;p&gt;The repo owner requested changes, and I submitted updates through PRs 5.1, 5.2, and 5.3, polishing the FAB’s placement, look, and behavior. The owner has been quiet lately, so these PRs are still awaiting review. But hey, even in its unfinished state, I learned a ton about Material UI and responsive design. Here’s hoping for a green light soon!&lt;/p&gt;

&lt;h3&gt;
  
  
  Reflections: From Closed PRs to Growing Confidence
&lt;/h3&gt;

&lt;p&gt;Looking back, Hacktoberfest 2024 pushed me in every way possible. I learned a lot about balancing real-life commitments with coding goals. That closed PR? It taught me resilience. The unit tests? They gave me a new appreciation for code reliability. And the FAB in TranspilerX? Well, it taught me that every feature, no matter how simple it seems, deserves attention to detail.&lt;/p&gt;

&lt;p&gt;This month gave me confidence and confirmed that I’m on the right path. I’ve grown as a coder, problem-solver, and collaborator. Each project pushed my limits, and the feedback I received was instrumental in shaping my skills. Hacktoberfest has been an unforgettable journey—one that I know will fuel my passion for coding for years to come&lt;/p&gt;

&lt;h1&gt;
  
  
  🌟 &lt;strong&gt;See All My Contributions&lt;/strong&gt; 📂
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Want to check out my issues, pull requests, and blogs? Here’s everything I contributed this Hacktoberfest!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  &lt;a href="https://github.com/tasbi03" rel="noopener noreferrer"&gt;Tasbi03&lt;/a&gt; - Tasbi Tasbi
&lt;/h3&gt;


&lt;h4&gt;
  
  
  🐛 &lt;strong&gt;Issues&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/freeCodeCamp/Developer_Quiz_Site/issues/1135" rel="noopener noreferrer"&gt;Issue-1&lt;/a&gt; - freeCodeCamp Developer Quiz Site&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tjtanjin/react-chatbotify/issues/145" rel="noopener noreferrer"&gt;Issue-2&lt;/a&gt; - React Chatbotify&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/EzazAA/terminal-cricket/issues/1" rel="noopener noreferrer"&gt;Issue-3&lt;/a&gt; - Terminal Cricket&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/issues/13" rel="noopener noreferrer"&gt;Issue-4&lt;/a&gt; - 100LinesOfPythonCode&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aayushai/TranspilerX/issues/19" rel="noopener noreferrer"&gt;Issue-5&lt;/a&gt; - TranspilerX&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;
  
  
  🚀 &lt;strong&gt;Pull Requests&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/freeCodeCamp/Developer_Quiz_Site/pull/1140" rel="noopener noreferrer"&gt;Pull Request-1&lt;/a&gt; - freeCodeCamp Developer Quiz Site&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tjtanjin/react-chatbotify/pull/179" rel="noopener noreferrer"&gt;Pull Request-2&lt;/a&gt; - React Chatbotify&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/EzazAA/terminal-cricket/pull/2" rel="noopener noreferrer"&gt;Pull Request-3&lt;/a&gt; - Terminal Cricket&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/pull/18" rel="noopener noreferrer"&gt;Pull Request-4&lt;/a&gt; - 100LinesOfPythonCode&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aayushai/TranspilerX/pull/50" rel="noopener noreferrer"&gt;Pull Request-5.1&lt;/a&gt; - TranspilerX&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aayushai/TranspilerX/pull/51" rel="noopener noreferrer"&gt;Pull Request-5.2&lt;/a&gt; - TranspilerX&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aayushai/TranspilerX/pull/52" rel="noopener noreferrer"&gt;Pull Request-5.3&lt;/a&gt; - TranspilerX&lt;/li&gt;
&lt;/ol&gt;


&lt;h4&gt;
  
  
  ✍️ &lt;strong&gt;Blog Posts&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tasbi03/my-hacktoberfest-adventure-contributing-to-freecodecamps-developer-quiz-site-2086"&gt;Blog Post-1&lt;/a&gt; - My Hacktoberfest Adventure: Contributing to freeCodeCamp's Developer Quiz Site&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tasbi03/my-second-hacktoberfest-adventure-testing-with-jest-for-the-first-time-1ban"&gt;Blog Post-2&lt;/a&gt; - My Second Hacktoberfest Adventure: Testing with Jest for the First Time&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tasbi03/my-hacktoberfest-journey-redeeming-myself-and-waiting-for-the-green-light-k75"&gt;Blog Post-3&lt;/a&gt; - My Hacktoberfest Journey: Redeeming Myself and Waiting for the Green Light&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tasbi03/hacktoberfest-adventure-adding-weather-magic-to-100linesofpythoncode-2m0f"&gt;Blog Post-4&lt;/a&gt; - Hacktoberfest Adventure: Adding Weather Magic to 100LinesOfPythonCode&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tasbi03/my-hacktoberfest-adventure-wrestling-with-javascript-and-the-elusive-green-light-l3n"&gt;Blog Post-5&lt;/a&gt; - My Hacktoberfest Adventure: Wrestling with JavaScript and the Elusive Green Light&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Hacktoberfest 2024 may be over, but this experience will stay with me as a reminder of how much you can accomplish when you embrace the journey. Here’s to more open-source adventures ahead! 🎉&lt;/p&gt;

</description>
      <category>hacktoberfest</category>
      <category>javascript</category>
      <category>python</category>
      <category>opensource</category>
    </item>
    <item>
      <title>My Hacktoberfest Adventure: Wrestling with JavaScript and the Elusive Green Light 🚥</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Sat, 26 Oct 2024 04:59:39 +0000</pubDate>
      <link>https://dev.to/tasbi03/my-hacktoberfest-adventure-wrestling-with-javascript-and-the-elusive-green-light-l3n</link>
      <guid>https://dev.to/tasbi03/my-hacktoberfest-adventure-wrestling-with-javascript-and-the-elusive-green-light-l3n</guid>
      <description>&lt;p&gt;After three successful pull requests, I thought I had the hang of this whole Hacktoberfest thing. Find a repo, make changes, open a PR, and bask in the glow of contributions. Easy, right? Well, my fourth pull request decided to teach me a lesson in patience and perseverance. And it came with an unexpected twist: JavaScript. 🤯&lt;/p&gt;

&lt;p&gt;The journey began when I found &lt;a href="https://github.com/aayushai/TranspilerX/issues/19" rel="noopener noreferrer"&gt;issue #19&lt;/a&gt; on the TranspilerX repository. The task seemed straightforward: add a clear button to a code editor and create a mobile-friendly action button with multiple options. "How hard could it be?" I thought. Spoiler alert: way harder than I expected. 😅&lt;/p&gt;

&lt;h3&gt;
  
  
  Diving into the Code 🧩
&lt;/h3&gt;

&lt;p&gt;First, I had to understand the existing code—which felt like stepping into a giant maze filled with traps labeled "JavaScript Errors." I spent &lt;em&gt;hours&lt;/em&gt; trying to figure out how everything fit together. There were React components, a bunch of unfamiliar libraries, and a sea of state variables. The first time I saw the &lt;code&gt;useEffect&lt;/code&gt; hook, I genuinely thought my brain might explode. 💥 But after some trial and error (mostly error), I started to get it.&lt;/p&gt;

&lt;p&gt;This was my first time working with JavaScript in this capacity as before in my second hactoberfest PR I did testing using jest which was harder, using javascript is not harder but looking at code of lines of 500 in each file is way more harder, and honestly, it was like trying to cook a gourmet meal without knowing how to turn on the stove. Every time I tried to add something, &lt;em&gt;BOOM&lt;/em&gt; – another error. A missing import here, an undefined function there, or my personal favorite: "unexpected token." 😩 It took a lot of Stack Overflow, Googling, and coffee to get through it. ☕&lt;/p&gt;

&lt;h3&gt;
  
  
  Finally Making It Work 🎉
&lt;/h3&gt;

&lt;p&gt;After what felt like ages wrestling with the code, I finally got the functionality working. I added a clear button that sits perfectly between the language selector and the copy button on the web view. I even managed to add a SpeedDial button for the mobile view that pops open with the actions you need—clear the code, copy it, and switch the theme. The satisfaction I felt when it actually worked was unreal. I did a little victory dance, and yes, it was terrible. 💃🕺&lt;/p&gt;

&lt;p&gt;I was ready to ride the wave of success. I opened &lt;a href="https://github.com/aayushai/TranspilerX/pull/50" rel="noopener noreferrer"&gt;PR #50&lt;/a&gt;, expecting the next part to be smooth sailing. But oh no—Vercel had other plans. Since the repo is under someone else’s account, my deployment needs to be authorized before it goes live. So now I’m waiting for a reply from the project maintainer, hoping they approve it and give me that sweet, sweet green check mark. ✅&lt;/p&gt;

&lt;h3&gt;
  
  
  The Hacktoberfest Struggle 🤹‍♀️
&lt;/h3&gt;

&lt;p&gt;If you've ever done Hacktoberfest, you know that finding good repos can be like finding a needle in a haystack. I wanted projects that were challenging but also interesting—ones that pushed me to learn. But that’s a tough balance! I looked through countless issues, often finding ones that were either too simple or way beyond my skill level. It’s a weird feeling, right? You're either a coding wizard or a clueless muggle, sometimes both within the span of five minutes. 🧙‍♂️🤦‍♀️&lt;/p&gt;

&lt;p&gt;This pull request was definitely my most challenging so far and you may thing that I just added 40 lines into my code and I am making so much fuss about it but remember when working on some else code is really difficult, it may look like a small thing to add but understanding what you are doing and getting accepted what you have done is most important. Hacktoberfest isn't just about getting t-shirts or badges; it’s about learning, growing, and figuring out how to solve problems. Sometimes, the most rewarding part isn’t the green check mark on your PR—it’s the journey that gets you there (though I’d still very much like that green check mark, please). 😜&lt;/p&gt;

&lt;h3&gt;
  
  
  Waiting for the Green Light 🚦
&lt;/h3&gt;

&lt;p&gt;So here I am, four pull requests in, with three accepted and one pending review. I’m learning the art of waiting (and how to spell "origin" correctly—long story, don’t ask). This experience has shown me that open source contributions aren’t always instant gratification. Sometimes you have to be patient, persistent, and enjoy the process—even if it involves a lot of debugging and talking to your computer like it’s a person. 🤖💬&lt;/p&gt;

&lt;p&gt;If you’re also on your Hacktoberfest journey, just know that every mistake is a step forward, and every success is a celebration—no matter how small. I hope my next post is about that beautiful green light on my PR, but until then, I’ll keep exploring, learning, and adding value, one error message at a time. 🚀&lt;/p&gt;

&lt;p&gt;Check out my first Hacktoberfest story here: &lt;a href="https://dev.to/tasbi03/my-hacktoberfest-journey-redeeming-myself-and-waiting-for-the-green-light-k75"&gt;My Hacktoberfest Journey - Redeeming Myself and Waiting for the Green Light&lt;/a&gt;. And wish me luck for my fourth pull request getting accepted! 🍀&lt;/p&gt;

&lt;p&gt;Happy coding! 💻&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Hacktoberfest Adventure: Adding Weather Magic to 100LinesOfPythonCode 🌦️✨</title>
      <dc:creator>Tasbi Tasbi </dc:creator>
      <pubDate>Wed, 23 Oct 2024 23:26:01 +0000</pubDate>
      <link>https://dev.to/tasbi03/hacktoberfest-adventure-adding-weather-magic-to-100linesofpythoncode-2m0f</link>
      <guid>https://dev.to/tasbi03/hacktoberfest-adventure-adding-weather-magic-to-100linesofpythoncode-2m0f</guid>
      <description>&lt;p&gt;Hey everyone! 👋&lt;/p&gt;

&lt;p&gt;I just wrapped up my &lt;strong&gt;fourth Pull Request&lt;/strong&gt; for Hacktoberfest 2024, and it’s been such a rewarding experience. This time, I tackled an issue in the &lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/issues/13" rel="noopener noreferrer"&gt;100LinesOfPythonCode repo&lt;/a&gt;, where I added a &lt;strong&gt;Weather App&lt;/strong&gt; that pulls in today’s forecast using the OpenWeatherMap API. Let me take you through my journey of coding, challenges, and fun.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌤️ The Weather App PR
&lt;/h3&gt;

&lt;p&gt;The goal was pretty straightforward: create a Python app that fetches weather information using an API. This is now live in the pull request &lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/pull/18" rel="noopener noreferrer"&gt;#18&lt;/a&gt;. It’s not just your regular weather app, though! I spiced things up by using the &lt;strong&gt;&lt;code&gt;rich&lt;/code&gt;&lt;/strong&gt; library to make the terminal output look fabulous—complete with colored tables and loading animations. After all, why settle for boring text when you can make it beautiful, right? 😉&lt;/p&gt;

&lt;p&gt;This PR adds the ability to get today’s forecast by simply entering the city name. I also made sure the data gets saved to a local JSON file so you can revisit it later. It’s a fun little project that really showcases how much visual polish matters, even in CLI apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  🌀 The "Challenges" (A.K.A. The Hard Parts)
&lt;/h3&gt;

&lt;p&gt;This project wasn't without its tricky moments. One of the hardest parts was handling &lt;strong&gt;asynchronous API data fetching&lt;/strong&gt; while maintaining a clean and user-friendly terminal output. Managing the response timing with the loading animation needed careful tweaking, especially to avoid unnecessary delays while still making the user feel like the data-fetching process was smooth. Getting the balance between user engagement and efficiency was a real challenge.&lt;/p&gt;

&lt;p&gt;Lastly, keeping my &lt;strong&gt;fork up-to-date&lt;/strong&gt; was tricky because the owner kept making changes to the main branch. I had to frequently merge upstream changes into my working branch to avoid conflicts. This was a great learning experience in managing merge conflicts and maintaining a clean history, but it certainly added some complexity!&lt;/p&gt;

&lt;h3&gt;
  
  
  🚦 PR Waiting Game: My Third Hacktoberfest PR
&lt;/h3&gt;

&lt;p&gt;My &lt;strong&gt;third Hacktoberfest PR&lt;/strong&gt; was a bit of a waiting game. I was working on the &lt;a href="https://github.com/EzazAA/terminal-cricket/pulls" rel="noopener noreferrer"&gt;Terminal Cricket Game&lt;/a&gt;, where I added core features and improved the terminal experience. The owner asked me to make changes in the &lt;strong&gt;root directory&lt;/strong&gt;, and since then, I've been waiting for a response. It's part of the Hacktoberfest adventure—the thrill of coding, submitting, and waiting for that sweet, sweet "merged" notification. 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  🌈 Lessons Learned
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Presentation Matters&lt;/strong&gt;: It’s not just about the data; it’s about how you present it. The &lt;code&gt;rich&lt;/code&gt; library really helped me take this weather app from "meh" to "wow!".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep Your Fork Updated&lt;/strong&gt;: The owner made some changes while I was working on my fork, so I had to frequently pull from the upstream to stay synced. It’s a good habit to learn when contributing to open source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence is Key&lt;/strong&gt;: Waiting for a PR to be reviewed can feel like forever, but staying engaged and being patient is all part of the experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  🚀 What’s Next?
&lt;/h3&gt;

&lt;p&gt;I’ve got a few more PRs to go for Hacktoberfest, and I’m looking for even more exciting issues to tackle. If you have any suggestions or projects, drop them in the comments below! I’m loving this journey so far, and can’t wait to see what else I can contribute to.&lt;/p&gt;

&lt;p&gt;Until next time, stay curious and keep coding! 🌟&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sumanth-0/100LinesOfPythonCode/pull/18" rel="noopener noreferrer"&gt;Check out my Weather App PR here&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://dev.to/tasbi03"&gt;Follow my Hacktoberfest journey on DEV&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
