<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Alex Mboutchouang]]></title><description><![CDATA[Alex Mboutchouang]]></description><link>https://blog.alexwalker.app</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 04:00:53 GMT</lastBuildDate><atom:link href="https://blog.alexwalker.app/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Understanding OData Filtering: A Comprehensive Guide]]></title><description><![CDATA[Filtering data efficiently is a fundamental of modern web development, especially when dealing with large datasets. In SharePoint, OData filtering is essential for querying and manipulating data from lists and libraries. But what exactly is OData fil...]]></description><link>https://blog.alexwalker.app/understanding-odata-filtering-a-comprehensive-guide</link><guid isPermaLink="true">https://blog.alexwalker.app/understanding-odata-filtering-a-comprehensive-guide</guid><category><![CDATA[SharePoint]]></category><category><![CDATA[OData]]></category><category><![CDATA[odata web service]]></category><category><![CDATA[OData Query Syntax]]></category><dc:creator><![CDATA[Alex Mboutchouang]]></dc:creator><pubDate>Wed, 27 Nov 2024 07:00:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/IuMKwupOsc0/upload/d236cb67673f571038a3c3f9e26ce63d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Filtering data efficiently is a fundamental of modern web development, especially when dealing with large datasets. In SharePoint, OData filtering is essential for querying and manipulating data from lists and libraries. But what exactly is OData filtering, where does it come from, and when should you use it? Let’s dive in.</p>
<h2 id="heading-the-lists-used-in-our-examples">The Lists Used in Our Examples</h2>
<p>To illustrate how OData filtering works, we'll use an <code>Project Management</code> application scenario. The app has three SharePoint lists: Users, Projects, and Tasks. Each list is structured with attributes that reflect real-world relationships in project management workflows. Here's a detailed overview of these lists:</p>
<h3 id="heading-users-list">Users List</h3>
<p>This list contains information about the users involved in the project.</p>
<p>Attributes:</p>
<ul>
<li><p>Id (Number): A unique identifier for each user.</p>
</li>
<li><p>FullName (String): The full name of the user.</p>
</li>
<li><p>Email (String): The user's email address.</p>
</li>
<li><p>IsActive (Boolean): Whether the User is active or not.</p>
</li>
<li><p>Role (Choice): The role of the user (e.g., <code>Manager</code>, <code>Developer</code>, <code>Tester</code>).</p>
</li>
</ul>
<h3 id="heading-projects-list">Projects List</h3>
<p>This list stores details about ongoing and completed projects.</p>
<p>Attributes:</p>
<ul>
<li><p>Id (Number): A unique identifier for each project.</p>
</li>
<li><p>Title (String): The name of the project.</p>
</li>
<li><p>Budget (Number): The allocated budget for the project.</p>
</li>
<li><p>StartDate (DateTime): The project's starting date.</p>
</li>
<li><p>EndDate (DateTime): The project's planned or actual ending date.</p>
</li>
<li><p>Manager (Lookup): A lookup field referencing the Users list to indicate the project manager.</p>
</li>
<li><p>Status (Choice): The project's current status (Active, Completed, On Hold).</p>
</li>
</ul>
<h3 id="heading-tasks-list">Tasks List</h3>
<p>This list tracks tasks associated with projects.</p>
<p>Attributes:</p>
<ul>
<li><p>Id (Number): A unique identifier for each task.</p>
</li>
<li><p>Title (String): A brief title for the task.</p>
</li>
<li><p>Description (String): A detailed description of the task.</p>
</li>
<li><p>DueDate (DateTime): The deadline for task completion.</p>
</li>
<li><p>Priority (Choice): The task's priority level (Low, Medium, High).</p>
</li>
<li><p>Status (Choice): The current task status (Not Started, In Progress, Completed).</p>
</li>
<li><p>AssignedTo (Lookup): A lookup field referencing the Users list for task assignment.</p>
</li>
<li><p>Project (Lookup): A lookup field referencing the Projects list to indicate the associated project.</p>
</li>
<li><p>Tags (Multi-Choice or Managed Metadata): Keywords or categories that can be used to classify tasks(<code>Documentation</code>, <code>Development</code>, <code>Testing</code>).</p>
</li>
</ul>
<h3 id="heading-relationships-between-the-lists">Relationships Between the Lists</h3>
<p>These lists are interlinked to reflect the relationships in a project management workflow:</p>
<ul>
<li><p>Each Project is managed by a user from the Users list.</p>
</li>
<li><p>Tasks in the Tasks list are assigned to users and associated with specific projects.</p>
</li>
</ul>
<p>Using this structure, you can create powerful queries to filter and retrieve data relevant to your application's needs. Let's now explore how OData filtering operates.</p>
<h2 id="heading-what-is-odata">What is OData?</h2>
<p>OData, short for Open Data Protocol, is a standardized protocol designed to query and manipulate data over RESTful APIs. Developed by Microsoft, it allows applications to interact with various data sources such as databases, file systems, and web services using a common query language.</p>
<p>OData is built on widely-used web standards such as:</p>
<ul>
<li><p>HTTP for transport.</p>
</li>
<li><p>JSON or XML for payload formatting</p>
</li>
<li><p>REST principles for resource interaction.</p>
</li>
</ul>
<p>Think of OData as SQL for web APIs, but much more versatile and designed for distributed systems.</p>
<h2 id="heading-how-does-odata-filtering-work-in-sharepoint">How Does OData Filtering Work in SharePoint?</h2>
<p>In SharePoint, the REST API leverages OData to retrieve data from lists, libraries, and other resources. Filtering using OData allows developers to specify criteria to narrow down results, reducing the amount of data transferred and improving performance.</p>
<p>An OData filter is essentially a query string appended to the endpoint URL. For example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Tasks'</span>)/items?<span class="hljs-variable">$filter</span>=Status eq <span class="hljs-string">'Completed'</span>
</code></pre>
<h2 id="heading-available-data-types-in-odata-filtering">Available Data Types in OData Filtering</h2>
<p>When working with OData, understanding the data types is essential as they determine what operations can be performed. SharePoint supports several data types, each with unique characteristics:</p>
<h3 id="heading-string">String</h3>
<p>Examples: Titles, names, or descriptions ("Task Title", "John Doe").</p>
<p>Common Operations:</p>
<ul>
<li><p>eq, ne: Equality and inequality.</p>
</li>
<li><p>startswith, endswith: Check prefixes or suffixes.</p>
</li>
<li><p>substringof: Partial matching.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Projects'</span>)/items?<span class="hljs-variable">$filter</span>=startswith(Title, <span class="hljs-string">'Test'</span>)
</code></pre>
<h3 id="heading-number">Number</h3>
<p>Examples: Integers and decimals used for IDs, counts, or numeric fields.</p>
<p>Common Operations:</p>
<ul>
<li><p>eq, ne: Equality and inequality.</p>
</li>
<li><p>gt, ge, lt, le: Comparisons.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Projects'</span>)/items?<span class="hljs-variable">$filter</span>=Budget gt 5000
</code></pre>
<h3 id="heading-boolean">Boolean</h3>
<p>Examples: Yes/No fields like IsActive.</p>
<p>Common Operations:</p>
<ul>
<li>eq: Equality (true or false).</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Users'</span>)/items?<span class="hljs-variable">$filter</span>=IsActive eq <span class="hljs-literal">true</span>
</code></pre>
<h3 id="heading-datetime">DateTime</h3>
<p>Examples: Created dates, modified dates, or custom date fields.</p>
<p>Common Operations:</p>
<ul>
<li>gt, ge, lt, le: Compare dates.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Projects'</span>)/items?<span class="hljs-variable">$filter</span>=StartDate ge datetime<span class="hljs-string">'2024-01-01'</span>
Or
/_api/web/lists/getbytitle(<span class="hljs-string">'Projects'</span>)/items?<span class="hljs-variable">$filter</span>=StartDate ge <span class="hljs-string">'2024-01-01T10:30:0000Z'</span>
</code></pre>
<h3 id="heading-lookup-fields">Lookup Fields</h3>
<p>Examples: Fields referencing other lists or users (e.g., Author/Id).</p>
<p>Common Operations:</p>
<ul>
<li>Use navigation properties with <code>/</code> to filter related data.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Tasks'</span>)/items?<span class="hljs-variable">$filter</span>=AssignedTo/Id eq 10
</code></pre>
<h3 id="heading-choice-and-managed-metadata">Choice and Managed Metadata</h3>
<p>Examples: Choice fields like Status (Completed, In Progress) or managed metadata tags.</p>
<p>Common Operations:</p>
<ul>
<li>eq, ne: Check specific values.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Tasks'</span>)/items?<span class="hljs-variable">$filter</span>=Status eq <span class="hljs-string">'Completed'</span>
</code></pre>
<h3 id="heading-guid">GUID</h3>
<p>Examples: Unique identifiers for items or lists.</p>
<p>Common Operations:</p>
<ul>
<li>eq, ne: Match specific GUIDs.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Projects'</span>)/items?<span class="hljs-variable">$filter</span>=UniqueId eq guid<span class="hljs-string">'12345678-1234-1234-1234-123456789abc'</span>
Or
/_api/web/lists/getbytitle(<span class="hljs-string">'Projects'</span>)/items?<span class="hljs-variable">$filter</span>=UniqueId eq <span class="hljs-string">'12345678-1234-1234-1234-123456789abc'</span>
</code></pre>
<h2 id="heading-possible-operations-in-odata-filtering">Possible Operations in OData Filtering</h2>
<p>OData filtering offers a wide range of operations that allow developers to perform complex queries. Here’s a detailed breakdown:</p>
<h3 id="heading-comparison-operators">Comparison Operators</h3>
<p>These operators compare values:</p>
<ul>
<li><p>eq: Equal to.</p>
</li>
<li><p>ne: Not equal to.</p>
</li>
<li><p>gt, ge: Greater than, greater than or equal.</p>
</li>
<li><p>lt, le: Less than, less than or equal.</p>
</li>
</ul>
<h3 id="heading-logical-operators">Logical Operators</h3>
<p>They are used to combine multiple conditions:</p>
<ul>
<li><p>and: Both conditions must be true.</p>
</li>
<li><p>or: At least one condition must be true.</p>
</li>
<li><p>not: Negates a condition.</p>
</li>
</ul>
<h3 id="heading-string-functions">String Functions</h3>
<p>Operate on text fields:</p>
<ul>
<li><p>startswith(Field, 'value'): Checks if the field starts with a value.</p>
</li>
<li><p>endswith(Field, 'value'): Checks if the field ends with a value.</p>
</li>
<li><p>substringof('value', Field): Checks if the field contains a value.</p>
</li>
</ul>
<h3 id="heading-arithmetic-operators">Arithmetic Operators</h3>
<p>Perform calculations on numeric fields:</p>
<ul>
<li>add, sub, mul, div, mod: Arithmetic operations.</li>
</ul>
<h3 id="heading-date-functions">Date Functions</h3>
<p>Handle date-specific queries:</p>
<ul>
<li>Compare date fields with operators (gt, lt, etc.).</li>
</ul>
<h3 id="heading-null-checks">Null Checks</h3>
<p>Identify null or undefined values:</p>
<ul>
<li>eq null, ne null: Check for nulls.</li>
</ul>
<h3 id="heading-lookup-and-navigation">Lookup and Navigation</h3>
<p>Query-related or nested fields:</p>
<ul>
<li>Use <code>/</code> to navigate lookup fields.</li>
</ul>
<h3 id="heading-collections">Collections</h3>
<p>Operate on fields that store multiple values (e.g., multi-choice fields):</p>
<ul>
<li>any, all: Apply conditions on collections.</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash">/_api/web/lists/getbytitle(<span class="hljs-string">'Tasks'</span>)/items?<span class="hljs-variable">$filter</span>=Tags/any(tag: tag eq <span class="hljs-string">'Development'</span>)
Or
/_api/web/lists/getbytitle(<span class="hljs-string">'Tasks'</span>)/items?<span class="hljs-variable">$filter</span>=Tags/all(tag: tag eq <span class="hljs-string">'Testing'</span>)
</code></pre>
<h2 id="heading-benefits-of-using-odata-filtering">Benefits of Using OData Filtering</h2>
<ul>
<li><p>Efficiency: Reduces the data the client fetches, saving bandwidth and processing time.</p>
</li>
<li><p>Standardization: Uses a well-documented standard, making it easy to learn and implement across different APIs.</p>
</li>
<li><p>Flexibility: Allows fine-grained control over what data is retrieved, including relationships and nested properties.</p>
</li>
<li><p>Improved performance: Queries are executed server-side, minimizing client-side processing.</p>
</li>
</ul>
<h2 id="heading-drawbacks-of-odata-filtering">Drawbacks of OData Filtering</h2>
<ul>
<li><p>Learning Curve: For developers unfamiliar with OData syntax, learning and adapting can take some time.</p>
</li>
<li><p>Limited Debugging: Troubleshooting complex queries can be tricky since errors may not always provide detailed insights.</p>
</li>
<li><p>Scalability Concerns: Overly complex queries with multiple joins or filters can impact server performance.</p>
</li>
<li><p>Compatibility Issues: While OData is standardized, specific implementations (like SharePoint's REST API) might have limitations or variations.</p>
</li>
</ul>
<h2 id="heading-when-to-use-odata-filtering">When to Use OData Filtering</h2>
<p>Use OData Filtering When:</p>
<ul>
<li><p>You need to retrieve specific subsets of data from large lists or libraries.</p>
</li>
<li><p>You want to improve application performance by reducing data transfer.</p>
</li>
<li><p>You are working with dynamic filtering options, such as user-specific queries.</p>
</li>
</ul>
<p>Avoid OData Filtering If:</p>
<ul>
<li><p>The dataset is small and can be fetched entirely without performance concerns.</p>
</li>
<li><p>The filter conditions are highly complex and can be handled more efficiently on the client side or through alternative APIs (like Microsoft Graph).</p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusion</h1>
<p>OData filtering is a powerful feature in SharePoint that enables developers to query data efficiently and effectively. By understanding the available data types and operations in OData filtering, SharePoint developers can create efficient, precise queries that enhance application performance. Mastering these tools ensures you can build scalable, robust solutions while minimizing unnecessary data transfer and processing.</p>
<p>Whether you’re developing workflows, dashboards, or user-driven interfaces, leveraging OData filtering is essential for making your SharePoint applications smarter and more responsive.</p>
<p>Have questions about OData filtering or need help with your SharePoint project? Drop your thoughts in the comments or reach out. I’d love to hear from you!</p>
]]></content:encoded></item><item><title><![CDATA[Manage script's configurations with hydra]]></title><description><![CDATA[Two years ago when while working on my Master's project which consisted in training an AI model for textual information retrieval, I had to train my models with different parameters to analyse their behaviour. At first, I had to change the values dir...]]></description><link>https://blog.alexwalker.app/manage-scripts-configurations-with-hydra</link><guid isPermaLink="true">https://blog.alexwalker.app/manage-scripts-configurations-with-hydra</guid><category><![CDATA[Python]]></category><category><![CDATA[cli]]></category><dc:creator><![CDATA[Alex Mboutchouang]]></dc:creator><pubDate>Sun, 06 Oct 2024 06:00:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/gpKe3hmIawg/upload/c5c7257d0c2e484c85e5512a445f878d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Two years ago when while working on my Master's project which consisted in training an AI model for textual information retrieval, I had to train my models with different parameters to analyse their behaviour. At first, I had to change the values directly in my code which was very tedious so I decided to manage these different parameters with the standard input using the <a target="_blank" href="https://docs.python.org/3/library/argparse.html">argparse</a> module that comes by default with python. With the increasing number of parameters, it was really getting complicated and that's when I discovered HYDRA and it definitely allowed me to move forward more quickly and complete my experiments. So, I decided to write this brief article to introduce you to HYDRA and how it works. I hope it will be helpful to others, as it was for me.</p>
<h2 id="heading-what-is-hydra">What is HYDRA</h2>
<p>HYDRA is a powerful open-source tool developed by Facebook's researchers to facilitate dynamic configuration creation. Hydra defines configurations from YAML files and this configuration can be modified with standard parameters from the CLI. The key features of HYDRA include:</p>
<ul>
<li><p>Hierarchical configuration is composable from multiple sources.</p>
</li>
<li><p>Configuration can be specified or overridden from the command line.</p>
</li>
<li><p>Dynamic command line tab completion.</p>
</li>
<li><p>Run your application locally or launch it to run remotely.</p>
</li>
<li><p>Run multiple jobs with different arguments with a single command.</p>
</li>
</ul>
<h2 id="heading-how-do-hydra-work">How do HYDRA work?</h2>
<h3 id="heading-installation">Installation</h3>
<p>HYDRA is a Python package and can therefore be installed from the Package Index using the following command.</p>
<pre><code class="lang-bash">pip install hydra-core
</code></pre>
<h3 id="heading-managing-configuration-with-hydra">Managing configuration with HYDRA</h3>
<p>To use HYDRA to manage configurations, the first step is to create our configuration as a YAML file. The following is an example of a configuration file.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">db:</span>
  <span class="hljs-attr">driver:</span> <span class="hljs-string">postgres</span>
  <span class="hljs-attr">database:</span> <span class="hljs-string">database_name</span>
  <span class="hljs-attr">user:</span> <span class="hljs-string">username</span>
  <span class="hljs-attr">pass:</span> <span class="hljs-string">password</span>

