dgplug member blogs

Reader

Read the latest posts from dgplug member blogs.

from titas

Hello people of the world wide web.
I'm Titas, a CS freshman trying to learn programming and build some cool stuff. Here's how I understood the importance of open source.

The first time I heard of open source was about 3 years ago in a YouTube video, but I didn't think much of it.
Read about it more and more on Reddit and in articles.

Fast forward to after high school — I'd failed JEE and had no chance of getting into a top engineering college. So I started looking at other options, found a degree and said to myself:
Okay, I can go here. I already know some Java and writing code is kinda fun (I only knew basics and had built a small game copying every keystroke of a YouTube tutorial).
So I thought I could learn programming, get a job, and make enough to pay my bills and have fun building stuff.

Then I tried to find out what I should learn and do.
Being a fool, I didn't look at articles or blog posts — I went to Indian YouTube channels.
And there was the usual advice: Do DSA & Algorithms, learn Web Development, and get into FAANG.

I personally never had the burning desire to work for lizard man, but the big thumbnails with “200k”, “300k”, “50 LPA” pulled me in.
I must’ve watched 100+ videos like that.
Found good creators too like Theo, Primeagen, etc.

So I decided I'm going to learn DSA.
First, I needed to polish my Java skills again.
Pulled out my old notebook and some YT tutorials, revised stuff, and started learning DSA.

It was very hard.
Leetcode problems weren't easy — I was sitting for hours just to solve a single problem.
3 months passed by — I learnt arrays, strings, linked lists, searching, sorting till now.
But solving Leetcode problems wasn't entertaining or fun.
I used to think — why should I solve these abstract problems if I want to work in FAANG (which I don't even know if I want)?

Then I thought — let's learn some development.
Procrastinated on learning DSA, and picked up web dev — because the internet said so.
Learnt HTML and CSS in about 2-3 weeks through tutorials, FreeCodeCamp, and some practice.

Started learning JavaScript — it's great.
Could see my output in the browser instantly.
Much easier than C ,which is in my college curriculum (though I had fun writing C).

Started exploring more about open source on YouTube and Reddit.
Watched long podcasts to understand what it's all about.
Learnt about OSS — what it is, about Stallman, GNU, FOSS.
OSS felt like an amazing idea — people building software and letting others use it for free because they feel like it.
The community aspect of it.
Understood why it's stupid to have everything under control of a capitalist company — who can just one day decide to stop letting you use your own software that you paid for.

Now I’m 7 months into college, already done with sem 1, scored decent marks.
I enjoy writing code but haven't done anything substantial.
So I thought to ask for some help. But who to ask?

I remembered a I've heard about this distant cousin Kushal who lives in Europe and has done some great software and my mother mentioned him like he was some kind of a genius .I once had a brief conversation with him via text regarding if I should take admission in BCA than an engineering degree, and his advice gave me some motivation and positivity . He said:

“BCA or Btech will for sure gets a job faster Than tradional studying If you can put in hours, that is way more important than IQ.
I have very average IQ but I just contributed to many projects.”

So 7 months later, I decided to text him again — and surprisingly, he replied and agreed to talk with me on a call.
Spoke with him for 45 odd minutes and asked a bunch of questions about software engineering, his work, OSS, etc.

Had much better clarity after talking with him.
He gave me the dgplug summer training docs and a Linux book he wrote.

So I started reading the training docs.

  • Step 0: Install a Linux distro → already have it ✅
  • Step 1: Learn touch typing → already know it ✅

Kept reading the training docs.
Read a few blog posts on the history of open source — already knew most of the stuff but learnt some key details.

Read a post by Anwesha on her experience with hacking culture and OSS as a lawyer turned software engineer — found it very intriguing.

Then watched the documentaries Internet's Own Boy and Coded Bias.
Learnt much more about Aaron Swartz than I knew — I only knew he co-founded Reddit and unalived himself after getting caught trying to open-source the MIT archives.

Now I had a deeper understanding of OSS and the culture.
But I had a big question about RMS — why was he so fixated on the freedom to hack and change stuff in the software he owned?
(Yes, the Free in FOSS doesn’t stand for free of cost — it stands for freedom.)

I thought free of cost makes sense — but why should someone have the right to make changes in a paid software?
Couldn't figure it out.
Focused on JS again — also, end-semester exams were coming.
My university has 3 sets of internal exams before the end-semester written exams. Got busy with that.

Kept writing some JS in my spare time.
Then during my exams...

It was 3:37 am, 5 June. I had my Statistics exam that morning.
I was done with studying, so I was procrastinating — watching random YouTube videos.
Then this video caught my attention:
How John Deere Steals Farmers of $4 Billion a Year

It went deep into how John Deere installs software into their tractors to stop farmers and mechanics from repairing their own machines.
Only authorized John Deere personnel with special software could do repairs.
Farmers were forced to pay extra, wait longer, and weren’t allowed to fix their own property.

Turns out, you don’t actually buy the tractor — you buy a subscription to use it.
Even BMW, GM, etc. make it nearly impossible to repair their cars.
You need proprietary software just to do an oil change.

Car makers won’t sell the software to these business owners, BUT they'll offer 7500$/year subscriptions to use their software. One auto shop owner explained how he has to pay $50,000/year in subscriptions just to keep his business running.

These monopolies are killing small businesses.

It’s not just India — billion-dollar companies everywhere are hell-bent on controlling everything.
They want us peasants to rent every basic necessity — to control us.

And that night, at 4:15 AM, I understood:

OSS is not just about convenience.
It’s not just for watching movies with better audio or downloading free pictures for my college projects.
It’s a political movement — against control.
It’s about the right to exist, and the freedom to speak, share, and repair.


That's about it. I'm not a great writer — it's my first blog post.

Next steps?
Learn to navigate IRC.
Get better at writing backends in Node.js.
And I'll keep writing my opinions, experiences, and learnings — with progressively better English.

print("titas signing out , post '0'!")
 
Read more...

from sandeepk

1. Why did you make the blog in the first place?

This blog initially started as part of the summer training by DGPLUG, where the good folks emphasize the importance of blogging and encourage everyone to write—about anything! That motivation got me into the habit, and I’ve been blogging on and off ever since.

2. What platform are you using to manage your blog and why did you choose it?

I primarily write on WriteFreely, hosted by Kushal, who was kind enough to host an instance. I also occasionally write on my WordPress blog. So yeah, I have two blogs.

3. Have you blogged on other platforms before?

I started with WordPress because it was a simple and fast way to get started. Even now, I sometimes post there, but most of my recent posts have moved to the WriteFreely instance.

4. How do you write your posts?

I usually just sit down and write everything in one go. Followed by editing part—skimming through it once, making quick changes, and then hitting publish.

5. When do you feel most inspired to write?

Honestly, I don’t wait for inspiration. I write whenever I feel like it—sometimes in a diary, sometimes on my laptop. A few of those thoughts end up as blog posts, while the rest get lost in random notes and files.

6. Do you publish immediately after writing or do you let it simmer a bit as a draft?

It depends. After reading a few books and articles on writing, I started following a simple process: finish a draft in one sitting, come back to it later for editing, and then publish.

7. Your favorite post on your blog?

Ahh! This blog post on Google Cloud IAM is one I really like because people told me it was well-written! :)

