<?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: Elxpro</title>
    <description>The latest articles on DEV Community by Elxpro (@theguuholi).</description>
    <link>https://dev.to/theguuholi</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F324015%2Fc2f20c59-99f1-48c6-9e8f-81b7a749e80b.jpeg</url>
      <title>DEV Community: Elxpro</title>
      <link>https://dev.to/theguuholi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/theguuholi"/>
    <language>en</language>
    <item>
      <title>AI-Assisted Software Development Fundamentals: A Practical Guide for Developers</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Tue, 22 Sep 2026 18:36:07 +0000</pubDate>
      <link>https://dev.to/theguuholi/ai-assisted-software-development-fundamentals-a-practical-guide-for-developers-3kgh</link>
      <guid>https://dev.to/theguuholi/ai-assisted-software-development-fundamentals-a-practical-guide-for-developers-3kgh</guid>
      <description>&lt;h1&gt;
  
  
  AI-Assisted Software Development Fundamentals: A Practical Guide for Developers
&lt;/h1&gt;

&lt;p&gt;AI-assisted development is not simply writing a prompt and accepting the generated code. It is a disciplined engineering practice in which a developer gives an AI system the right context, defines the boundaries of the task, evaluates its decisions, and verifies the result.&lt;/p&gt;

&lt;p&gt;This guide introduces the mental models needed to work effectively with coding agents and large language models. Each topic includes a practical worksheet and an exercise so that the concepts can be applied to a real codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning Outcomes
&lt;/h2&gt;

&lt;p&gt;By the end of this guide, you should be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;distinguish experimentation through vibe coding from disciplined AI-assisted development;&lt;/li&gt;
&lt;li&gt;explain the responsibilities of a model, an agent, and an agent harness;&lt;/li&gt;
&lt;li&gt;account for the nondeterministic nature of language models;&lt;/li&gt;
&lt;li&gt;create concise, useful project context;&lt;/li&gt;
&lt;li&gt;turn a vague request into a well-scoped engineering task;&lt;/li&gt;
&lt;li&gt;manage context as a limited resource;&lt;/li&gt;
&lt;li&gt;define permissions, acceptance criteria, and verification evidence;&lt;/li&gt;
&lt;li&gt;evaluate whether AI-generated work is actually ready to use.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Two Ways Developers Work with AI
&lt;/h2&gt;

&lt;p&gt;There is a meaningful difference between &lt;strong&gt;using an AI tool&lt;/strong&gt; and &lt;strong&gt;engineering a workflow around AI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A developer using AI may ask ChatGPT, Claude, Gemini, or Copilot for an explanation or a code sample. The interaction is usually local and temporary: ask a question, receive an answer, and manually decide what to do next.&lt;/p&gt;

&lt;p&gt;A developer building with AI-assisted workflows goes further. They design how the agent discovers context, which tools it can use, how work is divided, what evidence proves completion, and where human approval is required.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AI tool user&lt;/th&gt;
&lt;th&gt;AI-assisted workflow designer&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Interacts mainly through prompts&lt;/td&gt;
&lt;td&gt;Designs repeatable development workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supplies context manually&lt;/td&gt;
&lt;td&gt;Creates persistent and task-specific context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviews one answer at a time&lt;/td&gt;
&lt;td&gt;Defines validation and feedback loops&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses the model as an assistant&lt;/td&gt;
&lt;td&gt;Coordinates models, agents, tools, and permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optimizes individual requests&lt;/td&gt;
&lt;td&gt;Improves the surrounding engineering system&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These roles are not competing job titles. They describe a progression in how deliberately a developer uses AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;What distinguishes an isolated AI interaction from an AI-assisted workflow?&lt;/li&gt;
&lt;li&gt;Which responsibilities should remain with the developer even when an agent performs most implementation steps?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Map Your Current Usage
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Activity&lt;/th&gt;
&lt;th&gt;How I do it today&lt;/th&gt;
&lt;th&gt;Manual or repeatable?&lt;/th&gt;
&lt;th&gt;Evidence of correctness&lt;/th&gt;
&lt;th&gt;Improvement opportunity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Asking for explanations&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generating code&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Finding relevant files&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Running tests&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reviewing changes&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recording project conventions&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 1: Find One Repeatable Workflow
&lt;/h3&gt;

&lt;p&gt;Choose one AI-assisted activity you perform at least once per week.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write down every manual step.&lt;/li&gt;
&lt;li&gt;Mark which steps require engineering judgment.&lt;/li&gt;
&lt;li&gt;Mark which steps could be represented as instructions, tools, or automated checks.&lt;/li&gt;
&lt;li&gt;Design a repeatable workflow without removing the human decisions that protect quality.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A workflow map showing its manual steps, agent actions, human decisions, and validation gates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; You can explain what remains under human control, what the agent performs, and how the result is verified.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Vibe Coding vs. AI-Assisted Development
&lt;/h2&gt;

&lt;p&gt;Vibe coding is useful when the objective is exploration. You describe what you want, iterate quickly, and accept that the implementation may be temporary. It can be effective for prototypes, experiments, learning exercises, and small applications with limited risk.&lt;/p&gt;

&lt;p&gt;AI-assisted development is appropriate when the software contains important business rules, integrations, customer data, operational risk, or long-term maintenance requirements. The developer remains responsible for architecture, context, trade-offs, review, and validation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Vibe coding&lt;/th&gt;
&lt;th&gt;AI-assisted development&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Optimized for speed of exploration&lt;/td&gt;
&lt;td&gt;Optimized for controlled delivery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Useful for disposable prototypes&lt;/td&gt;
&lt;td&gt;Suitable for production systems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Requirements may emerge during generation&lt;/td&gt;
&lt;td&gt;Requirements and constraints are made explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broad changes may be acceptable&lt;/td&gt;
&lt;td&gt;Changes are scoped and reviewed carefully&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generated output drives the next step&lt;/td&gt;
&lt;td&gt;Engineering intent drives the agent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The distinction is not about whether AI writes code. It is about whether the development process contains enough control for the risk involved.&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[New development task] --&amp;gt; B{Production or long-lived?}
    B -- No --&amp;gt; C{Low impact if incorrect?}
    C -- Yes --&amp;gt; D[Vibe Coding]
    C -- No --&amp;gt; E[AI-Assisted Development]
    B -- Yes --&amp;gt; F{Business rules or sensitive data?}
    F -- Yes --&amp;gt; G[Controlled AI-Assisted Development]
    F -- No --&amp;gt; E

    D --&amp;gt; H[Explore quickly]
    E --&amp;gt; I[Define context and acceptance criteria]
    G --&amp;gt; J[Add permissions, verification, and human approval]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When is vibe coding a reasonable choice?&lt;/li&gt;
&lt;li&gt;Which task characteristics require a controlled AI-assisted workflow?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Choose the Right Mode
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Impact if wrong&lt;/th&gt;
&lt;th&gt;Expected lifetime&lt;/th&gt;
&lt;th&gt;Business complexity&lt;/th&gt;
&lt;th&gt;Recommended mode&lt;/th&gt;
&lt;th&gt;Why?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Weekend prototype&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Days&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Internal reporting script&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Months&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment authorization&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;td&gt;Years&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI concept test&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Hours&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database migration&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Permanent&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 2: Classify a Real Task
&lt;/h3&gt;

&lt;p&gt;Select one item from your current backlog. Decide whether it should be handled as exploration or controlled implementation.&lt;/p&gt;

&lt;p&gt;Document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the cost of an incorrect result;&lt;/li&gt;
&lt;li&gt;whether the implementation is disposable or permanent;&lt;/li&gt;
&lt;li&gt;which architectural decisions require a developer;&lt;/li&gt;
&lt;li&gt;which checks must pass before the change can be accepted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A one-page risk classification for a real backlog item, including the selected development mode and required controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; Your chosen workflow matches the risk and expected lifetime of the software.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. How an LLM Produces an Answer
&lt;/h2&gt;

&lt;p&gt;A large language model generates output by predicting tokens based on the context available to it. Given an incomplete sentence such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It works on my ___&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the model may assign different probabilities to tokens such as &lt;code&gt;machine&lt;/code&gt;, &lt;code&gt;computer&lt;/code&gt;, or &lt;code&gt;environment&lt;/code&gt;. It selects a continuation and repeats this process token by token.&lt;/p&gt;

&lt;p&gt;This produces an essential property of LLM-based systems: &lt;strong&gt;their output is not inherently deterministic&lt;/strong&gt;. The same request can produce different implementations, explanations, or decisions. Model configuration can reduce variation, but it does not turn generated output into verified truth.&lt;/p&gt;

&lt;p&gt;For software development, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;plausible code is not necessarily correct code;&lt;/li&gt;
&lt;li&gt;confident explanations can still contain false assumptions;&lt;/li&gt;
&lt;li&gt;repeated runs may reveal different interpretations of an ambiguous requirement;&lt;/li&gt;
&lt;li&gt;deterministic tools such as compilers and tests should verify nondeterministic output.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Why can the same prompt produce different implementations?&lt;/li&gt;
&lt;li&gt;Which deterministic tools can you use to evaluate nondeterministic output in your project?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Response Variance
&lt;/h3&gt;

&lt;p&gt;Run the same request three times and record the differences.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Observation&lt;/th&gt;
&lt;th&gt;Run 1&lt;/th&gt;
&lt;th&gt;Run 2&lt;/th&gt;
&lt;th&gt;Run 3&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Proposed design&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files selected&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assumptions made&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Error handling&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests suggested&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Potential risks&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 3: Measure Nondeterminism
&lt;/h3&gt;

&lt;p&gt;Select a real backlog item and first reduce it to an intentionally incomplete request similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a service that calculates taxes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Submit it three times in separate conversations. Compare the responses and identify every assumption the model had to invent.&lt;/p&gt;

&lt;p&gt;Then write a second version containing the real business domain, module, existing integration, inputs, outputs, error behavior, and acceptance criteria. Run that version three times as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A comparison table containing six responses, the assumptions each response invented, and the context that removed those assumptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; The second set of responses contains fewer conflicting assumptions than the first set.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Model, Agent, and Harness
&lt;/h2&gt;

&lt;p&gt;The terms &lt;strong&gt;model&lt;/strong&gt;, &lt;strong&gt;agent&lt;/strong&gt;, and &lt;strong&gt;harness&lt;/strong&gt; describe different layers of an AI-assisted system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model: The Reasoning Engine
&lt;/h3&gt;

&lt;p&gt;The model interprets the supplied context and generates the next response. It can analyze a problem, propose a plan, write code, or recommend a tool call. By itself, however, the model does not browse your repository or execute commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent: The Orchestrator
&lt;/h3&gt;

&lt;p&gt;The agent manages the interaction with the model. It gathers context, exposes tools, sends information to the model, receives requested actions, executes authorized actions, and continues the loop until it reaches a stopping condition.&lt;/p&gt;

&lt;h3&gt;
  
  
  Harness: The Operating Environment
&lt;/h3&gt;

&lt;p&gt;The harness is the broader system that makes agent behavior useful and controlled. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;instructions and context-loading rules;&lt;/li&gt;
&lt;li&gt;repository access and search tools;&lt;/li&gt;
&lt;li&gt;terminals, browsers, MCP servers, and external integrations;&lt;/li&gt;
&lt;li&gt;approval and permission boundaries;&lt;/li&gt;
&lt;li&gt;state, memory, and progress tracking;&lt;/li&gt;
&lt;li&gt;tests, linters, builds, evals, and other validation mechanisms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenAI describes agents as systems that combine models, tools, instructions, and orchestration. Anthropic similarly describes agents as models using tools in a loop. The practical lesson is that model quality is only one part of system quality. &lt;a href="https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/" rel="noopener noreferrer"&gt;OpenAI: A Practical Guide to Building AI Agents&lt;/a&gt; &lt;a href="https://www.anthropic.com/research/building-effective-agents" rel="noopener noreferrer"&gt;Anthropic: Building Effective AI Agents&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    H[Human Developer] --&amp;gt;|Goal, constraints, and approval| A[Agent]
    A --&amp;gt;|Instructions and selected context| M[Model]
    M --&amp;gt;|Reasoning or requested action| A

    A --&amp;gt;|Read, edit, or execute| R[Harness]
    R --&amp;gt; T[Repository]
    R --&amp;gt; C[Terminal and Tests]
    R --&amp;gt; X[External Tools and APIs]

    R --&amp;gt;|Results and evidence| A
    A --&amp;gt;|Plan, changes, and verification| H&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;What can an agent do that a model alone cannot?&lt;/li&gt;
&lt;li&gt;Which harness controls prevent technical capability from becoming uncontrolled authority?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Responsibility Map
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Harness&lt;/th&gt;
&lt;th&gt;Human&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Interpret requirements&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search repository files&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suggest a code change&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Execute a test command&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grant production access&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decide whether risk is acceptable&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Record verification evidence&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 4: Trace One Agent Interaction
&lt;/h3&gt;

&lt;p&gt;Observe a coding agent completing a small task. For every action, label it as model reasoning, agent orchestration, harness capability, or human decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; An annotated trace of one real coding-agent session, with every step assigned to the model, agent, harness, or human.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; You can identify where each layer begins and ends, including at least one action the agent must not perform without approval.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Context Engineering
&lt;/h2&gt;

&lt;p&gt;Prompt engineering focuses on how a request is written. Context engineering addresses the larger question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What information should be available to the model at this moment so that it can make a good decision?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Context can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;system and repository instructions;&lt;/li&gt;
&lt;li&gt;architecture and directory structure;&lt;/li&gt;
&lt;li&gt;relevant source files and tests;&lt;/li&gt;
&lt;li&gt;coding conventions;&lt;/li&gt;
&lt;li&gt;examples of correct behavior;&lt;/li&gt;
&lt;li&gt;tool descriptions;&lt;/li&gt;
&lt;li&gt;task requirements and acceptance criteria;&lt;/li&gt;
&lt;li&gt;previous messages and decisions;&lt;/li&gt;
&lt;li&gt;tool results, logs, and external documentation.
&lt;/li&gt;
&lt;/ul&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart LR
    T[Task] --&amp;gt; S[Select initial context]
    S --&amp;gt; R[Retrieve relevant information]
    R --&amp;gt; W[Perform the work]
    W --&amp;gt; V[Validate the result]
    V --&amp;gt; D{More context needed?}

    D -- Yes --&amp;gt; R
    D -- No --&amp;gt; P[Preserve decisions and evidence]
    P --&amp;gt; E[End]&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;Good context is not the largest possible collection of information. It is the smallest high-signal set that supports the current decision. Anthropic describes context as a finite resource and recommends curating relevant information, retrieving details just in time, and using progressive disclosure rather than loading everything up front. &lt;a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents" rel="noopener noreferrer"&gt;Anthropic: Effective Context Engineering for AI Agents&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Context: What Persists
&lt;/h3&gt;

