<?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: PGzlan</title>
    <description>The latest articles on DEV Community by PGzlan (@0xog_pg).</description>
    <link>https://dev.to/0xog_pg</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%2F1099561%2F41678a4e-d0ee-4875-81c5-0bbd0a3c2b25.png</url>
      <title>DEV Community: PGzlan</title>
      <link>https://dev.to/0xog_pg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/0xog_pg"/>
    <language>en</language>
    <item>
      <title>Identity and Access Management: Explained</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Mon, 06 Nov 2023 05:34:19 +0000</pubDate>
      <link>https://dev.to/0xog_pg/identity-and-access-management-explained-g81</link>
      <guid>https://dev.to/0xog_pg/identity-and-access-management-explained-g81</guid>
      <description>&lt;p&gt;The pillars of information security, namely Identification,  Authentication, Authorization, and Accountability (IAAA), are crucial  components in safeguarding sensitive information and resources by  ensuring their confidentiality, integrity, and availability.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identification&lt;/strong&gt; refers to the process of verifying a  user's claimed identity. Users provide a unique identifier, such as an  email address, username, or ID number, to establish their identity  within a particular system or environment. Many websites rely on email  addresses as identifiers instead of requiring users to create unique  usernames.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt; involves confirming that the user is  indeed who they claim to be. It aims to validate the claimed identity.  Passwords are a common authentication method, although other approaches  like entering a code received via email are gaining popularity due to  potential weaknesses in passwords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization&lt;/strong&gt; determines the user's permitted access rights. It involves granting specific privileges and permissions based  on the user's role, job function, or clearance level. By restricting  access to only necessary resources, the risk of unauthorized access and  data breaches is minimized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accountability&lt;/strong&gt; entails tracking user activity to  ensure they are held responsible for their actions. Once a user is  granted access to a system, mechanisms are in place to record and store  their activities in a centralized location. This logging of user  activity serves as a means to identify the source of security incidents  and take appropriate actions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Identity Management (IdM)
&lt;/h2&gt;

&lt;p&gt;Identity Management (IdM) is a vital aspect of cybersecurity that pertains to the management and regulation of digital identities. It encompasses the administration of user identities, including their authentication, authorization, and access control. The primary objective of IdM is to ensure that only authorized individuals can access specific resources and information. IdM systems are employed to oversee user identities across an organization's network.&lt;/p&gt;

&lt;p&gt;IdM systems utilize a centralized database to store user identities and access privileges. These systems offer functionalities for managing and monitoring user access to resources. Common features found in IdM systems include user provisioning, authentication, and authorization. User provisioning involves the creation and administration of user accounts, while authentication and authorization involve verifying a user's identity and granting access to designated resources.&lt;/p&gt;

&lt;p&gt;IdM systems play a critical role in organizations that utilize multiple systems and applications requiring access control. They streamline the management of user identities, mitigating the risk of unauthorized access to resources. Furthermore, IdM systems establish a central point of reference for user identity management, simplifying the process of managing user access rights for organizations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identity and Access Management (IAM)
&lt;/h2&gt;

&lt;p&gt;IAM (Identity and Access Management) is a more inclusive concept compared to IdM (Identity Management). It encompasses a range of processes and technologies aimed at managing and safeguarding digital identities and access privileges. IAM systems incorporate various functions such as user provisioning, access control, identity governance, and compliance management. Their purpose is to ensure that only authorized individuals can access specific resources and data, while also monitoring and controlling their access.&lt;/p&gt;

&lt;p&gt;IAM systems offer a comprehensive solution for managing and securing resource access within an organization. They integrate with multiple systems and applications, providing a centralized perspective on user identities and access rights. These systems utilize diverse technologies, including role-based access control, multi-factor authentication, and single sign-on, to manage access effectively.&lt;/p&gt;

&lt;p&gt;IAM systems aid organizations in complying with regulatory requirements such as HIPAA, GDPR, and PCI DSS. They provide functionalities to handle the lifecycle of user identities, including onboarding, offboarding, and access revocation. Furthermore, IAM systems enable organizations to track and audit user activity, helping prevent security breaches and ensuring compliance with industry regulations.&lt;/p&gt;

&lt;p&gt;Both IdM and IAM are integral components of cybersecurity as they ensure that only authorized individuals possess access to specific resources and information. While IdM systems focus on managing user identities, IAM systems encompass broader functions to manage and secure digital identities and access rights.&lt;/p&gt;

&lt;p&gt;A system regulates access to different resources using a selected model. Several prevalent access control models include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Discretionary Access Control (DAC)&lt;/li&gt;
&lt;li&gt;Role-Based Access Control (RBAC)&lt;/li&gt;
&lt;li&gt;Mandatory Access Control (MAC)&lt;/li&gt;
&lt;li&gt;Attribute-Based Access Control (ABAC)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In these models, access to resources is managed and granted based on different principles and mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discretionary Access Control
&lt;/h2&gt;

&lt;p&gt;Many people have utilized Discretionary Access Control (DAC) to share files or folders with friends and colleagues. In DAC, the owner of the resource explicitly adds users and assigns them appropriate permissions.&lt;/p&gt;

&lt;p&gt;For example, let's say you have your photos stored on an online platform. To share the images related to your graduation with your family, you individually add their accounts and grant them access to the specific album. As a result, the album permissions will reflect a few accounts with viewing privileges.&lt;/p&gt;

&lt;p&gt;This process is straightforward and under the complete control of the data owner. It works well for sharing with family members or a select few users within a company. However, difficulties can arise when attempting to scale sharing to a larger number of users, particularly as users' roles evolve over time. This situation leads us to consider sharing based on user roles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Role-Based Access Control
&lt;/h2&gt;

&lt;p&gt;Role-Based Access Control (RBAC) employs a highly intuitive approach. Each user is assigned one or more roles or functional positions, which determine their authorized access to different resources.&lt;/p&gt;

&lt;p&gt;For example, an accountant may require access to the company's accounting books but does not need access to research and development labs or documents. Consequently, users are categorized into various groups based on their roles. Authorization and access are then granted based on the group to which a user belongs.&lt;/p&gt;

&lt;p&gt;The classification of users according to their roles offers numerous advantages. For instance, when a user assumes a new role, it is simply a matter of adding them to the corresponding group. Similarly, if a user relinquishes a particular role, they can be removed from the relevant group. This approach greatly simplifies and streamlines maintenance tasks, making them more efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mandatory Access Control
&lt;/h2&gt;

&lt;p&gt;An operating system that implements Mandatory Access Control (MAC)  prioritizes security and imposes significant restrictions on user  capabilities. Such systems are typically used for specific purposes or  to handle highly classified data. Consequently, users are limited to  performing only essential tasks, and they are unable to carry out  actions like installing new software or modifying file permissions.&lt;/p&gt;

&lt;p&gt;AppArmor is a tool that enables the implementation of MAC on Linux  distributions. It is already included in various Linux distributions  such as Debian and Ubuntu.&lt;/p&gt;

&lt;p&gt;The SELinux project offers a flexible MAC solution for Linux systems. It is a standard feature in several Linux distributions like Red Hat  and Fedora.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attribute-Based Access Control
&lt;/h2&gt;

&lt;p&gt;Attribute-Based Access Control (ABAC) is a sophisticated access  control model that grants permissions based on attributes associated  with users, resources, and environmental conditions. Unlike traditional  access control models that rely on roles or groups, ABAC considers a  wide range of attributes in its decision-making process. These  attributes can include user characteristics, such as job title or  department, resource properties, such as sensitivity or location, and  contextual factors, such as time of day or network location.&lt;/p&gt;

&lt;p&gt;By evaluating these attributes, ABAC policies can dynamically  determine whether to grant or deny access to specific resources. This  dynamic decision-making capability allows organizations to implement  more fine-grained access control policies that align with their unique  security requirements. For example, an organization may define a policy  stating that only employees with a job title of "Manager" can access  confidential financial data during business hours, while restricting  access for other employees.&lt;/p&gt;

&lt;p&gt;ABAC provides a flexible and granular approach to access control.  Organizations can define complex policies that take into account  multiple attributes and their combinations to make access control  decisions. This flexibility allows for the implementation of more  nuanced and context-aware access control policies. Additionally, ABAC  supports the concept of dynamic and adaptive authorization, enabling  real-time adjustments to access permissions based on changing attributes or environmental conditions.&lt;/p&gt;

&lt;p&gt;Implementing ABAC typically involves the use of an attribute-based  policy language and an attribute-based policy enforcement point. The  policy language allows organizations to define and express their access  control policies using attributes and logical expressions. The policy  enforcement point evaluates these policies at runtime and enforces  access decisions based on the attributes associated with the requesting  user, requested resource, and the environment.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Python's IceCream Package: Effortless Debugging with Minimal Code</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sun, 29 Oct 2023 22:51:33 +0000</pubDate>
      <link>https://dev.to/0xog_pg/pythons-icecream-package-effortless-debugging-with-minimal-code-45fb</link>
      <guid>https://dev.to/0xog_pg/pythons-icecream-package-effortless-debugging-with-minimal-code-45fb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Often times when programming in Python, things don't work the way we expect them to work. We implement a function, and the function does not deliver the results that we were expect from it. Well, at least not all the time, and we have no clear reason to identify this behavior. Imagine some function taking some parameters &lt;code&gt;param1...paramN&lt;/code&gt;, then these parameters are used in a loop, which contains some conditional statements. So we have ourselves a complicated function, with loops, and conditions and things can become rather unpredictable.&lt;/p&gt;

&lt;p&gt;Of course the proper way to debug such a function would be by leveraging a debugger in your IDE (Integrated Development Environment) or your code editor by setting up break points to check what modifications occur to the variables inside. This can be rather tedious and a lot of time you find yourself avoiding the debugger and debugging mode. We just want to execute the code as it is right now, with a little bit of additional information so what ends up happening is just using good ol' &lt;code&gt;print&lt;/code&gt; statements.&lt;/p&gt;

&lt;p&gt;Debugging is an essential part of software development, and print statements have long been used to debug code. However, traditional print statements can be tedious to write and can clutter code. That's where the icecream (ic) package comes in. IceCream is a Python library that makes debugging effortless and readable with minimal code &lt;a href="https://towardsdatascience.com/introducing-icecream-never-use-print-to-debug-your-python-code-again-d8f2e5719f8a" rel="noopener noreferrer"&gt;[1]&lt;/a&gt;. In this blog post, we will explore the features of the IceCream package and provide code examples to demonstrate its usage.&lt;/p&gt;

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

&lt;p&gt;Let's say as a simple example, we have some function &lt;code&gt;multiply&lt;/code&gt; that takes &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; as parameters and returns the simple value of &lt;code&gt;a * b&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icecream&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;To test this function, we can write it in the following manner&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The output here would be:&lt;/p&gt;

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

6
12
20
30


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

&lt;/div&gt;

&lt;p&gt;This seems relatively simple to trace. That would not hold in cases we have a longer list of values to test. If this is a more complex function, we cannot predict immediately by looking at the function call what the result is going to. It would be nicer to have the function call to what is actually being called and what is the result of this function call and this is exactly what icecream &lt;code&gt;ic&lt;/code&gt; does &lt;a href="https://medium.com/@bobbymistery/debug-your-python-code-efficiently-with-icecream-package-10-advanced-examples-to-replace-print-820fef801cb0" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The output will look like this:&lt;/p&gt;

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

ic| multiply(2, 3): 6
ic| multiply(3, 4): 12
ic| multiply(4, 5): 20
ic| multiply(5, 6): 30


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

&lt;/div&gt;

&lt;p&gt;One of the neat things about &lt;code&gt;ic&lt;/code&gt; is, unlike &lt;code&gt;print&lt;/code&gt; (which have a &lt;code&gt;None&lt;/code&gt; return value), using &lt;code&gt;ic&lt;/code&gt; will not only provide a logging message, it will also get the returned value stored into the variable you assign it to:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this case, the output would be:&lt;/p&gt;

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

30
ic| multiply(5, 6): 30


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Multiple Values
&lt;/h3&gt;

&lt;p&gt;You can also use ic() to print multiple values at once. Here's an example:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icecream&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this example, we're using ic() to print the result of the multiplication operation and the result of the division operation. The output will look like this:&lt;/p&gt;

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

ic| result: 6, a/b: 0.6666666666666666


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

&lt;/div&gt;

