<?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: Jo</title>
    <description>The latest articles on DEV Community by Jo (@j0bs-code).</description>
    <link>https://dev.to/j0bs-code</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%2F904679%2F96ff9746-111a-4cac-a7e2-6265ce4fe95c.png</url>
      <title>DEV Community: Jo</title>
      <link>https://dev.to/j0bs-code</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/j0bs-code"/>
    <language>en</language>
    <item>
      <title>Light the Candle: An Offline Día de los Muertos Ofrenda Builder</title>
      <dc:creator>Jo</dc:creator>
      <pubDate>Sun, 01 Nov 2026 07:09:21 +0000</pubDate>
      <link>https://dev.to/j0bs-code/light-the-candle-an-offline-dia-de-los-muertos-ofrenda-builder-5545</link>
      <guid>https://dev.to/j0bs-code/light-the-candle-an-offline-dia-de-los-muertos-ofrenda-builder-5545</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week4-2026-10-26"&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ofrenda&lt;/strong&gt; is a private, offline remembrance builder for Día de los Muertos.&lt;/p&gt;

&lt;p&gt;You enter a loved one's name, your relationship, their favorite foods and songs, and a memory. A local open weight model then writes three things: a short remembrance honoring them, a gentle "letter back" in a warm voice, and a list of items to place on your ofrenda. It all appears on a candlelit, marigold themed page.&lt;/p&gt;

&lt;p&gt;I read the theme "Ghost in the Machine" as the people who live on in our stories. On Día de los Muertos, the line between past and present gets thinner, and the machine here isn't haunted. It helps carry a memory forward. The most personal prompts I can imagine giving an AI are stories about people I miss, so I built it so those stories never leave my computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;[Link your GitHub repo here, or paste it with: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jobs-code" rel="noopener noreferrer"&gt;
        jobs-code
      &lt;/a&gt; / &lt;a href="https://github.com/jobs-code/ofrenda" rel="noopener noreferrer"&gt;
        ofrenda
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🕯️ Ofrenda&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A private, offline remembrance builder for Día de los Muertos, powered by an open-weight model running entirely on your own computer.&lt;/p&gt;

&lt;p&gt;Enter a loved one's name, favorite foods, favorite songs, and a memory. Gemma writes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A remembrance&lt;/strong&gt; honoring them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A "letter back"&lt;/strong&gt; in a warm, gentle voice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A list of items&lt;/strong&gt; to place on your ofrenda&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All inside a candlelit, marigold-themed page.&lt;/p&gt;

&lt;p&gt;Built for the &lt;strong&gt;Ghost in the Machine&lt;/strong&gt; open-source AI challenge.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why open matters here&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;These are stories about people we love. Ofrenda uses an open-weight model running locally, so:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private:&lt;/strong&gt; nothing you type ever leaves your machine. No server, no account, no API key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline:&lt;/strong&gt; it works with Wi-Fi turned off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free:&lt;/strong&gt; no usage costs or rate limits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durable:&lt;/strong&gt; it can't disappear if a service shuts down or changes its terms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable:&lt;/strong&gt; change one line (&lt;code&gt;MODEL&lt;/code&gt;) to use any other open model, or a…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jobs-code/ofrenda" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
]
&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; Gemma3 : 4b, an open weight model from Google, running locally on my Mac&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference:&lt;/strong&gt; &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;, serving the model at &lt;code&gt;localhost:11434&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; about 40 lines of Python (standard library HTTP server plus &lt;code&gt;requests&lt;/code&gt;) that takes the form data, builds a prompt, and sends it to the local model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; a single HTML file with plain CSS and JavaScript, no frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The prompt asks the model for three sections (REMEMBRANCE, LETTER BACK, OFRENDA ITEMS) and tells it not to invent specific facts beyond what the person shared. That matters because the "letter back" should feel true to the person, not like made up fiction about them.&lt;/p&gt;

