<?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: dhruv</title>
    <description>The latest articles on DEV Community by dhruv (@drvcodenta).</description>
    <link>https://dev.to/drvcodenta</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%2F1197999%2Ffb6d7e82-71b7-4955-8571-4942b32f84e3.png</url>
      <title>DEV Community: dhruv</title>
      <link>https://dev.to/drvcodenta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/drvcodenta"/>
    <language>en</language>
    <item>
      <title>One Dockerfile, Two Stages: A 50% Size Reduction Story</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Mon, 03 Nov 2025 04:43:44 +0000</pubDate>
      <link>https://dev.to/drvcodenta/one-dockerfile-two-stages-a-50-size-reduction-story-l70</link>
      <guid>https://dev.to/drvcodenta/one-dockerfile-two-stages-a-50-size-reduction-story-l70</guid>
      <description>&lt;h1&gt;
  
  
  The Power of Simple Optimizations
&lt;/h1&gt;

&lt;p&gt;Sometimes the most impactful improvements come from stepping back and rethinking your approach. One of my pull request demonstrates this perfectly: &lt;strong&gt;32 lines added, 23 removed, and a Docker image that's half the size with 72% fewer security vulnerabilities.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's break down exactly what changed and why it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image size: 2.04 GB&lt;/li&gt;
&lt;li&gt;Security vulnerabilities: 290+&lt;/li&gt;
&lt;li&gt;Build approach: Single-stage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Image size: ~900 MB (50% reduction)&lt;/li&gt;
&lt;li&gt;Security vulnerabilities: ~80 (72% reduction)&lt;/li&gt;
&lt;li&gt;Build approach: Multi-stage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code changed:&lt;/strong&gt; 1 file, net +9 lines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;---
&lt;/span&gt;
&lt;span class="gu"&gt;## The Five Critical Insights&lt;/span&gt;

&lt;span class="gu"&gt;### 1. The Slim Base Image Difference&lt;/span&gt;

&lt;span class="gs"&gt;**Before:**&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;
&lt;/span&gt;
dockerfile
FROM python:3.11.2


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
# Stage 1: Build
FROM python:3.11.2 AS builder

# Stage 2: Runtime
FROM python:3.11.2-slim


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Learning:&lt;/strong&gt; The difference between &lt;code&gt;python:3.11.2&lt;/code&gt; and &lt;code&gt;python:3.11.2-slim&lt;/code&gt; is substantial. The full image includes compilers, build tools, and system utilities you don't need at runtime. The slim variant strips these away.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Impact:&lt;/strong&gt; This single change likely contributed 40–50% of the total size reduction.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2. Separate Build and Runtime Concerns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before: Everything in one stage&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
RUN pip install poetry \\
    &amp;amp;&amp;amp; poetry config virtualenvs.create false \\
    &amp;amp;&amp;amp; poetry install
# ...poetry stays in final image


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;After: Two distinct stages&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
# Stage 1: Install and build
FROM python:3.11.2 AS builder
RUN pip install poetry
RUN poetry install