8. Any future plans for your blog? Maybe a redesign, changing the tag system, etc.?

Nope! I like it as it is. Keeping it simple for now.

A big thanks to Jason for mentioning me in the challenge!

Cheers!

 
Read more...

from mrinalraj

Hey there! 👋 Welcome to my personal insights from the incredible Aero India 2025 event held at Yelahanka Air Base, Bengaluru! 🇮🇳✨ Buckle up, and let’s dive into this high-flying adventure! 🛩️🔥


🌅 Early Bird Adventures

Woke up super early ⏰ to beat the traffic towards Yelahanka ✨
Quickly grabbed some breakfast 🥪☕ and rushed to the bus stop 🚌
Took a connection via Hebbal ➡️ and then headed straight to Yelahanka Air Base 🚏🛫


👫 New Friends & Quick Access

Met some amazing people on the way 👋 — especially Shelja from HAL 👩‍🔧 who helped me get into the ADVA area swiftly 🔐💨
Such warmth and camaraderie! ❤️


🪑 Perfect Spot for Viewing

There were special seating arrangements 🎟️ with a direct view of the majestic birds in the sky 🛫🦅
There was a major buzz around:

  • 🇷🇺 Su-57
  • 🇺🇸 F-35
  • 🇮🇳 Hansa-S performing jaw-dropping aerobatics 🔄🎯

The sky was on 🔥 with excitement!


📅 How You Can Experience It Too!

🗓️ Dates: 10th – 14th Feb 2025
🎫 Single-Day Entry Passes Only