&lt;p&gt;The model name is one line of config, so any other model shown by &lt;code&gt;ollama list&lt;/code&gt; can be swapped in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;This project is about real people we love, so privacy isn't a nice to have.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private by design.&lt;/strong&gt; The only network traffic is to &lt;code&gt;localhost&lt;/code&gt;. A grandmother's recipes, a father's favorite song, a childhood story: none of it touches a server I don't control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works with the lights off.&lt;/strong&gt; [I tested it with Wi-Fi off, and it works exactly the same.]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Costs nothing.&lt;/strong&gt; No API key, no account, no rate limits, no per token bill for grief.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can't disappear.&lt;/strong&gt; A remembrance tool shouldn't vanish because a company changes its terms, raises prices, or shuts down. The model weights and the code live on my machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable and tunable.&lt;/strong&gt; I can change models with one line, or fine tune one locally on a family's own stories, which a closed API wouldn't let me do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A closed API would have worked technically, but it would have meant sending the most personal text I could imagine to someone else's server. For this project, open wasn't just cheaper. It was the right way to build it.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>OffMarket Writer: A Local AI That Turns Property Photos Into Listings</title>
      <dc:creator>Jo</dc:creator>
      <pubDate>Mon, 19 Oct 2026 03:58:22 +0000</pubDate>
      <link>https://dev.to/j0bs-code/offmarket-writer-a-local-ai-that-turns-property-photos-into-listings-41gj</link>
      <guid>https://dev.to/j0bs-code/offmarket-writer-a-local-ai-that-turns-property-photos-into-listings-41gj</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;OffMarket Writer is a local app for real estate agents. Upload up to six property photos, add the basic facts (price, beds, baths, location, extras), pick a tone, and it writes a headline, description, and highlights ready to paste into a listing.&lt;/p&gt;

&lt;p&gt;Agents would pay for it because writing listings is repetitive, and unlisted properties and client photos are things they often don't want on a third party server. It could be sold as a flat price tool instead of a per listing subscription.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/kstPZjFkVQE" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jobs-code" rel="noopener noreferrer"&gt;
        jobs-code
      &lt;/a&gt; / &lt;a href="https://github.com/jobs-code/OffMarket-Writer" rel="noopener noreferrer"&gt;
        OffMarket-Writer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🏠 OffMarket Writer&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Turn property photos into polished real estate listings, &lt;strong&gt;100% locally&lt;/strong&gt;
Your photos and unlisted property details never leave your laptop.&lt;/p&gt;
&lt;p&gt;Built with &lt;a href="https://ai.google.dev/gemma" rel="nofollow noopener noreferrer"&gt;Gemma 3&lt;/a&gt; (open-weight) running through &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; and a Streamlit interface.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What it does&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Upload up to 6 property photos&lt;/li&gt;
&lt;li&gt;Add basic facts (price, beds, baths, location, extras)&lt;/li&gt;
&lt;li&gt;Pick a tone (warm, luxury, concise, investor-focused)&lt;/li&gt;
&lt;li&gt;Get a headline, description, and highlights ready to copy&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Two passes with &lt;code&gt;gemma3:4b&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Look:&lt;/strong&gt; describes only what is visible in each photo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write:&lt;/strong&gt; combines those notes with the agent's facts into a listing&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The prompt forbids inventing features and follows fair housing guidelines.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why local?&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Client photos and unlisted properties stay private&lt;/li&gt;
&lt;li&gt;No per-listing API fees&lt;/li&gt;
&lt;li&gt;Open-weight model that can be swapped or fine-tuned&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href="https://ollama.com" rel="nofollow noopener noreferrer"&gt;Ollama&lt;/a&gt; and pull the model:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;   ollama pull gemma3:4b&lt;/pre&gt;

&lt;/div&gt;
&lt;ol start="2"&gt;
&lt;li&gt;Install dependencies:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;   pip install -r requirements.txt&lt;/pre&gt;

&lt;/div&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Run the app:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;   streamlit run app.py&lt;/pre&gt;

