<?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: Yassine Sallami</title>
    <description>The latest articles on DEV Community by Yassine Sallami (@yassinesallami).</description>
    <link>https://dev.to/yassinesallami</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2261297%2F39f59dbe-8d71-4e9e-be49-afe0a8fb249f.jpg</url>
      <title>DEV Community: Yassine Sallami</title>
      <link>https://dev.to/yassinesallami</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yassinesallami"/>
    <language>en</language>
    <item>
      <title>📈✨9 Free (or access option) computer science courses for building your skills!</title>
      <dc:creator>Yassine Sallami</dc:creator>
      <pubDate>Fri, 01 Nov 2024 18:51:05 +0000</pubDate>
      <link>https://dev.to/yassinesallami/9-free-or-access-option-computer-science-courses-for-building-your-skills-244e</link>
      <guid>https://dev.to/yassinesallami/9-free-or-access-option-computer-science-courses-for-building-your-skills-244e</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://pll.harvard.edu/course/cs50-introduction-computer-science" rel="noopener noreferrer"&gt;Harvard CS50&lt;/a&gt;&lt;/strong&gt;: Introduction to Computer Science (edX)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A comprehensive intro to CS, covering everything from algorithms to web development.&lt;/li&gt;
&lt;/ul&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%2Fcjgayumyfz7jxwfyrexi.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%2Fcjgayumyfz7jxwfyrexi.png" alt="Harvard CS50" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.coursera.org/specializations/python?utm_medium=sem&amp;amp;utm_source=gg&amp;amp;utm_campaign=b2c_emea__coursera_ftcof_career-academy_arte_march_24_dr_geo-multi-set3_pmax_gads_lg-all&amp;amp;campaignid=21103949440&amp;amp;adgroupid=&amp;amp;device=c&amp;amp;keyword=&amp;amp;matchtype=&amp;amp;network=x&amp;amp;devicemodel=&amp;amp;adposition=&amp;amp;creativeid=&amp;amp;hide_mobile_promo=&amp;amp;gad_source=1&amp;amp;gclid=CjwKCAjw-JG5BhBZEiwAt7JR6xfo1Z6GXCn6QEpF1KMc-xnsP-NSE3o2K2XxdWEXdvxkTzyhYW4HNRoCHl8QAvD_BwE" rel="noopener noreferrer"&gt;Python for Everybody&lt;/a&gt;&lt;/strong&gt; (Coursera, University of Michigan)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perfect for beginners wanting to learn Python and programming fundamentals.&lt;/li&gt;
&lt;/ul&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%2Fat774ppdunuskcut6dnk.jpg" 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%2Fat774ppdunuskcut6dnk.jpg" alt="Python for Everybody" width="686" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.coursera.org/specializations/algorithms" rel="noopener noreferrer"&gt;Algorithms Specialization&lt;/a&gt;&lt;/strong&gt; (Coursera, Stanford University)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dive deep into core CS algorithms with hands-on problem-solving.&lt;/li&gt;
&lt;/ul&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%2Fj4kh8r2c7w8h99mzplcu.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%2Fj4kh8r2c7w8h99mzplcu.png" alt="Algorithms Specialization" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.kaggle.com/code/usengecoder/introduction-to-data-science" rel="noopener noreferrer"&gt;Introduction to Data Science&lt;/a&gt;&lt;/strong&gt; (Kaggle)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Covers Python basics, data visualization, and data analysis.&lt;/li&gt;
&lt;/ul&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%2Fai80pietcxzsvxk79pom.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%2Fai80pietcxzsvxk79pom.png" alt="Introduction to Data Science" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.udacity.com/course/intro-to-artificial-intelligence--cs271" rel="noopener noreferrer"&gt;Introduction to Artificial Intelligence&lt;/a&gt;&lt;/strong&gt; (Udacity)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A beginner's course on AI covering search algorithms, knowledge representation, and more.&lt;/li&gt;
&lt;/ul&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%2F8oq544486g4ycpx7r3ke.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%2F8oq544486g4ycpx7r3ke.png" alt="Introduction to Artificial Intelligence" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.coursera.org/learn/machine-learning" rel="noopener noreferrer"&gt;Machine Learning&lt;/a&gt;&lt;/strong&gt; (Coursera, Andrew Ng)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A highly popular course explaining ML concepts in a simple, beginner-friendly way.&lt;/li&gt;
&lt;/ul&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%2F08h4rmceuurgirog96oh.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%2F08h4rmceuurgirog96oh.png" alt="Machine Learning" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML, CSS, and JavaScript for Web Developers&lt;/strong&gt; (Coursera, Johns Hopkins University)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn the basics of web development and start building web pages.&lt;/li&gt;
&lt;/ul&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%2F228iy1sbkqfx2ddkurye.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%2F228iy1sbkqfx2ddkurye.png" alt="HTML, CSS, and JavaScript for Web Developers" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.edx.org/learn/cybersecurity/university-of-washington-introduction-to-cybersecurity?webview=false&amp;amp;campaign=Introduction+to+Cybersecurity&amp;amp;source=edx&amp;amp;product_category=course&amp;amp;placement_url=https%3A%2F%2Fwww.edx.org%2Fschool%2Fuwashingtonx" rel="noopener noreferrer"&gt;Introduction to Cybersecurity&lt;/a&gt;&lt;/strong&gt; (University of Washington, edX)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Covers essential concepts in digital security and data protection.&lt;/li&gt;
&lt;/ul&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%2Falbegtf1atrwfb8vf8yg.jpg" 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%2Falbegtf1atrwfb8vf8yg.jpg" alt="Introduction to Cybersecurity" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.coursera.org/professional-certificates/google-it-automation" rel="noopener noreferrer"&gt;Google IT Automation with Python&lt;/a&gt;&lt;/strong&gt; (Coursera)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Develop Python skills to automate tasks and solve real-world problems.&lt;/li&gt;
&lt;/ul&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%2F5wezjw916ekmmdg4685l.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%2F5wezjw916ekmmdg4685l.png" alt="Google IT Automation with Python" width="768" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>learning</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🛠️ Command Line Tips for Boosting Efficiency</title>
      <dc:creator>Yassine Sallami</dc:creator>
      <pubDate>Sat, 26 Oct 2024 21:41:00 +0000</pubDate>
      <link>https://dev.to/yassinesallami/command-line-tips-for-boosting-efficiency-4i9j</link>
      <guid>https://dev.to/yassinesallami/command-line-tips-for-boosting-efficiency-4i9j</guid>
      <description>&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%2Fn455z6jlqdqfjooewbpm.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%2Fn455z6jlqdqfjooewbpm.png" alt="Command Line Tips for Boosting Efficiency" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ever found yourself needing to search through your command history? Here are some quick tricks to make your terminal life easier:&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;Search History&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can instantly rerun your last command by typing !!. Want to search for a specific command you ran? Pair history with grep:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ history | grep conda