&lt;p&gt;Note that ic() automatically separates the values with commas in the output &lt;a href="https://medium.com/@bobbymistery/debug-your-python-code-efficiently-with-icecream-package-10-advanced-examples-to-replace-print-820fef801cb0" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conditional Statements
&lt;/h3&gt;

&lt;p&gt;You can use ic() in conditional statements to print values only when certain conditions are met. Here's an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icecream&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="nf"&gt;is_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;is_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this example, we're using ic() to print the result of the conditional statement and the input value only when the input value is even. The output will look like this:&lt;/p&gt;

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

ic| result: True, num: 4
ic| result: False


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

&lt;/div&gt;

&lt;p&gt;Note that ic() will only print the second argument (num) when the first argument (result) is True &lt;a href="https://medium.com/@bobbymistery/debug-your-python-code-efficiently-with-icecream-package-10-advanced-examples-to-replace-print-820fef801cb0" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Iterables
&lt;/h3&gt;

&lt;p&gt;You can use ic() to print the contents of iterables such as lists, tuples, and dictionaries. Here's an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icecream&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sum_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="nf"&gt;sum_list&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this example, we're using ic() to print the input list and the sum of the list. The output will look like this:&lt;/p&gt;

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

ic| numbers: [1, 2, 3, 4, 5], result: 15


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

&lt;/div&gt;

&lt;p&gt;Note that ic() automatically prints the contents of the list &lt;a href="https://medium.com/@bobbymistery/debug-your-python-code-efficiently-with-icecream-package-10-advanced-examples-to-replace-print-820fef801cb0" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functions
&lt;/h3&gt;

&lt;p&gt;You can use ic() to print the result of a function call. Here's an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icecream&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;square_and_multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="nf"&gt;square_and_multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this example, we're using ic() to print the result of the multiply function call within the square_and_multiply function. The output will look like this:&lt;/p&gt;

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

ic| result: 12


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

&lt;/div&gt;

&lt;p&gt;Note that ic() automatically prints the return value of the function &lt;a href="https://medium.com/@bobbymistery/debug-your-python-code-efficiently-with-icecream-package-10-advanced-examples-to-replace-print-820fef801cb0" rel="noopener noreferrer"&gt;[2]&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nifty things about &lt;code&gt;ic&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;ic&lt;/code&gt; provides some nice utility in terms of readability, especially for large dictionaries. Let's say we have the following dict:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contacts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;John Doe&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contactMethods&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;123-456-7890&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;john.doe@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Jane Smith&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contactMethods&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;987-654-3210&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jane.smith@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Robert Johnson&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contactMethods&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;555-123-4567&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;robert.johnson@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Emily Davis&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contactMethods&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;111-222-3333&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;emily.davis@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Michael Brown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contactMethods&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;phone&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;444-555-6666&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;michael.brown@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We can print it using &lt;code&gt;ic&lt;/code&gt; to get some nice indentation and color&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fsatw9h3a5vwayxxnpfn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fsatw9h3a5vwayxxnpfn8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we call &lt;code&gt;ic()&lt;/code&gt; at a certain part of the function like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;icecream&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="nf"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;

&lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The output will look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ipython&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;d4984d3accb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;10.905&lt;/span&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6666666666666666&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This can be useful to determine where far we have reached in a certain function. You can also enable or disable it selectively&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br&gt;
&lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br&gt;
&lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/p&gt;

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

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

&lt;p&gt;&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ipython&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;d4984d3accb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;35.824&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ipython&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;d4984d3accb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;35.826&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ipython&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;d4984d3accb&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;multiply_and_divide&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;59&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;35.828&lt;/span&gt;&lt;br&gt;
&lt;span class="n"&gt;Out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.8571428571428571&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;IceCream is a powerful tool for debugging Python code that replaces the traditional print statement. It provides detailed information about variables, expressions, and function calls that make it easy to identify and fix errors in your code. With its customizable output, logging capabilities, and ability to access external modules, IceCream is a versatile debugging tool that can save you time and frustration. By using the examples provided in this blog post, you can start using IceCream in your own Python projects and improve your debugging workflow.&lt;/p&gt;




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

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://towardsdatascience.com/introducing-icecream-never-use-print-to-debug-your-python-code-again-d8f2e5719f8a" rel="noopener noreferrer"&gt;Introducing IceCream: Never Use Print() To Debug Your ...&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@bobbymistery/debug-your-python-code-efficiently-with-icecream-package-10-advanced-examples-to-replace-print-820fef801cb0" rel="noopener noreferrer"&gt;“Debug Your Python Code Efficiently with IceCream Package: 10 Advanced Examples to Replace Print Statements” | by Daniel Wu | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://towardsdatascience.com/stop-using-print-to-debug-in-python-use-icecream-instead-79e17b963fcc" rel="noopener noreferrer"&gt;Stop Using Print to Debug in Python. Use Icecream Instead | by Khuyen Tran | Towards Data Science&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Python Walrus Operator: An Introduction</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sat, 28 Oct 2023 19:14:20 +0000</pubDate>
      <link>https://dev.to/0xog_pg/python-walrus-operator-an-introduction-193f</link>
      <guid>https://dev.to/0xog_pg/python-walrus-operator-an-introduction-193f</guid>
      <description>&lt;p&gt;Python 3.8 introduced a new operator called the walrus operator, denoted by &lt;code&gt;:=&lt;/code&gt;. It's called the &lt;em&gt;Walrus&lt;/em&gt; operator because it looks like the eyes and the tusks of a walrus on its side. This operator allows you to evaluate an expression and assign its value to a variable in a single statement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Walrus Operator?
&lt;/h2&gt;

&lt;p&gt;The walrus operator, also known as the assignment expression operator, is a syntax enhancement that has been introduced in Python 3.8. It allows you to assign a value to a variable within an expression. The syntax for the walrus operator is &lt;code&gt;(variable := expression)&lt;/code&gt; &lt;a href="https://www.codeconquest.com/blog/python-walrus-operator-uses-and-controversy/"&gt;[1]&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Usage
&lt;/h2&gt;

&lt;p&gt;Let's start with a basic example to understand how the walrus operator works. Consider the following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;walrus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3357&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"walrus: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;walrus&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;/div&gt;



&lt;p&gt;In this example, we use the walrus operator to define the variable &lt;code&gt;value&lt;/code&gt; and assign it the value &lt;code&gt;3357&lt;/code&gt;. The expression &lt;code&gt;(value := 3357)&lt;/code&gt; returns the assigned value, which we then use to initialize the variable &lt;code&gt;walrus&lt;/code&gt;. As a result, both variables have the same value &lt;a href="https://www.codeconquest.com/blog/python-walrus-operator-uses-and-controversy/"&gt;[1]&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. If Statements
&lt;/h3&gt;

&lt;p&gt;The walrus operator can be useful in if statements when you want to perform an operation on an unknown variable. For example, let's say you want check if a specific environment variable is set and based on that, you want to execute a set of actions. This is one way it could be done conventionally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;shutil&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete_folder_contents&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Get the value of the "PGDATA" environment variable
&lt;/span&gt;    &lt;span class="n"&gt;pgdata_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PGDATA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Verify if the path exists
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="c1"&gt;# Iterate over the files and folders within the directory
&lt;/span&gt;            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="c1"&gt;# Check if it is a file and delete it
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="c1"&gt;# Check if it is a directory and delete it recursively
&lt;/span&gt;                &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rmtree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Folder contents deleted successfully."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The specified path does not exist."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The 'PGDATA' environment variable is not set."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;delete_folder_contents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how you can achieve this using the walrus operator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;shutil&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete_folder_contents&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Verify if the path exists
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PGDATA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Check if the path exists
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="c1"&gt;# Iterate over the files and folders within the directory
&lt;/span&gt;            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgdata_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

                &lt;span class="c1"&gt;# Check if it is a file and delete it
&lt;/span&gt;                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="c1"&gt;# Check if it is a directory and delete it recursively
&lt;/span&gt;                &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;shutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rmtree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Folder contents deleted successfully."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The specified path does not exist."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The 'PGDATA' environment variable is not set."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;delete_folder_contents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The assignment expression &lt;code&gt;(pgdata_path := os.environ.get("PGDATA", None))&lt;/code&gt; assigns the value of &lt;code&gt;os.environ.get("PGDATA", None)&lt;/code&gt; to &lt;code&gt;pgdata_path&lt;/code&gt; and simultaneously checks if it is not &lt;code&gt;None&lt;/code&gt;. This allows you to combine the assignment and the &lt;code&gt;if&lt;/code&gt; statement in a single line, removing one level of indentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. For Loops
&lt;/h3&gt;

&lt;p&gt;The walrus operator can also be used in for loops. Consider the following example where we want to create a list of squares of numbers in the input list if the squares are greater than 100:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Negative Fibonnaci not supported"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;fib_seq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fib_seq&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fib_seq&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fib_seq&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;    
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fib_seq&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;fib_sequence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"The Fibonacci sequence in the position &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fib_sequence&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The Fibonacci sequence in the position 10 is: 55
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the walrus operator &lt;code&gt;(fib_seq := (fib_seq[1], sum(fib_seq)))&lt;/code&gt; sets the values of the tuple (moves the second item in first position and places the sum of the existing values in the second position) and assigns that tuple to the variable &lt;code&gt;fib_seq&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. List Comprehension
&lt;/h3&gt;

&lt;p&gt;The walrus operator can also be used in list comprehensions to simplify the code. Consider the following example where we want to create a new list of squares of numbers from the input list of prime numbers if the squares are greater than 100:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;prime_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;applicable_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;psqrd&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prime_list&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;psqrd&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prime&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The original list is:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prime_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The output list is:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;applicable_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The original list is: [2, 3, 5, 7, 11]
The output list is: [121]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the walrus operator &lt;code&gt;(psqrd := prime ** 2)&lt;/code&gt; calculates the square of each number in the input list and assigns it to the variable &lt;code&gt;psqrd&lt;/code&gt;. If the square is greater than or equal to 100, it is added to the &lt;code&gt;applicable_list&lt;/code&gt; &lt;a href="https://www.codeconquest.com/blog/python-walrus-operator-uses-and-controversy/"&gt;[1]&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. While Loops
&lt;/h3&gt;

&lt;p&gt;The walrus operator can also be used in while loops. Consider the following example where we want to read input from a user until they enter the flag &lt;code&gt;\q&lt;/code&gt;'. One way of doing it would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Please provide the required data: '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'\q'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'Data passed is: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please provide the required data: 1
Please provide the required data: 2
Please provide the required data: 3
Please provide the required data: \q
Data passed is: ['1', '2', '3']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can modify this example to use the walrus operator to simplify the loop by creating the variable passed to &lt;code&gt;input&lt;/code&gt; as well as check its value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Please provide the required data: '&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;'\q'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;'Data passed is: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Please provide the required data: 1
Please provide the required data: 2
Please provide the required data: 3
Please provide the required data: \q
Data passed is: ['1', '2', '3']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Controversy Surrounding the Walrus Operator
&lt;/h2&gt;

&lt;p&gt;Like any new feature, the walrus operator has sparked some controversy within the Python community. Some developers argue that it violates certain heuristics and can lead to less readable code &lt;a href="https://realpython.com/python-walrus-operator/"&gt;[2]&lt;/a&gt;. However, others find it to be a powerful addition that simplifies certain programming tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The walrus operator might just be a valuable addition to Python's syntax, providing a concise and efficient way to assign and evaluate expressions. While it may be a subject of controversy, it offers developers new possibilities for writing clean and efficient code.&lt;/p&gt;




&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.codeconquest.com/blog/python-walrus-operator-uses-and-controversy/"&gt;Python Walrus Operator Uses and Controversy - Code Conquest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://realpython.com/python-walrus-operator/"&gt;The Walrus Operator: Python 3.8 Assignment Expressions - Real Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@rajputgajanan50/the-walrus-operator-in-python-90532f6ccd8a"&gt;The Walrus Operator (:=) in Python | by Gajanan Rajput | Medium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://peps.python.org/pep-0572/"&gt;PEP 572 – Assignment Expressions&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Exploring Different Types of Joins in Pandas</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Mon, 23 Oct 2023 08:34:48 +0000</pubDate>
      <link>https://dev.to/0xog_pg/exploring-different-types-of-joins-in-pandas-4d6h</link>
      <guid>https://dev.to/0xog_pg/exploring-different-types-of-joins-in-pandas-4d6h</guid>
      <description>&lt;p&gt;When working with data in Python, the Pandas library provides powerful tools for data manipulation and analysis. One essential operation when working with multiple datasets is joining them based on common columns. Pandas offers several types of joins to combine data efficiently. In this blog post, we will explore the different types of joins in Pandas and provide code examples using some dummy data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Joins
