<?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: Bilal Aslam</title>
    <description>The latest articles on DEV Community by Bilal Aslam (@bilal-dev-0x).</description>
    <link>https://dev.to/bilal-dev-0x</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3530229%2F2dcd358b-78df-4098-bbf8-beb89720d2c6.png</url>
      <title>DEV Community: Bilal Aslam</title>
      <link>https://dev.to/bilal-dev-0x</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bilal-dev-0x"/>
    <language>en</language>
    <item>
      <title>Build a YouTube Video Downloader with Python and yt-dlp</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Thu, 10 Sep 2026 21:04:11 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/build-a-youtube-video-downloader-with-python-and-yt-dlp-3cc3</link>
      <guid>https://dev.to/bilal-dev-0x/build-a-youtube-video-downloader-with-python-and-yt-dlp-3cc3</guid>
      <description>&lt;p&gt;Ever wanted to download YouTube videos directly from your Python program?&lt;/p&gt;

&lt;p&gt;In this project, I built a simple &lt;strong&gt;YouTube video search and downloader&lt;/strong&gt; using Python. The program lets you enter a search query, choose how many results you want, and download the videos with both &lt;strong&gt;video and audio&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This project also helped me understand how &lt;code&gt;yt-dlp&lt;/code&gt;, FFmpeg, Python &lt;code&gt;Path&lt;/code&gt;, and command-line based video downloading work together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Make sure you only download content you have permission to download and follow YouTube's Terms of Service and applicable copyright laws.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;The program can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search YouTube using a text query&lt;/li&gt;
&lt;li&gt;Download multiple search results&lt;/li&gt;
&lt;li&gt;Download the best available video quality&lt;/li&gt;
&lt;li&gt;Download audio separately when necessary&lt;/li&gt;
&lt;li&gt;Merge video and audio using FFmpeg&lt;/li&gt;
&lt;li&gt;Save downloaded videos to a custom folder&lt;/li&gt;
&lt;li&gt;Automatically create the download directory&lt;/li&gt;
&lt;li&gt;Let the user decide how many videos to download&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter the search query: GODS AMV
Enter the number of videos to download: 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program searches for the first two results and downloads them.&lt;/p&gt;




&lt;h1&gt;
  
  
  Technologies Used
&lt;/h1&gt;

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

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;&lt;code&gt;yt-dlp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;FFmpeg&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pathlib&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main library doing the heavy lifting is &lt;code&gt;yt-dlp&lt;/code&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Installing the Required Packages
&lt;/h1&gt;

&lt;p&gt;First, install &lt;code&gt;yt-dlp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt; yt-dlp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I initially used the &lt;code&gt;youtube_search&lt;/code&gt; package as well, but eventually removed it because &lt;code&gt;yt-dlp&lt;/code&gt; can perform YouTube searches by itself.&lt;/p&gt;

&lt;p&gt;That makes the final code simpler and avoids performing the same search twice.&lt;/p&gt;




&lt;h1&gt;
  
  
  Installing FFmpeg
&lt;/h1&gt;

&lt;p&gt;FFmpeg is important when YouTube provides video and audio as separate streams.&lt;/p&gt;

&lt;p&gt;On Windows, you can install it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;winget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Gyan.FFmpeg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installation, restart your terminal and verify it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;ffmpeg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the version information appears, FFmpeg is available from the command line.&lt;/p&gt;




&lt;h1&gt;
  
  
  Why Do We Need FFmpeg?
&lt;/h1&gt;

&lt;p&gt;One thing I learned while building this project is that a YouTube video isn't always downloaded as one single file.&lt;/p&gt;

&lt;p&gt;For higher-quality videos, YouTube can provide:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Video Stream
+
Audio Stream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, &lt;code&gt;yt-dlp&lt;/code&gt; may report:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Downloading 1 format(s): 399+251
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, one format is the video stream and the other is the audio stream.&lt;/p&gt;

&lt;p&gt;FFmpeg combines them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Video Stream
      +
Audio Stream
      |
      v
    FFmpeg
      |
      v
Complete MP4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without FFmpeg, the download may fail when merging multiple formats.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Final Python Code
&lt;/h1&gt;

&lt;p&gt;Here is the complete version of the project:&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;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yt_dlp&lt;/span&gt;


&lt;span class="n"&gt;DOWNLOAD_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;D:\My Downloads&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_and_download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_results&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="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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Searching for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;search_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&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;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;Number of videos requested: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_results&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;DOWNLOAD_PATH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parents&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;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;yt_dlp_options&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;format&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;bestvideo+bestaudio/best&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;outtmpl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;DOWNLOAD_PATH&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(title)s.%(ext)s&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;noplaylist&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merge_output_format&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;mp4&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;try&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;yt_dlp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;YoutubeDL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yt_dlp_options&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;ydl&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;Searching for videos...&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;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ydl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract_info&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;ytsearch&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_results&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;search_query&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;download&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;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;info&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;entries&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;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;entries&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;No videos found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;return&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Download complete!&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Successfully processed &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
                &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; video(s).&lt;/span&gt;&lt;span class="sh"&gt;"&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;entries&lt;/span&gt;

    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Error occurred: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&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;search_query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter the search query: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;max_results&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="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter the number of videos to download: &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="nf"&gt;search_and_download&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;search_query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_results&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  How the Code Works
&lt;/h1&gt;

&lt;p&gt;Let's break it down.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Importing the Libraries
&lt;/h2&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;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yt_dlp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Path&lt;/code&gt; comes from Python's built-in &lt;code&gt;pathlib&lt;/code&gt; module.&lt;/p&gt;

&lt;p&gt;It makes working with file and folder paths much cleaner than manually manipulating strings.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yt_dlp&lt;/code&gt; is responsible for searching and downloading the videos.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Setting the Download Directory
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;DOWNLOAD_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;D:\My Downloads&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells the program where downloaded videos should be saved.&lt;/p&gt;

&lt;p&gt;I used a raw string:&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="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;D:\My Downloads&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because Windows paths contain backslashes.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Creating the Download Folder
&lt;/h1&gt;

&lt;p&gt;Inside the function:&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;DOWNLOAD_PATH&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;parents&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes sure the folder exists.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;exist_ok=True&lt;/code&gt; means Python won't throw an error if the directory already exists.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;parents=True&lt;/code&gt; allows Python to create missing parent directories if necessary.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Configuring yt-dlp
&lt;/h1&gt;

&lt;p&gt;The main configuration is:&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;yt_dlp_options&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;format&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;bestvideo+bestaudio/best&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;outtmpl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;DOWNLOAD_PATH&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(title)s.%(ext)s&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;noplaylist&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merge_output_format&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;mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at each option.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;format&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format&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;bestvideo+bestaudio/best&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells &lt;code&gt;yt-dlp&lt;/code&gt; to prefer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Best video
+
Best audio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and fall back to the best combined format when necessary.&lt;/p&gt;

&lt;p&gt;This is important because using:&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bestvideo/best&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can result in downloading a video-only stream.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Setting the Output Filename
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;outtmpl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;DOWNLOAD_PATH&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%(title)s.%(ext)s&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;&lt;code&gt;%(title)s&lt;/code&gt; is replaced by the video's title.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;YouTube Video Title.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;video123.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  6. Preventing Playlist Downloads
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;noplaylist&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells &lt;code&gt;yt-dlp&lt;/code&gt; not to download an entire playlist when the URL or search result happens to belong to one.&lt;/p&gt;




&lt;h1&gt;
  
  
  7. Merging Into MP4
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merge_output_format&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;mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When separate video and audio streams are downloaded, FFmpeg can merge them into an MP4 file.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Searching YouTube
&lt;/h1&gt;

&lt;p&gt;The most important part for multiple results is:&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;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ydl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract_info&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;ytsearch&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_results&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;search_query&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;download&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose the user enters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GODS AMV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The resulting search expression becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ytsearch2:GODS AMV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tells &lt;code&gt;yt-dlp&lt;/code&gt; to search for two results.&lt;/p&gt;

&lt;p&gt;If the user enters:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;it becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ytsearch5:GODS AMV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and searches for five results.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Bug I Initially Had
&lt;/h1&gt;

&lt;p&gt;My first version had a logic problem.&lt;/p&gt;

&lt;p&gt;I was using:&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="nc"&gt;YoutubeSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;search_query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;max_results&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to find multiple videos.&lt;/p&gt;

&lt;p&gt;But later I used:&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;ytsearch1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;GODS&lt;/span&gt; &lt;span class="n"&gt;AMV&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for the actual download.&lt;/p&gt;

&lt;p&gt;So even if I requested:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5 videos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the download logic was effectively asking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Give me 1 video.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The search results were also not being used for downloading.&lt;/p&gt;

&lt;p&gt;The flow was basically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search for 5 videos
        |
        v
Get 5 results
        |
        v
Ignore those results
        |
        v
Search again using ytsearch1
        |
        v
Download 1 video
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not exactly the world's greatest software architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Fix
&lt;/h1&gt;

&lt;p&gt;I removed the unnecessary &lt;code&gt;youtube_search&lt;/code&gt; dependency and let &lt;code&gt;yt-dlp&lt;/code&gt; handle both searching and downloading.&lt;/p&gt;

&lt;p&gt;Now:&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ytsearch&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_results&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;search_query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;controls the number of search results.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ytsearch1:anime AMV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means one result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ytsearch5:anime AMV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means five results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ytsearch10:anime AMV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means ten results.&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Getting the Search Results
&lt;/h1&gt;

&lt;p&gt;After extraction:&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;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;info&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;entries&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;entries&lt;/code&gt; contains the videos returned by the search.&lt;/p&gt;

&lt;p&gt;We can check whether anything was found:&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;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;entries&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;No videos found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If results exist, we display how many were processed:&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="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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Successfully processed &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; video(s).&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;h1&gt;
  
  
  10. Handling Errors
&lt;/h1&gt;

&lt;p&gt;The download operation is wrapped inside:&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;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&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="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Error occurred: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the entire Python program from crashing without an explanation.&lt;/p&gt;

&lt;p&gt;Instead, the user gets an error message.&lt;/p&gt;




&lt;h1&gt;
  
  
  Example Run
&lt;/h1&gt;

&lt;p&gt;A typical run looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enter the search query: GODS AMV
Enter the number of videos to download: 2

Searching for: GODS AMV...
Number of videos requested: 2

Searching for videos...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;yt-dlp&lt;/code&gt; searches for the requested number of videos and downloads them.&lt;/p&gt;

&lt;p&gt;The files are saved inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;D:\My Downloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  An Important Lesson About Video and Audio
&lt;/h1&gt;

&lt;p&gt;One of the most useful things I learned from this project was that "best quality" does not necessarily mean "one file."&lt;/p&gt;

&lt;p&gt;A simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1080p Video
    +
High Quality Audio
    =
Two separate streams
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The downloader needs to combine them.&lt;/p&gt;

&lt;p&gt;That's why this configuration:&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format&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;bestvideo+bestaudio/best&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;works together with:&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merge_output_format&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;mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and FFmpeg.&lt;/p&gt;




&lt;h1&gt;
  
  
  Troubleshooting
&lt;/h1&gt;

&lt;h2&gt;
  
  
  FFmpeg Not Installed
&lt;/h2&gt;

&lt;p&gt;If you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR: You have requested merging of multiple formats
but ffmpeg is not installed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install FFmpeg:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;winget&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Gyan.FFmpeg&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;ffmpeg&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-version&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart your terminal if necessary.&lt;/p&gt;




&lt;h2&gt;
  
  
  Video Has No Sound
&lt;/h2&gt;

&lt;p&gt;If your downloaded file has no audio, check whether your format is:&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bestvideo&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That can select a video-only stream.&lt;/p&gt;