💼 Business Pass

  • Access to: Exhibitions (IDEX), Seminars, and Air Show (ADVA)
  • ❌ Excludes invite-only events (like Raksha Mantri Dinner, CEO Meet)
  • 💸 Cost: ₹5000/day

🎟️ ADVA Pass

  • Access to: Air Show and select exhibitions
  • ❌ May not include halls with foreign exhibitors (🇮🇱 Israel, 🇫🇷 Safran, 🇬🇧 Rolls-Royce, etc.)
  • 💸 Cost: ₹1000/day

🧑‍🤝‍🧑 General Pass

  • Access to: ADVA + Exhibitions
  • Only valid on: 4th & 5th day of the event
  • 🚸 Expect it to be crowded
  • 💸 Cost: ₹2500/day

🎫 My Experience with the Business Pass

Got myself a Business Pass 😎
Went straight to ADVA after a thorough bag check 🧳🔍
💡 Pro Tip: You can carry your own water bottle & snacks (chips, etc.) 💦🍿

By 11:45 AM, the air show was done 💥
I dashed over to the Exhibition Hall 🏛️ where I saw:

  • The mighty 🇮🇳 Kaveri Engine
  • Cutting-edge defense tech usually not open to public 👀📸

And yes, photography was allowed! 📷✨


🎤 Tech Talks & Seminars

After a bit of a hunt 🧭 I found the Seminar Hall
Was warmly welcomed 🤝 and walked into a room filled with:

  • 🪖 Top military generals
  • 💼 Business leaders from GE, Rolls-Royce, Safran

It was just wow — an incredible energy of innovation and strategy in the room! 🌐⚙️


🏁 Conclusion

This was a once-in-a-lifetime event 💫
I met brilliant minds 🧠, saw next-gen tech 🔧, and watched thrilling air stunts in real-time 🛩️💨

Highly recommend not missing this epic celebration of India's aviation might 🇮🇳✈️


💬 Got questions or want to connect?
📧 Reach me at: reach.mrinalraj@gmail.com
Let the skies inspire you! 🌤️🇮🇳

 
Read more...

from mrinalraj

Scenario

Folks! Have you ever wondered how to create a URL that always points to your router, even when its public IP address changes? It might sound complex and costly, but it's actually free!

Concept

This involves setting up Dynamic DNS (DDNS).

What you need

  1. A Wi-Fi Router supporting NO-IP as DDNS
  2. An account on NO-IP website

Steps for creating hostname in NO IP:

  1. Login to NO-IP website. Make sure to avoid use of special character in the password.
  2. Create a hostname.
  3. We are Done!!!

Steps for configuring DDNS in router:

  1. Login to your router with credentials.
  2. Navigate to DDNS which would possibly under Internet tab.
  3. Configuring DDNS. 3.1 Keep WAN Connection as 'auto'. 3.2 Provider: 'No-IP' 3.3 Username: 3.4 Password: 3.5 Hostname: Give the newly created hostname
  4. We are Done!!!

Testing

Reboot your router and verify if NO IP website is showing the recent router's public IP.

Result

Now every time your router public IP changes it would reflect the recent IP on the website.

Usage

NO-IP provides a free DDNS hostname that can be used in projects instead of the router's public IP address. Simply confirm the renewal email after 30 days.

Thank you !!! Follow Mrinal

 
Read more...

from mrinalraj

Scenario

Imagine wanting to stream video from a device behind your home router to your personal phone over the internet. This may sound like a complex task, but with port forwarding, it's simpler than you think.

What you need:

  1. A Wi-Fi Router
  2. A computer displaying the video feed connected to the Wi-Fi router
  3. A VNC viewer on your remote mobile device

The Solution:

Port forwarding is the secret sauce that makes this setup seamless. Here's how you can do it:

Steps:

Router –> Computer –> Display | Internet –> Mobile –> VNC

  1. Lets Visualize the network diagram as above.
  2. Be physically near your router.
  3. Login your Wi-Fi router with credentials.
  4. Navigate to Port Forwarding section. It must be in the Security section.
  5. Set the Port forwarding rules 5.1. Service Name: Give the port forwarding rule a descriptive name. 5.2. Port Range: Specify the range of ports you want to forward (e.g., 5900- 5901 for a single port). 5.3. Local IP Address: Enter the IP address of the device on your local network that you want to forward the ports to. Refer my previous post on How to make a connected device static. 5.4. Protocol: Select the protocol for the port forwarding rule (TCP, UDP, or both). 5.5 Keep WAN HOST IP as 0.0.0.0

We are done here!!! See its that simple. Lets now test it over is my port open? website.

