<?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: Yuthika Singh</title>
    <description>The latest articles on DEV Community by Yuthika Singh (@yuthika10).</description>
    <link>https://dev.to/yuthika10</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%2F4155170%2F1e6f8733-3d96-457a-ad41-e9c3f14b089a.jpg</url>
      <title>DEV Community: Yuthika Singh</title>
      <link>https://dev.to/yuthika10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yuthika10"/>
    <language>en</language>
    <item>
      <title>Baadal: I Built an App That Teaches You to Read the Sky Again</title>
      <dc:creator>Yuthika Singh</dc:creator>
      <pubDate>Sun, 11 Oct 2026 20:38:07 +0000</pubDate>
      <link>https://dev.to/yuthika10/baadal-i-built-an-app-that-teaches-you-to-read-the-sky-again-3c60</link>
      <guid>https://dev.to/yuthika10/baadal-i-built-an-app-that-teaches-you-to-read-the-sky-again-3c60</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;p&gt;&lt;em&gt;The cover is a sunset I photographed from my terrace in Mumbai. When I ran it through Baadal, Gemma called it **stratocumulus&lt;/em&gt;&lt;em&gt;: the lumpy, rolling cloud layer you can see catching the last of the light.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Every Mumbaikar knows the umbrella gamble. You open a weather app, it says &lt;em&gt;40% chance of rain&lt;/em&gt;, and you're no wiser than before. So you scroll a little longer, and step out without ever looking at the one thing that actually knows: the sky right above you.&lt;/p&gt;

&lt;p&gt;People used to read it. Fishermen read it before setting out, and farmers before sowing. So did my grandmother: she could look at the clouds over the building opposite and tell us, almost to the hour, when to rush the clothes off the line. Somewhere between her generation and mine, we swapped looking up for looking down.&lt;/p&gt;

&lt;p&gt;I wanted to build something that hands that skill back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Baadal&lt;/strong&gt; (बादल, Hindi for &lt;em&gt;cloud&lt;/em&gt;) is a tiny web app that does one thing: you step outside, take one photo of the sky, and it tells you the chance of rain in the next 3 hours. Then it teaches you how to read that sky yourself, so that next time you won't need it.&lt;/p&gt;

&lt;p&gt;The whole interaction takes under 30 seconds of screen time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Look up.&lt;/strong&gt; Frame mostly sky and tap &lt;em&gt;Read the sky&lt;/em&gt; (or upload a photo from your gallery).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 4 reads the clouds.&lt;/strong&gt; It names the cloud type (cumulus, stratus, cirrus and the rest of the 10 WMO genera), estimates how much of the sky is covered, and checks for towering growth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TabPFN does the forecasting.&lt;/strong&gt; It combines what you saw with live humidity, pressure and the 3-hour pressure trend, and returns a rain probability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You get a sky lesson.&lt;/strong&gt; Two sentences on &lt;em&gt;why&lt;/em&gt;, plus one "spot it yourself next time" tip, like &lt;em&gt;"If the top flattens into an anvil shape, rain is usually less than an hour away."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pocket the phone.&lt;/strong&gt; Three hours later you tap &lt;em&gt;It rained&lt;/em&gt; or &lt;em&gt;Stayed dry&lt;/em&gt;, and the app keeps an honest score.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result screen shows two bars side by side: &lt;strong&gt;"With your eyes"&lt;/strong&gt; (your photo + weather data) and &lt;strong&gt;"Weather data only"&lt;/strong&gt;. That comparison is the heart of the project. It shows exactly what &lt;em&gt;looking up&lt;/em&gt; adds.&lt;/p&gt;

&lt;p&gt;The best possible outcome for Baadal is that one day you don't open it at all. You just look up, and you know.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three skies, three readings
&lt;/h3&gt;