&lt;/div&gt;
&lt;ol start="4"&gt;&lt;li&gt;…&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jobs-code/OffMarket-Writer" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; Gemma 3 (4B, open weight) running locally through Ollama&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interface:&lt;/strong&gt; Streamlit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two pass pipeline:&lt;/strong&gt; First, Gemma looks at each photo and describes only what is visible. Second, it combines those notes with the agent's facts to write the listing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt guardrails:&lt;/strong&gt; A strict "use only provided information" rule, a ban on unsupported claims like "secure" or "newly renovated," and a fair housing rule that forbids language about who should or shouldn't live in a home.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What I learned testing it:&lt;/strong&gt; I ran six photos of a stone villa (exterior, courtyard, terrace, pool, bathroom, bedroom). It identified each space correctly and used my numbers (2 bed, 2 bath, 1500 sq ft) accurately. Early output had two problems: chatty intros like "Here's a description of..." and flowery adjectives the photos didn't support. Tightening the prompts fixed most of it. A 4B model needs firm rules to stay factual. Generation took about [X seconds] for six photos on my [MacBook Pro].&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; Property photos and pricing for unlisted homes never leave the agent's laptop. It works with wifi off.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; No per listing API fees, so a flat price is viable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; Because the model is open weight, I can edit its behavior through prompts today and fine tune or swap it later for a specific market or brand voice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Best Use of Gemma&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>YardWizard: snap your empty corner, then go plant something real</title>
      <dc:creator>Jo</dc:creator>
      <pubDate>Sun, 11 Oct 2026 16:26:14 +0000</pubDate>
      <link>https://dev.to/j0bs-code/yardwizard-snap-your-empty-corner-then-go-plant-something-real-293m</link>
      <guid>https://dev.to/j0bs-code/yardwizard-snap-your-empty-corner-then-go-plant-something-real-293m</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I photographed an empty lawn and my AI told me it could see tomato plants and basil.&lt;/p&gt;

&lt;p&gt;There were no tomatoes. There was no basil. There was grass.&lt;/p&gt;

&lt;p&gt;That moment shaped the whole design of &lt;strong&gt;YardWizard&lt;/strong&gt;, an app that looks at a photo of your balcony, backyard or lawn and suggests flowers and decorative plants that are easy to buy locally and right to plant this month. It has plant lists for &lt;strong&gt;India, Australia, the USA and the UK&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The screen part takes about 30 seconds: upload a photo, read the suggestions. After that the app has done its job. The real work is walking to a nursery, picking up a pot of crossandra or a bag of daffodil bulbs, and getting your hands in the soil. Every suggestion ends in something you can physically go and buy this week, and each card tells you whether to plant it now or wait, and when.&lt;/p&gt;

&lt;p&gt;It's for people who want a garden but don't know where to start, especially people with a bare balcony or an empty patch of lawn and no idea what suits it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/uwoc-5D80hE" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jobs-code" rel="noopener noreferrer"&gt;
        jobs-code
      &lt;/a&gt; / &lt;a href="https://github.com/jobs-code/yardWizard" rel="noopener noreferrer"&gt;
        yardWizard
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🌱 YardWizard&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Upload a snap of your balcony, backyard or lawn and get flowers and decorative plants that are easy to buy locally and right to plant &lt;strong&gt;this month&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Built for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05" rel="nofollow"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;. The screen part takes about 30 seconds. After that, you go to a nursery and plant something.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;You pick your region and upload a photo of your space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 4B (vision)&lt;/strong&gt;, running locally through Ollama, reads the photo and returns a small JSON profile: sunlight (full / part / shade), space type (pots / ground), visible plants, and a one-line note.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;hand-written plant list&lt;/strong&gt; for your region does the actual recommending, filtered by sun, space and the current month. Each card shows &lt;strong&gt;plant now&lt;/strong&gt; or &lt;strong&gt;next: &lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If the model misjudges the light, change the dropdowns and tap &lt;strong&gt;Suggest plants&lt;/strong&gt; again.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jobs-code/yardWizard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The pieces are deliberately small:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 4B (vision), running locally through Ollama.&lt;/strong&gt; It looks at the photo and returns a tiny JSON profile: how sunny the space looks, whether it's pots or open ground, what plants are visible, and one friendly sentence about the space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A hand-written plant list per region&lt;/strong&gt;, with sun needs, pots-or-ground suitability, and the months each plant is good to start. This list does the actual recommending, filtered by the current month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flask and a single HTML page.&lt;/strong&gt; No framework, no database, no API key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dropdowns to correct the model.&lt;/strong&gt; If Gemma misjudges the light, the user changes it with one tap and re-runs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I split the work like this on purpose. A 4B model is good at "what kind of space is this?" and unreliable at "which plant should I tell someone to buy in Kerala in October?" So the model reads the scene, and a list I wrote makes the recommendation. The model can't suggest a plant that doesn't exist or isn't sold locally, because it never picks the plants.&lt;/p&gt;

&lt;p&gt;I also tried the text-only &lt;code&gt;qwen3&lt;/code&gt; I already had installed, but it can't read images, so I pulled Gemma 3 for the photo step. This is my second project on the same local Gemma setup, after the workout planner I built last week.&lt;/p&gt;