&lt;p&gt;Use:&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bestvideo+bestaudio/best&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead.&lt;/p&gt;

&lt;p&gt;Also make sure FFmpeg is installed and accessible from PATH.&lt;/p&gt;




&lt;h2&gt;
  
  
  yt-dlp JavaScript Runtime Warning
&lt;/h2&gt;

&lt;p&gt;You may also see a warning similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WARNING: No supported JavaScript runtime could be found.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is related to YouTube's current extraction requirements and can mean some formats may be unavailable.&lt;/p&gt;

&lt;p&gt;If basic downloading works, you may not need to solve this immediately. However, if &lt;code&gt;yt-dlp&lt;/code&gt; starts failing to extract certain videos or formats, check the official &lt;code&gt;yt-dlp&lt;/code&gt; documentation for the current JavaScript runtime requirements.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I Learned From This Project
&lt;/h1&gt;

&lt;p&gt;This project looked simple at first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search YouTube
      ↓
Download video
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But it introduced several useful concepts.&lt;/p&gt;

&lt;p&gt;I learned about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python functions&lt;/li&gt;
&lt;li&gt;Exception handling&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pathlib&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;File paths on Windows&lt;/li&gt;
&lt;li&gt;Third-party Python packages&lt;/li&gt;
&lt;li&gt;Command-line tools&lt;/li&gt;
&lt;li&gt;Video and audio streams&lt;/li&gt;
&lt;li&gt;FFmpeg&lt;/li&gt;
&lt;li&gt;Search result handling&lt;/li&gt;
&lt;li&gt;Debugging logic errors&lt;/li&gt;
&lt;li&gt;Understanding what a library is actually doing behind the scenes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, I learned that &lt;strong&gt;getting code to run isn't the same as understanding why it works.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For example, my original program technically searched for multiple videos, but my download logic only downloaded one. Looking at the terminal output helped me identify the actual problem.&lt;/p&gt;




&lt;h1&gt;
  
  
  Possible Improvements
&lt;/h1&gt;

&lt;p&gt;There are several features I could add in the future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose video quality&lt;/li&gt;
&lt;li&gt;Download audio only&lt;/li&gt;
&lt;li&gt;Download subtitles&lt;/li&gt;
&lt;li&gt;Show download progress&lt;/li&gt;
&lt;li&gt;Let the user choose the output folder&lt;/li&gt;
&lt;li&gt;Add a graphical user interface&lt;/li&gt;
&lt;li&gt;Add URL-based downloading&lt;/li&gt;
&lt;li&gt;Validate user input&lt;/li&gt;
&lt;li&gt;Create a download history&lt;/li&gt;
&lt;li&gt;Add filename sanitization&lt;/li&gt;
&lt;li&gt;Allow users to select specific search results before downloading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A GUI version would be an interesting next step.&lt;/p&gt;




&lt;h1&gt;
  
  
  Project Structure
&lt;/h1&gt;

&lt;p&gt;For a simple version, the project can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;youtube-downloader/
│
├── youtube_downloader.py
│
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The downloaded videos are stored separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;D:\My Downloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;This was a small Python project, but it turned out to be a pretty useful learning exercise.&lt;/p&gt;

&lt;p&gt;The biggest lesson for me was debugging.&lt;/p&gt;

&lt;p&gt;I initially had two separate problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The downloaded videos had no sound.&lt;/li&gt;
&lt;li&gt;The number of requested results was not controlling the number of downloads.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first problem was caused by downloading a video-only stream:&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;bestvideo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second was caused by accidentally using:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;instead of dynamically using the user's requested number:&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;ytsearch&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_results&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After fixing both, the workflow became much cleaner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Input
    |
    v
yt-dlp YouTube Search
    |
    v
Requested Number of Results
    |
    v
Video + Audio Streams
    |
    v
FFmpeg
    |
    v
Final MP4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's another little Python project added to the learning journey.&lt;/p&gt;




&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This project is intended for educational purposes. Only download videos when you have the right or permission to do so, and respect copyright, platform rules, and the creator's rights.&lt;/p&gt;




&lt;h2&gt;
  
  
  If You Found This Useful
&lt;/h2&gt;

&lt;p&gt;I'm currently learning Python and building small projects to understand concepts by actually using them.&lt;/p&gt;

&lt;p&gt;If you're also learning Python, don't just copy the code.&lt;/p&gt;

&lt;p&gt;Break it.&lt;/p&gt;

&lt;p&gt;Change it.&lt;/p&gt;

&lt;p&gt;Make it fail.&lt;/p&gt;

&lt;p&gt;Then figure out why it failed.&lt;/p&gt;

&lt;p&gt;That's where the real learning starts.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>videodownloader</category>
      <category>funcoding</category>
    </item>
    <item>
      <title>RAZE Debug Mentor</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Sat, 05 Sep 2026 05:25:07 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/raze-debug-mentor-ccb</link>
      <guid>https://dev.to/bilal-dev-0x/raze-debug-mentor-ccb</guid>
      <description>&lt;p&gt;&lt;em&gt;This post is my submission for&lt;/em&gt; &lt;a href="https://dev.to/deved/build-apps-with-google-ai-studio"&gt;&lt;em&gt;DEV Education Track: Build Apps with Google AI Studio&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;RAZE — Debug Mentor&lt;/strong&gt;, an AI-powered debugging mentor designed to help developers understand &lt;em&gt;why&lt;/em&gt; their code is failing instead of simply giving them a corrected solution.&lt;/p&gt;

&lt;p&gt;RAZE follows a structured debugging workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem → Execution → Observation → Questions → Root Cause → Fix → Why It Works → Engineering Takeaway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of immediately generating an answer, RAZE looks at the user's code, execution result, expected vs. actual behavior, and debugging context before guiding them toward the underlying issue.&lt;/p&gt;

&lt;p&gt;One of the problems I specifically tested was a Python &lt;strong&gt;shallow-copy bug&lt;/strong&gt; involving nested dictionaries. RAZE was able to identify that copying the outer list did not create independent copies of the nested objects, explain the shared-reference behavior, and recommend &lt;code&gt;copy.deepcopy()&lt;/code&gt; as the appropriate fix.&lt;/p&gt;

&lt;p&gt;The original RAZE project is built with &lt;strong&gt;Python + FastAPI&lt;/strong&gt;. For this challenge, I imported the project into &lt;strong&gt;Google AI Studio&lt;/strong&gt;, where AI Studio recreated the application as a modern TypeScript-based web app that I could run and iterate on directly in the AI Studio environment.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Live App / AI Studio Applet:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://ai.studio/apps/9dd65d7a-41e2-460e-906c-380c386e5ba5" rel="noopener noreferrer"&gt;https://ai.studio/apps/9dd65d7a-41e2-460e-906c-380c386e5ba5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo shows the complete debugging flow: submitting a problem, running the code, examining the observed behavior, answering mentor questions, and receiving a root-cause explanation and fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience
&lt;/h2&gt;

&lt;p&gt;The most interesting part of this challenge was seeing how quickly Google AI Studio could turn an existing project into a runnable web application.&lt;/p&gt;

&lt;p&gt;I started with an existing Python/FastAPI version of RAZE and imported the GitHub repository into Google AI Studio. AI Studio analyzed the project and recreated the application using TypeScript, allowing me to run and interact with it directly inside the AI Studio environment.&lt;/p&gt;

&lt;p&gt;What I liked most was that I didn't have to start the application from scratch. I could bring an existing idea and codebase into the environment and then focus on getting the experience working and refining the product.&lt;/p&gt;

&lt;p&gt;Building RAZE also taught me an important lesson about AI-assisted development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI can build quickly, but the developer still has to understand, test, verify, and improve what is being built.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used AI heavily during development, but I also tested the actual debugging behavior with real programming problems, especially bugs involving mutable default arguments and shallow copies.&lt;/p&gt;

&lt;p&gt;That process made RAZE more than just an AI chatbot that generates code. The goal is to make it feel like a calm senior developer sitting beside you, helping you understand the bug before fixing it.&lt;/p&gt;

&lt;p&gt;Google AI Studio made experimenting with that idea significantly faster, especially when moving from an existing project into a runnable web experience.&lt;/p&gt;

</description>
      <category>deved</category>
      <category>learngoogleaistudio</category>
      <category>ai</category>
      <category>gemini</category>
    </item>
    <item>
      <title>🧠 I Built an AI That Reads Your Personality… and Roasts You 💀</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Wed, 02 Sep 2026 02:26:58 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/i-built-an-ai-that-reads-your-personality-and-roasts-you-eei</link>
      <guid>https://dev.to/bilal-dev-0x/i-built-an-ai-that-reads-your-personality-and-roasts-you-eei</guid>
      <description>&lt;p&gt;What if an AI could read your personality and roast you at the same time?&lt;/p&gt;

&lt;p&gt;That was the idea behind &lt;strong&gt;MindReader AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;MindReader AI is a fun AI-powered personality scanner built with &lt;strong&gt;Python&lt;/strong&gt; and &lt;strong&gt;Google Gemini&lt;/strong&gt;. It asks you 8 behavioral questions, analyzes your answers, and generates a short, personalized personality report.&lt;/p&gt;

&lt;p&gt;And sometimes…&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"BRO… HOW DID IT KNOW THAT?"💀&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 What Is MindReader AI?
&lt;/h2&gt;

&lt;p&gt;The concept is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answer 8 questions → AI analyzes your behavior → AI exposes you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The questions are designed around everyday situations involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decision making&lt;/li&gt;
&lt;li&gt;Criticism&lt;/li&gt;
&lt;li&gt;Money&lt;/li&gt;
&lt;li&gt;Social situations&lt;/li&gt;
&lt;li&gt;Risk taking&lt;/li&gt;
&lt;li&gt;Relationships&lt;/li&gt;
&lt;li&gt;Overthinking&lt;/li&gt;
&lt;li&gt;Uncertainty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers are sent to Gemini, which analyzes the patterns and generates a personality report.&lt;/p&gt;

&lt;p&gt;The report can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Personality type&lt;/li&gt;
&lt;li&gt;Overthinking score&lt;/li&gt;
&lt;li&gt;Self-awareness score&lt;/li&gt;
&lt;li&gt;Risk-taking score&lt;/li&gt;
&lt;li&gt;Pretending-You-Don't-Care score&lt;/li&gt;
&lt;li&gt;AI observations&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;"Caught"&lt;/strong&gt; moment&lt;/li&gt;
&lt;li&gt;Final verdict&lt;/li&gt;
&lt;li&gt;Confidence score&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't intended to be a scientific psychological assessment.&lt;/p&gt;

&lt;p&gt;It's an entertainment project and an experiment in making AI interaction more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Why Did I Build It?
&lt;/h2&gt;

&lt;p&gt;I didn't want to build another generic AI chatbot.&lt;/p&gt;

&lt;p&gt;There are already approximately &lt;strong&gt;7 billion of those.&lt;/strong&gt; 💀&lt;/p&gt;

&lt;p&gt;I wanted to build something where the &lt;strong&gt;AI's response itself becomes the experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You appear to be moderately introverted."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;MindReader might tell you:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You said you don't care. Your brain immediately opened 17 tabs trying to figure out what they meant."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's much more fun.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 The Roast Factor
&lt;/h2&gt;

&lt;p&gt;This is probably my favorite part of the project.&lt;/p&gt;

&lt;p&gt;I specifically designed the prompt so the AI doesn't produce a boring psychological essay.&lt;/p&gt;

&lt;p&gt;The output is supposed to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Short&lt;/li&gt;
&lt;li&gt;Funny&lt;/li&gt;
&lt;li&gt;Sarcastic&lt;/li&gt;
&lt;li&gt;Relatable&lt;/li&gt;
&lt;li&gt;Personalized&lt;/li&gt;
&lt;li&gt;Slightly brutal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the sections is called:&lt;/p&gt;

