<?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: Ashan_Dev</title>
    <description>The latest articles on DEV Community by Ashan_Dev (@itxashancode).</description>
    <link>https://dev.to/itxashancode</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%2F3805543%2F94c4e4f9-f52f-4d60-8cff-8e66d793256b.png</url>
      <title>DEV Community: Ashan_Dev</title>
      <link>https://dev.to/itxashancode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itxashancode"/>
    <language>en</language>
    <item>
      <title>UnProductive™: An Enterprise Dashboard for Accomplishing Absolutely Nothing</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Wed, 08 Apr 2026 17:22:14 +0000</pubDate>
      <link>https://dev.to/itxashancode/unproductive-an-enterprise-dashboard-for-accomplishing-absolutely-nothing-1d99</link>
      <guid>https://dev.to/itxashancode/unproductive-an-enterprise-dashboard-for-accomplishing-absolutely-nothing-1d99</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aprilfools-2026"&gt;DEV April Fools Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;UnProductive™ — The Anti-Productivity Suite.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A full bento-grid dashboard that looks like a legitimate SaaS product at first glance. Dark background, sidebar nav, real-time clock, progress charts, an AI advisor, a terminal. Everything a productivity app needs.&lt;/p&gt;

&lt;p&gt;Except every single feature is engineered to fail, flee, gaslight, or accomplish nothing whatsoever.&lt;/p&gt;

&lt;p&gt;Here's what's inside:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Evasive Button&lt;/strong&gt; — A box labeled "Important Decision Matrix" with a button that says "Acknowledge." It physically runs away when your cursor gets within 110px of it. If you actually manage to click it, the response is: &lt;em&gt;"Click registered. Action: none. You are welcome."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thought Shredder&lt;/strong&gt; — Type your billion-dollar idea. While you type, it randomly scrambles your characters and injects glitch symbols. Hit Obliterate and the text corrupts into garbage on-screen before disappearing to &lt;code&gt;/dev/null/forever&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UnProductive AI™&lt;/strong&gt; — Consults "The Oracle." The advice includes things like &lt;em&gt;"Analysis complete. You are 97% procrastination, 2% good intentions, 1% cached regret."&lt;/em&gt; and &lt;em&gt;"ERROR 418: Goal detected. Initiating avoidance protocol."&lt;/em&gt; Response accuracy: 0%. Powered by 0 neurons and pure vibes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibe Check Terminal&lt;/strong&gt; — A fake terminal with real commands. Run &lt;code&gt;npm install&lt;/code&gt; and it adds 9,847 packages with 12,674 vulnerabilities. Three of them are sentient. Run &lt;code&gt;git blame&lt;/code&gt; and it just says &lt;em&gt;"you did this."&lt;/em&gt; Try to &lt;code&gt;exit&lt;/code&gt; and it tells you the void doesn't have a door.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Anti-Ledger&lt;/strong&gt; — A to-do list. Click any item and it shakes, denies your access, and changes the status to "ACCESS DENIED." The task label gets a strikethrough. You did not complete it. You were rejected by it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chaos Clock&lt;/strong&gt; — Keeps time, mostly. 10% of the time it steps backwards. 12% of the time it jumps several hours in either direction with a color flash and a CSS skew. Feels eerily plausible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Productivity Donut&lt;/strong&gt; — Animates up to 99% with great confidence, then immediately crashes to 0% and fires a toast: &lt;em&gt;"Productivity peaked at 99%. System reset to preserve institutional standards."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gaslight Toasts&lt;/strong&gt; — Random notifications every 7–21 seconds. &lt;em&gt;"You blinked 5 times. Recommended: 3. Please calibrate."&lt;/em&gt; and &lt;em&gt;"Your cursor is moving at an unsustainable velocity."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synergy Optimizer Modal&lt;/strong&gt; — Full-screen takeover with a spinner and a progress bar permanently stuck at 99%. The Cancel button runs away from your cursor. Auto-dismisses after 28 seconds with: &lt;em&gt;"Results: statistically indistinguishable from before."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FIX UI Button&lt;/strong&gt; — Hue-rotates the page, mirrors it, rotates it slightly, or removes all color. Always reverts. Never fixes anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Daily Motivation Engine™&lt;/strong&gt; — Cycles through quotes like &lt;em&gt;"Every expert was once a beginner who gave up and rebranded as a consultant."&lt;/em&gt; and &lt;em&gt;"A plan without execution is a very impressive document."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Developer's Confession&lt;/strong&gt; — A "CLASSIFIED" section leaked as evidence that I have, outside of UnProductive™ hours, been observed writing real software. Links to my actual GitHub automation repos under a redacted watermark. The irony is intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://devaprilfoolschallenge.vercel.app/" rel="noopener noreferrer"&gt;devaprilfoolschallenge.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For the full experience, try these in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try to click the "Acknowledge" button&lt;/li&gt;
&lt;li&gt;Type something important into the Thought Shredder, then hit Obliterate&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;git blame&lt;/code&gt; in the Vibe Terminal&lt;/li&gt;
&lt;li&gt;Click "Run AI Optimizer" and try to cancel it&lt;/li&gt;
&lt;li&gt;Press FIX UI a few times&lt;/li&gt;
&lt;li&gt;Just... wait for a gaslight toast&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/itxashancode" rel="noopener noreferrer"&gt;
        itxashancode
      &lt;/a&gt; / &lt;a href="https://github.com/itxashancode/DEV-April-Fools-Challenge" rel="noopener noreferrer"&gt;
        DEV-April-Fools-Challenge
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Vanilla HTML, CSS, and JavaScript. No framework. Intentionally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three.js&lt;/strong&gt; for two things: a background particle field (2,200 points in acid/magenta/cyan pulled by the mouse), and the entropy visualizer widget which renders a wireframe torus knot that randomly glitches its scale, position, and color.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tailwind&lt;/strong&gt; (CDN) for layout. The bento grid is a 12-column CSS grid with span classes per widget — &lt;code&gt;w1&lt;/code&gt; through &lt;code&gt;w9&lt;/code&gt;, full-width for the GitHub confession section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 3D card tilt&lt;/strong&gt; on hover uses CSS custom properties set by &lt;code&gt;mousemove&lt;/code&gt; on each widget:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--local-mouse-x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--local-mouse-y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then consumed in CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.widget&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;perspective&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;900px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="n"&gt;rotateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--local-mouse-y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;-12deg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
             &lt;span class="n"&gt;rotateY&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--local-mouse-x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;12deg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
             &lt;span class="n"&gt;translateZ&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20px&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;No JS touches the transform. Keeps it smooth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The evasive button logic&lt;/strong&gt; (used in both the Acknowledge button and the Synergy Cancel button) tracks mouse distance to the button center and randomizes &lt;code&gt;top&lt;/code&gt;/&lt;code&gt;left&lt;/code&gt; within the parent's bounding rect if you get too close:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hypot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientX&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;maxY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;maxX&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&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;&lt;strong&gt;The noise overlay&lt;/strong&gt; is a single &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; with an SVG &lt;code&gt;feTurbulence&lt;/code&gt; filter tiled over the whole page at 4% opacity with &lt;code&gt;mix-blend-mode: overlay&lt;/code&gt;. Basically free performance-wise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Chaos Clock&lt;/strong&gt; has weighted randomness — most ticks advance normally, 10% go backwards, 12% jump by up to ±10 hours with a visual flash. Random clocks tend to feel too chaotic; weighted behavior makes it feel almost plausible until it isn't.&lt;/p&gt;