3 conda activate dnakey
5 history | grep conda
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need only your last few commands? Try using tail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ history | tail -n 3
4 history
5 history | grep conda
6 history | tail -n 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 &lt;strong&gt;Quick Command Fix&lt;/strong&gt;&lt;br&gt;
Made a typo in your last command? Use ^oldtext^newtext^ to replace part of it without retyping everything. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ ^conda^pip^&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This reruns the previous command, but with conda replaced by pip.&lt;/p&gt;

&lt;p&gt;🧹 &lt;strong&gt;Cleaning Up History&lt;/strong&gt;&lt;br&gt;
Need to delete a specific command from your history? Just specify the line number:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ history -d &amp;lt;line number&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or clear your entire history file with &lt;code&gt;history -c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These shortcuts make navigating your command history faster and more efficient.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>coding</category>
      <category>productivity</category>
    </item>
    <item>
      <title>#? List vs Tuples in python</title>
      <dc:creator>Yassine Sallami</dc:creator>
      <pubDate>Sat, 26 Oct 2024 00:34:39 +0000</pubDate>
      <link>https://dev.to/yassinesallami/-list-vs-tuples-in-python-2m3n</link>
      <guid>https://dev.to/yassinesallami/-list-vs-tuples-in-python-2m3n</guid>
      <description>&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%2F5e06n92v9rvxn1zcc2p9.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%2F5e06n92v9rvxn1zcc2p9.png" alt="List vs Tuples in python" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Python, Lists and Tuples are both sequence data types that can store collections of items, but they have some crucial differences that impact performance, flexibility, and usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Mutability&lt;/strong&gt;&lt;br&gt;
