<?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: Lasyapriya Putti</title>
    <description>The latest articles on DEV Community by Lasyapriya Putti (@lasyapriya_putti).</description>
    <link>https://dev.to/lasyapriya_putti</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%2F4156484%2F3ee97a44-b3d3-4d8a-9350-4037b7d3b6eb.png</url>
      <title>DEV Community: Lasyapriya Putti</title>
      <link>https://dev.to/lasyapriya_putti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lasyapriya_putti"/>
    <language>en</language>
    <item>
      <title>My friend's kirana store runs out of milk every Sunday. So I gave it a voice.</title>
      <dc:creator>Lasyapriya Putti</dc:creator>
      <pubDate>Mon, 05 Oct 2026 05:47:38 +0000</pubDate>
      <link>https://dev.to/lasyapriya_putti/my-friends-kirana-store-runs-out-of-milk-every-sunday-so-i-gave-it-a-voice-3c4k</link>
      <guid>https://dev.to/lasyapriya_putti/my-friends-kirana-store-runs-out-of-milk-every-sunday-so-i-gave-it-a-voice-3c4k</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;My friend Surya runs a &lt;strong&gt;kirana&lt;/strong&gt;: the small neighbourhood grocery store you'll find on almost every street in India. Milk, bread, sugar, dal, biscuits, soap. His shop is a few steps from my house.&lt;/p&gt;

&lt;p&gt;Two problems keep coming back. On Sundays and during festivals, demand jumps: Indian festival sweets and snacks are made from milk, flour and sugar, so those run out first. On other days he sometimes overstocks by mistake: packets get pushed behind other items, look finished, get reordered, and the extra stock expires and goes to waste.&lt;/p&gt;

&lt;p&gt;Nobody is careless here. Running a kirana means making change, serving a queue and answering questions at the same time. Nobody has a free hand to type into inventory software, and that software is in English anyway. So most owners run their stock from memory and gut feeling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KiranaVoice&lt;/strong&gt; is a stock assistant you talk to. One big button, in your own language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You say what happened:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"5 packets milk sold"&lt;/li&gt;
&lt;li&gt;"20 kg sugar aaya" (20 kg of sugar arrived)&lt;/li&gt;
&lt;li&gt;"ఈరోజు 20 కేజీల పంచదార దిగుమతి అయింది"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;You ask what's left:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"milk kitna bacha hai?" (how much milk is left?)&lt;/li&gt;
&lt;li&gt;"How many eggs do we have?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The app answers straight away, on screen and out loud. No typing and no menus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It repeats everything back before it saves anything.&lt;/strong&gt; A shop is noisy, and a speech recogniser can mishear. So for every sale or delivery, KiranaVoice says what it understood, for example "Sale: 5 milk", and changes the stock only when the owner taps &lt;strong&gt;Confirm&lt;/strong&gt;. A wrong entry is one tap on &lt;strong&gt;Undo&lt;/strong&gt; away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It warns you before the shelf is empty.&lt;/strong&gt; KiranaVoice looks at past sales, including weekend spikes and festival days. If tomorrow's expected demand is higher than what is on the shelf, it shows an urgent morning alert in the owner's language, with a suggested reorder quantity: &lt;em&gt;"Tomorrow's demand for milk is about 54 packets, but only 18 are left. Order 45 more today!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It works in &lt;strong&gt;11 languages&lt;/strong&gt;: Telugu, Hindi, Tamil, Kannada, Bengali, Marathi, Gujarati, Malayalam, Punjabi, Hinglish and English. The interface, item names, units and spoken alerts all switch together. It understands several items in one sentence ("2 milk, 3 sugar sold"), spoken numbers ("paanch", "ఐదు") and amounts like "250 gram" or "half".&lt;/p&gt;

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