&lt;/h2&gt;

&lt;p&gt;A join operation combines two or more datasets based on a common column or index. The resulting dataset includes rows that have matching values in the specified columns or indices. Pandas provides several join methods, each with its own behavior and use cases. Let's take a closer look at each one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inner Join
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HvN3O2rR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/udomghlkgwg1lgt7z5x2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HvN3O2rR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/udomghlkgwg1lgt7z5x2.png" alt="Image description" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An inner join returns only the rows that have matching values in both datasets. In other words, it keeps only the intersection of the two datasets. To demonstrate this, let's consider two dummy datasets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="c1"&gt;# Create dummy datasets
&lt;/span&gt;&lt;span class="n"&gt;df1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;'ID'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;'Value'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'B'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'C'&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
&lt;span class="n"&gt;df2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;'ID'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;'Data'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;

&lt;span class="c1"&gt;# Perform an inner join
&lt;/span&gt;&lt;span class="n"&gt;inner_join&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;df2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'ID'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'inner'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inner_join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;pd.merge()&lt;/code&gt; function is used to perform the join. By specifying &lt;code&gt;how='inner'&lt;/code&gt;, we perform an inner join based on the 'ID' column. The result will contain only the rows with matching IDs in both datasets. In this case, the output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ID Value  Data
0   2     B    10
1   3     C    20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Left Join
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GY0IRJMe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81pw2cs5nd5hzokelv6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GY0IRJMe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/81pw2cs5nd5hzokelv6u.png" alt="Image description" width="800" height="295"&gt;&lt;/a&gt;&lt;br&gt;
A left join returns all the rows from the left dataset and the matched rows from the right dataset. If no match is found in the right dataset, the corresponding values will be filled with NaN (missing values). Let's illustrate this with an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Perform a left join
&lt;/span&gt;&lt;span class="n"&gt;left_join&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;df2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'ID'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'left'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left_join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The left join keeps all the rows from the left dataset (&lt;code&gt;df1&lt;/code&gt;) and adds the matching rows from the right dataset (&lt;code&gt;df2&lt;/code&gt;). If there is no match, the 'Data' column will have NaN values. The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ID Value  Data
0   1     A   NaN
1   2     B  10.0
2   3     C  20.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Right Join
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--okRUmxwU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ph563bmqb8a1z16ry3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--okRUmxwU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ph563bmqb8a1z16ry3h.png" alt="Image description" width="800" height="295"&gt;&lt;/a&gt;&lt;br&gt;
A right join is similar to a left join but keeps all the rows from the right dataset and the matched rows from the left dataset. If no match is found in the left dataset, the corresponding values will be NaN. Let's see it in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Perform a right join
&lt;/span&gt;&lt;span class="n"&gt;right_join&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;df2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'ID'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'right'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;right_join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The right join includes all the rows from the right dataset (&lt;code&gt;df2&lt;/code&gt;) and adds the matching rows from the left dataset (&lt;code&gt;df1&lt;/code&gt;). If there is no match, the 'Value' column will contain NaN values. The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ID Value  Data
0   2     B    10
1   3     C    20
2   4   NaN    30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Outer Join
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cn5RRCDk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxekxh30j0jf3raul8ud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cn5RRCDk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxekxh30j0jf3raul8ud.png" alt="Image description" width="800" height="295"&gt;&lt;/a&gt;&lt;br&gt;
An outer join combines all the rows from both datasets. If a row has no match in the other dataset, the corresponding values will be NaN. This join type is useful when you want to retain all the information from both datasets. Let's try an outer join:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Perform an outer join
&lt;/span&gt;&lt;span class="n"&gt;outer_join&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;df2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'ID'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;'outer'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outer_join&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The outer join returns all rows from both datasets, filling missing values with NaN. The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ID Value  Data
0   1     A   NaN
1   2     B  10.0
2   3     C  20.0
3   4   NaN  30.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Joining datasets is a fundamental operation when working with multiple sources of data. In this blog post, we explored the different types of joins available in the Pandas library. We covered the inner join, left join, right join, and outer join, explaining their behaviors and providing code examples with dummy data.&lt;/p&gt;

&lt;p&gt;By understanding and using these join methods effectively, you can combine data from different sources to gain valuable insights and perform comprehensive data analysis. The ability to merge datasets based on common columns or indices is a powerful tool in your data manipulation toolkit.&lt;/p&gt;

&lt;p&gt;Remember to consider your specific use case and the relationships between your datasets when choosing the appropriate join method. Each join type has its advantages and is suitable for different scenarios. Experimentation and practice will help you become more proficient in using joins effectively.&lt;/p&gt;

&lt;p&gt;Pandas provides a wide range of functionalities for data manipulation, and joins are just one aspect of its capabilities. As you delve deeper into data analysis and manipulation, you'll discover even more powerful features and techniques offered by the library.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://pandas.pydata.org/pandas-docs/version/1.3/getting_started/comparison/comparison_with_spreadsheets.html"&gt;Comparison with spreadsheets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pandas.pydata.org/pandas-docs/version/0.20.1/generated/pandas.DataFrame.join.html"&gt;pandas.DataFrame.join&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>MITRE ATT&amp;CK: Your map to adversary movement</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sun, 15 Oct 2023 23:40:48 +0000</pubDate>
      <link>https://dev.to/0xog_pg/mitre-attck-your-map-to-adversary-movement-je5</link>
      <guid>https://dev.to/0xog_pg/mitre-attck-your-map-to-adversary-movement-je5</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n9J4DpTG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.search.brave.com/14YtXc7OdEY5vcTSO6vKPmhxjYroj6Q9zhgHd1U9GBQ/rs:fit:860:0:0/g:ce/aHR0cHM6Ly93d3cu/c3BsdW5rLmNvbS9j/b250ZW50L2RhbS9z/cGx1bmsyL2ltYWdl/cy9kYXRhLWluc2lk/ZXIvbWl0cmUtYXR0/LWNrLWZyYW1ld29y/ay9taXRyZS1waGFz/ZXMtZGlhZ3JhbS5z/dmc.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n9J4DpTG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://imgs.search.brave.com/14YtXc7OdEY5vcTSO6vKPmhxjYroj6Q9zhgHd1U9GBQ/rs:fit:860:0:0/g:ce/aHR0cHM6Ly93d3cu/c3BsdW5rLmNvbS9j/b250ZW50L2RhbS9z/cGx1bmsyL2ltYWdl/cy9kYXRhLWluc2lk/ZXIvbWl0cmUtYXR0/LWNrLWZyYW1ld29y/ay9taXRyZS1waGFz/ZXMtZGlhZ3JhbS5z/dmc.svg" alt="MITRE ATT&amp;amp;CK Logo" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; Introduction to MITRE ATT&amp;amp;CK
&lt;/li&gt;
&lt;li&gt; The Framework

&lt;ol&gt;
&lt;li&gt; Tactics
&lt;/li&gt;
&lt;li&gt; Techniques
&lt;/li&gt;
&lt;li&gt; Sub-techniques
&lt;/li&gt;
&lt;li&gt; Procedures
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt; How MITRE ATT&amp;amp;CK Works

&lt;ol&gt;
&lt;li&gt; Adversary Emulation
&lt;/li&gt;
&lt;li&gt; Threat Intelligence
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt; The Benefits of MITRE ATT&amp;amp;CK

&lt;ol&gt;
&lt;li&gt; Improved Threat Detection
&lt;/li&gt;
&lt;li&gt; Enhanced Incident Response
&lt;/li&gt;
&lt;li&gt; Better Security Assessments
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt; Implementing MITRE ATT&amp;amp;CK

&lt;ol&gt;
&lt;li&gt; Mapping Techniques and Controls
&lt;/li&gt;
&lt;li&gt; Leveraging MITRE ATT&amp;amp;CK for Red Teaming
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt; Limitations and Challenges
&lt;/li&gt;
&lt;li&gt; Conclusion
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction to MITRE ATT&amp;amp;CK
&lt;/h2&gt;

&lt;p&gt;In today's rapidly evolving threat landscape, organizations face constant challenges in defending against sophisticated cyber attacks. To address this, MITRE Corporation developed the MITRE ATT&amp;amp;CK framework. ATT&amp;amp;CK, which stands for Adversarial Tactics, Techniques, and Common Knowledge, is a globally accessible knowledge base of adversary tactics and techniques. It provides a structured and comprehensive approach to understanding and categorizing cyber threats.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Framework
&lt;/h2&gt;

&lt;p&gt;The MITRE ATT&amp;amp;CK framework is organized hierarchically, consisting of tactics, techniques, and sub-techniques. This structure allows security professionals to gain a deep understanding of how adversaries operate and the tactics they employ.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1. Tactics
&lt;/h3&gt;

&lt;p&gt;The tactics within the ATT&amp;amp;CK framework represent the underlying purpose or objective  (the &lt;strong&gt;&lt;em&gt;why&lt;/em&gt;&lt;/strong&gt;) behind each technique or sub-technique. They define the technical goals that adversaries aim to accomplish and the rationale behind their actions. For instance, an adversary might target credential access as a means to gain entry into a targeted network.&lt;/p&gt;

&lt;p&gt;Each tactic encompasses a set of techniques that have been observed by network defenders in real-world scenarios involving threat actors. It's important to note that the ATT&amp;amp;CK framework is not meant to be interpreted as a linear progression, where adversaries move through tactics in a straightforward manner from left to right to achieve their objectives. Furthermore, adversaries are not obligated to utilize all ATT&amp;amp;CK tactics in order to accomplish their operational goals.&lt;/p&gt;

&lt;p&gt;The MITRE ATT&amp;amp;CK framework defines several tactics, including the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Initial Access&lt;/li&gt;
&lt;li&gt;  Execution&lt;/li&gt;
&lt;li&gt;  Persistence&lt;/li&gt;
&lt;li&gt;  Privilege Escalation&lt;/li&gt;
&lt;li&gt;  Defense Evasion&lt;/li&gt;
&lt;li&gt;  Credential Access&lt;/li&gt;
&lt;li&gt;  Lateral Movement&lt;/li&gt;
&lt;li&gt;  Exfiltration&lt;/li&gt;
&lt;li&gt;  Impact&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.2. Techniques
&lt;/h3&gt;

&lt;p&gt;Techniques within the context of the ATT&amp;amp;CK framework describe the (&lt;strong&gt;&lt;em&gt;how&lt;/em&gt;&lt;/strong&gt;) methods employed by adversaries to accomplish a specific tactical  objective through their actions. For instance, an adversary might employ the technique of dumping credentials to gain access to privileged  accounts. &lt;/p&gt;

&lt;p&gt;Techniques can also indicate what an adversary acquires as a  result of their actions. A technique represents a distinct behavior  aimed at achieving a particular goal and is often just one step in a  series of activities carried out by the adversary to fulfill their  overall mission. &lt;/p&gt;

&lt;p&gt;It should be noted that certain techniques within  ATT&amp;amp;CK can enable an adversary to achieve multiple tactical  objectives, thus applying to multiple tactics within the framework. &lt;/p&gt;

&lt;p&gt;Additionally, many techniques involve the utilization of legitimate  system functions that can be exploited for malicious purposes, commonly  known as "living off the land." (at.exe, schdtsk, etc)&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3. Sub-techniques
&lt;/h3&gt;

&lt;p&gt;Sub-techniques provide further granularity within each technique, allowing for a more detailed understanding of adversary behaviors. They describe specific variations or methods used by adversaries to accomplish a technique within a tactic. Sub-techniques help in capturing the nuances and evolving tactics employed by adversaries.&lt;/p&gt;

&lt;p&gt;For instance, within the brute force &lt;a href="https://attack.mitre.org/techniques/T1110"&gt;T1110&lt;/a&gt; technique, there are specific behaviors that  outline distinct methods for executing the technique. These behaviors  include password guessing &lt;a href="https://attack.mitre.org/techniques/T1110/001"&gt;T1110.001&lt;/a&gt;, password cracking &lt;a href="https://attack.mitre.org/techniques/T1110/002"&gt;T1110.002&lt;/a&gt;, password spraying &lt;a href="https://attack.mitre.org/techniques/T1110/003"&gt;T1110.003&lt;/a&gt;, and credential stuffing &lt;a href="https://attack.mitre.org/techniques/T1110/004"&gt;T1110.004&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sub-techniques are often associated with  specific operating systems or platforms, although this is not always the case. It's important to note that not all techniques have corresponding sub-techniques.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.4. Procedures
&lt;/h3&gt;