Lists are mutable, meaning you can modify, add, or remove items after creation.&lt;br&gt;
Tuples are immutable, so once created, their elements cannot be changed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Syntax&lt;/strong&gt;&lt;br&gt;
Lists use square brackets: a = [1, 2, 3, 4, 5]&lt;br&gt;
Tuples use parentheses: b = (1, 2, 3, 4, 5)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Performance&lt;/strong&gt;&lt;br&gt;
Tuples are generally faster than lists due to their immutability.&lt;br&gt;
If you don’t need to modify the data, using a tuple can make your code slightly more efficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Use Cases&lt;/strong&gt;&lt;br&gt;
Lists are preferred for collections that require frequent updates, like adding, removing, or changing items.&lt;br&gt;
Tuples are best for fixed data collections, like storing coordinates (x, y) or returning multiple values from a function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Methods&lt;/strong&gt;&lt;br&gt;
Lists have more built-in methods like .append(), .remove(), .reverse(), which allow in-place modifications.&lt;br&gt;
Tuples have fewer methods since they are immutable.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>python</category>
      <category>productivity</category>
    </item>
    <item>
      <title>📛Stop Hardcoding Database Calls: Simplify with a Config Manager</title>
      <dc:creator>Yassine Sallami</dc:creator>
      <pubDate>Fri, 25 Oct 2024 00:55:42 +0000</pubDate>
      <link>https://dev.to/yassinesallami/stop-hardcoding-database-calls-simplify-with-a-config-manager-1m3o</link>
      <guid>https://dev.to/yassinesallami/stop-hardcoding-database-calls-simplify-with-a-config-manager-1m3o</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Working with &lt;a href="//mongodb.com"&gt;databases&lt;/a&gt; is inevitable in any modern software project. However, hardcoding database connections and operations in your main code can lead to poor scalability, difficult maintenance, and security issues. To combat these challenges, consider creating a Config Manager to handle all interactions with your database efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In this post, we'll walk through the advantages of using a Config Manager and how it can be implemented. Let’s start by looking at an example in Python using MongoDB and &lt;a href="//streamlit.app"&gt;Streamlit&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Why You Shouldn't Call Your Database Directly&lt;/strong&gt;&lt;br&gt;
When your application grows, having direct database calls littered throughout the code can cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hard to manage changes:&lt;/strong&gt; If you need to change database settings or schema, you have to search through your codebase to modify each instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lack of centralized error handling:&lt;/strong&gt; Error-prone operations, such as connecting to the database or handling connection timeouts, become harder to manage when scattered.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tight coupling:&lt;/strong&gt; Direct database operations in the main code introduce tight coupling, making the code harder to test and refactor.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To avoid these issues, you should encapsulate database operations inside a Config Manager.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;What is a Config Manager?&lt;/strong&gt;&lt;br&gt;
A Config Manager is a class or module that centralizes all database operations, handles error management, and makes your code more modular. It abstracts the details of the database, providing clean methods to interact with it.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Example: MongoDB Config Manager&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 streamlit as st
from pymongo import MongoClient
from pymongo.errors import ServerSelectionTimeoutError, AutoReconnect
from dotenv import load_dotenv
import os, datetime

load_dotenv()

# Get MongoDB URI from environment variables
mongo_uri = os.getenv("MONGODB_URI")

