<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jeevachaithanyan Sivanandan</title>
    <description>The latest articles on DEV Community by Jeevachaithanyan Sivanandan (@jeevanizm).</description>
    <link>https://dev.to/jeevanizm</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1179877%2F32f9ede4-86d9-4dfd-be42-86292094d126.jpg</url>
      <title>DEV Community: Jeevachaithanyan Sivanandan</title>
      <link>https://dev.to/jeevanizm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeevanizm"/>
    <language>en</language>
    <item>
      <title>How to find the current page template/view ID from the dev tools?</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Sun, 06 Jul 2025 18:04:13 +0000</pubDate>
      <link>https://dev.to/jeevanizm/how-to-find-the-current-page-templateview-id-from-the-dev-tools-35i0</link>
      <guid>https://dev.to/jeevanizm/how-to-find-the-current-page-templateview-id-from-the-dev-tools-35i0</guid>
      <description>&lt;p&gt;Often in Odoo development, we need to customize the current template view. In order to do that, we need to find the template ID of the current page and then customize it. It's easy to find information about the current template using debug mode; we can use the metadata option or edit form view. However, these are not available on website portal pages. If you want to edit such pages, you'll have to dive through the portal templates and trace up to the correct template ID, which can often take some time. There's an easier way to find the template from the browser dev tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v3x9cooyxyi8vlidxsf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v3x9cooyxyi8vlidxsf.png" alt="Image description" width="800" height="596"&gt;&lt;/a&gt;&lt;br&gt;
Let's say we need to edit the product template view page in the website portal. Just open your browser dev tools and highlight the HTML tag . You'll then see the tag data-viewID; it will have the ID of the template view. Copying this value, you can go to Settings &amp;gt; Technical &amp;gt; Views and search for this ID. You'll be able to see the template there.&lt;/p&gt;

</description>
      <category>odoo</category>
    </item>
    <item>
      <title>How to Add Custom Translations in Odoo Using .po Files</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Fri, 04 Jul 2025 15:27:02 +0000</pubDate>
      <link>https://dev.to/jeevanizm/how-to-add-custom-translations-in-odoo-using-po-files-2a50</link>
      <guid>https://dev.to/jeevanizm/how-to-add-custom-translations-in-odoo-using-po-files-2a50</guid>
      <description>&lt;p&gt;&lt;strong&gt;Step 1: Create a .po File&lt;/strong&gt;&lt;br&gt;
File Location&lt;br&gt;
Place your .po file in:&lt;/p&gt;

&lt;p&gt;/your_module/i18n/es.po  #  choose the correst lang code&lt;/p&gt;

&lt;p&gt;File Structure&lt;br&gt;
A basic .po file should include:&lt;/p&gt;

&lt;p&gt;Header (metadata)&lt;/p&gt;

&lt;p&gt;Translation entries (msgid = original text, msgstr = translated text)&lt;/p&gt;

&lt;p&gt;Example: es.po (Espanol Translations)&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
msgid ""&lt;br&gt;
msgstr ""&lt;br&gt;
"Project-Id-Version: Your Module 16.0\n"&lt;br&gt;
"Report-Msgid-Bugs-To: \n"&lt;br&gt;
"POT-Creation-Date: 2025-07-10 12:00+0000\n"&lt;br&gt;
"PO-Revision-Date: 2025-07-10 12:00+0000\n"&lt;br&gt;
"Last-Translator: Your Name &lt;a href="mailto:email@example.com"&gt;email@example.com&lt;/a&gt;\n"&lt;br&gt;
"Language-Team: Espanol&lt;a href="mailto:team@example.com"&gt;team@example.com&lt;/a&gt;\n"&lt;br&gt;
"Language: es_ES\n"&lt;br&gt;
"MIME-Version: 1.0\n"&lt;br&gt;
"Content-Type: text/plain; charset=UTF-8\n"&lt;br&gt;
"Content-Transfer-Encoding: 8bit\n"&lt;br&gt;
"Plural-Forms: nplurals=2; plural=(n != 1);\n"&lt;/p&gt;

&lt;h1&gt;
  
  
  . module: your_module
&lt;/h1&gt;

&lt;h1&gt;
  
  
  : model_terms:ir.ui.view,arch_db:your_module.your_view_id
&lt;/h1&gt;

&lt;p&gt;msgid "Customer"&lt;br&gt;
msgstr "cliente"&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;**Step 2: Ensure Your Template Uses Translatable Text&lt;br&gt;
**Option 1: Simple Text (Auto-translated)&lt;/p&gt;

&lt;p&gt;&lt;span&gt;Customer&lt;/span&gt;  &lt;/p&gt;

&lt;p&gt;**Step 3: Update &amp;amp; Load Translations&lt;br&gt;
**1. Update Your Module&lt;/p&gt;

&lt;p&gt;./odoo-bin -d your_db -u your_module --stop-after-init&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Force Reload Translations (If Needed)
./odoo-bin -d your_db -u your_module --i18n-overwrite --stop-after-init&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;**Common Issues &amp;amp; Fixes&lt;br&gt;
**Issue Solution&lt;br&gt;
Translations not loading    Ensure .po file is in /i18n/ and module is updated&lt;br&gt;
Case mismatch (e.g., Amount vs. AMOUNT) Make sure msgid matches exactly&lt;br&gt;
Missing view reference  Add model_terms:ir.ui.view in .po file&lt;/p&gt;