&lt;h3&gt;
  
  
  What worked and what didn't
&lt;/h3&gt;

&lt;p&gt;I tested eight photos across the regions:&lt;/p&gt;

&lt;p&gt;Gemma got the overall scene right every time. But on lawns it twice invented crops that weren't there, once tomatoes and basil, once just "vegetables". Small vision models seem to like seeing what a garden "should" contain.&lt;/p&gt;

&lt;p&gt;My first fix backfired. I told the model to list only plants that were clearly visible, and it copied my instruction into its answer. Two photos came back saying "I can see: only plants clearly visible." Small models follow examples more than rules. The fix was to remove the instruction from the JSON template, rephrase it, and add a small code-side filter that throws away echoed instructions. Now the model's mistakes stay inside the model.&lt;/p&gt;

&lt;p&gt;That is the argument for the architecture. The balcony, the most common real use case, worked cleanly every time. The lawn, where the model hallucinates, can't do any damage, because Gemma doesn't choose the plants and the user can correct the light and space in one tap.&lt;/p&gt;

&lt;p&gt;Limits I should be upfront about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Judging sunlight from a single photo is rough. The dropdowns exist because of this.&lt;/li&gt;
&lt;li&gt;The plant lists are a starting point. The USA is far too varied for one list, so mine covers temperate regions and the Deep South or the desert would need their own. Australia and India vary a lot too, and a local nursery knows your microclimate better than I do.&lt;/li&gt;
&lt;li&gt;Offline here means no internet at all on the laptop. I did not run the model on a phone, and that is the next step.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Photos of your home never leave your machine.&lt;/strong&gt; A picture of someone's balcony or backyard says a lot about where they live. Nothing is uploaded anywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works with no internet.&lt;/strong&gt; I recorded the demo with Wi-Fi off. That matters for a gardening tool, since gardens are often far from good signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could see and fix the model's behavior.&lt;/strong&gt; When Gemma hallucinated, I could change the prompt, filter the output, and rebuild the design around the model's weak spot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adding a country is just adding a list.&lt;/strong&gt; USA and UK took minutes to add, with no retraining and no API changes. Anyone can add their own district, or swap in a different model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Running the model directly on a phone, local language plant names, more regions, and a "what's flowering near me" feed that sends you outside to look at the real thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;Best Use of Gemma&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>I built LiftCoach for Kavya, who lifted the same weight for months</title>
      <dc:creator>Jo</dc:creator>
      <pubDate>Sun, 04 Oct 2026 17:51:28 +0000</pubDate>
      <link>https://dev.to/j0bs-code/i-built-liftcoach-for-kavya-who-lifted-the-same-weight-for-months-38a4</link>
      <guid>https://dev.to/j0bs-code/i-built-liftcoach-for-kavya-who-lifted-the-same-weight-for-months-38a4</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Kavya and I train at the same gym. She's consistent: she shows up, hits her sets, never skips. But for months she was stuck on the same weights.&lt;/p&gt;

&lt;p&gt;She had no system for progressive overload. She didn't know when to add 2.5 kg, when to add reps, or when to deload.&lt;/p&gt;

&lt;p&gt;So I built LiftCoach for her.&lt;/p&gt;