<span class="hljs-attr">social:</span>
  <span class="hljs-attr">google:</span>
    <span class="hljs-attr">client_id:</span> <span class="hljs-string">&lt;GOOGLE_CLIENT_ID&gt;</span>
    <span class="hljs-attr">client_secret:</span> <span class="hljs-string">&lt;GOOGLE_CLIENT_SECRET&gt;</span>
</code></pre>
<p>This configuration can be used in a Python module as follows:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> hydra
<span class="hljs-keyword">from</span> omegaconf <span class="hljs-keyword">import</span> DictConfig, OmegaConf
<span class="hljs-keyword">from</span> database <span class="hljs-keyword">import</span> DBDriver
<span class="hljs-keyword">from</span> socialauth <span class="hljs-keyword">import</span> GoogleAuth

<span class="hljs-meta">@hydra.main(version_base=None, config_path=".", config_name="conf")</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>(<span class="hljs-params">configs : DictConfig</span>) -&gt; <span class="hljs-keyword">None</span>:</span>
    <span class="hljs-comment"># db = DBDriver(configs.db)</span>
    <span class="hljs-comment"># google_provider = GoogleAuth(configs.social.google)</span>
    print(OmegaConf.to_yaml(cfg))

<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
    main()
</code></pre>
<p>If you run this script with <code>python</code> <a target="_blank" href="http://main.py"><code>main.py</code></a> without providing any command line parameters, you will get the following parameters:</p>
<pre><code class="lang-bash">python main.py
{<span class="hljs-string">'driver'</span>: <span class="hljs-string">'postgres'</span>, <span class="hljs-string">'database'</span>: <span class="hljs-string">'database_name'</span>, <span class="hljs-string">'user'</span>: <span class="hljs-string">'username'</span>, <span class="hljs-string">'pass'</span>: <span class="hljs-string">'password'</span>}
{<span class="hljs-string">'client_id'</span>: <span class="hljs-string">'&lt;GOOGLE_CLIENT_ID&gt;'</span>, <span class="hljs-string">'client_secret'</span>: <span class="hljs-string">'&lt;GOOGLE_CLIENT_SECRET&gt;'</span>}
db:
  driver: postgres
  database: database_name
  user: username
  pass: password