class ConfigManager:
    def __init__(self, user_id: str, db_name: str = "your_database", collection_name: str = "your_collection") -&amp;gt; None:
        self.user_id = user_id
        self.client = self.connect_to_mongo(mongo_uri)

        if self.client:
            self.db = self.client[db_name]
            self.collection = self.db[collection_name]
            self.user = self.collection.find_one({"badge_id": self.user_id})
            self.create_date = datetime.datetime.now()
            self.formatted_datetime = self.create_date.isoformat()

            if not self.user:
                self.add_new_user()
                self.user = self.collection.find_one({"badge_id": self.user_id})
        else:
            st.toast(":red[Failed to connect to MongoDB. User initialization aborted.]")

    def connect_to_mongo(self, uri, retries=3):
        client = None
        for attempt in range(retries):
            try:
                print(f"Attempting to connect to MongoDB (Attempt {attempt + 1})")
                client = MongoClient(uri, serverSelectionTimeoutMS=20000)
                client.server_info()  # Will raise an exception if unable to connect
                print("Connection to MongoDB successful.")
                return client
            except ServerSelectionTimeoutError as err:
                print(f"Connection attempt {attempt + 1} failed: {err}")
            except AutoReconnect as err:
                print(f"AutoReconnect error on attempt {attempt + 1}: {err}")
        print(f"Failed to connect to MongoDB after {retries} attempts.")
        return None

    def add_new_user(self):
        new_user = {
            "badge_id": self.user_id,
            "created_at": self.formatted_datetime,
            "badge_usage": 0,
            "created_docs": 0,
            "limitation": 10,
            "doc_params": self._get_default_doc_params(),
            "security": self._get_default_security(),
            "user_activity": {"vault": [], "action_merge": []}
        }
        self.collection.insert_one(new_user)

    def _get_default_doc_params(self) -&amp;gt; dict:
        return {
            "includes": ["upper", "lower", "number", "symbol", "arabic"],
            "input": {"length": {"max": 13, "min": 3}, "types": ["text", "image", "pdf", "audio", "video"]}
        }

    def _get_default_security(self) -&amp;gt; dict:
        return {"encryption": "cryptography.fernet", "encrypted_data": "json format", "file_extension": ".dkp"}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Features of the Config Manager&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Centralized Database Handling:&lt;/strong&gt; The ConfigManager is responsible for connecting to the MongoDB database. By abstracting this logic, you ensure that the rest of the application doesn’t need to worry about connection details or handling retries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automatic User Initialization:&lt;/strong&gt; When a user (in this case identified by user_id) interacts with the application, the manager checks if the user exists in the database. If not, it automatically creates a new user record, maintaining consistency in your database operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Retry Logic:&lt;/strong&gt; The &lt;code&gt;connect_to_mongo()&lt;/code&gt; method includes a retry mechanism for connection failures. This reduces the likelihood of total failure and ensures resilience in unstable network environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separation of Concerns:&lt;/strong&gt; The rest of the application doesn’t need to know about database internals, reducing dependencies and making it easier to modify database behavior in the future.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Benefits of Using a Config Manager&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier Maintenance:&lt;/strong&gt; By having all database interactions in one place, it’s easier to update or debug any issues related to the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Handling:&lt;/strong&gt; With a Config Manager, you can define custom error-handling logic that applies to all database interactions, avoiding unexpected crashes due to database timeouts or connection issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt; When your project grows, you won’t need to refactor code scattered across different modules. You can easily add new database operations or modify existing ones in the manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enhanced Security:&lt;/strong&gt; Database URIs and other sensitive information are abstracted away from the main code and retrieved securely using environment variables.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Config Manager is essential for building scalable and maintainable applications that interact with databases. It allows you to centralize connection logic, error handling, and security concerns. By abstracting these details away from the main code, you create a cleaner, more modular, and future-proof project structure.&lt;/p&gt;

&lt;p&gt;Instead of hardcoding database operations in your main application, invest in building a Config Manager and see the difference it makes in your code’s cleanliness and maintainability.&lt;/p&gt;

&lt;p&gt;Thank you for reading my post :)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>cleancode</category>
      <category>python</category>
    </item>
    <item>
      <title>How to create an image authentication system with python streamlit and canva!</title>
      <dc:creator>Yassine Sallami</dc:creator>
      <pubDate>Wed, 23 Oct 2024 22:54:04 +0000</pubDate>
      <link>https://dev.to/yassinesallami/how-to-create-an-image-authentication-system-with-python-streamlit-and-canva-3lk0</link>
      <guid>https://dev.to/yassinesallami/how-to-create-an-image-authentication-system-with-python-streamlit-and-canva-3lk0</guid>
      <description>&lt;p&gt;&lt;strong&gt;The includes&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 streamlit as st