&lt;p&gt;Procedures are indicators that represent the specific actions (the &lt;strong&gt;&lt;em&gt;what&lt;/em&gt;&lt;/strong&gt;) performed by an adversary and  serve as examples of how they have utilized a technique or  sub-technique. For instance, when it comes to OS credential dumping,  there exist various procedures like the extraction of LSASS memory  &lt;a href="https://attack.mitre.org/techniques/T1003/001"&gt;T1003.001&lt;/a&gt; using different tools, utilities, and commands.  &lt;/p&gt;

&lt;p&gt;Understanding these procedures can be valuable for replicating an  incident through adversary emulation and for detecting malicious  activity.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How MITRE ATT&amp;amp;CK Works
&lt;/h2&gt;

&lt;p&gt;MITRE ATT&amp;amp;CK works by providing organizations with a knowledge base that can be used to improve their cybersecurity defenses. It offers two primary components:&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Adversary Emulation
&lt;/h3&gt;

&lt;p&gt;Adversary emulation involves simulating real-world attack scenarios in a controlled environment to evaluate an organization's security controls and incident response capabilities. By replicating adversary behaviors and techniques, organizations can identify vulnerabilities and improve their defenses.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2. Threat Intelligence
&lt;/h3&gt;

&lt;p&gt;MITRE ATT&amp;amp;CK provides valuable threat intelligence by documenting the tactics, techniques, and procedures (TTPs) used by real-world adversaries. This information helps security teams understand the latest trends in cyber attacks, identify potential indicators of compromise (IOCs), and develop effective countermeasures.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Benefits of MITRE ATT&amp;amp;CK
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1. Improved Threat Detection
&lt;/h3&gt;

&lt;p&gt;By aligning security controls and detection mechanisms with the MITRE ATT&amp;amp;CK framework, organizations can enhance their ability to detect and respond to advanced threats. The framework provides a standardized language and taxonomy for understanding adversary behaviors, enabling more effective threat hunting and incident response.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2. Enhanced Incident Response
&lt;/h3&gt;

&lt;p&gt;MITRE ATT&amp;amp;CK helps organizations develop robust incident response plans by providing insights into the tactics and techniques employed by adversaries. This knowledge allows for more efficient and targeted incident response efforts, minimizing the impact of cyber attacks and reducing recovery time.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3. Better Security Assessments
&lt;/h3&gt;

&lt;p&gt;By leveraging MITRE ATT&amp;amp;CK, organizations can perform comprehensive security assessments to identify vulnerabilities and gaps in their defenses. The framework offers a standardized methodology for evaluating security controls, enabling organizations to prioritize remediation efforts and allocate resources effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Implementing MITRE ATT&amp;amp;CK
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1. Mapping Techniques and Controls
&lt;/h3&gt;

&lt;p&gt;Organizations can map their existing security controls to the techniques and tactics defined in the MITRE ATT&amp;amp;CK framework. This mapping helps identify coverage gaps and areas where additional controls are needed to mitigate specific threats. It provides a proactive approach to improve security postures.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2. Leveraging MITRE ATT&amp;amp;CK for Red Teaming
&lt;/h3&gt;

&lt;p&gt;Red teaming exercises involve emulating real-world attacks to test an organization's defenses. By using the MITRE ATT&amp;amp;CK framework, red teams can align their tactics and techniques with known adversary behaviors, providing a more realistic assessment of an organization's security posture.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Limitations and Challenges
&lt;/h2&gt;

&lt;p&gt;While MITRE ATT&amp;amp;CK is a valuable resource, it is not without limitations. The framework requires continuous updates to keep pace with evolving adversary tactics. It also requires organizations to invest time and resources in understanding and implementing the framework effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Conclusion
&lt;/h2&gt;

&lt;p&gt;MITRE ATT&amp;amp;CK offers a comprehensive and structured approach to understanding and categorizing adversary behaviors. By leveraging the framework, organizations can enhance their threat detection, incident response, and overall security posture. However, it is important to recognize the limitations and challenges associated with implementing and maintaining MITRE ATT&amp;amp;CK effectively.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Note: This document is a summary based on current understanding and does not represent an actual MITRE ATT&amp;amp;CK guide.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Shared Memory in Linux</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sat, 30 Sep 2023 19:50:47 +0000</pubDate>
      <link>https://dev.to/0xog_pg/using-shared-memory-in-linux-1p62</link>
      <guid>https://dev.to/0xog_pg/using-shared-memory-in-linux-1p62</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Shared memory is a powerful feature in Linux that allows processes to communicate and share data efficiently. In this blog post, we will delve into the world of shared memory, focusing on important functions like &lt;code&gt;shm_open&lt;/code&gt;. We will explore how shared memory works, discuss relevant functions, provide a code example, and highlight the benefits of using shared memory for inter-process communication. Additionally, we will address potential security risks associated with shared memory, particularly the concern of data being read off disk. By the end of this post, you will have a comprehensive understanding of shared memory in Linux, enabling you to leverage its advantages while ensuring data security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction to Shared Memory&lt;/li&gt;
&lt;li&gt;Shared Memory Functions

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;shm_open&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shm_unlink&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shmget&lt;/code&gt; and &lt;code&gt;shmat&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;shmdt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Benefits of Using Shared Memory&lt;/li&gt;
&lt;li&gt;Security Risks: Data Read Off Disk

&lt;ul&gt;
&lt;li&gt;Understanding the Vulnerability&lt;/li&gt;
&lt;li&gt;Mitigating Risks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Code Example&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Introduction to Shared Memory
&lt;/h2&gt;

&lt;p&gt;Shared memory allows multiple processes to access the same region of memory, facilitating fast and efficient communication between them. Instead of using slower inter-process communication methods like pipes or sockets, shared memory enables direct access to shared data, resulting in improved performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Shared Memory Functions
&lt;/h2&gt;

&lt;p&gt;Several key functions are used to work with shared memory in Linux. Let's explore them in detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;shm_open&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;shm_open&lt;/code&gt; function creates or opens a shared memory object. It takes a name and flags as arguments and returns a file descriptor that can be used to access the shared memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;shm_unlink&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;shm_unlink&lt;/code&gt; function removes a shared memory object by name. It ensures that the shared memory is properly cleaned up after use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;shm_unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;shmget&lt;/code&gt; and &lt;code&gt;shmat&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;shmget&lt;/code&gt; function allocates a new shared memory segment or retrieves an existing one based on a key. On the other hand, &lt;code&gt;shmat&lt;/code&gt; attaches the shared memory segment to the address space of the calling process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;shmget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key_t&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shmflg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;shmat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shmid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;shmaddr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shmflg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;shmdt&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;shmdt&lt;/code&gt; function detaches a shared memory segment from the address space of the calling process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;shmdt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;shmaddr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Benefits of Using Shared Memory
&lt;/h2&gt;

&lt;p&gt;Using shared memory offers several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: Shared memory allows for faster data exchange between processes since it avoids the overhead of copying data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency&lt;/strong&gt;: Processes can directly access shared data, eliminating the need for serialization and deserialization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronization&lt;/strong&gt;: Shared memory can be combined with synchronization mechanisms like semaphores ormutexes to ensure proper access control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Sharing&lt;/strong&gt;: Shared memory allows processes to share large amounts of data without duplicating it in memory.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Security Risks: Data Read Off Disk
&lt;/h2&gt;

&lt;p&gt;One potential security concern with shared memory is the possibility of sensitive data being read off disk. Shared memory objects are backed by files in the file system, and if the system crashes, the data may be temporarily stored on disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Vulnerability
&lt;/h3&gt;

&lt;p&gt;When data resides on disk, it becomes vulnerable to unauthorized access. Malicious users or processes with sufficient privileges may attempt to read the shared memory files directly, potentially compromising sensitive information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mitigating Risks
&lt;/h3&gt;

&lt;p&gt;To mitigate the security risks associated with shared memory, consider the following best practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Appropriate Permissions&lt;/strong&gt;: Set appropriate file permissions for the shared memory files to restrict access to authorized users and processes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encrypt Sensitive Data&lt;/strong&gt;: If the shared memory contains sensitive information, consider encrypting the data before storing it in the shared memory segment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure the System&lt;/strong&gt;: Implement strong security measures on the system, such as access controls, to prevent unauthorized access to shared memory files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle Segmentation Faults&lt;/strong&gt;: Properly handle segmentation faults to prevent sensitive data from being inadvertently written to disk.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these best practices, you can minimize the potential security risks associated with shared memory usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Code Example
&lt;/h2&gt;

&lt;p&gt;Here's a code example that demonstrates the usage of shared memory in Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Include the necessary headers&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"/my_shared_memory"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;shm_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shm_open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O_CREAT&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;O_RDWR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mo"&gt;0666&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shm_fd&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"shm_open"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Set the size of the shared memory region&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Resize the shared memory object to the desired size&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ftruncate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shm_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ftruncate"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Map the shared memory object into the process address space&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PROT_READ&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PROT_WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAP_SHARED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shm_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;MAP_FAILED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"mmap"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Write data to the shared memory&lt;/span&gt;
    &lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello, shared memory!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Print the contents of the shared memory&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Shared memory contents: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Unmap the shared memory object&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;munmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"munmap"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Close the shared memory file descriptor&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shm_fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"close"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Unlink the shared memory object&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shm_unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;perror&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"shm_unlink"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code example demonstrates creating a shared memory object using &lt;code&gt;shm_open&lt;/code&gt;. We allocate a shared memory segment of size 1024 bytes using &lt;code&gt;ftruncate&lt;/code&gt;. Then, we map the shared memory into the process address space using &lt;code&gt;mmap&lt;/code&gt; and write a string to it. Finally, we unmap the shared memory, close the file descriptor, and unlink the shared memory object.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Shared memory provides a powerful mechanism for efficient inter-process communication in Linux. Through functions like &lt;code&gt;shm_open&lt;/code&gt;, &lt;code&gt;shm_unlink&lt;/code&gt;, &lt;code&gt;shmget&lt;/code&gt;, and &lt;code&gt;shmat&lt;/code&gt;, developers can leverage shared memory to enhance performance and resource sharing among processes. However, it is crucial to be aware of the security risks associated with shared memory, particularly the possibility of data being read off disk. By implementing best practices and taking appropriate security measures, developers can ensure the integrity and confidentiality of shared data.&lt;/p&gt;

&lt;p&gt;In this blog post, we explored the concept of shared memory in Linux, understanding its benefits and the relevant functions such as &lt;code&gt;shm_open&lt;/code&gt;, &lt;code&gt;shm_unlink&lt;/code&gt;, &lt;code&gt;shmget&lt;/code&gt;, and &lt;code&gt;shmat&lt;/code&gt;. We also discussed the potential security risks associated with shared memory, emphasizing the importance of securing shared memory files and implementing strong access controls.&lt;/p&gt;

&lt;p&gt;Shared memory remains a valuable tool for efficient and high-performance inter-process communication. By understanding its functionality and taking necessary precautions, developers can harness the power of shared memory while safeguarding sensitive data.&lt;/p&gt;

&lt;p&gt;Remember to always prioritize security when working with shared memory and stay vigilant in protecting the confidentiality and integrity of shared data. With the right knowledge and practices, shared memory can be a reliable and effective solution for seamless communication and collaboration among processes in Linux.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/2/shmat"&gt;https://linux.die.net/man/2/shmat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://man7.org/linux/man-pages/man2/shmget.2.html"&gt;https://man7.org/linux/man-pages/man2/shmget.2.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/2/shmdt"&gt;https://linux.die.net/man/2/shmdt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/3/shm_open"&gt;https://linux.die.net/man/3/shm_open&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linux.die.net/man/3/shm_unlink"&gt;https://linux.die.net/man/3/shm_unlink&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Efficiency and Speed with GNU Parallel</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sat, 30 Sep 2023 19:50:20 +0000</pubDate>
      <link>https://dev.to/0xog_pg/efficiency-and-speed-with-gnu-parallel-loo</link>
      <guid>https://dev.to/0xog_pg/efficiency-and-speed-with-gnu-parallel-loo</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Understanding GNU Parallel&lt;/li&gt;