&lt;p&gt;October is Mumbai's in-between month: the monsoon has left, and the sky changes character through the day. I gave Baadal three skies I'd photographed from my terrace, one each in the afternoon, the evening and at night:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Photo taken&lt;/th&gt;
&lt;th&gt;What Gemma saw&lt;/th&gt;
&lt;th&gt;Baadal's rain chance*&lt;/th&gt;
&lt;th&gt;What actually happened&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Afternoon&lt;/td&gt;
&lt;td&gt;Cumulus&lt;/td&gt;
&lt;td&gt;13%&lt;/td&gt;
&lt;td&gt;Rained&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evening&lt;/td&gt;
&lt;td&gt;Stratocumulus&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;Stayed dry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Night&lt;/td&gt;
&lt;td&gt;Stratus&lt;/td&gt;
&lt;td&gt;5%&lt;/td&gt;
&lt;td&gt;Stayed dry&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;*I uploaded these from my gallery, so each rain chance was calculated with the live weather at the moment of upload, not the weather when the photo was taken. That makes this a test of Gemma's eyes, not a scored forecast, and I'm not counting it as one.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Gemma named a different cloud type for each sky, and the low numbers fit a dry October evening and night. The afternoon cumulus is the lesson I keep coming back to: puffy cumulus that keeps building in the afternoon heat can turn into a shower, and that afternoon it did. That is exactly the kind of sign Baadal's "spot it yourself" tips teach you to watch for, and catching it live, with that afternoon's own humidity and pressure, is the next test I'm running.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://cloud-oracle.onrender.com" rel="noopener noreferrer"&gt;https://cloud-oracle.onrender.com&lt;/a&gt; (free tier, so the first load can take ~50 seconds to wake up)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Look up and tap once.&lt;/strong&gt; Take a photo, upload one from your gallery, or pick the cloud yourself.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0t2qen0fre8md46e7j9s.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0t2qen0fre8md46e7j9s.png" alt="Baadal start screen" width="800" height="1134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Give it the sky.&lt;/strong&gt; This is the evening sky from my terrace that I gave Baadal for this reading.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0huocp5adcnz1q9bzd65.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0huocp5adcnz1q9bzd65.jpeg" alt="An evening sky over Mumbai with low, lumpy clouds" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The reading and the sky lesson.&lt;/strong&gt; Gemma called it &lt;strong&gt;stratocumulus, 6/8 covered, 80% sure&lt;/strong&gt;. Adding what I saw raised the rain chance from 1% (weather data only) to 10%, still low, and the lesson explains why in plain words: the clouds weren't growing tall, and the air was fairly dry at 56% humidity.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9pz0xrifdi6ha1nose4v.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9pz0xrifdi6ha1nose4v.png" alt="Baadal's reading: 10% chance of rain, stratocumulus, with the sky lesson" width="588" height="880"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Pocket the phone, then report back.&lt;/strong&gt; Later, you tell Baadal what really happened, and it keeps an honest score.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4qfqmhui0pq0o60058on.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4qfqmhui0pq0o60058on.png" alt="Logging what actually happened" width="588" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. No photo? Name the cloud yourself.&lt;/strong&gt; Every option has a one-line description, so even this screen teaches you something.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv08s4df32rh28v6rwf4u.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv08s4df32rh28v6rwf4u.png" alt="Choosing a cloud type by hand - from what the viewer can see" width="800" height="1559"&gt;&lt;/a&gt;&lt;/p&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/Yuthika10" rel="noopener noreferrer"&gt;
        Yuthika10
      &lt;/a&gt; / &lt;a href="https://github.com/Yuthika10/Baadal" rel="noopener noreferrer"&gt;
        Baadal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Point your phone at the sky, learn to read it. Gemma 4 identifies the clouds, TabPFN predicts rain in the next 3 hours, and the app teaches you to spot the signs yourself. Built for the Hacktoberfest 2026 DEV Touch Grass 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;Baadal ☁️&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Look up, take one photo, learn to read the sky.&lt;/strong&gt;
Gemma 4 (open-weight vision) reads the clouds, TabPFN (tabular foundation model) turns
what you saw plus live humidity and pressure into a rain probability for the next 3 hours
and Gemma explains it in two sentences with one "spot it yourself next time" tip.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;Sky photo ──► resized on phone (EXIF/GPS stripped) ──► Gemma 4 vision
                                                        → {genus, oktas, towering, confidence}