&lt;p&gt;Fonts: &lt;strong&gt;Space Mono&lt;/strong&gt; for the monospace/terminal aesthetic, &lt;strong&gt;Playfair Display&lt;/strong&gt; for the big italic headings. The contrast between them does a lot of work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Ode to Larry Masinter&lt;/strong&gt; — the HTTP 418 easter egg is hardcoded in the AI advisor responses (&lt;em&gt;"ERROR 418: Goal detected. Initiating avoidance protocol."&lt;/em&gt;), the project name gestures at RFC 2324's whole ethos, and the entire thing is built on the premise that software can be technically correct and completely useless. That feels like the spirit of the teapot to me.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built by &lt;a href="https://dev.to/itxashancode"&gt;@itxashancode&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>418challenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>I built a bot that answers GitHub Discussions using free AI models — here's what I learned</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Wed, 08 Apr 2026 13:16:48 +0000</pubDate>
      <link>https://dev.to/itxashancode/i-built-a-bot-that-answers-github-discussions-using-free-ai-models-heres-what-i-learned-35lb</link>
      <guid>https://dev.to/itxashancode/i-built-a-bot-that-answers-github-discussions-using-free-ai-models-heres-what-i-learned-35lb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Heads up:&lt;/strong&gt; This is an educational project. The bot can post to GitHub Discussions, which means you need to use it carefully. I'll cover what responsible use looks like at the end.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;A few months ago I wanted to get GitHub's &lt;a href="https://docs.github.com/en/discussions/guides/finding-your-discussions" rel="noopener noreferrer"&gt;Galaxy Brain badge&lt;/a&gt; — the one you earn by getting answers marked as Accepted in Discussions. I figured automating the search part would be interesting. Finding relevant open questions manually is genuinely tedious.&lt;/p&gt;

&lt;p&gt;What started as a script to find unanswered threads turned into a project I actually care about. Not because of the badge, but because of the infrastructure problems it forced me to solve.&lt;/p&gt;

&lt;p&gt;Here's what's in the codebase and what I learned building each piece.&lt;/p&gt;




&lt;h2&gt;
  
  
  The basic idea
&lt;/h2&gt;

&lt;p&gt;The bot does four things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Discovers GitHub repos that have Discussions enabled, filtered by topic tags and star count&lt;/li&gt;
&lt;li&gt;Fetches open, unanswered Discussion threads from those repos&lt;/li&gt;
&lt;li&gt;Sends the question to a free LLM via OpenRouter and gets an answer&lt;/li&gt;
&lt;li&gt;Optionally posts that answer (with your confirmation, by default)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of that is complicated. The interesting problems came from making it reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 1: Free LLM models are flaky
&lt;/h2&gt;

&lt;p&gt;OpenRouter's free tier is great — 18+ models, no billing required. The catch is availability. A model that worked yesterday might 404 today. A model that worked an hour ago might be rate-limited now.&lt;/p&gt;

&lt;p&gt;My first version just tried one model and crashed when it failed. The fix was a rotation list:&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="n"&gt;_DEFAULT_MODELS&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;qwen/qwen3.6-plus:free&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;stepfun/step-3.5-flash:free&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;nvidia/nemotron-3-super-120b-a12b:free&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;meta-llama/llama-3.3-70b-instruct:free&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;google/gemma-3-27b-it:free&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;# ... 13 more
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The bot tries them in order. If a model returns an empty response, a 404, or a 429, it logs the failure and moves to the next one. At session end, &lt;code&gt;--models&lt;/code&gt; shows a table of which models succeeded, failed, and how fast they were.&lt;/p&gt;

&lt;p&gt;One thing I noticed: "success" and "quality" are different. A model can return a response that passes all the checks but still gives a generic non-answer. The answer length filter (&lt;code&gt;ANSWER_MIN_CHARS&lt;/code&gt;, &lt;code&gt;ANSWER_MAX_CHARS&lt;/code&gt;) catches the worst cases, but it doesn't catch confident-sounding garbage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 2: Retrying the wrong way
&lt;/h2&gt;

&lt;p&gt;Before adding proper backoff, the bot would hit a rate limit and immediately retry. Then retry again. Then again. GitHub's API would respond with &lt;code&gt;429&lt;/code&gt; for the rest of the session.&lt;/p&gt;

&lt;p&gt;The fix was reading &lt;code&gt;Retry-After&lt;/code&gt; headers:&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="n"&gt;retry_after&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retry-After&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RATE_LIMIT_RETRY_AFTER_DEFAULT&lt;/span&gt;&lt;span class="p"&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;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retry_after&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub is inconsistent about including that header. When it's missing, the bot falls back to exponential delay. It's not perfect, but it's miles better than hammering an endpoint that's already telling you to stop.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 3: One bad endpoint killing the whole session
&lt;/h2&gt;

&lt;p&gt;This took me a while to notice. If a particular GraphQL query started timing out — say, because a repo was unusually large — the bot would retry it over and over, spending most of the session waiting.&lt;/p&gt;

&lt;p&gt;Circuit breakers solve this. After a configurable number of consecutive failures, the circuit "opens" and blocks further requests to that endpoint for a timeout period. Then it half-opens: one probe request goes through. If that succeeds, the circuit closes again.&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CircuitBreaker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;CLOSED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;closed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;OPEN&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;HALF&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;half_open&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;120&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;state&lt;/span&gt;    &lt;span class="o"&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;CLOSED&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;failures&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;opened_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The effect in practice: the bot now skips broken endpoints and moves to the next repo in the list, instead of getting stuck.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 4: Ctrl+C corrupting the stats file
&lt;/h2&gt;

&lt;p&gt;The stats file (&lt;code&gt;galaxy_brain_stats.json&lt;/code&gt;) gets written at the end of each session. If you hit Ctrl+C mid-write, you get a partial JSON file, which breaks the next session.&lt;/p&gt;

&lt;p&gt;The fix was a &lt;code&gt;ShutdownHandler&lt;/code&gt; that catches SIGINT/SIGTERM and sets a flag:&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ShutdownHandler&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;__init__&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_shutdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
        &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SIGINT&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;_handle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SIGTERM&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;_handle&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;_handle&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&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="n"&gt;_shutdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;requested&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="k"&gt;return&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;_shutdown&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every loop in the bot checks &lt;code&gt;shutdown.requested&lt;/code&gt; before its next iteration. Ctrl+C finishes the current task cleanly, then exits. The stats file always gets written to disk before the process ends.&lt;/p&gt;




&lt;h2&gt;
  
  
  What else is in there
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In-memory TTL cache.&lt;/strong&gt; Avoids re-fetching the same GraphQL results within a session. Default TTL is 5 minutes. When you're processing 50 repos, this matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-modal support.&lt;/strong&gt; If a Discussion post contains images and the selected model supports vision, the bot fetches the images and includes them in the prompt. Same for external links — it fetches the page content and appends it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key rotation.&lt;/strong&gt; You can put multiple OpenRouter API keys in &lt;code&gt;.env&lt;/code&gt;, comma-separated. When one hits its rate limit, the bot rotates to the next.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Webhook notifications.&lt;/strong&gt; Discord and Slack. Sends an alert when an answer gets accepted, and a summary at the end of each session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stats by org.&lt;/strong&gt; Breaks down your answer history by repository owner. Useful for seeing which communities you've been most active in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting it up
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/YOUR_USERNAME/galaxy-brain-bot.git
&lt;span class="nb"&gt;cd &lt;/span&gt;galaxy-brain-bot
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.template .env
&lt;span class="c"&gt;# Fill in GITHUB_TOKEN, GITHUB_USERNAME, OPENROUTER_KEYS&lt;/span&gt;
python test_bot.py  &lt;span class="c"&gt;# run this before anything else&lt;/span&gt;
python galaxy_brain_bot.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test suite checks all your credentials and API connections before you run the main bot. Run it first.&lt;/p&gt;

&lt;p&gt;By default, the bot asks for confirmation before posting each answer (&lt;code&gt;AUTO_APPROVE_ANSWERS=false&lt;/code&gt;). Keep it that way until you've seen a few answers and trust the output quality on the repos you're targeting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Responsible use
&lt;/h2&gt;

&lt;p&gt;A few things I want to say directly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't run it unsupervised at scale.&lt;/strong&gt; The &lt;code&gt;MAX_ANSWERS_PER_SESSION&lt;/code&gt; setting exists for a reason. Posting 50 answers in an hour is a good way to get flagged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read the answers before posting.&lt;/strong&gt; LLMs are wrong sometimes. Posting a confident wrong answer in a GitHub Discussion is worse than posting nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check the repo's rules.&lt;/strong&gt; Some repos have Codes of Conduct that explicitly restrict automated participation. The bot tries to detect this, but it can miss things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's a research tool, not a farming tool.&lt;/strong&gt; The badge is a byproduct. If you're using this to post low-effort answers at volume, you're not using it for what it was built for.&lt;/p&gt;