&lt;li&gt;Installation and Basic Usage&lt;/li&gt;
&lt;li&gt;Parallelization Modes and Job Control&lt;/li&gt;
&lt;li&gt;Advanced Features and Examples&lt;/li&gt;
&lt;li&gt;Advantages of Using GNU Parallel&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the world of command-line utilities, GNU Parallel stands out as a powerful tool for achieving parallelism and optimizing computational tasks. This article explores the fundamental concepts of GNU Parallel, demonstrates its usage through practical examples, and highlights the advantages it offers in terms of efficiency, scalability, and flexibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understanding GNU Parallel
&lt;/h2&gt;

&lt;p&gt;GNU Parallel is a command-line tool designed to execute tasks in  parallel, unlocking the potential of modern multi-core processors and  distributed computing environments. It allows users to divide a workload into smaller units (jobs) and run them simultaneously, thereby  significantly reducing the overall execution time. By default, GNU  Parallel distributes jobs across available CPU cores, but it can also  leverage remote servers to achieve distributed computing.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Installation and Basic Usage
&lt;/h2&gt;

&lt;p&gt;To get started with GNU Parallel, it must first be  installed on your system. On Linux, you can typically install it using  the package manager of your distribution. Once installed, GNU Parallel  can be used from the command line.&lt;br&gt;
The basic syntax for running commands in parallel with GNU Parallel is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parallel [options] command ::: arguments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;command&lt;/code&gt; represents the task or command to be executed, and &lt;code&gt;arguments&lt;/code&gt; are the inputs passed to the command. Multiple arguments can be specified, separated by spaces or provided through a file.&lt;br&gt;
For example, to display a list of files in parallel using the &lt;code&gt;cat&lt;/code&gt; command , the following command can be used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parallel cat::: file1.txt file2.txt file3.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GNU Parallel automatically distributes the files across available CPU cores, executing the &lt;code&gt;echo&lt;/code&gt; command concurrently.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Parallelization Modes and Job Control
&lt;/h2&gt;

&lt;p&gt;GNU Parallel offers different modes of parallelization to suit various scenarios. It supports both local parallelization and remote execution across multiple machines.&lt;br&gt;
Additionally, GNU Parallel provides fine-grained control over job execution. For instance, the &lt;code&gt;--dry-run&lt;/code&gt; option allows users to preview the commands without actually executing them. Furthermore, the &lt;code&gt;--halt&lt;/code&gt; option enables the termination of parallel execution if any job fails, ensuring robustness in complex workflows.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Advanced Features and Examples
&lt;/h2&gt;

&lt;p&gt;GNU Parallel offers a plethora of advanced features that make it a versatile tool for data processing and beyond.&lt;/p&gt;
&lt;h3&gt;
  
  
  a. Input Sources:
&lt;/h3&gt;

&lt;p&gt;GNU Parallel can read input data from various sources, including command substitution, standard input (&lt;code&gt;stdin&lt;/code&gt;), files, or even environment variables. This flexibility allows seamless  integration with other command-line tools and pipelines. 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;cat files.txt | parallel process_file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  b. Command Substitution:
&lt;/h3&gt;

&lt;p&gt;Commands can be generated dynamically using command substitution within  GNU Parallel. This enables the execution of complex workflows and the  passing of dynamically generated arguments to commands. 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;parallel "process_{}" ::: $(ls *.txt)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  c. Progress Monitoring:
&lt;/h3&gt;

&lt;p&gt;Using the &lt;code&gt;--progress&lt;/code&gt; option, GNU  Parallel provides real-time progress monitoring, displaying job  execution status, completion percentage, and ETA (Estimated Time of  Arrival). This feature is particularly useful when dealing with  time-consuming tasks. 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;parallel --progress process_file ::: *.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  d. Load Balancing:
&lt;/h3&gt;

&lt;p&gt;GNU Parallel supports load balancing mechanisms, ensuring equal  distribution of jobs across processors or machines. It can automatically adjust the workload distribution based on factors such as job  completion time or system load, optimizing resource utilization.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Advantages of Using GNU Parallel
&lt;/h2&gt;

&lt;p&gt;The utilization of GNU Parallel brings several advantages to data processing and computational tasks:&lt;/p&gt;

&lt;h3&gt;
  
  
  a. Improved Efficiency:
&lt;/h3&gt;

&lt;p&gt;By harnessing the power of parallel computing, GNU Parallel  significantly reduces the execution time of time-consuming tasks,  leading to enhanced efficiency and productivity.&lt;/p&gt;

&lt;h3&gt;
  
  
  b. Scalability and Flexibility:
&lt;/h3&gt;

&lt;p&gt;GNU Parallel effortlessly scales from single-core systems to multi-core  machines or even distributed computing environments, enabling seamless  parallelization across different setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  c. Simplified Parallelization:
&lt;/h3&gt;

&lt;p&gt;GNU Parallel abstracts the complexities of parallel computing, allowing  users to focus on task definition rather than intricate parallelization  mechanisms. This simplification accelerates development and facilitates  code maintenance.&lt;/p&gt;

&lt;h3&gt;
  
  
  d. Resource Optimization:
&lt;/h3&gt;

&lt;p&gt;With load balancing and job control features, GNU Parallel optimizes  resource utilization by distributing jobs evenly and monitoring their  execution. This ensures efficient utilization of CPU cores and minimizes idle times.&lt;/p&gt;

&lt;h3&gt;
  
  
  e. Seamless Integration:
&lt;/h3&gt;

&lt;p&gt;GNU Parallel seamlessly integrates with existing workflows, as it can be combined with other command-line tools and utilities. This  interoperability enables users to leverage the full potential of their  existing tools while achieving parallel execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Conclusion
&lt;/h2&gt;

&lt;p&gt;GNU Parallel empowers users to unlock the potential of parallel  computing, enabling faster and more efficient execution of computational tasks. By distributing jobs across available CPU cores or remote servers, GNU Parallel revolutionizes data processing and computational  workflows, offering scalability, simplicity, and resource optimization.  With its easy-to-use syntax and advanced features, GNU Parallel is a  valuable addition to any command-line toolkit, providing substantial  speed improvements and unlocking the full potential of modern computing  systems.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Git Patches: Your friend to less Copy-Paste</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sun, 24 Sep 2023 21:40:56 +0000</pubDate>
      <link>https://dev.to/0xog_pg/git-patches-your-friend-to-less-copy-paste-3294</link>
      <guid>https://dev.to/0xog_pg/git-patches-your-friend-to-less-copy-paste-3294</guid>
      <description>&lt;p&gt;Git, the most widely used version control system, offers a powerful feature called &lt;strong&gt;patches&lt;/strong&gt;. &lt;br&gt;
Patches allow developers to share and apply changes between different repositories or branches. &lt;/p&gt;

&lt;p&gt;As part of a project I am working on, I found myself relying on this functionality and have explored a couple features. In this post, we will explore the world of Git patches, discussing their benefits and demonstrating how to utilize them effectively. We will cover relevant commands, provide code examples, and delve into the advantages of using rejection (rej) files and hunks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What are Git Patches?&lt;/li&gt;
&lt;li&gt;Creating Patches

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git format-patch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Example: Creating a Patch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Applying Patches

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git apply&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Example: Applying a Patch&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Using Rej Files

&lt;ul&gt;
&lt;li&gt;Understanding Rej Files&lt;/li&gt;
&lt;li&gt;Resolving Conflicts with Rej Files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Working with Hunks

&lt;ul&gt;
&lt;li&gt;Understanding Hunks&lt;/li&gt;
&lt;li&gt;Manipulating Hunks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Wrap up&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What are Git Patches?
&lt;/h2&gt;

&lt;p&gt;Git patches are a way to capture and transfer changes made to a codebase. A patch file contains a textual representation of the differences between two states of a repository. It includes information about added, modified, or deleted lines in the code.&lt;/p&gt;

&lt;p&gt;Patches are valuable for sharing changes with others or applying them to different branches or repositories. They enable efficient code collaboration, particularly when dealing with remote teams or contributors.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Creating Patches
&lt;/h2&gt;

&lt;p&gt;Git provides the &lt;code&gt;git format-patch&lt;/code&gt; command to generate patches from commits or branches. Let's see how it works. I've made a repo as demo for this post which has the following commits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F1oqc46f43s054gzbehe0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F1oqc46f43s054gzbehe0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git format-patch&lt;/code&gt; Command
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;git format-patch&lt;/code&gt; command creates patch files for each commit in a specified range or branch. It generates files in the ".patch" format, which can be easily shared and applied.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Creating a Patch
&lt;/h3&gt;

&lt;p&gt;To create a patch for a specific commit, use the following command:&lt;/p&gt;

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

git format-patch &amp;lt;commit&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;For instance, to generate a patch for the last three commits, execute:&lt;/p&gt;

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

git format-patch HEAD~2


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

&lt;/div&gt;

&lt;p&gt;This command will produce two patch files, each representing a commit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fyg955dcpk3wl4vq5u6bh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fyg955dcpk3wl4vq5u6bh.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Applying Patches
&lt;/h2&gt;

&lt;p&gt;Once patches are created, they can be applied to a repository using the &lt;code&gt;git apply&lt;/code&gt; command. Applying patches allows for seamless integration of changes into a codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;git apply&lt;/code&gt; Command
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;git apply&lt;/code&gt; command is used to apply patches to a repository. It takes patch files and modifies the code accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Applying a Patch
&lt;/h3&gt;

&lt;p&gt;To apply a patch file, use the following command:&lt;/p&gt;

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

git apply &amp;lt;patch-file&amp;gt;


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

&lt;/div&gt;

&lt;p&gt;For example, to apply a patch named "this-is-my-patch.patch," run:&lt;/p&gt;

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

git apply this-is-my-patch.patch


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

&lt;/div&gt;

&lt;p&gt;The changes described in the patch file will be applied to the working directory.&lt;/p&gt;

&lt;p&gt;A patch file contains something similar to a &lt;code&gt;diff&lt;/code&gt; of the file and where the changes have occurred. The following is a sample of one of the patch files used for this demo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmxb715vojr8ox6pml6u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmxb715vojr8ox6pml6u2.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Using Rej Files
&lt;/h2&gt;

&lt;p&gt;If there's a mismatch between the file that you want to apply the patch to and the patch files, you will see a message similar to this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2hchsuuivvckccd84n73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2hchsuuivvckccd84n73.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To over come this, we can utilize &lt;code&gt;rej&lt;/code&gt; files.&lt;/p&gt;

&lt;p&gt;Rej files (rejection files) are generated during the patch application process when conflicts occur. They provide valuable information about rejected changes and aid in resolving conflicts effectively.&lt;/p&gt;

&lt;p&gt;These are produced when the &lt;code&gt;git apply&lt;/code&gt; command is used in a similar fashion:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git apply &lt;span class="nt"&gt;--reject&lt;/span&gt; &lt;span class="nt"&gt;--whitespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;fix this-is-my-patch.patch


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgn5zhgaivalrzk8rn8px.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgn5zhgaivalrzk8rn8px.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fgexbhmt3rvtk3szntfgo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fgexbhmt3rvtk3szntfgo.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Rej Files
&lt;/h3&gt;

&lt;p&gt;When Git encounters conflicts while applying a patch, it creates a rej file for each conflicting hunk. A rej file highlights the conflicting lines and provides context for resolving the conflicts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resolving Conflicts with Rej Files
&lt;/h3&gt;

&lt;p&gt;To resolve conflicts using rej files, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the rej file in a text editor.&lt;/li&gt;
&lt;li&gt;Identify the conflicting lines and understand the context.&lt;/li&gt;
&lt;li&gt;Manually modify the code to resolve the conflicts.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;git apply --reject&lt;/code&gt; command to reapply the patch, taking into account the manual modifications made.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using rej files streamlines the conflict resolution process, ensuring accurate application of changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Working with Hunks
&lt;/h2&gt;

&lt;p&gt;Hunks are portions of a patch file that describe a specific set of changes. Understanding and manipulating hunks allow for fine-grained control over patch application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Hunks
&lt;/h3&gt;

&lt;p&gt;Hunks represent the isolated changes within a patch file. They contain information about the lines affected, whether they were added, modified, or deleted, and context lines surrounding the changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manipulating Hunks
&lt;/h3&gt;