social:
  google:
    client_id: &lt;GOOGLE_CLIENT_ID&gt;
    client_secret: &lt;GOOGLE_CLIENT_SECRET&gt;
</code></pre>
<p>However, due to the power and flexibility of HYDRA, the values of these parameters can be modified directly during the execution of the program. The following example shows the result of the execution of the program by modifying the parameters:</p>
<pre><code class="lang-bash">python main.py db.driver=mysql db.database=example social.google.client_id=a4a4a4a4 social.google_secret=f5f5f5f5f5f5
{<span class="hljs-string">'driver'</span>: <span class="hljs-string">'mysql'</span>, <span class="hljs-string">'database'</span>: <span class="hljs-string">'example'</span>, <span class="hljs-string">'user'</span>: <span class="hljs-string">'username'</span>, <span class="hljs-string">'pass'</span>: <span class="hljs-string">'password'</span>}
{<span class="hljs-string">'client_id'</span>: <span class="hljs-string">'a4a4a4a4'</span>, <span class="hljs-string">'client_secret'</span>: <span class="hljs-string">'f5f5f5f5f5f5'</span>}
db:
  driver: mysql
  database: example
  user: username
  pass: password

social:
  google:
    client_id: a4a4a4a4
    client_secret: f5f5f5f5f5f5f