Live air   ──► Open-Meteo (humidity, pressure, 3h pressure change, dew point, wind)
                                │
             same feature code as training (app/features.py)
                                ▼
           TabPFN ──► P(rain in next 3 h)  [with your eyes]  vs  [weather data only]
                                ▼
           Gemma ──► 2-sentence explanation + 1 sky-reading tip
                                ▼
           You log "it rained / stayed dry" later → honest field score
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Project layout&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;Path&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scripts/fetch_history.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Downloads 2 years of hourly weather for your location, writes &lt;code&gt;data/training.csv&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scripts/evaluate.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TabPFN vs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Yuthika10/Baadal" 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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sky photo ─► resized on your phone (GPS/EXIF stripped) ─► Gemma 4 (vision)
                                                   → cloud type, coverage, towering?, confidence
Live air  ─► Open-Meteo (humidity, pressure, 3-h pressure change, dew point, wind)
                          │
           same feature code as training
                          ▼
         TabPFN ─► P(rain in next 3 h): "with your eyes" vs "weather data only"
                          ▼
         Gemma ─► 2-sentence explanation + 1 sky-reading tip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Open-source AI at the core:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 4&lt;/strong&gt; (open-weight) runs locally through &lt;strong&gt;Ollama&lt;/strong&gt; (&lt;code&gt;gemma4:e4b&lt;/code&gt;) on my laptop, and through the Gemini API (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt;) on the hosted demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TabPFN&lt;/strong&gt; (Prior Labs' tabular foundation model) runs through &lt;code&gt;tabpfn-client&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; + a single mobile web page, deployed on &lt;strong&gt;Render&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The data problem (and the workaround)
&lt;/h3&gt;

&lt;p&gt;There is no public dataset of "sky photo → did it rain afterwards". So I split the problem in two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TabPFN learns the weather side.&lt;/strong&gt; I pulled &lt;strong&gt;2 years of hourly history for Mumbai (17,538 hours)&lt;/strong&gt; from Open-Meteo: cloud cover at low/mid/high levels, humidity, temperature minus dew point, pressure, &lt;strong&gt;3-hour pressure change&lt;/strong&gt;, wind, recent rain, and time of day and year. The label is whether at least 0.2 mm of rain fell in the following 3 hours. In Mumbai that happens in &lt;strong&gt;32%&lt;/strong&gt; of all hours, thanks to the monsoon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma translates the photo into those same features.&lt;/strong&gt; Its answer (say, &lt;em&gt;cumulus, 6/8 covered, towering&lt;/em&gt;) is mapped onto the cloud-layer columns. Your eyes act as ground truth for the layer you can actually see, and the weather model fills in the layers hidden behind it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both training and live predictions run through &lt;strong&gt;one shared feature function&lt;/strong&gt;, so the model never sees data built two different ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does TabPFN actually help?
&lt;/h3&gt;

&lt;p&gt;I trained on the older 80% of hours (a balanced sample of 3,000 rows) and tested on the most recent 20%, so the model never peeks at the future:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;ROC-AUC ↑&lt;/th&gt;
&lt;th&gt;Brier ↓&lt;/th&gt;
&lt;th&gt;F1&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Climatology (always guess the average)&lt;/td&gt;
&lt;td&gt;0.500&lt;/td&gt;
&lt;td&gt;0.398&lt;/td&gt;
&lt;td&gt;0.000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logistic regression&lt;/td&gt;
&lt;td&gt;0.905&lt;/td&gt;
&lt;td&gt;0.119&lt;/td&gt;
&lt;td&gt;0.868&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gradient boosting&lt;/td&gt;
&lt;td&gt;0.928&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.107&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.885&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TabPFN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.937&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.118&lt;/td&gt;
&lt;td&gt;0.866&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsso2lyfhlsfw32jlwwcn.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsso2lyfhlsfw32jlwwcn.png" alt="ROC-AUC comparison: TabPFN 0.937, gradient boosting 0.928, logistic regression 0.905, climatology 0.500" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The axis starts at 0.5, which is what random guessing scores, so the gaps look bigger than they are.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;TabPFN ranks rainy hours best (highest AUC), with &lt;strong&gt;zero hyperparameter tuning&lt;/strong&gt;: it's one &lt;code&gt;fit()&lt;/code&gt; call on 3,000 rows. Gradient boosting is slightly better calibrated (lower Brier score) and has a marginally higher F1. To be fair to everyone, the test period (May to October) is mostly monsoon, where rain falls in &lt;strong&gt;65%&lt;/strong&gt; of hours compared with 32% across the training years, so all the models are being tested on a harder, shifted season. I picked TabPFN for the app because it was the strongest at the core job (telling a rainy hour from a dry one) with nothing to tune.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gemma's two jobs
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Vision.&lt;/strong&gt; A strict prompt asks for a single JSON object: cloud genus, coverage in oktas, towering growth, darkness, confidence, and the visual clues it used. Every answer is validated against that schema. If it doesn't validate, Gemma gets one repair attempt, and if that fails the app says so honestly and lets you pick the cloud type yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teacher.&lt;/strong&gt; Gemma writes the two-sentence explanation and the "spot it yourself" tip, and it is told not to invent numbers that aren't in the facts it was given. This is the part I care about most: a forecast tells you about today, but a lesson stays with you.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Three things that broke (and what I learned)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"429 Too Many Requests" on Render.&lt;/strong&gt; Open-Meteo's free API rate-limits by IP address, and Render's servers share outbound IPs with many other apps. The fix: &lt;strong&gt;the phone fetches the weather itself&lt;/strong&gt; (the user's own IP) and sends it along with the photo, with a server-side fallback that has a cache and a retry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma's replies weren't pure JSON.&lt;/strong&gt; Sometimes there was a draft object, then the real one, then a note. A strict &lt;code&gt;json.loads&lt;/code&gt; rejected all of it. I replaced it with a parser that scans for the first complete object containing the keys I need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows blocked a dependency.&lt;/strong&gt; Smart App Control refused to load &lt;code&gt;pyarrow&lt;/code&gt; (which &lt;code&gt;tabpfn-client&lt;/code&gt; needs) on my laptop. Rather than switch off a security feature, I ran the TabPFN evaluation in Google Colab, and the deployed Linux server runs TabPFN without any issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Gemma can confuse similar clouds (stratocumulus vs altocumulus), and haze can look like cloud. The confidence score and the "Correct it" button exist for exactly this.&lt;/li&gt;
&lt;li&gt;The cloud-layer history comes from a weather model's estimates, not real observations, so the training data is a proxy.&lt;/li&gt;
&lt;li&gt;Predicting rain 3 hours out is hard, even for real forecasters. This is a learning tool, not a replacement for a weather service.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Reading the sky was always open knowledge. Nobody owned it; it was passed from one person to the next by pointing upward. It felt right to rebuild it with tools that are open too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Your sky stays yours.&lt;/strong&gt; In local mode, Gemma 4 runs on my own laptop through Ollama. The photo never leaves the device, and on the hosted version it is resized on the phone (stripping GPS and EXIF) and never stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works where you actually look up.&lt;/strong&gt; Terraces, trails and train platforms don't always have good signal. An open-weight model I can run locally means the vision part doesn't depend on a paid cloud API being reachable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I can swap and tune everything.&lt;/strong&gt; Same prompt, same JSON schema, different Gemma size: &lt;code&gt;e4b&lt;/code&gt; on a laptop, &lt;code&gt;26b&lt;/code&gt; in the cloud. With a closed API I couldn't inspect or change the model, only the prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A foundation model for tables changes the economics.&lt;/strong&gt; TabPFN let me get a strong rain model from a CSV without a training loop or a GPU, and the open ecosystem around it (Open-Meteo's free data, open models) means the whole thing costs &lt;strong&gt;$0 to run&lt;/strong&gt; for a personal project.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;: Gemma 4 does both the vision (reading the sky) and the teaching (explaining the forecast), locally via Ollama and hosted via the Gemini API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of TabPFN&lt;/strong&gt;: TabPFN is the forecasting model, benchmarked against three baselines on a time-based split.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render&lt;/strong&gt;: the app (frontend + FastAPI + TabPFN predictions) is deployed on Render via a Blueprint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tomorrow morning, before you check your phone, step outside and look up for one minute. What do you see? ☁️&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