On Personal Mobile over Internet

  1. Install VNC over mobile phone
  2. Enter the router public IP followed by port number eg. 24.57.121.123:5900
  3. Suppose you don't have a router public IP address handy you can get it from what's my IP address? website.
  4. Above IP means that in the router public IP, connect to device at port 5900
  5. Enter credentials and we are done!!!

Limitation

  1. Since your router IP changes after reboot. Refer my previous post on How to get free url for Router's public IPs
  2. If the local device streaming feed is not static. It me loose the IP after device restart. Making device static is better solution. Refer my previous post on How to make a connected device static.

Thank you !!! Follow Mrinal

 
Read more...

from mrinalraj

Scenario

I recently needed to establish a static IP for my Python project to facilitate SSH access. The issue I faced was that DHCP kept assigning a new IP every time my system rebooted.

I discovered that we can set the IP address to be static, and the steps for doing so are outlined below:

About:

dhcpcd.conf:

Location: /etc/dhcpcd.conf Usage: DHCP client daemon is used towards the client side to configure the interfaces.

while

dhcpd.conf

Location: /etc/dhcp/dhcpd.conf Usage: It acts as server for dynamically assigning IPs to devices in the network

Step 0: Setup dhcpcd:

Install: sudo apt-get install dhcpcd Enable: sudo systemctl enable dhcpcd sudo systemctl start dhcpcd Verify: sudo systemctl status dhcpcd

Step 1: Open the dhcpcd.conf file

sudo nano /etc/dhcpcd.conf

If your project uses Wi-Fi, proceed with the following steps; otherwise, replace the interface name accordingly. interface wlan0 static ip_address=your_desired_static_ip/24 static routers=your_router_ip static domain_name_servers=your_dns_server_ip or interface wlan0 static ip_address=your_desired_static_ip/24 static routers=192.168.0.1 static domain_name_servers=192.168.0.1 8.8.8.8

Replace “your_desired_static_ip”, “your_router_ip”, and “your_dns_server_ip” with the appropriate values for your network. Ensure you choose an IP address that is not already in use on your network.

How to get router ip: Refer whats my ip address?

How to get the dns server: On terminal do nslookup google.com

Note: you need to have package 'dnsutils' installed. (sudo apt-get install dnsutils)

Step 2: Restart the dhcp service

sudo service dhcpcd restart or do sudo reboot

 
Read more...

from mrinalraj

Scenario

I recently wanted my Python program to execute right after the system boots up. I discovered several options to achieve this, eliminating the need for manual intervention to run the program.