&lt;p&gt;To manipulate hunks during patch application, consider the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To apply only specific hunks from a patch file, use the &lt;code&gt;--include&lt;/code&gt; or &lt;code&gt;--exclude&lt;/code&gt; options with the &lt;code&gt;git apply&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;To interactively choose individual hunks to apply, utilize the &lt;code&gt;git add --patch&lt;/code&gt; command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Manipulating hunks provides flexibility in applying changes, allowing for precise control over the patches.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Wrap up
&lt;/h2&gt;

&lt;p&gt;Git patches are an indispensable tool for code collaboration and efficient transfer of changes between repositories. By understanding how to create and apply patches, utilize rej files, and work with hunks, developers can enhance their collaboration and streamline the integration of code.&lt;/p&gt;

&lt;p&gt;Leveraging Git patches allows developers to easily share their changes, collaborate effectively with remote teams, and ensure seamless integration of code across branches and repositories. Understanding the commands and techniques associated with Git patches empowers developers to optimize their workflow and enhance productivity.&lt;/p&gt;

&lt;p&gt;GL HF&lt;/p&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Colab + Postgres + ngrok: A whopping trio!</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sun, 10 Sep 2023 20:49:53 +0000</pubDate>
      <link>https://dev.to/0xog_pg/colab-postgres-ngrok-a-whopping-trio-19l</link>
      <guid>https://dev.to/0xog_pg/colab-postgres-ngrok-a-whopping-trio-19l</guid>
      <description>&lt;p&gt;In the &lt;a href="https://dev.to/0xog_pg/leveraging-google-colab-to-run-postgres-a-comprehensive-guide-3kpn"&gt;previous post&lt;/a&gt;, we saw how to run Postgres on Google Colab and interface with it through &lt;code&gt;psql&lt;/code&gt; as well as from Python itself. This only allowed accessing the database from within the Colab notebook - there was no way to connect from other applications or devices on the internet. &lt;/p&gt;

&lt;p&gt;In this post, we will explore how to publicly expose the Postgres instance using &lt;code&gt;ngrok&lt;/code&gt;, allowing secure connections from anywhere. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wait. What is Ngrok?
&lt;/h2&gt;

&lt;p&gt;Ngrock is a tunneling tool that allows you to expose a web service running on your local machine to the public internet over HTTPS. Here are some key things to know about ngrok:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It creates a secure tunnel between a public URL and a port on your local machine. This lets you share your locally-running services (like web apps) with others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When you run ngrok, it provides you with a public URL that maps to your local server. For example, it might create a URL like &lt;a href="https://abcdef.ngrok.io" rel="noopener noreferrer"&gt;https://abcdef.ngrok.io&lt;/a&gt; that tunnels to localhost:8080.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The URLs it generates are random subdomains under the ngrok domain, and change each time you restart ngrok. This helps protect your local server from being directly exposed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It supports TCP and HTTP(S) tunnels. So you can expose web servers, databases, APIs and more using any protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The tunnel is secure - it uses HTTPS and has built-in authentication. Ngrok handles encrypting and decrypting traffic between endpoints automatically.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we can use &lt;code&gt;ngrok&lt;/code&gt; to accessing our database from outside the local network, and exposing APIs for testing mobile or web clients or whoever we want.&lt;/p&gt;

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

&lt;p&gt;To start, we'll install ngrok on Colab:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FWSdG5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FWSdG5.png" alt="ngrok install and run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can grab your &lt;code&gt;authtoken&lt;/code&gt; from the &lt;code&gt;ngrok&lt;/code&gt; portal. To verify, you can open your &lt;code&gt;Agents&lt;/code&gt; tab which is under &lt;code&gt;Tunnels&lt;/code&gt; and you can the session that was started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FIfUTg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FIfUTg.png" alt="ngrok session"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting from another machine
&lt;/h2&gt;

&lt;p&gt;Now on another (our local) computer, we can use the ngrok URL instead of localhost to reach our database.&lt;/p&gt;

&lt;p&gt;We pass the ngrok URL along with username, password and database. The SSL connection is required due to ngrok's encryption.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FXy3of.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.stack.imgur.com%2FXy3of.png" alt="local notebook"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should now be connected to the Colab Postgres instance from your local machine! We can run queries and interact with the database remotely. Now your Python application has full access to the database running on Colab. The ngrok tunnel handles secure communication behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other use cases
&lt;/h2&gt;

&lt;p&gt;Exposing the database publicly opens up many possibilities beyond local experimentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build test applications and connect from your laptop&lt;/li&gt;
&lt;li&gt;Demo prototypes to clients without sharing Colab link &lt;/li&gt;
&lt;li&gt;Integrate Colab work with larger apps via the database&lt;/li&gt;
&lt;li&gt;Perform multi-user testing of database-backed services&lt;/li&gt;
&lt;li&gt;Connect a web app to Postgres on Colab for development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ngrok handles authentication securely, so you don't have to publicly expose credentials or ports. It's a very convenient tool for bringing services outside Colab.&lt;/p&gt;

&lt;p&gt;Additionally, it might be possible to save your database on you google drive and then import your drive to continue between sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post we saw how to use ngrok to forward port 5432 and make the Postgres instance on Google Colab publicly accessible via a web URL. This lets us connect and query the database from other machines, scripts, and applications securely.&lt;/p&gt;

&lt;p&gt;Combined with Postgres and Ngrok, Colab provides a powerful free environment for developing, testing and prototyping full-stack database applications right from the browser. Ngrok opens new possibilities beyond the single notebook model, breaking Colab out of isolation when needed.&lt;/p&gt;

&lt;p&gt;GL, HF.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>python</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Leveraging Google Colab to run Postgres: A Comprehensive Guide</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sun, 10 Sep 2023 16:54:03 +0000</pubDate>
      <link>https://dev.to/0xog_pg/leveraging-google-colab-to-run-postgres-a-comprehensive-guide-3kpn</link>
      <guid>https://dev.to/0xog_pg/leveraging-google-colab-to-run-postgres-a-comprehensive-guide-3kpn</guid>
      <description>&lt;p&gt;Google Colab is a powerful cloud-based platform that provides a convenient environment for running Python code, performing data analysis, and executing machine learning tasks. While Colab offers built-in support for popular data manipulation libraries, such as Pandas and NumPy, connecting to a PostgreSQL database requires additional setup. In this guide, we'll explore how you can use Google Colab with Postgres, enabling you to leverage the power of SQL database operations within your Colab notebooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we dive into the process, ensure you have the following prerequisites in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Google account: You'll need a Google account to access Google Colab.&lt;/li&gt;
&lt;li&gt;A PostgreSQL database: Ensure you have a working PostgreSQL database instance with the necessary credentials.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting up Google Colab
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open your web browser and navigate to &lt;a href="https://colab.research.google.com/" rel="noopener noreferrer"&gt;Google Colab&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sign in with your Google account if you haven't already.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "New Notebook" to create a new Colab notebook.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installing Required Libraries
&lt;/h2&gt;

&lt;p&gt;Before doing anything, we need to check that the Postgres version we want is installed on Colab and then we can proceed, for the purposes of this walkthrough, we'll use Postgres 15&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;dirmngr ca-certificates software-properties-common gnupg gnupg2 apt-transport-https curl &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;curl &lt;span class="nt"&gt;-fSsL&lt;/span&gt; https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /usr/share/keyrings/postgresql.gpg &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ jammy-pgdg main'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/pgdg.list
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;postgresql-client-15 postgresql-15 &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service postgresql start


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

&lt;/div&gt;

&lt;p&gt;The following steps should end with the a screen similar to this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fnuv4fuyjmvzkmj5ruw76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fnuv4fuyjmvzkmj5ruw76.png" alt="Successful installation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once Postgres is in place, we should configure our users with proper permissions so that we can easily access our database. Let's create the following users:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="c"&gt;# Setup a password `postgres` for username `postgres`&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"CREATE ROLE root WITH SUPERUSER;"&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"ALTER ROLE root WITH LOGIN;"&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql &lt;span class="nt"&gt;-U&lt;/span&gt; postgres &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"CREATE ROLE postgres WITH PASSWORD 'postgres';"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Let's break down each line of the snippet:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;!sudo -u postgres psql -U postgres -c "CREATE ROLE root WITH SUPERUSER;"&lt;/code&gt;: This line executes a PostgreSQL command to create a new role (user) named "root" with superuser privileges. Superuser privileges provide extensive permissions and control over the database system. By creating this role, the snippet aims to establish a powerful user for administrative purposes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!sudo -u postgres psql -U postgres -c "ALTER ROLE root WITH LOGIN;"&lt;/code&gt;: This line executes a PostgreSQL command to allow the "root" role to log in. The WITH LOGIN clause grants the role the ability to authenticate and access the database system.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;!sudo -u postgres psql -U postgres -c "CREATE ROLE postgres WITH PASSWORD 'postgres';"&lt;/code&gt;: This line creates a new role named "postgres" with the password "postgres". The role is created with default privileges, which are typically limited compared to a superuser role. This setup allows for a more "secure" configuration by setting a password for the "postgres" role.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my experience, setting &lt;code&gt;root&lt;/code&gt; with &lt;code&gt;LOGIN&lt;/code&gt; from the get-go usually fails for some reason. It also happens with the &lt;code&gt;postgres&lt;/code&gt; user. If you encounter that, just run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"ALTER USER postgres PASSWORD 'postgres'"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now that's out of the way, let's see how we can use Postgres.&lt;/p&gt;

&lt;p&gt;One of the issues that might seem annoying with Colab, is that if you run a cell for some jobs, it'll block the entire notebook from executing any cells. Luckily, we aren't trapped in all cases. There's an IPython extention called &lt;code&gt;colabxterm&lt;/code&gt; that can be used to provide a terminal-like interface from a cell within the notebook. We can use this to out advantage. To install it, we just do the following&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="o"&gt;!&lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;colab-xterm
load_ext colabxterm


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

&lt;/div&gt;

&lt;p&gt;After this is done, you can run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

%xterm


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

&lt;/div&gt;

&lt;p&gt;To spawn a console&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2kxx29dhl0fdq95pfmmp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2kxx29dhl0fdq95pfmmp.png" alt="Console spawned"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can use this to connect to psql and run our queries!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb6blvs4bt4lxgs8eqob8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fb6blvs4bt4lxgs8eqob8.png" alt="psql run"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To connect to a PostgreSQL database from Colab, we need to install the &lt;code&gt;psycopg2&lt;/code&gt; library, which allows Python to interact with PostgreSQL databases. Additionally, we'll install the &lt;code&gt;sqlalchemy&lt;/code&gt; library, which provides a higher-level interface for working with databases.&lt;/p&gt;

&lt;p&gt;To install the required libraries, add the following code snippet in a Colab cell:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt; &lt;span class="n"&gt;sqlalchemy&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Importing Necessary Modules
&lt;/h2&gt;

&lt;p&gt;In the first cell of your Colab notebook, import the required modules:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Connecting to the PostgreSQL Database
&lt;/h2&gt;

&lt;p&gt;To establish a connection to your PostgreSQL database, you need to provide the necessary connection details, such as the host, port, database name, username, and password.&lt;/p&gt;

&lt;p&gt;Use the following code snippet as an example to establish a connection using &lt;code&gt;psycopg2&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;psycopg2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_host&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_port&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_username&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;your_password&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connection established successfully!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error connecting to the database:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Replace the placeholders (&lt;code&gt;your_host&lt;/code&gt;, &lt;code&gt;your_port&lt;/code&gt;, &lt;code&gt;your_database&lt;/code&gt;, &lt;code&gt;your_username&lt;/code&gt;, &lt;code&gt;your_password&lt;/code&gt;) with your actual database connection details.&lt;/p&gt;

&lt;p&gt;Alternatively, you can use the &lt;code&gt;sqlalchemy&lt;/code&gt; library to create an engine and connect to the database:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;postgresql://your_username:your_password@your_host:your_port/your_database&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connection established successfully!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error connecting to the database:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Replace the placeholders (&lt;code&gt;your_host&lt;/code&gt;, &lt;code&gt;your_port&lt;/code&gt;, &lt;code&gt;your_database&lt;/code&gt;, &lt;code&gt;your_username&lt;/code&gt;, &lt;code&gt;your_password&lt;/code&gt;) with your actual database connection details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executing SQL Queries
&lt;/h2&gt;