&lt;h2&gt;
  
  
  Source code
&lt;/h2&gt;

&lt;p&gt;Full source, setup instructions, and config reference: &lt;a href="https://github.com/itxashancode/Galaxy-Brain-Automation" rel="noopener noreferrer"&gt;https://github.com/itxashancode/Galaxy-Brain-Automation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The whole thing is one Python file (&lt;code&gt;galaxy_brain_bot.py&lt;/code&gt;) plus a test suite. No frameworks, no magic — just &lt;code&gt;requests&lt;/code&gt;, &lt;code&gt;rich&lt;/code&gt; for the terminal UI, and &lt;code&gt;python-dotenv&lt;/code&gt;. If you want to understand a specific piece, it's all in one place.&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments. If you spot something in the circuit breaker or backoff logic that could be better, I'm genuinely interested.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for learning. MIT licensed.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>github</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🏥 gh-repo-health: Check Your GitHub Repo's Health Score in Seconds</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Thu, 19 Mar 2026 03:56:43 +0000</pubDate>
      <link>https://dev.to/itxashancode/gh-repo-health-check-your-github-repos-health-score-in-seconds-2bon</link>
      <guid>https://dev.to/itxashancode/gh-repo-health-check-your-github-repos-health-score-in-seconds-2bon</guid>
      <description>&lt;p&gt;Have you ever opened a GitHub repo and wondered &lt;em&gt;"is this project actually maintained?"&lt;/em&gt; — or pushed your own project and asked &lt;em&gt;"does this even look professional?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I asked myself the same questions. So I built &lt;strong&gt;&lt;code&gt;gh-repo-health&lt;/code&gt;&lt;/strong&gt; — a CLI tool that audits any GitHub repository and gives it a health score based on community standards.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Why I Built This
&lt;/h2&gt;

&lt;p&gt;When I was exploring open source projects to contribute to, I kept manually checking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does it have a &lt;strong&gt;README&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Is there a &lt;strong&gt;CONTRIBUTING&lt;/strong&gt; guide?&lt;/li&gt;
&lt;li&gt;Any &lt;strong&gt;issue templates&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;LICENSE&lt;/strong&gt; file?&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;CODE_OF_CONDUCT&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing this for every repo was exhausting. I wanted a single command that tells me everything at once.&lt;/p&gt;

&lt;p&gt;So I built &lt;code&gt;gh-repo-health&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ What It Does
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gh-repo-health&lt;/code&gt; scans any public GitHub repository and checks for key community health files:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Why It Matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;README.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;First impression — does the project explain itself?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LICENSE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Legal clarity for contributors and users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CONTRIBUTING.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Guides new contributors on how to help&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODE_OF_CONDUCT.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets community standards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SECURITY.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Responsible disclosure for vulnerabilities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Issue Templates&lt;/td&gt;
&lt;td&gt;Structured bug reports and feature requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pull Request Template&lt;/td&gt;
&lt;td&gt;Consistent PR process&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each check passes or fails, and you get an overall &lt;strong&gt;health score&lt;/strong&gt; at the end.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;p&gt;Clone the repo and run it against any GitHub repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/itxashancode/gh-repo-health
&lt;span class="nb"&gt;cd &lt;/span&gt;gh-repo-health
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then audit any repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python main.py itxashancode/Pull-Shark-Automation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll get output like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ README.md          found
✅ LICENSE            found
❌ CONTRIBUTING.md    missing
❌ CODE_OF_CONDUCT    missing
✅ Issue Templates    found
❌ SECURITY.md        missing
❌ PR Template        missing

Health Score: 43% — Needs Improvement
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ How It Works
&lt;/h2&gt;

&lt;p&gt;The tool uses the &lt;strong&gt;GitHub REST API&lt;/strong&gt; to check for the existence of community health files. No cloning required — it's all API calls.&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;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filepath&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.github.com/repos/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/contents/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It checks common file locations — root, &lt;code&gt;.github/&lt;/code&gt;, and &lt;code&gt;docs/&lt;/code&gt; — so it doesn't miss files tucked in subdirectories.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What I Learned Building This
&lt;/h2&gt;

&lt;p&gt;This was one of my early Python projects, and it taught me a lot:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;GitHub's API is incredibly powerful&lt;/strong&gt; — you can inspect almost anything about a repo without cloning it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community health files genuinely matter&lt;/strong&gt; — repos with them get more contributions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI tools are satisfying to build&lt;/strong&gt; — instant feedback, no UI needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling is critical&lt;/strong&gt; — private repos, rate limits, and missing tokens all need to be handled gracefully&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🔮 What's Next
&lt;/h2&gt;

&lt;p&gt;I'm planning to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;strong&gt;Badge generation&lt;/strong&gt; — embed a health score badge in your README&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;Batch scanning&lt;/strong&gt; — audit all repos in an organization at once&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;GitHub Actions integration&lt;/strong&gt; — fail CI if health score drops below a threshold&lt;/li&gt;
&lt;li&gt;[ ] &lt;strong&gt;JSON output&lt;/strong&gt; — for piping results into other tools&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌟 Try It on Your Own Repo
&lt;/h2&gt;

&lt;p&gt;Run &lt;code&gt;gh-repo-health&lt;/code&gt; against your own projects. You might be surprised what's missing!&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/itxashancode/gh-repo-health" rel="noopener noreferrer"&gt;GitHub: itxashancode/gh-repo-health&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, drop a ⭐ on the repo — it genuinely motivates me to keep building.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Ashan, an APTECH student from Karachi building GitHub automation tools and learning in public. If you have ideas for features, drop them in the comments below — I read every one! 👇&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>python</category>
      <category>devtools</category>
    </item>
    <item>
      <title>🎮 What I Learned Building a Minecraft Voting Portal with Pure HTML, CSS &amp; JS (No Frameworks!)</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Sun, 15 Mar 2026 01:50:54 +0000</pubDate>
      <link>https://dev.to/itxashancode/what-i-learned-building-a-minecraft-voting-portal-with-pure-html-css-js-no-frameworks-li1</link>
      <guid>https://dev.to/itxashancode/what-i-learned-building-a-minecraft-voting-portal-with-pure-html-css-js-no-frameworks-li1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I'm a student developer from Karachi, Pakistan 🇵🇰 — studying at APTECH and building real projects to level up my skills. This one started as a fun side project for a Minecraft server community called &lt;strong&gt;HustlersMC&lt;/strong&gt; and turned into one of the biggest learning experiences of my journey so far.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;No React. No Vue. No Tailwind. Just &lt;strong&gt;pure HTML, CSS, and JavaScript&lt;/strong&gt; — and way more depth than I expected.&lt;/p&gt;

&lt;p&gt;Here's everything I genuinely learned. 👇&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Why Build a Voting Portal?
&lt;/h2&gt;

&lt;p&gt;Minecraft servers live and die by their ranking on voting sites like &lt;a href="https://www.planetminecraft.com/" rel="noopener noreferrer"&gt;Planet Minecraft&lt;/a&gt; and &lt;a href="https://minecraft-server-list.com/" rel="noopener noreferrer"&gt;Minecraft Server List&lt;/a&gt;. The more players vote, the higher the server ranks, the more new players join.&lt;/p&gt;

&lt;p&gt;Most voting portals out there are &lt;strong&gt;ugly&lt;/strong&gt;, &lt;strong&gt;slow&lt;/strong&gt;, or just a boring list of links. I wanted to build something that actually made players &lt;em&gt;want&lt;/em&gt; to vote — something that felt premium, fast, and exciting the moment you landed on it.&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;Vote-for-HustlersMC&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What I Built
&lt;/h2&gt;