&lt;h3&gt;
  
  
  🚨 CAUGHT
&lt;/h3&gt;

&lt;p&gt;This is basically the AI saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Yeah... I noticed that."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🚨 CAUGHT:
You said "I don't care."

Your brain immediately started analyzing
why they said what they said.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal isn't to insult the user.&lt;/p&gt;

&lt;p&gt;It's to create that moment where the result feels &lt;strong&gt;way too relatable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤖 How Does It Work?
&lt;/h2&gt;

&lt;p&gt;The overall flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Answers
     ↓
Question Manager
     ↓
Gemini AI
     ↓
Personality Analysis
     ↓
Personality Report
     ↓
Saved TXT Report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;QuestionManager&lt;/code&gt; handles the questions and user responses.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;PersonalityAnalyzer&lt;/code&gt; prepares the information and sends it to Gemini.&lt;/p&gt;

&lt;p&gt;The generated result is then passed to the report system and saved as a timestamped &lt;code&gt;.txt&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;This separation keeps the application easier to understand and maintain.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Project Architecture
&lt;/h2&gt;

&lt;p&gt;One of the things I wanted to practice with this project was &lt;strong&gt;OOP and separation of responsibilities&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The project is organized roughly 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;MindReader-AI/
│
├── main.py
├── cli.py
├── requirements.txt
│
├── src/
│   ├── analyzer.py
│   ├── questions.py
│   ├── report.py
│   └── config.py
│
├── gui/
│   ├── app.py
│   ├── theme.py
│   ├── parser.py
│   ├── components.py
│   └── views/
│       ├── welcome_view.py
│       ├── question_view.py
│       ├── scanning_view.py
│       └── result_view.py
│
├── prompts/
│   └── personality_prompt.txt
│
└── data/
    └── reports/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact structure may evolve as the project grows, but the main idea remains the same:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UI should not be responsible for everything.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🎨 From CLI to GUI
&lt;/h2&gt;

&lt;p&gt;MindReader originally started as a &lt;strong&gt;CLI application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The terminal version uses &lt;code&gt;Rich&lt;/code&gt; to make the experience more interactive and visually appealing.&lt;/p&gt;

&lt;p&gt;But after getting the core system working, I wanted to turn it into something that actually looked like an AI product.&lt;/p&gt;

&lt;p&gt;So I built a full desktop GUI using &lt;strong&gt;CustomTkinter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The GUI follows this flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Welcome
   ↓
Answer 8 Questions
   ↓
AI Scanning
   ↓
Personality Reveal
   ↓
Saved Report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The visual identity uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deep charcoal background&lt;/li&gt;
&lt;li&gt;Electric purple accents&lt;/li&gt;
&lt;li&gt;Cyan AI/scanner accents&lt;/li&gt;
&lt;li&gt;Rounded cards&lt;/li&gt;
&lt;li&gt;Subtle animations&lt;/li&gt;
&lt;li&gt;Clean typography&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI scanner + psychological mystery + questionable humor.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Every element glowing like it's about to launch a spaceship.&lt;/strong&gt; 😂&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 The AI Scanning Experience
&lt;/h2&gt;

&lt;p&gt;One problem I wanted to avoid was the GUI freezing while waiting for the Gemini response.&lt;/p&gt;

&lt;p&gt;Nobody wants to click a button and stare at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Not Responding...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the AI request runs in the background while the interface remains responsive.&lt;/p&gt;

&lt;p&gt;During the scan, the application can display messages such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Reading behavioral patterns...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connecting personality signals...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Detecting suspicious levels of overthinking...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Preparing your psychological damage...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SCAN COMPLETE ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The waiting period becomes part of the experience instead of looking like the application crashed.&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 CLI Still Works
&lt;/h2&gt;

&lt;p&gt;Even after building the GUI, I didn't want to throw away the original CLI version.&lt;/p&gt;

&lt;p&gt;MindReader now supports both experiences.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎨 GUI
&lt;/h3&gt;

&lt;p&gt;Run the GUI using the project's GUI entry point.&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  💻 CLI
&lt;/h3&gt;

&lt;p&gt;The CLI remains available separately.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This gives the project two different experiences:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GUI:&lt;/strong&gt; A polished desktop application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI:&lt;/strong&gt; A lightweight terminal-based personality scanner.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ Tech Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;The core programming language used throughout the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Gemini API
&lt;/h3&gt;

&lt;p&gt;Used for generating the AI-powered personality analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  CustomTkinter
&lt;/h3&gt;

&lt;p&gt;Used to build the modern desktop GUI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rich
&lt;/h3&gt;

&lt;p&gt;Used to improve the CLI experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  python-dotenv
&lt;/h3&gt;

&lt;p&gt;Used for environment-based configuration and API key management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Object-Oriented Programming
&lt;/h3&gt;

&lt;p&gt;The project uses classes to separate different responsibilities instead of putting everything inside one giant file.&lt;/p&gt;

&lt;p&gt;Because eventually that giant file would probably start reading &lt;strong&gt;my&lt;/strong&gt; personality instead. 💀&lt;/p&gt;




&lt;h2&gt;
  
  
  📄 Saving Personality Reports
&lt;/h2&gt;

&lt;p&gt;Every completed scan can be saved as a timestamped text report.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data/reports/
└── TTT_2026-08-31_19-17-51.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the result isn't lost when the application closes.&lt;/p&gt;

&lt;p&gt;The GUI can also provide access to the generated report.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔐 API Key Security
&lt;/h2&gt;

&lt;p&gt;The Gemini API key is &lt;strong&gt;not hardcoded into the source code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The project uses environment-based configuration so sensitive credentials don't need to be committed to GitHub.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;.env&lt;/code&gt; file should never be pushed to the repository.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GEMINI_API_KEY=your_api_key_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actual API key should remain private.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Handling API Failures
&lt;/h2&gt;

&lt;p&gt;While developing the project, I also encountered Gemini &lt;code&gt;503 UNAVAILABLE&lt;/code&gt; responses when the model was experiencing high demand.&lt;/p&gt;

&lt;p&gt;Instead of immediately crashing the application, the project includes retry handling for temporary API failures.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API Request
     ↓
503 Error?
   ↙     ↘
 YES      NO
 ↓         ↓
Retry    Continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was a good reminder that using an API isn't just about making the first request work.&lt;/p&gt;

&lt;p&gt;You also need to think about what happens when things &lt;strong&gt;don't&lt;/strong&gt; work.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What I Learned
&lt;/h2&gt;

&lt;p&gt;This project taught me much more than just how to call an AI API.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Working With AI APIs
&lt;/h3&gt;

&lt;p&gt;I learned how to structure prompts, provide user context, process generated responses, and handle API failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. OOP in a Real Project
&lt;/h3&gt;

&lt;p&gt;Instead of practicing classes only with tiny examples, I used OOP to structure an actual application.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. GUI Development
&lt;/h3&gt;

&lt;p&gt;Building the GUI made me think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User experience&lt;/li&gt;
&lt;li&gt;Navigation&lt;/li&gt;
&lt;li&gt;Application state&lt;/li&gt;
&lt;li&gt;Background tasks&lt;/li&gt;
&lt;li&gt;Loading states&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Visual feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Separation of Concerns
&lt;/h3&gt;

&lt;p&gt;Keeping the AI logic separate from the UI made the project much easier to work with.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. AI + Software Engineering
&lt;/h3&gt;

&lt;p&gt;The AI may generate the personality analysis, but everything around it still needs proper engineering.&lt;/p&gt;

&lt;p&gt;The API doesn't magically write your architecture for you.&lt;/p&gt;

&lt;p&gt;Unfortunately. 😂&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Example Personality Result
&lt;/h2&gt;

&lt;p&gt;A typical result can look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🧠 MINDREADER AI
SCAN COMPLETE ✓

TYPE:
Professional Overthinker™

📊 BRAIN STATS

Overthinking: 97%
Self-Awareness: 91%
Risk Taking: 31%
Pretending IDC: 94%

🤖 AI SAYS:

You don't make bad decisions.
You simply spend 4 hours making them.

🚨 CAUGHT:

You say "I don't care"
after thinking about it for 3 hours.

💀 FINAL VERDICT:

Emotionally stable.
Mentally running Windows 37.

CONFIDENCE: 94%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact result changes depending on the user's answers.&lt;/p&gt;

&lt;p&gt;That's the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 What I Want to Improve Next
&lt;/h2&gt;

&lt;p&gt;There are still several ideas I'd like to explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More behavioral scenarios&lt;/li&gt;
&lt;li&gt;Additional personality dimensions&lt;/li&gt;
&lt;li&gt;Better result visualization&lt;/li&gt;
&lt;li&gt;Custom question packs&lt;/li&gt;
&lt;li&gt;Historical scan comparisons&lt;/li&gt;
&lt;li&gt;More report export formats&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But I'm intentionally keeping the project focused.&lt;/p&gt;

&lt;p&gt;I don't want MindReader to become some giant psychological platform.&lt;/p&gt;

&lt;p&gt;The goal is still:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A fun AI experiment that makes you question your own decisions. 💀&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎥 See It In Action
&lt;/h2&gt;

&lt;p&gt;I've recorded both versions of MindReader:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI → GUI → AI scanning → personality reveal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The GUI shows the complete user experience, while the CLI demonstrates the original terminal-based version.&lt;/p&gt;

&lt;p&gt;The most important part?&lt;/p&gt;

&lt;p&gt;Waiting to see what the AI is going to say about you. 😂&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Try MindReader AI
&lt;/h2&gt;

&lt;p&gt;The project is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/bilal-dev-0x/MindReader-AI" rel="noopener noreferrer"&gt;MindReader AI&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feel free to explore the code, try the application, or experiment with the personality prompt.&lt;/p&gt;

&lt;p&gt;And if the AI exposes you...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's between you and Gemini. 💀&lt;/strong&gt;&lt;/p&gt;




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

&lt;p&gt;MindReader AI started with a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can I make an AI personality scanner that's actually fun to use?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It eventually became a project where I could combine:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Python&lt;/code&gt; + &lt;code&gt;OOP&lt;/code&gt; + &lt;code&gt;AI APIs&lt;/code&gt; + &lt;code&gt;GUI Development&lt;/code&gt; + &lt;code&gt;File Handling&lt;/code&gt; + &lt;code&gt;Project Architecture&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;into one application.&lt;/p&gt;

&lt;p&gt;It's not a scientific personality test.&lt;/p&gt;

&lt;p&gt;It's not designed to diagnose anyone.&lt;/p&gt;

&lt;p&gt;It's simply an experiment in making AI interaction more entertaining.&lt;/p&gt;

&lt;p&gt;And honestly, the best part is watching someone finish the questions and wait for the result.&lt;/p&gt;

&lt;p&gt;Because sooner or later, there's always that moment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Wait..."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Why is this actually accurate?"&lt;/strong&gt; 💀&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  👨‍💻 Final Question
&lt;/h2&gt;

&lt;p&gt;If you tried MindReader AI, what personality type do you think it would give you?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Professional Overthinker?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Silent Strategist?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chaotic Decision Maker?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or something even worse? 😂&lt;/p&gt;




&lt;p&gt;⭐ If you enjoyed the project, consider giving the repository a star on GitHub.&lt;/p&gt;

&lt;h1&gt;
  
  
  Python #AI #Gemini #GenerativeAI #PythonProjects #OOP #CustomTkinter #GUI #SoftwareDevelopment #AIProjects #BuildInPublic #LearningInPublic
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>CrediSys — Building an AI-Powered Loan Management System in Python</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Sat, 29 Aug 2026 17:57:51 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/credisys-building-an-ai-powered-loan-management-system-in-python-1f0k</link>
      <guid>https://dev.to/bilal-dev-0x/credisys-building-an-ai-powered-loan-management-system-in-python-1f0k</guid>
      <description>&lt;h1&gt;
  
  
  CrediSys — Building an AI-Powered Loan Management System in Python