</description>
      <category>odoo</category>
    </item>
    <item>
      <title>git clone only particular branch</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Fri, 20 Jun 2025 12:55:48 +0000</pubDate>
      <link>https://dev.to/jeevanizm/git-clone-only-particular-branch-5ai6</link>
      <guid>https://dev.to/jeevanizm/git-clone-only-particular-branch-5ai6</guid>
      <description>&lt;p&gt;Just use the command to clone only a particular branch not all branches from a repo &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone --branch &amp;lt;branch_name&amp;gt; --single-branch &amp;lt;repository_url&amp;gt;&lt;/code&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>cli</category>
      <category>howto</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Odoo check if a module is installed or not</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Fri, 30 May 2025 08:23:01 +0000</pubDate>
      <link>https://dev.to/jeevanizm/odoo-check-if-a-module-is-installed-or-not-4e3d</link>
      <guid>https://dev.to/jeevanizm/odoo-check-if-a-module-is-installed-or-not-4e3d</guid>
      <description>&lt;p&gt;If you need to check if a website is installed or not in the database for odoo&lt;/p&gt;

&lt;p&gt;SELECT name,state FROM ir_module_module WHERE name = 'module_name';&lt;/p&gt;

</description>
      <category>odoo</category>
    </item>
    <item>
      <title>Odoo Database Table Naming Quirk</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Fri, 30 May 2025 08:20:22 +0000</pubDate>
      <link>https://dev.to/jeevanizm/odoo-database-table-naming-quirk-3i7k</link>
      <guid>https://dev.to/jeevanizm/odoo-database-table-naming-quirk-3i7k</guid>
      <description>&lt;p&gt;In Odoo, database table names typically follow a straightforward convention: they are the underscored (_) version of the model name as seen in the user interface. For example, the sale.order model corresponds to the sale_order table. However, this pattern isn't always consistent. For instance, you might expect the ir.action.server model to map to the ir_action_server table, but the actual table name is ir_act_server.&lt;/p&gt;

&lt;p&gt;This subtle naming quirk can be easy to overlook and may cause confusion when working with Odoo's database. I hope sharing this saves you time if you encounter a similar situation!&lt;/p&gt;

</description>
      <category>odoo</category>
      <category>database</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Inheritance Vs composition</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Fri, 11 Apr 2025 06:51:59 +0000</pubDate>
      <link>https://dev.to/jeevanizm/inheritance-vs-composition-4527</link>
      <guid>https://dev.to/jeevanizm/inheritance-vs-composition-4527</guid>
      <description>&lt;p&gt;Inheritance&lt;/p&gt;

&lt;p&gt;Inheritance is a mechanism in object-oriented programming (OOP) where a new class (the child class or subclass) inherits properties and methods from an existing class (the parent class or superclass).&lt;/p&gt;

&lt;p&gt;"Is-a" relationship: Inheritance models an "is-a" relationship. For example, a Dog is an Animal. The Dog class would inherit general characteristics and behaviors from the Animal class and can also have its own specific attributes and methods (like bark()).&lt;br&gt;
Code Reusability: Inheritance promotes code reusability. Common functionalities can be defined in the parent class and reused by multiple child classes, reducing code duplication.&lt;br&gt;
Extensibility: Child classes can extend or override the functionality inherited from the parent class to suit their specific needs.&lt;br&gt;
Example in Python:&lt;/p&gt;

&lt;p&gt;Python&lt;/p&gt;

&lt;p&gt;class Animal:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, name):&lt;br&gt;
        self.name = name&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def speak(self):
    print("Generic animal sound")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;class Dog(Animal):&lt;br&gt;
    def speak(self):  # Overrides the parent's speak method&lt;br&gt;
        print("Woof!")&lt;/p&gt;

&lt;p&gt;class Cat(Animal):&lt;br&gt;
    def speak(self):  # Overrides the parent's speak method&lt;br&gt;
        print("Meow!")&lt;/p&gt;

&lt;p&gt;dog = Dog("Buddy")&lt;br&gt;
cat = Cat("Whiskers")&lt;/p&gt;

&lt;p&gt;dog.speak()  # Output: Woof!&lt;br&gt;
cat.speak()  # Output: Meow!&lt;br&gt;
print(dog.name) # Output: Buddy (inherited from Animal)&lt;br&gt;
Composition&lt;/p&gt;

&lt;p&gt;Composition is a design principle in OOP where a class contains objects of other classes. Instead of inheriting behavior, the class achieves its functionality by delegating tasks to its constituent objects.&lt;/p&gt;

