<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged syntax</title>
<link>https://coderlegion.com/tag/syntax</link>
<description>Powered by Question2Answer</description>
<item>
<title>Syntaxerror invalid syntax /Needs Improvement</title>
<link>https://coderlegion.com/24889/syntaxerror-invalid-syntax-needs-improvement</link>
<description>&lt;p&gt;&lt;strong&gt;The &lt;/strong&gt; &lt;span style=&quot;color: rgb(132, 63, 161);&quot;&gt;&lt;strong&gt;SyntaxError: invalid syntax&lt;/strong&gt;&lt;/span&gt; &lt;strong&gt; is a common error encountered by Python developers. It occurs when the Python interpreter encounters an invalid syntax in the parsing stage of the source code. This error can be caused by a variety of human mistakes, such as forgetting to include quotes, missing commas, or misspelling keywords. In this tutorial, we will explore some common causes of this error and learn how to solve them. &lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;toc-div&quot;&gt;
&lt;h4&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;&lt;strong&gt; Table of Contents: &lt;a id=&quot;toc-toogle&quot; class=&quot;open&quot;&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;div id=&quot;toc-list&quot;&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#_Toc125206348&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Causes of the Error.&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#_Toc125206349&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Solution&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#_Toc125206350&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;Conclusion&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#_Toc125206351&quot;&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;References&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2&gt;&lt;a class=&quot;custom_anchor&quot; name=&quot;_Toc125206348&quot;&gt;&lt;/a&gt;&lt;strong&gt;Causes of the Error&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;No Quotes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;One of the most common causes of &lt;strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/tutorial/errors.html#syntax-errors&quot;&gt; the error &lt;/a&gt; &lt;/strong&gt; is forgetting to include quotes around string literals. For example, the following code will produce this error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;print(Opensource Program)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 print(Opensource Program) ^^^^^^^^^^^^^^^^^^
SyntaxError: invalid syntax.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Missing Commas&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Another common cause of this error is forgetting to include a comma between items in a list or dictionary. Let's take a look at an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;grades = {
'Biology': 54,
'Chemistry': 76
'Swahili': 65
}
print(f'Chemistry grade is {grades[&quot;Chemistry&quot;]}.')
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 3 'chemisty':76 ^ SyntaxError: invalid syntax.
Perhaps you forgot a comma?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Misspelling Keywords&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can also occur when misspelling a keyword, such as &quot;for&quot; or &quot;if&quot;. Below is an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;fro i in range(5):
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 fro i in range(5): ^ SyntaxError: invalid
syntax
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Failing to Add a Keyword Altogether&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can also occur when a keyword is missing altogether, such as &quot;in&quot; in a for loop. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;for i range(5):
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output &lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 for i range(5): ^^^^^ SyntaxError: invalid
syntax
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Using Invalid Syntax with Functions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can also occur when using invalid syntax with functions, such as using a semicolon instead of colons. The following code will produce this error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;def exFun();
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 def exFun(); ^ SyntaxError: expected ':'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Switching Python Versions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can also occur when switching between different versions of Python. For example, the following code will produce this error in Python 3:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;print 'am a star in the ocean'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 print 'am a star in the ocean'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: Missing parentheses in call to
'print'. Did you mean print(...)?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Missing Parenthesis&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can occur when a parenthesis is missing in a function definition. For example, the following code will produce this error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;def my_function
print(&quot;Hello, world!&quot;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 def my_function ^ SyntaxError: expected '('
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Wrong Indentation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can occur when the indentation of code is incorrect, such as in a function definition. For example, the following code will produce this error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;def my_function():
print(&quot;Hello, world!&quot;) print(&quot;This line is improperly indented.&quot;)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 3 print(&quot;This line is improperly indented.&quot;)
IndentationError: unexpected indent
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Unmatched Quotes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This error can occur when quotes are not closed properly in a string. Here is how it occurs:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;x = &quot;Hello, world!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span style=&quot;font-family: arial,helvetica,sans-serif;&quot;&gt;File &quot;&quot;, line 1 x = &quot;Hello, world! ^ SyntaxError:
unterminated string literal (detected at line 1)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;a class=&quot;custom_anchor&quot; name=&quot;_Toc125206349&quot;&gt;&lt;/a&gt;&lt;strong&gt;Solution&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;To solve the &quot;SyntaxError: invalid syntax&quot; error, it is important to carefully review the code and check for any of the causes listed above.&lt;/p&gt;
&lt;p&gt;Once the cause of the error has been identified, it can usually be easily corrected.&lt;/p&gt;
&lt;p&gt;For example, if the error is caused by missing quotes, simply adding the missing quotes will solve the problem. If the error is caused by a missing comma, adding the missing comma will solve the problem. If the error is caused by a misspelled keyword, correcting the spelling will solve the problem. And so on.&lt;/p&gt;
&lt;p&gt;It is also important to pay attention to the error message and the line number that is indicated, as this can provide a clue as to where the problem is located in the code.&lt;/p&gt;
&lt;p&gt;In addition to reviewing and correcting the code, it is also important to ensure that the correct version of Python is being used. If the code was written in an older version of Python, it may not be compatible with a newer version and will need to be updated&lt;/p&gt;
&lt;div class=&quot;div-faq&quot;&gt;&lt;span class=&quot;faq-header&quot;&gt;FAQ&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;Can I use a code formatter to fix the &quot;SyntaxError: invalid syntax&quot; error?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yes, using a code formatter can also be a helpful tool for identifying and correcting syntax errors in your code. A code formatter can automatically format your code according to a specific style guide, making it easier to spot and fix any invalid syntax.&lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;&lt;a class=&quot;custom_anchor&quot; name=&quot;_Toc125206350&quot;&gt;&lt;/a&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;While the &lt;span style=&quot;color: rgb(132, 63, 161);&quot;&gt;&lt;strong&gt;SyntaxError: invalid syntax &lt;/strong&gt;&lt;/span&gt;error is common especially since we as humans are prone to error, it is easy to solve . By &lt;strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.python.org/dev/peps/pep-0008/&quot;&gt; understanding the causes &lt;/a&gt; &lt;/strong&gt; of this error and learning how to solve it, you will be better equipped to troubleshoot and correct any issues that arise in your Python code.&lt;/p&gt;
&lt;h2&gt;&lt;a class=&quot;custom_anchor&quot; name=&quot;_Toc125206351&quot;&gt;&lt;/a&gt;&lt;strong&gt;References&lt;/strong&gt; &lt;strong&gt; &lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;Python's official documentation on the specific error message &quot;SyntaxError: invalid syntax&quot;: &lt;u&gt; &lt;a href=&quot;https://docs.python.org/3/library/exceptions.html#SyntaxError&quot; target=&quot;_blank&quot; rel=&quot;noopener nofollow&quot;&gt; https://docs.python.org/3/library/exceptions.html#SyntaxError &lt;/a&gt; &lt;/u&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/24889/syntaxerror-invalid-syntax-needs-improvement</guid>
<pubDate>Wed, 19 Aug 2026 05:47:33 +0000</pubDate>
</item>
<item>
<title>DevLog 20260225: Divooka Visual Programming - Direct Value Setting of Compound Inputs</title>
<link>https://coderlegion.com/12185/devlog-20260225-divooka-visual-programming-direct-value-setting-of-compound-inputs</link>
<description>&lt;p&gt;Finally, it arrived! Well, not exactly here yet, but getting closer.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uefmdr5tir0qjdcfyax.png&quot; alt=&quot;Screenshot of Visual Programming in Divooka - Value Assignment of Compound Inputs&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;overview&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;Divooka intends to make visual programming simple and accessible - the accessible part is achieved both through wide availability and the general-purpose nature of the programming system, but the &lt;em&gt;simple&lt;/em&gt; part is what we spend lots of effort thinking hard trying to improve.&lt;/p&gt;
&lt;p&gt;In the past, dealing with complex configuration takes the form of either &lt;em&gt;&quot;explosion&quot;&lt;/em&gt; of arguments or dedicated &lt;code&gt;Make XXX&lt;/code&gt; construction functions:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mf6epcnl90nzwn4v3sni.png&quot; alt=&quot;An Example of A Node with Lots of Inputs&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/haamwdqh83lph8wphcw4.png&quot; alt=&quot;An Example of A Node Taking a Struct, Which Needs to be Created from a Node with Lots of Inputs&quot;&gt;&lt;/p&gt;
&lt;p&gt;The problem arises due to direct exposure of all input arguments in visual programming. Both approach makes the canvas look busy, with the former a common approach in existing systems - using a struct sounds good on paper but still requires a complex looking construction node. This is a common problem in visual programming systems, below shows how it's done in Blender and ComfyUI.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p74kj1nn0v5clwya2bp4.png&quot; alt=&quot;A Node with Many Inputs in ComfyUI&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jkcps43hasucbgc4fjr.png&quot; alt=&quot;A Node with Many Inputs in Blender&quot;&gt;&lt;/p&gt;
&lt;p&gt;You do get used to it after a while, but a busy looking canvas remains a busy-looking canvas. In Blender, you can sort of &quot;collapse&quot; a node:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51ssein4u54ak1b4x2dp.png&quot; alt=&quot;Collapse Nodes in Blender&quot;&gt;&lt;/p&gt;
&lt;p&gt;As Blender is constantly improving, we can also now collapse property groups as shown in the earlier screenshot.&lt;/p&gt;
&lt;p&gt;As a syntax purist and (unfortunately) very conscious about my working space, my eyes can't tolerate messiness. I kind of like how Houdini approaches this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6rcfmxoty5i6dt915ue9.png&quot; alt=&quot;Nodes in Houdini Are Very Simple and Clean&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/25jwxr7qrhzxak2u6ylm.png&quot; alt=&quot;Houdini Makes Use of Property Panels&quot;&gt;&lt;/p&gt;
&lt;p&gt;Essentially they offload all the complexity to the properties panel - this has the huge benefit of making everything look very clean. But the downside is Houdini rely heavily on scripting expressions (like Excel).&lt;/p&gt;
&lt;p&gt;TerraGen and World Machine mixes the approach:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8j6701vpaacarx9406jj.png&quot; alt=&quot;A Node Graph in World Machine&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fabvq61w0sqm3oiybyxf.png&quot; alt=&quot;A Node Graph in TerraGen&quot;&gt;&lt;/p&gt;
&lt;p&gt;In both cases, connections represent flow of terrain data only and additional configurations are offloaded to property panels. In TerraGen especially, this allows those properties to be animated. The downside, once again, is &lt;strong&gt;whatever is offloaded to property panels are no longer programmable using nodes&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;our-approach&quot;&gt;Our Approach&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9uefmdr5tir0qjdcfyax.png&quot; alt=&quot;Compound Input Editing Popup in Divooka&quot;&gt;&lt;/p&gt;
&lt;p&gt;Our proposed solution for Divooka looks like this: fundamentally all properties remain as node inputs, but compound values (especially value types) should just allow &quot;editing in place&quot; through a property panel. If more complex programming is needed, one can easily fall back to &lt;code&gt;Make XXX&lt;/code&gt; nodes again.&lt;/p&gt;
&lt;h3 id=&quot;future-work&quot;&gt;Future Work&lt;/h3&gt;
&lt;p&gt;There is still remaining work on type check, hierarchical compound types, arrays, and serialization, and also node rendering.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;As usual with all the exciting language features of Divooka we intend to introduce, there are lots of details to take care of here.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12185/devlog-20260225-divooka-visual-programming-direct-value-setting-of-compound-inputs</guid>
<pubDate>Wed, 25 Feb 2026 17:55:52 +0000</pubDate>
</item>
<item>
<title>Object-Oriented Configuration: Why TOML Is the Only Choice</title>
<link>https://coderlegion.com/6540/object-oriented-configuration-why-toml-is-the-only-choice</link>
<description>&lt;p&gt;&lt;em&gt;Configuration languages shape how developers think about their systems. We chose TOML because it brings object-oriented thinking to configuration—concepts with operations, not nested metadata.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;configuration-languages-are-contentious&quot;&gt;Configuration Languages Are Contentious&lt;/h3&gt;
&lt;p&gt;Developers have strong opinions about configuration formats. YAML advocates appreciate the clean look and minimal syntax. JSON supporters like the explicit structure and universal tooling. INI users value simplicity. Each choice involves tradeoffs, and those tradeoffs matter when you're configuring something that needs to be both human-readable and machine-reliable.&lt;/p&gt;
&lt;p&gt;We've all been burned by configuration. YAML turns &lt;code&gt;no&lt;/code&gt; into &lt;code&gt;false&lt;/code&gt;. JSON strips trailing commas. INI has no nesting. This is cognitive overhead that distracts from what you're actually trying to configure.&lt;/p&gt;
&lt;p&gt;What if configuration could think like code?&lt;/p&gt;
&lt;h3 id=&quot;toml-keeps-configuration-explicit&quot;&gt;TOML Keeps Configuration Explicit&lt;/h3&gt;
&lt;p&gt;When we needed a configuration format for a system with complex validation rules and nested test cases, we evaluated the usual suspects. YAML would give us clean syntax but unpredictable parsing. JSON would be explicit but verbose and unforgiving. We needed something developers could read, write, and trust without fighting the format.&lt;/p&gt;
&lt;p&gt;TOML stood out because it's explicitly declarative. What you write is what you get. No type coercion surprises, no invisible whitespace dependencies, no ambiguity about structure. But unlike JSON's verbosity, TOML has syntactic features that make configurations genuinely pleasant to write.&lt;/p&gt;
&lt;h3 id=&quot;dot-notation-without-explicit-nesting&quot;&gt;Dot Notation Without Explicit Nesting&lt;/h3&gt;
&lt;p&gt;Here's where TOML gets interesting. You can reference nested attributes using dot notation without having to explicitly define the parent structure first:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[eval]
description = &quot;Test response accuracy&quot;
type = &quot;accuracy&quot;
targets.agents = [&quot;*&quot;]
targets.tools = []
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice &lt;code&gt;targets.agents&lt;/code&gt; and &lt;code&gt;targets.tools&lt;/code&gt;? We didn't have to write:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[eval]
description = &quot;...&quot;
type = &quot;accuracy&quot;

[eval.targets]
agents = [&quot;*&quot;]
tools = []
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We just used dot notation inline. The structure is implicit but unambiguous. TOML creates the &lt;code&gt;targets&lt;/code&gt; object automatically. This is a small thing that adds up when you're writing dozens of configs. It allows you to think in terms of attributes, not nesting depth. You are, however, free to construct the full nested structure if you prefer that style; in cases where we have this flexibility, we prioritize grouping similar concepts together for clarity.&lt;/p&gt;
&lt;h3 id=&quot;array-of-tables-repeatable-structures&quot;&gt;Array of Tables: Repeatable Structures&lt;/h3&gt;
&lt;p&gt;Configuration often involves repeating the same structure with different values—test cases, server definitions, deployment targets. TOML's &lt;code&gt;[[double bracket]]&lt;/code&gt; syntax creates arrays of tables cleanly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[[eval.cases]]
prompt = &quot;What is the capital of France?&quot;
output.contains = &quot;Paris&quot;

[[eval.cases]]
prompt = &quot;Explain what HTTP is&quot;
output = {
  similar = &quot;HTTP is a protocol for transferring data over the web.&quot;,
  threshold = 0.8
}

[[eval.cases]]
prompt = &quot;Get weather data&quot;
[eval.cases.output.schema]
temperature = { type = &quot;float&quot; }
condition = { type = &quot;str&quot; }
humidity = { type = &quot;int&quot; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each &lt;code&gt;[[eval.cases]]&lt;/code&gt; declaration adds another item to the array. The structure is visually distinct. The repetition is obvious. You can scan through entries without getting lost in nesting.&lt;/p&gt;
&lt;h3 id=&quot;dot-notation-as-behavior-modifiers&quot;&gt;Dot Notation as Behavior Modifiers&lt;/h3&gt;
&lt;p&gt;Here's where TOML's dot syntax enables something clever: you can use it to attach behavior modifiers to fields without introducing extra nesting. Instead of wrapping configuration in container objects, you extend the field name itself:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[[eval.cases]]
prompt = &quot;What is the capital of France?&quot;
output.contains = &quot;Paris&quot;

[[eval.cases]]
prompt = &quot;What's the weather like?&quot;
output.startswith = [&quot;It's&quot;, &quot;Currently&quot;, &quot;The weather&quot;]

[[eval.cases]]
prompt = &quot;Extract the user's email address&quot;
output.match = &quot;\w+@\w+\.\w+&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each suffix—&lt;code&gt;.contains&lt;/code&gt;, &lt;code&gt;.startswith&lt;/code&gt;, &lt;code&gt;.match&lt;/code&gt;—changes how the value gets interpreted. The field name carries the semantic meaning. You're not nesting objects or adding metadata layers. You're using the key itself to express intent.&lt;/p&gt;
&lt;p&gt;This is object-oriented thinking applied to configuration. You have a concept. You apply operations to it. It's how developers already think—now it's how configuration works. When someone sees &lt;code&gt;output.contains&lt;/code&gt;, they immediately understand the pattern. They can intuit what other operations exist. Compare this to YAML or JSON where you'd need wrapper objects:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;output&quot;: {
    &quot;strategy&quot;: &quot;contains&quot;,
    &quot;value&quot;: &quot;Paris&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or nested structures:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;output:
  contains: &quot;Paris&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TOML keeps it flat. The field name describes the behavior, and the value is just the value—no extra layers wrapping things up.&lt;/p&gt;
&lt;p&gt;This pattern extends to schema definitions. Field validation rules attach directly to field names:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[[eval.cases]]
prompt = &quot;Validate user profile&quot;
[eval.cases.output.schema]
username = {
  type = &quot;str&quot;,
  min_length = 3,
  max_length = 20
}
age = {
  type = &quot;int&quot;,
  min = 13,
  max = 120
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The validation constraints are readable and self-documenting. No wrapper objects, no indirection—just direct field definitions with their validation rules.&lt;/p&gt;
&lt;h3 id=&quot;inline-tables-for-compact-structure&quot;&gt;Inline Tables for Compact Structure&lt;/h3&gt;
&lt;p&gt;When configuration objects are small, TOML lets you write them inline:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;latency = { max_ms = 3000 }
output = { similar = &quot;expected text&quot;, threshold = 0.8 }
tools = [{ name = &quot;add&quot;, args = [2, 2] }]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is more readable than splitting every small object into its own &lt;code&gt;[section]&lt;/code&gt; block, but it's still explicit. You can see exactly what's nested and what isn't.&lt;/p&gt;
&lt;h3 id=&quot;what-toml-gets-right&quot;&gt;What TOML Gets Right&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Ecosystem adoption&lt;/strong&gt;: Python's packaging ecosystem standardized on TOML. &lt;code&gt;pyproject.toml&lt;/code&gt; replaced &lt;code&gt;setup.py&lt;/code&gt; and became the official configuration format for Python projects. Poetry, Ruff, Black, pytest—all use TOML. When the Python community—known for pragmatism and careful design decisions—chooses TOML as the de facto standard, that's a signal worth paying attention to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Explicit types&lt;/strong&gt;: Strings need quotes. Numbers don't. Booleans are &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;, not &lt;code&gt;yes&lt;/code&gt;/&lt;code&gt;no&lt;/code&gt;/&lt;code&gt;on&lt;/code&gt;/&lt;code&gt;off&lt;/code&gt;. Dates are ISO 8601. No guessing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Readable structure&lt;/strong&gt;: Keys are unquoted unless they need special characters. Sections use &lt;code&gt;[headers]&lt;/code&gt; that stand out visually. Comments use &lt;code&gt;#&lt;/code&gt; like most scripting languages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No invisible whitespace&lt;/strong&gt;: Unlike YAML, indentation is cosmetic. Your config won't break because someone's editor uses tabs instead of spaces. We chose TOML knowing this would eliminate an entire category of bugs.&lt;/p&gt;
&lt;h3 id=&quot;the-tradeoffs-we-accepted&quot;&gt;The Tradeoffs We Accepted&lt;/h3&gt;
&lt;p&gt;TOML isn't perfect. Deeply nested structures get verbose—you end up with long dotted paths or multiple &lt;code&gt;[section.subsection.subsubsection]&lt;/code&gt; headers. If your config is a deeply nested tree, JSON or YAML might feel more natural.&lt;/p&gt;
&lt;p&gt;TOML also doesn't support references or anchors like YAML does. You can't define a block once and reuse it elsewhere. For configurations where reusability matters more than explicitness, that's a real limitation.&lt;/p&gt;
&lt;p&gt;And TOML is less universally supported than JSON. Most languages have libraries, but JSON is everywhere. If you need to parse configs in obscure environments or legacy systems, JSON's ubiquity wins.&lt;/p&gt;
&lt;h3 id=&quot;could-toml-be-better-&quot;&gt;Could TOML Be Better?&lt;/h3&gt;
&lt;p&gt;One pattern we noticed: when you're defining attributes deep inside an array of tables, you have to repeat the full path:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[[eval.cases]]
prompt = &quot;Test prompt&quot;
  [eval.cases.output.schema]
  field1 = { type = &quot;str&quot; }
  field2 = { type = &quot;int&quot; }

[[eval.cases]]
prompt = &quot;Another test&quot;
  [eval.cases.output.schema]
  field1 = { type = &quot;str&quot; }
  field2 = { type = &quot;int&quot; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;code&gt;[eval.cases.output.schema]&lt;/code&gt; is verbose. What if TOML supported a shorthand where a leading dot means &quot;relative to the parent table&quot;?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[[eval.cases]]
prompt = &quot;Test prompt&quot;
  [.output.schema]
  field1 = { type = &quot;str&quot; }
  field2 = { type = &quot;int&quot; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This would indicate &quot;relative to the last table-array item.&quot; It's a small syntactic feature that would reduce visual noise in configs with deep nesting under array items. Maybe that's worth exploring as a TOML extension, or maybe it introduces ambiguity that breaks the explicit clarity that makes TOML work. Worth considering.&lt;/p&gt;
&lt;h3 id=&quot;why-configuration-format-matters&quot;&gt;Why Configuration Format Matters&lt;/h3&gt;
&lt;p&gt;Configuration gets read and written constantly. Developers write it when defining behavior. They read it when debugging. They scan it during code review. They modify it when requirements change. The format needs to be immediately legible and predictable.&lt;/p&gt;
&lt;p&gt;This matters especially when the system being configured is already complex or non-deterministic. Configuration shouldn't add another layer of cognitive overhead—that's the problem we started with. TOML's declarative clarity lets developers focus on what they're configuring, not how the format will interpret it.&lt;/p&gt;
&lt;p&gt;For Agent CI, TOML is our primary integration point. Evaluation configurations live in &lt;code&gt;.agentci/evals/&lt;/code&gt; and define all testing behavior without requiring changes to application code. This separation means you can add comprehensive evaluation coverage to existing agents without modifying prompts, tools, or deployment logic. The configuration format becomes the interface. It needs to be readable, maintainable, and expressive enough to handle complex validation rules. TOML gives us that.&lt;/p&gt;
&lt;h3 id=&quot;the-broader-pattern&quot;&gt;The Broader Pattern&lt;/h3&gt;
&lt;p&gt;This choice reflects a larger philosophy: developer tools should be predictable. Surprises belong in what you're building, not in the tools you're using to build it.&lt;/p&gt;
&lt;p&gt;YAML's type coercion might save a few characters, but it creates confusion when &lt;code&gt;Norway&lt;/code&gt; becomes &lt;code&gt;true&lt;/code&gt; because it matches a boolean alias. JSON's strict structure eliminates ambiguity but makes you count brackets and remember commas. TOML finds middle ground—explicit enough to be predictable, expressive enough to be pleasant.&lt;/p&gt;
&lt;p&gt;Configuration languages shape how developers think about their systems. A good config format makes structure obvious, reduces ceremony, and doesn't surprise you. TOML does that.&lt;/p&gt;
&lt;p&gt;If you're curious how these patterns play out in practice, the evaluation configs we've been using as examples are open source: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Agent-CI/client-config/&quot;&gt;github.com/Agent-CI/client-config&lt;/a&gt;. If this resonates with configuration frustrations you've hit—or if you've found other patterns that work—we want to hear about it. Configuration design is iterative. The more real-world usage we can learn from, the better.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Travis Dent is CEO of Agent CI, bringing systematic software development practices to AI agent development.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Python</category>
<guid isPermaLink="true">https://coderlegion.com/6540/object-oriented-configuration-why-toml-is-the-only-choice</guid>
<pubDate>Thu, 16 Oct 2025 21:34:35 +0000</pubDate>
</item>
<item>
<title>Topic 20250618: Procedural Context is More Learning (and Syntax) to Users</title>
<link>https://coderlegion.com/3363/topic-20250618-procedural-context-is-more-learning-and-syntax-to-users</link>
<description>&lt;h3 id=&quot;overview-1&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;When people first open Divooka, they see a network of interconnected nodes where connections represent data flow.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/09w4h4ekh092007lcieh.png&quot; alt=&quot;Hello World in Divooka&quot;&gt;&lt;/p&gt;
&lt;p&gt;Even someone who has never seen visual programming or Divooka before can read the titles of the nodes and input parameters and have a pretty good guess at what the program does.&lt;/p&gt;
&lt;p&gt;Thus, a key to using Divooka (in the dataflow context) efficiently is understanding the execution runtime - what nodes are active, what the dependency tree is, and how caching works.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qff3yneo64t71mme33a0.png&quot; alt=&quot;Canonical Example of Divooka Program&quot;&gt;&lt;/p&gt;
&lt;p&gt;As someone who has been using Unreal Engine Blueprint since 2014, the concept of &quot;execution flow&quot; appears natural to me - but when showing this to new users, it became evident that it takes time to tune in and learn to read the diagrams.&lt;/p&gt;
&lt;p&gt;We'll take a look at what procedural context is, then briefly analyze why that's the case.&lt;/p&gt;
&lt;h3 id=&quot;the-procedural-constructs&quot;&gt;The Procedural Constructs&lt;/h3&gt;
&lt;p&gt;The procedural context in Divooka provides many constructs that may be familiar to those from traditional programming languages.&lt;/p&gt;
&lt;p&gt;An example is shown below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xcspn3im5zkka4w0qcco.png&quot; alt=&quot;Procedural Example&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;common-constructs&quot;&gt;Common Constructs&lt;/h4&gt;
&lt;p&gt;Conditional logic is done using the &lt;strong&gt;Branch&lt;/strong&gt; node.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pbihzzew385ja3qhtiwd.png&quot; alt=&quot;Branch Node&quot;&gt;&lt;/p&gt;
&lt;p&gt;Loops are implemented using the &lt;strong&gt;Repeat&lt;/strong&gt; node.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/thv3amrjl4i1ufrupazg.png&quot; alt=&quot;Repeat Node&quot;&gt;&lt;/p&gt;
&lt;p&gt;Iteration is done using the &lt;strong&gt;For Each&lt;/strong&gt; node.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ql7n4ejel01nehp9dqum.png&quot; alt=&quot;For Each Node&quot;&gt;&lt;/p&gt;
&lt;p&gt;Functions are handled using the &lt;strong&gt;Execute Event&lt;/strong&gt; and &lt;strong&gt;Custom Event&lt;/strong&gt; nodes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sc114ttylctvk2ud65mt.png&quot; alt=&quot;Custom Events&quot;&gt;&lt;/p&gt;
&lt;p&gt;A switch-case structure is implemented using the &lt;strong&gt;Switch&lt;/strong&gt; node.&lt;/p&gt;
&lt;p&gt;(Pending image)&lt;/p&gt;
&lt;h4 id=&quot;unique-constructs&quot;&gt;Unique Constructs&lt;/h4&gt;
&lt;p&gt;In addition, Divooka also offers constructs that are unique to it:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sequence&lt;/strong&gt; nodes are used to define multiple sequential steps.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zk5upgtqff6xbbatxrvu.png&quot; alt=&quot;Sequence Node&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Events&lt;/strong&gt; are entry points defined by the framework (procedural context base type).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z5xv5n64dbesogk75inv.png&quot; alt=&quot;Event Example&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;implementation-note&quot;&gt;Implementation Note&lt;/h4&gt;
&lt;p&gt;Certain constructs are currently missing:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Break&lt;/strong&gt;: to exit a loop prematurely.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;caveats-of-states&quot;&gt;Caveats of States&lt;/h4&gt;
&lt;p&gt;What's more, in procedural context there is the possibility of manipulating state - for example, incrementing a number to be used next time.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xhoq417eu65xdj97z511.png&quot; alt=&quot;State Variable Example&quot;&gt;&lt;/p&gt;
&lt;p&gt;Thus, to use the procedural context effectively, users need to learn a good amount of &quot;syntax&quot;: control flow, state handling, and more.&lt;/p&gt;
&lt;h3 id=&quot;the-two-contexts&quot;&gt;The Two Contexts&lt;/h3&gt;
&lt;p&gt;Given that all of the top 10 most popular programming languages support imperative/procedural programming as the default mode, one might expect this to be the most straightforward paradigm. In reality, that's not the case.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uhjzx1by2t1sf2ertcj8.png&quot; alt=&quot;The Two Contexts&quot;&gt;&lt;/p&gt;
&lt;p&gt;Use the &lt;strong&gt;dataflow context&lt;/strong&gt; for data-centric operations, such as data transformations.&lt;/p&gt;
&lt;p&gt;Use the &lt;strong&gt;procedural context&lt;/strong&gt; for logic-centric operations, such as branching and conditional executions.&lt;/p&gt;
&lt;p&gt;Unlike procedural context, when using dataflow context, users need to learn only a single syntax: connections represent data flows, and everything (almost) always executes - depending on node activation status. To follow the flow of a program is simply to follow the connections - there's no concern about branches or alternate execution paths.&lt;/p&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;The procedural context is more complex for several reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Connections now represent both data and execution flow&lt;/li&gt;
&lt;li&gt;Some nodes can interrupt, diverge from, or selectively execute downstream connections - requiring users to understand exact behaviors to make accurate predictions&lt;/li&gt;
&lt;li&gt;There are many types of flow control nodes, each requiring learning&lt;/li&gt;
&lt;li&gt;State is involved&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Part of the reason Divooka started with the dataflow context was exactly to reduce this complexity. However, as programs become more complicated and procedural logic becomes involved, it's not possible to avoid procedural context - in fact, having it is often more convenient than not.&lt;/p&gt;
&lt;p&gt;Users must make informed decisions about what to put into procedural context and what to offload to dataflow context.&lt;/p&gt;
&lt;h3 id=&quot;references&quot;&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/Divooka/Language/DataflowContext&quot;&gt;Dataflow context in Divooka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/Divooka/Language/ProceduralContext&quot;&gt;Procedural context in Divooka&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>C#</category>
<guid isPermaLink="true">https://coderlegion.com/3363/topic-20250618-procedural-context-is-more-learning-and-syntax-to-users</guid>
<pubDate>Wed, 18 Jun 2025 17:44:27 +0000</pubDate>
</item>
<item>
<title>Regular Expression - A Comprehensive Guide</title>
<link>https://coderlegion.com/3193/regular-expression-a-comprehensive-guide</link>
<description>&lt;p&gt;(Originally posted on Methodox Wiki, visit &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/KnowledgeBase/Regex&quot;&gt;the page&lt;/a&gt; for a live tester!)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Contents&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#h-1-introduction&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#h-2-live-tester&quot;&gt;Live Tester&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#h-3-practical-syntax&quot;&gt;Practical Syntax&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#h-4-comprehensive-reference&quot;&gt;Comprehensive Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;#h-5-conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;(Due to CoderLegion content length limit, section 4 is ommitted)&lt;/p&gt;
&lt;h3 id=&quot;1-introduction&quot;&gt;1. Introduction&lt;/h3&gt;
&lt;p&gt;Text - whether it’s log files, configuration data, user input, or documents - is everywhere in programming. From simple scripts to full-blown applications, developers frequently need to &lt;strong&gt;search&lt;/strong&gt;, &lt;strong&gt;validate&lt;/strong&gt;, &lt;strong&gt;extract&lt;/strong&gt;, or &lt;strong&gt;transform&lt;/strong&gt; pieces of text. While many IDEs and editors (like Notepad++, VS Code, or Sublime Text) offer basic find-and-replace functionality, they quickly reach their limits when you need to handle patterns, conditional logic, or repeated structures. That’s where &lt;strong&gt;regular expressions&lt;/strong&gt; (regex) come in.&lt;/p&gt;
&lt;p&gt;At its core, a regular expression is a compact, declarative way to describe a set of strings. Instead of manually scanning through text to find, say, all warning messages in a log, you can write a single pattern that matches timestamps, log levels, filenames, email addresses, URLs - you name it. Once you understand the fundamentals, regex can become one of the most powerful “weapons” in your developer toolbox.&lt;/p&gt;
&lt;p&gt;Consider a typical log snippet:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2025-05-31 14:23:48 [Info] Starting application...
2025-05-31 14:23:50 [Info] Loading application data...
2025-05-31 14:23:55 [Warning] Missing font file: New Times Roman.
2025-05-31 14:24:22 [Info] The application has started, with 1 warning.
2025-05-31 14:25:01 [Error] Unhandled exception: NullReferenceException.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to answer questions like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“What warnings were emitted, and when?”&lt;/li&gt;
&lt;li&gt;“Which lines contain error messages?”&lt;/li&gt;
&lt;li&gt;“How many times did the application start?”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You could write a script in your favorite language that splits on spaces, checks tokens, and does string comparisons. But that quickly becomes tedious: parsing variability in timestamps, handling optional fields, or ignoring whitespace quirks can make your code fragile.&lt;/p&gt;
&lt;p&gt;With a well-crafted regex, however, you can match on the entire log line, capture the timestamp, the log level, and the rest of the message - all in one pattern. More importantly, regex can handle &lt;strong&gt;any&lt;/strong&gt; text-based format for which there’s a consistent structure: CSV files, HTML/XML tags, custom configuration formats, and so on.&lt;/p&gt;
&lt;p&gt;By the end of this article, you will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Understand the basic motivation behind regular expressions.&lt;/li&gt;
&lt;li&gt;See practical syntax elements and examples for day-to-day tasks.&lt;/li&gt;
&lt;li&gt;Have a handy reference that summarizes the most commonly used regex constructs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Whether you’ve done a bit of “find and replace” in an editor, or you’ve written simple string processing code, this guide will bridge the gap and show you how to level up with regular expressions.&lt;/p&gt;
&lt;h3 id=&quot;2-live-tester&quot;&gt;2. Live Tester&lt;/h3&gt;
&lt;p&gt;See &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/KnowledgeBase/Regex#h-2-live-tester&quot;&gt;original post&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;3-practical-syntax&quot;&gt;3. Practical Syntax&lt;/h3&gt;
&lt;p&gt;In this section, we’ll cover the core building blocks of regex patterns. Each subsection introduces a concept, followed by real-world examples - some based on log processing, others on everyday tasks like validating email addresses or extracting numbers from text.&lt;/p&gt;
&lt;h4 id=&quot;3-1-literal-characters-and-simple-matches&quot;&gt;3.1 Literal Characters and Simple Matches&lt;/h4&gt;
&lt;p&gt;At the simplest level, a regex can be just literal characters. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pattern &lt;code&gt;Error&lt;/code&gt; will match any occurrence of the substring “Error” in a text.&lt;/li&gt;
&lt;li&gt;Pattern &lt;code&gt;2025-05-31&lt;/code&gt; will match that exact date string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, real-world text rarely lines up perfectly. Log messages, for instance, include varying timestamps and different log levels. To match them in a generic way, you need &lt;strong&gt;metacharacters&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Key Point:&lt;/strong&gt; Most characters in a regex match themselves literally, except for special metacharacters (like &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;\&lt;/code&gt;, etc.). To match a literal period, bracket, or other metacharacter, you must “escape” it with a backslash (&lt;code&gt;\.&lt;/code&gt; to match a literal dot, &lt;code&gt;\[&lt;/code&gt; to match a literal left bracket, and so on).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;3-2-character-classes-and-ranges&quot;&gt;3.2 Character Classes (&lt;code&gt;[]&lt;/code&gt;) and Ranges&lt;/h4&gt;
&lt;p&gt;A &lt;strong&gt;character class&lt;/strong&gt; is a bracketed set of characters that match exactly one character from the set. For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[AEIOU]&lt;/code&gt; matches any single uppercase vowel.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[0-9]&lt;/code&gt; matches any digit from 0 through 9.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[A-Za-z0-9_]&lt;/code&gt; matches a typical word character (letter, digit, or underscore).&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;example-1-matching-a-four-digit-year&quot;&gt;Example 1: Matching a Four-Digit Year&lt;/h5&gt;
&lt;p&gt;Suppose you want to match any year between 1900 and 2099:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^(19|20)[0-9]{2}$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; are &lt;strong&gt;anchors&lt;/strong&gt; (we’ll cover them in a moment).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(19|20)&lt;/code&gt; matches either “19” or “20”.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[0-9]{2}&lt;/code&gt; matches exactly two digits.&lt;/li&gt;
&lt;li&gt;Altogether, this matches “1900” through “2099”.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;example-2-extracting-log-levels&quot;&gt;Example 2: Extracting Log Levels&lt;/h5&gt;
&lt;p&gt;Given a log line like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2025-05-31 14:23:55 [Warning] Missing font file: New Times Roman.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can match the log level (&lt;code&gt;Info&lt;/code&gt;, &lt;code&gt;Warning&lt;/code&gt;, &lt;code&gt;Error&lt;/code&gt;, etc.) with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\[(Info|Warning|Error|Debug)\]
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;\[` and `\]&lt;/code&gt; match literal square brackets.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(Info|Warning|Error|Debug)&lt;/code&gt; matches one of those four words.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you expect additional levels (e.g., &lt;code&gt;Trace&lt;/code&gt; or &lt;code&gt;Fatal&lt;/code&gt;), you can add them inside the parentheses:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\[(?:Info|Warning|Error|Debug|Trace|Fatal)\]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we’ve used &lt;code&gt;(?: … )&lt;/code&gt; to create a &lt;strong&gt;non-capturing group&lt;/strong&gt; (we’ll talk about groups more in section 5).&lt;/p&gt;
&lt;h4 id=&quot;3-3-quantifiers-repetition-control&quot;&gt;3.3 Quantifiers: Repetition Control&lt;/h4&gt;
&lt;p&gt;Quantifiers specify how many times the preceding element should match. The most common quantifiers are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; – Match zero or more times (greedy).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+&lt;/code&gt; – Match one or more times (greedy).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;?&lt;/code&gt; – Match zero or one time (makes the preceding token optional).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{n}&lt;/code&gt; – Match exactly &lt;em&gt;n&lt;/em&gt; times.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{n,m}&lt;/code&gt; – Match between &lt;em&gt;n&lt;/em&gt; and &lt;em&gt;m&lt;/em&gt; times (inclusive).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{n,}&lt;/code&gt; – Match &lt;em&gt;n&lt;/em&gt; or more times.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;example-3-matching-timestamps&quot;&gt;Example 3: Matching Timestamps&lt;/h5&gt;
&lt;p&gt;A timestamp like &lt;code&gt;2025-05-31 14:23:48&lt;/code&gt; can be matched with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;\d&lt;/code&gt; is shorthand for &lt;code&gt;[0-9]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\d{4}&lt;/code&gt; matches exactly four digits (the year).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-&lt;/code&gt; matches a literal hyphen.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\d{2}&lt;/code&gt; matches two digits (month and day).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\s+&lt;/code&gt; matches one or more whitespace characters (space, tab).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\d{2}:\d{2}:\d{2}&lt;/code&gt; matches &lt;code&gt;HH:MM:SS&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you’re sure there’s exactly one space between date and time, you could use &lt;code&gt;\s&lt;/code&gt; instead of &lt;code&gt;\s+&lt;/code&gt;.&lt;/p&gt;
&lt;h5 id=&quot;example-4-optional-file-extension&quot;&gt;Example 4: Optional File Extension&lt;/h5&gt;
&lt;p&gt;Suppose you have filenames like &lt;code&gt;report.txt&lt;/code&gt; or &lt;code&gt;report&lt;/code&gt;. To match both, you could use:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^report(?:\.txt)?$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; ensure we match the entire string.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;(?:\.txt)?&lt;/code&gt; means “optionally match ‘.txt’”.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;\.&lt;/code&gt; matches a literal dot.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;txt&lt;/code&gt; matches “txt”.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;?&lt;/code&gt; after the group makes it optional.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-4-anchors-positioning-matches&quot;&gt;3.4 Anchors: Positioning Matches&lt;/h4&gt;
&lt;p&gt;Anchors specify positions in the text rather than actual characters:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^&lt;/code&gt; – Start of the line/string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$&lt;/code&gt; – End of the line/string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\b&lt;/code&gt; – Word boundary (between &lt;code&gt;\w&lt;/code&gt; and &lt;code&gt;\W&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\B&lt;/code&gt; – Non-word boundary.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;example-5-lines-starting-with-error-&quot;&gt;Example 5: Lines Starting with “Error”&lt;/h5&gt;
&lt;p&gt;If you want to catch any line that begins with the word “Error” (as a standalone word), you can write:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^Error\b.*$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^Error&lt;/code&gt; ensures the line starts with “Error”.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\b&lt;/code&gt; asserts a word boundary so that “Errors” or “ErrorCode” are not matched.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.*&lt;/code&gt; matches the rest of the line (any character, zero or more times).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$&lt;/code&gt; anchors the end of line.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-5-groups-and-capturing&quot;&gt;3.5 Groups and Capturing&lt;/h4&gt;
&lt;p&gt;Parentheses &lt;code&gt;(&lt;/code&gt; and &lt;code&gt;)&lt;/code&gt; serve two main purposes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Grouping&lt;/strong&gt;: Treat multiple tokens as a single unit (often used with quantifiers or alternation).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Capturing&lt;/strong&gt;: Store the text matched by that group for later retrieval (in code or in a replacement string).&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&quot;example-6-capturing-timestamps-and-levels&quot;&gt;Example 6: Capturing Timestamps and Levels&lt;/h5&gt;
&lt;p&gt;Given:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2025-05-31 14:23:55 [Warning] Missing font...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You might write:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+\[(Info|Warning|Error|Debug)\]\s+(.*)$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(\d{4}-\d{2}-\d{2})&lt;/code&gt; captures the date (&lt;code&gt;Group 1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(\d{2}:\d{2}:\d{2})&lt;/code&gt; captures the time (&lt;code&gt;Group 2&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(Info|Warning|Error|Debug)&lt;/code&gt; captures the log level (&lt;code&gt;Group 3&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(.*)&lt;/code&gt; captures the rest of the message (&lt;code&gt;Group 4&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In most languages, after matching, you can extract Group 1, Group 2, etc.:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;e.g., in C#: &lt;code&gt;match.Groups[1].Value&lt;/code&gt; gives the date.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to group without capturing (for alternation or quantifier purposes), use &lt;code&gt;(?: … )&lt;/code&gt;. For instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(?:Info|Warning|Error|Debug)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;does &lt;strong&gt;not&lt;/strong&gt; create a numbered backreference.&lt;/p&gt;
&lt;h4 id=&quot;3-6-common-metacharacters-and-escape-sequences&quot;&gt;3.6 Common Metacharacters and Escape Sequences&lt;/h4&gt;
&lt;p&gt;Some of the most frequently used shorthand and metacharacters include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.&lt;/code&gt; – Matches any character except newline (in most flavors; some allow a “dotall” mode to match newline).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\d&lt;/code&gt; – Digit (equivalent to &lt;code&gt;[0-9]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\D&lt;/code&gt; – Non-digit (equivalent to &lt;code&gt;[^0-9]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\w&lt;/code&gt; – Word character (letter, digit, underscore; &lt;code&gt;[A-Za-z0-9_]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\W&lt;/code&gt; – Non-word character (anything not in &lt;code&gt;\w&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\s&lt;/code&gt; – Whitespace character (space, tab, newline, etc.).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\S&lt;/code&gt; – Non-whitespace character.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\t&lt;/code&gt;, &lt;code&gt;\n&lt;/code&gt;, &lt;code&gt;\r&lt;/code&gt; – Tab, newline, carriage return.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; When writing regexes in code, you often need to escape backslashes. For instance, in C# you can use verbatim string literals (&lt;code&gt;@&quot;\d{4}-\d{2}-\d{2}&quot;&lt;/code&gt;) to avoid double escapes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;3-7-practical-example-extracting-email-addresses&quot;&gt;3.7 Practical Example: Extracting Email Addresses&lt;/h4&gt;
&lt;p&gt;Say you have a document or a configuration file and need to pull out all email addresses. A simple - but not fully RFC‑compliant - pattern is:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;\b&lt;/code&gt; – Ensure we start at a word boundary.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[A-Za-z0-9._%+-]+&lt;/code&gt; – One or more letters, digits, dots, underscores, percent signs, plus, or hyphens (the local part before the &lt;code&gt;@&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@&lt;/code&gt; – Literal “@” symbol.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[A-Za-z0-9.-]+&lt;/code&gt; – One or more letters, digits, dots, or hyphens (domain).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\.&lt;/code&gt; – Literal dot.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[A-Za-z]{2,}&lt;/code&gt; – At least two letters for the TLD (e.g., “com”, “org”, “io”).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\b&lt;/code&gt; – End at a word boundary to prevent partial matches (so we don’t match trailing punctuation).&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;testing-it&quot;&gt;Testing It&lt;/h5&gt;
&lt;p&gt;Given:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Please contact *Emails are not allowed* or *Emails are not allowed* for more info. Alternatively, reach out to admin@localhost if testing locally.
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*Emails are not allowed*&lt;/code&gt; matches.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*Emails are not allowed*&lt;/code&gt; matches.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;admin@localhost&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; match because &lt;code&gt;localhost&lt;/code&gt; has no “&lt;code&gt;.&lt;/code&gt; + two-or-more-letters” TLD.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-8-practical-example-validating-north-american-phone-numbers&quot;&gt;3.8 Practical Example: Validating North American Phone Numbers&lt;/h4&gt;
&lt;p&gt;North American Numbering Plan (NANP) phone numbers often look like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;123-456-7890&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(123) 456-7890&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;123.456.7890&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;+1 (123) 456-7890&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A practical regex might be:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^(\+1\s?)?           # Optional country code +1 and a space
(?:\(\d{3}\)|\d{3})  # Either (123) or 123
[ .-]?               # Separator: space, dot, or hyphen (optional)
\d{3}                # Next three digits
[ .-]?               # Separator again (optional)
\d{4}$               # Last four digits
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When compacted (and removing whitespace/comments):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^(\+1\s?)?(?:\(\d{3}\)|\d{3})[ .-]?\d{3}[ .-]?\d{4}$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;^&lt;/code&gt; and &lt;code&gt;$&lt;/code&gt; anchor the pattern to the entire string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(\+1\s?)?&lt;/code&gt; – Optionally match “+1” followed by an optional space.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(?:\(\d{3}\)|\d{3})&lt;/code&gt; – Either three digits inside parentheses or three digits without.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[ .-]?&lt;/code&gt; – Optionally match a space, a dot, or a hyphen.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\d{3}&lt;/code&gt; – Three digits.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[ .-]?&lt;/code&gt; – Separator again.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;\d{4}&lt;/code&gt; – Four digits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This pattern will match most common North American formats. By tweaking the groups and quantifiers, you can adapt it for other regions or stricter/looser rules.&lt;/p&gt;
&lt;h4 id=&quot;3-9-practical-example-parsing-log-files&quot;&gt;3.9 Practical Example: Parsing Log Files&lt;/h4&gt;
&lt;p&gt;Returning to our log example, suppose you want to extract &lt;strong&gt;only&lt;/strong&gt; the warning messages and their timestamps. You might apply a regex like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[Warning\]\s+(.*)$
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Group 1&lt;/strong&gt; captures the timestamp (&lt;code&gt;2025-05-31 14:23:55&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Group 2&lt;/strong&gt; captures the message itself (&lt;code&gt;Missing font file: New Times Roman.&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In most programming languages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt; (using &lt;code&gt;System.Text.RegularExpressions&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;var pattern = @&quot;^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[Warning\]\s+(.*)$&quot;;
var matches = Regex.Matches(logContents, pattern, RegexOptions.Multiline);
foreach (Match m in matches) {
    string timestamp = m.Groups[1].Value;
    string message   = m.Groups[2].Value;
    Console.WriteLine($&quot;[{timestamp}] Warning: {message}&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt; (using the &lt;code&gt;re&lt;/code&gt; module):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import re

pattern = r'^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2})\s+\[Warning\]\s+(.*)$'
for line in log_contents.splitlines():
    m = re.match(pattern, line)
    if m:
        timestamp = m.group(1)
        message   = m.group(2)
        print(f&quot;[{timestamp}] Warning: {message}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even if you’ve only ever clicked “Replace” in an editor, these examples should give you a clear sense of how powerful a single regex can be. You define &lt;strong&gt;“match everything up until &lt;code&gt;[&lt;/code&gt;Warning&lt;code&gt;]&lt;/code&gt;, then capture whatever comes next”&lt;/strong&gt;, and you get exactly the data you want.&lt;/p&gt;
&lt;h4 id=&quot;3-10-testing-and-debugging-regex&quot;&gt;3.10 Testing and Debugging Regex&lt;/h4&gt;
&lt;p&gt;When you’re new to regex, it’s easy to overlook small mistakes - missing an escape, misplacing a quantifier, forgetting an anchor. Here are a few tips:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use an Online Tester&lt;/strong&gt;&lt;br&gt;
Websites like &lt;a rel=&quot;nofollow&quot; href=&quot;https://regex101.com&quot;&gt;regex101.com&lt;/a&gt; (PCRE, JavaScript, Python), &lt;a rel=&quot;nofollow&quot; href=&quot;http://regexstorm.net/tester&quot;&gt;RegexStorm&lt;/a&gt; (for .NET), or &lt;a rel=&quot;nofollow&quot; href=&quot;https://regexr.com&quot;&gt;regexr.com&lt;/a&gt; let you type your pattern, paste test text, and see matches/highlights in real time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start Simple, Then Grow&lt;/strong&gt;&lt;br&gt;
If you need a complex pattern, start with a small piece. For instance, test just &lt;code&gt;\d{4}-\d{2}-\d{2}&lt;/code&gt; on the date first, then add time, then add log level, etc.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comment Your Patterns&lt;/strong&gt; (When Supported)&lt;br&gt;
Some languages/flavors support the “extended” or “free-spacing” mode, where you can add whitespace and &lt;code&gt;# comments&lt;/code&gt; inside your regex:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(?x)            # Enable free-spacing mode
^               # Start of line
(\d{4}-\d{2}-\d{2})   # Group 1: Date
\s+             # One or more spaces
(\d{2}:\d{2}:\d{2})   # Group 2: Time
\s+             # One or more spaces
\[Warning\]     # Literal [Warning]
\s+             # One or more spaces
(.*)            # Group 3: Message text
$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes maintenance and future edits easier, especially for complex regexes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Escape Early&lt;/strong&gt;&lt;br&gt;
If you need to match special characters (&lt;code&gt;.&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;[&lt;/code&gt;, &lt;code&gt;]&lt;/code&gt;, &lt;code&gt;(&lt;/code&gt;, &lt;code&gt;)&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;$&lt;/code&gt;, &lt;code&gt;\&lt;/code&gt;), always escape them with a backslash unless you explicitly want their special behavior.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;4-comprehensive-reference&quot;&gt;4. Comprehensive Reference&lt;/h3&gt;
&lt;p&gt;Omitted due to content length limit. Visit &lt;a rel=&quot;nofollow&quot; href=&quot;https://wiki.methodox.io/en/KnowledgeBase/Regex&quot;&gt;Methodox Wiki&lt;/a&gt; for more.&lt;/p&gt;
&lt;h3 id=&quot;5-conclusion&quot;&gt;5. Conclusion&lt;/h3&gt;
&lt;p&gt;By now you should have a solid grasp of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Why&lt;/strong&gt; regular expressions are invaluable for text processing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How&lt;/strong&gt; to write basic patterns: literals, character classes, quantifiers, anchors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How&lt;/strong&gt; to use groups, lookarounds, and backreferences for more advanced matching.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Which&lt;/strong&gt; tokens and constructs constitute the “core” of most practical regexes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Where&lt;/strong&gt; to look when you need to refresh your memory (the reference section above, or a site like &lt;a rel=&quot;nofollow&quot; href=&quot;http://regexstorm.net/reference&quot;&gt;regexstorm.net/reference&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With a few dozen minutes of practice - writing regexes against sample text - you’ll rapidly gain confidence. Remember:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Test early and often&lt;/strong&gt; in an online tester or your IDE’s “Find in Files” - seeing the matches in real time is far more enlightening than manually eyeballing code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Readability matters.&lt;/strong&gt; If the pattern becomes unreadable, use the free-spacing mode (&lt;code&gt;(?x)&lt;/code&gt;) and add comments.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep it simple&lt;/strong&gt; for common tasks. You rarely need the most arcane syntax; matching log levels, dates, email addresses, or basic CSV fields can usually be done with straightforward character classes and quantifiers.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Once you’ve mastered the basics, you can explore more advanced topics like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Atomic grouping&lt;/strong&gt; and &lt;strong&gt;possessive quantifiers&lt;/strong&gt; (for performance-critical patterns).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Recursive patterns&lt;/strong&gt; (in PCRE or some advanced flavors) to match nested constructs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conditional subpatterns&lt;/strong&gt; (in PCRE or .NET) where you test if a group has matched before deciding the next part of the pattern.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But those are topics for another day. For now, lean on the examples and reference sheet above, and try applying regex to your next text‑processing challenge. In no time, you’ll find yourself thinking in patterns - and you won’t look back.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Congratulations on starting your pattern crafting journey! Keep this guide handy, bookmark your favorite regex tester, and remember that a well‑written regular expression often turns hours of manual parsing into a single line of elegant code.&lt;/em&gt;&lt;/p&gt;
&lt;h4 id=&quot;references-1&quot;&gt;References&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;http://regexstorm.net/&quot;&gt;RegStorm for C#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>Syntax Basics</category>
<guid isPermaLink="true">https://coderlegion.com/3193/regular-expression-a-comprehensive-guide</guid>
<pubDate>Mon, 02 Jun 2025 23:03:31 +0000</pubDate>
</item>
<item>
<title>SQL - A Quick Intro</title>
<link>https://coderlegion.com/3192/sql-a-quick-intro</link>
<description>&lt;h2 id=&quot;sql---a-quick-intro&quot;&gt;SQL - A Quick Intro&lt;/h2&gt;
&lt;h3 id=&quot;overview-2&quot;&gt;Overview&lt;/h3&gt;
&lt;p&gt;In this article, we’ll walk through the essentials of SQL using the SQLite dialect. We’ll start by creating a couple of sample tables and populating them with data. These tables will serve as the foundation for our examples in later sections. By the end of this overview, you will have a simple schema to work with and understand how to set the scene for common SQL operations.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Create a table for users
CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    username TEXT NOT NULL,
    email TEXT NOT NULL,
    joined_date TEXT NOT NULL  -- stored as ISO-8601 strings in SQLite
);

-- Create a table for orders
CREATE TABLE IF NOT EXISTS orders (
    id INTEGER PRIMARY KEY,
    user_id INTEGER NOT NULL,
    product TEXT NOT NULL,
    quantity INTEGER NOT NULL,
    order_date TEXT NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

-- Insert sample data into users
INSERT INTO users (username, email, joined_date) VALUES
    ('alice', '*Emails are not allowed*', '2023-01-15'),
    ('bob', '*Emails are not allowed*', '2023-02-10'),
    ('carol', '*Emails are not allowed*', '2023-03-05');

-- Insert sample data into orders
INSERT INTO orders (user_id, product, quantity, order_date) VALUES
    (1, 'Keyboard', 2, '2023-04-01'),
    (1, 'Mouse', 1, '2023-04-07'),
    (2, 'Monitor', 1, '2023-04-15'),
    (3, 'Desk Lamp', 3, '2023-05-02'),
    (2, 'USB Cable', 5, '2023-05-10');
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These two tables - &lt;strong&gt;users&lt;/strong&gt; and &lt;strong&gt;orders&lt;/strong&gt; - will be the basis for our queries. Feel free to run these statements in an SQLite environment (e.g., the &lt;code&gt;sqlite3&lt;/code&gt; CLI or any GUI tool) to experiment with the examples that follow.&lt;/p&gt;
&lt;h3 id=&quot;common-syntax&quot;&gt;Common Syntax&lt;/h3&gt;
&lt;p&gt;In this section, we’ll introduce the four most common SQL statements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SELECT&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DELETE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;INSERT&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We’ll focus on the typical usage patterns for each statement without covering every possible option or keyword. All SQL keywords are shown in uppercase by convention - this is a good practice. However, they are usually case-insensitive to the SQL engine.&lt;/p&gt;
&lt;h4 id=&quot;1-select&quot;&gt;1. SELECT&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;SELECT&lt;/code&gt; statement is used to retrieve data from one or more tables. At its simplest, you specify the columns you want and the table from which to retrieve them:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT id, username, email
FROM users;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want all columns, use &lt;code&gt;*&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT *
FROM orders;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can filter results using &lt;code&gt;WHERE&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT username, email
FROM users
WHERE joined_date &amp;gt;= '2023-02-01';
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To sort results, use &lt;code&gt;ORDER BY&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT id, product, quantity, order_date
FROM orders
WHERE quantity &amp;gt; 1
ORDER BY order_date DESC;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Limit the number of rows returned:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT *
FROM orders
LIMIT 3;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Combine clauses:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT username, email
FROM users
WHERE username LIKE 'a%'
ORDER BY joined_date;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;LIKE&lt;/code&gt; keyword here matches all names starting with an &lt;code&gt;a&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;2-update&quot;&gt;2. UPDATE&lt;/h4&gt;
&lt;p&gt;Use &lt;code&gt;UPDATE&lt;/code&gt; to modify existing rows. Always include a &lt;code&gt;WHERE&lt;/code&gt; clause to avoid updating every row unintentionally:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Change Bob's email address
UPDATE users
SET email = '*Emails are not allowed*'
WHERE username = 'bob';
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can update multiple columns at once:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;UPDATE users
SET email = '*Emails are not allowed*',
    joined_date = '2023-01-20'
WHERE username = 'alice';
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s good practice to run a &lt;code&gt;SELECT&lt;/code&gt; with the same &lt;code&gt;WHERE&lt;/code&gt; first:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT * FROM users WHERE username = 'alice';
-- Review the row, then:
UPDATE users
SET email = '*Emails are not allowed*'
WHERE username = 'alice';
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-delete&quot;&gt;3. DELETE&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;DELETE&lt;/code&gt; statement removes rows from a table. Again, a &lt;code&gt;WHERE&lt;/code&gt; clause is essential:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Delete Carol's record
DELETE FROM users
WHERE username = 'carol';
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To delete all rows in a table (but keep the table structure):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;DELETE FROM orders;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SQLite supports &lt;code&gt;DELETE FROM table_name;&lt;/code&gt; without &lt;code&gt;WHERE&lt;/code&gt; to remove every row. If you only want to remove specific rows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;DELETE FROM orders
WHERE order_date &amp;lt; '2023-04-01';
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;4-insert&quot;&gt;4. INSERT&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;INSERT&lt;/code&gt; adds new rows into a table. We already used this in the overview to populate &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;orders&lt;/code&gt;. The basic syntax specifies columns and values:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;INSERT INTO users (username, email, joined_date)
VALUES ('dave', '*Emails are not allowed*', '2023-06-01');
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can omit the column list if you supply values for every column in the exact order:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;INSERT INTO orders VALUES (NULL, 4, 'Webcam', 2, '2023-06-02');
-- NULL for id since it's an AUTOINCREMENT primary key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to insert from another table (a simple form of &lt;code&gt;SELECT&lt;/code&gt; inside &lt;code&gt;INSERT&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;INSERT INTO orders (user_id, product, quantity, order_date)
SELECT id, 'Headphones', 1, '2023-06-05'
FROM users
WHERE username = 'bob';
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;techniques&quot;&gt;Techniques&lt;/h3&gt;
&lt;p&gt;The examples above covered basic CRUD operations. In this section, we’ll focus on more advanced - but frequently used - &lt;code&gt;SELECT&lt;/code&gt; patterns in SQLite, including implicit joins, explicit joins, Common Table Expressions (&lt;code&gt;WITH&lt;/code&gt;), and subqueries. These techniques are particularly helpful when you need to combine data from multiple tables or derive aggregated results.&lt;/p&gt;
&lt;h4 id=&quot;1-implicit-join-using-multiple-tables-in-from&quot;&gt;1. Implicit Join Using Multiple Tables in FROM&lt;/h4&gt;
&lt;p&gt;An implicit join (sometimes called a “comma join”) lists multiple tables in the &lt;code&gt;FROM&lt;/code&gt; clause and specifies the join condition in &lt;code&gt;WHERE&lt;/code&gt;. This style is concise but can be less clear for complex queries:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- List every order along with the username of the user who placed it
SELECT u.username, o.product, o.quantity, o.order_date
FROM users u, orders o
WHERE u.id = o.user_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, &lt;code&gt;u&lt;/code&gt; is an alias for &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;o&lt;/code&gt; is an alias for &lt;code&gt;orders&lt;/code&gt;. The join condition &lt;code&gt;u.id = o.user_id&lt;/code&gt; ties rows in &lt;code&gt;users&lt;/code&gt; to matching rows in &lt;code&gt;orders&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can add filters:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Only orders with quantity &amp;gt; 1
SELECT u.username, o.product, o.quantity
FROM users u, orders o
WHERE u.id = o.user_id
  AND o.quantity &amp;gt; 1
ORDER BY o.order_date;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-explicit-join-syntax-inner-join-left-join-&quot;&gt;2. Explicit Join Syntax (INNER JOIN, LEFT JOIN)&lt;/h4&gt;
&lt;p&gt;SQLite supports the standard explicit &lt;code&gt;JOIN&lt;/code&gt; syntax, which is recommended for clarity:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- INNER JOIN retrieves only matching rows
SELECT u.username, o.product, o.order_date
FROM users u
INNER JOIN orders o
    ON u.id = o.user_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For a left (or left outer) join, which returns all rows from the left table and matching rows (if any) from the right table:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- List all users, including those who have not placed orders
SELECT u.username, o.product, o.order_date
FROM users u
LEFT JOIN orders o
    ON u.id = o.user_id;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If a user has no matching &lt;code&gt;orders&lt;/code&gt;, the &lt;code&gt;product&lt;/code&gt; and &lt;code&gt;order_date&lt;/code&gt; columns will be &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Multiple Joins&lt;/strong&gt;&lt;br&gt;
When you have more than two tables, chain the joins together:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Suppose we add a table for payment info
CREATE TABLE IF NOT EXISTS payments (
    id INTEGER PRIMARY KEY,
    order_id INTEGER NOT NULL,
    amount REAL NOT NULL,
    payment_date TEXT NOT NULL,
    FOREIGN KEY (order_id) REFERENCES orders(id)
);

-- Sample data
INSERT INTO payments (order_id, amount, payment_date) VALUES
    (1, 49.98, '2023-04-02'),
    (2, 19.99, '2023-04-08'),
    (3, 149.99, '2023-04-16');

-- Query: find username, product, and payment amount for each paid order
SELECT u.username,
       o.product,
       p.amount,
       p.payment_date
FROM users u
INNER JOIN orders o
    ON u.id = o.user_id
INNER JOIN payments p
    ON o.id = p.order_id
ORDER BY p.payment_date;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-with-clause-common-table-expressions-&quot;&gt;3. WITH Clause (Common Table Expressions)&lt;/h4&gt;
&lt;p&gt;A Common Table Expression (CTE) defined by &lt;code&gt;WITH&lt;/code&gt; allows you to create a temporary, named result set that you can reference in a subsequent query. This is useful for breaking complex queries into more readable pieces.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Example: Find users who have spent more than $50 in total
WITH user_totals AS (
    SELECT u.id AS user_id,
           u.username,
           SUM(p.amount) AS total_spent
    FROM users u
    INNER JOIN orders o
        ON u.id = o.user_id
    INNER JOIN payments p
        ON o.id = p.order_id
    GROUP BY u.id, u.username
)
SELECT username, total_spent
FROM user_totals
WHERE total_spent &amp;gt; 50;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The CTE named &lt;code&gt;user_totals&lt;/code&gt; aggregates total spending per user.&lt;/li&gt;
&lt;li&gt;The outer &lt;code&gt;SELECT&lt;/code&gt; filters users based on their aggregated spending.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;CTEs can be &lt;strong&gt;recursive&lt;/strong&gt; as well, but for a quick intro, focus on non-recursive CTEs.&lt;/p&gt;
&lt;h4 id=&quot;4-subqueries&quot;&gt;4. Subqueries&lt;/h4&gt;
&lt;p&gt;Subqueries (also called inner queries or nested queries) are queries embedded inside other SQL statements. They can appear in the &lt;code&gt;SELECT&lt;/code&gt; list, &lt;code&gt;FROM&lt;/code&gt; clause, or &lt;code&gt;WHERE&lt;/code&gt; clause.&lt;/p&gt;
&lt;h5 id=&quot;4-1-subquery-in-select-list&quot;&gt;4.1 Subquery in SELECT List&lt;/h5&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Add a column showing the number of orders each user has placed
SELECT u.username,
       u.email,
       (
           SELECT COUNT(*)
           FROM orders o
           WHERE o.user_id = u.id
       ) AS order_count
FROM users u;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The subquery &lt;code&gt;(SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id)&lt;/code&gt; executes for each row in &lt;code&gt;users&lt;/code&gt;.&lt;/p&gt;
&lt;h5 id=&quot;4-2-subquery-in-where-clause&quot;&gt;4.2 Subquery in WHERE Clause&lt;/h5&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Find users who have never placed an order
SELECT username, email
FROM users
WHERE id NOT IN (
    SELECT DISTINCT user_id
    FROM orders
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Alternatively, using &lt;code&gt;NOT EXISTS&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT username, email
FROM users u
WHERE NOT EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.user_id = u.id
);
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&quot;4-3-subquery-in-from-clause&quot;&gt;4.3 Subquery in FROM Clause&lt;/h5&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Join users to a derived table that calculates order counts
SELECT t.username, t.order_count
FROM (
    SELECT u.id AS user_id,
           u.username,
           COUNT(o.id) AS order_count
    FROM users u
    LEFT JOIN orders o
        ON u.id = o.user_id
    GROUP BY u.id, u.username
) AS t
WHERE t.order_count &amp;gt;= 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, the subquery in the &lt;code&gt;FROM&lt;/code&gt; clause (aliased as &lt;code&gt;t&lt;/code&gt;) computes the number of orders per user. The outer query then filters on &lt;code&gt;order_count&lt;/code&gt;.&lt;/p&gt;
&lt;h4 id=&quot;5-aggregation-and-group-by&quot;&gt;5. Aggregation and GROUP BY&lt;/h4&gt;
&lt;p&gt;While technically a part of &lt;code&gt;SELECT&lt;/code&gt; patterns, aggregation is so common that it merits a dedicated mention:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Total quantity ordered per product
SELECT product,
       SUM(quantity) AS total_quantity
FROM orders
GROUP BY product
ORDER BY total_quantity DESC;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&quot;having&quot;&gt;HAVING&lt;/h5&gt;
&lt;p&gt;To filter on aggregated values, use &lt;code&gt;HAVING&lt;/code&gt; rather than &lt;code&gt;WHERE&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;-- Only products with total quantity &amp;gt; 2
SELECT product,
       SUM(quantity) AS total_quantity
FROM orders
GROUP BY product
HAVING total_quantity &amp;gt; 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;6-putting-it-all-together&quot;&gt;6. Putting It All Together&lt;/h4&gt;
&lt;p&gt;Let’s combine a few of these techniques into a more comprehensive example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We want to list each user, their total number of orders, total quantity ordered, and their most recent order date.&lt;/li&gt;
&lt;li&gt;Only include users who have placed at least one order.&lt;/li&gt;
&lt;li&gt;Sort by total quantity descending.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;WITH user_orders AS (
    SELECT u.id    AS user_id,
           u.username,
           COUNT(o.id)           AS order_count,
           SUM(o.quantity)       AS total_quantity,
           MAX(o.order_date)     AS last_order_date
    FROM users u
    INNER JOIN orders o
        ON u.id = o.user_id
    GROUP BY u.id, u.username
)
SELECT username,
       order_count,
       total_quantity,
       last_order_date
FROM user_orders
WHERE order_count &amp;gt;= 1
ORDER BY total_quantity DESC;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Explanation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The CTE &lt;code&gt;user_orders&lt;/code&gt; aggregates order-related metrics per user.&lt;/li&gt;
&lt;li&gt;The outer query filters out users with zero orders and sorts the results.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;putting-it-into-practice&quot;&gt;Putting It into Practice&lt;/h3&gt;
&lt;p&gt;Here are a few additional examples and variations you might find useful in everyday data analysis with SQLite:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Top 3 Users by Total Spending&lt;/strong&gt;&lt;br&gt;
Combine payments and orders to rank users.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;WITH spending AS (
    SELECT u.id         AS user_id,
           u.username,
           SUM(p.amount) AS total_spent
    FROM users u
    INNER JOIN orders o
        ON u.id = o.user_id
    INNER JOIN payments p
        ON o.id = p.order_id
    GROUP BY u.id, u.username
)
SELECT username, total_spent
FROM spending
ORDER BY total_spent DESC
LIMIT 3;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Find Orders with No Payment Records&lt;/strong&gt;&lt;br&gt;
Use a left join and look for &lt;code&gt;NULL&lt;/code&gt; in the payment side.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;SELECT o.id AS order_id,
       u.username,
       o.product,
       o.order_date
FROM orders o
LEFT JOIN payments p
    ON o.id = p.order_id
INNER JOIN users u
    ON o.user_id = u.id
WHERE p.id IS NULL;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Update via Subquery&lt;/strong&gt;&lt;br&gt;
Suppose we want to mark users who joined before a certain date as “legacy” in a new column. First, add a column:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;ALTER TABLE users ADD COLUMN status TEXT DEFAULT 'active';

UPDATE users
SET status = 'legacy'
WHERE joined_date &amp;lt; '2023-02-01';
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Delete Based on a Joined Condition&lt;/strong&gt;&lt;br&gt;
If you needed to delete payments for orders that were canceled (imagine a hypothetical &lt;code&gt;orders.status = 'canceled'&lt;/code&gt; column), you could write:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;DELETE FROM payments
WHERE order_id IN (
    SELECT id
    FROM orders
    WHERE status = 'canceled'
);
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nested CTEs&lt;/strong&gt;&lt;br&gt;
Chain multiple CTEs to break down a complex problem:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;WITH recent_orders AS (
    SELECT *
    FROM orders
    WHERE order_date &amp;gt;= '2023-04-01'
),
recent_payments AS (
    SELECT o.id     AS order_id,
           o.user_id,
           p.amount,
           p.payment_date
    FROM recent_orders o
    INNER JOIN payments p
        ON o.id = p.order_id
)
SELECT u.username,
       SUM(rp.amount) AS recent_spending
FROM users u
INNER JOIN recent_payments rp
    ON u.id = rp.user_id
GROUP BY u.username
ORDER BY recent_spending DESC;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;conclusion-2&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This article has introduced the basics of SQL using the SQLite dialect, focusing on the most common statements - &lt;strong&gt;SELECT&lt;/strong&gt;, &lt;strong&gt;UPDATE&lt;/strong&gt;, &lt;strong&gt;DELETE&lt;/strong&gt;, and &lt;strong&gt;INSERT&lt;/strong&gt; - as well as several useful &lt;code&gt;SELECT&lt;/code&gt; techniques. You now have a schema with &lt;code&gt;users&lt;/code&gt;, &lt;code&gt;orders&lt;/code&gt;, and &lt;code&gt;payments&lt;/code&gt; to experiment with, and you’ve seen how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create tables and insert data.&lt;/li&gt;
&lt;li&gt;Perform simple CRUD operations.&lt;/li&gt;
&lt;li&gt;Join tables both implicitly and explicitly.&lt;/li&gt;
&lt;li&gt;Use Common Table Expressions (&lt;code&gt;WITH&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Write subqueries in various parts of a statement.&lt;/li&gt;
&lt;li&gt;Aggregate data and filter with &lt;code&gt;HAVING&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These examples should provide a solid foundation for everyday data analysis tasks. As you become more comfortable, you can explore advanced topics like window functions, triggers, and indexing strategies in SQLite.&lt;/p&gt;
</description>
<category>Data Science</category>
<guid isPermaLink="true">https://coderlegion.com/3192/sql-a-quick-intro</guid>
<pubDate>Mon, 02 Jun 2025 23:03:06 +0000</pubDate>
</item>
<item>
<title>Python Syntax</title>
<link>https://coderlegion.com/174/python-syntax</link>
<description>&lt;h2&gt;A. Introduction&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Python syntax&lt;/strong&gt; is the language grammar or structure of expressions or statements that are read by the Python parser before executing the full code. Python &lt;strong&gt;tokenizes the source code into keywords, operators, identifiers, etc&lt;/strong&gt; to quickly determine if its syntax is correct. If there is an error, python would raise technically an exception called &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/exceptions.html#SyntaxError&quot; target=&quot;_blank&quot;&gt;SyntaxError&lt;/a&gt; along with its equivalent error message. Through this error detection, it saves computer resources by holding the full code execution.&lt;/p&gt;
&lt;p&gt;In subsequent sections, I will present example codes that illustrate correct syntax. Use of &lt;strong&gt;indentation&lt;/strong&gt; to form a block of code, variable namings, basic data type usage, function and class definitions and others.&lt;/p&gt;
&lt;h2&gt;B. Indentation&lt;/h2&gt;
&lt;p&gt;Python uses indentations to define blocks of code. A block of code starts with indentation and ends with the first unindented line. The amount of indentation usually consists of four spaces and must be consistent throughout that block.&lt;/p&gt;
&lt;p&gt;Bad indentation raises the &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.python.org/3/library/exceptions.html#IndentationError&quot; target=&quot;_blank&quot;&gt;IndentationError&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;1. Indentation from if/else statement&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;country = input('Please enter your country: ')
if country == 'USA':
    print(f'Your beautiful country is {country}')
else:
    print(f'Your country is {country}')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=8926219421780463666&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;2. Indentation from for loop&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;fruits.py&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;for fruit in [('mango', 'yellow'), ('apple', 'red'), ('avocado', 'green')]:
    print(fruit[0])
    print(f'color: {fruit[1]}')
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Execute the script in the terminal&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python fruits.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mango
color: yellow
apple
color: red
avocado
color: green
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Indentation from a function&lt;/h3&gt;
&lt;p&gt;Functions are used to organize code statements. All functions use an indentation. Here is an example of writing a correct syntax for functions.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def get_car_brand_names():
    cars = ['Toyota', 'Ford', 'Ferrari']
    new_car = 'Honda'
    cars.append(new_car)
    return cars

car_brands = get_car_brand_names()
print(car_brands)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. More than one level of Indentation&lt;/h3&gt;
&lt;p&gt;Python can handle multiple levels of indentations. A good programming practice however is to limit it to two to maintain readability.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;status.py&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;gender = 'male'
age = 24
if gender == 'male':
    if age &amp;gt;= 18:
        print('male adult')
    else:
        print('male teenager')
else:
    print('female')
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. Do not mix the number of spaces in indentations&lt;/h3&gt;
&lt;p&gt;This is bad.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;if gender == 'male':
      if age &amp;gt;= 18:
        print('male adult')
    else:
        print('male teenager')
else:
      print('female')
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. Indentations from space and tab&lt;/h3&gt;
&lt;p&gt;Indentation can be created in two ways.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;space - using the space bar on your keyboard&lt;/li&gt;
&lt;li&gt;tab - using the tab key on your keyboard&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Guide&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To create an indentation by four spaces, just press your space bar 4 times.&lt;/li&gt;
&lt;li&gt;For tab indentation you need to check your code editor how many spaces are set to create a single tab. In Python a tab is represented by a character &lt;code&gt;\t&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Do not mix tab and space usage to avoid errors. If you are using spaces, always use it. And if you use tabs, always use it as well.&lt;/li&gt;
&lt;li&gt;The most common and recommended way is to use a space and it should be 4 spaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;C. Statement Termination&lt;/h2&gt;
&lt;p&gt;A statement or expression is terminated by a newline character &lt;code&gt;'\n'&lt;/code&gt;. Or in your code editor, just use the &lt;code&gt;enter key&lt;/code&gt;. It is non-printable.&lt;/p&gt;
&lt;h3&gt;1. Basic example&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;prog_lang_name = 'Python'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://logiclair.org/?qa=blob&amp;amp;qa_blobid=7329121649617283251&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3&gt;2. A newline character does not always mean the end of a statement&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;a. Parenthesis, Bracket and Brace&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If there are parenthesis, bracket or brace the statement does not end there. It would continue to the next line. Line statement continuations are usually used if using a single is too long.&lt;/p&gt;
&lt;div class=&quot;div-blue&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Note:&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;the line that starts with &lt;code&gt;#&lt;/code&gt; is just a comment. It does not affect the code logic.&lt;/span&gt;
&lt;/div&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# parenthesis
get_sum = (10 + 
    10 + 15)
print(get_sum)  # 35

# brace
city_list = ['Paris', 'Oslo', 'Bangkok', 'Beijing', 'Chicago', 'Amsterdam' ,
    'Tokyo', 'Brusells']

# bracket
sports_dict = {'basketball': 'ball game', 'cliff diving': 'diving', 'softball': 'bat-and-ball',
    'chess': 'board game'}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;b. Backslash or &lt;code&gt;\&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If there is a backslash or &lt;code&gt;\&lt;/code&gt; at the end of the line, that means a continuation of the statement will continue in the next line.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;get_sum = 10 + \
          10 + \
          15
print(get_sum)  # 35
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D. Variables and Data Types&lt;/h2&gt;
&lt;p&gt;Variables are containers to hold data. Data types include integers, floating-point numbers, bool, strings, and more complex types like lists, dictionaries, objects, etc.&lt;/p&gt;
&lt;h3&gt;1. Variable Names&lt;/h3&gt;
&lt;p&gt;To write a statement or code expression, the variable name must be on the left-hand side of the equal sign and its intended value must be on the right-hand side of the equal sign.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;num_computers = 25
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the English alphabet to name a variable except keywords. It is a good programming practice to use the English letters in the alphabet and underscore &lt;code&gt;_&lt;/code&gt; characters to separate words to create a variable name.&lt;/p&gt;
&lt;p&gt;Never use keywords as your variable names. Keywords are used internally by Python. They have special meanings in the language.&lt;/p&gt;
&lt;p&gt;Let us generate keywords by python script.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import keyword

python_keywords = keyword.kwlist
print(python_keywords)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;output&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await',
 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except',
 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda',
 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-red&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Caution:&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;Do not use any of these keywords as a variable, function and class names.&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;Here are some examples of correct variable namings.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;sky_color = 'blue'
planets = ['mars', 'saturn']
usd_oil_price_per_barrel = 78.5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do not use a number as a character that starts the variable name and do not use special characters such question mark, etc. The following would result to a syntax error.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;7elevel = 'good'
sun?shine = 'bright'
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. Data Types&lt;/h3&gt;
&lt;h4&gt;a. Numeric and Boolean&lt;/h4&gt;
&lt;p&gt;Python has some data types such as integers, float, complex, boolean, fraction and decimal for numeric types. Here are some syntax how to use numeric types.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;age = 24  # integer
price = 99.99  # float
cplx = 2 + 3j  # complex number
is_raining = False  # boolean can be either True or False

# Fraction
from fractions import Fraction
num = Fraction(75, 110)
print(num)  # 15/22

# Decimal
from decimal import Decimal
balance = Decimal(17.6)
print(balance)  # 17.60000000000000142108547152020037174224853515625
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;b. Sequence types&lt;/h4&gt;
&lt;p&gt;Python has some sequence types. They are list, range, tuple, binary and string data.&lt;/p&gt;
&lt;p&gt;Do not forget to separate items inside the list, range and tuple with a comma. If you fail, it will generate a syntax error.&lt;/p&gt;
&lt;p&gt;Correct usage to avoid syntax errors.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# list
game_stats = [15, 20, 18, 24]

# range
for r in range(1, 10, 2):
    print(r)

# tuple
population = (100, 600, 800)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For string and binary data, do not forget to enclose the value with single or double quotes.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# string
username = 'jupiter'
name = &quot;romelo&quot;

# binary, similar to string but with a `b` prefix.
address = b'xxx yyy zzz'

# syntax error in a string, notice the missing opening quote.
name = gina&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;E. Control Flow Statements&lt;/h2&gt;
&lt;p&gt;The usual control flow statements uses &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;elif&lt;/code&gt;, and &lt;code&gt;else&lt;/code&gt; for conditional operations, and &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;while&lt;/code&gt; loops for iteration.&lt;/p&gt;
&lt;p&gt;Here are some examples of a correct syntax in control flow statements. The things to remember here are the colon or &lt;code&gt;:&lt;/code&gt; after the &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;elif&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;while&lt;/code&gt; lines; and the indentation which we already discussed in previous section.&lt;/p&gt;
&lt;h3&gt;1. The if, elif and else example&lt;/h3&gt;
&lt;p&gt;Give an award of 5000 if a team wins a game, 1000 for even and 100 for a loss.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;result = 'win'
if result == 'win':
    award = 5000
elif result == 'even':
    award = 1000
else:
    award = 100
print(f'award: {award}')  # award: 1000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. The for loop example&lt;/h3&gt;
&lt;p&gt;Loop thru the list and print each item.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;for num in [5, 9, 1, 3]:
    print(num)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. The while loop example&lt;/h3&gt;
&lt;p&gt;Print a number as long as it is above 10. Start at 20.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;num = 20
while num &amp;gt; 10:
    print(num)
    num = num - 1
&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;div-green&quot;&gt;
&lt;span class=&quot;alert-header&quot;&gt;Tip:&lt;/span&gt;
&lt;span class=&quot;alert-body&quot;&gt;Remember to add a colon or `:` at the end of the line where there is a control flow keywords.&lt;/span&gt;
&lt;/div&gt;
&lt;h2&gt;F. Functions and Classes&lt;/h2&gt;
&lt;p&gt;Function uses the &lt;code&gt;def&lt;/code&gt; keyword followed by the function name and parentheses &lt;code&gt;()&lt;/code&gt;. Python supports both procedural and object-oriented programming (OOP). Classes are defined using the &lt;code&gt;class&lt;/code&gt; keyword.&lt;/p&gt;
&lt;h3&gt;1. A sample &lt;code&gt;add&lt;/code&gt; function&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Define a function
def add(a, b):
    total = a + b
    return total

# Use it
result = add(4, 8)
print(result)  # 12
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Things to remember to avoid syntax errors.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* Function starts with a def keyword.
* The word `add` is called an identifier or function name and must not be a keyword.
* The function name must be a single word or two or more words connected using the underscore `_`.
* We have two parameters in this example, `a` and `b`.
* The parameters are enclosed in parentheses.
* There is a colon `:` after the closing parenthesis.
* There is indentation.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. A sample Country class&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# Define a class
class Country:
    def __init__(self, name, capital):
        self.name = name
        self.capital = capital

    def info(self):
        print(f'The capital of {self.name} is {self.capital}.')

# Use it
country_info = Country('France', 'Paris')
country_info.info()  # The capital of France is Paris.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Things to remember to avoid syntax errors.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* A class definition starts with a class keyword followed by a name and ends with a colon `:`.
* The word Country is called the identifier or a class name.
* The rests are similar to the function definition.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;G. Importing Modules&lt;/h2&gt;
&lt;p&gt;Modules can be libraries of functions, classes, or variables. You use the &lt;code&gt;import&lt;/code&gt; statement to use a module.&lt;/p&gt;
&lt;p&gt;Here is an example syntax for importing a module. Teachers want to calculate the students' grade average from a given list of grades. They use Python's module called &lt;code&gt;statistics&lt;/code&gt; which has a function &lt;code&gt;mean&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import statistics

grades = [85, 90, 89, 84]
average = statistics.mean(grades)
print(f'average: {average}')  # average: 87
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;H. Exception Handling&lt;/h2&gt;
&lt;p&gt;Python uses try-except blocks to handle exceptions. Code that might raise an exception is placed in the &lt;code&gt;try&lt;/code&gt; block, and the handling of the exception is then implemented in the &lt;code&gt;except&lt;/code&gt; block. when everything is done, codes in the &lt;code&gt;finally&lt;/code&gt; block will be executed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;import random

rnum = random.randint(0, 9)
try:
    result = 5 / rnum

except ZeroDivisionError as err:
    print(&quot;Cannot divide by zero.&quot;)
    print(err)

except Exception as err:
    print(&quot;Unexpected error&quot;)
    print(err)

else:
    # without exception or error
    print(&quot;No exception occurred.&quot;)
    print(f'result: {result}')

finally:
    # This is always executed.
    print(&quot;finally block&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;I. PEP 8&lt;/h2&gt;
&lt;p&gt;Python's coding style is guided by &lt;a rel=&quot;nofollow&quot; href=&quot;https://peps.python.org/pep-0008/&quot; target=&quot;_blank&quot;&gt;PEP 8, or Python Enhancement Proposal&lt;/a&gt;. It provides guidelines and best practices on how to format Python code. This will promote code consistency and readability. There is a lot that we can learn about Python's syntax as well.&lt;/p&gt;
&lt;h2&gt;J. Summary&lt;/h2&gt;
&lt;p&gt;The article provides a comprehensive guide to &lt;strong&gt;Python syntax&lt;/strong&gt;, covering topics such as indentation, statement termination, variables, data types, control flow, functions, classes, module importing, exception handling, and adherence to &lt;strong&gt;PEP 8&lt;/strong&gt; coding standards.&lt;/p&gt;
</description>
<category>Python Basics</category>
<guid isPermaLink="true">https://coderlegion.com/174/python-syntax</guid>
<pubDate>Tue, 05 Mar 2024 12:36:11 +0000</pubDate>
</item>
</channel>
</rss>