&lt;p&gt;Here's the feature list at a glance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🪟 &lt;strong&gt;Glassmorphism UI&lt;/strong&gt; — frosted glass cards, layered transparencies, depth without weight&lt;/li&gt;
&lt;li&gt;✍️ &lt;strong&gt;Typewriter text effects&lt;/strong&gt; — dynamic headlines that animate on load&lt;/li&gt;
&lt;li&gt;🌌 &lt;strong&gt;Animated backgrounds&lt;/strong&gt; — subtle motion that brings the page to life&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;10+ verified voting platforms&lt;/strong&gt; integrated in one place&lt;/li&gt;
&lt;li&gt;📈 &lt;strong&gt;SEO-ready structure&lt;/strong&gt; — meta tags, semantic HTML, Open Graph&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Analytics-ready&lt;/strong&gt; — plug in your tracking ID and you're live&lt;/li&gt;
&lt;li&gt;♿ &lt;strong&gt;Accessibility-first&lt;/strong&gt; — keyboard navigable, proper contrast, ARIA labels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it runs on &lt;strong&gt;zero dependencies&lt;/strong&gt;. No npm. No build step. Just open &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Lesson 1: Pure CSS Can Do Incredible Things
&lt;/h2&gt;

&lt;p&gt;I went into this thinking I'd need a CSS framework to pull off the glassmorphism look. I was wrong.&lt;/p&gt;

&lt;p&gt;The glass card effect is just a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.glass-card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;32px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.3&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;That's it. &lt;code&gt;backdrop-filter: blur()&lt;/code&gt; is the magic. It blurs everything &lt;em&gt;behind&lt;/em&gt; the element, creating that frosted glass illusion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Before reaching for a framework, ask yourself — can CSS do this natively? More often than not, the answer is yes. Frameworks add weight. Native CSS adds nothing.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Lesson 2: The Typewriter Effect Taught Me JavaScript Timing
&lt;/h2&gt;

&lt;p&gt;The animated typewriter headline was something I'd seen on hundreds of sites but never built myself. I assumed it required a library. It doesn't.&lt;/p&gt;

&lt;p&gt;Here's the core logic I wrote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;phrases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Vote. Rise. Conquer.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Support HustlersMC Today.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Every Vote Counts. ⚔️&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;phraseIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;charIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isDeleting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;typeWriter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;phrases&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;phraseIndex&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;displayed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isDeleting&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;charIndex&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;charIndex&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.typewriter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;displayed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isDeleting&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;charIndex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;isDeleting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pause before deleting&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isDeleting&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;charIndex&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;isDeleting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;phraseIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phraseIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;phrases&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;typeWriter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isDeleting&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;typeWriter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; &lt;code&gt;setTimeout&lt;/code&gt; recursion is incredibly powerful for animations. Understanding the difference between typing speed (100ms) and deletion speed (60ms) is what makes it feel &lt;em&gt;human&lt;/em&gt;. Small timing details create big UX impact.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Lesson 3: SEO Is Not Just for Big Websites
&lt;/h2&gt;

&lt;p&gt;This one surprised me most. I thought SEO was something you worry about when you have a blog or a business. But even a simple static page benefits enormously from it.&lt;/p&gt;

&lt;p&gt;I added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Basic SEO --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Vote for HustlersMC — the fastest growing Minecraft server in Pakistan. Support us on 10+ platforms!"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"keywords"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"HustlersMC, Minecraft server, vote, Pakistan Minecraft, server ranking"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Open Graph for social sharing --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Vote for HustlersMC 🎮"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Click to vote and help us climb the rankings!"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://yoursite.com/preview.png"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"website"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Semantic HTML --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;, &lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;, &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;, &lt;span class="nt"&gt;&amp;lt;nav&amp;gt;&lt;/span&gt;, &lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The moment I shared the link on Discord, the &lt;strong&gt;Open Graph preview card&lt;/strong&gt; showed up beautifully — the server logo, title, and description. Players were more likely to click it. The server's visibility on Google improved too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Semantic HTML + meta tags = free marketing. It costs you 10 minutes and pays back for months.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Lesson 4: Animated Backgrounds Are About Restraint, Not Complexity
&lt;/h2&gt;

&lt;p&gt;My first attempt at the animated background was too intense — particles flying everywhere, colors shifting rapidly. It looked like a nightclub, not a website.&lt;/p&gt;

&lt;p&gt;The version I shipped uses a subtle CSS keyframe animation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;gradientShift&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0%&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#0f0c29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#302b63&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#24243e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300%&lt;/span&gt; &lt;span class="m"&gt;300%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gradientShift&lt;/span&gt; &lt;span class="m"&gt;8s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt; &lt;span class="n"&gt;infinite&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;Slow. Smooth. Atmospheric. It adds life without distracting from the content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Great animation is mostly about what you &lt;em&gt;don't&lt;/em&gt; do. Subtlety wins. If users notice the animation more than the content, you've gone too far.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Lesson 5: Building for a Real Community Changes Everything
&lt;/h2&gt;

&lt;p&gt;This wasn't a practice project for a fake client. Real players from HustlersMC were going to use this. That pressure made me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test on mobile obsessively (most Minecraft players are on phones between sessions)&lt;/li&gt;
&lt;li&gt;Check contrast ratios for accessibility&lt;/li&gt;
&lt;li&gt;Make sure every voting link opened correctly in a new tab&lt;/li&gt;
&lt;li&gt;Add a smooth loading state so it didn't flash unstyled content (FOUC)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also integrated &lt;strong&gt;Google Analytics&lt;/strong&gt; so the server owner could see which voting platforms were being used most and which players were dropping off. That turned a static page into an actual growth tool.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned:&lt;/strong&gt; Building for real users forces you to care about details you'd ignore in a tutorial. Ship something real as early as possible — even if it's small.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ The Tech Stack (Zero Dependencies)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;How&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Structure&lt;/td&gt;
&lt;td&gt;Semantic HTML5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Pure CSS3 (glassmorphism, keyframe animations, CSS variables)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interactivity&lt;/td&gt;
&lt;td&gt;Vanilla JavaScript (typewriter, scroll effects)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO&lt;/td&gt;
&lt;td&gt;Meta tags, Open Graph, semantic markup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analytics&lt;/td&gt;
&lt;td&gt;Google Analytics (plug-and-play)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;GitHub Pages (free, instant)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No npm. No node_modules. No build pipeline. Just files.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Result
&lt;/h2&gt;

&lt;p&gt;A voting portal that looks like it cost money to build — but didn't. Players actually commented on how clean it looked. The server owner could share the link anywhere and it looked professional on every platform.&lt;/p&gt;

&lt;p&gt;You can explore the full source code here 👇&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 GitHub:&lt;/strong&gt; &lt;a href="https://github.com/itxashancode/Vote-for-HustlersMC" rel="noopener noreferrer"&gt;github.com/itxashancode/Vote-for-HustlersMC&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 What Would You Build Next?
&lt;/h2&gt;

&lt;p&gt;I'm currently exploring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adding a live vote counter with localStorage&lt;/li&gt;
&lt;li&gt;A leaderboard showing top voters of the month&lt;/li&gt;
&lt;li&gt;A Discord webhook that pings the server when someone votes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you've built something for a game community — or if you're curious about any of the techniques above — &lt;strong&gt;drop a comment below!&lt;/strong&gt; I'd love to see what you're working on. 🎮&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If this helped you, consider giving the repo a ⭐ — it genuinely means a lot to a student developer from Pakistan trying to make his mark!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>css</category>
    </item>
    <item>
      <title>🐍 5 Python Scripts Every Student Dev Should Automate First</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Fri, 13 Mar 2026 16:04:02 +0000</pubDate>
      <link>https://dev.to/itxashancode/5-python-scripts-every-student-dev-should-automate-first-a21</link>
      <guid>https://dev.to/itxashancode/5-python-scripts-every-student-dev-should-automate-first-a21</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;I'm a student dev from Karachi. No internship. No senior to guide me.&lt;br&gt;
Just a laptop, Python, and a habit of automating everything that bored me twice.&lt;br&gt;
Here's what I wish I had automated sooner.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. 🔁 Auto-Rename &amp;amp; Organize Your Downloads Folder
&lt;/h2&gt;