&lt;p&gt;It's a simple tool that takes her recent weights and reps and applies the basic rules of progressive overload to tell her exactly what to do next session: add weight, add a rep, or hold. If she doesn't like an exercise, it suggests swaps that train the same muscles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/Rmyn9DTVSiI" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/jobs-code" rel="noopener noreferrer"&gt;
        jobs-code
      &lt;/a&gt; / &lt;a href="https://github.com/jobs-code/liftcoach" rel="noopener noreferrer"&gt;
        liftcoach
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Built for the Hacktoberfest 2026 Weekend Challenge
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;LiftCoach&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A local, private workout progression coach. Enter your profile and your last sessions for the lifts you choose, and LiftCoach tells you the next weight, sets and reps. If you dislike a lift, it suggests swaps that train the same muscles.&lt;/p&gt;
&lt;p&gt;Built for the Hacktoberfest 2026 Weekend Challenge: &lt;strong&gt;Build for a Friend&lt;/strong&gt;. I built it for Kavya, who lifts same weight for months.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/jobs-code/liftcoach/screenshot.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fjobs-code%2Fliftcoach%2FHEAD%2Fscreenshot.png" alt="LiftCoach screenshot"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Python rules engine&lt;/strong&gt; (&lt;code&gt;logic.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Decides next weight, reps and sets using double progression. Plain code.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Curated exercise table&lt;/strong&gt; (&lt;code&gt;logic.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;20 exercises tagged by muscle group, movement pattern and equipment. Picks swaps for disliked lifts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Gemma 3 4B via Ollama&lt;/strong&gt; (&lt;code&gt;app.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;An open weight model that only explains the plan in coach language. It never changes the numbers or adds exercises.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Gradio&lt;/strong&gt; (&lt;code&gt;app.py&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;The web form.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Safety checks: input range validation, plus a…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/jobs-code/liftcoach" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;LiftCoach is split into two parts: plain Python for anything that has to be reliable, and an open-weight model for anything that needs language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The stack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python rules engine (&lt;code&gt;logic.py&lt;/code&gt;)&lt;/strong&gt; decides the next weight, sets and reps using double progression. If she hits 12 reps on every set, the weight goes up. If she hits 8 or more, she adds a rep. If she misses 8 reps two sessions in a row at the same weight, it deloads about 10%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A curated exercise table&lt;/strong&gt; of 20 exercises, each tagged by muscle group, movement pattern and equipment. When Kavya dislikes a lift, the code picks swaps from this table (bench press to dumbbell press, for example), so the swaps always hit the same muscles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 4B through Ollama&lt;/strong&gt; runs locally and only explains the plan in coach language. It never changes the numbers or adds exercises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradio&lt;/strong&gt; is the web form (the frontend).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why I didn't let the model do the math.&lt;/strong&gt; Small local models are unreliable at arithmetic, and a wrong weight jump is a safety problem. So the model gets the finished decision and only writes the explanation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safety and validation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input ranges are checked (weight, reps, age, body weight), and bad entries get a clear message instead of a crash.&lt;/li&gt;
&lt;li&gt;A body-weight sanity check flags logged weights far above the typical range for the user's body weight and gender. When it fires, the plan holds the weight until the input is confirmed. These ratios are rough heuristics from public strength-standard tables, not an official standard.&lt;/li&gt;
&lt;li&gt;The under-18 supervision note is added by Python, not by the model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What went wrong, and how I fixed it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gemma invented a reason for disliking a lift ("you were feeling uncomfortable"). I added a prompt rule not to assume reasons.&lt;/li&gt;
&lt;li&gt;It described the next target as if it had already been lifted. I told it the weights are next targets.&lt;/li&gt;
&lt;li&gt;The warning said "double-check" but the plan still raised the weight. I made the plan hold the weight when an input is flagged.&lt;/li&gt;
&lt;li&gt;Gemma added a supervision note for an adult. I moved that check into Python.&lt;/li&gt;
&lt;li&gt;It called "same weight, add a rep" an increase. I added a prompt rule to describe the action exactly as given.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lesson: the model drifts in small ways, so the exact plan is always shown first, generated by plain Python, and Gemma's text is only the explanation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI help:&lt;/strong&gt; I used an AI assistant to help write the code, then tested it myself and adjusted the rules and prompts based on what I saw.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;LiftCoach asks for things people don't casually hand to a company: age, gender, body weight, and a full training log. Where that data goes is part of the product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Privacy by design.&lt;/strong&gt; Gemma runs on my Mac through Ollama, and the app sends nothing to a third-party server. I tested it offline and it still produced a plan. Users don't have to wonder whether their body data is being stored or used for ads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It works where we train.&lt;/strong&gt; Gym basements have bad signal. A local model doesn't care.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Free and durable.&lt;/strong&gt; No API key, no per-request bill, no usage limit. A provider can't shut it down, reprice it, or change it under me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Control over behaviour.&lt;/strong&gt; Gemma drifted: it invented reasons, mislabelled actions, and added unsolicited advice. Because I controlled the whole stack, I could fix each problem myself: tighten the prompt, move the age check into Python, and keep the exact plan logic in plain code. I can also swap the model by changing one line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where it falls short:&lt;/strong&gt; a 4B model on a laptop is slower and wordier than a large hosted model, and I had to work around its mistakes. Hosted APIs can be tuned too. For an app handling body data, I chose privacy and stability over raw capability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; &lt;br&gt;
LiftCoach runs Gemma 3 4B locally through Ollama. Gemma writes the coaching explanation, while plain Python rules decide the numbers and the swaps.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