&lt;/h1&gt;

&lt;p&gt;I recently completed and submitted &lt;strong&gt;CrediSys&lt;/strong&gt;, an AI-powered, terminal-based Loan Management System, to the &lt;strong&gt;Hack The Limit&lt;/strong&gt; hackathon on Devpost.&lt;/p&gt;

&lt;p&gt;This project started with a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if I built a real software system instead of another small Python practice project?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question eventually turned into CrediSys — a system designed around the workflow of a small lending business, from registering customers and issuing loans to tracking repayments, detecting overdue installments, and analyzing business performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What is CrediSys?
&lt;/h2&gt;

&lt;p&gt;CrediSys is a &lt;strong&gt;Python-based Loan Management System&lt;/strong&gt; that manages the complete loan lifecycle from a single terminal application.&lt;/p&gt;

&lt;p&gt;The system includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer management&lt;/li&gt;
&lt;li&gt;Loan plan management&lt;/li&gt;
&lt;li&gt;Loan creation and validation&lt;/li&gt;
&lt;li&gt;Reducing-balance EMI calculations&lt;/li&gt;
&lt;li&gt;Automatic repayment schedules&lt;/li&gt;
&lt;li&gt;Installment payment tracking&lt;/li&gt;
&lt;li&gt;Overdue detection&lt;/li&gt;
&lt;li&gt;Grace-period handling&lt;/li&gt;
&lt;li&gt;Loan status management&lt;/li&gt;
&lt;li&gt;Business analytics&lt;/li&gt;
&lt;li&gt;Monthly data snapshots&lt;/li&gt;
&lt;li&gt;AI-powered staff assistance through &lt;strong&gt;CrediAI&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal wasn't to build a banking application with hundreds of features.&lt;/p&gt;

&lt;p&gt;Instead, I wanted to build a focused system where the core workflow actually makes sense from beginning to end.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧑‍💻 Customer Management
&lt;/h2&gt;

&lt;p&gt;The first part of CrediSys is customer management.&lt;/p&gt;

&lt;p&gt;Users can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register customers&lt;/li&gt;
&lt;li&gt;Validate customer information&lt;/li&gt;
&lt;li&gt;View customer records&lt;/li&gt;
&lt;li&gt;Update customer information&lt;/li&gt;
&lt;li&gt;Prevent deletion of customers with unresolved loans&lt;/li&gt;
&lt;li&gt;Soft-delete eligible completed customers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The system is designed around the Pakistani context, including validation for &lt;strong&gt;Pakistani CNIC and phone-number formats&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One important design decision was using &lt;strong&gt;soft deletion&lt;/strong&gt; for eligible customers instead of permanently removing their records.&lt;/p&gt;

&lt;p&gt;This means historical information can remain available for analytics and record keeping.&lt;/p&gt;




&lt;h2&gt;
  
  
  💰 Loan Management
&lt;/h2&gt;

&lt;p&gt;Once a customer exists, a loan can be created using predefined loan plans.&lt;/p&gt;

&lt;p&gt;Each plan defines rules such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimum loan amount&lt;/li&gt;
&lt;li&gt;Maximum loan amount&lt;/li&gt;
&lt;li&gt;Interest rate&lt;/li&gt;
&lt;li&gt;Loan duration&lt;/li&gt;
&lt;li&gt;Interest calculation method&lt;/li&gt;
&lt;li&gt;Grace period&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When creating a loan, CrediSys validates the requested amount against the selected plan before continuing.&lt;/p&gt;

&lt;p&gt;The system then calculates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly EMI&lt;/li&gt;
&lt;li&gt;Total interest&lt;/li&gt;
&lt;li&gt;Total payable amount&lt;/li&gt;
&lt;li&gt;Number of installments&lt;/li&gt;
&lt;li&gt;Repayment schedule&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📐 Reducing-Balance EMI Calculation
&lt;/h2&gt;

&lt;p&gt;One of the most challenging parts of the project was implementing the reducing-balance EMI calculation correctly.&lt;/p&gt;

&lt;p&gt;Instead of calculating interest on the original principal throughout the entire loan, the interest is calculated based on the remaining principal.&lt;/p&gt;