&lt;p&gt;Your downloads folder is a graveyard. Fix it in 15 lines.&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;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;shutil&lt;/span&gt;

&lt;span class="n"&gt;FOLDER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expanduser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;~/Downloads&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;TYPES&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;Images&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;.jpg&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;.jpeg&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;.png&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;.gif&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;.webp&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;Docs&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;.pdf&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;.docx&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;.txt&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;.xlsx&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;Code&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;.py&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;.js&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;.ts&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;.html&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;.css&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;Videos&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;.mp4&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;.mov&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;.mkv&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;Zips&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;.zip&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;.rar&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;.tar&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="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FOLDER&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splitext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exts&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TYPES&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ext&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;exts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;dest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FOLDER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makedirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FOLDER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;dest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it once a week with Task Scheduler (Windows) or a cron job. You'll feel like a wizard.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. 📸 Bulk Screenshot → PDF Converter
&lt;/h2&gt;

&lt;p&gt;Got lecture slides scattered as screenshots? Merge them into one PDF instantly.&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;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;screenshots_to_pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merged.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RGB&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;endswith&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.png&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;.jpg&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;.jpeg&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;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;save_all&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;append_images&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:])&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;✅ Saved: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;screenshots_to_pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./slides&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;Install: &lt;code&gt;pip install Pillow&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This saved me hours before exams. Seriously.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. 🔔 Desktop Notifier for Any Website Change
&lt;/h2&gt;

&lt;p&gt;Watching for a job post? A price drop? A new batch opening?&lt;br&gt;
Stop refreshing. Let Python do it.&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;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;plyer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;notification&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://example.com/jobs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# replace with your target
&lt;/span&gt;&lt;span class="n"&gt;CHECK_EVERY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;  &lt;span class="c1"&gt;# seconds
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;👁️ Watching for changes...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&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;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CHECK_EVERY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;🚨 Page Changed!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install: &lt;code&gt;pip install requests plyer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Set it, forget it, get notified.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. 📂 Auto-Backup Your Projects to a Zip
&lt;/h2&gt;

&lt;p&gt;Before you break something (you will), back it 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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;zipfile&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;backup_project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./backups&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makedirs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y%m%d_%H%M%S&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;zip_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;backup_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.zip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;zipfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ZipFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zip_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;zipfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ZIP_DEFLATED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;zf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;walk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source_dir&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;dirs&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;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dirs&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;node_modules&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;.git&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;__pycache__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;filepath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;zf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;relpath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source_dir&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;✅ Backup saved: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;zip_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;backup_project&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./my-project&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;Notice: it skips &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;.git&lt;/code&gt;, and &lt;code&gt;__pycache__&lt;/code&gt; — so the zip stays small.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. 🤖 GitHub Auto-Commit Streak Keeper
&lt;/h2&gt;

&lt;p&gt;Missing a day on your contribution graph hurts.&lt;br&gt;
This script makes a tiny commit so your streak stays alive when life gets in the way.&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;import&lt;/span&gt; &lt;span class="n"&gt;subprocess&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;LOG_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;streak.log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LOG_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;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;streak kept: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;git&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;add&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LOG_FILE&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;git&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;commit&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;-m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chore: streak &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="n"&gt;subprocess&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;git&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;push&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;✅ Streak alive!&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;Set this on a cron job at 11:50 PM. Sleep peacefully.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Use on a personal/practice repo — not your main project.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎯 Quick Recap
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Script&lt;/th&gt;
&lt;th&gt;What It Solves&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Downloads Organizer&lt;/td&gt;
&lt;td&gt;Chaos in your folders&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Screenshots → PDF&lt;/td&gt;
&lt;td&gt;Messy lecture notes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Website Change Notifier&lt;/td&gt;
&lt;td&gt;FOMO on opportunities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Project Backup&lt;/td&gt;
&lt;td&gt;That "oh no" moment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Streak Keeper&lt;/td&gt;
&lt;td&gt;GitHub anxiety&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  💬 Drop Your Script in the Comments
&lt;/h2&gt;

&lt;p&gt;What's the first thing YOU automated as a student dev?&lt;br&gt;
I'm building a list — your script might end up in part 2. 👇&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built in Karachi. Tested at 2am. Working on more automation tools at &lt;a href="https://github.com/itxashancode" rel="noopener noreferrer"&gt;github.com/itxashancode&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>automation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Have 18 GitHub Repos at 17 — Here's What I Built, Broke, and Learned</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Thu, 12 Mar 2026 23:42:21 +0000</pubDate>
      <link>https://dev.to/itxashancode/i-have-18-github-repos-at-17-heres-what-i-built-broke-and-learned-3kh9</link>
      <guid>https://dev.to/itxashancode/i-have-18-github-repos-at-17-heres-what-i-built-broke-and-learned-3kh9</guid>
      <description>&lt;p&gt;When I joined GitHub, I didn't have a plan.&lt;/p&gt;

&lt;p&gt;I just started building things — some useful, some broken, some embarrassing.&lt;br&gt;
But 18 repositories later, I've learned more from pushing code than from any tutorial.&lt;/p&gt;

&lt;p&gt;Here's an honest breakdown of what I built, what flopped, and what actually taught me something real.&lt;/p&gt;




&lt;h2&gt;
  
  
  🦈 The One That Started Everything: Pull Shark Automation
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Automate GitHub PR creation at scale — 62 PRs/min with Python&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This was my first "real" project. I wanted the GitHub Pull Shark badge, but doing it manually was painfully slow. So I automated it.&lt;/p&gt;

&lt;p&gt;What it does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dual modes: Sequential (stable) and Parallel (blazing fast async)&lt;/li&gt;
&lt;li&gt;Multi-token rotation to stay within rate limits&lt;/li&gt;
&lt;li&gt;Auto-merge, Discord/Slack webhooks, proxy support&lt;/li&gt;
&lt;li&gt;Windows compatible
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Sequential mode
&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;

&lt;span class="c1"&gt;# Parallel mode (fast)
&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;parallel_automation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;concurrent&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="c1"&gt;# Test without committing
&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;dry&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real-world result: &lt;strong&gt;62.5 PRs/min&lt;/strong&gt; with 3 tokens and 20 parallel workers.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;em&gt;Built for learning and CI/CD stress testing. Use responsibly.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/itxashancode/Pull-Shark-Automation" rel="noopener noreferrer"&gt;Pull-Shark-Automation on GitHub&lt;/a&gt; — drop a ⭐ if it helps!&lt;/p&gt;




&lt;h2&gt;
  
  
  🤝 Pair Extraordinaire — Automating Co-Author Badges
&lt;/h2&gt;

&lt;p&gt;After Pull Shark, I went after the Pair Extraordinaire badge.&lt;br&gt;
Same idea — understand how GitHub's contribution system works by building around it.&lt;/p&gt;

&lt;p&gt;This one taught me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How Git co-authoring actually works under the hood&lt;/li&gt;
&lt;li&gt;Managing multiple identities in commits&lt;/li&gt;
&lt;li&gt;Token scoping and permission management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/itxashancode/Pair-Extraordinaire" rel="noopener noreferrer"&gt;Pair-Extraordinaire on GitHub&lt;/a&gt; — drop a ⭐ if it helps!&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What 18 Repos Actually Taught Me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. READMEs matter more than code quality at first&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nobody digs into your code on first impression. They read your README.&lt;br&gt;
Write it like you're explaining to a smart friend who's never seen your project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Stars don't validate you — but they do signal clarity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pull Shark got 27 stars in a week not because the code was perfect,&lt;br&gt;
but because the README was clear and the use case was specific.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Broken repos are fine. Abandoned repos are not.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have repos I haven't touched in weeks. That's okay.&lt;br&gt;
What's not okay is leaving them with no description, no README, no context.&lt;br&gt;
Even a one-liner description helps someone understand what you were thinking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Your GitHub is a portfolio before you have a portfolio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't have a deployed portfolio site yet (it's in progress 👀).&lt;br&gt;
But recruiters and collaborators can still see exactly what I can do&lt;br&gt;
by looking at my repos. Treat every repo like a mini-resume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Committing consistently beats committing perfectly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Green squares on your contribution graph tell a story.&lt;br&gt;
Don't wait until your code is "ready." Push early, push often.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ My Current Stack Across All Projects
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language/Tool&lt;/th&gt;
&lt;th&gt;Used For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Automation, scripting, GitHub tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JavaScript / TypeScript&lt;/td&gt;
&lt;td&gt;Web apps, frontend logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React + Next.js&lt;/td&gt;
&lt;td&gt;UI, full stack projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Backend, API building&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Firebase&lt;/td&gt;
&lt;td&gt;Auth, real-time DB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML + CSS&lt;/td&gt;
&lt;td&gt;Foundations, landing pages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔭 What I'm Building Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Personal portfolio site with Next.js (almost done)&lt;/li&gt;
&lt;li&gt;AI-powered web app integrating Claude / OpenAI APIs&lt;/li&gt;
&lt;li&gt;More open source tools for developers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤙 Let's Connect
&lt;/h2&gt;