</code></pre>
<p>It is important to note that, the values written in the configuration file are just the default values. It is also possible to define parameters without default values. In this case, the user would have to pass the values at runtime as we do for functions in programming. For such a configuration, the default value is <code>???</code> as we can see in the following:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">db:</span>
  <span class="hljs-attr">driver:</span> <span class="hljs-string">postgres</span>
  <span class="hljs-attr">database:</span> <span class="hljs-string">database_name</span>
  <span class="hljs-attr">user:</span> <span class="hljs-string">username</span>
  <span class="hljs-attr">pass:</span> <span class="hljs-string">password</span>

<span class="hljs-attr">social:</span>
  <span class="hljs-attr">google:</span>
    <span class="hljs-attr">client_id:</span> <span class="hljs-string">???</span>
    <span class="hljs-attr">client_secret:</span> <span class="hljs-string">???</span>
</code></pre>
<p>If we run our program without passing values for the parameters <a target="_blank" href="http://social.google"><code>social.google</code></a><code>.client_id</code> and <a target="_blank" href="http://social.google"><code>social.google</code></a><code>.client_secret</code> we will get the following error:</p>
<pre><code class="lang-bash">python main.py
{<span class="hljs-string">'driver'</span>: <span class="hljs-string">'postgres'</span>, <span class="hljs-string">'database'</span>: <span class="hljs-string">'database_name'</span>, <span class="hljs-string">'user'</span>: <span class="hljs-string">'username'</span>, <span class="hljs-string">'pass'</span>: <span class="hljs-string">'password'</span>}
Error executing job with overrides: []
Traceback (most recent call last):
  File <span class="hljs-string">"/home/username/github/tutorials/hydra/main.py"</span>, line 9, <span class="hljs-keyword">in</span> main
    google_provider = GoogleAuth(**configs.social.google)
omegaconf.errors.MissingMandatoryValue: Missing mandatory value: social.google.client_id
    full_key: social.google.client_id
    object_type=dict
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>HYDRA is a powerful open-source tool developed by Facebook's researchers to facilitate dynamic configuration creation. Hydra defines configurations from YAML files and this configuration can be modified with standard parameters from the CLI.</p>
]]></content:encoded></item><item><title><![CDATA[Use Data classes to write your Python Classes quickly]]></title><description><![CDATA[The Python programming language is world-renowned for its simplicity. As Python developers, We strive to write code that is elegant, concise, and easy to understand. Yet, when defining classes to hold simple data structures, we often find ourselves d...]]></description><link>https://blog.alexwalker.app/use-data-classes-to-write-your-python-classes-quickly</link><guid isPermaLink="true">https://blog.alexwalker.app/use-data-classes-to-write-your-python-classes-quickly</guid><category><![CDATA[Python]]></category><category><![CDATA[oop]]></category><dc:creator><![CDATA[Alex Mboutchouang]]></dc:creator><pubDate>Mon, 30 Sep 2024 06:00:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ieic5Tq8YMk/upload/8671990ba307b054ed26b0e98ca006e2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The Python programming language is world-renowned for its simplicity. As Python developers, We strive to write code that is elegant, concise, and easy to understand. Yet, when defining classes to hold simple data structures, we often find ourselves drowning in boilerplate code, writing the same standard methods each time. Luckily, python also offers a powerful module that lets us automatically add certain attributes and methods(<code>__init__</code>, <code>__repr__</code>) to our classes. This is the dataclasses module. In this article, we explore one of Python's most powerful modules for simplifying our code: dataclasses. Whether you're a seasoned Pythonista or just getting started, understanding how to leverage data classes can significantly enhance your productivity and the clarity of your code. Join me as we delve into the world of data classes, uncovering their secrets, learning how to wield their power, and unleashing the full potential of Python's object-oriented capabilities. By the end of this article, you'll be equipped with the basic knowledge and skills to wield data classes. Let's dive in!</p>
<h2 id="heading-basic-usage">Basic Usage</h2>
<p>Let us start with an example. let's say we are developing a 3d Game and we want a class that represents a point in a 3d dimension. The class will look like the following.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Point3d</span>(<span class="hljs-params">object</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, x: int, y: int, z: int</span>):</span>
        self.x = x
        self.y = y
        self.z = z

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__repr__</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">f"Point(x=<span class="hljs-subst">{self.x}</span>, y=<span class="hljs-subst">{self.y}</span>, z=<span class="hljs-subst">{self.z}</span>)"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__eq__</span>(<span class="hljs-params">self, point</span>):</span>
        <span class="hljs-keyword">return</span> self.x == point.x <span class="hljs-keyword">and</span> self.y == point.y <span class="hljs-keyword">and</span> self.z == point.z

point1 = Point3d(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>)
point2 = Point3d(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>)

print(point1)
print(point2)

print(point1 == point2) <span class="hljs-comment"># False</span>
print(point1 == Point3d(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>)) <span class="hljs-comment"># True</span>
</code></pre>
<p>The dataclasses modules offer a streamlined approach to defining classes whose primary purpose is to store data. With just a few lines of code, you can create a data class that automatically generates common methods like <strong>init()</strong>, <strong>repr()</strong>, <strong>eq()</strong>, and more. Writing our previous class using the dataclasses module will look like the following:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Point3d</span>:</span>
    x: int
    y: int
    z: int

point1 = Point3d(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>)
point2 = Point3d(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>)

print(point1)
print(point2)