import # your database manager here!
from cryptography.fernet import Fernet
from PIL import Image, PngImagePlugin
import base64, hashlib, uuid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize a session with streamlit if you want to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def initialize_session_state():
   pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The main script:&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;class BadgeConfig:
        def __init__(self):
          initialize_session_state()
          # Ensure badge_id is stored as a class attribute
          self.badge_id = None

        # Generate a SHA-256 hash from image data
        def generate_image_hash(self, image_data):
            return hashlib.sha256(image_data).hexdigest()

        # Create the encryption signature using Fernet
        def create_signature(self, unique_id):
            id_image_bytes = unique_id.encode("utf-8")
            # Ensure 32-byte length
            padded_id_image_bytes = id_image_bytes.ljust(32)[:32] 
            encoded_key = base64.urlsafe_b64encode(padded_id_image_bytes)
            return Fernet(encoded_key)

        # Check if image was created on Canva using PngImagePlugin
        def is_canva_image(self, image):
            if isinstance(image, PngImagePlugin.PngImageFile):
                # Extract metadata from the image
                metadata = image.info  # Info contains the metadata

                # Checking if 'Canva' appears in the 'xmp:CreatorTool' field
                xmp_metadata = metadata.get('XML:com.adobe.xmp', '')
                if "Canva" in xmp_metadata:
                    return True
                return False

        # Display the uploaded badge and validate its dimensions and source
        def process_image(self, user_badge):
            try:
                image = Image.open(user_badge)
                WIDTH, HEIGHT = image.size
                if WIDTH != 1080 or HEIGHT != 1920:
                    st.warning("This is not a valid dnakey-badge!")
                    st.stop()

                # Check if the image is created on Canva
                if not self.is_canva_image(image):
                    st.warning("The uploaded image is not a Canva PNG image!")
                    st.stop()

                st.image(user_badge, caption="Uploaded Image", use_column_width=True)

                # Reset the file pointer and read the image data for hashing
                user_badge.seek(0)
                return user_badge.read()
            except Exception as e:
                st.error(f"Error processing the image: {str(e)}")
                st.stop()

        # Handle badge activation and update session
        def activate_badge(self, badge_usage, config_manager):
            if not st.session_state['toast_shown']:
                st.toast("**:blue[Your Id Badge is activated now!]**", icon="🧁")
                st.session_state['toast_shown'] = True

            if not st.session_state['usage_updated'] and badge_usage &amp;gt; 0:
                config_manager.update_usage_badge_count()
                st.session_state['usage_updated'] = True

        # Main function to create a session and handle badge logic
        def create_session(self, user_badge):
            # Process image and generate its unique ID
            image_data = self.process_image(user_badge)
            unique_id = self.generate_image_hash(image_data)

            # Create an encryption signature
            signature = self.create_signature(unique_id)

            # Create a UUID (version 5) based on the existing unique_id
            self.badge_id = str(uuid.uuid5(uuid.NAMESPACE_DNS, unique_id))

            # Initialize config manager
            config_manager = ConfigManager(self.badge_id)
            badge_usage = config_manager.get_badge_usage()

            # Handle badge activation and session updates
            self.activate_badge(badge_usage, config_manager)

            return signature, self.badge_id  # Return the badge_id as well

# call the script
with st.sidebar:
     st.title("Log-In Here:")
     with st.popover("Upload Your Agent Badge!", use_container_width=True):
     user_badge = st.file_uploader("Your Agent Badge!", type=["png"], key="agent_badge")

     if user_badge:
        # User badge is uploaded
        signature, badge_id = BadgeConfig().create_session(user_badge)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>python</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Introducing the DNA-KEY System: Taking the Password Generator to the Next Level! 🔐</title>
      <dc:creator>Yassine Sallami</dc:creator>
      <pubDate>Wed, 23 Oct 2024 21:49:46 +0000</pubDate>
      <link>https://dev.to/yassinesallami/introducing-the-dna-key-system-taking-the-password-generator-to-the-next-level-52la</link>
      <guid>https://dev.to/yassinesallami/introducing-the-dna-key-system-taking-the-password-generator-to-the-next-level-52la</guid>
      <description>&lt;p&gt;🚀 Introducing the DNA-KEY System: Taking the Password Generator to the Next Level! 🔐&lt;/p&gt;

&lt;p&gt;Our innovative DNA-KEY system integrates cryptographic techniques to ensure document integrity and protection (the document acts like a brain 🧠). Here’s a sneak peek of how it works:&lt;/p&gt;

&lt;p&gt;🖼️ Badge Verification:&lt;br&gt;
Your user badge (image type) is transformed into a unique hash, which is then turned into a user ID and a signature for the document, ensuring only original images are accepted.&lt;/p&gt;

&lt;p&gt;🔒 Document Validation:&lt;br&gt;
Documents are securely linked to badge IDs, with a checksum ensuring data consistency. The engine creates smart documents that are compressed, encrypted, and personalized with the user’s signature.&lt;/p&gt;

&lt;p&gt;🧑‍💻 Complex Password Generation:&lt;br&gt;
A text or hybrid input system (more on the hybrid type next time!) turns simple keys into complex passwords, ensuring top-tier security for every document.&lt;/p&gt;

&lt;p&gt;📂 Database Integration:&lt;br&gt;
Store and track user activity, document IDs, and checksums for robust auditing and transparency.&lt;br&gt;
Note: Dna-Key does not store your signature.&lt;/p&gt;

&lt;p&gt;Stay tuned for more updates on how the DNA-KEY system is pushing the boundaries of security!&lt;br&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%2F6vyky3afhgd7dp6b8scm.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%2F6vyky3afhgd7dp6b8scm.png" alt="Image description" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>security</category>
      <category>python</category>
    </item>
  </channel>
</rss>