&lt;p&gt;If you're a dev from Pakistan, a beginner just starting out,&lt;br&gt;
or someone who loves building weird automation tools — let's connect.&lt;br&gt;
Drop a comment, follow along, or check out my repos.&lt;/p&gt;

&lt;p&gt;📦 &lt;a href="https://github.com/itxashancode" rel="noopener noreferrer"&gt;GitHub → itxashancode&lt;/a&gt;&lt;br&gt;
🌐 &lt;a href="https://linktr.ee/itxashanvibes" rel="noopener noreferrer"&gt;Linktree → itxashanvibes&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What was your first GitHub repo? Drop it in the comments 👇&lt;/em&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>beginners</category>
      <category>python</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🤝 Automate GitHub's Pair Extraordinaire Badge with Python</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Wed, 11 Mar 2026 10:13:57 +0000</pubDate>
      <link>https://dev.to/itxashancode/automate-githubs-pair-extraordinaire-badge-with-python-26bi</link>
      <guid>https://dev.to/itxashancode/automate-githubs-pair-extraordinaire-badge-with-python-26bi</guid>
      <description>&lt;h2&gt;
  
  
  A deep dive into Pair Extraordinaire Automation — a Python framework that streamlines co-authored PRs at scale, with dual execution modes, token rotation, webhook notifications, and smart state resumption.
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🔗 Full source code on GitHub: &lt;a href="https://github.com/itxashancode/Pair-Extraordinaire" rel="noopener noreferrer"&gt;Pair-Extraordinaire&lt;/a&gt; — drop a ⭐ if it helps!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Ever wondered how some developers rack up GitHub achievement badges at scale? Or wanted to deeply understand how GitHub co-authoring workflows actually function under the hood? That's exactly what &lt;strong&gt;Pair Extraordinaire Automation&lt;/strong&gt; is built for.&lt;/p&gt;

&lt;p&gt;This open-source Python framework automates co-authored Pull Request workflows — giving you a hands-on way to explore GitHub API integration, token management, webhook notifications, and stateful automation design, all in one project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Heads up:&lt;/strong&gt; This tool is built for &lt;strong&gt;educational purposes&lt;/strong&gt; — to study GitHub automation and co-authoring patterns. Always use it responsibly and in line with &lt;a href="https://docs.github.com/en/site-policy/github-terms/github-terms-of-service" rel="noopener noreferrer"&gt;GitHub's Terms of Service&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🏆 What Is the Pair Extraordinaire Badge?
&lt;/h2&gt;

&lt;p&gt;GitHub awards the &lt;strong&gt;Pair Extraordinaire&lt;/strong&gt; achievement when you co-author and merge Pull Requests with a collaborator. The badge has four tiers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Required PRs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;1 PR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🥉 Bronze&lt;/td&gt;
&lt;td&gt;10 PRs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🥈 Silver&lt;/td&gt;
&lt;td&gt;24 PRs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🥇 Gold&lt;/td&gt;
&lt;td&gt;48 PRs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The magic happens through Git's &lt;code&gt;Co-authored-by&lt;/code&gt; commit trailer — a simple but powerful convention that GitHub recognises to credit multiple authors on a single commit.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 What Does This Project Do?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pair Extraordinaire Automation&lt;/strong&gt; is a configurable Python framework that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates branches, makes co-authored commits, opens Pull Requests, and merges them — all automatically&lt;/li&gt;
&lt;li&gt;Supports &lt;strong&gt;sequential&lt;/strong&gt; and &lt;strong&gt;parallel&lt;/strong&gt; execution modes&lt;/li&gt;
&lt;li&gt;Handles &lt;strong&gt;rate limits&lt;/strong&gt; with exponential backoff and smart retry logic&lt;/li&gt;
&lt;li&gt;Rotates across &lt;strong&gt;multiple GitHub tokens&lt;/strong&gt; for higher throughput&lt;/li&gt;
&lt;li&gt;Sends real-time progress updates to &lt;strong&gt;Discord or Slack&lt;/strong&gt; via webhooks&lt;/li&gt;
&lt;li&gt;Persists state so you can &lt;strong&gt;resume after any interruption&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Includes a &lt;strong&gt;dry-run mode&lt;/strong&gt; for testing without touching your repository&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ Architecture Overview
&lt;/h2&gt;

&lt;p&gt;The project is cleanly structured into four layers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pair Extraordinaire Automation
│
├── run.py              ← Entry point &amp;amp; orchestrator
├── src/                ← Core bot logic (git ops, GitHub API, token mgr)
├── config/             ← JSON settings + .env variables
└── templates/          ← Commit message &amp;amp; PR body templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The orchestration flow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start → Load Config → Choose Mode (Sequential / Parallel)
      → Create Branch → Co-authored Commit → Push → Open PR
      → Auto-Merge → Save State → Notify → Repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I like about this design is its clear separation of concerns. The &lt;code&gt;src/&lt;/code&gt; layer handles all Git and GitHub API interactions, while &lt;code&gt;config/&lt;/code&gt; and &lt;code&gt;templates/&lt;/code&gt; let you customise behaviour without touching any core logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You'll need Python 3.8+, Git 2.0+, and the &lt;a href="https://cli.github.com/" rel="noopener noreferrer"&gt;GitHub CLI&lt;/a&gt; installed. You also need two GitHub accounts — your own and a collaborator's.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repo&lt;/span&gt;
git clone https://github.com/itxashancode/Pair-Extraordinaire-Automation.git
&lt;span class="nb"&gt;cd &lt;/span&gt;Pair-Extraordinaire-Automation

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# Authenticate GitHub CLI&lt;/span&gt;
gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;Copy &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env&lt;/code&gt; and fill in your details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GITHUB_TOKEN=your_personal_access_token
REPO_OWNER=your_github_username
REPO_NAME=your_repository_name

CO_AUTHOR_NAME=Collaborator Name
CO_AUTHOR_EMAIL=collaborator@email.com
CO_AUTHOR_TOKEN=collaborator_token_optional

# Optional webhooks
DISCORD_WEBHOOK=https://discord.com/api/webhooks/...
SLACK_WEBHOOK=https://hooks.slack.com/services/...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then set your run parameters in &lt;code&gt;config/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pr_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"delay_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"auto_merge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dry_run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_retries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Always test first with dry-run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python run.py &lt;span class="nt"&gt;--dry-run&lt;/span&gt; &lt;span class="nt"&gt;--count&lt;/span&gt; 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simulates the full workflow — branch creation, commits, PRs — without making any real changes. It's a great way to catch config mistakes before they matter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run for real
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Basic run (uses config defaults)&lt;/span&gt;
python run.py

&lt;span class="c"&gt;# Custom count with specific delay&lt;/span&gt;
python run.py &lt;span class="nt"&gt;--count&lt;/span&gt; 50 &lt;span class="nt"&gt;--delay&lt;/span&gt; 10