&lt;p&gt;The standard EMI formula is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EMI = P × r × (1 + r)^n / ((1 + r)^n − 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;P&lt;/code&gt; = Principal amount&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;r&lt;/code&gt; = Monthly interest rate&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;n&lt;/code&gt; = Number of monthly installments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an annual interest rate, the monthly rate is calculated as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;monthly_rate = annual_rate / 100 / 12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I didn't want the application to simply produce an EMI number.&lt;/p&gt;

&lt;p&gt;The loan engine also generates a complete repayment schedule so that every installment contains information about its expected payment and status.&lt;/p&gt;

&lt;p&gt;This was an important learning experience because I had to understand the mathematics behind the calculation instead of treating it as a black box.&lt;/p&gt;




&lt;h2&gt;
  
  
  📅 Repayment Schedules
&lt;/h2&gt;

&lt;p&gt;After creating a loan, CrediSys generates a month-by-month repayment schedule.&lt;/p&gt;

&lt;p&gt;Each installment contains information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installment number&lt;/li&gt;
&lt;li&gt;Due date&lt;/li&gt;
&lt;li&gt;Amount&lt;/li&gt;
&lt;li&gt;Payment status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The schedule allows the application to track the loan throughout its lifecycle.&lt;/p&gt;

&lt;p&gt;This became especially useful when implementing payment recording and overdue detection.&lt;/p&gt;




&lt;h2&gt;
  
  
  💳 Payment Management
&lt;/h2&gt;

&lt;p&gt;CrediSys allows staff to record individual installment payments.&lt;/p&gt;

&lt;p&gt;The system includes validation to prevent things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invalid installment payments&lt;/li&gt;
&lt;li&gt;Duplicate payments&lt;/li&gt;
&lt;li&gt;Paying multiple installments when the workflow expects an individual installment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Payment history can also be viewed for individual loans.&lt;/p&gt;

&lt;p&gt;This helped me understand that financial software isn't simply about storing numbers.&lt;/p&gt;

&lt;p&gt;Every action needs rules.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Overdue Detection &amp;amp; Grace Periods
&lt;/h2&gt;

&lt;p&gt;Another interesting part of the project was implementing overdue detection.&lt;/p&gt;

&lt;p&gt;An installment isn't immediately considered overdue after its due date.&lt;/p&gt;

&lt;p&gt;CrediSys supports a configurable &lt;strong&gt;grace period&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The basic logic is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Due Date
    ↓
Grace Period
    ↓
Still unpaid?
    ↓
Mark as overdue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the system to distinguish between an installment that is simply past its due date and one that has actually exceeded the allowed grace period.&lt;/p&gt;

&lt;p&gt;This was one of the areas where testing different dates and payment states became particularly important.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Business Analytics
&lt;/h2&gt;

&lt;p&gt;CrediSys also includes basic business analytics.&lt;/p&gt;

&lt;p&gt;The system can track information such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customer statistics&lt;/li&gt;
&lt;li&gt;Loan statuses&lt;/li&gt;
&lt;li&gt;Total amount lent&lt;/li&gt;
&lt;li&gt;Total amount recovered&lt;/li&gt;
&lt;li&gt;Outstanding amounts&lt;/li&gt;
&lt;li&gt;Expected interest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also implemented &lt;strong&gt;monthly snapshots&lt;/strong&gt; so historical business data can be compared over time.&lt;/p&gt;

&lt;p&gt;The idea is to eventually make this layer much more sophisticated, but for this version I focused on building a reliable foundation first.&lt;/p&gt;




&lt;h1&gt;
  
  
  🤖 CrediAI
&lt;/h1&gt;

&lt;p&gt;One of the most exciting parts of the project is &lt;strong&gt;CrediAI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;CrediAI is an AI assistant integrated into CrediSys using &lt;strong&gt;Google's Gemini API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It can help staff with tasks such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Answering questions about the system&lt;/li&gt;
&lt;li&gt;Looking up relevant loan information&lt;/li&gt;
&lt;li&gt;Explaining business data in plain English&lt;/li&gt;
&lt;li&gt;Helping users navigate the application&lt;/li&gt;
&lt;li&gt;Generating useful staff-oriented responses and reports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, there is an important architectural decision behind CrediAI.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI does NOT control the financial logic.
&lt;/h3&gt;

&lt;p&gt;Calculations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EMI&lt;/li&gt;
&lt;li&gt;Interest&lt;/li&gt;
&lt;li&gt;Payments&lt;/li&gt;
&lt;li&gt;Repayment schedules&lt;/li&gt;
&lt;li&gt;Overdue detection&lt;/li&gt;
&lt;li&gt;Loan rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;remain controlled by the application's Python logic.&lt;/p&gt;

&lt;p&gt;The AI acts as an &lt;strong&gt;intelligence and assistance layer&lt;/strong&gt;, rather than becoming the source of truth for financial calculations.&lt;/p&gt;

&lt;p&gt;I wanted to keep that separation clear.&lt;/p&gt;




&lt;h1&gt;
  
  
  🏗️ How I Built It
&lt;/h1&gt;

&lt;p&gt;I built CrediSys incrementally rather than trying to implement everything at once.&lt;/p&gt;

&lt;p&gt;The development process roughly looked 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;Customer Management
        ↓
Loan Plans
        ↓
Loan Engine
        ↓
EMI Calculation
        ↓
Repayment Schedules
        ↓
Payment Management
        ↓
Overdue Detection
        ↓
Analytics
        ↓
CrediAI
        ↓
Main Application Integration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach made it easier to test each part before connecting everything together.&lt;/p&gt;

&lt;p&gt;It also helped me understand how individual modules should communicate with each other.&lt;/p&gt;




&lt;h1&gt;
  
  
  🗄️ Why JSON Instead of a Database?
&lt;/h1&gt;

&lt;p&gt;The current version uses &lt;strong&gt;JSON files for persistent storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I know that a relational database would be more appropriate for a larger production system.&lt;/p&gt;

&lt;p&gt;But I deliberately chose JSON for this version.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because I wanted to understand &lt;strong&gt;file-based persistence and data management&lt;/strong&gt; before introducing additional infrastructure.&lt;/p&gt;

&lt;p&gt;For me, this project was also a learning project.&lt;/p&gt;

&lt;p&gt;I didn't want to hide complexity behind tools that I didn't understand yet.&lt;/p&gt;

&lt;p&gt;The next logical step would be migrating the system to something like SQLite or another relational database.&lt;/p&gt;




&lt;h1&gt;
  
  
  😵 Challenges I Faced
&lt;/h1&gt;

&lt;p&gt;This project came with quite a few.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Financial calculations
&lt;/h3&gt;

&lt;p&gt;Getting reducing-balance EMI calculations and repayment schedules right required understanding the actual mathematics behind them.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Payment states
&lt;/h3&gt;

&lt;p&gt;A payment isn't just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;paid = True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are different states and conditions that need to be handled correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Overdue detection
&lt;/h3&gt;

&lt;p&gt;The grace-period logic required careful date handling and testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Data integrity
&lt;/h3&gt;

&lt;p&gt;Deleting customers, modifying loans, and recording payments can affect historical information.&lt;/p&gt;

&lt;p&gt;I had to think about what should and shouldn't be allowed.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. AI integration
&lt;/h3&gt;

&lt;p&gt;Connecting an external AI model was relatively easy compared with figuring out &lt;strong&gt;how it should interact with the existing application without taking control of the core business logic&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Keeping the project manageable
&lt;/h3&gt;

&lt;p&gt;There were always more features I could add.&lt;/p&gt;

&lt;p&gt;At some point I had to stop thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What else can I add?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and start thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What does the system actually need to work properly?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was probably one of the most important lessons from this project.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 What I Learned
&lt;/h1&gt;

&lt;p&gt;CrediSys taught me much more than just Python syntax.&lt;/p&gt;

&lt;p&gt;I learned how important it is to divide a large problem into smaller modules with clear responsibilities.&lt;/p&gt;

&lt;p&gt;I also learned about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data validation&lt;/li&gt;
&lt;li&gt;File handling&lt;/li&gt;
&lt;li&gt;JSON persistence&lt;/li&gt;
&lt;li&gt;Date manipulation&lt;/li&gt;
&lt;li&gt;Financial calculations&lt;/li&gt;
&lt;li&gt;API integration&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Software architecture&lt;/li&gt;
&lt;li&gt;Testing real scenarios&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Git and GitHub&lt;/li&gt;
&lt;li&gt;Designing around business rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But probably the biggest lesson was this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building software is mostly about solving problems and making decisions, not just writing code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There were many times when the code technically worked but the design didn't make sense.&lt;/p&gt;

&lt;p&gt;I had to repeatedly test, break things, rethink the approach, and improve it.&lt;/p&gt;




&lt;h1&gt;
  
  
  🏆 The Biggest Thing I'm Proud Of
&lt;/h1&gt;

&lt;p&gt;I'm most proud that CrediSys became a &lt;strong&gt;complete working workflow instead of a collection of unrelated features&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A typical flow can look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Register Customer
       ↓
Create Loan
       ↓
Calculate EMI
       ↓
Generate Schedule
       ↓
Record Payments
       ↓
Detect Overdue Installments
       ↓
Update Loan Status
       ↓
Analyze Business Data
       ↓
Ask CrediAI for Assistance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything is connected.&lt;/p&gt;

&lt;p&gt;That was the real goal of the project.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔮 What's Next?
&lt;/h1&gt;

&lt;p&gt;CrediSys is only the first version.&lt;/p&gt;

&lt;p&gt;Some improvements I'd like to implement in the future include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated unit tests&lt;/li&gt;
&lt;li&gt;More comprehensive financial validation&lt;/li&gt;
&lt;li&gt;PDF loan statements&lt;/li&gt;
&lt;li&gt;Graphical user interface&lt;/li&gt;
&lt;li&gt;Role-based staff authentication&lt;/li&gt;
&lt;li&gt;Migration from JSON to a relational database&lt;/li&gt;
&lt;li&gt;More advanced analytics&lt;/li&gt;
&lt;li&gt;Better reporting&lt;/li&gt;
&lt;li&gt;Multi-turn conversational memory for CrediAI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't expect to implement all of these immediately.&lt;/p&gt;

&lt;p&gt;The project is meant to evolve alongside my own learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎥 Demo
&lt;/h1&gt;

&lt;p&gt;I also created a short demo showing the main functionality of CrediSys.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://youtu.be/deCN5ALLtwk" rel="noopener noreferrer"&gt;https://youtu.be/deCN5ALLtwk&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  🔗 Project Links
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Devpost:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://devpost.com/software/credisys-ai-powered-loan-management-system" rel="noopener noreferrer"&gt;https://devpost.com/software/credisys-ai-powered-loan-management-system&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/bilal-dev-0x/CrediSys-Loan-Management-System" rel="noopener noreferrer"&gt;https://github.com/bilal-dev-0x/CrediSys-Loan-Management-System&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;CrediSys started as an idea for a serious Python project and became my first hackathon submission.&lt;/p&gt;

&lt;p&gt;It isn't a perfect production banking platform, and I don't claim that it is.&lt;/p&gt;

&lt;p&gt;But that's not what I was trying to build.&lt;/p&gt;

&lt;p&gt;I wanted to understand what it actually feels like to take a real-world problem, break it into smaller problems, turn those problems into software, debug the inevitable mess, and eventually ship something.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CrediSys is my first version of that journey.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And I'm looking forward to building the next one.&lt;/p&gt;

&lt;h1&gt;
  
  
  Python #SoftwareDevelopment #ArtificialIntelligence #Gemini #MachineLearning #Devpost #Hackathon #GitHub #ComputerScience #StudentDeveloper
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Random News Headline Generator in Python 📰😂</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Thu, 18 Dec 2025 14:23:10 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/random-news-headline-generator-in-python-5aeh</link>
      <guid>https://dev.to/bilal-dev-0x/random-news-headline-generator-in-python-5aeh</guid>
      <description>&lt;p&gt;Have you ever wanted to create &lt;strong&gt;funny, political, celebrity, or animal news headlines&lt;/strong&gt; automatically? 📰  &lt;/p&gt;

&lt;p&gt;In this post, I’ll share a simple &lt;strong&gt;Python project&lt;/strong&gt; that generates &lt;strong&gt;random news headlines&lt;/strong&gt;. It's beginner-friendly and a fun way to practice Python programming.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is this project about?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Random News Headline Generator&lt;/strong&gt; is a &lt;strong&gt;Python terminal-based project&lt;/strong&gt; that generates random headlines across four categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Funny News&lt;/strong&gt; 😂
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Political News&lt;/strong&gt; 🏛️
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Celebrity News&lt;/strong&gt; 🌟
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Animal News&lt;/strong&gt; 🐾
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s perfect for beginners who want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practice Python basics
&lt;/li&gt;
&lt;li&gt;Learn &lt;strong&gt;random data generation&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Work with &lt;strong&gt;lists&lt;/strong&gt; and &lt;strong&gt;loops&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create small but fun projects&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Generates &lt;strong&gt;random headlines&lt;/strong&gt; in different categories
&lt;/li&gt;
&lt;li&gt;Simple &lt;strong&gt;terminal interface&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Easy to expand with your own categories
&lt;/li&gt;
&lt;li&gt;Can be improved with file saving, GUI, or web interface
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The project uses &lt;strong&gt;Python lists&lt;/strong&gt; to store headlines and the &lt;strong&gt;random module&lt;/strong&gt; to pick one randomly.  &lt;/p&gt;

&lt;p&gt;Here’s a &lt;strong&gt;simplified example&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import random

funny_news = [
    "Man Tries to Pay With Banana, Cashier Confused",
    "Cat Becomes Mayor of Small Town"
]

political_news = [
    "Election Results Shock Everyone",
    "Politician Forgets Speech on Stage"
]

category = input("Choose category (funny/political): ").lower()

if category == "funny":
    print(random.choice(funny_news))
elif category == "political":
    print(random.choice(political_news))
else:
    print("Category not found!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can expand the lists and categories as much as you want. But For real fun you should check my code at Github....Link is at end of post.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Run the Project
&lt;/h2&gt;

&lt;p&gt;Make sure you have Python 3.x installed&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download or clone the repository:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/bilal-dev-0x/random-news-headline-generator.git
cd random-news-headline-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run the project:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the on-screen instructions to generate random headlines 🎉&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this project is useful&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Even though it’s a small project, it helps you:&lt;/li&gt;
&lt;li&gt;Practice Python loops and lists&lt;/li&gt;
&lt;li&gt;Understand random module usage&lt;/li&gt;
&lt;li&gt;Learn how to structure a small project&lt;/li&gt;
&lt;li&gt;Build something fun and shareable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a great starting point before moving on to GUI apps or web projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Steps / Improvements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add more categories (Sports, Tech, etc.)&lt;/li&gt;
&lt;li&gt;Add file export to save generated headlines&lt;/li&gt;
&lt;li&gt;Convert it into a GUI app using Tkinter&lt;/li&gt;
&lt;li&gt;Share it as a web app using Flask or Streamlit&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This Random News Headline Generator is a fun beginner project that you can finish in a few hours.&lt;/p&gt;

&lt;p&gt;It’s a good addition to your portfolio because it shows you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work with Python basics&lt;/li&gt;
&lt;li&gt;Build small projects&lt;/li&gt;
&lt;li&gt;Think about user interaction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check out the GitHub repo here:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/bilal-dev-0x/Random-Fake-Headline-Generator" rel="noopener noreferrer"&gt;Random News Headline Generator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect with me on LinkedIn:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/bilal-aslam-04a456383/" rel="noopener noreferrer"&gt;Bilal Aslam&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>projects</category>
      <category>fun</category>
    </item>
    <item>
      <title>Build Your Own Jarvis AI Assistant in Python 🚀</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Tue, 30 Sep 2025 03:33:08 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/build-your-own-jarvis-ai-assistant-in-python-421c</link>
      <guid>https://dev.to/bilal-dev-0x/build-your-own-jarvis-ai-assistant-in-python-421c</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Build Your Own Jarvis AI Assistant in Python 🚀&lt;/span&gt;

&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;Python&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://img.shields.io/badge/Python-3.10%2B-3776AB?style=flat-square&amp;amp;logo=python&amp;amp;logoColor=white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;Gemini&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://img.shields.io/badge/Google%20Gemini-API-8B5CF6?style=flat-square&amp;amp;logo=googlegemini&amp;amp;logoColor=white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;Voice Assistant&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://img.shields.io/badge/Voice-Assistant-0EA5E9?style=flat-square&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;![&lt;/span&gt;&lt;span class="nv"&gt;License&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://img.shields.io/badge/License-MIT-22C55E?style=flat-square&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; A beginner-friendly Python voice assistant that listens for the wake word **"Jarvis"**, understands voice commands, performs useful desktop and web actions, and uses **Google Gemini** for AI-powered responses.&lt;/span&gt;
&lt;span class="p"&gt;
---
&lt;/span&gt;
&lt;span class="gu"&gt;## Introduction&lt;/span&gt;

Ever wanted to build your own AI assistant like &lt;span class="gs"&gt;**Jarvis from Iron Man**&lt;/span&gt;?

I started this project as a way to learn Python, APIs, speech recognition, automation, and AI integration by actually building something instead of only following tutorials.

The project has evolved from a simple Python voice assistant into a more capable assistant using &lt;span class="gs"&gt;**Google Gemini**&lt;/span&gt; for AI-powered responses.

Jarvis can:
&lt;span class="p"&gt;
-&lt;/span&gt; 🎤 Listen for the wake word &lt;span class="sb"&gt;`Jarvis`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; 🗣️ Convert speech into text
&lt;span class="p"&gt;-&lt;/span&gt; 🤖 Generate AI responses using Google Gemini
&lt;span class="p"&gt;-&lt;/span&gt; 🔊 Speak responses using text-to-speech
&lt;span class="p"&gt;-&lt;/span&gt; 🌐 Open websites such as YouTube, Google, and Spotify
&lt;span class="p"&gt;-&lt;/span&gt; 🎵 Play songs from a custom music library
&lt;span class="p"&gt;-&lt;/span&gt; 📰 Fetch and read news headlines
&lt;span class="p"&gt;-&lt;/span&gt; 📅 Tell the current date
&lt;span class="p"&gt;-&lt;/span&gt; ⏰ Tell the current time
&lt;span class="p"&gt;-&lt;/span&gt; 💬 Open WhatsApp on Windows
&lt;span class="p"&gt;-&lt;/span&gt; ⚙️ Perform different local automation tasks

The goal is not to create a perfect commercial AI assistant.

The goal is to &lt;span class="gs"&gt;**learn by building**&lt;/span&gt;.
&lt;span class="p"&gt;
---
&lt;/span&gt;
&lt;span class="gh"&gt;# ✨ Features&lt;/span&gt;

&lt;span class="gu"&gt;## 🎤 Wake Word Detection&lt;/span&gt;

Jarvis continuously listens for short audio recordings and waits until it detects:

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;text
&lt;/span&gt;Jarvis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once detected, it responds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Yes Commander?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and starts listening for the actual command.&lt;/p&gt;

&lt;p&gt;The user's title is configurable through:&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;USER_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;Commander&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🗣️ Speech Recognition
&lt;/h2&gt;

&lt;p&gt;The microphone input is recorded using &lt;code&gt;sounddevice&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The recorded audio is then converted into an &lt;code&gt;AudioData&lt;/code&gt; object and passed to &lt;code&gt;SpeechRecognition&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The basic flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microphone
    ↓
sounddevice
    ↓
AudioData
    ↓
SpeechRecognition
    ↓
Text command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives Jarvis the ability to understand spoken commands instead of requiring keyboard input.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤖 Gemini AI Integration
&lt;/h2&gt;

&lt;p&gt;One of the biggest changes in the newer version of Jarvis is the move to &lt;strong&gt;Google Gemini&lt;/strong&gt; for AI-powered responses.&lt;/p&gt;

&lt;p&gt;The project uses Google's modern GenAI SDK:&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;google&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gemini client is initialized using the API key stored in &lt;code&gt;config.json&lt;/code&gt;:&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;genai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gemini_api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Gemini model can also be configured without changing the Python code:&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;"GEMINI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GEMINI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"GEMINI_MODEL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.6-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"NEWS_API_KEY"&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="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;If Jarvis does not recognize a command as one of its built-in actions, it sends the command to Gemini.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain object oriented programming in Python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis sends the request to Gemini and then speaks the generated response.&lt;/p&gt;




&lt;h1&gt;
  
  
  👨‍✈️ Personalized Responses
&lt;/h1&gt;

&lt;p&gt;Jarvis has a configurable user title:&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;USER_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;Commander&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the assistant to address the user naturally.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Yes Commander?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sorry Commander, this song is not in your library.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change this value to:&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;USER_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;Sir&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&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;USER_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;Bilal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  🌐 Web Automation
&lt;/h1&gt;

&lt;p&gt;Jarvis can open commonly used websites directly through Google Chrome.&lt;/p&gt;

&lt;p&gt;Currently supported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open YouTube
Open Google
Open Spotify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open YouTube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis opens YouTube automatically in Chrome.&lt;/p&gt;

&lt;p&gt;The current Chrome path is configured for Windows:&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;chrome_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C:/Program Files/Google/Chrome/Application/chrome.exe %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Chrome is installed somewhere else on your system, this path may need to be changed.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎵 Music Library
&lt;/h1&gt;

&lt;p&gt;Jarvis can play songs from a custom music library.&lt;/p&gt;

&lt;p&gt;Songs are stored separately in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;music_library.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command format is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Play &amp;lt;song name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Play Never Gonna Give You Up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis checks whether the requested song exists in:&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;music_library&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the song exists, Jarvis opens the saved link.&lt;/p&gt;

&lt;p&gt;If it doesn't exist, Jarvis responds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sorry Commander, this song is not in your library.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it easy to customize the assistant with your own songs.&lt;/p&gt;




&lt;h1&gt;
  
  
  📰 News Headlines
&lt;/h1&gt;

&lt;p&gt;Jarvis can fetch the latest headlines using the &lt;strong&gt;News API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Global news
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a valid &lt;code&gt;NEWS_API_KEY&lt;/code&gt; is configured, Jarvis requests the top headlines and reads up to five of them.&lt;/p&gt;

&lt;p&gt;The current implementation uses the Pakistan news endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://newsapi.org/v2/top-headlines?country=pk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Headline 1: ...
Headline 2: ...
Headline 3: ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The News API key is optional.&lt;/p&gt;

&lt;p&gt;If you don't configure it, Jarvis can still be used for its other features.&lt;/p&gt;




&lt;h1&gt;
  
  
  💬 WhatsApp Automation
&lt;/h1&gt;

&lt;p&gt;The Windows version can launch the installed WhatsApp application using PowerShell.&lt;/p&gt;

&lt;p&gt;Command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open WhatsApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis uses Windows' application launcher to find and start the WhatsApp application.&lt;/p&gt;

&lt;p&gt;This feature is currently designed for &lt;strong&gt;Windows&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  📅 Date and Time
&lt;/h1&gt;

&lt;p&gt;Jarvis can provide basic date and time information.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Date
&lt;/h2&gt;

&lt;p&gt;Command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Today date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Today is Friday, 21 August 2026
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The date is generated dynamically using Python's &lt;code&gt;datetime&lt;/code&gt; module.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current Time
&lt;/h2&gt;

&lt;p&gt;Command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis reads the current time aloud.&lt;/p&gt;

&lt;p&gt;It also handles the special case where the minute is exactly &lt;code&gt;00&lt;/code&gt;, responding with an "o'clock" style response.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 AI Fallback
&lt;/h1&gt;

&lt;p&gt;This is one of the most useful parts of the project.&lt;/p&gt;

&lt;p&gt;Jarvis first checks whether a command matches one of its built-in commands.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open YouTube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is handled locally.&lt;/p&gt;

&lt;p&gt;But if the command doesn't match a predefined action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain recursion in Python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis sends it to Gemini.&lt;/p&gt;

&lt;p&gt;The simplified architecture 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;                 ┌──────────────────┐
                 │  Voice Command   │
                 └────────┬─────────┘
                          ↓
                 ┌──────────────────┐
                 │ Speech-to-Text   │
                 └────────┬─────────┘
                          ↓
                 ┌──────────────────┐
                 │  Wake Word Check │
                 └────────┬─────────┘
                          ↓
                 ┌──────────────────┐
                 │  Command Router  │
                 └───────┬───┬──────┘
                         │   │
              Known      │   │      Unknown
              command    │   │      command
                         ↓   ↓
                  ┌──────┐  ┌─────────────┐
                  │Local │  │ Gemini AI   │
                  │Action│  │ Response    │
                  └───┬──┘  └──────┬──────┘
                      │             │
                      └──────┬──────┘
                             ↓
                    ┌────────────────┐
                    │ Text-to-Speech │
                    └────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives Jarvis two different capabilities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Deterministic local commands&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI-powered responses&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  🛠️ Tech Stack
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Purpose&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;Main programming language&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Gemini&lt;/td&gt;
&lt;td&gt;AI-powered responses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;google-genai&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gemini API integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SpeechRecognition&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Speech-to-text recognition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sounddevice&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Microphone recording&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gTTS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Text-to-speech generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pygame-ce&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Audio playback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;requests&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;News API requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;webbrowser&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opening websites&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;subprocess&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Windows application automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;datetime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Date and time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;Configuration and API keys&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  📁 Project Structure
&lt;/h1&gt;

&lt;p&gt;The project currently follows a simple structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jarvis-AI-Virtual-Assistant/
│
├── main.py
├── music_library.py
├── config.json.example
├── requirements.txt
├── .gitignore
├── LICENSE
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main application logic lives inside:&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The music collection is managed separately in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;music_library.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example configuration is stored in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.json.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your real &lt;code&gt;config.json&lt;/code&gt; should remain local and should never be uploaded to GitHub.&lt;/p&gt;




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

&lt;h2&gt;
  
  
  1. Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10 or newer&lt;/li&gt;
&lt;li&gt;A working microphone&lt;/li&gt;
&lt;li&gt;Internet connection&lt;/li&gt;
&lt;li&gt;Google Gemini API key&lt;/li&gt;
&lt;li&gt;Windows if you want to use the WhatsApp launcher&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Clone the Repository
&lt;/h2&gt;

&lt;p&gt;Clone the project from GitHub:&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/bilal-dev-0x/Jarvis-AI-Virtual-Assistant.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then enter the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;Jarvis-AI-Virtual-Assistant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Create a Virtual Environment
&lt;/h2&gt;

&lt;p&gt;Create a virtual environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows PowerShell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\.venv\Scripts\Activate.ps1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Linux/macOS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  📦 4. Install Dependencies
&lt;/h1&gt;

&lt;p&gt;Install the required Python packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This installs the libraries required for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Voice input&lt;/li&gt;
&lt;li&gt;Speech recognition&lt;/li&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;Text-to-speech&lt;/li&gt;
&lt;li&gt;Audio playback&lt;/li&gt;
&lt;li&gt;News API requests&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🔐 5. Configure API Keys
&lt;/h1&gt;

&lt;p&gt;The project uses a local &lt;code&gt;config.json&lt;/code&gt; file for API configuration.&lt;/p&gt;

&lt;p&gt;First create it from the example file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;config.json.example&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;config.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Linux/macOS
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;config.json.example config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add your API keys.&lt;/p&gt;

&lt;p&gt;Example:&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;"GEMINI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GEMINI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"GEMINI_MODEL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.6-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"NEWS_API_KEY"&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="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;
  
  
  Gemini API Key
&lt;/h3&gt;

&lt;p&gt;The Gemini API key is required because Gemini is used for AI fallback responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  News API Key
&lt;/h3&gt;

&lt;p&gt;The News API key is optional.&lt;/p&gt;

&lt;p&gt;It is only required for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Global news
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ Never upload your real API keys to GitHub.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  ▶️ 6. Run Jarvis
&lt;/h1&gt;

&lt;p&gt;Start the assistant with:&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis will initialize and begin listening.&lt;/p&gt;

&lt;p&gt;Say:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Then give it a command.&lt;/p&gt;




&lt;h1&gt;
  
  
  🎯 Example Commands
&lt;/h1&gt;

&lt;p&gt;Here are some commands you can try:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Voice Command&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Hello&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Greets the user&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Open YouTube&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opens YouTube&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Open Google&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opens Google&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Open Spotify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opens Spotify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Play &amp;lt;song&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Plays a song from the music library&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Global news&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reads up to five top Pakistan headlines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Today date&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tells the current date&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Current time&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tells the current time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Open WhatsApp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opens WhatsApp on Windows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Any other question&lt;/td&gt;
&lt;td&gt;Sends the request to Gemini&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Explain Python functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is machine learning?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jarvis can pass those requests to Gemini and speak the response.&lt;/p&gt;




&lt;h1&gt;
  
  
  ⚙️ How The Code Works
&lt;/h1&gt;

&lt;p&gt;The project is divided into several simple pieces.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Recording Audio
&lt;/h2&gt;

&lt;p&gt;The assistant records microphone input using &lt;code&gt;sounddevice&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A simplified version looks like:&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;recording&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rec&lt;/span&gt;&lt;span class="p"&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;seconds&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;sample_rate&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;samplerate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sample_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;channels&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="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;int16&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The recording is then converted into &lt;code&gt;AudioData&lt;/code&gt;:&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;audio_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AudioData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;recording&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tobytes&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;sample_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows &lt;code&gt;SpeechRecognition&lt;/code&gt; to process the recorded audio.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Converting Speech to Text
&lt;/h2&gt;

&lt;p&gt;The recorded audio is sent to Google's speech recognition service:&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;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recognizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recognize_google&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives Jarvis a text representation of what the user said.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Detecting the Wake Word
&lt;/h2&gt;

&lt;p&gt;Jarvis checks whether the recognized text contains:&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;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jarvis&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;command&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it does, Jarvis enters command mode.&lt;/p&gt;

&lt;p&gt;It then responds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Yes Commander?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and records another audio clip for the actual command.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Processing Commands
&lt;/h2&gt;

&lt;p&gt;After the wake word is detected, Jarvis checks several predefined commands.&lt;/p&gt;

&lt;p&gt;For example:&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;elif&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open youtube&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&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;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;webpath&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.youtube.com/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This connects a spoken command directly to a Python automation task.&lt;/p&gt;

&lt;p&gt;Other commands follow the same basic structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Sending Unknown Commands to Gemini
&lt;/h2&gt;

&lt;p&gt;If none of the predefined commands match, Jarvis sends the command to Gemini.&lt;/p&gt;

&lt;p&gt;The project creates a Gemini chat using the configured model:&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;chat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;gemini_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A prompt is then created:&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;prompt&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;
You are Jarvis, a helpful AI virtual assistant.
Give short responses.
Address the user naturally as &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;USER_TITLE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;.

User command: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command is sent to Gemini:&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Gemini returns text, Jarvis speaks the response.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Text-to-Speech
&lt;/h2&gt;

&lt;p&gt;Jarvis uses &lt;code&gt;gTTS&lt;/code&gt; to generate speech:&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;tts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;gTTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&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;The generated audio is saved temporarily:&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;tts&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;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;pygame&lt;/code&gt; plays the generated MP3.&lt;/p&gt;

&lt;p&gt;After playback finishes, the temporary file is removed.&lt;/p&gt;

&lt;p&gt;The file used for temporary speech output is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jarvis_voice.mp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  🧩 Customization
&lt;/h1&gt;

&lt;p&gt;One of the best things about this project is that you can modify it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Change Jarvis' Title
&lt;/h2&gt;

&lt;p&gt;In &lt;code&gt;main.py&lt;/code&gt;:&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;USER_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;Commander&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can change it to:&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;USER_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;Sir&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&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;USER_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;Bilal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Add More Songs
&lt;/h2&gt;

&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;music_library.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add your own songs and links.&lt;/p&gt;

&lt;p&gt;This allows you to create your own personalized music library.&lt;/p&gt;




&lt;h2&gt;
  
  
  Change the Gemini Model
&lt;/h2&gt;

&lt;p&gt;The Gemini model is controlled through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&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;"GEMINI_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"GEMINI_MODEL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gemini-3.6-flash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"NEWS_API_KEY"&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="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;This means you can change the configured model without directly editing the Gemini code in &lt;code&gt;main.py&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Add New Commands
&lt;/h2&gt;

&lt;p&gt;You can extend the command section in &lt;code&gt;main.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&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;elif&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;open github&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&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;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;webpath&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://github.com/&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;Now Jarvis can understand:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open GitHub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and automatically open GitHub.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔒 Security
&lt;/h1&gt;

&lt;p&gt;The project uses a local configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your real API keys should remain there.&lt;/p&gt;

&lt;p&gt;The repository contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.json.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of your actual secrets.&lt;/p&gt;

&lt;p&gt;Make sure &lt;code&gt;.gitignore&lt;/code&gt; excludes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.json
.venv/
__pycache__/
*.pyc
jarvis_voice.mp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never publish API keys in your source code.&lt;/p&gt;




&lt;h1&gt;
  
  
  🖥️ Platform Notes
&lt;/h1&gt;

&lt;p&gt;The current project is primarily designed around a Windows environment.&lt;/p&gt;

&lt;p&gt;Some functionality is platform-specific.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Chrome path is configured for Windows.&lt;/li&gt;
&lt;li&gt;WhatsApp launching uses PowerShell.&lt;/li&gt;
&lt;li&gt;Some desktop automation may need modification on Linux/macOS.&lt;/li&gt;
&lt;li&gt;Microphone recording requires a working input device.&lt;/li&gt;
&lt;li&gt;Speech recognition requires internet access.&lt;/li&gt;
&lt;li&gt;Gemini responses require a valid Gemini API key.&lt;/li&gt;
&lt;li&gt;News fetching requires a News API key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core Python concepts can still be adapted for other platforms.&lt;/p&gt;




&lt;h1&gt;
  
  
  🧠 What I Learned From This Project
&lt;/h1&gt;

&lt;p&gt;This project has been a practical way for me to learn several concepts that are difficult to understand when studying them separately.&lt;/p&gt;

&lt;p&gt;While building Jarvis, I practiced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python functions&lt;/li&gt;
&lt;li&gt;Loops and conditionals&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Working with external libraries&lt;/li&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;JSON configuration&lt;/li&gt;
&lt;li&gt;Speech recognition&lt;/li&gt;
&lt;li&gt;Text-to-speech&lt;/li&gt;
&lt;li&gt;Audio processing&lt;/li&gt;
&lt;li&gt;Web automation&lt;/li&gt;
&lt;li&gt;Windows automation&lt;/li&gt;
&lt;li&gt;AI API integration&lt;/li&gt;
&lt;li&gt;Modular Python projects&lt;/li&gt;
&lt;li&gt;Git and GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More importantly, I learned that a project doesn't have to be perfect before you start building it.&lt;/p&gt;

&lt;p&gt;You can start small and keep improving it.&lt;/p&gt;




&lt;h1&gt;
  
  
  📈 From a Simple Python Project to an AI Assistant
&lt;/h1&gt;

&lt;p&gt;The original idea behind this project was relatively simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Listen → Recognize → Execute
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I learned more Python and started working with APIs, the project gradually became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Listen
   ↓
Speech Recognition
   ↓
Wake Word Detection
   ↓
Command Processing
   ↓
Local Automation OR Gemini AI
   ↓
Text-to-Speech
   ↓
Spoken Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This progression is probably the most valuable part of the project for me.&lt;/p&gt;

&lt;p&gt;It shows how a small beginner project can become a playground for learning new technologies.&lt;/p&gt;




&lt;h1&gt;
  
  
  🚧 Current Limitations
&lt;/h1&gt;

&lt;p&gt;Jarvis is still a learning project, so there are several things I want to improve.&lt;/p&gt;

&lt;p&gt;Some current limitations include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wake-word detection is based on speech recognition rather than a dedicated wake-word engine.&lt;/li&gt;
&lt;li&gt;Some commands are hard-coded.&lt;/li&gt;
&lt;li&gt;Browser paths are currently Windows-specific.&lt;/li&gt;
&lt;li&gt;WhatsApp automation is Windows-specific.&lt;/li&gt;
&lt;li&gt;Internet connectivity is required for speech recognition and Gemini responses.&lt;/li&gt;
&lt;li&gt;The command router can be improved.&lt;/li&gt;
&lt;li&gt;There are currently no automated tests.&lt;/li&gt;
&lt;li&gt;The project does not yet have a graphical interface.&lt;/li&gt;
&lt;li&gt;Pakistani news has a placeholder response in the current release.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These limitations are part of the reason I continue improving the project.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔮 Future Improvements
&lt;/h1&gt;

&lt;p&gt;There are several improvements I would like to make in future versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠 Better command routing&lt;/li&gt;
&lt;li&gt;🎙️ Dedicated offline wake-word detection&lt;/li&gt;
&lt;li&gt;📴 More offline commands&lt;/li&gt;
&lt;li&gt;🖥️ GUI interface&lt;/li&gt;
&lt;li&gt;🛠️ Better error handling&lt;/li&gt;
&lt;li&gt;🧪 Automated testing&lt;/li&gt;
&lt;li&gt;🌍 Cross-platform support&lt;/li&gt;
&lt;li&gt;⚡ Faster voice interaction&lt;/li&gt;
&lt;li&gt;🗂️ Better project architecture&lt;/li&gt;
&lt;li&gt;🔌 More automation integrations&lt;/li&gt;
&lt;li&gt;🤖 More advanced AI capabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project is still evolving, so more features will likely be added as I continue learning.&lt;/p&gt;




&lt;h1&gt;
  
  
  📂 GitHub Repository
&lt;/h1&gt;

&lt;p&gt;The complete source code is available on GitHub:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/bilal-dev-0x/Jarvis-AI-Virtual-Assistant" rel="noopener noreferrer"&gt;&lt;strong&gt;Jarvis AI Virtual Assistant&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to explore the code, fork the project, experiment with it, and build your own version.&lt;/p&gt;




&lt;h1&gt;
  
  
  💡 Final Thoughts
&lt;/h1&gt;

&lt;p&gt;This project started as a way to practice Python.&lt;/p&gt;

&lt;p&gt;It eventually became something much more interesting: a small personal AI assistant that combines &lt;strong&gt;voice recognition, automation, APIs, text-to-speech, and Gemini AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're learning Python, I highly recommend building projects like this.&lt;/p&gt;

&lt;p&gt;You don't need to understand everything before starting.&lt;/p&gt;

&lt;p&gt;Build something.&lt;/p&gt;

&lt;p&gt;Break it.&lt;/p&gt;

&lt;p&gt;Fix it.&lt;/p&gt;

&lt;p&gt;Add another feature.&lt;/p&gt;

&lt;p&gt;Break it again. 😂&lt;/p&gt;

&lt;p&gt;That's how you learn.&lt;/p&gt;

&lt;p&gt;I'm still improving Jarvis as I continue my journey through Python, AI, and Machine Learning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connect With Me
&lt;/h2&gt;

&lt;p&gt;👨‍💻 &lt;strong&gt;GitHub:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/bilal-dev-0x" rel="noopener noreferrer"&gt;https://github.com/bilal-dev-0x&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;LinkedIn:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/bilal-aslam-04a456383/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/bilal-aslam-04a456383/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📝 &lt;strong&gt;DEV.to:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.to/bilal-dev-0x"&gt;https://dev.to/bilal-dev-0x&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Thanks for reading! 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you build your own version of Jarvis, I'd love to see what you add to it.&lt;/p&gt;

&lt;h1&gt;
  
  
  python #ai #gemini #automation #voiceassistant #beginners #programming #pythonprojects #learninginpublic #opensource
&lt;/h1&gt;

</description>
      <category>ai</category>
      <category>aitool</category>
      <category>automation</category>
      <category>beginners</category>
    </item>
    <item>
      <title>📚 AI Study Buddy – Your Smart Text Summarizer (Heroku Back to School AI Challenge)</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Sat, 27 Sep 2025 09:41:37 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/ai-study-buddy-your-smart-text-summarizer-heroku-back-to-school-ai-challenge-2g62</link>
      <guid>https://dev.to/bilal-dev-0x/ai-study-buddy-your-smart-text-summarizer-heroku-back-to-school-ai-challenge-2g62</guid>
      <description>&lt;p&gt;&lt;strong&gt;What I built&lt;/strong&gt;&lt;br&gt;
I built AI Study Buddy, a web app that helps students summarize long texts into clear, short versions. It’s designed for anyone who needs quick understanding of study material without wasting time.&lt;/p&gt;

&lt;p&gt;The app supports multiple summarization algorithms (LexRank, LSA, Luhn, Edmundson), giving flexibility to students and educators who want different styles of summaries.&lt;/p&gt;

&lt;p&gt;It’s deployed on Heroku, making it free and accessible anywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;br&gt;
👉 Live App: &lt;a href="https://ai-study-buddy-challenge-10c223d9b0e6.herokuapp.com/" rel="noopener noreferrer"&gt;https://ai-study-buddy-challenge-10c223d9b0e6.herokuapp.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Screenshots:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fneow8ika2v9ujf8ul1rs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fneow8ika2v9ujf8ul1rs.png" alt=" " width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category Submission:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Student Success (helps students save time, learn faster, and study smarter).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I built it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;: &lt;code&gt;Flask&lt;/code&gt;(Python)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summarization&lt;/strong&gt;: &lt;code&gt;sumy&lt;/code&gt; library with multiple algorithms&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend&lt;/strong&gt;: HTML, CSS, animations&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt;: Heroku (&lt;code&gt;using gunicorn, requirements.txt, Procfile&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;I used Flask to connect the summarization logic with a clean web interface. Students paste their text, choose summarizer type, and get results instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Challenges I ran into&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up Heroku deployment (requirements.txt, Procfile, dynos).&lt;/li&gt;
&lt;li&gt;Debugging package versions and making sure the app runs the same on Heroku as on my PC.&lt;/li&gt;
&lt;li&gt;Styling the app to make it both useful and enjoyable with animations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Accomplishments that I’m proud of&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Got the app running live on Heroku 🚀&lt;/li&gt;
&lt;li&gt;Combined multiple summarization algorithms in one place.&lt;/li&gt;
&lt;li&gt;Built a clean, animated UI that feels smooth and modern.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What I learned&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to deploy Python/Flask apps on Heroku.&lt;/li&gt;
&lt;li&gt;The importance of package management (requirements.txt).&lt;/li&gt;
&lt;li&gt;How different summarization algorithms work.&lt;/li&gt;
&lt;li&gt;What’s next for AI Study Buddy&lt;/li&gt;
&lt;li&gt;Adding support for uploading PDFs and summarizing automatically.&lt;/li&gt;
&lt;li&gt;Integrating AI-powered summaries (transformer-based like BERT or GPT).&lt;/li&gt;
&lt;li&gt;Expanding to multiple languages for international students.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Built with&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Python
- Flask
- Sumy
- HTML
- CSS
- Heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🚀 Submission for:&lt;/strong&gt; Heroku Back to School AI Challenge&lt;/p&gt;

</description>
      <category>herokuchallenge</category>
      <category>python</category>
      <category>flask</category>
      <category>challenge</category>
    </item>
    <item>
      <title>The Classic Number Guessing Game 🔢: A Perfect Python Starter Project 🎯</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Fri, 26 Sep 2025 08:07:40 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/the-classic-number-guessing-game-a-perfect-python-starter-project-5h6m</link>
      <guid>https://dev.to/bilal-dev-0x/the-classic-number-guessing-game-a-perfect-python-starter-project-5h6m</guid>
      <description>&lt;p&gt;&lt;strong&gt;🎯 Project Goal: Learn Python Basics, Loops, and File I/O&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The number guessing game is a rite of passage for every new programmer. It touches on fundamental concepts like &lt;strong&gt;variable assignment&lt;/strong&gt;, &lt;strong&gt;conditional logic&lt;/strong&gt; &lt;strong&gt;&lt;code&gt;($\\text{if}/\\text{elif}/\\text{else}$)&lt;/code&gt;&lt;/strong&gt;, loops &lt;strong&gt;&lt;code&gt;($\\text{while}$)&lt;/code&gt;&lt;/strong&gt;, and (in this advanced version) &lt;strong&gt;file handling&lt;/strong&gt; to save a high score.&lt;/p&gt;

&lt;p&gt;This post will break down the core logic of a Python script for a simple number guessing game that challenges the player to guess a random number between &lt;code&gt;1 and 100&lt;/code&gt; in the fewest attempts possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡️ You can find the complete, runnable code, including setup instructions for the &lt;code&gt;$\\text{Hi-score.txt}$&lt;/code&gt; file, in the accompanying&lt;/strong&gt;: &lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/bilal-dev-0x/Number-guessing-game.git" rel="noopener noreferrer"&gt;https://github.com/bilal-dev-0x/Number-guessing-game.git&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 Code Breakdown: Key Concepts
&lt;/h2&gt;

&lt;p&gt;Let's explore the essential pieces of the game's logic.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Game Setup: Randomness and Initialization
&lt;/h3&gt;

&lt;p&gt;The game begins by selecting a random integer and setting up our counter.&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;random&lt;/span&gt;
&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randint&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="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;guesses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;import random&lt;/code&gt;&lt;/strong&gt;: We use this statement to bring in Python's built-in &lt;strong&gt;&lt;code&gt;$\\text{random}$&lt;/code&gt;&lt;/strong&gt; library.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;random.randint(1, 100)&lt;/code&gt;&lt;/strong&gt;: This line selects the &lt;strong&gt;secret number &lt;code&gt;($\\text{n}$)&lt;/code&gt;&lt;/strong&gt; between &lt;code&gt;1 and 100&lt;/code&gt;, inclusive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;guesses = 0&lt;/code&gt;&lt;/strong&gt;: We initialize our attempt counter. This variable will be the final metric for the player's performance and the number we save to the high score file.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. The Core Logic: The Infinite Loop
&lt;/h3&gt;

&lt;p&gt;The game loop is the heart of the application. We use a &lt;strong&gt;&lt;code&gt;$\\text{while True}$&lt;/code&gt; *&lt;em&gt;loop, which runs indefinitely until a *&lt;/em&gt;&lt;code&gt;$\\text{break}$&lt;/code&gt;&lt;/strong&gt; statement is explicitly encountered.&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;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;guesses&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;a&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="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guess the number : &lt;/span&gt;&lt;span class="sh"&gt;"&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;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Success and game over!
&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;You guessed correct number in &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;guesses&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; attempts.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt; 

    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Clue for the player
&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;Higher number....Please.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# The other clue
&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;Lower number....Please.&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;while True:&lt;/code&gt;&lt;/strong&gt;: Creates the infinite game loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;guesses += 1&lt;/code&gt;&lt;/strong&gt;: Increments the counter with every single guess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;$\\text{if}/\\text{elif}/\\text{else}$&lt;/code&gt;&lt;/strong&gt;: This is the &lt;strong&gt;conditional logic&lt;/strong&gt; that provides the critical feedback loop. If the guess &lt;strong&gt;&lt;code&gt;($\\text{a}$)&lt;/code&gt;&lt;/strong&gt; is correct, we print the result and use &lt;strong&gt;&lt;code&gt;break&lt;/code&gt;&lt;/strong&gt; to exit the loop. Otherwise, the player gets a hint to go &lt;strong&gt;&lt;code&gt;$\\text{Higher}$&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;$\\text{Lower}$&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Performance Review: Conditional Messaging
&lt;/h3&gt;

&lt;p&gt;After the player wins and breaks out of the main loop, we evaluate their score based on a few simple tiers. This is another great use of &lt;strong&gt;&lt;code&gt;$\\text{if}/\\text{elif}/\\text{else}$&lt;/code&gt;&lt;/strong&gt; to provide personalized feedback.&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;if&lt;/span&gt; &lt;span class="n"&gt;guesses&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;10&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;You have done it in some attempts....this is incredible.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;guesses&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20&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;You are doing good....improve it more.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;else&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;Too much attempts .... try to lower the attempts count.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  4. High Score Management: Reading and Writing to a File
&lt;/h3&gt;

&lt;p&gt;This is the most powerful feature of this script, introducing &lt;strong&gt;File I/O&lt;/strong&gt;. It allows the program to remember the best score even after it's closed and re-opened.&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="c1"&gt;# ... first, read the old high score ...
&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi-score.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;r&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;content&lt;/span&gt; &lt;span class="o"&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;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# ... then compare and potentially overwrite ...
&lt;/span&gt;&lt;span class="k"&gt;if&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;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;guesses&lt;/span&gt;&lt;span class="p"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hi-score.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;w&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="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guesses&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;High score is &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;guesses&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reading &lt;code&gt;($\\text{"r"}$ mode)&lt;/code&gt;&lt;/strong&gt;: We open the &lt;strong&gt;&lt;code&gt;$\\text{Hi-score.txt}$&lt;/code&gt;&lt;/strong&gt; file in &lt;strong&gt;read mode&lt;/strong&gt; to fetch the existing record. The &lt;strong&gt;&lt;code&gt;$\\text{with open(...) as f:}$&lt;/code&gt;&lt;/strong&gt; structure is best practice as it ensures the file is always closed automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comparison&lt;/strong&gt;: &lt;strong&gt;&lt;code&gt;if int(content) &amp;gt; guesses:&lt;/code&gt;&lt;/strong&gt; is the core logic. Since lower is better in this game, we check if the &lt;strong&gt;old score &lt;code&gt;($\\text{content}$)&lt;/code&gt;&lt;/strong&gt; is a higher number (worse score) than our &lt;strong&gt;current score &lt;code&gt;($\\text{guesses}$)&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing &lt;code&gt;($\\text{"w"}$ mode)&lt;/code&gt;&lt;/strong&gt;: If we beat the record, we open the file in &lt;strong&gt;write mode&lt;/strong&gt; &lt;strong&gt;&lt;code&gt;($\\text{"w"}$)&lt;/code&gt;&lt;/strong&gt;, which &lt;strong&gt;overwrites&lt;/strong&gt; the old contents with our new, lower score. We must convert the integer &lt;strong&gt;&lt;code&gt;$\\text{guesses}$&lt;/code&gt;&lt;/strong&gt; back to a string using &lt;strong&gt;&lt;code&gt;str(guesses)&lt;/code&gt;&lt;/strong&gt; before writing it to the text file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This simple game covers core programming pillars and offers a great foundation for building more _complex projects_!&lt;/p&gt;

&lt;p&gt;Go ahead and fork the repository, run the code, and try to break your own_ high score_!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;➡️ Find the full Python script and setup instructions here: [&lt;a href="https://github.com/bilal-dev-0x/Number-guessing-game.git" rel="noopener noreferrer"&gt;https://github.com/bilal-dev-0x/Number-guessing-game.git&lt;/a&gt;]&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>python</category>
      <category>github</category>
    </item>
    <item>
      <title>Python Snake-water-gun Game....!</title>
      <dc:creator>Bilal Aslam</dc:creator>
      <pubDate>Thu, 25 Sep 2025 20:27:12 +0000</pubDate>
      <link>https://dev.to/bilal-dev-0x/python-snake-water-gun-game-3omi</link>
      <guid>https://dev.to/bilal-dev-0x/python-snake-water-gun-game-3omi</guid>
      <description>&lt;h2&gt;
  
  
  🐍💧🔫 Building a Snake Water Gun Game in Python — My First Console Game!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🎮 What Is Snake Water Gun?&lt;/strong&gt;&lt;br&gt;
You’ve heard of Rock Paper Scissors — now meet its quirky cousin: Snake Water Gun! It’s a fun little game where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🐍 Snake drinks water&lt;/li&gt;
&lt;li&gt;💧 Water drowns gun&lt;/li&gt;
&lt;li&gt;🔫 Gun shoots snake&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each player picks one of the three, and the winner is decided based on these rules.&lt;/p&gt;

&lt;p&gt;🧠 How I Built It in Python&lt;br&gt;
I wanted to create something simple, interactive, and beginner-friendly. Here's the core logic:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📦 Step 1: Setup Choices&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;computer = random.choice([1, 0, -1])
youstr = input("Enter your choice : ")
youdict = {"s" : 1, "w" : -1, "g" : 0}
reversedict = {1 :"snake", 0 : "gun", -1 :"water"}
you = youdict[youstr]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The computer randomly picks a move.&lt;/li&gt;
&lt;li&gt;The player enters s, w, or g.&lt;/li&gt;
&lt;li&gt;I use dictionaries to map choices to numbers and back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;⚔️ Step 2: Decide the Winner&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if computer == -1 and you == 1:
    print("Snake drinks water 🐍💧")
    print("You win....!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wrote clear &lt;code&gt;if-elif&lt;/code&gt; conditions for every possible matchup.&lt;br&gt;
Emojis make the output more fun and readable!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 How to Play&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clone the repo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash
git clone https://github.com/bilal-dev-0x/Snake-water-gun-Game.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run the game:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash
python snake_water_gun.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter your move: s for snake, w for water, g for gun.&lt;/p&gt;

&lt;p&gt;💡 What I Learned&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to use &lt;code&gt;random.choice()&lt;/code&gt; for unpredictability.&lt;/li&gt;
&lt;li&gt;Mapping inputs with dictionaries for clean code.&lt;/li&gt;
&lt;li&gt;Writing readable and fun console output.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🔗 Try It Yourself!&lt;br&gt;
Check out the full code on GitHub: &lt;br&gt;
&lt;a href="https://github.com/bilal-dev-0x/Snake-water-gun-Game.git" rel="noopener noreferrer"&gt;https://github.com/bilal-dev-0x/Snake-water-gun-Game.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>gamedev</category>
      <category>developer</category>
    </item>
  </channel>
</rss>