&lt;p&gt;"Has-a" relationship: Composition models a "has-a" relationship. For example, a Car has an Engine and Wheels. The Car class would contain instances of the Engine and Wheel classes and use their functionalities.&lt;br&gt;
Flexibility: Composition offers more flexibility than inheritance. You can easily change the behavior of a class at runtime by replacing its component objects.&lt;br&gt;
Loose Coupling: Composition leads to looser coupling between classes. Changes in one component class are less likely to affect the classes that use it (as long as the component's interface remains the same).&lt;br&gt;
Example in Python:&lt;/p&gt;

&lt;p&gt;Python&lt;/p&gt;

&lt;p&gt;class Engine:&lt;br&gt;
    def start(self):&lt;br&gt;
        print("Engine started")&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def stop(self):
    print("Engine stopped")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;class Wheels:&lt;br&gt;
    def rotate(self):&lt;br&gt;
        print("Wheels are rotating")&lt;/p&gt;

&lt;p&gt;class Car:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self):&lt;br&gt;
        self.engine = Engine()&lt;br&gt;
        self.wheels = Wheels()&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def drive(self):
    self.engine.start()
    self.wheels.rotate()
    print("Car is moving")

def park(self):
    self.engine.stop()
    print("Car parked")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;my_car = Car()&lt;br&gt;
my_car.drive()&lt;br&gt;
my_car.park()&lt;br&gt;
How Inheritance and Composition are Related&lt;/p&gt;

&lt;p&gt;Both inheritance and composition are mechanisms for achieving code reuse and building complex objects in OOP. However, they differ in their approach and the type of relationship they model:&lt;/p&gt;

&lt;p&gt;Inheritance focuses on creating a hierarchy of classes where subclasses inherit and extend the behavior of their superclasses ("is-a").&lt;br&gt;
Composition focuses on building objects by combining instances of other classes, leveraging their functionalities ("has-a").&lt;br&gt;
In many situations, you might need to choose between inheritance and composition. The principle "favor composition over inheritance" is often recommended because composition tends to lead to more flexible, maintainable, and less coupled code.&lt;/p&gt;

&lt;p&gt;However, inheritance is still valuable when there is a clear "is-a" relationship and you want to reuse and extend a well-defined base class. Sometimes, a combination of both inheritance and composition can be used effectively to model complex systems. For instance, a base class might define a general structure (inheritance), while its instances contain specialized component objects (composition) to perform specific tasks.&lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>oop</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>How to Import Packages in Go</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Sun, 02 Mar 2025 21:31:41 +0000</pubDate>
      <link>https://dev.to/jeevanizm/how-to-import-packages-in-go-1oap</link>
      <guid>https://dev.to/jeevanizm/how-to-import-packages-in-go-1oap</guid>
      <description>&lt;p&gt;When a Go project grows larger, it becomes necessary to access functions and variables from different packages. In Go, we can do this using the import statement.&lt;/p&gt;

&lt;p&gt;Project Structure Example&lt;/p&gt;

&lt;p&gt;Consider we have a project structure as below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MainFolder/&lt;br&gt;
│── FolderA/&lt;br&gt;
│── FolderB/&lt;br&gt;
│── FolderC/&lt;br&gt;
│── main.go&lt;br&gt;
│── go.mod&lt;br&gt;
│── go.sum&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FolderA has a function → FunctionA

FolderB has a function → FunctionB

FolderC has a function → FunctionC

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

&lt;/div&gt;



&lt;p&gt;Importing a Package in main.go&lt;/p&gt;

&lt;p&gt;If we need to use FunctionA inside main.go, we import the package as follows:&lt;br&gt;
&lt;/p&gt;

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

import (
    "MainFolder/FolderA" // Importing FolderA package
)

func main() {
    // Now we can access functions from FolderA
    FolderA.SampleFunction2() // ✅ This works because it starts with an uppercase letter
    FolderA.sampleFunction1() // ❌ Error: Unexported function (starts with lowercase)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This rule also applies to struct fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type User struct {
    Name  string  // Exported
    age   int     // Unexported
}

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

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Exported vs Unexported Functions&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Functions that start with an uppercase letter (SampleFunction2()) are exported and can be accessed from other packages.&lt;/p&gt;

&lt;p&gt;Functions that start with a lowercase letter (sampleFunction1()) are unexported and can only be accessed within the same package.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Example: Correct Function Declarations in FolderA/a.go&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package FolderA // Package name should match the folder name

// Exported function (accessible from other packages)
func SampleFunction2() {
    // Function logic
}