&lt;span class="c"&gt;# Resume after an interruption — state is automatically tracked&lt;/span&gt;
python run.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sample output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;🚀 Starting Pair Extraordinaire Automation from PR #&lt;/span&gt;1
&lt;span class="go"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;🔹 Processing PR #&lt;/span&gt;1
&lt;span class="go"&gt;  ├─ 🌿 Created branch: pair-auto-1-a1b2c3d4
  ├─ 💾 Committed with Co-authored-by trailer
  ├─ 📤 Pushed to remote
&lt;/span&gt;&lt;span class="gp"&gt;  └─ ✅ PR #&lt;/span&gt;101 created and merged
&lt;span class="go"&gt;
⏱️  Waiting 15 seconds...

&lt;/span&gt;&lt;span class="gp"&gt;🔹 Processing PR #&lt;/span&gt;2
&lt;span class="c"&gt;...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔑 The Co-authored-by Mechanic
&lt;/h2&gt;

&lt;p&gt;The key to how this project works is a Git commit trailer that GitHub specifically recognises:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;feat: automated update #1

This is an automated co-authored commit.

Co-authored-by: Collaborator Name &lt;span class="nv"&gt;&amp;lt;collaborator@email.com&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a PR containing this trailer is merged, GitHub awards the Pair Extraordinaire badge to &lt;strong&gt;both&lt;/strong&gt; the author and the co-author. The email in the trailer must match an email associated with the collaborator's GitHub account — that's a common gotcha.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛡️ Security Considerations
&lt;/h2&gt;

&lt;p&gt;A few things to keep in mind when running this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Never commit your &lt;code&gt;.env&lt;/code&gt; file&lt;/strong&gt; — it's already in &lt;code&gt;.gitignore&lt;/code&gt;, keep it that way&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;fine-grained personal access tokens&lt;/strong&gt; scoped to specific repos only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rotate tokens every 30–90 days&lt;/strong&gt; as a good hygiene practice&lt;/li&gt;
&lt;li&gt;Monitor your rate limit with &lt;code&gt;gh api rate_limit&lt;/code&gt; — you get 5,000 requests/hour per token, and multi-token rotation lets you stack that&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🐛 Common Issues
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;gh: command not found&lt;/code&gt;&lt;/strong&gt; → Install GitHub CLI for your platform and verify with &lt;code&gt;gh --version&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Authentication failed&lt;/code&gt;&lt;/strong&gt; → Run &lt;code&gt;gh auth login&lt;/code&gt; and follow the prompts, or use &lt;code&gt;echo "TOKEN" | gh auth login --with-token&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Co-authored-by not recognized&lt;/code&gt;&lt;/strong&gt; → Double-check that &lt;code&gt;CO_AUTHOR_EMAIL&lt;/code&gt; exactly matches an email registered on the collaborator's GitHub account&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;API rate limit exceeded&lt;/code&gt;&lt;/strong&gt; → Increase &lt;code&gt;delay_seconds&lt;/code&gt; in config, or add a second token for rotation&lt;/p&gt;




&lt;h2&gt;
  
  
  📈 Real-World Benchmarks
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Badge Goal&lt;/th&gt;
&lt;th&gt;PRs&lt;/th&gt;
&lt;th&gt;Approx. Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;~30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bronze&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;~3 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Silver&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;td&gt;~5 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gold&lt;/td&gt;
&lt;td&gt;48&lt;/td&gt;
&lt;td&gt;~10 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  💡 What I Learned Building This
&lt;/h2&gt;

&lt;p&gt;This project is a great reference for several Python and GitHub automation patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stateful automation&lt;/strong&gt; — persisting progress to a JSON file so a long-running task can be safely interrupted and resumed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exponential backoff&lt;/strong&gt; — retry logic that doubles the wait time on each failure (5s → 10s → 20s) to avoid hammering a rate-limited API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token rotation&lt;/strong&gt; — cycling through multiple API tokens to multiply your effective request quota&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Template-based commit messages&lt;/strong&gt; — separating message content from code so customisation doesn't require touching logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook integration&lt;/strong&gt; — pushing structured notifications to Discord/Slack with colour-coded severity levels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you never use this for badge automation specifically, these patterns come up constantly in real-world automation and DevOps work.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤝 Contributing
&lt;/h2&gt;

&lt;p&gt;The project is MIT licensed and welcomes contributions. If you want to jump in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo fork itxashancode/Pair-Extraordinaire-Automation
git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/your-improvement
&lt;span class="c"&gt;# Make changes, commit with conventional commits&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"feat: add your amazing feature"&lt;/span&gt;
gh &lt;span class="nb"&gt;pr &lt;/span&gt;create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The codebase follows type hints and clear docstrings — &lt;code&gt;black&lt;/code&gt; for formatting, &lt;code&gt;flake8&lt;/code&gt; for style, &lt;code&gt;mypy&lt;/code&gt; for type checking.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/itxashancode/Pair-Extraordinaire-Automation" rel="noopener noreferrer"&gt;itxashancode/Pair-Extraordinaire-Automation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👤 &lt;strong&gt;Author:&lt;/strong&gt; &lt;a href="https://github.com/itxashancode" rel="noopener noreferrer"&gt;@itxashancode&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;More from the author:&lt;/strong&gt; &lt;a href="https://linktr.ee/itxashanvibes" rel="noopener noreferrer"&gt;linktr.ee/itxashanvibes&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you found this interesting, drop a ⭐ on the repo and let me know in the comments — what GitHub automation patterns have you built or wanted to build?&lt;/p&gt;

</description>
      <category>python</category>
      <category>github</category>
      <category>opensource</category>
      <category>automation</category>
    </item>
    <item>
      <title>I'm a Self-Taught Dev from Pakistan — Here's What My First 6 Months Looked Like</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Thu, 05 Mar 2026 16:37:40 +0000</pubDate>
      <link>https://dev.to/itxashancode/im-a-self-taught-dev-from-pakistan-heres-what-my-first-6-months-looked-like-1i0m</link>
      <guid>https://dev.to/itxashancode/im-a-self-taught-dev-from-pakistan-heres-what-my-first-6-months-looked-like-1i0m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Everyone talks about learning to code. Nobody talks about learning to code when resources cost money you don't have, and people around you don't understand why you're staring at a screen at 2 AM."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm &lt;strong&gt;Ashan&lt;/strong&gt; — a student at APTECH Pakistan and an aspiring full stack developer. This is my honest, unfiltered story.&lt;/p&gt;




&lt;h2&gt;
  
  
  📅 Month 1–2: HTML &amp;amp; CSS (The Honeymoon Phase)
&lt;/h2&gt;

&lt;p&gt;I started the way everyone does — building a portfolio page that looked &lt;em&gt;nothing&lt;/em&gt; like what I imagined.&lt;/p&gt;

&lt;p&gt;I spent &lt;strong&gt;3 hours&lt;/strong&gt; trying to center a div. No joke.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
Please just center



  Finally.

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The lesson?&lt;/strong&gt; Everyone struggles with CSS at first. It's not you — it's the box model.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Month 3–4: JavaScript Hit Different
&lt;/h2&gt;

&lt;p&gt;HTML/CSS felt visual and rewarding. JavaScript felt like being handed a book written in a language I'd never seen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// My first real "aha" moment&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;greet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Hello, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;! You can actually code.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ashan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
&lt;span class="c1"&gt;// → Hello, Ashan! You can actually code.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The moment &lt;strong&gt;functions&lt;/strong&gt; clicked for me, everything changed. I started building small projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ A to-do app&lt;/li&gt;
&lt;li&gt;✅ A quiz game&lt;/li&gt;
&lt;li&gt;✅ A basic calculator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of them were pretty. All of them taught me something.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Month 5–6: React &amp;amp; The Real World
&lt;/h2&gt;

&lt;p&gt;React blew my mind. Components, state, props — it felt like thinking in &lt;strong&gt;building blocks&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;WelcomeCard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

      &lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="err"&gt;👋&lt;/span&gt;
      &lt;span class="nx"&gt;You&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;re building something real.

  );
}

export default WelcomeCard;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The mental shift from "writing HTML" to "composing UI" was huge.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 3 Things Nobody Told Me
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. You will Google everything — and that's completely normal
&lt;/h3&gt;