&lt;p&gt;Project-level context should explain durable facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what the system does;&lt;/li&gt;
&lt;li&gt;its major architectural boundaries;&lt;/li&gt;
&lt;li&gt;the directory structure;&lt;/li&gt;
&lt;li&gt;how to build, test, lint, and run it;&lt;/li&gt;
&lt;li&gt;naming and coding conventions;&lt;/li&gt;
&lt;li&gt;important domain rules;&lt;/li&gt;
&lt;li&gt;examples that represent the expected style.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repository instruction files such as &lt;code&gt;AGENTS.md&lt;/code&gt; can hold this persistent guidance. GitHub Copilot, for example, discovers repository-wide and path-specific instruction files and combines applicable instructions for the current task. &lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions" rel="noopener noreferrer"&gt;GitHub Docs: Adding Custom Instructions&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;How is context engineering broader than prompt engineering?&lt;/li&gt;
&lt;li&gt;Which information belongs in persistent project context, and which information belongs only to a task?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: One-Page Project Context
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Questions to answer&lt;/th&gt;
&lt;th&gt;Your project&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Purpose&lt;/td&gt;
&lt;td&gt;What problem does this system solve?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;What are the major modules and boundaries?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Commands&lt;/td&gt;
&lt;td&gt;How do developers build, test, lint, and run it?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conventions&lt;/td&gt;
&lt;td&gt;Which patterns, names, and styles are mandatory?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain rules&lt;/td&gt;
&lt;td&gt;Which business rules must never be guessed?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Examples&lt;/td&gt;
&lt;td&gt;Which files demonstrate the preferred implementation?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restrictions&lt;/td&gt;
&lt;td&gt;What must the agent not modify or access?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 5: Create a Minimal Context File
&lt;/h3&gt;

&lt;p&gt;Create a one-page &lt;code&gt;AGENTS.md&lt;/code&gt; draft for a real repository. Keep only information that is both durable and useful across multiple tasks.&lt;/p&gt;

&lt;p&gt;Remove:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generic advice such as “write high-quality code”;&lt;/li&gt;
&lt;li&gt;documentation already easy to discover;&lt;/li&gt;
&lt;li&gt;rules the team does not actually follow;&lt;/li&gt;
&lt;li&gt;detailed instructions relevant to only one task.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A one-page &lt;code&gt;AGENTS.md&lt;/code&gt; draft stored in, or ready to add to, a repository you actively maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; Another developer or a fresh agent session can use the file to locate the architecture, run the primary checks, follow conventions, and avoid prohibited changes.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Context Engineering for a Single Interaction
&lt;/h2&gt;

&lt;p&gt;Persistent project context is not enough. Every task needs local information that explains the desired change.&lt;/p&gt;

&lt;p&gt;Compare these requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a service that calculates taxes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In the billing module, add a service that calculates tax for invoices.
Use the existing Stripe integration and follow the adapter pattern used by
the other billing integrations. The service must return either the calculated
tax breakdown or a domain error. Add unit tests for domestic, international,
and unsupported-region cases. Do not change the public invoice API.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second request does more than add words. It reduces the number of decisions the model must invent.&lt;/p&gt;

&lt;p&gt;A useful task context normally includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Objective:&lt;/strong&gt; the observable outcome.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location:&lt;/strong&gt; the module, feature, or ownership boundary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business context:&lt;/strong&gt; why the change exists.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Existing patterns:&lt;/strong&gt; examples and integrations to reuse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints:&lt;/strong&gt; behavior or interfaces that must not change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acceptance criteria:&lt;/strong&gt; conditions that define success.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification:&lt;/strong&gt; commands or evidence that prove completion.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Which decisions did the vague tax-service request force the model to invent?&lt;/li&gt;
&lt;li&gt;What is the difference between an implementation constraint and an acceptance criterion?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Task Context Canvas
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Task identifier&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Business objective&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User-visible outcome&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relevant module&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Files or examples to inspect first&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Existing APIs to reuse&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Constraints and non-goals&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure behavior&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Acceptance criteria&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification commands&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actions requiring approval&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 6: Rewrite a Vague Request
&lt;/h3&gt;

&lt;p&gt;Choose a vague request from your real backlog. If none is available, use one of these examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Refactor this code.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Improve the performance of this endpoint.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add authentication.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rewrite it using every field in the Task Context Canvas. Do not prescribe the implementation unless a genuine constraint requires it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A completed Task Context Canvas attached to, or ready to attach to, the real backlog item.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; A developer unfamiliar with the conversation can explain the expected behavior, scope, non-goals, and proof of completion.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Modern Context Management
&lt;/h2&gt;

&lt;p&gt;Larger context windows do not eliminate the need for context engineering. As conversations and tool outputs accumulate, relevant facts compete with old logs, rejected approaches, and unrelated files.&lt;/p&gt;

&lt;p&gt;Modern agent workflows commonly use four techniques:&lt;/p&gt;

&lt;h3&gt;
  
  
  Just-in-Time Retrieval
&lt;/h3&gt;

&lt;p&gt;Give the agent identifiers such as file paths, ticket IDs, or documentation links, and let it retrieve the full content when required.&lt;/p&gt;

&lt;h3&gt;
  
  
  Progressive Disclosure
&lt;/h3&gt;

&lt;p&gt;Start with architecture and task boundaries. Load implementation details only after the agent identifies the relevant component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structured Notes
&lt;/h3&gt;

&lt;p&gt;Store decisions, progress, unresolved questions, and verification results outside the active conversation so that long-running tasks can resume without retaining every raw tool output.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Isolation
&lt;/h3&gt;

&lt;p&gt;Use separate focused agents or sessions for independent investigations. Return concise findings to the coordinating agent instead of merging every exploratory detail into one context window.&lt;/p&gt;

&lt;p&gt;These techniques are intended to preserve signal, not to hide required information. The goal is to make relevant context available at the point of decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Why does a larger context window not remove the need for context management?&lt;/li&gt;
&lt;li&gt;When should information be retrieved just in time instead of loaded at the beginning?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Context Budget
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information&lt;/th&gt;
&lt;th&gt;Load now&lt;/th&gt;
&lt;th&gt;Retrieve later&lt;/th&gt;
&lt;th&gt;Exclude&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Architecture overview&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entire repository documentation&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Relevant interface&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Historical logs from last year&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Current failing test&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Similar implementation&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unrelated module source code&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 7: Reduce a Context Package
&lt;/h3&gt;

&lt;p&gt;Select a completed engineering task and gather every artifact associated with it: ticket, conversation, files, logs, documentation, and test output.&lt;/p&gt;

&lt;p&gt;Create three lists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;information required before work begins;&lt;/li&gt;
&lt;li&gt;information retrievable when a specific question appears;&lt;/li&gt;
&lt;li&gt;information that adds noise without changing a decision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A three-part context inventory labeled &lt;code&gt;load now&lt;/code&gt;, &lt;code&gt;retrieve later&lt;/code&gt;, and &lt;code&gt;exclude&lt;/code&gt; for a real engineering task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; A fresh agent session can produce the correct implementation and verification plan using the reduced context package.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Acceptance Criteria, Evals, and Verification
&lt;/h2&gt;

&lt;p&gt;Because model output varies, quality cannot depend only on whether one generated answer looks convincing.&lt;/p&gt;

&lt;p&gt;An effective AI-assisted workflow separates three questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Did the agent produce something?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Does it satisfy the requested behavior?&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What evidence proves that it satisfies the requested behavior?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Acceptance criteria define the required behavior. Verification collects deterministic evidence such as test results, compiler output, schema validation, or a focused manual check. Evals measure performance across a representative set of tasks or cases instead of relying on one successful example.&lt;/p&gt;

&lt;p&gt;OpenAI recommends establishing eval baselines when building agents, while Anthropic emphasizes defining outcomes and combining appropriate graders for the task. &lt;a href="https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/" rel="noopener noreferrer"&gt;OpenAI: A Practical Guide to Building AI Agents&lt;/a&gt; &lt;a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents" rel="noopener noreferrer"&gt;Anthropic: Demystifying Evals for AI Agents&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Research existing system] --&amp;gt; B[Create implementation plan]
    B --&amp;gt; C{Human approves plan?}
    C -- No --&amp;gt; B
    C -- Yes --&amp;gt; D[Implement scoped change]
    D --&amp;gt; E[Run tests and quality checks]
    E --&amp;gt; F{Evidence satisfies criteria?}
    F -- No --&amp;gt; G[Diagnose failure]
    G --&amp;gt; D
    F -- Yes --&amp;gt; H[Review diff]
    H --&amp;gt; I{Only intended changes?}
    I -- No --&amp;gt; D
    I -- Yes --&amp;gt; J[Complete task]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;What is the difference between acceptance criteria, verification, and an eval?&lt;/li&gt;
&lt;li&gt;Why is an agent's statement that tests passed not sufficient evidence?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Verification Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Evidence&lt;/th&gt;
&lt;th&gt;Verification method&lt;/th&gt;
&lt;th&gt;Expected result&lt;/th&gt;
&lt;th&gt;Actual result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Domestic tax is calculated&lt;/td&gt;
&lt;td&gt;Unit test&lt;/td&gt;
&lt;td&gt;&lt;code&gt;run focused test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unsupported region returns an error&lt;/td&gt;
&lt;td&gt;Unit test&lt;/td&gt;
&lt;td&gt;&lt;code&gt;run error-case test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public API remains compatible&lt;/td&gt;
&lt;td&gt;Contract test&lt;/td&gt;
&lt;td&gt;&lt;code&gt;run API suite&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code follows repository style&lt;/td&gt;
&lt;td&gt;Formatter/linter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;run quality gate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No violations&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No unrelated files changed&lt;/td&gt;
&lt;td&gt;Diff review&lt;/td&gt;
&lt;td&gt;&lt;code&gt;inspect diff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only scoped files&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 8: Turn Requirements into Evidence
&lt;/h3&gt;

&lt;p&gt;Take the improved task from Exercise 6. For each acceptance criterion, define one observable piece of evidence.&lt;/p&gt;

&lt;p&gt;Reject evidence such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“the implementation looks correct”;&lt;/li&gt;
&lt;li&gt;“the agent said the tests pass”;&lt;/li&gt;
&lt;li&gt;“the code follows best practices.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Replace it with a test result, command output, contract comparison, or explicit review procedure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A verification matrix attached to a current task, pull request, or implementation plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; Every acceptance criterion has evidence that another developer can independently reproduce.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Permission and Authority Boundaries
&lt;/h2&gt;

&lt;p&gt;An agent may be technically capable of performing an action without being authorized to perform it. A mature workflow distinguishes capability from permission.&lt;/p&gt;

&lt;p&gt;Typical permission levels include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read repository files;&lt;/li&gt;
&lt;li&gt;modify files inside the current task scope;&lt;/li&gt;
&lt;li&gt;execute local tests;&lt;/li&gt;
&lt;li&gt;install dependencies;&lt;/li&gt;
&lt;li&gt;access secrets or customer data;&lt;/li&gt;
&lt;li&gt;modify databases;&lt;/li&gt;
&lt;li&gt;deploy software;&lt;/li&gt;
&lt;li&gt;send messages or create external records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;High-impact or difficult-to-reverse actions should require explicit approval. The boundary should be defined before execution, not after the agent announces what it has done.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Why are capability and permission different concerns?&lt;/li&gt;
&lt;li&gt;Which actions in your environment are difficult to reverse or affect people outside the development team?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Worksheet: Authority Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Allowed automatically&lt;/th&gt;
&lt;th&gt;Requires approval&lt;/th&gt;
&lt;th&gt;Prohibited&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read source files&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit task-related files&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run local tests&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install a dependency&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Change a database schema&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access production logs&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy to production&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contact a customer&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Apply It to Your Project 9: Define a Safe Operating Boundary
&lt;/h3&gt;

&lt;p&gt;Choose one development environment and complete the Authority Matrix. For every action requiring approval, define who can approve it and what information they need before deciding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A reviewed Authority Matrix for a real repository or development environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; The agent can make useful progress without gaining unnecessary access or guessing whether a sensitive action is permitted.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. End-to-End Practice: The Tax Service
&lt;/h2&gt;

&lt;p&gt;Apply the complete workflow to the original vague request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a service that calculates taxes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[Business request] --&amp;gt; B[Define expected outcome]
    B --&amp;gt; C[Locate owning module]
    C --&amp;gt; D[Retrieve relevant context]
    D --&amp;gt; E[Define task contract]
    E --&amp;gt; F[Set authority boundaries]
    F --&amp;gt; G[Create implementation plan]
    G --&amp;gt; H[Implement]
    H --&amp;gt; I[Collect verification evidence]
    I --&amp;gt; J[Human review]
    J --&amp;gt; K{Accepted?}
    K -- No --&amp;gt; D
    K -- Yes --&amp;gt; L[Preserve decisions and results]&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Quick Check
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Which artifacts from the previous sections are required before implementation begins?&lt;/li&gt;
&lt;li&gt;At which points can the workflow return to context collection or implementation?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1: Establish the Business Objective
&lt;/h3&gt;

&lt;p&gt;Explain who needs the service, which transaction it supports, and what an incorrect result would affect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Locate the Ownership Boundary
&lt;/h3&gt;

&lt;p&gt;Identify the module responsible for invoices, the existing integration boundary, and the public API that must remain stable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Retrieve Relevant Context
&lt;/h3&gt;

&lt;p&gt;Load the architecture overview, the existing Stripe adapter, one representative test, and the domain error conventions. Do not load unrelated modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Define the Task Contract
&lt;/h3&gt;

&lt;p&gt;Specify inputs, outputs, supported regions, rounding rules, failure behavior, constraints, and non-goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Define Authority
&lt;/h3&gt;

&lt;p&gt;Allow repository reads, scoped file changes, and local tests. Require approval for dependency changes, schema migrations, external API calls, or deployments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Define Acceptance Evidence
&lt;/h3&gt;

&lt;p&gt;Map each supported behavior to a test or reproducible check. Include compatibility and diff-scope checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Ask the Agent to Research and Plan
&lt;/h3&gt;

&lt;p&gt;Require the agent to inspect existing patterns and present a plan before implementation. Review assumptions that affect business behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Implement and Verify
&lt;/h3&gt;

&lt;p&gt;Run the focused tests, the project quality gate, and a final diff review. Record the actual command output rather than accepting a summary without evidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Practice Worksheet
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Decision or artifact&lt;/th&gt;
&lt;th&gt;Owner&lt;/th&gt;
&lt;th&gt;Evidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Business objective&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture boundary&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context package&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task contract&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authority boundary&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Implementation plan&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verification results&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Final review&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Final challenge:&lt;/strong&gt; Apply this workflow to one real backlog item. Preserve the completed worksheets as part of the task record and compare the result with a previous AI-assisted task that did not use the workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deliverable:&lt;/strong&gt; A complete task record containing the context package, task contract, authority matrix, implementation plan, verification matrix, and final review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof of completion:&lt;/strong&gt; A second developer can reproduce the checks, understand the important decisions, and determine why the task was accepted without relying on the original conversation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference
&lt;/h2&gt;

&lt;p&gt;Before asking an agent to implement a change, confirm that you can answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What outcome is required?&lt;/li&gt;
&lt;li&gt;Why does the business need it?&lt;/li&gt;
&lt;li&gt;Which module owns the behavior?&lt;/li&gt;
&lt;li&gt;Which existing pattern should be reused?&lt;/li&gt;
&lt;li&gt;What must not change?&lt;/li&gt;
&lt;li&gt;Which information belongs in context now?&lt;/li&gt;
&lt;li&gt;Which information can be retrieved later?&lt;/li&gt;
&lt;li&gt;Which actions require approval?&lt;/li&gt;
&lt;li&gt;What are the acceptance criteria?&lt;/li&gt;
&lt;li&gt;What evidence will prove completion?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these answers are unclear, the agent is being asked to invent engineering decisions rather than execute them.&lt;/p&gt;

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

&lt;p&gt;Effective AI-assisted development is not primarily about discovering a perfect prompt. It is about designing an environment in which a probabilistic model can contribute without replacing engineering responsibility.&lt;/p&gt;