&lt;p&gt;Once the connection is established, you can execute SQL queries and fetch the results using the &lt;code&gt;cursor&lt;/code&gt; object (if using &lt;code&gt;psycopg2&lt;/code&gt;) or the &lt;code&gt;execute&lt;/code&gt; method of the engine (if using &lt;code&gt;sqlalchemy&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Here's an example that executes a simple &lt;code&gt;SELECT&lt;/code&gt; query and fetches the results using &lt;code&gt;psycopg2&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM your_table;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error executing the query:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Replace &lt;code&gt;your_table&lt;/code&gt; with the name of the table you want to query from your database.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;sqlalchemy&lt;/code&gt;, you can execute queries using the &lt;code&gt;execute&lt;/code&gt; method of the &lt;code&gt;engine&lt;/code&gt; object:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM your_table&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Error executing the query:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Replace &lt;code&gt;your_table&lt;/code&gt; with the name of the table you want to query from your database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing the Connection
&lt;/h2&gt;

&lt;p&gt;After you finish executing the queries, remember to close the connection to the database to release any resources.&lt;/p&gt;

&lt;p&gt;Use the following code to close the connection when using &lt;code&gt;psycopg2&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connection closed successfully!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;For &lt;code&gt;sqlalchemy&lt;/code&gt;, close the connection as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Connection closed successfully!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here's what this would look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fwdrtjwmp6sqanmcqs3te.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fwdrtjwmp6sqanmcqs3te.png" alt="SQLAlchemyDemo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this guide, we explored how to use Google Colab with a PostgreSQL database. By following the steps outlined here, you can establish a connection to your database, execute SQL queries, and retrieve the results within your Colab notebooks. This integration allows you to leverage the power of both Colab's data analysis capabilities and the SQL operations provided by Postgres, enabling you toperform advanced data manipulations and gain valuable insights.&lt;/p&gt;

&lt;p&gt;One of the key advantages of using Google Colab with Postgres is the ability to seamlessly combine the data analysis capabilities of Colab with the power of SQL queries. With Colab, you have access to a wide range of Python libraries for data manipulation and visualization. By connecting to a Postgres database, you can leverage the SQL language to efficiently retrieve and manipulate data directly from your database.&lt;/p&gt;

&lt;p&gt;For example, you can use SQL queries to perform aggregations, filtering, and join operations on large datasets stored in your Postgres database. These operations can be executed efficiently on the database server, reducing the data transfer overhead and improving performance. Once you have the desired data subset, you can use Colab's data analysis libraries, such as Pandas and Matplotlib, to further explore and visualize the data.&lt;/p&gt;

&lt;p&gt;Integrating Google Colab with Postgres opens up a world of possibilities for data analysis and exploration. By combining the strengths of Colab's Python libraries and Postgres' SQL capabilities, you can efficiently work with large datasets, perform advanced data manipulations, and gain valuable insights. So, give it a try and unlock the full potential of your data analysis workflows with Google Colab and Postgres!&lt;/p&gt;

&lt;p&gt;GL, HF!&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>python</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>PyScript: Python in the Browser</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sat, 12 Aug 2023 18:18:59 +0000</pubDate>
      <link>https://dev.to/0xog_pg/pyscript-python-in-the-browser-3dbd</link>
      <guid>https://dev.to/0xog_pg/pyscript-python-in-the-browser-3dbd</guid>
      <description>&lt;p&gt;PyScript is tool that allows Python code to run directly in the browser via web assembly (Wasm). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.devrant.com%2Fdevrant%2Frant%2Fr_718849_VMP6g.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.devrant.com%2Fdevrant%2Frant%2Fr_718849_VMP6g.jpg" alt="WebAssemMeme"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This opens up opportunities to use Python for frontend web development and interact with JavaScript environments from Python. In this blog post, we'll explore what PyScript is, how to use it, and provide some code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is PyScript?
&lt;/h2&gt;

&lt;p&gt;PyScript is a framework that allows users to create rich Python applications in the browser using HTML’s interface and the power of Pyodide, WASM, and modern web technologies. The PyScript framework provides users at every experience level with access to an expressive, easy-to-learn programming language with countless applications. [It enables users to run Python code directly in their browser, giving anyone the ability to program without infrastructure barriers. You can add an interactive Python REPL directly to your website, share an interactive dashboard with a colleague as an HTML file, or create a client-side Python-powered web application.&lt;/p&gt;

&lt;p&gt;Some of the key features of PyScript include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allows users to write and run Python code in HTML.&lt;/li&gt;
&lt;li&gt;It allows users to build web applications using Python&lt;/li&gt;
&lt;li&gt;It allows sharing machine learning models in an HTML file so that others can run those models in their browsers&lt;/li&gt;
&lt;li&gt;It helps to avoid setup&lt;/li&gt;
&lt;li&gt;It allows using UI components such as buttons, containers, text boxes, etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So in summary, PyScript allows writing frontend code with the Python programming language and interacting seamlessly with JavaScript environments, all running natively in the browser via WebAssembly.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I use PyScript?
&lt;/h2&gt;

&lt;p&gt;To use PyScript, you do not require any development environment other than a web browser (Chrome is recommended. Long Live 🔥🦊) and a text editor, even though using your IDE of choice might be convenient&lt;/p&gt;

&lt;p&gt;That's it. There is no installation required. The PyScript assets served on pyscript.net which makes the process of getting up and running pretty easy. &lt;/p&gt;

&lt;h2&gt;
  
  
  Our first PyScript file
&lt;/h2&gt;

&lt;p&gt;Using your favorite editor, create a new file called with the &lt;code&gt;html&lt;/code&gt; extension (This ideally should be in the same directory as your support Python Script(s), JavaScript, and CSS files with the following content, and open the file in your web browser.&lt;/p&gt;

&lt;p&gt;For the sake of brevity, let's assume the file you created is called &lt;code&gt;index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://pyscript.net/latest/pyscript.css"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;defer&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://pyscript.net/latest/pyscript.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"color"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"color-picker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 48px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;py-script&amp;gt;&lt;/span&gt;
from js import document
from pyodide.ffi import create_proxy
color_picker = document.getElementById("color-picker")
text = document.getElementById("text")
def on_color_change(event):
    text.style.color = event.target.value
color_picker.addEventListener("change", create_proxy(on_color_change))
    &lt;span class="nt"&gt;&amp;lt;/py-script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We start by linking PyScript and you you can do that in two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Download a copy of the latest version of PyScript, and add the required files to &lt;code&gt;head&lt;/code&gt; in your HTML document:&lt;/li&gt;
&lt;li&gt; Add the CDN version of PyScript's JS and CSS files to &lt;code&gt;head&lt;/code&gt; in your HTML document:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This script is an HTML file that uses PyScript to create a color picker and change the color of the text based on the selected color. The logic is present inside the &lt;code&gt;&amp;lt;py-script&amp;gt;&lt;/code&gt; tag&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
      ...
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"color"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"color-picker"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"font-size: 48px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;py-script&amp;gt;&lt;/span&gt;
from js import document
from pyodide.ffi import create_proxy

color_picker = document.getElementById("color-picker")
text = document.getElementById("text")

def on_color_change(event):
    text.style.color = event.target.value

color_picker.addEventListener("change", create_proxy(on_color_change))
    &lt;span class="nt"&gt;&amp;lt;/py-script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you open this file in a web browser, you will see an input element of type &lt;code&gt;color&lt;/code&gt; that allows you to select a color, and a &lt;code&gt;div&lt;/code&gt; element containing the text “Hello World!” in a large font size. &lt;/p&gt;

&lt;p&gt;The script uses PyScript to select the color picker and the &lt;code&gt;div&lt;/code&gt; element using their IDs, and defines a function &lt;code&gt;on_color_change&lt;/code&gt; that is called whenever the value of the color picker changes. &lt;/p&gt;

&lt;p&gt;In this function, the &lt;code&gt;style.color&lt;/code&gt; property of the &lt;code&gt;div&lt;/code&gt; element is set to the value of the color picker. &lt;/p&gt;

&lt;p&gt;The script also attaches an event listener to the color picker to call the &lt;code&gt;on_color_change&lt;/code&gt; function whenever its value changes. As a result, when you select a color using the color picker, the color of the text will change accordingly.&lt;/p&gt;

&lt;p&gt;If you take a closer look at the &lt;code&gt;addEventListener&lt;/code&gt;, you'll notice a function called &lt;code&gt;create_proxy&lt;/code&gt; that wraps the &lt;code&gt;on_color_change&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;This purpose of this function comes from the fact that Pyodide needs to briefly proxy the Python function &lt;code&gt;on_color_change&lt;/code&gt; so the JS function &lt;code&gt;addEventListener&lt;/code&gt; knows how to interact with it. But once &lt;code&gt;addEventListener&lt;/code&gt; terminates, that proxy is no longer needed, it gets destroyed... and then when an event comes around to trigger your function, the proxy it should be using is gone. This will cause the script to return the following error&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uncaught Error: This borrowed proxy was automatically destroyed at the end of a function call. Try using create_proxy or create_once_callable.
The object was of type "function" and had repr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two functions that are mentioned in the error create a &lt;a href="https://github.com/pyodide/pyodide/blob/b193fe1f5dfc1e7831114bc0eac06ca661bcf1a0/src/core/pyproxy.ts#L546" rel="noopener noreferrer"&gt;PyProxy&lt;/a&gt;  (a JS object) of your Python object that you, the user, are supposed to manage the lifetime of, by calling &lt;a href="https://github.com/pyodide/pyodide/blob/b193fe1f5dfc1e7831114bc0eac06ca661bcf1a0/src/core/pyproxy.ts#L617" rel="noopener noreferrer"&gt;&lt;code&gt;PyProxy.destroy()&lt;/code&gt;&lt;/a&gt; on it when you're done with it. Or, if you use &lt;a href="https://github.com/pyodide/pyodide/blob/b193fe1f5dfc1e7831114bc0eac06ca661bcf1a0/src/core/pyproxy.c#L1311" rel="noopener noreferrer"&gt;&lt;code&gt;create_once_callable()&lt;/code&gt;&lt;/a&gt;, the proxy will &lt;code&gt;destroy()&lt;/code&gt; itself after the first time it's called.&lt;/p&gt;

&lt;p&gt;For an object such as an event listener, destroying the proxy for the lifetime of your page may not be a desirable thing, so you can just leave it hanging around. It's worth noting that if you remove that event listener or the element attached to it, you should plan to track and destroy the PyProxy, to avoid taking up memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interacting with JavaScript
&lt;/h2&gt;

&lt;p&gt;A major benefit of PyScript is being able to directly interact with JavaScript from Python code. This enables full integration with frontend frameworks and libraries.&lt;/p&gt;

&lt;p&gt;PyScript provides a &lt;code&gt;js&lt;/code&gt; module that exposes JavaScript functions and objects to Python. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stylesheet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://pyscript.net/latest/pyscript.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://pyscript.net/latest/pyscript.js&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;🦊&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sayMyName&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Saying your name in Javascript: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sayMyName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Dev.to&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Fs7r8iemg2lgzvtqms3om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fs7r8iemg2lgzvtqms3om.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we define a Python function that calls out to JavaScript's &lt;code&gt;console.log()&lt;/code&gt;. When compiled and run, it will print the passed name. It can also be seen in the console of the web browser.&lt;/p&gt;

&lt;p&gt;We can also access global JavaScript objects. For example, to display a alert popup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;

&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from Python!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So PyScript provides full interoperability between Python and JavaScript for building hybrid applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Async/Await Support
&lt;/h2&gt;

&lt;p&gt;Another key feature of PyScript is built-in support for asyncio and async/await syntax. This enables writing asynchronous Python code that integrates cleanly with async-based JavaScript code and event loops.&lt;/p&gt;

&lt;p&gt;For example, we can write an async function that performs a simulated async task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;link&lt;/span&gt; &lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stylesheet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://pyscript.net/latest/pyscript.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://pyscript.net/latest/pyscript.js&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;js&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pyodide.ffi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_proxy&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_task&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Task finished!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;do_task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Done!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;create_proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we define an async function &lt;code&gt;do_task()&lt;/code&gt; that sleeps for 1 second, and call it from the main function &lt;code&gt;main()&lt;/code&gt;. We schedule &lt;code&gt;main()&lt;/code&gt; to run asynchronously after 0 seconds using JavaScript's &lt;code&gt;setTimeout()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When compiled and run, this will output the lines with a 1 second delay in between, demonstrating asyncio integration with the browser's event loop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fxh8qxyqdz60pvdgcdvi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fxh8qxyqdz60pvdgcdvi1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;PyScript provides an intriguing new way to use Python for frontend web development by compiling it to WebAssembly. It maintains the core Python syntax and semantics while enabling seamless interoperability with JavaScript.&lt;/p&gt;

&lt;p&gt;Some key advantages it offers include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Familiar Python syntax for writing frontend code&lt;/li&gt;
&lt;li&gt;Full asyncio/await support for asynchronous programming&lt;/li&gt;
&lt;li&gt;Interactive usage directly in browsers via debugging tools&lt;/li&gt;
&lt;li&gt;Performance comparable to JavaScript with WebAssembly compilation&lt;/li&gt;
&lt;li&gt;Reuse of Python skills, libraries and frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PyScript is a powerful tool for building frontend apps with Python. I'm excited to see where the project goes and do intend to play around with it a little more&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Google Colab: Boost your Notebook Experience</title>
      <dc:creator>PGzlan</dc:creator>
      <pubDate>Sat, 12 Aug 2023 14:19:15 +0000</pubDate>
      <link>https://dev.to/0xog_pg/google-colab-boost-your-notebook-experience-44f4</link>
      <guid>https://dev.to/0xog_pg/google-colab-boost-your-notebook-experience-44f4</guid>
      <description>&lt;p&gt;Google Colab, or Colaboratory, is a free online coding environment that offers a platform for anyone who wants to develop machine learning applications. It's fast, easy to use, and best of all, it gives you access to Google's hardware, including GPUs and TPUs, absolutely free of charge! .&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Google Colab?
&lt;/h2&gt;

&lt;p&gt;Google Colab is based on Jupyter Notebook, a popular open-source web application that allows you to create and share documents that contain live code, equations, visualizations, and narrative text. Colab extends the Jupyter Notebook system, enabling you to write and execute Python code (in lucky instances R) in your browser, with zero configuration required, free access to GPUs, easy sharing, and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F51u2k1b8xv6eyn6937gq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F51u2k1b8xv6eyn6937gq.png" alt="R runtime"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started with Google Colab
&lt;/h2&gt;

&lt;p&gt;Starting with Google Colab is as simple as logging into your Google account and then accessing the Colab at &lt;code&gt;colab.research.google.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you're there, you can create a new notebook by clicking on &lt;code&gt;File -&amp;gt; New notebook&lt;/code&gt;. A new tab will open with your fresh notebook.&lt;/p&gt;

&lt;p&gt;The interface is divided into two main areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;main toolbar&lt;/code&gt; which has options to share, save, connect to GitHub, etc.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;cell space&lt;/code&gt; where you can write your code or text.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each notebook is made up of cells. There are two types of cells:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Code cells&lt;/code&gt;: Where you write and execute your code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Text cells&lt;/code&gt;: Where you write text or HTML code for explanations, much like in this blog post.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can add a new cell by clicking on &lt;code&gt;+ Code&lt;/code&gt; or &lt;code&gt;+ Text&lt;/code&gt; on the top left corner of your notebook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fds9sfv42grbpbkb1xyfl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fds9sfv42grbpbkb1xyfl.png" alt="Code_text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use Google Colab
&lt;/h2&gt;

&lt;p&gt;Let's dive into a simple example that demonstrates how to write, run code, and use the output.&lt;/p&gt;

&lt;p&gt;First, add a new code cell and write the following Python code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Google Colab!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click the play button on the left or press &lt;code&gt;Shift+Enter&lt;/code&gt; to run the cell. The output will be displayed right below the cell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Google&lt;/span&gt; &lt;span class="n"&gt;Colab&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple Python code execution. Now, let's see how we can use Google Colab to run a more complex task, such as training a machine learning model. We'll use the popular &lt;code&gt;Iris dataset&lt;/code&gt; from the &lt;code&gt;scikit-learn&lt;/code&gt; library to train a logistic regression model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Importing necessary libraries
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.datasets&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_iris&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.model_selection&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;train_test_split&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.linear_model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LogisticRegression&lt;/span&gt;

&lt;span class="c1"&gt;# Load Iris dataset
&lt;/span&gt;&lt;span class="n"&gt;iris&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_iris&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iris&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;

&lt;span class="c1"&gt;# Split the data for training and testing
&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Define the model
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Train the model
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Evaluate the model
&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_test&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Model accuracy: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code first loads the Iris dataset, then splits it into a training set and a test set. A Logistic Regression model is then defined and trained, and finally, the model's accuracy is evaluated and printed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Colab's GPU
&lt;/h2&gt;

&lt;p&gt;One of the significant advantages of Google Colab is the free GPU that Google provides for your computations, which can be incredibly beneficial for tasks like training deep learning models. To use the GPU, you need to change your notebook settings by going to &lt;code&gt;Runtime -&amp;gt; Change runtime type&lt;/code&gt; and selecting &lt;code&gt;GPU&lt;/code&gt; from the Hardware accelerator dropdown menu.&lt;/p&gt;

&lt;p&gt;Once you've done that, you can verify that you're using GPU by running the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;

&lt;span class="c1"&gt;# Check if GPU is available
&lt;/span&gt;&lt;span class="n"&gt;device_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gpu_device_name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;device_name&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/device:GPU:0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SystemError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GPU device not found&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Found GPU at: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;device_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the GPU is correctly configured, the output will be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Found&lt;/span&gt; &lt;span class="n"&gt;GPU&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;GPU&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the current version of colab, you can see the GPU name in the top right corner which has like a small resource monitor&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Without GPU&lt;/th&gt;
&lt;th&gt;With GPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media.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%2F5ijjmdxu3vpy4so5658b.png" alt="Without GPU"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media.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%2Fujipwnq3d48etavyp9c9.png" alt="With GPU"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Colab Forms
&lt;/h2&gt;

&lt;p&gt;Colab Forms provide an easy way to parameterize code in Google Colab notebooks. From a code cell, you can select &lt;code&gt;Insert → Add form field&lt;/code&gt; to add a form field. When you change the value in a form, the corresponding value in the code will change. Forms support many types of fields, including string fields, raw fields, date fields, number fields, boolean fields, and markdown. You can also hide the code associated with a form by selecting &lt;code&gt;View → Show/hide code&lt;/code&gt; or using the toolbar above the selected code cell&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F50mub6rysv3wcocjfadz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F50mub6rysv3wcocjfadz.png" alt="Form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;String fields&lt;/strong&gt;: You can use string fields to allow users to enter text. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"string"}
&lt;/span&gt;&lt;span class="n"&gt;dropdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1st option&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;#@param ["1st option", "2nd option", "3rd option"]
&lt;/span&gt;&lt;span class="n"&gt;text_and_dropdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;value&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;#@param ["1st option", "2nd option", "3rd option"] {allow-input: true} 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Number fields&lt;/strong&gt;: You can use number fields to allow users to enter numbers. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;number_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"number"}
&lt;/span&gt;&lt;span class="n"&gt;integer_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"integer"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sliders&lt;/strong&gt;: You can use sliders to allow users to select a value from a range. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;number_slider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"slider", min:-1, max:1, step:0.1}
&lt;/span&gt;&lt;span class="n"&gt;integer_slider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"slider", min:0, max:100, step:1}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Date fields&lt;/strong&gt;: You can use date fields to allow users to select a date. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;date_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2018-03-22&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"date"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Boolean fields&lt;/strong&gt;: You can use boolean fields to allow users to select a true or false value. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;boolean_checkbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"boolean"}
&lt;/span&gt;&lt;span class="n"&gt;boolean_dropdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt; &lt;span class="c1"&gt;#@param ["False", "True"] {type:"raw"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raw fields&lt;/strong&gt;: You can use raw fields to allow users to enter any value without type checking. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nb"&gt;raw_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="c1"&gt;#@param {type:"raw"}
&lt;/span&gt;&lt;span class="n"&gt;raw_dropdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;raw_input&lt;/span&gt; &lt;span class="c1"&gt;#@param [1, "raw_input", "False", "'string'"] {type:"raw"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Fpdmzwxqme2eta86obqj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fpdmzwxqme2eta86obqj2.png" alt="Forms_result"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Colab Magics
&lt;/h2&gt;