&lt;p&gt;🔗 &lt;strong&gt;Live demo:&lt;/strong&gt; &lt;a href="https://kiranavoice.streamlit.app/" rel="noopener noreferrer"&gt;https://kiranavoice.streamlit.app/&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note on the hosted demo.&lt;/strong&gt; The cloud server has no GPU or Ollama, so the live link uses the rule-based parser and a weekday-average forecast on demo data. The full setup, with Gemma through Ollama and TabPFN, runs on the shop's own machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Open it in &lt;strong&gt;Chrome or Edge&lt;/strong&gt; and allow the microphone. You can also type, and any of these will work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;5 packets milk sold&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2 milk 3 sugar sold&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;20 kg sugar aaya&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sugar kitna bacha hai&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Video:&lt;/strong&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/F637oDcgWK8" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Screenshots: &lt;br&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%2Fayh2f0c9a8rp81ci6ycg.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%2Fayh2f0c9a8rp81ci6ycg.png" alt=" " width="800" height="299"&gt;&lt;/a&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fct3i4czvzy94gsablqrm.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%2Fct3i4czvzy94gsablqrm.png" alt=" " width="800" height="156"&gt;&lt;/a&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsizm1cwdandrlfvk1tcg.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%2Fsizm1cwdandrlfvk1tcg.png" alt=" " width="800" height="374"&gt;&lt;/a&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbskgmkn8tjastj7lsr5k.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%2Fbskgmkn8tjastj7lsr5k.png" alt=" " width="800" height="254"&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/lasyapriyaputti" rel="noopener noreferrer"&gt;
        lasyapriyaputti
      &lt;/a&gt; / &lt;a href="https://github.com/lasyapriyaputti/KiranaVoice" rel="noopener noreferrer"&gt;
        KiranaVoice
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&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; Voice ─▶ browser speech recognition ─▶ rule-based parser ──┐
                                                            ├─▶ checked against the item catalog
 Unclear speech ─▶ Gemma 2 (2B) via Ollama ─────────────────┘            │
                                                                         ▼
        Stock question ─▶ answered at once       Sale / delivery ─▶ read back aloud ─▶ Confirm ─▶ SQLite
                                                                                                    │
                                              sales history ─▶ TabPFN (or weekday average) ─▶ morning alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The AI is not the whole system.&lt;/strong&gt; If a plain program can decide something reliably, a plain program should. Telling "sold" from "aaya", reading "250 gram", or knowing that "kg" is a unit and not an item are all done by ordinary code. &lt;strong&gt;Gemma 2 (2B) via Ollama&lt;/strong&gt; is asked only when the rules understand nothing. Its answer must then match a real item in the catalog, or it is thrown away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The system never guesses.&lt;/strong&gt; If it doesn't understand, it says so and asks again. It will not quietly record "milk" because that was the default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forecasting.&lt;/strong&gt; For every item with enough history, I train &lt;strong&gt;TabPFN&lt;/strong&gt; on small tabular features: day of week, weekend, festival, same day last week and a rolling average. TabPFN is built for small datasets, and one shop's history is small. With too little data it falls back to a weekday/weekend average. Each alert includes a range and a reorder amount with a 15% safety buffer. Every confirmed sale feeds back into the history. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Python, Streamlit, SQLite (WAL mode), Ollama with Gemma 2 2B, TabPFN, and a small custom browser component for the mic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What testing taught me.&lt;/strong&gt; My first version had bugs that would have quietly wrecked a real shop's stock:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It looked up items with &lt;code&gt;LIKE '%Milk%'&lt;/code&gt;, so one sale could change several products.&lt;/li&gt;
&lt;li&gt;It treated the word "kg" as proof that the item was sugar.&lt;/li&gt;
&lt;li&gt;When it understood nothing, it recorded Milk anyway.&lt;/li&gt;
&lt;li&gt;Every spoken sentence reloaded the whole page and reset the language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I fixed each one with exact item matching, unit words ignored when choosing items, an explicit "I didn't understand", and a mic component that hands text straight to Python. I also made every confirmation idempotent, so a double tap can't record a sale twice.&lt;/p&gt;

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

&lt;p&gt;A kirana's daily sales are its business. Here is what open tooling made possible that a closed API would not have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The shop's data stays in the shop.&lt;/strong&gt; Stock and sales live in a local SQLite file, and the AI can run on the owner's own machine. Nothing has to be sent to a company's server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No meter running.&lt;/strong&gt; There is no per-request fee. Kirana margins are thin, and a bill that grows with every sale would end the idea before it started.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I can change it.&lt;/strong&gt; Adding a language means adding item names and keywords, not retraining or renegotiating anything. A better open model can replace Gemma without touching the rest of the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It can get more private.&lt;/strong&gt; Chrome's speech recognition still sends audio to Google, so KiranaVoice is &lt;strong&gt;not fully offline yet&lt;/strong&gt;. The fix is an offline Indian-language speech model from the open Whisper family, and only open weights let me plan that.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Known Limits, and What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 2 2B is still learning Telugu, Tamil and Kannada.&lt;/strong&gt; That's why plain rules handle most sentences, with Gemma as a safety net. Next: test a larger open model and fine-tune on real shop speech.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech recognition still needs internet,&lt;/strong&gt; because Chrome sends audio to Google. Next: an offline Indian-language model from the open Whisper family.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The forecast on the demo uses sample sales history,&lt;/strong&gt; not real sales. It learns from every confirmed sale, so it improves with use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Brand-name items&lt;/strong&gt; still appear in English. Next: regional-language names, which native speakers can contribute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The morning alert shows when the app is opened.&lt;/strong&gt; Next: WhatsApp delivery, since that's where owners actually look.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond that, I plan to add &lt;strong&gt;udhaar&lt;/strong&gt; (credit given to regular customers) tracking by voice.&lt;/p&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; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Best Use of TabPFN&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

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