# Stage 2: Copy only what's needed
FROM python:3.11.2-slim
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Learning:&lt;/strong&gt; Build tools don't need to ship to production. Poetry, compilers, and development headers are essential for installation but deadweight at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Eliminates build dependencies from the final image while keeping all functionality.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Layer Consolidation Matters
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Multiple separate apt-get update calls&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
RUN apt-get update &amp;amp;&amp;amp; \\
    apt-get install -y postgresql-client libpq-dev &amp;amp;&amp;amp; \\
    rm -rf /var/lib/apt/lists/*

RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \\
    libmemcached11 \\
    libmemcachedutil2 \\
    libmemcached-dev \\
    libz-dev

RUN apt-get update &amp;amp;&amp;amp; apt-get install -y dos2unix


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; Consolidated installation&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
RUN apt-get update &amp;amp;&amp;amp; \\
    apt-get install -y postgresql-client libpq-dev \\
    libmemcached11 libmemcachedutil2 libmemcached-dev libz-dev \\
    dos2unix &amp;amp;&amp;amp; \\
    rm -rf /var/lib/apt/lists/*


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Learning:&lt;/strong&gt; Each &lt;code&gt;RUN&lt;/code&gt; command creates a new layer. Multiple apt-get update calls mean multiple cached package lists. Consolidating reduces both layer count and duplicate data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Smaller image size and better cache utilization during builds.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Copy Strategy Optimization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Copy everything early&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
WORKDIR /blt
COPY . /blt
# ...then install dependencies


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; Copy dependencies first, code last&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
# Stage 1
COPY pyproject.toml poetry.lock* ./
RUN poetry install

# Stage 2
COPY . /blt


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Learning:&lt;/strong&gt; Docker caches layers. If you copy your entire application before installing dependencies, every code change invalidates the dependency installation cache. Copying dependency files first means dependencies only reinstall when they actually change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Faster builds during development and CI/CD.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Runtime vs. Build Dependencies
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; All dependencies in final image&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
libmemcached-dev  # Development headers
libz-dev          # Development headers


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; Only runtime dependencies in final stage&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
dockerfile
# Builder: libmemcached-dev libz-dev
# Runtime: libmemcached11 libmemcachedutil2


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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Learning:&lt;/strong&gt; Development headers (&lt;code&gt;-dev&lt;/code&gt; packages) are needed to compile extensions but not to run them. The runtime only needs the shared libraries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Smaller attack surface and fewer vulnerabilities (72% reduction).&lt;/p&gt;




&lt;h2&gt;
  
  
  The Security Dimension
&lt;/h2&gt;

&lt;p&gt;Reducing vulnerabilities from 290+ to 80 wasn't just about using a slim base image—it was about shipping less code.&lt;/p&gt;

&lt;p&gt;Every package is a potential vulnerability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build tools contain vulnerabilities you'll never exploit (because you're not building in production)&lt;/li&gt;
&lt;li&gt;Development headers expose attack surfaces you don't need&lt;/li&gt;
&lt;li&gt;Unused system utilities are just risk without reward&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The math is simple:&lt;/strong&gt; Fewer packages = fewer CVEs = better security posture.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Practical Takeaways
&lt;/h2&gt;

&lt;h3&gt;
  
  
  For Your Next Dockerfile
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Always use multi-stage builds for compiled/installed dependencies&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stage 1: Build and install&lt;/li&gt;
&lt;li&gt;Stage 2: Runtime with minimal base&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Choose the smallest base image that works&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;python:3.11-slim&lt;/code&gt; over &lt;code&gt;python:3.11&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Alpine if you can handle the musl differences&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Consolidate RUN commands&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combine related operations&lt;/li&gt;
&lt;li&gt;Clean up in the same layer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Copy smartly&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependencies first&lt;/li&gt;
&lt;li&gt;Application code last&lt;/li&gt;
&lt;li&gt;Leverage layer caching&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Distinguish -dev from runtime packages&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build stage: &lt;code&gt;libpq-dev&lt;/code&gt;, &lt;code&gt;gcc&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Runtime stage: &lt;code&gt;libpq5&lt;/code&gt;, binaries only&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  The ROI
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development:&lt;/strong&gt; Faster builds, better caching&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment:&lt;/strong&gt; Faster pulls, quicker rollbacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Smaller attack surface, fewer CVEs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Costs:&lt;/strong&gt; Less storage, less bandwidth&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion: Small Changes, Big Impact
&lt;/h2&gt;

&lt;p&gt;This pull request is a reminder that optimization doesn't always require complex refactoring. Sometimes it's about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding what you're shipping&lt;/li&gt;
&lt;li&gt;Separating what you need from what you needed&lt;/li&gt;
&lt;li&gt;Applying fundamental best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One file changed. Fifty-five lines modified. Image size cut in half. Vulnerabilities reduced by 72%.&lt;/p&gt;

&lt;p&gt;That's the power of thoughtful Docker optimization.&lt;/p&gt;




&lt;h2&gt;
  
  
  Before You Go
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Action Item:&lt;/strong&gt; Pull up your most recent Dockerfile and ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Am I shipping build tools to production?&lt;/li&gt;
&lt;li&gt;Could I use a slimmer base image?&lt;/li&gt;
&lt;li&gt;Are my RUN commands consolidated?&lt;/li&gt;
&lt;li&gt;Is my COPY strategy cache-friendly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The answers might just cut your image size in half.&lt;/p&gt;




&lt;p&gt;open source PR link - &lt;a href="https://github.com/OWASP-BLT/BLT/pull/3072" rel="noopener noreferrer"&gt;https://github.com/OWASP-BLT/BLT/pull/3072&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/build/building/multi-stage/" rel="noopener noreferrer"&gt;Docker Multi-Stage Builds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hub.docker.com/_/python" rel="noopener noreferrer"&gt;Python Docker Image Variants&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/" rel="noopener noreferrer"&gt;Dockerfile Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>performance</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>Offline-First Kiosk: Lessons from the Field</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Sun, 02 Nov 2025 18:07:01 +0000</pubDate>
      <link>https://dev.to/drvcodenta/offline-first-kiosk-lessons-from-the-field-86e</link>
      <guid>https://dev.to/drvcodenta/offline-first-kiosk-lessons-from-the-field-86e</guid>
      <description>&lt;h2&gt;
  
  
  When "Impossible" Becomes "Deployed"
&lt;/h2&gt;

&lt;p&gt;Picture this: You have a tight deadline to build a production-ready kiosk application. It needs to work offline, handle outdated hardware, be completely locked down for security, and provide a smooth user experience. Oh, and it needs to be deployed to physical devices that won't play nice with modern Android features.&lt;/p&gt;

&lt;p&gt;Sound impossible? That's what I thought too.&lt;/p&gt;

&lt;p&gt;But here's the thing about modern web development—with the right architecture and a solid understanding of offline-first principles, you can achieve what seems impossible. This is the story of how I built a kiosk application, and the technical decisions that made it possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mission: Offline-First in a Connected World
&lt;/h2&gt;

&lt;p&gt;The brief was straightforward: create an information kiosk that could display data, handle user interactions, and most importantly, &lt;strong&gt;keep working even when the internet doesn't&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Offline-First Matters
&lt;/h3&gt;

&lt;p&gt;In the world of kiosks, internet connectivity is a luxury, not a guarantee. Whether it's a venue with spotty WiFi, a remote location, or just network hiccups during peak usage, your app needs to be resilient. Users don't care about your excuses—they expect it to work, period.&lt;/p&gt;

&lt;p&gt;The offline-first philosophy flips traditional thinking on its head:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Assume the network is unreliable&lt;/strong&gt; (because it is)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache aggressively&lt;/strong&gt; (but intelligently)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provide immediate feedback&lt;/strong&gt; (even if the server hasn't responded)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sync when possible&lt;/strong&gt; (but never block the user)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Tech Stack: Choosing Speed Without Sacrificing Quality
&lt;/h2&gt;

&lt;p&gt;With a tight deadline, every technology choice mattered. Here's what made the cut:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Core Players
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Vite&lt;/strong&gt; - When you're iterating rapidly, waiting for builds kills momentum. Vite's lightning-fast hot module replacement meant changes appeared instantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React + Ionic Framework&lt;/strong&gt; - Cross-platform UI components that look native and feel natural on touch devices. No need to reinvent the wheel for buttons, modals, and navigation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capacitor&lt;/strong&gt; - The bridge between web and native. Need to lock down the device? Pin the app? Access hidden settings? Capacitor made it possible without writing Java.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TailwindCSS&lt;/strong&gt; - Utility classes meant styling components in seconds, not hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TanStack Query&lt;/strong&gt; - The secret weapon. This library handled caching, background refetching, optimistic updates, and error recovery with minimal configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Configuration That Changed Everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;QueryClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;defaultOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;queries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;staleTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Data stays fresh for 5 minutes&lt;/span&gt;
      &lt;span class="na"&gt;refetchOnWindowFocus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Don't refetch when window regains focus&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Offline-First Kiosk: Lessons from the Field
&lt;/h1&gt;

&lt;h2&gt;
  
  
  This Simple Configuration Meant
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Data loaded once and stayed cached for 5 minutes&lt;/li&gt;
&lt;li&gt;No unnecessary network requests&lt;/li&gt;
&lt;li&gt;Instant UI updates from cache&lt;/li&gt;
&lt;li&gt;Background refetching kept data current&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Hardware Plot Twist
&lt;/h2&gt;

&lt;p&gt;Just when you think you've got everything figured out, reality throws a curveball.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;The kiosk devices presented several obstacles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Outdated Android version with limited Play Services&lt;/li&gt;
&lt;li&gt;Locked-down settings requiring administrator access&lt;/li&gt;
&lt;li&gt;Performance constraints that would make a modern smartphone weep&lt;/li&gt;
&lt;li&gt;No easy way to install standard apps&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Creative Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem #1: Can't access device settings
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Activity Launcher app to access hidden administrator menus&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem #2: Can't install apps from Play Store
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Sideloading APKs manually&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem #3: Performance limitations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Aggressive optimization everywhere&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Code splitting for heavy components&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EventInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../pages/EventInfo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// WebP images instead of PNG/JPEG&lt;/span&gt;
&lt;span class="c1"&gt;// Async font loading&lt;/span&gt;
&lt;span class="c1"&gt;// Minimal JavaScript bundles&lt;/span&gt;
&lt;span class="c1"&gt;// Tree-shaking with ES modules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Security: Locking It Down Tight
&lt;/h2&gt;

&lt;p&gt;A kiosk app is only useful if users can't escape it or access things they shouldn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multi-Layered Security
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Layer 1: Android App Pinning&lt;/strong&gt;&lt;br&gt;
The nuclear option — users physically cannot leave the app without administrative action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: Custom Passcode System&lt;/strong&gt;&lt;br&gt;
Protected administrative functions with a custom implementation when built-in options weren't flexible enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3: Navigation Lockdown&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disabled back button&lt;/li&gt;
&lt;li&gt;Blocked system gestures&lt;/li&gt;
&lt;li&gt;Prevented accidental exits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Layer 4: Device Administrator Privileges&lt;/strong&gt;&lt;br&gt;
Used Activity Launcher to access device admin settings and override restrictions.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Service Worker That Wasn't
&lt;/h2&gt;

&lt;p&gt;Here's the ironic part: despite the emphasis on offline-first, the final implementation didn't use traditional service workers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Not?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Time constraints&lt;/strong&gt; — Service workers require careful lifecycle management and testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native deployment&lt;/strong&gt; — Capacitor's native HTTP plugin provided caching out of the box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complexity vs. benefit&lt;/strong&gt; — TanStack Query handled most offline scenarios elegantly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Offline-First Principles Remained
&lt;/h2&gt;

&lt;p&gt;Even without a service worker, the architecture embodied offline-first thinking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local-first data with aggressive caching&lt;/li&gt;
&lt;li&gt;Optimistic UI updates for instant feedback&lt;/li&gt;
&lt;li&gt;Native caching mechanisms via Capacitor&lt;/li&gt;
&lt;li&gt;Graceful degradation when network unavailable&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Sometimes the best solution is the one that works with your constraints, not against them.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Data Management: The Smart Way
&lt;/h2&gt;

&lt;h3&gt;
  
  
  TanStack Query as Your Sync Engine
&lt;/h3&gt;

&lt;p&gt;This library solved multiple problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Background Refetching:&lt;/strong&gt; Data stayed current without manual intervention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimistic Updates:&lt;/strong&gt; Click a button, see the result immediately, sync with server in background&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retry Logic:&lt;/strong&gt; Automatic retries with exponential backoff&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Invalidation:&lt;/strong&gt; Smart synchronization that knows when to refetch and when to use cached data&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  State Management Philosophy
&lt;/h3&gt;

&lt;p&gt;Instead of Redux or MobX, the app used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TanStack Query for server state&lt;/li&gt;
&lt;li&gt;React Context for global UI state&lt;/li&gt;
&lt;li&gt;URL parameters for navigation state&lt;/li&gt;
&lt;li&gt;Local component state for UI interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple. Effective. Easy to reason about.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons from the Trenches
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Worked Brilliantly
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vite for fast iteration&lt;/li&gt;
&lt;li&gt;Ionic + Capacitor for native capabilities without native complexity&lt;/li&gt;
&lt;li&gt;TailwindCSS for rapid UI development&lt;/li&gt;
&lt;li&gt;TypeScript for fewer runtime bugs&lt;/li&gt;
&lt;li&gt;Component architecture for extensibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I'd Do Differently
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;More time for testing edge cases&lt;/li&gt;
&lt;li&gt;Add React error boundaries&lt;/li&gt;
&lt;li&gt;Integrate performance monitoring early&lt;/li&gt;
&lt;li&gt;Push progressive enhancement further&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Checklist: Building Offline-First Apps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choose Your Caching Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service workers for web apps&lt;/li&gt;
&lt;li&gt;Native plugins for hybrid apps&lt;/li&gt;
&lt;li&gt;Aggressive but intelligent caching&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Embrace Optimistic UI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Update UI immediately and handle rollback on failure&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Test Offline Scenarios&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete offline mode&lt;/li&gt;
&lt;li&gt;Slow 3G&lt;/li&gt;
&lt;li&gt;Intermittent connectivity&lt;/li&gt;
&lt;li&gt;Server errors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Plan for Sync Conflicts&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Last write wins?&lt;/li&gt;
&lt;li&gt;Server authority?&lt;/li&gt;
&lt;li&gt;User resolution?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Monitor Performance&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bundle size&lt;/li&gt;
&lt;li&gt;Image formats&lt;/li&gt;
&lt;li&gt;Code splitting&lt;/li&gt;
&lt;li&gt;Lazy loading&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Secure It Properly&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lock down navigation&lt;/li&gt;
&lt;li&gt;Protect admin functions&lt;/li&gt;
&lt;li&gt;Use device-level security&lt;/li&gt;
&lt;li&gt;Test escape attempts&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




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

&lt;p&gt;After focused development the kiosk app shipped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smooth, responsive UI&lt;/li&gt;
&lt;li&gt;Offline-capable&lt;/li&gt;
&lt;li&gt;Secure and locked-down&lt;/li&gt;
&lt;li&gt;Handles outdated hardware gracefully&lt;/li&gt;
&lt;li&gt;Easy to update and maintain&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion: Offline-First Is a Mindset
&lt;/h2&gt;

&lt;p&gt;Offline-first is not just service workers or IndexedDB. It's about designing for unreliable networks and building resilience at every layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools that helped&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TanStack Query&lt;/li&gt;
&lt;li&gt;Capacitor&lt;/li&gt;
&lt;li&gt;Modern web frameworks&lt;/li&gt;
&lt;li&gt;Fast build tools&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;What are your offline-first war stories? Drop them below.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TanStack Query Documentation: &lt;a href="https://tanstack.com/query/latest" rel="noopener noreferrer"&gt;https://tanstack.com/query/latest&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Ionic Framework: &lt;a href="https://ionicframework.com/" rel="noopener noreferrer"&gt;https://ionicframework.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Capacitor: &lt;a href="https://capacitorjs.com/" rel="noopener noreferrer"&gt;https://capacitorjs.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Service Worker API: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Offline First Principles: &lt;a href="https://offlinefirst.org/" rel="noopener noreferrer"&gt;https://offlinefirst.org/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>android</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Python Deque v/s List🐍</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Wed, 14 Aug 2024 11:04:26 +0000</pubDate>
      <link>https://dev.to/drvcodenta/python-deque-vs-list-18ak</link>
      <guid>https://dev.to/drvcodenta/python-deque-vs-list-18ak</guid>
      <description>&lt;p&gt;I've always wondered why we use &lt;code&gt;deque&lt;/code&gt; for working with queues in Python. After doing some research, I found out some cool things that &lt;code&gt;deque&lt;/code&gt; has to offer, while using &lt;code&gt;list&lt;/code&gt; for queues may not always be a good choice.&lt;br&gt;
What is &lt;code&gt;deque&lt;/code&gt;, anyway?&lt;br&gt;
Essentially, it's very similar to a native Python list, but better.&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%2F0itpcq6edqnzsjmezdgp.gif" 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%2F0itpcq6edqnzsjmezdgp.gif" alt="Deque be like" width="498" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Elements in a &lt;code&gt;list&lt;/code&gt; are stored contiguously in a single block of memory and have a single pointer that points to the very first element. On the other hand, &lt;code&gt;deque&lt;/code&gt; is a double-ended list with pointers at both ends.&lt;/p&gt;

&lt;p&gt;Here are some factors which make deque a better choice than list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Append Operation
: Both &lt;code&gt;list&lt;/code&gt; and &lt;code&gt;deque&lt;/code&gt; take constant time complexity for appending, as list uses pointer arithmetic (e.g., &lt;code&gt;o + length(4) = address 4&lt;/code&gt;) to find the last element and then append a new item. In case of deque, it has a rear pointer at the end. So it also takes constant time complexity&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%2Fyc4giarter2pnp8g1v65.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%2Fyc4giarter2pnp8g1v65.png" alt="append operation usecase" width="800" height="135"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Pop Operation&lt;br&gt;
: Both structures have the same constant time complexity as they find the last element using the same logic and then pop the last element from the list.&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%2Fjwrg3xfr7lqecohscohn.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%2Fjwrg3xfr7lqecohscohn.png" alt="pop operation usecase" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prepending Operation&lt;br&gt;
: Here's where the magic of deque begins! List structures need to shift forward each element by 1 position, and insert the value at first position making the whole process O(n) time complexity or linear time complexity. A &lt;code&gt;deque&lt;/code&gt;, on the other hand, with its front pointer, performs prepending in constant time complexity by using a circular buffer and shifting the front pointer to -1. In reality, the new value is stored in a higher memory address, but under the hood, it is logically the first element of the &lt;code&gt;deque&lt;/code&gt; after the prepend operation. &lt;/p&gt;&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%2Fa99spbjyho6p79qk8z51.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%2Fa99spbjyho6p79qk8z51.png" alt="prepend operation usecase" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Popping from the left&lt;br&gt;
: Again, &lt;code&gt;list&lt;/code&gt; structures need to pop the leftmost element and shift each value by one position to the left, resulting in linear time complexity. On the other hand, &lt;code&gt;deque&lt;/code&gt; pops the value at the front pointer and updates the front pointer to the right. Yes, it takes only constant time complexity, making the process significantly more efficient.&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%2Fbl6922a8izvaqzikzenj.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%2Fbl6922a8izvaqzikzenj.png" alt="popleft operation usecase" width="800" height="174"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insertion/Deletion into middle&lt;br&gt;
: With a &lt;code&gt;list&lt;/code&gt;, the time complexity ranges from O(1) to O(n) depending on the position of the element. In the case of &lt;code&gt;deque&lt;/code&gt;, it ranges from O(1) to O(n/2).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Beyond Read and Write: Executing Files with chmod</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Tue, 23 Apr 2024 07:43:46 +0000</pubDate>
      <link>https://dev.to/drvcodenta/non-executable-files-in-unix-like-systems-1in6</link>
      <guid>https://dev.to/drvcodenta/non-executable-files-in-unix-like-systems-1in6</guid>
      <description>&lt;p&gt;In Linux, a non-executable file is one that cannot be directly run by the system as a program. These files typically contain data or instructions that require another program to interpret or process them. There are two main reasons a file might not be executable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Missing permissions&lt;/strong&gt;: In Linux, file permissions control what users can do with a file. These permissions include read, write, and execute. By default, some files might only have read/write permissions, meaning they can be viewed or modified but not directly executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;File type&lt;/strong&gt;: Certain file types, like text files (.txt), image files (.jpg), or document files (.pdf), are not meant to be executable programs. They contain data meant to be processed by specific applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Examples of non-executable files:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data files&lt;/strong&gt;: These include various file formats that store information, like images, documents, spreadsheets, audio, and videos. They require specific software to be opened and used.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration files&lt;/strong&gt;: These files contain settings for programs or the system itself. They are typically text files and are read by software to configure its behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Log files&lt;/strong&gt;: These files record system events or application activity. They are mainly for troubleshooting and are not meant to be executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shell scripts&lt;/strong&gt;: Shell scripts are text files containing commands intended to be executed by the shell. However, if they lack the necessary permissions (explained below), they won't be executable directly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Finding non-executable files:&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;You can use the &lt;code&gt;find&lt;/code&gt; command with the &lt;code&gt;-not&lt;/code&gt; operator (if using GNU find) to search for files that lack execute permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;Making non-executable files executable:&lt;/em&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shell scripts:&lt;/strong&gt; For shell scripts, you can grant them execute permission using the &lt;code&gt;chmod&lt;/code&gt; command. This allows the script to be run from the terminal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Other files:&lt;/strong&gt; While possible, it's generally not recommended to make non-executable files executable unless you understand why they are non-executable and what the intended use is.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding the 'chmod' Command:
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;chmod&lt;/code&gt; command is an integral part of any Unix-like operating system and has been around since the early days of Unix. It stands for "change mode" and is used to define the way a file can be accessed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to use it&lt;/strong&gt;&lt;br&gt;
The basic usage of chmod involves invoking the command followed by the permissions you want to set and then the file or directory you're modifying.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod 755 filename.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Let's break down the command:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;755&lt;/strong&gt;: This is the permission setting you are applying. It's represented in octal notation (base-8). Here's how it breaks down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first digit (7) represents the permissions for the owner of the file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;r (4) - Read permission
w (2) - Write permission
x (1) - Execute permission (since 7 = 4 + 2 + 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The second digit (5) represents the permissions for the group that owns the file:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  r (4) - Read permission
  x (1) - Execute permission (since 5 = 4 + 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The third digit (5) represents the permissions for everyone else (users who are not the owner or part of the group):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  r (4) - Read permission
  x (1) - Execute permission (since 5 = 4 + 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In simpler terms, this command sets the following permissions for filename.txt:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Owner&lt;/em&gt;: can read, write, and execute the file.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Group&lt;/em&gt;: can only read and execute the file.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Everyone else&lt;/em&gt;: can only read and execute the file.
Here are some important points to consider:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a common permission setting used for executable files (like shell scripts) that need to be run by users.&lt;br&gt;
&lt;em&gt;Be cautious when using 777 (read, write, and execute for everyone) as it grants unrestricted access to the file, which can be a security risk. You might need to use &lt;code&gt;sudo&lt;/code&gt; before the command (&lt;code&gt;sudo chmod 755 filename.txt&lt;/code&gt;) if you don't have the necessary permissions to modify the file.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The commonly used parameters
&lt;/h2&gt;

&lt;p&gt;There are several permissions that you can set with &lt;code&gt;chmod&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;-u stands for 'user', the owner of the file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod u+x filename.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-g stands for 'group', users who are members of the file's group.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod g+w filename.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-o stands for 'others', users who are not the owner of the file or members of the group.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod o-r filename.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Other supported parameters:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;chmod&lt;/code&gt; supports a number of parameters like &lt;code&gt;-f&lt;/code&gt; (force), &lt;code&gt;-v&lt;/code&gt; (verbose), &lt;code&gt;-c&lt;/code&gt; (changes), &lt;code&gt;-R&lt;/code&gt; (recursive), &lt;code&gt;--help&lt;/code&gt; (display help and exit), and &lt;code&gt;--version&lt;/code&gt; (output version information and exit). Each parameter provides a specific functionality to the &lt;code&gt;chmod&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Warning:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
It’s crucial to be careful when changing permissions, especially when using the -R (recursive) option. If misused, you could inadvertently give users unintended access to sensitive files or directories.&lt;/p&gt;
&lt;h2&gt;
  
  
  Can we Run a Script that's not Executable?
&lt;/h2&gt;

&lt;p&gt;yes, we can!&lt;br&gt;
If a shell script isn’t executable, we cannot run it directly in the terminal. Of course, the execute permission of the script can be changed so that we can run it. But, that may not always be possible. For example, if the script belongs to another user, we may not have the necessary privileges to change the execute permission of the script using the &lt;code&gt;chmod&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;If we have an executable script, we can run it directly in the terminal. Suppose we have the following script, &lt;code&gt;hello_world.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
echo “Hello World"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script just prints Hello World and exits. We specify the interpreter of the script on the first line after the shebang (&lt;code&gt;#!&lt;/code&gt;). In our case, the interpreter is &lt;code&gt;/bin/bash&lt;/code&gt;. This tells the operating system to use Bash as the interpreter for parsing the remainder of the script.&lt;/p&gt;

&lt;p&gt;Let’s first check the execute permission of this script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ -l hello_world.sh
-rwxr-xr-x 1 dt dt 23 April  08:32 hello_world.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the execute permission of the script is set for all users, we can run it directly in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./hello_world.sh
Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we’ll consider the case when the script isn’t executable. First, let’s remove the execute permission of the script &lt;code&gt;hello_world.sh&lt;/code&gt; using &lt;code&gt;chmod&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod -x hello_world.sh
$ ls –l hello_world.sh
-rw-r--r-- 1 dt dt 23 April  08:32  hello_world.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As it’s apparent from the output of the &lt;code&gt;ls –l&lt;/code&gt; command, nobody not even the owner of the script – has the right to execute this script. Let’s try to run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./hello_world.sh
-bash: ./hello_world.sh: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our objective is to run the script &lt;code&gt;hello_world.sh&lt;/code&gt; in the remainder of this tutorial.&lt;/p&gt;

&lt;p&gt;One way to run a script that we don’t have the execute permission is to specify the shell explicitly while running the script. Let’s run the script, &lt;code&gt;hello_world.sh&lt;/code&gt;, with the Bash interpreter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ /bin/bash ./hello_world.sh
Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we’re able to specify the interpreter while running the script, we can run the script with another interpreter, for example, the Korn shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ /bin/ksh ./hello_world.sh
Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another way to run a script that isn’t executable is using the source command. Let’s run the script, &lt;code&gt;hello_world.sh&lt;/code&gt;, using source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ source ./hello_world.sh
Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sourcing a script means that we run the script in the current shell. So, if the script contains an &lt;code&gt;exit&lt;/code&gt; command, we must be cautious since we may exit from the current shell itself.&lt;/p&gt;

&lt;p&gt;We can use the dot or period character (&lt;code&gt;.&lt;/code&gt;) instead of source and get the same result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ . ./hello_world.sh
Hello World
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>cybersecurity</category>
      <category>terminal</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lambda Function(Python)</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Sat, 13 Apr 2024 13:05:00 +0000</pubDate>
      <link>https://dev.to/drvcodenta/lambda-functionpython-569l</link>
      <guid>https://dev.to/drvcodenta/lambda-functionpython-569l</guid>
      <description>&lt;p&gt;In Python, a lambda function is a small anonymous function without a name. It is defined using the lambda keyword and has the following syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lambda arguments: expression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambda functions are often used in situations where a small function is required for a short period of time. They are commonly used as arguments to higher-order functions, such as map, filter, and reduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function to double the input
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def double(x):
  return x * 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lambda function to double the input
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lambda x: x * x * x * x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above lambda function has the same functionality as the double function defined earlier. However, the lambda function is anonymous, as it does not have a name.&lt;/p&gt;

&lt;p&gt;Lambda functions can have multiple arguments, just like regular functions. Here is an example of a lambda function with multiple arguments:&lt;/p&gt;

&lt;h3&gt;
  
  
  Function to calculate the product of two numbers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def multiply(x, y):
    return x * y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Lambda function to calculate the product of two numbers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lambda x, y: x * y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambda functions can also include multiple statements, but they are limited to a single expression. For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Lambda function to calculate the product of two numbers, with additional print statement
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lambda x, y: print(f'{x} * {y} = {x * y}')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the lambda function includes a print statement, but it is still limited to a single expression.&lt;/p&gt;

&lt;p&gt;Lambda functions are often used in conjunction with higher-order functions, such as map, filter, and reduce which we will look into later.&lt;/p&gt;

&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>machinelearning</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>bisect module and methods(python)</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Mon, 26 Feb 2024 12:23:27 +0000</pubDate>
      <link>https://dev.to/drvcodenta/bisect-module-and-methodspython-3nhj</link>
      <guid>https://dev.to/drvcodenta/bisect-module-and-methodspython-3nhj</guid>
      <description>&lt;p&gt;The bisect module is written in python and here is the &lt;a href="https://github.com/python/cpython/blob/3.12/Lib/bisect.py" rel="noopener noreferrer"&gt;source code&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What it does?&lt;/strong&gt;&lt;br&gt;
The bisect module in Python provides support for maintaining a list in sorted order without having to sort the list after each insertion. It uses a binary search algorithm to find the insertion point for a given element in a sorted list, which is more efficient than linear search.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key functions provided by the bisect module:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bisect.bisect_left(list, num, beg, end)&lt;/code&gt;:
This function returns the sorted list after inserting the number in the appropriate position. If the element already exists, then the element is inserted at the leftmost possible position.
import bisect
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;list = [1, 3, 4, 4, 6, 7]
bisect.bisect_left(list, 5)
print(list)  # Output: [4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bisect.bisect_right(list, num, beg, end)&lt;/code&gt;:
This function works similar to &lt;code&gt;bisect_left()&lt;/code&gt;, but if the element already exists, then the rightmost position is returned. &lt;code&gt;bisect.bisect()&lt;/code&gt; is an alias for &lt;code&gt;bisect_right()&lt;/code&gt;.
import bisect
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;list = [1, 3, 4, 4, 4, 6, 7]
print(bisect.bisect_right(list, 4))  # Output: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bisect.insort_left(list, num, beg, end)&lt;/code&gt;:
This function returns the sorted list after inserting the number in the appropriate position. If the element already exists, then the element is inserted at the leftmost possible position.
&lt;/li&gt;
&lt;/ul&gt;

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

list = [1, 3, 4, 4, 6, 7]
bisect.insort_left(list, 5)
print(list)  # Output: [1, 3, 4, 4, 5, 6, 7]

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bisect.insort_right(list, num, beg, end)&lt;/code&gt;:
This function works similar to &lt;code&gt;insort_left()&lt;/code&gt;, but if the element already exists, then the element is inserted at the rightmost possible position. &lt;code&gt;bisect.insort()&lt;/code&gt; is an alias for &lt;code&gt;insort_right()&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

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

list = [1, 3, 4, 4, 6, 7]
bisect.insort_right(list, 4)
print(list)  # Output: [1, 3, 4, 4, 4, 6, 7]

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;In all these functions, beg and end are optional arguments specifying the range in which to search for the insertion point. If omitted, the entire list is used.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>accessing rows and columns in a 2d array and insert method(python)</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Wed, 14 Feb 2024 20:22:00 +0000</pubDate>
      <link>https://dev.to/drvcodenta/accessing-rows-and-columns-in-a-2d-array-and-insert-methodpython-2plo</link>
      <guid>https://dev.to/drvcodenta/accessing-rows-and-columns-in-a-2d-array-and-insert-methodpython-2plo</guid>
      <description>&lt;p&gt;In Python, a 2D array (or matrix) is essentially a list of lists. You can access elements, rows, and columns in a 2D array using indexing.&lt;/p&gt;

&lt;p&gt;Here's how you can do it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessing an element&lt;/strong&gt;: To access an element in a 2D array, you use two indices. The first index is for the row and the second index is for the column. For example, &lt;code&gt;matrix[i][j]&lt;/code&gt; will give you the element at the ith row and jth column.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessing a row&lt;/strong&gt;: To access a row in a 2D array, you only need one index. For example, &lt;code&gt;matrix[i]&lt;/code&gt; will give you the ith row.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessing a column&lt;/strong&gt;: Accessing a column is a bit trickier because Python's list of lists structure does not have built-in support for accessing columns. You typically use a loop or a list comprehension to access a column. For example, &lt;code&gt;[row[j] for row in matrix]&lt;/code&gt; will give you the jth column.&lt;/p&gt;

&lt;p&gt;Suppose you want to access all of the items present in one row of a 2-dimensional array or a matrix and change it to some value(let's say 0 to 1), then you can do it this way:&lt;/p&gt;

&lt;p&gt;// creating a matrix initializing 0 at all of the indices&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;matrix = [[0]*n for i in range(m)] # n = number of cells in a row or number of columns and m = number of rows

for i in range(n):
    matrix[row_number][i] = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to access a particular column in the matrix, and change all the values of the column in a matrix to 1, then you can do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for j in range(m):
    matrix[j][column_number] = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Insert Method in python&lt;/em&gt;&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;arr.insert(i, n) #Here 'i' is the index and 'n' is any number

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

&lt;/div&gt;



&lt;p&gt;Note: When we Insert any number 'n' in the array using insert method, then it slides the remaining right side elements of the array to right&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;
arr = [1,2,3,4,5]

arr.insert(3, 1)

print(arr) //OUTPUT: [1,2,3,1,4,5]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdez2hae7ft9j7krhevp4.gif" 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%2Fdez2hae7ft9j7krhevp4.gif" alt="accessing rows and column in 2d array(python)" width="498" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>learning</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Integrity Constraints in DBMS</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Sun, 11 Feb 2024 09:00:12 +0000</pubDate>
      <link>https://dev.to/drvcodenta/integrity-constraints-in-dbms-576d</link>
      <guid>https://dev.to/drvcodenta/integrity-constraints-in-dbms-576d</guid>
      <description>&lt;p&gt;There are four main types of integrity constraints in DBMS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain Constraints: 
They define the domain or set of values that an attribute can hold (e.g., integers, characters, dates, times, strings, etc.).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE employees
ADD CONSTRAINT CHECK_age (age &amp;gt;= 18 AND age &amp;lt;= 65);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Entity Integrity Constraints:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It ensures that the primary key column(s) contain unique and non-null values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE customers
ADD CONSTRAINT PRIMARY KEY (customer_id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Referential Integrity Constraints:
These constraints maintain relationships between tables by ensuring that foreign key values reference valid primary key values. This prevents orphaned records and ensures data consistency.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE orders
ADD CONSTRAINT FK_customer_id
FOREIGN KEY (customer_id) REFERENCES customers(customer_id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;User-Defined Integrity Constraints:
These constraints are custom constraints defined by the database administrator or application developer to enforce specific business rules or data requirements.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLE products
ADD CONSTRAINT CHECK_stock_quantity (stock_quantity &amp;gt;= 0);

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;what is &lt;em&gt;candidate key&lt;/em&gt;?&lt;/strong&gt;&lt;br&gt;
In a relational database, a candidate key is a minimal superkey. A superkey is a set of one or more attributes that uniquely identify every row in a table. A candidate key is a superkey that does not contain any redundant attributes. In other words, no attribute in the candidate key can be removed without losing the uniqueness of the row.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;primary key&lt;/em&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a relational database, a primary key is a special constraint that uniquely identifies each row in a table. It is a column or combination of columns that cannot contain null values and must have unique values. The primary key is used to enforce referential integrity, which ensures that relationships between tables are maintained.&lt;/p&gt;

&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Object Oriented Analysis and Designing Basics</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Mon, 25 Dec 2023 19:17:45 +0000</pubDate>
      <link>https://dev.to/drvcodenta/object-oriented-analysis-and-designing-basics-2b1f</link>
      <guid>https://dev.to/drvcodenta/object-oriented-analysis-and-designing-basics-2b1f</guid>
      <description>&lt;p&gt;There are various concepts involved while developing a software, such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Object-Oriented Analysis(OOA)&lt;/em&gt;:It involves investigating a problem domain to identify the objects and their relationships that are relevant to the problem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Object-oriented design (OOD)&lt;/em&gt;: is the next step after OOA, which involves designing the software system based on the objects identified during OOA&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both combined is known as OOAD(Object-oriented analysis and design), which involves a number of techniques and practises, including object-oriented programming, design patterns, UML diagrams, and other use cases.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here are some important aspects used in OOAD:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Object-Oriented Programming: involves modeling real-world objects as software objects, with properties and methods that represent the behavior of those objects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Design Patterns: Design patterns are reusable solutions to common problems in software design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UML Diagrams: OOAD uses UML diagrams to represent the different components and interactions of a software system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Cases: OOAD uses use cases to help developers understand the requirements of a system and to design software systems that meet those requirements.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  what are the advantages of OOAD?
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Reusability&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Maintainability&lt;/li&gt;
&lt;li&gt;Flexibility&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  What are the disadvantages of it?
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Complex to design&lt;/li&gt;
&lt;li&gt;Time-Complexity&lt;/li&gt;
&lt;li&gt;Difficult to make changes, once it has been designed&lt;/li&gt;
&lt;li&gt;Cost&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;In one line, it is tough to build something complex&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Example of Object Oriented Design:&lt;/em&gt;&lt;br&gt;
Suppose you are designing a software system for a bank. You would start by performing object-oriented analysis to identify the objects and their relationships that are relevant to the problem. Some of the objects that you might identify include customers, accounts, and transactions. You would then use object-oriented design to create a software system based on these objects.&lt;br&gt;
For example, you might create a class called Customer that has properties such as name, address, and account_number. You might also create a class called Account that has properties such as balance, interest_rate, and account_type. You would then use these classes to create a software system that allows bank staff to manage customer accounts and transactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;em&gt;MOST USED TERMS IN OBJECT-ORIENTED DESIGNING:&lt;/em&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Objects&lt;/em&gt;: is an instance of a class. It is a concrete entity that has its own state and behavior, based on the properties and methods defined in the class&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Class&lt;/em&gt;: is a blueprint or template for creating objects. It defines the properties and methods that an object will have, but it is not an object itself.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Messages&lt;/em&gt;: Objects communicate by message passing. Messages consist of the &lt;br&gt;
integrity of the target object, the name of the requested operation, and any other &lt;br&gt;
action needed to perform the function&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Abstraction&lt;/em&gt;: is the removal of the irrelevant and the amplification of the essentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Encapsulation&lt;/em&gt;: : Encapsulation is also called an information hiding concept. Encapsulation not only bundles essential information of an object together but also restricts access to the data and methods &lt;br&gt;
from the outside world. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Inheritance&lt;/em&gt;: OOD allows similar classes to stack up in a hierarchical manner where the lower or sub-classes can import, implement, and re-use allowed variables and &lt;br&gt;
functions from their immediate superclasses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Polymorphism&lt;/em&gt;: : OOD languages provide a mechanism where methods performing similar tasks but vary in arguments, can be assigned the same name. Depending upon how the service is invoked, the respective portion of the code gets executed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are confused between Object and Class, because I was always confused in these concepts then you can remember this analogy:&lt;/p&gt;

&lt;p&gt;Class provides the blueprint of the bicycle, but Object is the bicycle itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Doubt: How to design Objects?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;We can Design an object in following phases:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Identifying the Object&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Construction of design model for Object(Object Representation)&lt;/em&gt;:
&lt;em&gt;Static model&lt;/em&gt; which describes the static structure using Class Diagram and Object Diagram.
&lt;em&gt;Dynamic Model&lt;/em&gt; which describes the dynamic structure of a system and show interaction between classes using Interaction diagrams and state-chart diagrams.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Classification of Operations&lt;/em&gt;: An operation specifies what is to be done and not how it should be done!So in this phase, the operations that would be performed on objects are defined...&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Algorithm Design&lt;/em&gt;: The operations in the objects are defined using algorithms. An algorithm is a stepwise procedure that solves the problem laid down in an operation. Algorithms focus on how it is to be done.&lt;em&gt;Computation Complexity&lt;/em&gt;, &lt;em&gt;flexibility of the Algorithm&lt;/em&gt;, &lt;em&gt;Understandability&lt;/em&gt; are the metrics for choosing the Optimal Algorithm&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Design of Relationships&lt;/em&gt;: The strategy to implement the relationships needs to be chalked out during the 
object design phase.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Implementation of control for external interactions&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Package classes and associations into modules&lt;/em&gt;: Hiding Internal Information from Outside view, Coherence of Elements, and Construction of Physical Modules&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Design Optimizations methods:&lt;/em&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Addition of Redundant Associations&lt;/li&gt;
&lt;li&gt;Omission of Non-Usable Associations&lt;/li&gt;
&lt;li&gt;Optimization of Algorithms&lt;/li&gt;
&lt;li&gt;Saving and Storing of Derived Attributes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for Reading the Tutorial&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%2F3rqrfty2uebr8sthi9qi.gif" 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%2F3rqrfty2uebr8sthi9qi.gif" alt="Thanks" width="498" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Little bit Git...</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Sun, 26 Nov 2023 23:22:52 +0000</pubDate>
      <link>https://dev.to/drvcodenta/little-bit-git-300</link>
      <guid>https://dev.to/drvcodenta/little-bit-git-300</guid>
      <description>&lt;p&gt;Getting started head on...&lt;/p&gt;

&lt;h2&gt;
  
  
  git log
&lt;/h2&gt;

&lt;p&gt;I was working on some project, the conflict error occured again and again while I was trying to push. So, I decided to use &lt;code&gt;rebase&lt;/code&gt; and move ahead with the problem but I needed to git see the commit history before I could use &lt;code&gt;git rebase&lt;/code&gt; so what command did I use back then?&lt;/p&gt;

&lt;p&gt;Before you move forward!!!&lt;/p&gt;

&lt;p&gt;Think hard...&lt;/p&gt;

&lt;p&gt;The answer is this👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git log &amp;lt;branch-to-rebase-onto&amp;gt;..HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;&amp;lt;branch-to-rebase-onto&amp;gt;&lt;/code&gt; is replaced with the branch where I have to rebase it onto(generally it's &lt;code&gt;origin/master&lt;/code&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  git stash
&lt;/h2&gt;

&lt;p&gt;I was trying to setup an environment for some open source project, which needed installation of &lt;strong&gt;Vagrant&lt;/strong&gt;(it's a Virtual Machine Environment in simple words). While doing the setup of the environment, I went through several Errors! &lt;br&gt;
I solved some with the help of my helpful brother   and some on my own but then in the end, I figured out that some Changes that I made in my configuration file for Vagrant were not suitable for pushing to the origin of the main repository for that open source project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In Short, there were some Changes specific for my own system(not suitable for a public repository)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now I needed to add my changes to git commit without adding that configuration file, which command did I use to ignore that particular file?&lt;/p&gt;

&lt;p&gt;The answer is this👇&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;If you want to reapply the changes back to the working directory, use this command👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Stash Apply
&lt;/h2&gt;

&lt;p&gt;There was a time when I wanted to restore some previously stashed work to a new Branch using git, How did I do it?&lt;/p&gt;

&lt;p&gt;The answer is this👇&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create a New Branch:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout -b new_branch_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Apply Stashed Changes:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;/p&gt;

&lt;p&gt;I can use this👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash branch new_branch_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;branch&lt;/code&gt; and &lt;code&gt;new_branch_name&lt;/code&gt; are the branches from which you are taking stashed changes from and the branch you are pushing it to respectively&lt;/p&gt;

&lt;h2&gt;
  
  
  Tags:
&lt;/h2&gt;

&lt;p&gt;Tags are necessary to mark specific points the history of the commits!&lt;br&gt;
Releases are one important example&lt;/p&gt;

&lt;p&gt;To push tags to a remote repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git push origin &amp;lt;tagname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;replace &lt;code&gt;tagname&lt;/code&gt; with whatever tag you want to paste&lt;/p&gt;

&lt;h2&gt;
  
  
  git diff:
&lt;/h2&gt;

&lt;p&gt;To review the changes that are currently staged (in the index) before committing them, use this👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git diff --cached
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>Github Actions Basics</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Sat, 18 Nov 2023 17:27:58 +0000</pubDate>
      <link>https://dev.to/drvcodenta/github-actions-basics-m57</link>
      <guid>https://dev.to/drvcodenta/github-actions-basics-m57</guid>
      <description>&lt;p&gt;&lt;strong&gt;Github Actions are used to automate project management tasks by using workflows.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each Workflow contains a series of tasks, which are implemented or run automatically everytime when the workflow runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Github Action is a CI/CD(Continuous Integration and Continuous Delivery) platform that allows you to automate your build, test and deployment pipelines&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Components of Github Actions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1.&lt;strong&gt;Workflow&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workflow is a configurable automated process that will run one or more jobs,&lt;/li&gt;
&lt;li&gt;defined by a YAML file/Syntax,&lt;/li&gt;
&lt;li&gt;and it's placed inside &lt;code&gt;.github/workflows&lt;/code&gt; path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2.&lt;strong&gt;Events&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is Something that triggers Workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3.&lt;strong&gt;Jobs&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Job is a set of steps in a workflow, each step is either a &lt;code&gt;Shell script&lt;/code&gt; or an &lt;code&gt;action&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Steps are executed in order, and are dependent on each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Sharing&lt;/strong&gt; mechanism is integrated into the steps, since they are dependent on each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4.&lt;strong&gt;Actions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom application for the Github Actions platform that performs a complex but frequently repeated tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;5.&lt;strong&gt;Runners&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;is a server that runs your workflow when they are triggered.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let us Understand the Workflow file(YAML):&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;name: learn-github-actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;it will appear in the 'Actions' tab of the Github Repository&lt;/li&gt;
&lt;li&gt;it is an optional step
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;run-name: ${{github.actor}} is learning Github actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;it specifies the name of workflow run, that will appear in the list of workflow runs on 'Actions' Tab
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on: [push]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;specifies the trigger for the Workflow
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Groups all the jobs that run in the learn-github-action workflow
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;check-bats-version:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Defines a job named &lt;code&gt;check-bats-version&lt;/code&gt;. The child keys will define properties of the job.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;runs-on: ubuntu-latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;configures the job to run on the latest version of the Ubuntu Linux runner(Fresh virtual machine hosted by Github)
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;groups together all the steps that runs in this job. Each item nested under this section is a separate &lt;code&gt;action&lt;/code&gt; or a &lt;code&gt;shell script&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-uses: actions/checkout@v4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;uses&lt;/code&gt; keyword specifies that this step will run &lt;code&gt;v4&lt;/code&gt; of the &lt;code&gt;actions/checkout&lt;/code&gt; action.&lt;/li&gt;
&lt;li&gt;This actions checks out your repository onto the runner, allowing you to run scripts or other actions against your code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-uses: actions/setup-node@v3
 with:
    node-version: '14'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This step uses the &lt;code&gt;actions/setup-node@v3&lt;/code&gt; action to install the specified version of the Node that will be used for the project&lt;/li&gt;
&lt;li&gt;This puts both the &lt;code&gt;node&lt;/code&gt; &amp;amp; &lt;code&gt;npm&lt;/code&gt; commands in your Path
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-run: npm install -g bats
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;run&lt;/strong&gt; keyword tells the job to execute a command on the Runner.&lt;/li&gt;
&lt;li&gt;In this case, you're using &lt;code&gt;npm&lt;/code&gt; to install &lt;code&gt;bats&lt;/code&gt; software testing package.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-run:bats-v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finally you'll run the &lt;code&gt;bats&lt;/code&gt; command with a parameter that outputs the software version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading the tutorial!&lt;br&gt;
If you have any feedback, then you can DM me on &lt;a href="https://twitter.com/DhruvTr89566170" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/dhruv-trivedi-06a767228/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>githubactions</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Hacktoberfest23 and MLH</title>
      <dc:creator>dhruv</dc:creator>
      <pubDate>Mon, 13 Nov 2023 21:37:04 +0000</pubDate>
      <link>https://dev.to/drvcodenta/hacktoberfest23-and-mlh-454o</link>
      <guid>https://dev.to/drvcodenta/hacktoberfest23-and-mlh-454o</guid>
      <description>&lt;h3&gt;
  
  
  What is Hacktoberfest?
&lt;/h3&gt;

&lt;p&gt;In simple words, Hacktoberfest provides opportunities to the beginners who want to start contributing in Open Source.&lt;br&gt;
Hacktoberfest is an annual event that takes place every October and is aimed at encouraging contributions to open-source projects. It was started by DigitalOcean in collaboration with GitHub to promote community participation in the open-source ecosystem. &lt;br&gt;
You experience new things with making open-source contributions through Hacktoberfest and participating in MLH Global Hack Week Open source was a testament to the enriching opportunities that such events offer. By actively engaging in these initiatives, you not only expand your technical skills but also gain exposure to a diverse and dynamic world of collaborative development.&lt;br&gt;
I just had a little bit idea about things like giving back to the community, learning in public, but doing it yourself is just a very different feeling.&lt;/p&gt;

&lt;p&gt;Up until now i was learning things only for the sake of learning, but you just don't code for yourself. It all ultimately boils down to whether it could be of some use to the society in some way or not, i call that testing phase for production use. Testing phase is something that exists at all levels whether it's your standard curriculum or some PHD level course.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ram's story
&lt;/h3&gt;

&lt;p&gt;Consider an example of a student named Ram, who, during his academic pursuits, acquired knowledge primarily for the purpose of achieving academic excellence, with a focus on obtaining high marks. Ram's approach to learning centered on the immediate goal of academic success, with less emphasis on understanding how the acquired knowledge could be applied to benefit the broader community.&lt;/p&gt;

&lt;p&gt;While Ram may excel in the context of elementary education by prioritizing grades, this singular focus on academic achievement may inadvertently foster a mindset that places less importance on the broader implications and practical applications of acquired knowledge. In the professional realm, particularly as one advances in their career, an exclusive emphasis on grades may prove to be a limitation. Society tends to value individuals who not only possess theoretical knowledge but also demonstrate the ability to apply that knowledge in practical, meaningful ways.&lt;/p&gt;

&lt;p&gt;As Ram progresses in his career, he may encounter challenges related to adaptability and collaborative work. The professional landscape values individuals who not only excel in academic settings but also contribute to the collective progress of projects and initiatives. The ability to communicate one's thought process, collaborate effectively, and apply knowledge to real-world situations becomes increasingly crucial.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the long run, individuals who prioritize not just academic success but also the practical application of knowledge tend to thrive in professional environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ram, realizing the evolving demands of the professional world, may need to adapt his work ethic to align more closely with the expectations of a collaborative and application-oriented work environment. Recognizing and addressing these aspects early in one's career can contribute significantly to long-term professional success and fulfillment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Highs and Lows
&lt;/h3&gt;

&lt;p&gt;Making Contributions first time is not easy, i accept it as the codebase looks so big, complex and people making PR on issues seem like people from another world on first go but actually it isn't that tough for a beginners.&lt;/p&gt;

&lt;p&gt;Initially i was more focused on understanding how the things were working in the project, and came to conclusion that i need to learn more but this was not a solution. I needed to make a PR but didn't knew how to do it. &lt;strong&gt;Believe me, thoughts like would maintainers be friendly, can I even solve an issue when there are so many contributors grabbing the issues that i could have solved, let's focus on something else etc are just barrier, focus on only what you can do and neglect what you cannot do for the time being, you can learn it later&lt;/strong&gt;(Don't make it a headache).&lt;br&gt;
I was looking for projects from the start of October but due to college exams and pressure of starting something new, i couldn't find a good place to start. End date was coming close, and whatever issue i thought i could contribute to, had already been closed by maintainer as there were other contributors also. Thanks to &lt;a href="https://finder.eddiehub.io/" rel="noopener noreferrer"&gt;Good-first-issue-finder&lt;/a&gt; , this site was created by Eddiehub organization(i found it during the MLH Global hack week Open source), and came to know about some projects that i could contribute to. First PR that i made under the tag of Hacktoberfest belonged to a Readme file but it came as a booster(I don't know why xD!) in confidence then i made 4 more PRs in just next 2 days including making a PR in code. It was just my thinking process that stopped me from contributing otherwise it was not very tough. Actually there are much more big things going on in Open source, beginners are like small kids playing in backyard of Open source but it is definitely eye opening as you have to start somewhere otherwise you won't be able to start!&lt;/p&gt;

&lt;h3&gt;
  
  
  Growth
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Git/Github: You cannot just be a developer without Git and Github, it's mandatory(so contribute,learn more and more about Git and Github)&lt;/li&gt;
&lt;li&gt;Learn in Public: Don't just learn for the sake of learning only, learn so that you can help the society in some way or other&lt;/li&gt;
&lt;li&gt;Keep Contributing, Don't stop: Don't just stop at hacktoberfest, just keep looking for new projects and keep contributing&lt;/li&gt;
&lt;li&gt;Collaboration while building: Ultimately each project that would be used by people will be build with developers when they collaborate, so learning about how to collaborate is more important than most of the people think!&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>hack23contributor</category>
      <category>beginners</category>
      <category>opensource</category>
      <category>majorleaguehacking</category>
    </item>
  </channel>
</rss>