&lt;p&gt;Colab provides a set of commands that provide a mini command language for Google Colab notebooks. They are called "Magics", which are a feature of IPython, which is the kernel used by Google Colab. These commands are orthogonal to the syntax of Python and are extensible by the user with new commands. Magics come in two kinds: Line magics, which are commands prepended by one &lt;code&gt;%&lt;/code&gt; character and whose arguments only extend to the end of the current line, and Cell magics, which use two percent characters as a marker (&lt;code&gt;%%&lt;/code&gt;), and they receive as argument both the current line where they are declared and the whole body of the cell. &lt;/p&gt;

&lt;p&gt;You can list all available magic commands by using the &lt;code&gt;%lsmagic&lt;/code&gt; command. This command will display a list of all the available line and cell magics. You can also access the help module for magic commands by using the &lt;code&gt;%magic&lt;/code&gt; command. You can also bring up the help module for a specific command by appending a &lt;code&gt;?&lt;/code&gt; to the end of the command, for example &lt;code&gt;%timeit?&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fkbk1znf2y1pznc5rrayu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fkbk1znf2y1pznc5rrayu.png" alt="lsmagic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frjkvq7qmsmjtr07iedsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Frjkvq7qmsmjtr07iedsa.png" alt="magic_help"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can create your own custom magic commands in Google Colab. Magic commands are a feature of IPython, which is the kernel used by Google Colab. IPython has a system of commands called ‘magics’ that provide a mini command language that is orthogonal to the syntax of Python and is extensible by the user with new commands. Magics come in two kinds: Line magics, which are commands prepended by one &lt;code&gt;%&lt;/code&gt; character and whose arguments only extend to the end of the current line, and Cell magics, which use two percent characters as a marker (&lt;code&gt;%%&lt;/code&gt;), and they receive as argument both the current line where they are declared and the whole body of the cell&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;IPython.core.magic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;register_line_magic&lt;/span&gt;

&lt;span class="nd"&gt;@register_line_magic&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Register the magic command
&lt;/span&gt;&lt;span class="nf"&gt;get_ipython&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;register_magic_function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;magic_kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;line&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.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%2Fpc1qh20st8371l6u6v1p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fpc1qh20st8371l6u6v1p.png" alt="Custom line magic demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also use line magic within your code to do some actions such as changing directory&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fj1pxja6o9ouugppltpsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fj1pxja6o9ouugppltpsg.png" alt="changing directory"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Run system commands
&lt;/h2&gt;

&lt;p&gt;You can run system commands in Google Colab by using the &lt;code&gt;!&lt;/code&gt; character before the command. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F5xzbsousf2sj2s73zp8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F5xzbsousf2sj2s73zp8q.png" alt="OS type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the underlying host of this notebook is Linux, you can run all the Linux commands you desire.&lt;/p&gt;

&lt;p&gt;For example, to run the &lt;code&gt;ls&lt;/code&gt; command, you would enter &lt;code&gt;!ls&lt;/code&gt; in a code cell and run it. This will execute the &lt;code&gt;ls&lt;/code&gt; command and display the output in the cell. You can also use this method to run more complex commands and even chain multiple commands together using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;. For example, to update the package list and then install a package, you could enter &lt;code&gt;!apt-get update &amp;amp;&amp;amp; apt-get install -y package-name&lt;/code&gt; in a code cell and run it.&lt;/p&gt;

&lt;p&gt;This can be useful for cases when you want to perhaps do some processing on some video (perhaps extract a part of it based on timestamps) with a certain tool such as ffmpeg, you can run your ffmpeg command before executing your code&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Google Colab is a powerful tool for anyone who wants to dive into machine learning without worrying about setting up an environment or the computational resources (you can also use it to test out things quickly if especially if you're testing something Linux related). It has an easy to get into user interface for coding and collaboration, and the free access to Google's hardware makes it a go-to choice for many data scientists and researchers.&lt;/p&gt;

&lt;p&gt;So, start integrating Google Colab into your workflow to take it to the next level&lt;/p&gt;

&lt;p&gt;Note: While Google Colab is a fantastic resource, remember that it is not meant for long, continuous usage. The session will disconnect after a period of inactivity. You can check around for how you can reduce the likelyhood of that happening&lt;/p&gt;

</description>
      <category>python</category>
      <category>jupyter</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