print(point1 == point2) <span class="hljs-comment"># False</span>
print(point1 == Point3d(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">8</span>)) <span class="hljs-comment"># True</span>
</code></pre>
<p>In this example, we the decorator <code>@dataclass</code> of dataclasses to instruct Python to automatically generate special methods for our class Point3d. This allows developers to save a massive amount of time and focus on the real logic of the program rather than losing time with boilerplate class definitions.</p>
<h2 id="heading-customizing-data-classes">Customizing Data classes</h2>
<p>While dataclasses provide convenient default behaviour, Python's flexibility allows us to customize their functionality to suit our specific needs. Whether it's setting default values, specifying ordering, or controlling mutability, data classes offer a range of customization options. Let's explore some of these customization features.</p>
<h3 id="heading-setting-default-values">Setting Default Values</h3>
<p>The dataclasses module allows us to specify default values for attributes. This makes it possible to create instances without providing values for all attributes.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Point3d</span>:</span>
    x: int = <span class="hljs-number">0</span>
    y: int = <span class="hljs-number">0</span>
    z: int = <span class="hljs-number">0</span>

point1 = Point3d()
point2 = Point3d(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>)
print(point1 == point2) <span class="hljs-comment"># False</span>
print(point1 == Point3d(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)) <span class="hljs-comment"># True</span>
</code></pre>
<p>In this example, we set all attributes to have a default value of 0. When creating a Point3d instance, if an attribute is not provided, it defaults to 0.</p>
<h3 id="heading-specifying-ordering">Specifying Ordering</h3>
<p>With the <code>@dataclass</code> decorator, we can specify the order in which attributes are compared and sorted using the <strong>order</strong> parameter.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass(order=True)</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Product</span>:</span>
    name: str
    price: float

product1 = Product(<span class="hljs-string">"Laptop"</span>, <span class="hljs-number">999.99</span>)
product2 = Product(<span class="hljs-string">"Smartphone"</span>, <span class="hljs-number">699.99</span>)

print(product1 &lt; product2)  <span class="hljs-comment"># Output: False</span>
</code></pre>
<p>In this example, the <code>order=True</code> parameter specifies that instances of the Product class should be orderable based on their attributes. By default, instances are compared based on the lexicographic order of their attributes.</p>
<h3 id="heading-controlling-mutability">Controlling Mutability</h3>
<p>You can make attributes of a data class immutable by setting the frozen parameter to True in the <code>@dataclass</code> decorator.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass(frozen=True)</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Point3d</span>:</span>
    x: int
    y: int
    z: int

point = Point3d(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
point.x = <span class="hljs-number">4</span>  <span class="hljs-comment"># AttributeError: can't set attribute</span>
</code></pre>
<p>In this example, the Point class is immutable, meaning once an instance is created, its attributes cannot be modified.</p>
<pre><code class="lang-bash">Traceback (most recent call last):
  File <span class="hljs-string">"/home/username/github/blog/point3d.py"</span>, line 10, <span class="hljs-keyword">in</span> &lt;module&gt;
    point.x = 4  <span class="hljs-comment"># AttributeError: can't set attribute</span>
    ^^^^^^^
  File <span class="hljs-string">"&lt;string&gt;"</span>, line 4, <span class="hljs-keyword">in</span> __setattr__
dataclasses.FrozenInstanceError: cannot assign to field <span class="hljs-string">'x'</span>
</code></pre>
<p>By customizing dataclasses, you can change their behaviour to match your requirements, whether it's setting default values, controlling the order, or ensuring immutability. These customization options enhance the flexibility and power of dataclasses in Python.</p>
<h2 id="heading-inheritance-and-data-classes">Inheritance and Data classes</h2>
<p>One of the most important features of the OOP(object-oriented programming) is the inheritance. Inheritance allows classes to inherit attributes and methods from parent classes. When it comes to dataclasses, inheritance works seamlessly, allowing you to create child classes that inherit attributes and behaviours from their parent dataclasses. The following code snippet shows an Example of classes with inheritance using dataclasses.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>:</span>
    name: str
    sound: str

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span>(<span class="hljs-params">Animal</span>):</span>
    breed: str
    num_legs: int = <span class="hljs-number">4</span>

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span>(<span class="hljs-params">Animal</span>):</span>
    breed: str
    num_legs: int

dog = Dog(name=<span class="hljs-string">"Buddy"</span>, sound=<span class="hljs-string">"Woof"</span>, breed=<span class="hljs-string">"Labrador"</span>,  num_legs=<span class="hljs-number">4</span>)
cat = Cat(name=<span class="hljs-string">"Misty"</span>, sound=<span class="hljs-string">"Meow"</span>, breed=<span class="hljs-string">"Siamese"</span>)

print(dog) <span class="hljs-comment"># Dog(name='Buddy', sound='Woof', breed='Labrador', num_legs=4)</span>
print(cat) <span class="hljs-comment"># Cat(name='Misty', sound='Meow', breed='Siamese', num_legs=4)</span>
</code></pre>
<p>In this example, we first create a class that represents an Animal with 2 attributes(<code>name</code>, <code>sound</code>). Then we create 2 more classes(<code>Dog</code>and <code>Cat</code>). Each of these classes defines 2 more attributes(<code>breed</code>, <code>num_legs</code>). This also works well with Class method.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> dataclasses <span class="hljs-keyword">import</span> dataclass

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Vehicle</span>:</span>
    brand: str

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">honk</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"Beep Beep!"</span>

<span class="hljs-meta">@dataclass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span>(<span class="hljs-params">Vehicle</span>):</span>
    model: str

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">honk</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"HONK!"</span>

car = Car(brand=<span class="hljs-string">"Toyota"</span>, model=<span class="hljs-string">"Camry"</span>)

print(car.honk())  <span class="hljs-comment"># Output: HONK!</span>
</code></pre>
<p>In this example, the Car class overrides the honk() method inherited from its parent class Vehicle to provide a different honking sound.</p>
<p>Understanding how inheritance works with dataclasses allows you to build hierarchies of classes that share common attributes and behaviours while still allowing for customization and specialization in subclasses.</p>
<h2 id="heading-performance-considerations">Performance Considerations</h2>
<p>One important thing to be aware of when using the dataclasses module in Python is their performance characteristics, especially in performance-critical applications. Although data classes offer many benefits in terms of readability and simplicity, they may introduce some overhead compared to traditional classes. The following points are some important aspects of how the dataclasse module uses memory.</p>
<h3 id="heading-memory-overhead">Memory Overhead</h3>
<p>Each data class instance consumes memory to store its attributes and any additional overhead introduced by Python's runtime. While this overhead is usually minimal, it can become a concern when dealing with large numbers of instances or when memory usage is a critical factor.</p>
<h3 id="heading-attribute-access-overhead">Attribute Access Overhead</h3>
<p>Dataclasses rely on Python's attribute access mechanisms, which may introduce some overhead compared to accessing attributes directly in a traditional class. While this overhead is typically negligible for most applications, it can become a consideration in performance-sensitive code.</p>
<h3 id="heading-initialization-overhead">Initialization Overhead</h3>
<p>Data classes automatically generate an <strong>init()</strong> method to initialize instances, which involves calling Python's object creation mechanisms. While this initialization overhead is generally small, it may become noticeable in applications that create large numbers of instances frequently.</p>
<h3 id="heading-comparison-overhead">Comparison Overhead</h3>
<p>Data classes automatically generate <strong>eq()</strong> and other comparison methods, which involve comparing the attributes of instances. While this overhead is usually minimal, it may become significant in applications that perform a large number of comparisons.</p>
<h3 id="heading-serialization-overhead">Serialization Overhead</h3>
<p>Data classes provide a convenient way to serialize instances to JSON, dictionaries, or other formats. However, this serialization process incurs overhead compared to directly accessing and manipulating the attributes of instances.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Data classes in Python offer an amazing approach to defining classes for storing data, reducing boilerplate code and improving code readability. By leveraging automatic method generation and customization options, developers can focus on solving problems rather than wrestling with class definitions.</p>
<p>While data classes provide many benefits, it's important to consider potential performance overhead in performance-critical applications. By understanding the trade-offs and making informed decisions, developers can effectively harness the power of data classes to build robust and maintainable Python codebases.</p>
<p>As you explore data classes further, experiment with different use cases, and discover new ways to leverage their power. Thanks for reading and see you soon for a new article.</p>
<h3 id="heading-reference">Reference</h3>
<ul>
<li><a target="_blank" href="https://docs.python.org/3/library/dataclasses.html">https://docs.python.org/3/library/dataclasses.html</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Python structural pattern matching]]></title><description><![CDATA[In the list of new features when version 3.10 of Python was announced, structural pattern matching was one of the most innovative features for me. While most people describe that as the Switch...case Pattern that we know in other popular programming ...]]></description><link>https://blog.alexwalker.app/python-structural-pattern-matching</link><guid isPermaLink="true">https://blog.alexwalker.app/python-structural-pattern-matching</guid><category><![CDATA[Python]]></category><category><![CDATA[pattern-matching]]></category><dc:creator><![CDATA[Alex Mboutchouang]]></dc:creator><pubDate>Mon, 27 May 2024 06:00:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/D9Zow2REm8U/upload/e7ede1fdabf7eea1a203ca3e41dd0005.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the list of new features when version 3.10 of Python was announced, structural pattern matching was one of the most innovative features for me. While most people describe that as the Switch...case Pattern that we know in other popular programming languages like PHP or Javascript, structural pattern matching offers much more, as we will explore in this blog post. It provides a powerful mechanism for matching complex data structures and integrating seamlessly with Python's existing features.</p>
<h2 id="heading-pattern-matching">Pattern Matching</h2>
<p>As described in <a target="_blank" href="https://en.wikipedia.org/wiki/Pattern_matching">this amazing Wikipedia article</a>, pattern matching in computer science is checking a given sequence of tokens for the presence of the constituents of some pattern. The pattern here can be a string or any other data. Pattern matching is a good alternative to conditional statements, resulting in cleaner, more readable code. It simplifies complex conditional logic and makes the code more self-explanatory.</p>
<h2 id="heading-pythons-structural-pattern-matching">Python's Structural Pattern Matching</h2>
<p>In Python, <code>match</code> statement introduces structural pattern matching, providing a more concise and expressive way to handle conditional logic. Unlike traditional constructs like <code>if-elif-else</code> and <code>switch-case</code>(in other programming languages), which rely on sequential evaluation or equality checks, <code>match</code> allows a direct matching of patterns against values, enabling more robust and readable code.</p>
<h3 id="heading-syntax-and-basic-usage">Syntax and Basic Usage</h3>
<p>The <code>match</code> statement in Python &gt;= 3.10 allows for concise conditional branching by matching a given value against patterns defined in <code>case</code> clauses. It sequentially evaluates each pattern and executes the corresponding action for the first matching pattern encountered. Patterns are evaluated from top to bottom, with the <code>_</code> wildcard pattern serving as a catch-all for unmatched values. Guards, specified using the if keyword, enable additional conditions to be applied to patterns.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">classify_value</span>(<span class="hljs-params">value: int</span>):</span>
    match value:
        case <span class="hljs-number">0</span>:
            print(<span class="hljs-string">"Zero"</span>)
        case n <span class="hljs-keyword">if</span> n &gt; <span class="hljs-number">0</span>:
            print(<span class="hljs-string">"Positive"</span>)
        case n <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">0</span>:
            print(<span class="hljs-string">"Negative"</span>)

check_sign(<span class="hljs-number">5</span>)   <span class="hljs-comment"># Output: Positive</span>
check_sign(<span class="hljs-number">-3</span>)  <span class="hljs-comment"># Output: Negative</span>
check_sign(<span class="hljs-number">0</span>)   <span class="hljs-comment"># Output: Zero</span>
</code></pre>
<p>In this example, we define a function classify_value that takes an integer value as input and uses the match statement to match it against different literal values. Depending on the value of the input, it prints the corresponding classification.</p>
<p>It also works very well with strings as we can see in the following example.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">check_string</span>(<span class="hljs-params">value: str</span>):</span>
    match value:
        case <span class="hljs-string">"apple"</span>:
            print(<span class="hljs-string">"It's an apple"</span>)
        case <span class="hljs-string">"banana"</span>:
            print(<span class="hljs-string">"It's a banana"</span>)
        case _:
            print(<span class="hljs-string">"It's something else"</span>)

check_string(<span class="hljs-string">"apple"</span>)   <span class="hljs-comment"># Output: It's an apple</span>
check_string(<span class="hljs-string">"banana"</span>)  <span class="hljs-comment"># Output: It's a banana</span>
check_string(<span class="hljs-string">"orange"</span>)  <span class="hljs-comment"># Output: It's something else</span>
</code></pre>
<p>In this example, the check_string function takes a string value as input and uses the match statement to match it against different patterns defined in the case clauses. If the input string matches one of the specified patterns ("apple" or "banana"), the corresponding action is executed. Otherwise, the _ wildcard pattern catches any unmatched values, and the default action is executed, indicating that it's something else.</p>
<h2 id="heading-advanced-patterns">Advanced Patterns</h2>
<p>Pattern matching does not only work with basic types in Python, it can also be used with more complex types like lists, dict or tuples. Here are some examples.</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> typing <span class="hljs-keyword">import</span> List

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">match_list</span>(<span class="hljs-params">lst: List[int]</span>):</span>
    match lst:
        case [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, _]:
            print(<span class="hljs-string">"The first two elements are 1 and 2"</span>)
        case [x, y, z]:
            print(<span class="hljs-string">f"The list exacly 3 elements which are: <span class="hljs-subst">{x}</span>, <span class="hljs-subst">{y}</span>, <span class="hljs-subst">{z}</span>"</span>)
        case _:
            print(<span class="hljs-string">"List does not match"</span>)

match_list([<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>])       <span class="hljs-comment"># Output: The first two elements are 1 and 2</span>
match_list([<span class="hljs-number">4</span>, <span class="hljs-number">5</span>, <span class="hljs-number">6</span>])       <span class="hljs-comment"># Output: The list exacly 3 elements which are: 4, 5, 6</span>
match_list([<span class="hljs-number">7</span>, <span class="hljs-number">8</span>, <span class="hljs-number">9</span>, <span class="hljs-number">10</span>])   <span class="hljs-comment"># Output: First three elements are 7, 8, 9</span>
</code></pre>
<p>In the example, the match_list function takes a string value as input and uses the match statement to match it against different patterns defined in the case clauses. If the input string matches one of the specified patterns</p>
<ul>
<li><p>The First pattern in this case checks if the first two elements the the list are 1 and 2.</p>
</li>
<li><p>The Second pattern checks if the list has exactly 3 elements.</p>
</li>
<li><p>If none of these cases is matched, the _ wildcard pattern will be triggered and the default action is executed, indicating that it's something else.</p>
</li>
</ul>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">match_tuple</span>(<span class="hljs-params">tup</span>):</span>
    match tup:
        case (<span class="hljs-number">0</span>, _):
            print(<span class="hljs-string">"Tuple starts with zero"</span>)
        case (_, <span class="hljs-string">"hello"</span>):
            print(<span class="hljs-string">"Tuple contains 'hello'"</span>)
        case _:
            print(<span class="hljs-string">"Tuple does not match"</span>)

match_tuple((<span class="hljs-number">0</span>, <span class="hljs-string">"world"</span>))    <span class="hljs-comment"># Output: Tuple starts with zero</span>
match_tuple((<span class="hljs-number">42</span>, <span class="hljs-string">"hello"</span>))   <span class="hljs-comment"># Output: Tuple contains 'hello'</span>
match_tuple((<span class="hljs-number">10</span>, <span class="hljs-string">"bye"</span>))     <span class="hljs-comment"># Output: Tuple does not match</span>
</code></pre>
<p>This example shows how match can be used with a tuple. The first pattern checks if the first element of the tuple is 0 and the second pattern checks if the last element in the tuple is the string hello.</p>
<h2 id="heading-pattern-matching-with-custom-classes">Pattern matching with Custom Classes</h2>
<p>As Python developers, we write our own custom classes in most projects we work on. Another interesting aspect of match is how it works with custom classes. Basically, custom classes can define the <strong>__match_args__</strong> attributes, which should be a tuple that defines what attributes on a class instance get used in the case expression of a match statement.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Point</span>:</span>
    __match_args__ = (<span class="hljs-string">'x'</span>, <span class="hljs-string">'y'</span>)
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, x, y</span>):</span>
        self.x = x
        self.y = y

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">match_instance</span>(<span class="hljs-params">obj</span>):</span>
    match obj:
        case Point(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>):
            print(<span class="hljs-string">"Origin Point"</span>)
        case Point(x, y):
            print(<span class="hljs-string">f"Point at (<span class="hljs-subst">{x}</span>, <span class="hljs-subst">{y}</span>)"</span>)
        case _:
            print(<span class="hljs-string">"Not a Point instance"</span>)

point1 = Point(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>)
point2 = Point(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>)
point3 = Point(<span class="hljs-number">2</span>, <span class="hljs-number">2</span>)

match_instance(point1)   <span class="hljs-comment"># Output: Origin Point</span>
match_instance(point2)   <span class="hljs-comment"># Output: Point at (1, 1)</span>
match_instance(point3)   <span class="hljs-comment"># Output: Point at (2, 2)</span>
match_instance(<span class="hljs-string">"Hello"</span>)  <span class="hljs-comment"># Output: Not a Point instance</span>
</code></pre>
<p>In this example, we define a class Point with two attributes(x and y). Additionally, we also define <strong>__match_args__</strong> with both attributes meaning both will be used in the match expression. The match_instance function then takes an object as parameters and uses it to initiate the match pattern with the following cases:</p>
<ul>
<li><p>Point(0, 0): This pattern checks if the provided object is the origin(Point with x=0 and y = 0).</p>
</li>
<li><p>Point(x, y): This pattern checks if the provided object is a valid Point but different from the origin(Point with x != 0 and y != 0).</p>
</li>
<li><p>If none of these cases is matched, the _ wildcard pattern will be triggered and the default action is executed, indicating that it's something else.</p>
</li>
</ul>
<h2 id="heading-error-handling-with-pattern-matching">Error Handling with Pattern Matching</h2>
<p>Another important application of structural pattern matching in Python is error handling. it simplifies error handling and makes them more efficient, as we can see in the following use case.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomErrorType1</span>(<span class="hljs-params">Exception</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, message</span>):</span>
        self.message = message

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CustomErrorType2</span>(<span class="hljs-params">Exception</span>):</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, message</span>):</span>
        self.message = message


<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">process_data</span>(<span class="hljs-params">data</span>):</span>
    <span class="hljs-keyword">if</span> data.get(<span class="hljs-string">"status"</span>) == <span class="hljs-string">"success"</span>:
        result = data.get(<span class="hljs-string">"result"</span>)
        print(<span class="hljs-string">"Data processing successful. Result:"</span>, result)
    <span class="hljs-keyword">elif</span> data.get(<span class="hljs-string">"status"</span>) == <span class="hljs-string">"error"</span>:
        error = data.get(<span class="hljs-string">"error"</span>)
        <span class="hljs-keyword">if</span> isinstance(error, CustomErrorType1):
            print(<span class="hljs-string">"Error of Type1 occurred during data processing:"</span>, error.message)
        <span class="hljs-keyword">elif</span> isinstance(error, CustomErrorType2):
            print(<span class="hljs-string">"Error of Type2 occurred during data processing:"</span>, error.message)
        <span class="hljs-keyword">else</span>:
            print(<span class="hljs-string">"Unknown error occurred during data processing"</span>)
    <span class="hljs-keyword">else</span>:
        print(<span class="hljs-string">"Invalid data format"</span>)

<span class="hljs-comment"># Example usage</span>
data1 = {<span class="hljs-string">"status"</span>: <span class="hljs-string">"success"</span>, <span class="hljs-string">"result"</span>: <span class="hljs-number">42</span>}
data2 = {<span class="hljs-string">"status"</span>: <span class="hljs-string">"error"</span>, <span class="hljs-string">"error"</span>: CustomErrorType1(<span class="hljs-string">"Data not found"</span>)}
data3 = {<span class="hljs-string">"status"</span>: <span class="hljs-string">"error"</span>, <span class="hljs-string">"error"</span>: CustomErrorType2(<span class="hljs-string">"unauthorized access"</span>)}
data4 = {<span class="hljs-string">"status"</span>: <span class="hljs-string">"invalid"</span>}

process_data(data1)  <span class="hljs-comment"># Output: Data processing successful. Result: 42</span>
process_data(data2)  <span class="hljs-comment"># Output: Error of Type1 occurred during data processing: Data not found</span>
process_data(data3)  <span class="hljs-comment"># Output: Error of Type2 occurred during data processing: unauthorized access</span>
process_data(data4)  <span class="hljs-comment"># Output: Invalid data format</span>
</code></pre>
<p>This approach provides a more elegant and readable way to handle different cases, making the code more expressive and reducing the need for nested <code>if-else</code> blocks or cumbersome <code>try-except</code> constructs.</p>
<h2 id="heading-best-practices-and-tips">Best Practices and Tips</h2>
<p>One of the common questions that came out about structural pattern matching in Python is the question of knowing when to use them over the traditional control flow constructs like <code>if-elif-else</code>. Here are some points to consider when deciding which one to use.</p>
<ul>
<li><p>Structured Data: Pattern matching excels when working with structured data, such as dictionaries, tuples, or custom data types, where different patterns can be matched against specific attributes or values.</p>
</li>
<li><p>Multiple Conditions: If you have multiple conditions to check and handle based on the structure of data, pattern matching can provide a more concise and readable solution compared to nested if-elif-else blocks.</p>
</li>
<li><p>Error Handling: Pattern matching can be particularly useful for error handling, especially when dealing with custom exceptions or complex error scenarios. It allows elegantly handling different error or exception types and associated actions.</p>
</li>
<li><p>Simple Conditions: For simple conditional checks where you're only comparing values or evaluating boolean expressions, traditional control flow constructs like if-elif-else may be more straightforward and familiar.</p>
</li>
<li><p>Readability: In some cases, using if-elif-else statements may lead to more readable code, especially when the logic is straightforward and doesn't involve complex patterns or data structures.</p>
</li>
<li><p>Legacy Codebases: If you're working on a codebase that doesn't yet support Python 3.10 or where developers are not familiar with pattern matching, sticking with traditional control flow constructs may be more appropriate to maintain consistency and readability.</p>
</li>
</ul>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In conclusion, structural pattern matching in Python offers numerous benefits, including code readability, simplified conditional logic, and improved error handling. By providing a more concise and expressive syntax for matching patterns within data structures, Python's pattern-matching feature empowers developers to write cleaner and more maintainable code. I encourage you to explore and experiment with this powerful new feature in your own projects, leveraging its capabilities to streamline their code and unlock new possibilities. To delve deeper into structural pattern matching and its applications, I recommend consulting the official Python documentation and exploring additional resources available online.</p>
<h3 id="heading-references">references</h3>
<ul>
<li><p><a target="_blank" href="https://en.wikipedia.org/wiki/Pattern_matching">https://en.wikipedia.org/wiki/Pattern_matching</a></p>
</li>
<li><p><a target="_blank" href="https://peps.python.org/pep-0622/">https://peps.python.org/pep-0622/</a></p>
</li>
<li><p><a target="_blank" href="https://docs.python.org/3/whatsnew/3.10.html">https://docs.python.org/3/whatsnew/3.10.html</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Understanding the Differences Between Database, Data Warehouse, and Data Lake]]></title><description><![CDATA[In today's digital landscape, the phrase "data is the new oil" resonates more than ever, underscoring the pivotal role that data plays in shaping our modern world. As our lives become increasingly intertwined with technology, decisions across virtual...]]></description><link>https://blog.alexwalker.app/understanding-the-differences-between-database-data-warehouse-and-data-lake</link><guid isPermaLink="true">https://blog.alexwalker.app/understanding-the-differences-between-database-data-warehouse-and-data-lake</guid><category><![CDATA[Databases]]></category><category><![CDATA[#datawarehouse]]></category><category><![CDATA[datalake]]></category><dc:creator><![CDATA[Alex Mboutchouang]]></dc:creator><pubDate>Sun, 28 Apr 2024 17:07:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/klWUhr-wPJ8/upload/2739b2b22dfc7267f2a503483e923acf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In today's digital landscape, the phrase "data is the new oil" resonates more than ever, underscoring the pivotal role that data plays in shaping our modern world. As our lives become increasingly intertwined with technology, decisions across virtually every facet of life are informed by data. It's no wonder then, that organizations are pouring significant resources into the collection, storage, processing, and analysis of data.</p>
<p>Enter the concepts of databases, data warehouses, and data lakes – the cornerstone of modern data management. These entities form the backbone of organizations' efforts to harness the power of data, enabling them to glean insights and drive informed decision-making.</p>
<p>But what exactly do these terms entail, and why are they essential in today's data-driven era? Join us as we delve into the intricacies of databases, data warehouses, and data lakes, unravelling their roles and uncovering the key considerations that underpin their utilization in the ever-evolving landscape of data management.</p>
<h2 id="heading-databases">Databases</h2>
<p>A database is a collection of data that is organized and stored for easy access, retrieval, and management. It typically uses a schema to define the structure of the data and supports operations like querying, updating, and deleting.</p>
<h3 id="heading-key-features">Key Features</h3>
<ul>
<li><p>Provides efficient storage and retrieval of data.</p>
</li>
<li><p>Supports transaction processing, ensuring data integrity and consistency.</p>
</li>
<li><p>Allows for concurrent access by multiple users.</p>
</li>
<li><p>Suitable for applications requiring real-time data access and updates.</p>
</li>
</ul>
<h2 id="heading-data-warehouses">Data Warehouses</h2>
<p>A data warehouse is an art of centralized repository that stores structured and organized data from one or multiple sources. It is optimized for querying and analysis, typically using Online Analytical Processing (OLAP) tools, and is designed to support decision-making processes.</p>
<h3 id="heading-key-features-1">Key features</h3>
<ul>
<li><p>Integrates data from various sources, providing a unified view for analysis.</p>
</li>
<li><p>Supports complex queries and analytics to uncover insights and trends.</p>
</li>
<li><p>Provides historical data for trend analysis and reporting.</p>
</li>
<li><p>Enhances data quality through data cleaning and transformation processes.</p>
</li>
</ul>
<h2 id="heading-data-lake">Data lake</h2>
<p>A data lake is a centralized repository that stores vast amounts of raw, unstructured, and semi-structured data in its native format. It allows organizations to store data without the need for a predefined schema, enabling flexible processing and analysis.</p>
<h3 id="heading-key-features-2">Key features</h3>
<ul>
<li><p>Accommodates diverse data types and formats, including text, images, videos, and sensor data.</p>
</li>
<li><p>Enables data exploration and discovery without upfront schema design.</p>
</li>
<li><p>Supports advanced analytics, including machine learning and big data processing.</p>
</li>
<li><p>Scales easily handle large volumes of data, including streaming data sources.</p>
</li>
</ul>
<h2 id="heading-how-do-they-differ">How do they differ?</h2>
<p>Databases, data warehouses, and data lakes differ in structure, use cases, and handling of data types. Databases are either structured or semi-structured (no SQL database) and rely on predefined schemas, ideal for transaction processing and real-time data access. Data warehouses, require structured data, excel in analytics, reporting, and decision support, often integrating diverse data sources. Conversely, data lakes store raw data without predefined schemas, facilitating exploratory analysis, big data processing, and storage of structured, unstructured, and semi-structured data, offering unparalleled flexibility in data handling.</p>
<h3 id="heading-databases-1">Databases</h3>
<p>databases are best suited to being used to store operational data because they are efficient for storage and retrieval.</p>
<h3 id="heading-data-warehouses-1">Data warehouses</h3>
<p>In the scenario where You require to integrate data from one or many sources for analytics, reporting, and decision-making, data warehouses are more suitable.</p>
<h3 id="heading-data-lakes">Data lakes</h3>
<p>Data Lakes are best suited to being used You need to store and analyze large volumes of diverse data types, including unstructured and semi-structured data, and when you want to perform exploratory analysis or advanced analytics.</p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>In conclusion, databases, data warehouses, and data lakes each offer unique strengths and cater to distinct use cases within the realm of data management. By comprehending the advantages and limitations of these systems, organizations can make informed decisions when devising their data management strategies. Whether it's the real-time processing capabilities of databases, the analytical prowess of data warehouses, or the flexibility and scalability of data lakes, a nuanced understanding empowers organizations to leverage the right tools for their specific needs, ultimately driving efficiency, innovation, and success in the ever-evolving landscape of data-driven decision-making. I hope this article has provided you with a brief description of what databases, data warehouses and data lakes are and when to use them. Thanks for reading and see you soon for a new article.</p>
]]></content:encoded></item></channel></rss>