&lt;p&gt;The developer remains accountable for context, architecture, constraints, permissions, trade-offs, and evidence. The agent accelerates exploration and execution inside those boundaries. The model supplies reasoning and generation. The harness connects everything to the real development environment.&lt;/p&gt;

&lt;p&gt;When these layers are designed deliberately, AI becomes more than a code generator. It becomes part of a repeatable engineering system.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents" rel="noopener noreferrer"&gt;Anthropic: Effective Context Engineering for AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.anthropic.com/research/building-effective-agents" rel="noopener noreferrer"&gt;Anthropic: Building Effective AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents" rel="noopener noreferrer"&gt;Anthropic: Demystifying Evals for AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/" rel="noopener noreferrer"&gt;OpenAI: A Practical Guide to Building AI Agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-custom-instructions" rel="noopener noreferrer"&gt;GitHub Docs: Adding Custom Instructions for GitHub Copilot CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agents.md/" rel="noopener noreferrer"&gt;AGENTS.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dora.dev/research/2025/dora-report/" rel="noopener noreferrer"&gt;DORA: State of AI-Assisted Software Development 2025&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://www.alchemistdrops.com/blog/ai-assisted-software-development-fundamentals-a-practical-guide-for-developers" rel="noopener noreferrer"&gt;AlchemistDrops&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering Two Pointers: A Step-by-Step Guide to Solving Sequence Problems</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Tue, 22 Sep 2026 18:14:37 +0000</pubDate>
      <link>https://dev.to/theguuholi/mastering-two-pointers-a-step-by-step-guide-to-solving-sequence-problems-1ba7</link>
      <guid>https://dev.to/theguuholi/mastering-two-pointers-a-step-by-step-guide-to-solving-sequence-problems-1ba7</guid>
      <description>&lt;h1&gt;
  
  
  Mastering Two Pointers: A Step-by-Step Guide to Solving Sequence Problems
&lt;/h1&gt;

&lt;p&gt;Two Pointers is an algorithmic pattern used to solve problems by tracking two positions in a sequence at the same time.&lt;/p&gt;

&lt;p&gt;A sequence can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an array;&lt;/li&gt;
&lt;li&gt;a list;&lt;/li&gt;
&lt;li&gt;a string;&lt;/li&gt;
&lt;li&gt;a linked list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of checking every possible combination with nested loops, the Two Pointers pattern moves two pointers through the data using a clear rule.&lt;/p&gt;

&lt;p&gt;This often improves a solution from &lt;code&gt;O(n^2)&lt;/code&gt; to &lt;code&gt;O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Kind of Problems Does Two Pointers Solve?
&lt;/h2&gt;

&lt;p&gt;Two Pointers is useful when a problem asks you to work with two positions inside the same sequence.&lt;/p&gt;

&lt;p&gt;It commonly solves problems like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finding two numbers that match a condition;&lt;/li&gt;
&lt;li&gt;checking if a string is a palindrome;&lt;/li&gt;
&lt;li&gt;reversing a string or list;&lt;/li&gt;
&lt;li&gt;moving values inside an array;&lt;/li&gt;
&lt;li&gt;removing duplicates from a sorted array;&lt;/li&gt;
&lt;li&gt;comparing values from both ends;&lt;/li&gt;
&lt;li&gt;working with sorted arrays;&lt;/li&gt;
&lt;li&gt;detecting cycles in linked lists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most important idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Every time you move a pointer, you must know why that move is safe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Core Idea
&lt;/h2&gt;

&lt;p&gt;A Two Pointers solution usually follows this structure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a left pointer.&lt;/li&gt;
&lt;li&gt;Create a right pointer.&lt;/li&gt;
&lt;li&gt;Compare the values at both pointers.&lt;/li&gt;
&lt;li&gt;Decide which pointer should move.&lt;/li&gt;
&lt;li&gt;Repeat until you find the answer or the pointers meet.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2, 7, 11, 15]
 L          R
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;L&lt;/code&gt; points to the beginning;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;R&lt;/code&gt; points to the end.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Should You Think About Two Pointers?
&lt;/h2&gt;

&lt;p&gt;Ask yourself these questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the input a sequence?&lt;/li&gt;
&lt;li&gt;Do I need to compare two values?&lt;/li&gt;
&lt;li&gt;Is the sequence sorted?&lt;/li&gt;
&lt;li&gt;Am I looking for a pair?&lt;/li&gt;
&lt;li&gt;Do I need to reverse something?&lt;/li&gt;
&lt;li&gt;Do I need to move values in-place?&lt;/li&gt;
&lt;li&gt;Can I discard part of the search space after each comparison?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the answer is yes to some of these questions, Two Pointers may be useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Two Pointers Strategies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Opposite Direction Pointers
&lt;/h3&gt;

&lt;p&gt;One pointer starts at the beginning.&lt;/p&gt;

&lt;p&gt;The other pointer starts at the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2, 3, 4, 5]
 L           R
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;palindrome checks;&lt;/li&gt;
&lt;li&gt;reversing arrays;&lt;/li&gt;
&lt;li&gt;sorted Two Sum;&lt;/li&gt;
&lt;li&gt;container with most water.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Same Direction Pointers
&lt;/h3&gt;

&lt;p&gt;Both pointers move from left to right.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[0, 1, 0, 3, 12]
 R
 W
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one pointer reads values;&lt;/li&gt;
&lt;li&gt;the other pointer writes or tracks valid positions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moving zeroes;&lt;/li&gt;
&lt;li&gt;removing duplicates;&lt;/li&gt;
&lt;li&gt;filtering values.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Fast and Slow Pointers
&lt;/h3&gt;

&lt;p&gt;One pointer moves faster than the other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;slow -&amp;gt; moves 1 step
fast -&amp;gt; moves 2 steps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detecting cycles;&lt;/li&gt;
&lt;li&gt;finding the middle of a linked list;&lt;/li&gt;
&lt;li&gt;removing the nth node from the end.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Method
&lt;/h2&gt;

&lt;p&gt;Use this process when solving a Two Pointers problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Understand the Input
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What is the sequence?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbers = [2, 7, 11, 15]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sequence is a list of numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Decide Where the Pointers Start
&lt;/h3&gt;

&lt;p&gt;For a sorted array pair problem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;left = 0
right = length - 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[2, 7, 11, 15]
 L          R
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Write the Movement Rules
&lt;/h3&gt;

&lt;p&gt;Before coding, write the rules in plain English.&lt;/p&gt;

&lt;p&gt;For Two Sum II:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If sum == target, return the answer.
If sum &amp;lt; target, move the left pointer to the right.
If sum &amp;gt; target, move the right pointer to the left.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Trace the Example by Hand
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbers = [2, 7, 11, 15]
target = 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;left = 0, right = 3
2 + 15 = 17
17 is greater than 9
Move right left

left = 0, right = 2
2 + 11 = 13
13 is greater than 9
Move right left

left = 0, right = 1
2 + 7 = 9
Found the answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Write the Code
&lt;/h3&gt;

&lt;p&gt;Example in Elixir:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Solution&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;two_sum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;two_sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_tuple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tuple_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;cond&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example: Valid Palindrome
&lt;/h2&gt;

&lt;p&gt;Problem:&lt;/p&gt;

&lt;p&gt;Given a string, return &lt;code&gt;true&lt;/code&gt; if it reads the same forward and backward.&lt;/p&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Pointer idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;l e v e l
L       R
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If characters are different, return false.
If characters are equal, move both pointers inward.
If pointers meet or cross, return true.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Elixir solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Solution&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;palindrome?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;palindrome?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;graphemes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_tuple&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tuple_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_chars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

left = 0, right = 4
l == l

left = 1, right = 3
e == e

left = 2, right = 2
stop

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Practice Two Pointers
&lt;/h2&gt;

&lt;p&gt;Follow this routine:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read the problem.&lt;/li&gt;
&lt;li&gt;Identify the sequence.&lt;/li&gt;
&lt;li&gt;Choose where each pointer starts.&lt;/li&gt;
&lt;li&gt;Write the movement rules in English.&lt;/li&gt;
&lt;li&gt;Trace one example manually.&lt;/li&gt;
&lt;li&gt;Write the code.&lt;/li&gt;
&lt;li&gt;Test with small inputs.&lt;/li&gt;
&lt;li&gt;Explain why each pointer movement is safe.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not jump straight to code.&lt;/p&gt;