Option 1: Editing through Crontab

  1. Open a terminal with elevated privileges: sudo su -
  2. Edit the crontab configuration: crontab -e
  3. Add the following command to start the Python program (assuming you want to run it on a Raspberry Pi terminal): ```bash
  4. @reboot /usr/bin/python3 /path/to/your/script.py

Option 2: Editing through services using systemd

  • Create a script, name it as “myscript.sh”
  • Make the script executable: chmod +x myscript.sh
  • Navigate to the systemd directory: cd /etc/systemd/system/
  • Create a service file named “myscript.service” inside the systemd directory.
  • And below lines using nano myscript.sh
Description=My Script

[Service]
ExecStart=/path/to/myscript.sh
WorkingDirectory=/path/to/
StandardOutput=inherit
StandardError=inherit
Restart=always
User=<replace_username>

[Install]
WantedBy=multi-user.target
  • Reload systemd: sudo systemctl daemon-reload
  • Enable the service: sudo systemctl enable myscript.service
  • Start the service: sudo systemctl start myscript.service
  • To check the service status: sudo systemctl status myscript.service

Option 3: Autostart using lxsession

  • Edit the autostart configuration file: nano ~/.config/lxsession/LXDE-pi/autostart
  • Add the following line to automatically start the Python script: @lxterminal -e python3 /path/to/your/script.py
  • Save the file and initiate a system reboot: sudo reboot
 
Read more...

from Pradhvan

djangonaut_space_image

Week 1 started with a welcome session hosted by the organizers to give us all an opportunity to say hello and meet each other. Since most of the folks would be working in different teams, it was really nice to talk to each member of the cohort in one session.

WelcomeToDjangonautSpace Djangonaut Welcome Session

I picked up two issues to work on this week:

  • For djangoproject.com, I am working on fixing feed aggregation that let's approved users add their RSS feed in the website. The github issue #1137 has a fair bit of information on the issue and the detailed notes from Carlton were really helpful to get a mental model of the problem. I am still working on a draft PR and hopefully I can have a initial version of the draft out for review in the next week or so.

  • For django-cms, I am pairing with my fellow team mates on the issue #5839 that deals with Internationalization and redirection of a page and homepage when the pages have content in different languages. On our pairing session we did manage to replicate the same issue in django-cms quickstart but weren't able to figure it out, need to do some more digging on it.

What I learnt this week 🧠

  • Supporting Multiple Languages with Django
  • How to set single instance model with constraints in Django
  • How to configure multiple pages with primary and fallback languages in django-cms

Side Quests 🧙🏾‍♂️

  • For django-cms I think a really good tutorial can be one that builds upon where Django Girls tutorial leaves you with. This tutorial can also serve really well as getting started guide for django-cms from a perspective of someone who isn't well versed with Django or wants a beginner friendly introduction on how to use django-cms with your Django project.

Reflections🪞

  • I need to set more structured and dedicated time to work on the issues I pick up during the week.

Credits: – Djangonaut Logo

#Djangonaut

 
Read more...

from Pradhvan

djangonaut_space_image

2024 has started on a good note for me, I got accepted into the the djangonaut program. It's a eight week mentorship program run by folks in the Django community to help others contribute back to the Django ecosystem.

Team size is intentionally kept small, for three Djangonauts per team there is one captian and one navigator.

Week 0 is mostly focused on getting to know folks in the cohort, your team and the mentors.

I got sorted into a team mars and we're working on contributions to the django-cms project.

The team consists of me, Moe, Raffaella, Anvansh our captian and Mark Walker as our navigator.

Activity Log for Week 0:

  • Picked a weekly catchup time with Mark, since all of us are on a different timezone.
  • Joined the django-cms's slack channel and got introduced to other memeber of the community in the django-cms's bi-weekly tech committee meeting.
  • Played with django-cms-quickstart to get a bird eye's view of the project.
  • Picked out potential tickets to work on for next week.

One really cool thing I liked about the cohort is they're big on encouraging us to talk with other members on the discord channel, explore various team projects, and pick up tasks that interest us from them.

I've always been fascinated by Django Debug Toolbar and ORM, so I'm thinking of starting with some low-hanging fruit there or revisiting my old Django tickets that I left hanging.

Looking forward to the next eight weeks to collaborate with this amazing community and learn along the way.

Credits: – Djangonaut Logo

#Djangonaut

 
Read more...

from sandeepk

In CSS, combinators are used to select content by combining selectors in specific relationships. There are different types of relationships that can be used to combine selectors.

Descendant combinator

The descendant combinator is represented by a space “ ” and typically used between two selectors. It selects the second selector if the first selector is the ancestor (parent, parent parent's) element. These selectors are called the descendant selectors.

.cover p {
    color: red;
}
<div class="cover"><p>Text in .cover</p></div>
<p>Text not in .cover</p>

In this example, the text “Text in .cover” will be displayed in red.

Child combinators

The child combinator is represented by “>” and is used between two selectors. In this, an element is only selected if the second selector is the direct child of the first selector element. This means there should not be any other selector between the first selector element and second element selector.

ul > li {
    border-top: 5px solid red;
} 
<ul>
    <li>Unordered item</li>
    <li>Unordered item
        <ol>
            <li>Item 1</li>
            <li>Item 2</li>
        </ol>
    </li>
</ul>

In this example, the <li> element with the text “Unordered item” will have a red top border.

Adjacent sibling combinator

The adjacent sibling combinator is represented by “+” is placed between the two CSS selector. In this element is selected if the selector element is directly followed by the first element selector or only the adjacent sibling

h1 + span {
    font-weight: bold;
    background-color: #333;
    color: #fff;
    padding: .5em;
}
<div>
    <h1>A heading</h1>
    <span>Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth tatsoi tomatillo
            melon azuki bean garlic.</span>

    <span>Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts fava bean collard
            greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea peanut soko zucchini.</span>
</div>

In this example, the first element will have the given CSS properties.

General sibling combinator

The general sibling combinator is represented by “~“. It selects all the sibling element, not only the direct sibling element, then we use the general sibling combinator.

h1 ~ h2 {
    font-weight: bold;
    background-color: #333;
    color: #fff;
    padding: .5em;
}
<article>
    <h1>A heading</h1>
    <h2>I am a paragraph.</h2>
    <div>I am a div</div>
    <h2>I am another paragraph.</h2>
</article>

In this example, every <h2> element will have the given CSS properties.

CSS combinators provide powerful ways to select and style content based on their relationships in the HTML structure. By understanding combinators, we can create clean, maintainable, and responsive web designs.

Cheers!

ReferencesMDN Web Docs

#CSS #Combinators #WebDevelopment #FrontendDev

 
Read more...

from Pradhvan

Python has a built in function called abs() that is used to find the absolute value from an interget or float value.

Absolute values are values that return a magnitue of a given number. If I put it in more simple tems, magnitue of a number tells us how far they are from zero in the number line.

For negative numbers - sign is not considered.

Example

>>> x, y = -10.11, -10
>>> abs(x)
>>>10.11
>>>abs(y)
>>>10

Like most of python builtins it also has a dunder method __abs__

>>> y = -10
>>> y.__abs__()
>>> 10

Real World Example

temprature_chart

Suppose you are given a chart of temprature that has temprature values and you need to find the value that is closest to 0.

class TempratureReader:

    def closest_to_zero(self, readings: List[float]) -> float:

        result = readings[0]

        for reading in readings:
            if abs(reading) < abs(result):
                result = reading
            elif abs(reading) == abs(result):
                result = max(result, reading )

        return result
>>> t = TempratureReader()
>>> t.closest_to_zero([10.11,-35.11,22.11, -2.1, -1.1, 1.1])
>>> 1.1

absoulte values of other types

  • For complex number, abs() returns the maginitudu.
>>> num = complex(3, 10)
>>> num
>>> (3+10j)
>>> abs(num)
>>> 10.44030650891055
  • For Decimal values it just works like float just returns the postive value.

References

 
Read more...

from sandeepk

Today, I decided to analyze my bank account statement by downloading it from the day I opened my bank account. To my surprise, it was presented as a web page. Initially, my inner developer urged me to write code to scrape that data. However, feeling a bit lazy, I postponed doing so.

Later in the evening, I searched the web to find an alternate way to extract the data and discovered that HTML tables can be converted to CSV files. All I had to do was save the code in CSV format. I opened the Chrome browser's inspect code feature, copied the table, saved it with the CSV extension, and then opened the file with LibreOffice. Voila! I had the spreadsheet with all my transactions.

Cheers!

#TIL #CSV #HTML Table

 
Read more...

from Pradhvan

How not to do it

If you are doing a fresh setup of UFW whenever you add a rule like ufw allow 'Nginx HTTP' the status of it would be inactive.

$sudo ufw allow 'Nginx HTTP'
Rule added
$sudo ufw status
Status: inactive

This would seem odd right, why is it inactive.

During your search, you may discover that you need to activate it with a new command that you find on the internet in order to understand why it was inactive. So you just enable it.

Simple problem, simple solution. :-P

$sudo ufw enable
Output
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

If you just do yes here and go on a break closing the ssh connection.

Congratulations, you are logged out of your server.

Thisisfine

This just happened with me today while setting up a small droplet on digitalocean that hosts static page for a domain with nginx.

How to do it correctly

The problem lies in the last command

$sudo ufw enable
Output
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

There can be three cases now if you have enabled UFW.

First, don't quit the ssh session and add a rule to allow ssh connection.

$sudo ufw allow OpenSSH
$sudo ufw allow ssh
$sudo ufw allow 22

Assuming you use a default port for ssh, if it;s some other port you can just allow that port number like the port 333

$sudo ufw allow 333

That way you would still have access to SSH when your session ends/timesout.

Second, be smart and allow ssh ports before you enable the ufw.

Third, you just go bonkers and reset the ufw and start again. hahahaha!

sudo ufw reset

Common ufw commands you might find handy

  • Be sus and deny incoming.
# Set the defaults to deny incoming and allow outgoing connections
$sudo ufw default deny incoming
$sudo ufw default allow outgoing

  • Allow specific port ranges
$sudo ufw allow 6000:6007/tcp
$sudo ufw allow 6000:6007/udp
  • Allow specific address
$sudo ufw allow from 203.0.113.4


References

 
Read more...

from Pradhvan

Decorators 101

  • A decorator may perform some processing with the decorated function, and returns it or replaces it with another function or callable object.

  • Inspection reveals that target is a now a reference to inner

@deco
def target():
    print("Running target()")

target # <function deco.<locals>.inner at 0x10063b598>
  • Decorators have the power to replace the decorated function with a different one.
  • Decorators are executed immediately when a module is loaded.
# Program to check how decorators are executed

registry = []


def register(func):
    print(f"running register({func})")
    registry.append(func)
    return func

@register
def f1():
    print("running f1()")

@register
def f2():
    print("running f2()")

def f3():
    print(f"running f3()")

def main():
    print("running main()")
    print("registry ->", registry)
    f1()
    f2()
    f3()

if __name__ == '__main__':
    main()
"""
OUTPUT
------

running register(<function f1 at 0x107a25c10>)
running register(<function f2 at 0x1079b0280>)
running main()
registry -> [<function f1 at 0x107a25c10>, <function f2 at 0x1079b0280>]
running f1()
running f2()
running f3()

"""
  • Register runs (twice) before any other function in the module.

  • When register is called, it receives as an argument the function object being decorated—for example, <function f1 at 0x100631bf8>.

    • After the module is loaded, the registry list holds references to the two decorated functions: f1 and f2.
  • A real decorator is usually defined in one module and applied to functions in other modules.Unlike the example above.

Variable Scoping

b = 6

def smart_function(a):
    print(a)
    print(b)
    b = 9 

smart_function(3)

"""
OUTPUT
------

      3 def smart_function(a):
      4     print(a)
----> 5     print(b)
      6     b = 9
      7 

UnboundLocalError: local variable 'b' referenced before assignment
"""
  • Python does not require you to declare variables, but assumes that a variable assigned in the body of a function is local.

  • To make the above program work with b=6 you would need to use the keyword global.

Closure

  • A closure is a function with an extended scope that encompasses nonglobal variables referenced in the body of the function but not defined there.

  • It does not matter whether the function is anonymous or not; what matters is that it can access nonglobal variables that are defined outside of its body.

# Closure Example

def make_averager():
    series = [] # Free Variable
    
    def averager(new_value):
        series.append(new_value)
        total = sum(series)
        return total/sum(series)
    return averager # Returns a function object

avg = make_averager()

avg(10) # 10.0

avg(11) # 10.5 

avg(12) # 1.0
  • series is a local variable of make_averager because the assignment series = [] happens in the body of that function. But when avg(10) is called, make_averager has already returned, and its local scope is long gone.

  • Within averager(), series is a free variable i.e a variable that is not bound in the local scope.

  • __code__ attribute keeps the names of the local and free variables.

  • The value for series is kept in the __closure__ attribute of the returned function avg.

avg.__code__.co_varnames # ('new_value', 'total')

avg.__code__.co_freevars # ('series',)

avg.__closure__ # (<cell at 0x107a44f78: list object at 0x107a91a48>,) 

avg.__closure__[0].cell_contents # [10, 11, 12]

Formal Definition

A closure is a function that retains the bindings of the free variables that exist when the function is defined, so that they can be used later when the function is invoked and the defining scope is no longer available.

Refactoring averager

def make_averager():
    count = 0
    total = 0
    
    def averager(new_value):
        count += 1
        total += new_value
        return total/count
    return averager

avg = make_averager()
avg(10)

"""
OUTPUT
------
UnboundLocalError: local variable 'count' referenced before assignment
"""

Why did count not behave like series i.e free variable ?

  • For series we took advantage of the fact that lists are mutable and we never assigned to the series name. We only called series.append and invoked sum and len on it.
  • count is an immutable types and all you can do is read, never update. If you try to rebind them, as in count = count + 1, then you are implicitly creating a local variable count. It is no longer a free variable, and therefore it is not saved in the closure.

Refactoring averager with nonlocal

def make_averager():
    count = 0
    total = 0
    
    def average(new_value):
        nonlocal count, total
        count += 1 
        total += new_value
        return total / count 
    return averager
  • nonlocal lets you declare a variable as a free variable even when it is assigned within the function.
  • If a new value is assigned to a nonlocal variable, the binding stored in the closure is changed.

    # Code example here!
    

Understanding a simple decorator

# clockdeco.py
import time 

def clock(func):
    def clocked(*args):
        t0 = time.perf_counter()
        # closure for clocked encompasses the func free variable
        result = func(*args)
        elapsed = time.perf_counter()
        name = func.__name__
        arg_str = ','.join(repr(args) for arg in args)
        print(f'[{elapsed:0.8f}s] {name}({arg_str}) -> {result!r}')
        return result
    return clocked
# SimpleDeco.py

import time 

from clockdeco import clock

@clock
def snooze(seconds):
    time.sleep(seconds)

@clock
def factorial(n):
    return 1 if n < 2 else n*factorial(n-1)


if __name__ == '__main__':
    print('*' * 40, 'Calling snooze(.123)')
    snooze(.123)
    print('*' * 40, 'Calling factorial(6)')
    print('6! =', factorial(6))
    
"""
OUTPUT
------

**************************************** Calling snooze(.123)
[14549.25258126s] snooze((0.123,)) -> None
**************************************** Calling factorial(6)
[14549.25291446s] factorial((1,)) -> 1
[14549.25296426s] factorial((2,)) -> 2
[14549.25301028s] factorial((3,)) -> 6
[14549.25305792s] factorial((4,)) -> 24
[14549.25310024s] factorial((5,)) -> 120
[14549.25314435s] factorial((6,)) -> 720
6! = 720
"""    
  • @clock on factorial(n) is just the syntatic sugar for factorial = clock(factorial)
  • clock(func) gets the factorial function as its func argument.
  • It then creates and returns the clocked function, which the Python interpreter assigns to factorial behind the scenes.
  • The __name__ of factorial(n) would give you clocked
import clockdeco_demo
clockdeco_demo.factorial.__name__
"""
Output
------
'clocked'
"""
  • Each time factorial(n) is called, clocked(n) gets executed.

Common Decorators in the standard library through functools

  • @wraps
  • @lru_cache
  • @singledispatch

#notes #Python #FluentPython #Decorators #Closure

 
Read more...

from sandeepk

The Debug Diary – Chapter I

Lately, I was debugging an issue with the importer tasks of our codebase and came across a code block which looks fine but makes an extra database query in the loop. When you have a look at the Django ORM query

jato_vehicles = JatoVehicle.objects.filter(
    year__in=available_years,<more_filters>
).only("manufacturer_code", "uid", "year", "model", "trim")

for entry in jato_vehicles.iterator():
    if entry.manufacturer_code:
        <logic>
    ymt_key = (entry.year, entry.model, entry.trim_processed)
...

you will notice we are using only, which only loads the set of fields mentioned and deferred other fields, but in the loop, we are using the field trim_processed which is a deferred field and will result in an extra database call.

Now, as we have identified the performance issue, the best way to handle the cases like this is to use values or values_list. The use of only should be discouraged in the cases like these.

Update code will look like this

jato_vehicles = JatoVehicle.objects.filter(
    year__in=available_years,<more-filters>).values_list(
    "manufacturer_code",
    "uid",
    "year",
    "model",
    "trim_processed",
    named=True,
)

for entry in jato_vehicles.iterator():
    if entry.manufacturer_code:
        <logic>
    ymt_key = (entry.year, entry.model, entry.trim_processed)
...

By doing this, we are safe from accessing the fields which are not mentioned in the values_list. If anyone tries to do so, an exception will be raised.

** By using named=True we get the result as a named tuple which makes it easy to access the values :)

Cheers!

#Django #ORM #Debug

 
Read more...

from sandeepk

select_for_update is the answer if you want to acquire a lock on the row. The lock is only released after the transaction is completed. This is similar to the Select for update statement in the SQL query.

>>> Dealership.objects.select_for_update().get(pk='iamid')
>>> # Here lock is only required on Dealership object
>>> Dealership.objects.select_related('oem').select_for_update(of=('self',))

select_for_update have these four arguments with these default value – nowait=False – skiplocked=False – of=() – nokey=False

Let's see what these all arguments mean

nowait

Think of the scenario where the lock is already acquired by another query, in this case, you want your query to wait or raise an error, This behavior can be controlled by nowait, If nowait=True we will raise the DatabaseError otherwise it will wait for the lock to be released.

skip_locked

As somewhat name implies, it helps to decide whether to consider a locked row in the evaluated query. If the skip_locked=true locked rows will not be considered.

nowait and skip_locked are mutually exclusive using both together will raise ValueError

of

In select_for_update when the query is evaluated, the lock is also acquired on the select related rows as in the query. If one doesn't wish the same, they can use of where they can specify fields to acquire a lock on

>>> Dealership.objects.select_related('oem').select_for_update(of=('self',))
# Just be sure we don't have any nullable relation with OEM

no_key

This helps you to create a weak lock. This means the other query can create new rows which refer to the locked rows (any reference relationship).

Few more important points to keep in mind select_for_update doesn't allow nullable relations, you have to explicitly exclude these nullable conditions. In auto-commit mode, select_for_update fails with error TransactionManagementError you have to add code in a transaction explicitly. I have struggled around these points :).

Here is all about select_for_update which you require to know to use in your code and to do changes to your database.

Cheers!

#Python #Django #ORM #Database

 
Read more...