// Unexported function (only accessible within the same package)
func sampleFunction1() {
    // Function logic
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Accessing Another Package from FolderA (Using FolderB's Function in FolderA)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, let's say we need to call FunctionB from FolderB inside FolderA/a.go:&lt;/p&gt;

&lt;p&gt;Correct way to import and use FunctionB in FolderA/a.go&lt;/p&gt;

&lt;p&gt;package FolderA&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "MainFolder/FolderB"

func sampleFunction1() {
    FolderB.FunctionB() // ✅ Correct usage
}

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

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Accessing Global Variables from Another Package&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
If FolderC contains a global variable like DbPass, we can access it from FolderA as follows:&lt;/p&gt;

&lt;p&gt;Example: Using Global Variables from FolderC in FolderA/a.go&lt;br&gt;
&lt;/p&gt;

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

import (
    "MainFolder/FolderB"
    "MainFolder/FolderC"
)

func sampleFunction1() {
    FolderB.FunctionB() // ✅ Function call

    // Accessing a global variable from FolderC
    if FolderC.DbPass == "some value" { // ✅ Variable must start with an uppercase letter
        // Do something
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key Takeaways&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Package Naming Conventions: The package name should match the folder name (e.g., package FolderA inside FolderA/).&lt;/li&gt;
&lt;li&gt;Exported Functions and Variables: Functions and variables that need to be accessed from other packages must start with an uppercase letter.&lt;/li&gt;
&lt;li&gt;Lowercase Functions and Variables: Functions and variables that start with lowercase letters are private to the package.&lt;/li&gt;
&lt;li&gt;Importing a Package: Use import "MainFolder/FolderX" to access other packages in the project.&lt;/li&gt;
&lt;li&gt;Calling a Function from Another Package: Use PackageName.FunctionName() syntax.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
    </item>
    <item>
      <title>odoo redirect /shop page</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Fri, 28 Feb 2025 08:54:45 +0000</pubDate>
      <link>https://dev.to/jeevanizm/odoo-redirect-shop-page-3l5j</link>
      <guid>https://dev.to/jeevanizm/odoo-redirect-shop-page-3l5j</guid>
      <description>&lt;p&gt;if you want to redirect Odoo /shop page to /products&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
   &amp;lt;template id="redirect_shop_to_products" inherit_id="website_sale.product"&amp;gt;&lt;br&gt;
        &amp;lt;xpath expr="//li[@class='breadcrumb-item o_not_editable']/a" position="attributes"&amp;gt;&lt;br&gt;
            &amp;lt;attribute name="t-att-href"&amp;gt;keep('/products', category=0)&amp;lt;/attribute&amp;gt;&lt;br&gt;
        &amp;lt;/xpath&amp;gt;&lt;br&gt;
    &amp;lt;/template&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
`&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Python Program for a Turing Machine Simulator python Copy code</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Sun, 22 Dec 2024 11:51:50 +0000</pubDate>
      <link>https://dev.to/jeevanizm/python-program-for-a-turing-machine-simulator-python-copy-code-5a3j</link>
      <guid>https://dev.to/jeevanizm/python-program-for-a-turing-machine-simulator-python-copy-code-5a3j</guid>
      <description>&lt;p&gt;class TuringMachine:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, tape, transitions, initial_state, accept_state, reject_state):&lt;br&gt;
        self.tape = list(tape)  # The tape is a list of characters&lt;br&gt;
        self.head = 0           # Head position starts at the beginning&lt;br&gt;
        self.state = initial_state&lt;br&gt;
        self.transitions = transitions&lt;br&gt;
        self.accept_state = accept_state&lt;br&gt;
        self.reject_state = reject_state&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def step(self):
    """Perform one step of the Turing machine."""
    symbol = self.tape[self.head] if self.head &amp;lt; len(self.tape) else ' '  # Read the current symbol (blank if out of bounds)

    if (self.state, symbol) in self.transitions:
        new_state, write_symbol, move = self.transitions[(self.state, symbol)]

        # Write the new symbol on the tape
        if self.head &amp;lt; len(self.tape):
            self.tape[self.head] = write_symbol
        else:
            self.tape.append(write_symbol)

        # Move the head
        if move == 'R':
            self.head += 1
        elif move == 'L':
            self.head -= 1
            if self.head &amp;lt; 0:
                self.tape.insert(0, ' ')  # Extend tape on the left

        # Update the state
        self.state = new_state
    else:
        # Transition not defined for current state and symbol
        self.state = self.reject_state

def run(self):
    """Run the Turing machine until it reaches an accept or reject state."""
    while self.state != self.accept_state and self.state != self.reject_state:
        self.step()
    return self.state == self.accept_state

def display_tape(self):
    """Display the tape and head position."""
    tape_view = ''.join(self.tape).rstrip()  # Remove trailing blanks
    print("Tape:", tape_view)
    print("Head:", ' ' * self.head + '^')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Define the Turing machine configuration
&lt;/h1&gt;

&lt;p&gt;tape = list("1011")  # Initial tape&lt;br&gt;
transitions = {&lt;br&gt;
    # (current_state, current_symbol): (new_state, write_symbol, move_direction)&lt;br&gt;
    ('q0', '1'): ('q0', '1', 'R'),&lt;br&gt;
    ('q0', '0'): ('q0', '0', 'R'),&lt;br&gt;
    ('q0', ' '): ('q_accept', ' ', 'N'),  # N: No move&lt;br&gt;
}&lt;br&gt;
initial_state = 'q0'&lt;br&gt;
accept_state = 'q_accept'&lt;br&gt;
reject_state = 'q_reject'&lt;/p&gt;
&lt;h1&gt;
  
  
  Create and run the Turing machine
&lt;/h1&gt;

&lt;p&gt;tm = TuringMachine(tape, transitions, initial_state, accept_state, reject_state)&lt;br&gt;
tm.display_tape()&lt;/p&gt;

&lt;p&gt;if tm.run():&lt;br&gt;
    print("Turing machine accepted the input.")&lt;br&gt;
else:&lt;br&gt;
    print("Turing machine rejected the input.")&lt;/p&gt;

&lt;p&gt;tm.display_tape()&lt;/p&gt;

&lt;p&gt;draft article below &lt;br&gt;
Simulating a Turing Machine in Python&lt;br&gt;
A Turing machine is a fundamental concept in computer science, representing a theoretical model of computation that defines what it means for a system to be "computable." While it's an abstract idea, we can simulate a Turing machine using Python, showcasing the language's Turing completeness.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore the basics of a Turing machine, implement a Python simulator, and test it with various examples.&lt;/p&gt;

&lt;p&gt;What is a Turing Machine?&lt;br&gt;
A Turing machine consists of:&lt;/p&gt;

&lt;p&gt;Tape: An infinitely long sequence of cells that can hold symbols. The tape serves as both input and memory.&lt;br&gt;
Head: A pointer that can read and write symbols on the tape and move left or right.&lt;br&gt;
States: The machine can be in one of many states, including an initial state, accept state, and reject state.&lt;br&gt;
Transition Rules: A set of instructions dictating what the machine does based on its current state and the symbol under the head.&lt;br&gt;
Why Simulate a Turing Machine in Python?&lt;br&gt;
Python, being a Turing-complete language, can simulate any computational process. By implementing a Turing machine in Python:&lt;/p&gt;

&lt;p&gt;You can better understand how computation works at a fundamental level.&lt;br&gt;
It serves as a practical example of Python’s computational power.&lt;br&gt;
Python Implementation of a Turing Machine&lt;br&gt;
Below is the Python code for a Turing machine simulator:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
class TuringMachine:&lt;br&gt;
    def &lt;strong&gt;init&lt;/strong&gt;(self, tape, transitions, initial_state, accept_state, reject_state):&lt;br&gt;
        self.tape = list(tape)  # The tape is a list of characters&lt;br&gt;
        self.head = 0           # Head position starts at the beginning&lt;br&gt;
        self.state = initial_state&lt;br&gt;
        self.transitions = transitions&lt;br&gt;
        self.accept_state = accept_state&lt;br&gt;
        self.reject_state = reject_state&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def step(self):
    """Perform one step of the Turing machine."""
    symbol = self.tape[self.head] if self.head &amp;lt; len(self.tape) else ' '  # Read the current symbol (blank if out of bounds)

    if (self.state, symbol) in self.transitions:
        new_state, write_symbol, move = self.transitions[(self.state, symbol)]

        # Write the new symbol on the tape
        if self.head &amp;lt; len(self.tape):
            self.tape[self.head] = write_symbol
        else:
            self.tape.append(write_symbol)

        # Move the head
        if move == 'R':
            self.head += 1
        elif move == 'L':
            self.head -= 1
            if self.head &amp;lt; 0:
                self.tape.insert(0, ' ')  # Extend tape on the left

        # Update the state
        self.state = new_state
    else:
        # Transition not defined for current state and symbol
        self.state = self.reject_state

def run(self):
    """Run the Turing machine until it reaches an accept or reject state."""
    while self.state != self.accept_state and self.state != self.reject_state:
        self.step()
    return self.state == self.accept_state

def display_tape(self):
    """Display the tape and head position."""
    tape_view = ''.join(self.tape).rstrip()  # Remove trailing blanks
    print("Tape:", tape_view)
    print("Head:", ' ' * self.head + '^')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Example: Testing the Turing Machine&lt;br&gt;
Configuration&lt;br&gt;
Let’s configure the Turing machine to read a binary string and accept it if it reaches the end without errors.&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;/p&gt;

&lt;h1&gt;
  
  
  Define the Turing machine configuration
&lt;/h1&gt;

&lt;p&gt;tape = list("1011")  # Initial tape&lt;br&gt;
transitions = {&lt;br&gt;
    # (current_state, current_symbol): (new_state, write_symbol, move_direction)&lt;br&gt;
    ('q0', '1'): ('q0', '1', 'R'),&lt;br&gt;
    ('q0', '0'): ('q0', '0', 'R'),&lt;br&gt;
    ('q0', ' '): ('q_accept', ' ', 'N'),  # N: No move&lt;br&gt;
}&lt;br&gt;
initial_state = 'q0'&lt;br&gt;
accept_state = 'q_accept'&lt;br&gt;
reject_state = 'q_reject'&lt;/p&gt;

&lt;h1&gt;
  
  
  Create and run the Turing machine
&lt;/h1&gt;

&lt;p&gt;tm = TuringMachine(tape, transitions, initial_state, accept_state, reject_state)&lt;br&gt;
tm.display_tape()&lt;/p&gt;

&lt;p&gt;if tm.run():&lt;br&gt;
    print("Turing machine accepted the input.")&lt;br&gt;
else:&lt;br&gt;
    print("Turing machine rejected the input.")&lt;/p&gt;

&lt;p&gt;tm.display_tape()&lt;br&gt;
Expected Output&lt;br&gt;
For the input 1011, the output will be:&lt;/p&gt;

&lt;p&gt;yaml&lt;br&gt;
Copy code&lt;br&gt;
Tape: 1011&lt;br&gt;
Head: ^&lt;br&gt;
Turing machine accepted the input.&lt;br&gt;
Tape: 1011&lt;br&gt;
Head:     ^&lt;br&gt;
How It Works&lt;br&gt;
The machine starts at the first position and reads the tape.&lt;br&gt;
It moves right until it encounters a blank space (' ').&lt;br&gt;
It transitions to the accept state (q_accept) and halts.&lt;br&gt;
Extending the Example&lt;br&gt;
You can extend this example to handle more complex operations. For example:&lt;/p&gt;

&lt;p&gt;Replace Symbols on the Tape&lt;br&gt;
python&lt;br&gt;
Copy code&lt;br&gt;
transitions = {&lt;br&gt;
    ('q0', '1'): ('q1', 'X', 'R'),  # Replace 1 with X&lt;br&gt;
    ('q1', '0'): ('q0', 'Y', 'R'),  # Replace 0 with Y&lt;br&gt;
    ('q1', ' '): ('q_accept', ' ', 'N'),&lt;br&gt;
}&lt;br&gt;
For tape = list("1011"), this will produce:&lt;/p&gt;

&lt;p&gt;makefile&lt;br&gt;
Copy code&lt;br&gt;
Tape: XYX1&lt;br&gt;
Head:     ^&lt;br&gt;
Turing machine accepted the input.&lt;br&gt;
Add a Reject State&lt;br&gt;
To handle invalid input, define a reject_state:&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
transitions = {&lt;br&gt;
    ('q0', '1'): ('q0', '1', 'R'),&lt;br&gt;
    ('q0', '2'): ('q_reject', '2', 'N'),  # Reject if symbol 2 is encountered&lt;br&gt;
}&lt;br&gt;
For tape = list("12"), this will produce:&lt;/p&gt;

&lt;p&gt;makefile&lt;br&gt;
Copy code&lt;br&gt;
Tape: 12&lt;br&gt;
Head: ^&lt;br&gt;
Turing machine rejected the input.&lt;br&gt;
Key Takeaways&lt;br&gt;
Simulating a Turing Machine: Python can simulate a Turing machine effectively, demonstrating its computational power.&lt;br&gt;
Understanding Computation: This program offers insights into how fundamental computation models work.&lt;br&gt;
Customization: By modifying the transition rules and tape, you can simulate various computational tasks.&lt;br&gt;
Conclusion&lt;br&gt;
This simple Turing machine simulator in Python is a great way to explore computational theory. It demonstrates how complex operations can emerge from simple rules, and it provides a platform to experiment with theoretical computer science concepts.&lt;/p&gt;

&lt;p&gt;If you want to delve deeper, consider building visualizations or extending the simulator for more advanced computations. The possibilities are endless!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Install Odoo v 17 with Python 3.12 in MSWindows 11</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Sat, 21 Dec 2024 15:09:47 +0000</pubDate>
      <link>https://dev.to/jeevanizm/install-odoo-v-17-with-python-312-in-mswindows-11-3m0m</link>
      <guid>https://dev.to/jeevanizm/install-odoo-v-17-with-python-312-in-mswindows-11-3m0m</guid>
      <description>&lt;p&gt;If you're looking to set up Odoo 17 on a Windows 11 system with Python 3.12, you might face a few compatibility challenges with dependencies. This guide provides a custom requirements.txt tailored specifically for this configuration, along with solutions for common issues during installation.&lt;/p&gt;

&lt;p&gt;Custom requirements.txt for Windows 11 with Python 3.12&lt;/p&gt;

&lt;p&gt;Below is the custom requirements.txt file that ensures Odoo 17 works seamlessly on Windows 11 with Python 3.12. This file includes compatible versions of required packages and handles Windows-specific dependencies.&lt;/p&gt;

&lt;p&gt;`# Windows 11 Compatible Requirements for Python 3.12&lt;/p&gt;

&lt;p&gt;Babel==2.10.3&lt;/p&gt;

&lt;p&gt;chardet==5.2.0&lt;/p&gt;

&lt;p&gt;cryptography==42.0.8&lt;/p&gt;

&lt;p&gt;decorator==5.1.1&lt;/p&gt;

&lt;p&gt;docutils==0.20.1&lt;/p&gt;

&lt;p&gt;ebaysdk==2.1.5&lt;/p&gt;

&lt;p&gt;freezegun==1.2.1&lt;/p&gt;

&lt;p&gt;geoip2==2.9.0&lt;/p&gt;

&lt;p&gt;gevent==24.2.1 ; sys_platform == 'win32'&lt;/p&gt;

&lt;p&gt;greenlet==3.0.3 ; sys_platform == 'win32'&lt;/p&gt;

&lt;p&gt;idna==3.6&lt;/p&gt;

&lt;p&gt;Jinja2==3.1.2&lt;/p&gt;

&lt;p&gt;libsass==0.22.0 ; sys_platform == 'win32'  # Prebuilt wheel available&lt;/p&gt;

&lt;p&gt;lxml==5.2.1&lt;/p&gt;

&lt;p&gt;lxml-html-clean ; python_version &amp;gt;= '3.12'  # Required for HTML clean in Windows&lt;/p&gt;

&lt;p&gt;MarkupSafe==2.1.5&lt;/p&gt;

&lt;p&gt;num2words==0.5.13&lt;/p&gt;

&lt;p&gt;ofxparse==0.21&lt;/p&gt;

&lt;p&gt;passlib==1.7.4&lt;/p&gt;

&lt;p&gt;Pillow==10.2.0&lt;/p&gt;

&lt;p&gt;polib==1.1.1&lt;/p&gt;

&lt;p&gt;psutil==5.9.8&lt;/p&gt;

&lt;p&gt;psycopg2==2.9.9 ; sys_platform == 'win32'&lt;/p&gt;

&lt;p&gt;pydot==1.4.2&lt;/p&gt;

&lt;p&gt;pyopenssl==24.1.0&lt;/p&gt;

&lt;p&gt;PyPDF2==2.12.1&lt;/p&gt;

&lt;p&gt;pypiwin32 ; sys_platform == 'win32'&lt;/p&gt;

&lt;p&gt;pyserial==3.5&lt;/p&gt;

&lt;p&gt;python-dateutil==2.8.2&lt;/p&gt;

&lt;p&gt;python-ldap==3.4.4 ; sys_platform == 'win32'  # Prebuilt wheel required&lt;/p&gt;

&lt;p&gt;python-stdnum==1.19&lt;/p&gt;

&lt;p&gt;pytz&lt;/p&gt;

&lt;p&gt;pyusb==1.2.1&lt;/p&gt;

&lt;p&gt;qrcode==7.4.2&lt;/p&gt;

&lt;p&gt;reportlab==4.1.0&lt;/p&gt;

&lt;p&gt;requests==2.31.0&lt;/p&gt;

&lt;p&gt;rjsmin==1.2.0&lt;/p&gt;

&lt;p&gt;rl-renderPM==4.0.3 ; sys_platform == 'win32'  # Needed by reportlab&lt;/p&gt;

&lt;p&gt;urllib3==2.0.7&lt;/p&gt;

&lt;p&gt;vobject==0.9.6.1&lt;/p&gt;

&lt;p&gt;Werkzeug==3.0.1&lt;/p&gt;

&lt;p&gt;xlrd==2.0.1&lt;/p&gt;

&lt;p&gt;XlsxWriter==3.1.9&lt;/p&gt;

&lt;p&gt;xlwt==1.3.0&lt;/p&gt;

&lt;p&gt;zeep==4.2.1&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;Handling Common Installation Issues&lt;/p&gt;

&lt;p&gt;When installing the dependencies in the requirements.txt, you might encounter the following error :&lt;/p&gt;

&lt;p&gt;&lt;code&gt;running build_ext&lt;br&gt;
building '_ldap' extension&lt;br&gt;
creating build\temp.win-amd64-cpython-312\Release\Modules&lt;br&gt;
"C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.42.34433\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DHAVE_SASL -DHAVE_TLS -DL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This error typically occurs due to missing precompiled wheels for certain dependencies, such as python-ldap. Building these dependencies from source requires additional setup, but you can bypass the issue by downloading prebuilt wheels.&lt;/p&gt;

&lt;p&gt;Solution: Install Prebuilt Wheels&lt;/p&gt;

&lt;p&gt;For Windows, prebuilt wheels can simplify the installation process significantly. Use the following steps to resolve the issue:&lt;/p&gt;

&lt;p&gt;Download Prebuilt Wheel:&lt;/p&gt;

&lt;p&gt;Go to the GitHub repository &lt;a href="https://github.com/mymy47/python-builds-for-windows/releases" rel="noopener noreferrer"&gt;https://github.com/mymy47/python-builds-for-windows/releases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Download the appropriate wheel file for python-ldap or any other dependency causing the issue.&lt;/p&gt;

&lt;p&gt;Install the Wheel:&lt;/p&gt;

&lt;p&gt;Use pip to install the wheel manually:&lt;/p&gt;

&lt;p&gt;pip install path_to_downloaded_wheel.whl&lt;br&gt;
Continue Installing Dependencies:&lt;/p&gt;

&lt;p&gt;Once the problematic dependency is resolved, install the remaining packages:&lt;/p&gt;

&lt;p&gt;pip install -r requirements.txt&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Boosting Code Quality in Odoo with Type Hints: Benefits Beyond Performance</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Mon, 11 Nov 2024 21:13:04 +0000</pubDate>
      <link>https://dev.to/jeevanizm/boosting-code-quality-in-odoo-with-type-hints-benefits-beyond-performance-2e89</link>
      <guid>https://dev.to/jeevanizm/boosting-code-quality-in-odoo-with-type-hints-benefits-beyond-performance-2e89</guid>
      <description>&lt;p&gt;As Odoo evolves, developers gain access to powerful tools like type hinting that improve code quality, readability, and maintainability. Type hints, while often mistaken as performance enhancers, primarily serve to make code easier to understand and more resilient to future changes. This article explores how type hints bring substantial benefits to Odoo development and why they are worth the effort.&lt;/p&gt;

&lt;p&gt;What Are Type Hints?&lt;br&gt;
Type hints in Python are annotations that describe the expected data type of a variable, parameter, or return value. For example, in Odoo, type hints can clarify model relationships, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;product_category_id: 'ProductCategory' = fields.Many2one(
    'product.category',
    string='Product Category',
    help='Link to the product category associated with this partner category'
)

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

&lt;/div&gt;



&lt;p&gt;This tells developers (and analysis tools) that product_category_id references a ProductCategory model.&lt;/p&gt;

&lt;p&gt;Key Benefits of Type Hints in Odoo&lt;br&gt;
Type hints significantly enhance the quality of Odoo codebases, even without affecting runtime performance. Here’s how they improve development:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Improved Readability and Self-Documentation&lt;br&gt;
Type hints make code more readable and act as self-documentation. In large Odoo projects, models can have extensive relationships, making it valuable to explicitly show the expected types. The type hint in product_category_id: 'ProductCategory' clarifies its purpose, which helps new or unfamiliar developers understand relationships faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhanced Developer Experience&lt;br&gt;
Type hints provide better IDE support, with features like autocomplete, tooltip explanations, and safer refactoring. IDEs can recognize the type of product_category_id as a ProductCategory and offer relevant methods and attributes, making development faster and more accurate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Early Error Detection&lt;br&gt;
Type hints enable static type checkers like mypy or Pyright to detect type errors before runtime, reducing bugs. For example, if a non-ProductCategory value is mistakenly assigned to product_category_id, type checkers will raise a warning, ensuring data consistency early.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improved Maintainability&lt;br&gt;
Odoo code often involves complex model relationships, and type hints help clarify these links, reducing ambiguity. By showing exactly what each field references, type hints make code easier to maintain and extend, which is essential as models evolve.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No Direct Performance Boost, But Indirect Gains&lt;br&gt;
Type hints do not directly impact runtime speed, as Python ignores them at runtime. However, they can indirectly improve efficiency by:&lt;/p&gt;

&lt;p&gt;Reducing Downtime: Early error detection reduces runtime crashes.&lt;br&gt;
Speeding Development: Enhanced IDE support and fewer bugs make development smoother.&lt;/p&gt;

&lt;p&gt;Here’s an example where product_category_id references the ProductCategory model, with type hints to aid clarity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import typing
from odoo import fields, models

if typing.TYPE_CHECKING:
    from odoo.addons.product.models.product_category import ProductCategory

class PartnerCategory(models.Model):
    _inherit = "res.partner.category"
    _description = "Customized Partner Tag"

    product_category_id: 'ProductCategory' = fields.Many2one(
        'product.category',
        string='Product Category',
        help='Link to the product category associated with this partner category'
    )

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

&lt;/div&gt;



&lt;p&gt;This type hint clarifies product_category_id's expected type without affecting runtime.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Odoo: Import CSV file and write into sale order lines</title>
      <dc:creator>Jeevachaithanyan Sivanandan</dc:creator>
      <pubDate>Mon, 28 Oct 2024 16:38:53 +0000</pubDate>
      <link>https://dev.to/jeevanizm/odoo-import-csv-file-and-write-into-sale-order-lines-pj1</link>
      <guid>https://dev.to/jeevanizm/odoo-import-csv-file-and-write-into-sale-order-lines-pj1</guid>
      <description>&lt;p&gt;Odoo: Import CSV file and write into sale order lines&lt;/p&gt;

&lt;p&gt;The method features: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;read an imported csv file&lt;/li&gt;
&lt;li&gt;check some validations&lt;/li&gt;
&lt;li&gt;write the values from the csv file into the sale order line and sale order
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    def action_import_csv(self):

        if not self.file_name or not self.file_name.lower().endswith('.csv'):
            raise UserError("Invalid file format! Please upload a CSV file.")

        try:
            csv_data = base64.b64decode(self.csv_file_upload).decode('utf-8')
            csv_reader = csv.DictReader(StringIO(csv_data))
        except Exception:
            raise UserError("Failed to read CSV file. Ensure the file is properly formatted.")

        sale_order = self.get_current_sale_order()

        partner_id = None  
        updated_lines = {}  

        for i, row in enumerate(csv_reader):

            if i == 0:
                row_partner_id = int(row.get("Partner ID", 0) or 0)
                partner_id = row_partner_id

                if sale_order.partner_id.id != partner_id:
                    raise UserError("The Partner ID in the CSV does not match the Sale Order's Partner.")
            elif row.get("Partner ID"):
                raise UserError("Only the first row should contain a Partner ID. Subsequent rows should leave this field empty.")

            sku = row.get("Product ID", "").strip()
            quantity = float(row.get("Product Quantity", 0))

            if not sku:
                raise UserError("Product ID (SKU) is missing in one of the rows.")

            product = self.env['product.product'].search([('default_code', '=', sku)], limit=1)
            if not product:
                raise UserError(f"Product with SKU {sku} not found in the system.")


            sale_order_line = self.env['sale.order.line'].create({
                'order_id': sale_order.id,
                'product_id': product.id,
                'product_uom_qty': quantity,
            })
            updated_lines[sku] = quantity

        sale_order.write({
            'partner_invoice_id': sale_order.partner_id.address_get(['invoice'])['invoice'],
            'partner_shipping_id': sale_order.partner_id.address_get(['delivery'])['delivery'],
        })

        return {
            'type': 'ir.actions.client',
            'tag': 'reload',
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