&lt;p&gt;Senior devs do it too. The skill isn't memorizing syntax. It's knowing &lt;em&gt;what&lt;/em&gt; to search for.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Build ugly projects first
&lt;/h3&gt;

&lt;p&gt;Pretty comes with practice. Shipping something broken teaches you more than planning something perfect.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Your background doesn't disqualify you
&lt;/h3&gt;

&lt;p&gt;It's your superpower story. Developers from non-traditional backgrounds bring perspectives the industry desperately needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 My Honest Progress Chart
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Month&lt;/th&gt;
&lt;th&gt;Focus&lt;/th&gt;
&lt;th&gt;Feeling&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;HTML basics&lt;/td&gt;
&lt;td&gt;🤩 Excited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;CSS layouts&lt;/td&gt;
&lt;td&gt;😤 Frustrated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;JS fundamentals&lt;/td&gt;
&lt;td&gt;😵 Confused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;JS projects&lt;/td&gt;
&lt;td&gt;😤→😊 Getting it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;React intro&lt;/td&gt;
&lt;td&gt;🤯 Mind blown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;React + Firebase&lt;/td&gt;
&lt;td&gt;🔥 Building real things&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🚀 What's Next for Me
&lt;/h2&gt;

&lt;p&gt;I'm now diving into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js&lt;/strong&gt; — for server-side rendering and full stack apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firebase&lt;/strong&gt; — for auth, databases, and real-time features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI integrations&lt;/strong&gt; — because that's where the web is going&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The journey is far from over — but I'm proud of how far I've come from that mis-centered div.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;💬 &lt;strong&gt;If you're starting&lt;/strong&gt; — what's the hardest thing you've hit so far? Drop it in the comments. Let's figure it out together. 👇&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>career</category>
      <category>startup</category>
    </item>
    <item>
      <title>🦈 Pull Shark Automation: Create 62 GitHub PRs/min with Python</title>
      <dc:creator>Ashan_Dev</dc:creator>
      <pubDate>Wed, 04 Mar 2026 10:26:40 +0000</pubDate>
      <link>https://dev.to/itxashancode/pull-shark-automation-create-62-github-prsmin-with-python-6ig</link>
      <guid>https://dev.to/itxashancode/pull-shark-automation-create-62-github-prsmin-with-python-6ig</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;🔗 Full source code on GitHub: &lt;a href="https://github.com/itxashancode/Pull-Shark-Automation" rel="noopener noreferrer"&gt;Pull-Shark-Automation&lt;/a&gt; — drop a ⭐ if it helps!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Is Pull Shark Automation?
&lt;/h2&gt;

&lt;p&gt;Ever wanted to earn the GitHub &lt;strong&gt;Pull Shark badge&lt;/strong&gt; — or stress-test your CI/CD pipelines by generating hundreds of pull requests automatically? Meet &lt;strong&gt;Pull Shark Automation&lt;/strong&gt;, an open-source Python framework built for exactly that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Disclaimer:&lt;/strong&gt; This tool is for educational purposes only. Use responsibly and in accordance with &lt;a href="https://docs.github.com/en/site-policy/github-terms/github-terms-of-service" rel="noopener noreferrer"&gt;GitHub's Terms of Service&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;GitHub's Pull Shark badge is awarded when your PRs get merged — Default (2 PRs), Bronze (16), Silver (128), and Gold (1024). Doing that manually is tedious. Doing it at 62 PRs/minute? That's automation.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dual execution modes&lt;/strong&gt; — Sequential (stable) and Parallel (blazing fast, async)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-token rotation&lt;/strong&gt; — Automatically switches GitHub tokens to stay within rate limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy support&lt;/strong&gt; — Built-in proxy scraping and rotation from free sources&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-merge&lt;/strong&gt; — PRs are created &lt;em&gt;and&lt;/em&gt; merged without manual intervention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State persistence&lt;/strong&gt; — Resume from interruptions via &lt;code&gt;state.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time notifications&lt;/strong&gt; — Discord &amp;amp; Slack webhook support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows compatible&lt;/strong&gt; — Async operations work cross-platform&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ Architecture Overview
&lt;/h2&gt;

&lt;p&gt;The project is cleanly modularized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;main.py                    # Sequential mode entry point
parallel_automation.py     # Parallel/async mode
git_manager.py             # Git branch, commit, push
github_tool.py             # GitHub CLI wrapper + rate limiting
token_manager.py           # Multi-token rotation
proxy_manager.py           # Proxy scraping &amp;amp; rotation
notifier.py                # Discord &amp;amp; Slack webhooks
logger.py                  # Dual-output logging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;high_performance/&lt;/code&gt; package provides async-first versions of all the above for maximum throughput.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone &amp;amp; Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/itxashancode/Pull-Shark-Automation.git
&lt;span class="nb"&gt;cd &lt;/span&gt;Pull-Shark-Automation
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Authenticate GitHub CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Configure &lt;code&gt;config.json&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repo_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"base_branch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pr_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"delay_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"auto_merge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dry_run"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_concurrent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Run
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Sequential (reliable)&lt;/span&gt;
python main.py

&lt;span class="c"&gt;# Parallel (fast)&lt;/span&gt;
python parallel_automation.py &lt;span class="nt"&gt;--count&lt;/span&gt; 100 &lt;span class="nt"&gt;--concurrent&lt;/span&gt; 10

&lt;span class="c"&gt;# Dry run (test without commits)&lt;/span&gt;
python main.py &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Performance Benchmarks
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Workers&lt;/th&gt;
&lt;th&gt;Tokens&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Time for 1000 PRs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sequential&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;~2 PRs/min&lt;/td&gt;
&lt;td&gt;~8 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;~36 PRs/min&lt;/td&gt;
&lt;td&gt;~28 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parallel&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;~62 PRs/min&lt;/td&gt;
&lt;td&gt;~16 min&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With 3 GitHub tokens and 20 parallel workers, the tool hit &lt;strong&gt;62.5 PRs/min&lt;/strong&gt; in real-world testing.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔑 Multi-Token Setup
&lt;/h2&gt;

&lt;p&gt;Add multiple tokens to &lt;code&gt;github_tokens.json&lt;/code&gt; for automatic rotation — each GitHub token supports 5,000 requests/hour, so 3 tokens gives you 15,000+/hour:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github_pat_..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Secondary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github_pat_..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Backup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github_pat_..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;TokenManager&lt;/code&gt; automatically picks the token with the most remaining requests.&lt;/p&gt;




&lt;h2&gt;
  
  
  📢 Notifications
&lt;/h2&gt;

&lt;p&gt;Set up Discord or Slack webhooks in &lt;code&gt;config.json&lt;/code&gt; to receive live progress updates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"discord_webhook"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://discord.com/api/webhooks/..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slack_webhook"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://hooks.slack.com/services/..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll get color-coded alerts for PR creation, merges, failures, and completion summaries.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏆 Earning Your Pull Shark Badge
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Badge&lt;/th&gt;
&lt;th&gt;PRs Needed&lt;/th&gt;
&lt;th&gt;Recommended Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;python main.py --count 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bronze&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;&lt;code&gt;python main.py --count 20 --delay 15&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Silver&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;td&gt;&lt;code&gt;python parallel_automation.py --count 150 --concurrent 15&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gold&lt;/td&gt;
&lt;td&gt;1024&lt;/td&gt;
&lt;td&gt;&lt;code&gt;python parallel_automation.py --count 1024 --concurrent 20&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔗 Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;GitHub Repo:&lt;/strong&gt; &lt;a href="https://github.com/itxashancode/Pull-Shark-Automation" rel="noopener noreferrer"&gt;itxashancode/Pull-Shark-Automation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Author:&lt;/strong&gt; &lt;a href="https://linktr.ee/itxashanvibes" rel="noopener noreferrer"&gt;@itxashancode&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you found this useful, drop a ⭐ on the repo and share with devs who love automation!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have questions or feature ideas? Drop them in the comments below.&lt;/em&gt; 👇&lt;/p&gt;

</description>
      <category>python</category>
      <category>github</category>
      <category>automation</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