&lt;p&gt;The pointer movement is the most important part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exercises
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Exercise 1: Valid Palindrome
&lt;/h3&gt;

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

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

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start one pointer at the beginning.&lt;/li&gt;
&lt;li&gt;Start one pointer at the end.&lt;/li&gt;
&lt;li&gt;Compare both characters.&lt;/li&gt;
&lt;li&gt;Move inward when they match.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extra tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"level" -&amp;gt; true
"hello" -&amp;gt; false
"a" -&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 2: Reverse List
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2, 3, 4, 5]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[5, 4, 3, 2, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start one pointer at the beginning.&lt;/li&gt;
&lt;li&gt;Start one pointer at the end.&lt;/li&gt;
&lt;li&gt;Swap both values.&lt;/li&gt;
&lt;li&gt;Move both pointers inward.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extra tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[] -&amp;gt; []
[1] -&amp;gt; [1]
[1, 2] -&amp;gt; [2, 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 3: Two Sum II
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbers = [2, 7, 11, 15]
target = 9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a sorted array.&lt;/li&gt;
&lt;li&gt;Move the left pointer when the sum is too small.&lt;/li&gt;
&lt;li&gt;Move the right pointer when the sum is too large.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extra tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 2, 3, 4, 6], target = 6 -&amp;gt; [2, 4]
[2, 3, 4], target = 6 -&amp;gt; [1, 3]
[-1, 0], target = -1 -&amp;gt; [1, 2]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 4: Move Zeroes
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[0, 1, 0, 3, 12]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 3, 12, 0, 0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use one pointer to read.&lt;/li&gt;
&lt;li&gt;Use another pointer to track where the next non-zero value should go.&lt;/li&gt;
&lt;li&gt;Keep the original order of non-zero values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Extra tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[0] -&amp;gt; [0]
[1, 0] -&amp;gt; [1, 0]
[0, 0, 1] -&amp;gt; [1, 0, 0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Exercise 5: Container With Most Water
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1, 8, 6, 2, 5, 4, 8, 3, 7]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Practice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with the widest container.&lt;/li&gt;
&lt;li&gt;Calculate the current area.&lt;/li&gt;
&lt;li&gt;Move the pointer with the smaller height.&lt;/li&gt;
&lt;li&gt;Keep the best area found.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key idea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The shorter side limits the area.
Move the shorter side because it is the only side that can improve the result.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Checklist
&lt;/h2&gt;

&lt;p&gt;Before using Two Pointers, answer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Where does the left pointer start?&lt;/li&gt;
&lt;li&gt;Where does the right pointer start?&lt;/li&gt;
&lt;li&gt;What does each pointer represent?&lt;/li&gt;
&lt;li&gt;What condition moves the left pointer?&lt;/li&gt;
&lt;li&gt;What condition moves the right pointer?&lt;/li&gt;
&lt;li&gt;When does the algorithm stop?&lt;/li&gt;
&lt;li&gt;Why is each pointer movement safe?&lt;/li&gt;
&lt;li&gt;What is the time complexity?&lt;/li&gt;
&lt;li&gt;What is the space complexity?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you can answer these questions, you understand the pattern.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://www.alchemistdrops.com/blog/mastering-two-pointers-a-step-by-step-guide-to-solving-sequence-problems" rel="noopener noreferrer"&gt;AlchemistDrops&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Lessons from Law 1 of "The 48 Laws of Power"</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Mon, 06 Jan 2025 10:17:27 +0000</pubDate>
      <link>https://dev.to/theguuholi/lessons-from-law-1-of-the-48-laws-of-power-n8</link>
      <guid>https://dev.to/theguuholi/lessons-from-law-1-of-the-48-laws-of-power-n8</guid>
      <description>&lt;h3&gt;
  
  
  Strategy, Respect, and Prudence: Lessons from Law 1 of "The 48 Laws of Power"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Law 1: Never outshine the master.&lt;/strong&gt; This idea resonates deeply, not just in the context of bosses and leaders but in any relationship where we depend on or learn from someone. Below, we explore the book's teachings and practical reflections to apply them intelligently and respectfully in your life.&lt;/p&gt;




&lt;h3&gt;
  
  
  Submission with Purpose: Strategy and Proactivity
&lt;/h3&gt;

&lt;p&gt;Submitting strategically is not a sign of weakness but a way to achieve greater objectives. It's about knowing when to yield to move forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; An employee accepts challenging or unpleasant tasks at work, demonstrating commitment and reliability. This positions the professional as indispensable, potentially leading to promotions or future opportunities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Practical application in daily life:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you feel the urge to retaliate, take a deep breath. Use phrases that defuse tense situations, such as: “I understand your point; can you explain more about how I can improve?” This demonstrates maturity and builds stronger relationships.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Respect the Trajectory of Those Above
&lt;/h3&gt;

&lt;p&gt;Respecting the journey of those above you is essential to building healthy relationships and avoiding unnecessary confrontations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to practice this?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Listen more:&lt;/strong&gt; Ask about the person's experiences and stories. For example: “How did you start in this field?” or “What motivated you to get where you are?”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acknowledge efforts:&lt;/strong&gt; Make positive comments, such as: “I find it impressive how you managed that complex project.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid comparisons:&lt;/strong&gt; Focus on the person's merits instead of criticizing or thinking about what you would have done differently.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Dynamics of Autonomy and Control
&lt;/h3&gt;

&lt;p&gt;To effectively support a superior, it is crucial to observe their preferences and adapt your behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Autonomy vs. Control:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Autonomy:&lt;/strong&gt; Some leaders prefer the team to make decisions independently. If this is the case, present ready solutions before seeking approval.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; Others like to be involved in the details. In this scenario, share each step of the progress and request constant feedback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Quick Results vs. Planned Outcomes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leaders who prioritize &lt;strong&gt;quick results&lt;/strong&gt; value practical and immediate solutions.&lt;/li&gt;
&lt;li&gt;Leaders who prefer &lt;strong&gt;planning&lt;/strong&gt; focus on detailed strategies and long-term forecasts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where to note patterns:&lt;/strong&gt; Use tools like Notion, Evernote, or a simple notebook to record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Communication preferences.&lt;/li&gt;
&lt;li&gt;Typical reactions under pressure.&lt;/li&gt;
&lt;li&gt;Things the leader values, such as punctuality or creativity.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Aligning Priorities and Solving Problems in Advance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;How to align priorities?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ask directly: “What points are most important to you in this project?”&lt;/li&gt;
&lt;li&gt;Show interest: “I can help ensure this goal is achieved. Is there any area that needs special attention?”&lt;/li&gt;
&lt;li&gt;Review your actions to ensure they meet the leader’s expectations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Solving problems in advance:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Observe recurring failures:&lt;/strong&gt; Identify and avoid errors that have occurred in previous projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anticipate obstacles:&lt;/strong&gt; Propose solutions before problems are noticed. For example: “I noticed the presentation needs clearer charts. I prepared something to improve this.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Be proactive:&lt;/strong&gt; Act before being asked. This demonstrates initiative and commitment.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Reflection on Career Goals
&lt;/h3&gt;

&lt;p&gt;Your current goals—earning money, taking care of your family, and building passive income—are legitimate and respectable. However, having clarity about the path forward can help you achieve these goals more efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Questions for reflection:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do you want to accomplish in the next 5 or 10 years?&lt;/li&gt;
&lt;li&gt;What skills do you need to develop to grow in your field or create new sources of income?&lt;/li&gt;
&lt;li&gt;How can you build passive income sustainably? Consider investments, creating digital products, or other sources that don’t demand much of your time.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Final Considerations
&lt;/h3&gt;

&lt;p&gt;Applying Law 1 in practice requires observation, respect, and prudence. Be strategic in submission, value the trajectory of those above, and align priorities clearly and efficiently. Additionally, take time to reflect on your long-term goals, ensuring your actions align with what truly matters to you.&lt;/p&gt;

</description>
      <category>development</category>
      <category>productivity</category>
      <category>leadership</category>
      <category>learning</category>
    </item>
    <item>
      <title>How to Build an Effective Software Engineer CV</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Thu, 02 Jan 2025 19:16:57 +0000</pubDate>
      <link>https://dev.to/theguuholi/how-to-build-a-good-developer-cv-407h</link>
      <guid>https://dev.to/theguuholi/how-to-build-a-good-developer-cv-407h</guid>
      <description>&lt;h1&gt;
  
  
  How to Build a Good Developer CV
&lt;/h1&gt;

&lt;p&gt;Creating a strong CV is essential for standing out in the competitive tech industry. This guide will walk you through the process of building a solid resume, including tips from top resources like &lt;a href="https://www.resumemaker.online" rel="noopener noreferrer"&gt;ResumeMaker&lt;/a&gt;, &lt;a href="https://www.jobscan.co" rel="noopener noreferrer"&gt;JobScan&lt;/a&gt;, &lt;a href="https://stackoverflow.blog/2020/11/25/how-to-write-an-effective-developer-resume-advice-from-a-hiring-manager/" rel="noopener noreferrer"&gt;StackOverflow Blog&lt;/a&gt;, and &lt;a href="https://www.cake.me/Engineering-resume-samples" rel="noopener noreferrer"&gt;Cake&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Points for a Strong Resume
&lt;/h2&gt;




&lt;h3&gt;
  
  
  1. &lt;strong&gt;Keep it One Page&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Employers typically spend only a few seconds scanning your resume. A concise, one-page resume helps you highlight your best qualities without overwhelming the reader.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Include Relevant Skills&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Only list skills that are relevant to the job you are applying for. Tailor your technical knowledge section to the job description to improve your chances of getting noticed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Personalize Your Resume&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Customize your resume to match the specific role you are applying for. This includes adjusting your experience descriptions and technical skills to reflect what the employer values.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Include Online Links&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Include links to your LinkedIn, GitHub, or portfolio. These links can showcase your work in a more dynamic way than a static resume.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Guide to Building a Developer CV
&lt;/h2&gt;




&lt;h3&gt;
  
  
  Step 1: &lt;strong&gt;Choose a Pre-Designed Resume Template&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use pre-designed resume templates to make the process easier. Templates help ensure your CV looks professional and is well-organized.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: &lt;strong&gt;Use Action Words&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Begin bullet points with action verbs such as "designed," "developed," "led," or "implemented." This demonstrates your active involvement in past projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: &lt;strong&gt;Measure Impact, Not Just Responsibilities&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instead of simply listing tasks, explain the impact of your work. Use metrics when possible (e.g., "Reduced load time by 30%," "Improved performance, resulting in 40% higher efficiency").&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: &lt;strong&gt;Tailor Your CV to the Job&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Match the keywords and technologies mentioned in the job description. This not only ensures that your resume aligns with the company's needs, but also increases the chance of passing Applicant Tracking Systems (ATS).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: &lt;strong&gt;Highlight Relevant Experience&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Focus on showcasing experience that directly aligns with the position. For instance, emphasize projects that use the technologies or skills the company is looking for.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: &lt;strong&gt;List Education and Certifications&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Include your relevant degrees, certifications, or courses you've completed, especially if they’re relevant to the job you're applying for.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 7: &lt;strong&gt;Focus on Technical Knowledge&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your technical skills section should showcase the languages, tools, frameworks, and platforms you’re proficient in. Avoid listing too many tools that you’re not experienced with.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 8: &lt;strong&gt;Remove the Word “I”&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your CV should be written in the third person. Avoid using personal pronouns like "I" to keep the tone professional and objective.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 9: &lt;strong&gt;Avoid Buzzwords&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Instead of generic buzzwords (e.g., "team player," "hardworking"), focus on specific skills, experiences, and accomplishments that demonstrate your abilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 10: &lt;strong&gt;Proofread for Typos and Grammar Mistakes&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A CV with typos and grammar mistakes can easily harm your chances. Make sure to proofread your resume carefully or have someone else review it for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resume Cheat Sheet
&lt;/h2&gt;

&lt;p&gt;Check these off as you finalize your CV:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Use a pre-designed resume template&lt;/li&gt;
&lt;li&gt;[ ] Ensure your resume fits on 1 page&lt;/li&gt;
&lt;li&gt;[ ] Tailor your CV by including keywords from the job description&lt;/li&gt;
&lt;li&gt;[ ] Mention the company name you're applying to&lt;/li&gt;
&lt;li&gt;[ ] Make sure your first item aligns with the company's needs&lt;/li&gt;
&lt;li&gt;[ ] Experience titles demonstrate value&lt;/li&gt;
&lt;li&gt;[ ] Include online links (LinkedIn, GitHub, etc.)&lt;/li&gt;
&lt;li&gt;[ ] Remove personal pronouns ("I")&lt;/li&gt;
&lt;li&gt;[ ] Avoid buzzwords, focus on specifics&lt;/li&gt;
&lt;li&gt;[ ] Use action words in descriptions&lt;/li&gt;
&lt;li&gt;[ ] Quantify impact with numbers when possible&lt;/li&gt;
&lt;li&gt;[ ] Only include sections that are impressive: Experience, Projects, Education, and Technical Skills&lt;/li&gt;
&lt;li&gt;[ ] Double-check for typos and bad grammar&lt;/li&gt;
&lt;/ul&gt;




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




&lt;p&gt;A good CV is a powerful tool to showcase your skills and experience. By focusing on relevant skills, measurable impact, and aligning your CV with the job you're applying for, you increase your chances of standing out to employers. Use the steps and tips in this guide to build a resume that truly represents your expertise as a developer.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>If you want to understand how Elixir Apps work, this is the way</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Thu, 25 Aug 2022 19:15:00 +0000</pubDate>
      <link>https://dev.to/theguuholi/if-you-want-to-understand-how-elixir-apps-work-this-is-the-way-h89</link>
      <guid>https://dev.to/theguuholi/if-you-want-to-understand-how-elixir-apps-work-this-is-the-way-h89</guid>
      <description>&lt;p&gt;Before you read this Article, I highly recommend you read the article about GenServer:&lt;br&gt;
&lt;a href="https://dev.to/postelxpro/read-this-article-if-you-want-to-learn-genserver-1l24"&gt;https://dev.to/postelxpro/read-this-article-if-you-want-to-learn-genserver-1l24&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Greeting
&lt;/h1&gt;

&lt;p&gt;Hello #devElixir!!! Welcome to #FullStackElxpro&lt;/p&gt;

&lt;p&gt;Here, we discuss strategies and tips for your Elixir learning journey from zero to an expert in 3 months.&lt;/p&gt;

&lt;p&gt;I am Gustavo, and today&amp;amp;#39;s theme is **Setup your local machine to use Elixir**.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ps: You can follow the Article with &lt;strong&gt;a VIDEO&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about Elixir on a Telegram channel?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elxpro.com/subscribe-elxcrew" rel="noopener noreferrer"&gt;https://elxpro.com/subscribe-elxcrew&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  What is the difference between Supervisor and DynamicSupervisor?
&lt;/h1&gt;

&lt;p&gt;Before understanding the difference between Supervisor and DynamicSupervisor. Let`s read and understand both. &lt;/p&gt;
&lt;h2&gt;
  
  
  Supervisor
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html" rel="noopener noreferrer"&gt;https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html" rel="noopener noreferrer"&gt;https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A supervisor is a process that supervises other processes, which we refer to as child processes. Supervisors are used to building a hierarchical process structure called a supervision tree. Supervision trees provide fault tolerance and encapsulate how our applications start and shut down.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my experience as a Developer in general, Supervisor is a way to keep the lifecycle of my Elixir Web Applications and a way to start and manage the essential dependencies you will have in your App. E.g., Ecto, Phoenix, Oban, Broadway.&lt;/p&gt;

&lt;p&gt;Suppose you understand how Supervisor Works. It will be much easier to create dependencies of processes and how to start them quickly. Building Elixir applications and understanding core frameworks will be more straightforward in that case. &lt;/p&gt;
&lt;h2&gt;
  
  
  DynamicSupervisor
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;A DynamicSupervisor starts with no children. Instead, children are started on demand via start_child/2. When a dynamic supervisor terminates, all children are shut down at the same time, with no guarantee of ordering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://hexdocs.pm/elixir/1.13/DynamicSupervisor.html" rel="noopener noreferrer"&gt;https://hexdocs.pm/elixir/1.13/DynamicSupervisor.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://elixir-lang.org/getting-started/mix-otp/dynamic-supervisor.html" rel="noopener noreferrer"&gt;https://elixir-lang.org/getting-started/mix-otp/dynamic-supervisor.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DynamicSupervisor starts the process when is necessary, and you can see it easily when you have a Browser opened or a query execution using Ecto. I like creating associations during our typical day as an Elixir Developer because most of the time you will not use DynamycSupervisor/Supervisor. But they are there, you are using them, and you probably will need to debug or understand a piece of code in our core frameworks like ECTO/Phoenix or others. That is why understanding the difference between them and maybe in a day use them. &lt;/p&gt;
&lt;h1&gt;
  
  
  What's worth more? Use Supervisor or DynamicSupervisor
&lt;/h1&gt;

&lt;p&gt;I think you will use both but in a different context&lt;/p&gt;


&lt;h1&gt;
  
  
  Do you remember any stories where this was important to you?
&lt;/h1&gt;

&lt;p&gt;Yes, I do. I remember when I knew only to use Phoenix and Ecto barely, and I had some problems with those frameworks and lifecycles. And also, I was encouraging myself to learn deeply about how Phoenix, Ecto, and Elixir work. &lt;/p&gt;

&lt;p&gt;I had no idea why the application.ex was in my phoenix applications, no idea how the process and supervisors tree works, no idea how a phoenix app works. And I lost a lot of productivity in my day as an Elixir developer because I did not know why/how they worked and why they were there. When I decided to study how they worked and research both, my life as an Elixir developer changed. Elixir's level of skill and productivity was raised 10x more because I only understood how they work.&lt;/p&gt;


&lt;h1&gt;
  
  
  Where do you see people get it wrong the most?
&lt;/h1&gt;

&lt;p&gt;The main problem is you feel comfortable using only libs like Phoenix and Ecto for more than 10 months. Because if you don`t understand how your elixir application works, you will face problems scaling apps using dependencies like Oban, Broadway, or frameworks to use Cache, MongoDb, and even simple GenServer. &lt;/p&gt;

&lt;p&gt;The best way in my experience is:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Am I okay to create standard Phoenix Apps?&lt;/li&gt;
&lt;li&gt;Now I am going to study how Process works.&lt;/li&gt;
&lt;li&gt;Do I know how to make a GenServer/Agents and Tasks? I am going to look at it. &lt;/li&gt;
&lt;li&gt;Do I understand how Supervisor and DynamicSupervisor work? I am good at learning it. &lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;
  
  
  Where to start?
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Level 1
&lt;/h2&gt;

&lt;p&gt;Start a standard Elixir app&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❯ mix new practice                                       

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

&lt;/div&gt;



&lt;p&gt;and create a GenServer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule StocksV1 do
  use GenServer

  def start_link(name: name, valuation: valuation) do
    GenServer.start_link(__MODULE__, valuation, name: name)
  end

  def init(state) do
    {:ok, state}
  end

  def handle_cast({:add, value}, state) do
    state = state + value
    {:noreply, state}
  end

  def add(stock, value) do
    GenServer.cast(stock, {:add, value})
  end
end

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

&lt;/div&gt;



&lt;p&gt;Lets Play around with our Genserver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(4)&amp;gt; StocksV1.start_link name: :etsy, valuation: 10

iex(5)&amp;gt; :sys.get_state :etsy

iex(6)&amp;gt; GenServer.cast :etsy, {:add, 30} 

iex(7)&amp;gt; :sys.get_state :etsy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How about we want to start our stock within our App?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this case, we can use Supervisor but how to start it? &lt;/p&gt;

&lt;p&gt;It is simple, but we need to use the application because we are learning the whole process we need to use the application. And Application is essential for our Libs and Elixir application.&lt;/p&gt;

&lt;p&gt;Read more: &lt;a href="https://hexdocs.pm/elixir/1.13/Application.html" rel="noopener noreferrer"&gt;https://hexdocs.pm/elixir/1.13/Application.html&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Applications are the idiomatic way to package software in Erlang/OTP. To get the idea, they are similar to the "library" concept common in other programming languages, but with some additional characteristics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;straightforward to use it, you only need to add in your &lt;strong&gt;mix.exs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def application do
    [
      extra_applications: [:logger],
      mod: {Practice.Application, []}
    ]
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create &lt;strong&gt;application.ex&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule Practice.Application do
  use Application

  def start(_, _) do
    children = []
    Supervisor.start_link(children, strategy: :one_for_one, name: __MODULE__)
  end
end

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

&lt;/div&gt;



&lt;p&gt;Every time that you create an Application you must create an :erlang.link and in this case our link is our Supervisor. After starting the Supervisor you can only add your process to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule Practice.Application do
  use Application

  def start(_, _) do
    children = [
      {StocksV1, name: :etsy, valuation: 10},
      # {StocksV1, name: :appl, valuation: 10}
    ]
    Supervisor.start_link(children, strategy: :one_for_one, name: __MODULE__)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But you will notice that one of them is commented because you need IDS, and we can`t start it when we want but when we start the application, which makes us move to the next step. Start using DynamicSupervisors.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
defmodule Practice.Application do&lt;br&gt;
  use Application&lt;/p&gt;

&lt;p&gt;def start(_, _) do&lt;br&gt;
    children = [&lt;br&gt;
      {Registry, keys: :unique, name: Stocks},&lt;br&gt;
      {DynamicSupervisor, strategy: :one_for_one, name: Stocks.DynamicSupervisor}&lt;br&gt;
    ]&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Supervisor.start_link(children, strategy: :one_for_one, name: __MODULE__)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;end&lt;br&gt;
end&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
defmodule Stocks do&lt;br&gt;
  use GenServer&lt;/p&gt;

&lt;p&gt;def start_link(name: name, valuation: valuation) do&lt;br&gt;
    name = stock_name(name)&lt;br&gt;
    GenServer.start_link(&lt;strong&gt;MODULE&lt;/strong&gt;, valuation, name: name)&lt;br&gt;
  end&lt;/p&gt;

&lt;p&gt;def stock_name(name) do&lt;br&gt;
    {:via, Registry, {&lt;strong&gt;MODULE&lt;/strong&gt;, name}}&lt;br&gt;
  end&lt;/p&gt;

&lt;p&gt;def init(state) do&lt;br&gt;
    {:ok, state}&lt;br&gt;
  end&lt;/p&gt;

&lt;p&gt;def handle_cast({:add, value}, state) do&lt;br&gt;
    state = state + value&lt;br&gt;
    {:noreply, state}&lt;br&gt;
  end&lt;/p&gt;

&lt;p&gt;def create_stock(name, valuation \ 20) do&lt;br&gt;
    DynamicSupervisor.start_child(&lt;br&gt;
      Stocks.DynamicSupervisor,&lt;br&gt;
      {Stocks, [name: name, valuation: valuation]}&lt;br&gt;
    )&lt;br&gt;
  end&lt;/p&gt;

&lt;p&gt;def add(stock, value) do&lt;br&gt;
    stock = stock_name(stock)&lt;br&gt;
    GenServer.cast(stock, {:add, value})&lt;br&gt;
  end&lt;br&gt;
end&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When you call create_stock, different of a GenServer, you will create a child for your DynamicSupervisor and then. Create a process_id linking to your Parent's process.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
iex(1)&amp;gt; Stocks.create_stock "apple", 100&lt;br&gt;
{:ok, #PID&amp;lt;0.175.0&amp;gt;}&lt;/p&gt;

&lt;p&gt;iex(2)&amp;gt; Stocks.create_stock "alphabet", 300&lt;br&gt;
{:ok, #PID&amp;lt;0.177.0&amp;gt;}&lt;/p&gt;

&lt;p&gt;iex(3)&amp;gt; :sys.get_state pid("0.175.0")&lt;br&gt;
100&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Because we are using Registry, the way that we are creating processes is different. that is why we have the function stock_name, creating the unique ID to our process and then change the state.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
iex(4)&amp;gt; Stocks.add "apple", 300&lt;br&gt;
:ok&lt;br&gt;
iex(5)&amp;gt; :sys.get_state pid("0.175.0")&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;p&gt;If you followed this article, you will notice how simple is to use both of the services when you understand how the process works.&lt;/p&gt;

&lt;p&gt;Social networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>beam</category>
      <category>phoenix</category>
      <category>liveview</category>
    </item>
    <item>
      <title>The most effective way to Setup your machine to use Elixir</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Fri, 19 Aug 2022 12:52:00 +0000</pubDate>
      <link>https://dev.to/theguuholi/the-most-effective-way-to-setup-your-machine-to-use-elixir-2f78</link>
      <guid>https://dev.to/theguuholi/the-most-effective-way-to-setup-your-machine-to-use-elixir-2f78</guid>
      <description>&lt;h1&gt;
  
  
  Greeting
&lt;/h1&gt;

&lt;p&gt;Hello #devElixir!!! Welcome to #FullStackElxpro&lt;/p&gt;

&lt;p&gt;Here we discuss strategies and tips for your Elixir learning journey, from scratch to a hero Elixir developer.&lt;/p&gt;

&lt;p&gt;I am Gustavo, and today&amp;amp;#39;s theme is **Setup your local machine to use Elixir**.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ps: You can follow the Article with &lt;strong&gt;a VIDEO&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about Elixir on a Telegram channel?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elxpro.com/subscribe-elxcrew" rel="noopener noreferrer"&gt;https://elxpro.com/subscribe-elxcrew&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why is it essential to set up your machine to use Elixir?
&lt;/h1&gt;

&lt;p&gt;Having the tools on time will help you be more productive and performant.&lt;/p&gt;

&lt;p&gt;And in addition to letting you perform faster, it will be simple and fast when you have everything you need to develop with Elixir.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do you remember when it was necessary for your career?
&lt;/h1&gt;

&lt;p&gt;For most of the projects I worked on, I noticed how arduous it was to set up my local machine to work with the right tools. When I decided to work with Elixir, I mapped all essential tools to work in multiple scenarios. I got lucky because this setup was always a success. Why do I want to share it with you?  To make your life as an Elixir engineer easier.&lt;/p&gt;

&lt;h1&gt;
  
  
  Let`s start
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Zsh&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zsh is a nice tool to use in your terminal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;brew install zsh zsh-completions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://formulae.brew.sh/formula/curl" rel="noopener noreferrer"&gt;Curl&lt;/a&gt;&lt;/strong&gt;: Sometimes to, test HTTP requests is very usefull&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/tonsky/FiraCode/wiki/Installing" rel="noopener noreferrer"&gt;Firacode&lt;/a&gt;&lt;/strong&gt;: This font is easier to read for a developer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After installing, I highly recommend setting up your terminal with this font.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;OhMyZsh&lt;/a&gt;&lt;/strong&gt;: Nice tool to make your terminal awesome for a developer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://elixir-lang.org/install.html" rel="noopener noreferrer"&gt;Elixir&lt;/a&gt;&lt;/strong&gt;: The most important tool. Elixir lang &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://hexdocs.pm/phoenix/installation.html" rel="noopener noreferrer"&gt;Phoenix&lt;/a&gt;&lt;/strong&gt;: The most important framework. Phoenix to create Web Elixir projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://git-scm.com/download/mac" rel="noopener noreferrer"&gt;GIT&lt;/a&gt;&lt;/strong&gt;: Essential to control version code&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;a href="https://docs.docker.com/engine/install/ubuntu/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;/strong&gt;:
&lt;/h3&gt;

&lt;p&gt;This is one of the most essential tools for a new-age developer. Docker makes our life easier to simulate environments, build our own image projects, and install databases and tools for the developers without dirtying our computers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Redis&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;When I need to use Redis in a project, I install it using docker.&lt;br&gt;
&lt;strong&gt;Mongo&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When I need to use Mongo in a project, I install it using docker.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Kafka&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When I need to use Kafka in a project, I install it using docker. I always use the script below, and it work really well &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://gist.github.com/theguuholi/f33b000d6aa1ee83b4d403574969e4a2" rel="noopener noreferrer"&gt;https://gist.github.com/theguuholi/f33b000d6aa1ee83b4d403574969e4a2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Postgres&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Postgres is an essential Database for those who work with Elixir. And The script below that I provided for you is a way to install the Postgres database easily and fast to start without your need to make any extra configurations in your local machine.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;docker network create pg --driver bridge&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;docker run --name pg --network=pg -e "POSTGRES_PASSWORD=postgres" -p 5432:5432 -v $HOME/docker/volumes/postgres:/var/lib/postgresql/data -d postgres:13.4&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://gigalixir.readthedocs.io/en/latest/getting-started-guide.html#install-the-command-line-interface" rel="noopener noreferrer"&gt;Gigalixir&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A very nice tool to deploy Elixir application and cheap. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Docker-compose&lt;/strong&gt;:  Most of the time, when you install Docker, the tool gives you docker-compose&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://kubernetes.io/docs/setup/production-environment/container-runtimes/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/strong&gt;:  Most of the time, when you install Docker, the tool gives you kubernetes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://k9scli.io/topics/install/" rel="noopener noreferrer"&gt;K9s&lt;/a&gt;&lt;/strong&gt;: Kubernetes CLI To Manage Your Clusters In Style!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://formulae.brew.sh/formula/kubectx" rel="noopener noreferrer"&gt;kubectx&lt;/a&gt;&lt;/strong&gt;: Tool to change kubernetes clusters easily&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/#install-with-homebrew-on-macos" rel="noopener noreferrer"&gt;kubernetes-cli&lt;/a&gt;&lt;/strong&gt;: Tool to execute commands in kubernetes. &lt;/p&gt;

&lt;p&gt;...kubectl..... get, apply... pods, deployments....  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://helm.sh/docs/intro/install/" rel="noopener noreferrer"&gt;Helm&lt;/a&gt;&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Helm helps you manage Kubernetes applications — Helm Charts help you define, install, and upgrade even the most complex Kubernetes application&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://formulae.brew.sh/cask/dbeaver-community" rel="noopener noreferrer"&gt;DBeaver&lt;/a&gt;&lt;/strong&gt;: Access SQL databases &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.conduktor.io/" rel="noopener noreferrer"&gt;Conduktor&lt;/a&gt;&lt;/strong&gt;:&lt;br&gt;
We take the complexity out of Kafka. We give you the tools you need to troubleshoot, develop, test, and collaborate with confidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://docs.insomnia.rest/insomnia/install" rel="noopener noreferrer"&gt;Insomnia&lt;/a&gt;&lt;/strong&gt;: For me, is one the best HTTP tool, also easier to create a good APIs with REST/GraphQL documentation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cloud SDKs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Most of companies use one of them. I prefer google cloud :D &lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Google Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://formulae.brew.sh/cask/google-cloud-sdk" rel="noopener noreferrer"&gt;Google Cloud SDK&lt;/a&gt;&lt;/strong&gt;: Tool to access Google Cloud Services&lt;/p&gt;
&lt;h3&gt;
  
  
  Aws
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://formulae.brew.sh/formula/awscli" rel="noopener noreferrer"&gt;Aws-Cli&lt;/a&gt;&lt;/strong&gt;: Tool to access Aws Services&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://formulae.brew.sh/formula/eksctl" rel="noopener noreferrer"&gt;Eks-ctl&lt;/a&gt;&lt;/strong&gt;: Tool to manage Aws kubernetes&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://code.visualstudio.com/download" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Beautify&lt;/li&gt;
&lt;li&gt;Color Highlight&lt;/li&gt;
&lt;li&gt;ElixirLS&lt;/li&gt;
&lt;li&gt;ENV&lt;/li&gt;
&lt;li&gt;Git Graph&lt;/li&gt;
&lt;li&gt;Live Share&lt;/li&gt;
&lt;li&gt;Markdown All in One&lt;/li&gt;
&lt;li&gt;Material Icon Theme&lt;/li&gt;
&lt;li&gt;Phoenix Framework &lt;/li&gt;
&lt;li&gt;PostCSS Language Support&lt;/li&gt;
&lt;li&gt;Tailwind CSS IntelliSense&lt;/li&gt;
&lt;li&gt;Tools for Apache Kafka &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My &lt;strong&gt;settings.json&lt;/strong&gt; to VSCode: &lt;a href="https://gist.github.com/theguuholi/0a8d3c8ca651f0fe737e10d53415eb20" rel="noopener noreferrer"&gt;https://gist.github.com/theguuholi/0a8d3c8ca651f0fe737e10d53415eb20&lt;/a&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "editor.fontFamily": "Fira Code",
    "editor.fontLigatures": true,
    "emmet.includeLanguages": {
        "html-eex": "html"
    },
    "bracketPairColorizer.consecutivePairColors": [
        [
            "&amp;lt;",
            "&amp;lt;/"
        ],
        [
            "&amp;lt;",
            "/&amp;gt;"
        ],
        [
            "Gold",
            "Orchid",
            "LightSkyBlue"
        ],
        "Red"
    ],
    "files.associations": {
        "*.eex": "html-eex",
        "*.leex": "html-eex",
        "*.heex": "html-eex"
    },
    "beautify.language": {
        "js": {
            "type": [
                "javascript",
                "json",
                "jsonc"
            ],
            "filename": [
                ".jshintrc",
                ".jsbeautifyrc"
            ]
        },
        "css": [
            "css",
            "less",
            "scss"
        ],
        "html": [
            "htm",
            "html",
            "html-eex"
        ]
    },
    "[javascript]": {
        "editor.defaultFormatter": "HookyQR.beautify"
    },
    "[html-eex]": {
        "editor.defaultFormatter": "HookyQR.beautify"
    },
    "workbench.iconTheme": "material-icon-theme",
    "explorer.confirmDelete": false,
    "[json]": {
        "editor.defaultFormatter": "HookyQR.beautify"
    },
    "security.workspace.trust.untrustedFiles": "open",
    "explorer.confirmDragAndDrop": false,
    "diffEditor.ignoreTrimWhitespace": false,
    "terminal.integrated.enableMultiLinePasteWarning": false,
    "editor.bracketPairColorization.enabled": true,
    "editor.guides.bracketPairs": "active",
    "editor.codeActionsOnSave": {

    },
    "[css]": {
        "editor.defaultFormatter": "HookyQR.beautify"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ShortCuts and Zsh
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/zdharma-continuum/zinit" rel="noopener noreferrer"&gt;Install Z-init:&lt;br&gt;
&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash -c "$(curl --fail --show-error --silent --location https://raw.githubusercontent.com/zdharma-continuum/zinit/HEAD/scripts/install.sh)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plugins Zinit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zinit light zdharma/fast-syntax-highlighting
zinit light zsh-users/zsh-autosuggestions
zinit light zsh-users/zsh-completions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;zdharma/fast-syntax-highlighting: recognize commands&lt;br&gt;
zsh-users/zsh-autosuggestions: suggest commands.&lt;br&gt;
zsh-users/zsh-completion: add commands&lt;/p&gt;

&lt;p&gt;My Zshrc config: &lt;br&gt;
&lt;a href="https://gist.github.com/theguuholi/d5da8b11d100f04290f8ba203f991767" rel="noopener noreferrer"&gt;https://gist.github.com/theguuholi/d5da8b11d100f04290f8ba203f991767&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Social networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ElxproBr - &lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>programing</category>
      <category>beam</category>
      <category>phoenix</category>
    </item>
    <item>
      <title>If you already created LiveView pages without this, read this article.</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Wed, 03 Aug 2022 19:14:00 +0000</pubDate>
      <link>https://dev.to/theguuholi/if-you-already-created-liveview-pages-without-this-read-this-article-3l87</link>
      <guid>https://dev.to/theguuholi/if-you-already-created-liveview-pages-without-this-read-this-article-3l87</guid>
      <description>&lt;h1&gt;
  
  
  Greeting
&lt;/h1&gt;

&lt;p&gt;Hello #devElixir!!! Welcome to #FullStackElxpro&lt;/p&gt;

&lt;p&gt;Here we discuss strategies and tips for your Elixir learning journey. This is from scratch until your first wave as an elixir developer.&lt;/p&gt;

&lt;p&gt;I am Gustavo, and today&amp;amp;#39;s theme is **LiveView Pages**.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ps: You can follow the Article with &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=MEQbfw9OItE" rel="noopener noreferrer"&gt;a VIDEO&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about Elixir on a Telegram channel?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elxpro.com/subscribe-elxcrew" rel="noopener noreferrer"&gt;https://elxpro.com/subscribe-elxcrew&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;You can read &lt;strong&gt;temporary_assign&lt;/strong&gt; on &lt;a href="https://hexdocs.pm/phoenix_live_view/dom-patching.html#temporary-assigns" rel="noopener noreferrer"&gt;Elixir Documentation&lt;/a&gt;, but for me, it was really hard to understand. I will explain it to you using what is temporary_assign for me, and you can get your conclusion.&lt;/p&gt;

&lt;p&gt;For me, &lt;strong&gt;temporary_assign&lt;/strong&gt; with &lt;strong&gt;phx-update&lt;/strong&gt; is a simpler way to prevent bugs in your LiveView pages when you have lists and possible real-time interactions with your pages, defining the best behavior with your team, product owners, and UX.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I figure that out?
&lt;/h2&gt;

&lt;p&gt;When you are building LiveView pages, you probably just care about getting things done or getting the expected behavior; when you load/reload pages, your list will work normally, and the default behavior is a prepend on the list. But some bugs appear when necessary to update a list, and the elements are the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is temporary_assign so important?
&lt;/h2&gt;

&lt;p&gt;It is so straightforward to use and can avoid many future problems. With a couple of lines implemented, you only need to define what is important in your list and what is a possible expected behavior when you update that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why temporary_assign can get consistent LiveView pages.
&lt;/h2&gt;

&lt;p&gt;Because you can only define the expected behavior when new elements come, and if you don`t have this feature, for now, you can prevent kind of a bug in the future with only a few ways to think in your elements when you use &lt;strong&gt;temporary_assign&lt;/strong&gt; and &lt;strong&gt;phx-updates&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use temporary_assign to get consistent LiveView Pages.
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Without temporary_assigns example
&lt;/h3&gt;

&lt;p&gt;If you use temporary_assigns and add new elements to your screen, the default behavior will be prepended and does not matter the ID.&lt;/p&gt;

&lt;p&gt;...Live do&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
  def mount(_, _, socket) do&lt;br&gt;
    messages = Enum.map(1..3, &amp;amp;%{id: &amp;amp;1, username: "gus #{&amp;amp;1}", text: "pumpkin  #{&amp;amp;1}"})&lt;br&gt;
    socket = assign(socket, messages: messages)&lt;br&gt;
    {:ok, socket}&lt;br&gt;
  end&lt;/p&gt;

&lt;p&gt;def handle_info({:u_msg, message}, socket) do&lt;br&gt;
    {:noreply, update(socket, :messages, fn messages -&amp;gt; [message | messages] end)}&lt;br&gt;
  end&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;...html.heex&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
    &amp;lt;%= self |&amp;gt; :erlang.pid_to_list %&amp;gt;&lt;br&gt;
    &amp;lt;ul&amp;gt;&lt;br&gt;
        &amp;lt;%= for message &amp;lt;- @messages do %&amp;gt;&lt;br&gt;
        &amp;lt;li&amp;gt;&lt;br&gt;
            &amp;lt;p&amp;gt;&amp;lt;span&amp;gt;&amp;lt;%= message.username %&amp;gt;:&amp;lt;/span&amp;gt; &amp;lt;%= message.text %&amp;gt;&amp;lt;/p&amp;gt;&lt;br&gt;
        &amp;lt;/li&amp;gt;&lt;br&gt;
        &amp;lt;% end %&amp;gt;&lt;br&gt;
    &amp;lt;/ul&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
iex(4)&amp;gt; pid = pid("0.698.0")&lt;/p&gt;

&lt;h1&gt;
  
  
  PID&amp;lt;0.698.0&amp;gt;
&lt;/h1&gt;

&lt;p&gt;iex(5)&amp;gt;  msg = %{username: "gus 234234", text: "pumpkin 1", id: :rand.uniform(10_000)}&lt;br&gt;
%{id: 870, text: "pumpkin 1", username: "gus 234234"}&lt;br&gt;
iex(6)&amp;gt; send pid, {:u_msg, msg}&lt;br&gt;&lt;br&gt;
{:u_msg, %{id: 870, text: "pumpkin 1", username: "gus 234234"}}&lt;br&gt;
iex(7)&amp;gt; send pid, {:u_msg, msg}&lt;br&gt;&lt;br&gt;
{:u_msg, %{id: 870, text: "pumpkin 1", username: "gus 234234"}}&lt;br&gt;
iex(8)&amp;gt; &lt;/p&gt;

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

&lt;h3&gt;
  
  
  Only temporary_assigns example
&lt;/h3&gt;

&lt;p&gt;After defining what property element is temporary_assign and what will happen after receiving a new element, LiveView will delete every element and include the new one happening because now we have started using the default behavior &lt;code&gt;replace.&lt;/code&gt; Now, define what you expect when a new element is added to your list using the useful article LiveView documentation provides us on the link below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hexdocs.pm/phoenix_live_view/dom-patching.html" rel="noopener noreferrer"&gt;https://hexdocs.pm/phoenix_live_view/dom-patching.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
  def mount(_, _, socket) do&lt;br&gt;
    messages = Enum.map(1..3, &amp;amp;%{id: &amp;amp;1, username: "gus #{&amp;amp;1}", text: "pumpkin  #{&amp;amp;1}"})&lt;br&gt;
    socket = assign(socket, messages: messages)&lt;br&gt;
    {:ok, socket, temporary_assigns: [messages: []]}&lt;br&gt;
  end&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
 msg = %{username: "gus #{:rand.uniform(10_000)}", text: "pumpkin #{:rand.uniform(10_000)}", id: :rand.uniform(10_000)}&lt;br&gt;
%{id: 9282, text: "pumpkin 7151", username: "gus 5213"}&lt;br&gt;
iex(35)&amp;gt; send pid, {:u_msg, msg}                                                                {:u_msg, %{id: 9282, text: "pumpkin 7151", username: "gus 5213"}}&lt;br&gt;
iex(36)&amp;gt; &lt;/p&gt;

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

&lt;h3&gt;
  
  
  The power of temporary_assigns and DOM patching.
&lt;/h3&gt;

&lt;p&gt;When you use &lt;code&gt;phx-update&lt;/code&gt; with &lt;code&gt;temporary_assign,&lt;/code&gt; magic happens. You can define how to order your elements, not repeat the same element on your screen and define the best behavior for your user by simply adding phx-update. &lt;/p&gt;

&lt;p&gt;Of course, you need to include an ID attribute in your &lt;code&gt;phx-update,&lt;/code&gt; and every element in your list must also have an ID attribute.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
    &lt;/p&gt;
&lt;ul id="msgs"&gt;

        &amp;lt;%= for message &amp;lt;- @messages do %&amp;gt;
        &lt;li id="{Integer.to_string(message.id)}"&gt;

            &lt;p&gt;&lt;span&gt;&amp;lt;%= message.username %&amp;gt;:&lt;/span&gt; &amp;lt;%= message.text %&amp;gt;&lt;/p&gt;

        &lt;/li&gt;

        &amp;lt;% end %&amp;gt;
    &lt;/ul&gt;


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

&lt;p&gt;Take a look an try by your self :D&lt;/p&gt;

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

&lt;p&gt;iex(33)&amp;gt; send pid, {:u_msg, msg}&lt;br&gt;&lt;br&gt;
{:u_msg, %{id: 6719, text: "pumpkin 2150", username: "gus 8319"}}&lt;br&gt;
iex(34)&amp;gt;  msg = %{username: "gus #{:rand.uniform(10_000)}", text: "pumpkin #{:rand.uniform(10_000)}", id: :rand.uniform(10_000)}&lt;br&gt;
%{id: 9282, text: "pumpkin 7151", username: "gus 5213"}&lt;br&gt;
iex(35)&amp;gt; send pid, {:u_msg, msg}                                                                {:u_msg, %{id: 9282, text: "pumpkin 7151", username: "gus 5213"}}&lt;br&gt;
iex(36)&amp;gt; &lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  THE END.
&lt;/h1&gt;

&lt;p&gt;After this article, I hope you understand how important it is to use temporary_assigns and phx-update. See you next time BYE!!!&lt;/p&gt;

&lt;p&gt;Social networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ElxproBr - &lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>liveview</category>
      <category>elixir</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Read this Article if you want to learn Elixir with GenServer.</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Tue, 02 Aug 2022 17:37:00 +0000</pubDate>
      <link>https://dev.to/theguuholi/read-this-article-if-you-want-to-learn-genserver-1l24</link>
      <guid>https://dev.to/theguuholi/read-this-article-if-you-want-to-learn-genserver-1l24</guid>
      <description>&lt;h1&gt;
  
  
  Greeting
&lt;/h1&gt;

&lt;p&gt;Hello #devElixir!!! Welcome to #FullStackElxpro&lt;/p&gt;

&lt;p&gt;Here we discuss strategies and tips for your Elixir learning journey, from scratch to a hero Elixir developer.&lt;/p&gt;

&lt;p&gt;I am Gustavo, and today's theme is &lt;strong&gt;GenServer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ps: You can follow the Article with &lt;strong&gt;a &lt;a href="https://youtu.be/uBBPdfvHLZ0" rel="noopener noreferrer"&gt;VIDEO&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about Elixir on a Telegram channel?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://elxpro.com/subscribe-elxcrew" rel="noopener noreferrer"&gt;https://elxpro.com/subscribe-elxcrew&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is a GenServer?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://hexdocs.pm/elixir/GenServer.html" rel="noopener noreferrer"&gt;GenServer&lt;/a&gt; is a process like any other Elixir process (&lt;em&gt;Tasks, Spawn, Agents&lt;/em&gt;). It can be used to manage state and execute code asynchronously and includes some handy functionality around tracing and error reporting.&lt;/p&gt;

&lt;p&gt;And for me, as a Liveview evangelist is one of the best ways to learn what you have behind the LiveView Apps, providing a better way to organize, think and isolate pieces of code.&lt;/p&gt;

&lt;p&gt;Before we move forward, I think it is essential to read &lt;a href="https://hexdocs.pm/elixir/GenServer.html#module-when-not-to-use-a-genserver" rel="noopener noreferrer"&gt;When Not Use GenServer&lt;/a&gt;. Because one of the biggest mistakes you can make is using GenServer for Everything, which is unnecessary.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the difference between GenServer, Tasks, and Agents?
&lt;/h1&gt;

&lt;p&gt;Before you keep reading this article, I highly recommend watching the video about Elixir's processes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/em4QECkQx4s" rel="noopener noreferrer"&gt;https://youtu.be/em4QECkQx4s&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GenServer&lt;/strong&gt; : The GenServer behaviour abstracts the common client-server interaction. Developers are only required to implement the callbacks and functionality they are interested in.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hexdocs.pm/elixir/Task.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Tasks&lt;/strong&gt;&lt;/a&gt;: Tasks are processes meant to execute one particular action throughout their lifetime, often with little or no communication with other processes. The most common use case for tasks is to convert sequential code into concurrent code by computing a value asynchronously.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hexdocs.pm/elixir/Agent.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Agents&lt;/strong&gt;&lt;/a&gt;: Agents are a simple abstraction around state.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why is GenServer Important?
&lt;/h1&gt;

&lt;p&gt;I have seen developers who start their career as Elixir developers but don't understand the basic concepts of how Elixir works.&lt;/p&gt;

&lt;p&gt;Elixir is not a normal programming language. I mean that because Frontend Developers usually come to Elixir from React, Angular, and Vue, all of which use JavaScript and oriented programming languages. And daily, they face difficulties understanding what is behind LiveView, how to split components, and thinking in &lt;strong&gt;single responsibilities principles.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They don't understand it because of two simple things. Behind Elixir, there are processes, and LiveView is very similar to a GenServer.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is the best moment to use GenServer?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Handle Sync and Async Calls:&lt;/strong&gt; As we discussed, the main purpose of a GenServer is not to Code Organization but as a way to keep the state and manipulate it easily. Example &lt;strong&gt;Shopping Cart&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;System Messages:&lt;/strong&gt; You can see some examples when you create ways to use &lt;em&gt;spawn, send and receive&lt;/em&gt;_ &lt;strong&gt;. As&lt;/strong&gt; _ I mentioned, I recorded a video explaining how the process works, and one of the examples is a simulation of how to access the database and execute a query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring Events:&lt;/strong&gt; Imagine that you have a company monitoring company stocks every second. The stocks' assets rise and fall every second.&lt;/p&gt;

&lt;h1&gt;
  
  
  Where to start?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Callbacks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;init/1 (required) - invoked when the server is started and sets the initial state&lt;/li&gt;
&lt;li&gt;handle_cast/2 - invoked when GenServer.cast/2 is called to handle messages asynchronously&lt;/li&gt;
&lt;li&gt;handle_call/3 - invoked when GenServer.call/3 is called to handle messages synchronously

&lt;ul&gt;
&lt;li&gt;call/3 will block until a reply is received (unless the call times out or nodes are disconnected)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;handle_info/2 - invoked to handle all other messages (i.e., outside of those triggered by GenServer.call/3 and GenServer.cast/2, and &lt;a href="https://erlang.org/doc/design_principles/spec_proc.html#msg" rel="noopener noreferrer"&gt;"system" messages&lt;/a&gt;)

&lt;ul&gt;
&lt;li&gt;g., messages/events handled internally within the GenServer&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;terminate/2 - invoked when the GenServer is about to exit&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Init
&lt;/h2&gt;

&lt;p&gt;Before we talk about Init, we must talk about&amp;nbsp;&lt;strong&gt;start_link&amp;nbsp;&lt;/strong&gt;together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;start_link&lt;/strong&gt;: when it is called, the new process created will call&amp;nbsp;&lt;strong&gt;init&lt;/strong&gt;, and&amp;nbsp;&lt;strong&gt;init&lt;/strong&gt;&amp;nbsp;will start the state, which is an empty map, and the parent of&amp;nbsp;&lt;strong&gt;ShoppingCart&amp;nbsp;&lt;/strong&gt;is the IEX terminal.&lt;/p&gt;

&lt;p&gt;Take a look at the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule ShoppingCart do
  use GenServer

  def start_link([name, state]) do
    IO.inspect(state, label: "start_link")
    GenServer.start_link(__MODULE__, state, name: name)
  end

  def init(state) do
    IO.inspect state, label: "init"
    {:ok, state}
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt; ShoppingCart.start_link [:elxpro_cart, []]
start_link: []
init: []
{:ok, #PID&amp;lt;0.161.0&amp;gt;}
iex(2)&amp;gt; Process.whereis :elxpro_cart
#PID&amp;lt;0.161.0&amp;gt;
iex(3)&amp;gt; self   
#PID&amp;lt;0.159.0&amp;gt;
iex(4)&amp;gt; :observer.start

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

&lt;/div&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%2Fgvdmcnweflbuudvfoxog.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%2Fgvdmcnweflbuudvfoxog.png" alt=" " width="799" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  HandleCast
&lt;/h2&gt;




&lt;p&gt;Invoked when GenServer.cast/2 is called to handle messages asynchronously&lt;/p&gt;

&lt;p&gt;In our example, imagine that you need to add a new product to your cart but don't care how many products you have there. You only want to add it is a perfect example of how to call&amp;nbsp;&lt;strong&gt;handle_cast.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def handle_cast({:add, product}, state) do
    state = state ++ [product]
    {:noreply, state}
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt; ShoppingCart.start_link [:cart_1, []]
start_link: []
init: []
{:ok, #PID&amp;lt;0.151.0&amp;gt;}

iex(2)&amp;gt; GenServer.cast :cart_1, {:add, %{name: "Pumpkin", price: 10}}

iex(3)&amp;gt; "0.151.0" |&amp;gt; pid |&amp;gt; :sys.get_state
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  HandleCall
&lt;/h2&gt;




&lt;p&gt;The&amp;nbsp;&lt;strong&gt;handle_call&lt;/strong&gt;/3 callback is invoked when GenServer.call/3 is called to handle synchronous messages. The main params are&amp;nbsp;&lt;strong&gt;function_pattern_mathing&lt;/strong&gt;,&amp;nbsp;&lt;strong&gt;_from,&lt;/strong&gt;&amp;nbsp;&lt;strong&gt;state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;function_pattern_mathing:&amp;nbsp;&lt;/strong&gt;a Way to identify how to call the function&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_from:&amp;nbsp;&lt;/strong&gt;most of the time is the process_id that calls the function, and most of the time is useful&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;state:&amp;nbsp;&lt;/strong&gt;actual component state.&lt;/p&gt;

&lt;p&gt;And the most common return is*&lt;em&gt;&amp;nbsp;{:reply, response, state}&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reply:&amp;nbsp;&lt;/strong&gt;indicates that those who called the process will receive a message result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Response:&lt;/strong&gt;&amp;nbsp;message to return for who called the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State:&amp;nbsp;&lt;/strong&gt;update process state.&lt;/p&gt;

&lt;p&gt;Check the example, Bellow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def handle_call(:apply_discount, _from, state) do
    state = Enum.map(state, &amp;amp;%{&amp;amp;1 | price: &amp;amp;1.price - 1})
    products = Enum.map(state, &amp;amp;(&amp;amp;1.name &amp;lt;&amp;gt; " "))
    {:reply, "Discount applied to: #{products}", state}
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt; ShoppingCart.start_link [:cart_1, []]
start_link: []
init: []
{:ok, #PID&amp;lt;0.161.0&amp;gt;}


iex(2)&amp;gt;  GenServer.cast :cart_1, {:add, %{name: "Pumpkin", price: 10}}

iex(3)&amp;gt;   GenServer.cast :cart_1, {:add, %{name: "Gatorade", price: 20}}


iex(6)&amp;gt;  GenServer.call :cart_1, :apply_discount            
Result: "Discount applied to: Pumpkin Gatorade "

State: 
iex(7)&amp;gt;   pid = "0.161.0" |&amp;gt; pid |&amp;gt; :sys.get_state
[%{name: "Pumpkin", price: 8}, %{name: "Gatorade", price: 18}]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  HandleInfo
&lt;/h2&gt;

&lt;p&gt;The handle_info/2 callback is invoked to handle all other messages (i.e., outside of those triggered by GenServer.call/3 and GenServer.cast/2)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  def handle_info(:increase_price, state) do
    state = Enum.map(state, &amp;amp;%{&amp;amp;1 | price: &amp;amp;1.price + 1})
    {:noreply, state}
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex(1)&amp;gt;  ShoppingCart.start_link [:cart_1, []]
iex(2)&amp;gt; GenServer.cast :cart_1, {:add, %{name: "Pumpkin", price: 10}}
iex(3)&amp;gt; pid = pid("0.161.0")                

iex(4)&amp;gt; :sys.get_state(pid)
[%{name: "Pumpkin", price: 10}]

iex(5)&amp;gt; send pid, :increase_price
iex(6)&amp;gt; :sys.get_state(pid)      
[%{name: "Pumpkin", price: 11}]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule ShoppingCart do
  use GenServer

  def start_link([name, state]) do
    IO.inspect(state, label: "start_link")
    GenServer.start_link(__MODULE__, state, name: name)
  end

  def init(state) do
    IO.inspect(state, label: "init")
    {:ok, state}
  end

  def handle_cast({:add, product}, state) do
    state = state ++ [product]
    {:noreply, state}
  end

  def handle_call(:apply_discount, _from, state) do
    state = Enum.map(state, &amp;amp;%{&amp;amp;1 | price: &amp;amp;1.price - 1})
    products = Enum.map(state, &amp;amp;(&amp;amp;1.name &amp;lt;&amp;gt; " "))
    {:reply, "Discount applied to: #{products}", state}
  end

  def handle_info(:increase_price, state) do
    state = Enum.map(state, &amp;amp;%{&amp;amp;1 | price: &amp;amp;1.price + 1})
    {:noreply, state}
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  THE END.
&lt;/h1&gt;

&lt;p&gt;The main goal of this Article is to help you understand how easy it is GenServer and after couple examples, you can possibly create simpler LiveView Pages and Elixir Codes&lt;/p&gt;

&lt;p&gt;Social networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ElxproBr - &lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>liveview</category>
      <category>phoenix</category>
      <category>programming</category>
    </item>
    <item>
      <title>Understand why LibCluster is essential for your Phoenix Liveview applications</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Tue, 12 Jul 2022 17:35:42 +0000</pubDate>
      <link>https://dev.to/theguuholi/understand-why-libcluster-is-essential-for-your-phoenix-liveview-applications-4c5a</link>
      <guid>https://dev.to/theguuholi/understand-why-libcluster-is-essential-for-your-phoenix-liveview-applications-4c5a</guid>
      <description>&lt;h1&gt;
  
  
  Greeting
&lt;/h1&gt;

&lt;p&gt;Hello #devElixir!!! Welcome to #FullStackElxpro&lt;/p&gt;

&lt;p&gt;Here we discuss strategies and tips for your Elixir learning journey. This is from scratch until your first wave as an elixir developer&lt;/p&gt;

&lt;p&gt;I am Gustavo and today's theme is: &lt;strong&gt;Understand why LibCluster is essential for your Phoenix Liveview applications&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;_ps: You can follow the article with &lt;strong&gt;VIDEO&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about elixir on a Telegram channel?&lt;/em&gt;&lt;br&gt;
&lt;a href="https://elxpro.com/subscribe-elxcrew" rel="noopener noreferrer"&gt;https://elxpro.com/subscribe-elxcrew&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Which is?
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;LibCluster&lt;/strong&gt; is a library that proves a simple way of connecting between &lt;strong&gt;ERLANG NODES&lt;/strong&gt; that facilitates cluster communication.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why is &lt;strong&gt;LibCluster&lt;/strong&gt; important?
&lt;/h1&gt;

&lt;p&gt;It becomes important from the moment you have distributed systems and you create communication in a simple way between them, where there is a huge difficulty in creating &lt;em&gt;listeners&lt;/em&gt; when a need is running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you read the &lt;a href="https://www.youtube.com/watch?v=Yo5w6E8QxeU" rel="noopener noreferrer"&gt;article/video&lt;/a&gt; about &lt;em&gt;Nodes&lt;/em&gt; you probably know how to connect two applications in Elixir in a simple way, however, how do you get this environment in production? how are you going to detect these nodes in a Kubernetes cluster?, like this communication between different IPs in a simple way? create code for it?&lt;/p&gt;

&lt;p&gt;The best way to create it is through LibCluster (the article about nodes teaches you what's under the hood)&lt;/p&gt;

&lt;h1&gt;
  
  
  How did you find this out?
&lt;/h1&gt;

&lt;p&gt;One of the first libraries I learned about has more than 4 years of journey as an Elixir developer, there was always talk about the benefits of Elixir, it was the agent that had the advantage of distributed systems that were little or not used. But in a project using &lt;strong&gt;LiveView&lt;/strong&gt; the &lt;strong&gt;LibCluster&lt;/strong&gt; becomes more than mandatory and it was the case of a project that I can work on.&lt;/p&gt;

&lt;h1&gt;
  
  
  What are the advantages of using &lt;strong&gt;LibCluster&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;The main advantage is to create connections between applications quickly, without having to connect nodes, generators, and OTP. LibCluster will abstract all these rules into a simple configuration.&lt;/p&gt;

&lt;h1&gt;
  
  
  When is the best time to implement &lt;strong&gt;LibCluster&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;At the beginning of my career, I noticed essential things like implementation in Elixir, and I believe that today LibCluster is one of them. &lt;strong&gt;especially if you use live preview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can start implementing LibCluster in Dev using the strategy of &lt;a href="https://hexdocs.pm/libcluster/Cluster.Strategy.Gossip.html" rel="noopener noreferrer"&gt;&lt;em&gt;Gossip&lt;/em&gt;&lt;/a&gt; as it is one of the simplest and easiest to understand LibCluster, and when for production will depend on whether you are going to use Kubernetes, ECS, or any other environment. I work with clusters in Kubernetes and implement DNS.&lt;/p&gt;

&lt;h1&gt;
  
  
  THE END.
&lt;/h1&gt;

&lt;p&gt;I hope the article helped you understand the need and urgency of how to use LibCluster in your applications. :D&lt;/p&gt;

&lt;p&gt;Social networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ElxproBr - &lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>liveview</category>
      <category>phoenix</category>
      <category>elixir</category>
      <category>programming</category>
    </item>
    <item>
      <title>The worst way to handle sessions using Phoenix LiveView.</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Tue, 12 Jul 2022 17:23:27 +0000</pubDate>
      <link>https://dev.to/theguuholi/the-worst-way-to-handle-sessions-using-phoenix-liveview-4kld</link>
      <guid>https://dev.to/theguuholi/the-worst-way-to-handle-sessions-using-phoenix-liveview-4kld</guid>
      <description>&lt;h1&gt;
  
  
  Greeting
&lt;/h1&gt;

&lt;p&gt;Hello #devElixir!!! Welcome to #FullStackElxpro&lt;/p&gt;

&lt;p&gt;Here we discuss strategies and tips for your Elixir learning journey. This is from scratch until your first wave as an elixir developer&lt;/p&gt;

&lt;p&gt;I am Gustavo and today's theme is: &lt;strong&gt;The worst way to handle sessions using Phoenix LiveView.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;_ps: You can follow the article with &lt;strong&gt;&lt;a href="https://youtu.be/0_XNM-JvcT8" rel="noopener noreferrer"&gt;VIDEO&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want to learn more about elixir on a Telegram channel?&lt;/em&gt;&lt;br&gt;
&lt;a href="https://elxpro.com/subscribe-elxcrew" rel="noopener noreferrer"&gt;https://elxpro.com/subscribe-elxcrew&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Which is?
&lt;/h1&gt;

&lt;p&gt;The session is something temporary in an application. It is nothing more and nothing less than that.&lt;/p&gt;

&lt;p&gt;However, in Elixir, Phoenix, and Liveview (mainly the web part) there are several ways to work with the session.&lt;/p&gt;

&lt;p&gt;Can use:&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://hexdocs.pm/phoenix/plug.html" rel="noopener noreferrer"&gt;Plugs&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Which is a connection middleware and through this middleware persists data and reads data in a session. And there are several plugs to deal with this middle of this one, but this is not the case in this article&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://hexdocs.pm/phoenix/Phoenix.Token.html" rel="noopener noreferrer"&gt;Phoenix Token&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;And a way to use and save data that expires in a simple way&lt;/p&gt;
&lt;h2&gt;
  
  
  Live view
&lt;/h2&gt;

&lt;p&gt;There are several ways like session_storage, local_storage (as long as you use hooks), and live_session. And you can check out all kinds of approaches.&lt;/p&gt;

&lt;p&gt;What is your live_session and why use it, as several advantages and approaches are straightforward that will in this article make a difference in the maintenance and readability of the application.&lt;/p&gt;
&lt;h1&gt;
  
  
  What is the difference between &lt;strong&gt;sessions&lt;/strong&gt; and &lt;strong&gt;live_session&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;The main difference is that the main focus of the session is on the connection, the persistent data traffic on the connection.&lt;/p&gt;

&lt;p&gt;Now in the live_session you can get the data from the &lt;em&gt;session&lt;/em&gt;, include it in the &lt;strong&gt;socket&lt;/strong&gt;, and also program generic events on your page, which is a lot not to replicate code, in short, it's a middleware with superpowers.&lt;/p&gt;
&lt;h1&gt;
  
  
  How did you find this out?
&lt;/h1&gt;

&lt;p&gt;The way I found out, was by reading the phoenix 1.5 to 1.6 update. And when the &lt;strong&gt;_session&lt;/strong&gt; appeared, I thought there was no need for live. But I had pagination in an app that was working on a shared header using a live view within a live view.&lt;/p&gt;

&lt;p&gt;If you understand processes, there was one process monitoring another an absurd complexity to create communication, it took a long time to understand how **OTP, Elixir, Processes under the hood and I even understand it all, and one solution (solution) was so verbose and complicated to handle.&lt;/p&gt;

&lt;p&gt;At this event I had already worked with &lt;strong&gt;live_session&lt;/strong&gt; on other projects (outside the Company), and I saw the power and amount of benefits that live_session brings to the new version of &lt;strong&gt;Phoenix Liveview&lt;/strong&gt; through a conversation about code decisions I presented the solution and everyone liked it and the implementation was very simple.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ps: (I won't show a solution developed in this article, however, in the end, you will be able to create solutions better than I implemented)&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Why is &lt;strong&gt;live_session&lt;/strong&gt; important?
&lt;/h1&gt;

&lt;p&gt;The great importance and question of superpowers that are easy to use. One of the game changers from version 1.5 to 1.6 was &lt;em&gt;live_session&lt;/em&gt; because you don't need to write a lot of code, with just a few lines you'll be able to interact with the socket and include implementations and events, and especially create user rules.&lt;/p&gt;
&lt;h1&gt;
  
  
  What is the biggest benefit of &lt;strong&gt;live_session&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;The biggest benefit is the issue of handling a socket as a session.&lt;/p&gt;
&lt;h1&gt;
  
  
  Do you remember any stories where this was important to you?
&lt;/h1&gt;

&lt;p&gt;As I mentioned, the main one was your question about information generically designated in the socket, without having to replicate code something that the developers think and are.&lt;/p&gt;

&lt;p&gt;And the other one was when I needed to trigger events from &lt;strong&gt;handle_events, handle_infos, handle_params&lt;/strong&gt; without having to implement it on every page&lt;/p&gt;
&lt;h1&gt;
  
  
  How to create &lt;strong&gt;live_sessions&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;You can start by understanding why. Some questions may help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I need to share this information on more than 1 page?&lt;/li&gt;
&lt;li&gt;Does this event need to be replicated on more than one page?&lt;/li&gt;
&lt;li&gt;Do I need to create any generalized trading rules?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is yes, &lt;strong&gt;&lt;a href="https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Router.html#live_session/3" rel="noopener noreferrer"&gt;live_session&lt;/a&gt;&lt;/strong&gt; is the best option.&lt;/p&gt;

&lt;p&gt;You can see in the image below that it was necessary to implement just a few lines of code and live_session starts to behave like a &lt;em&gt;middleware&lt;/em&gt;&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%2Fdw10zivsq0roly4fvjvj.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%2Fdw10zivsq0roly4fvjvj.png" alt=" " width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before starting any session what &lt;strong&gt;live_session&lt;/strong&gt; will do is call the permission module, check the scope (which is more than amazing pattern matching), and sign new information into the socket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule LiveSessions.Permissions do
  import Phoenix.LiveView
  alias FoodOrder.Accounts
  alias FoodOrderWeb.Router.Helpers, such as: Routes
  alias LiveSessions.CreateCart

  def on_mount(:user, _params, %{"user_token" =&amp;gt; user_token}, socket) do
    assign_user(socket, :user, user_token)
  The end

  def on_mount(:admin, _params, %{"user_token" =&amp;gt; user_token}, socket) do
    assign_user(socket, :admin, user_token)
  The end

  defp assign_user(socket, _,nil) do
    error_login(socket, "You must be logged in")
  The end

  defp assign_user(socket, :user, user_token) do
    current_user = Accounts.get_user_by_session_token(user_token)
    cart_id = get_connect_params(socket)["cart_id"]

    socket =
      socket
      |&amp;gt; assign_new(:current_user, fn -&amp;gt; current_user end)
      |&amp;gt; CreateCart.execute(cart_id)

    {:cont, socket}
  The end

  defp assign_user(socket, :admin, user_token) do
    user_token
    |&amp;gt; Accounts.get_user_by_session_token()
    |&amp;gt; return_socket(socket)
  The end

  defp return_socket(%{role: role}, socket) when role != :ADMIN,
    do: error_login(socket, "You do not have permission to access this page")

  defp return_socket(current_user, socket),
    do: {:cont, assign_new(socket, :current_user, fn -&amp;gt; current_user end)}

  defp error_login(socket, message) do
    socket =
      socket
      |&amp;gt; put_flash(:error, message)
      |&amp;gt; redirect(to: Routes.main_path(socket, :index))

    {:stop, socket}
  The end
The end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;p&gt;I hope I helped you in your learning, I always recommend visiting youtube videos, it usually has more resources. A big hug!!&lt;/p&gt;

&lt;p&gt;Social networks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Twitter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ElxproBr - &lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>liveview</category>
      <category>phoenix</category>
      <category>elixir</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Entenda o porque o LibCluster e essencial para suas aplicacoes em Phoenix Liveview</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Mon, 11 Jul 2022 11:13:46 +0000</pubDate>
      <link>https://dev.to/theguuholi/entenda-o-porque-o-libcluster-e-essencial-para-suas-aplicacoes-em-phoenix-liveview-2h4</link>
      <guid>https://dev.to/theguuholi/entenda-o-porque-o-libcluster-e-essencial-para-suas-aplicacoes-em-phoenix-liveview-2h4</guid>
      <description>&lt;h1&gt;
  
  
  Saudacao
&lt;/h1&gt;

&lt;p&gt;Seja muito bem vindo, seja muito bem vinda ao #FullstackElxpro&lt;/p&gt;

&lt;p&gt;Aqui nós discutimos as estratégias e dicas de sua jornada de aprendizado em Elixir. Isso é do zero até a sua primeira vaga como desenvolvedor elixir&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Eu sou o Gustavo e o tema de hoje é: &lt;strong&gt;A pior maneira de lidar com sessoes com Phoenix Liveview.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;_ps: Voce pode acompanhar o artigo com o &lt;a href="https://youtu.be/GBQ6zw3aXr4" rel="noopener noreferrer"&gt;video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quer aprender mais sobre elixir em um canal do Telegram?&lt;/em&gt;&lt;br&gt;
&lt;a href="https://elxpro.com/elxcrew-org-yt-descr" rel="noopener noreferrer"&gt;https://elxpro.com/elxcrew-org-yt-descr&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é?
&lt;/h1&gt;

&lt;p&gt;O &lt;strong&gt;libcluster&lt;/strong&gt; e uma biblioteca que prove uma maneira simples de conexao entre &lt;strong&gt;ERLANG NODES&lt;/strong&gt; que facilita a comunicacao de clusters. &lt;/p&gt;

&lt;h1&gt;
  
  
  Por quê &lt;strong&gt;LibCluster&lt;/strong&gt; é importante?
&lt;/h1&gt;

&lt;p&gt;Passa a ser importante a partir do momento em que voce tem sistemas distribuidos e voce precisa de criar comunicacao de maneira simples entre eles, onde existe uma dificuldade enorme de criar &lt;em&gt;listeners&lt;/em&gt; quando uma aplicacao esta em execucao. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se voce leu o &lt;a href="https://www.youtube.com/watch?v=Yo5w6E8QxeU" rel="noopener noreferrer"&gt;artigo/video&lt;/a&gt; sobre &lt;em&gt;Nodes&lt;/em&gt; voce provavelmente sabe como conectar duas aplicacoes em Elixir de maneira simples porem, como voce controla esse ambiente em producao? como voce vai detectar esses nodes em um cluster de kubernetes?, como criar essa comunicacao entre ips diferentes de maneira simples? criar codigos para isso?&lt;/p&gt;

&lt;p&gt;Na verdade a melhor maneira de criar essa conexao e atraves do libcluster (o artigo sobre nodes te ensina o que esta por debaixo dos panos) &lt;/p&gt;

&lt;h1&gt;
  
  
  Como foi que você descobriu isso?
&lt;/h1&gt;

&lt;p&gt;Foi uma das primeiras bibliotecas que aprendi ha mais de 4 anos de jornada como desenvolvedor Elixir, se falava de beneficios do Elixir mas sempre agente comentava que a vantagem de sistemas distribuidos era pouco ou nao utilizada. Mas em um projeto utilizando &lt;strong&gt;liveview&lt;/strong&gt; o &lt;strong&gt;libcluster&lt;/strong&gt; passa a ser mais que obrigatorio e foi o caso de um projeto que eu comecei a atuar. &lt;/p&gt;

&lt;h1&gt;
  
  
  Quais as vantagens de usar &lt;strong&gt;LibCluster&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;A principal vantagem e criar conexao entre aplicacoes de maneira rapida e simples, sem ter que precisar criar conexao de nodes, genservers e otp. O libcluster vai abstrair todas essas regras para uma simples configuracao.&lt;/p&gt;

&lt;h1&gt;
  
  
  Qual o melhor momento para Implementar o &lt;strong&gt;LibCluster&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;No comeco da minha carreira eu percebi coisas essenciais como implementacao em aplicacoes Elixir, e acredito que hoje o libcluster e uma delas. &lt;strong&gt;principalmente se voce utilizar liveview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Voce pode comecar a implementacao do libcluster em Dev utilizando a estrategia de &lt;a href="https://hexdocs.pm/libcluster/Cluster.Strategy.Gossip.html" rel="noopener noreferrer"&gt;&lt;em&gt;Gossip&lt;/em&gt;&lt;/a&gt; por ser uma das mais simples e facil de entender o libcluster, e quando for para producao vai depender se voce vai utilizar Kubernetes, ECS, ou qualquer outro ambiente.  Geralmente eu trabalho com clusters em kubernetes e implemento DNS. &lt;/p&gt;

&lt;h1&gt;
  
  
  FIM.
&lt;/h1&gt;

&lt;p&gt;Eu espero que o artigo tenha te ajudado a entender a necessidade e a urgencia de comecar a utilizar o libcluster em suas aplicacoes. :D &lt;/p&gt;

&lt;p&gt;Redes Sociais: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gustavo Oliveira - &lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/gustavo-oliveira-642b23aa/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elxpro Linkedin - &lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;https://www.linkedin.com/company/36977430&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Twiter - &lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;https://twitter.com/elx_pro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ElxproBr - &lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Elxpro - &lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
      <category>beam</category>
      <category>liveview</category>
    </item>
    <item>
      <title>A pior maneira de lidar com sessoes com Phoenix Liveview.</title>
      <dc:creator>Elxpro</dc:creator>
      <pubDate>Tue, 05 Jul 2022 21:53:07 +0000</pubDate>
      <link>https://dev.to/theguuholi/a-pior-maneira-de-lidar-com-sessoes-com-phoenix-liveview-55m3</link>
      <guid>https://dev.to/theguuholi/a-pior-maneira-de-lidar-com-sessoes-com-phoenix-liveview-55m3</guid>
      <description>&lt;h1&gt;
  
  
  Saudacao
&lt;/h1&gt;

&lt;p&gt;Seja muito bem vindo, seja muito bem vinda ao #FullstackElxpro&lt;/p&gt;

&lt;p&gt;Aqui nós discutimos as estratégias e dicas de sua jornada de aprendizado em Elixir. Isso é do zero até a sua primeira vaga como desenvolvedor elixir&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to learn Elixir in three months? &lt;a href="https://elxpro.com/sell" rel="noopener noreferrer"&gt;https://elxpro.com/sell&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Eu sou o Gustavo e o tema de hoje é: &lt;strong&gt;A pior maneira de lidar com sessoes com Phoenix Liveview.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;_ps: Voce pode acompanhar o artigo com o video&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Quer aprender mais sobre elixir em um canal do Telegram?&lt;/em&gt;&lt;br&gt;
&lt;a href="https://elxpro.com/elxcrew-org-yt-descr" rel="noopener noreferrer"&gt;https://elxpro.com/elxcrew-org-yt-descr&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  O que é?
&lt;/h1&gt;

&lt;p&gt;Sessao basicamente e algo temporareo em uma aplicacao. Nao e nada mais e nada menos que isso. &lt;/p&gt;

&lt;p&gt;Porem em Elixir, Phoenix e Liveview (principalmente a parte web) ha diversas maneiras de trabalhar com sessao.  &lt;/p&gt;

&lt;p&gt;Pode utilizar:&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;a href="https://hexdocs.pm/phoenix/plug.html" rel="noopener noreferrer"&gt;Plugs&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Que e um middleware de conexao e atravez deste middleware persistir dados e ler dados em uma sessao. E ha diversos plugs para lidar com este middle, mas nao e o caso deste artigo&lt;/p&gt;
&lt;h2&gt;
  
  
  [Phoenix Token
&lt;/h2&gt;

&lt;p&gt;](&lt;a href="https://hexdocs.pm/phoenix/Phoenix.Token.html" rel="noopener noreferrer"&gt;https://hexdocs.pm/phoenix/Phoenix.Token.html&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;E uma maneira de utilizar e guardar dados que expiram de maneira simples&lt;/p&gt;
&lt;h2&gt;
  
  
  Liveview
&lt;/h2&gt;

&lt;p&gt;Ha diversas maneiras como: session_storage, local_storage (desde que use hooks), live_session. E tu pode conferir todos os tipos de abordagem.&lt;/p&gt;

&lt;p&gt;O que voce vai ver neste artigo e live_session e o porque utiliza-lo, pois ha diversas vantagens e abordagens que sao extremamente simples que vai fazer toda a diferenca na manutencao e legibilidade da aplicacao.&lt;/p&gt;
&lt;h1&gt;
  
  
  Qual a Diferença entre &lt;strong&gt;sessoes&lt;/strong&gt; e &lt;strong&gt;live_session&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;A principal diferenca e que a sessao o foco maior e na conexao, trafegar dados persistidos na conexao. &lt;/p&gt;

&lt;p&gt;Agora no live_session voce consegue pegar os dados da &lt;em&gt;sessao&lt;/em&gt;, incluir no &lt;strong&gt;socket&lt;/strong&gt; e tambem consegue programar eventos genericos em sua pagina o que facilita muito para nao replicar codigo, em resumo e um middleware com super poderes. &lt;/p&gt;
&lt;h1&gt;
  
  
  Como foi que você descobriu isso?
&lt;/h1&gt;

&lt;p&gt;A maneira como eu descobri, foi na leitura do upgrade do phoenix 1.5 para o 1.6. E quando apareceu &lt;strong&gt;live_session&lt;/strong&gt; achava que nao tinha necessidade alguma. Porem em uma aplicacao que venho trabalhando tinha um header compartilhado usando uma pagina liveview dentro de outra pagina liveview. &lt;/p&gt;

&lt;p&gt;Se voce entende de processos, tinha um processo monitorando outro uma complexidade absurda para criar comunicao, exigia muito do time entender como &lt;strong&gt;OTP, Elixir, Processos&lt;/strong&gt; funciona por debaixo dos panos e mesmo entendo tudo isso, e uma solucao (workaround) era tao verboso e complicado de manipular. &lt;/p&gt;

&lt;p&gt;Neste evento eu ja tinha trabalhado com &lt;strong&gt;live_session&lt;/strong&gt; em outros projetos (fora da Empresa), e vi o quao poderoso e a quantidade de beneficios que o live_session traz para a nova versao do &lt;strong&gt;Phoenix Liveview&lt;/strong&gt; atravez de uma conversa sobre decisoes de codigo eu apresentei a solucao e todos gostaram e a implementacao foi muito simples.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;ps: (eu nao vou mostrar a solucao desenvolvida neste artigo, porem, no final, voce sera capaz de criar solucoes melhores do que eu implementei)&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Por quê &lt;strong&gt;live_session&lt;/strong&gt; é importante?
&lt;/h1&gt;

&lt;p&gt;A grande importancia e a questao dos superpodeeres que sao faceis de utilizar. Um dos divisores de agua da versao 1.5 para a 1.6 foi o &lt;em&gt;live_session&lt;/em&gt; pois voce nao precisa escrever muito codigo, com poucas linhas voce vai conseguir interagir com o socket e incluir implementacoes e eventos, e principalmente criar regras de falhas. &lt;/p&gt;
&lt;h1&gt;
  
  
  Qual o maior benefício do &lt;strong&gt;live_session&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;O maior beneficio e a questao de manipular um socket como uma sessao. &lt;/p&gt;
&lt;h1&gt;
  
  
  Você se lembra de alguma história em que isso foi importante pra você?
&lt;/h1&gt;

&lt;p&gt;Como eu mensionei, a principal historia foi a questao de assinar informacoes no socket de maneira generica, sem ter que replicar codigos algo que desenvolvedores acha chato e realmente e. &lt;/p&gt;

&lt;p&gt;E a outra foi quando precisei trigar eventos de &lt;strong&gt;handle_events, handle_infos, handle_params&lt;/strong&gt; sem precisar implementar em todas as paginas&lt;/p&gt;
&lt;h1&gt;
  
  
  Como criar &lt;strong&gt;live_sessions&lt;/strong&gt;?
&lt;/h1&gt;

&lt;p&gt;Voce pode comecar entendendo o motivo. Algumas perguntas pode te ajudar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eu preciso de compartilhar essa informacao com mais de 1 pagina?&lt;/li&gt;
&lt;li&gt;Esse evento precisa ser replicado em mais de uma pagina? &lt;/li&gt;
&lt;li&gt;Preciso de criar alguma regra de negocio generalizada? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se a resposa for sim, o &lt;strong&gt;&lt;a href="https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Router.html#live_session/3" rel="noopener noreferrer"&gt;live_session&lt;/a&gt;&lt;/strong&gt; e a melhor opcao. &lt;/p&gt;

&lt;p&gt;Voce pode acomparnhar na imagem abaixo que foi preciso implementar somente algumas linhas de codigos e o livesession comeca a se comportar como um &lt;em&gt;middleware&lt;/em&gt;&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%2Fdw10zivsq0roly4fvjvj.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%2Fdw10zivsq0roly4fvjvj.png" alt=" " width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Antes de comecar qualquer sessao o que o &lt;strong&gt;live_session&lt;/strong&gt; vai fazer e chamar o modulo de permissao, verficiando o escopo (o que e um pattern matching mais do que incrivel)  e assinar novas informacoes no socket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule LiveSessions.Permissions do
  import Phoenix.LiveView
  alias FoodOrder.Accounts
  alias FoodOrderWeb.Router.Helpers, as: Routes
  alias LiveSessions.CreateCart

  def on_mount(:user, _params, %{"user_token" =&amp;gt; user_token}, socket) do
    assign_user(socket, :user, user_token)
  end

  def on_mount(:admin, _params, %{"user_token" =&amp;gt; user_token}, socket) do
    assign_user(socket, :admin, user_token)
  end

  defp assign_user(socket, _, nil) do
    error_login(socket, "You must be logged in")
  end

  defp assign_user(socket, :user, user_token) do
    current_user = Accounts.get_user_by_session_token(user_token)
    cart_id = get_connect_params(socket)["cart_id"]

    socket =
      socket
      |&amp;gt; assign_new(:current_user, fn -&amp;gt; current_user end)
      |&amp;gt; CreateCart.execute(cart_id)

    {:cont, socket}
  end

  defp assign_user(socket, :admin, user_token) do
    user_token
    |&amp;gt; Accounts.get_user_by_session_token()
    |&amp;gt; return_socket(socket)
  end

  defp return_socket(%{role: role}, socket) when role != :ADMIN,
    do: error_login(socket, "You don`t have permissions to access this page")

  defp return_socket(current_user, socket),
    do: {:cont, assign_new(socket, :current_user, fn -&amp;gt; current_user end)}

  defp error_login(socket, message) do
    socket =
      socket
      |&amp;gt; put_flash(:error, message)
      |&amp;gt; redirect(to: Routes.main_path(socket, :index))

    {:halt, socket}
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Finalizacao
&lt;/h1&gt;

&lt;p&gt;Eu espero que eu tenha te ajudado no seu aprendizado, recomendo sempre visitar os videos do youtube, geralmente tem mais recursos. Um grande abraco!! &lt;/p&gt;

&lt;p&gt;Redes Sociais: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/gustavo-oliveira-642b23aa/" rel="noopener noreferrer"&gt;Gustavo Oliveira&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/company/36977430" rel="noopener noreferrer"&gt;Elxpro(linkedin)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/elx_pro" rel="noopener noreferrer"&gt;Twiter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA" rel="noopener noreferrer"&gt;ElxproBr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ" rel="noopener noreferrer"&gt;Elxpro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
      <category>beam</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
