<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Sam Parmar on Medium]]></title>
        <description><![CDATA[Stories by Sam Parmar on Medium]]></description>
        <link>https://medium.com/@parmsam?source=rss-dff427493333------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*PL273317twlP0CrNsV2rlg@2x.jpeg</url>
            <title>Stories by Sam Parmar on Medium</title>
            <link>https://medium.com/@parmsam?source=rss-dff427493333------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 11 Apr 2026 09:10:40 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@parmsam/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[ellmer and chatlas Chat objects automatically handle tool loops]]></title>
            <link>https://parmsam.medium.com/ellmer-and-chatlas-chat-objects-automatically-handle-tool-loops-054a42418e38?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/054a42418e38</guid>
            <category><![CDATA[loop]]></category>
            <category><![CDATA[ellmer]]></category>
            <category><![CDATA[chatlas]]></category>
            <category><![CDATA[agents]]></category>
            <category><![CDATA[tools]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Fri, 07 Nov 2025 00:07:35 GMT</pubDate>
            <atom:updated>2025-11-09T19:38:06.738Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="A minimalist blue gradient cover image for a tech blog post titled “ellmer and chatlas: Chat objects automatically handle tool loops.” The design features white sans-serif text and a diagram showing a smiling chat bubble connected by looping arrows to three boxes labeled “TOOL CALL,” representing automatic function-calling cycles. The layout is clean and modern, evoking automation and LLM tool orchestration." src="https://cdn-images-1.medium.com/max/1024/1*SY4yMbdO5HKt-_hNq9e0Nw.png" /><figcaption>A minimalist blue gradient cover image for a tech blog post titled “ellmer and chatlas: Chat objects automatically handle tool loops.” The design features white sans-serif text and a diagram showing a smiling chat bubble connected by looping arrows to three boxes labeled “TOOL CALL,” representing automatic function-calling cycles. The layout is clean and modern, evoking automation and LLM tool orchestration.</figcaption></figure><p>A few months ago, Simon Willison <a href="https://simonwillison.net/2025/Sep/18/agents/">posted a compelling definition of agents on his blog</a>: “An LLM agent runs tools in a loop to achieve a goal.” This got me thinking about how <a href="https://ellmer.tidyverse.org/index.html">ellmer</a> and <a href="https://posit-dev.github.io/chatlas/">chatlas</a>, two R and Python packages for building LLM chat applications, handle the tool loop.</p><p>The answer? They handle it automatically. Once you register your tools with a Chat object, the R package and Python library take care of the entire loop for you. There’s no additional steps required.</p><h3>Seeing the Tool Loop in Action</h3><p>Here’s a minimal example showing how ellmer automatically manages multiple tool calls to solve a math problem:</p><pre>``` r<br>library(ellmer)<br><br># Define simple R functions<br>adder &lt;- function(a,b){<br>  return(a + b)<br>}<br><br>multer &lt;- function(a,b){<br>  return(a * b)<br>}<br><br># Wrap them as tools with descriptions<br>tool_adder &lt;- tool(<br>  adder,<br>  description = &quot;Adds two numbers together.&quot;,<br>  arguments  = list(<br>    a = type_integer(&quot;First number to add.&quot;),<br>    b = type_integer(&quot;Second number to add.&quot;)<br>  )<br>)<br><br>tool_multer &lt;- tool(<br>  multer,<br>  description = &quot;Multiplies two numbers together.&quot;,<br>  arguments  = list(<br>    a = type_integer(&quot;First number to multiply.&quot;),<br>    b = type_integer(&quot;Second number to multiply.&quot;)<br>  )<br>)<br><br># Create a chat and register the tools<br>chat &lt;- chat_anthropic(model = &quot;claude-3-7-sonnet-20250219&quot;)<br><br>chat$register_tool(tool_adder)<br>chat$register_tool(tool_multer)<br><br># Ask the LLM to solve a problem requiring multiple tool calls<br>response &lt;- chat$chat(&quot;Can you use adder and multer to solve 50101*1020+547892+10010? Just give me the numeric answer with no commas.&quot;)<br>#&gt; I&#39;ll solve 50101*1020+547892+10010 using the available tools.<br>#&gt; <br>#&gt; First, I&#39;ll multiply 50101 by 1020, and then add the result to 547892 and <br>#&gt; 10010.<br>#&gt; ◯ [tool call] multer(a = 50101L, b = 1020L)<br>#&gt; ● #&gt; 51103020<br>#&gt; Now I&#39;ll add the multiplication result (51103020) to 547892:<br>#&gt; ◯ [tool call] adder(a = 51103020L, b = 547892L)<br>#&gt; ● #&gt; 51650912<br>#&gt; Finally, I&#39;ll add 10010 to the previous result:<br>#&gt; ◯ [tool call] adder(a = 51650912L, b = 10010L)<br>#&gt; ● #&gt; 51660922<br>#&gt; The answer is 51660922.<br><br># Verify the result<br>expectation &lt;- 50101*1020+547892+10010<br><br>grepl(<br>  pattern = as.character(expectation), <br>  x = expectation<br>)<br>#&gt; [1] TRUE<br>```<br><br>&lt;sup&gt;Created on 2025-11-06 with [reprex v2.0.2](https://reprex.tidyverse.org)&lt;/sup&gt;</pre><p>Notice how the Chat object seamlessly handled three sequential tool calls without any manual intervention. The LLM decided which tools to call, in what order, and when it had enough information to provide the final answer.</p><p>Here’s an example using Chatlas in Python too (you can run this one yourself to see each of the tool calls):</p><pre>import chatlas as ctl<br>from dotenv import load_dotenv<br>load_dotenv()<br><br># Define simple Python functions<br>def adder(a: int, b: int) -&gt; int:<br>    &quot;&quot;&quot;<br>    Adds two numbers together.<br>    <br>    Parameters<br>    ----------<br>    a : int<br>        First number to add.<br>    b : int<br>        Second number to add.<br>    &quot;&quot;&quot;<br>    return a + b<br><br>def multer(a: int, b: int) -&gt; int:<br>    &quot;&quot;&quot;<br>    Multiplies two numbers together.<br>    <br>    Parameters<br>    ----------<br>    a : int<br>        First number to multiply.<br>    b : int<br>        Second number to multiply.<br>    &quot;&quot;&quot;<br>    return a * b<br><br># Create a chat and register the tools<br>chat = ctl.ChatAnthropic(model=&quot;claude-3-7-sonnet-20250219&quot;)<br>chat.register_tool(adder)<br>chat.register_tool(multer)<br><br># Ask the LLM to solve a problem requiring multiple tool calls<br>response = chat.chat(&quot;Can you use adder and multer to solve 50101*1020+547892+10010? Just give me the numeric answer with no commas.&quot;)<br><br># Verify the response contains the expected answer<br>expectation = 50101 * 1020 + 547892 + 10010<br>assert str(expectation) in response.content</pre><h3>What’s Happening Behind the Scenes</h3><p>The Chat object is doing the heavy lifting here:</p><ol><li><strong>Managing conversation state</strong>: It tracks all messages exchanged between you and the LLM</li><li><strong>Executing the tool loop</strong>: When the LLM requests a tool call, the Chat object executes your R/Python function, captures the result, and sends it back to the LLM</li><li><strong>Iterating until completion</strong>: This loop continues until the LLM has everything it needs to answer your question</li></ol><p>This abstraction means you can focus on defining your tools and asking questions, while the package and library handles all the orchestration.</p><h3>Learn More</h3><p>Both packages offer similar functionality:</p><p><a href="https://ellmer.tidyverse.org/reference/Chat.html">The Chat object - Chat</a></p><blockquote>“A Chat is a sequence of user and assistant <a href="https://ellmer.tidyverse.org/reference/Turn.html">Turn</a>s sent to a specific <a href="https://ellmer.tidyverse.org/reference/Provider.html">Provider</a>. A Chat is a mutable R6 object that takes care of managing the state associated with the chat; i.e. it records the messages that you send to the server, and the messages that you receive back. If you register a tool (i.e. an R function that the assistant can call on your behalf), it also takes care of the tool loop.</blockquote><blockquote>You should generally not create this object yourself, but instead call <a href="https://ellmer.tidyverse.org/reference/chat_openai.html">chat_openai()</a> or friends instead.”</blockquote><p><a href="https://posit-dev.github.io/chatlas/reference/Chat.html">chatlas</a></p><blockquote>“A chat object that can be used to interact with a language model.</blockquote><blockquote>A Chat is an sequence of sequence of user and assistant <a href="https://posit-dev.github.io/chatlas/reference/Turn.html#chatlas.Turn">Turn</a>s sent to a specific <a href="https://posit-dev.github.io/chatlas/reference/Provider.html#chatlas.Provider">Provider</a>. A Chat takes care of managing the state associated with the chat; i.e. it records the messages that you send to the server, and the messages that you receive back. If you register a tool (i.e. an function that the assistant can call on your behalf), it also takes care of the tool loop.”</blockquote><p>By automatically handling the tool loop, these packages make it remarkably simple to build LLM agents that can accomplish multi-step tasks using the functions you provide.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=054a42418e38" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Tracking token usage and cost in Shinychat-based apps]]></title>
            <link>https://parmsam.medium.com/tracking-token-usage-and-cost-in-shinychat-based-apps-c3f692e12f25?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/c3f692e12f25</guid>
            <category><![CDATA[cost-usage]]></category>
            <category><![CDATA[shinychat]]></category>
            <category><![CDATA[token-usage]]></category>
            <category><![CDATA[ellmer]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Sat, 01 Nov 2025 16:46:38 GMT</pubDate>
            <atom:updated>2025-11-05T13:57:56.777Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="“Digital illustration showing a modern dashboard concept for a Medium article titled ‘Tracking Token Usage and Cost in Shinychat-based Apps’. The design features a chat interface with a robot icon representing an AI assistant, alongside a cost and token usage display reading ‘Cost: $0.015 | Tokens: 260’. A subtle line chart rises in the background, set against a deep blue backdrop with white and light-blue elements, conveying data transparency and modern analytics.”" src="https://cdn-images-1.medium.com/max/1024/1*sLmr1NmaOdYa6GqxD6ncQQ.png" /><figcaption><strong>Digital illustration generated using ChatGPT showing a modern dashboard concept for a Medium article titled <em>‘Tracking Token Usage and Cost in Shinychat-based Apps’</em>. The design features a chat interface with a robot icon representing an AI assistant, alongside a cost and token usage display reading ‘Cost: $0.015 | Tokens: 260’. A subtle line chart rises in the background, set against a deep blue backdrop with white and light-blue elements, conveying data transparency and modern analytics.</strong></figcaption></figure><p>Building AI-powered applications with Shiny has become increasingly accessible thanks to open-source packages like <a href="https://posit-dev.github.io/shinychat/">shinychat</a> and <a href="https://ellmer.tidyverse.org/index.html">ellmer</a>. However, as LLM costs can quickly add up, monitoring token usage and expenses in real-time is crucial for production applications</p><h3>The Challenge</h3><p>When I was working on <a href="https://github.com/parmsam/diagrambot">diagrambot</a> (a fork of <a href="https://posit.co/">Posit</a>’s <a href="https://github.com/tidyverse/ggbot2/">ggbot2</a>), I realized the importance of cost transparency. Users should know how much their AI interactions are costing, and developers need to monitor usage patterns to optimize their applications. ggbot2 does this and diagrambot does it too on top of the <a href="https://github.com/posit-dev/shinyrealtime/">Shinyrealtime</a> R package.</p><h3>The Solution: Built-in Tracking with ellmer</h3><p>The good news? The ellmer package makes this surprisingly straightforward, if you’re developing chat-based LLM apps. It provides built-in methods to track both token usage and approximate costs across all major LLM providers, calculating these metrics automatically as your chat progresses.</p><h3>Key Methods</h3><ul><li><a href="https://ellmer.tidyverse.org/reference/Chat.html?q=get_tokens#method-get-tokens-">get_tokens</a>(): Returns a data frame with detailed token usage per interaction</li><li><a href="https://ellmer.tidyverse.org/reference/Chat.html?q=get_tokens#method-get-cost-">get_cost</a>(): Calculates cumulative costs based on the provider&#39;s pricing model</li></ul><h3>Implementation: Before and After</h3><p>Let’s transform a basic Shinychat app (<a href="https://ellmer.tidyverse.org/articles/streaming-async.html?q=shinychat#shiny-example">Shinychat app in the ellmer docs</a>) to include real-time cost and token tracking. Here’s how this would look if you wanted to do this.</p><h4>Before: Basic Chat App</h4><pre>library(shiny)<br>library(shinychat)<br><br>ui &lt;- bslib::page_fillable(<br>  chat_mod_ui(&quot;chat&quot;)<br>)<br><br>server &lt;- function(input, output, session) {<br>  chat &lt;- ellmer::chat_openai(<br>    system_prompt = &quot;You&#39;re a trickster who answers in riddles&quot;,<br>    model = &quot;gpt-4.1-nano&quot;<br>  )<br><br>  chat_mod_server(&quot;chat&quot;, chat)<br>}<br><br>shinyApp(ui, server)</pre><h4>After: Enhanced with Cost Tracking</h4><pre>library(shiny)<br>library(shinychat)<br><br>ui &lt;- bslib::page_fillable(<br>  # Token and cost tracking display<br>  div(<br>    style = &quot;padding: 10px; margin-bottom: 10px; background-color: #f8f9fa; border-radius: 5px;&quot;,<br>    helpText(<br>      &quot;Cost: &quot;,<br>      textOutput(&quot;session_cost_chat&quot;, inline = TRUE),<br>      &quot; | Tokens: &quot;,<br>      textOutput(&quot;session_tokens_chat&quot;, inline = TRUE)<br>    )<br>  ),<br>  chat_mod_ui(&quot;chat&quot;)<br>)<br><br>server &lt;- function(input, output, session) {<br>  chat &lt;- ellmer::chat_openai(<br>    system_prompt = &quot;You&#39;re a trickster who answers in riddles&quot;,<br>    model = &quot;gpt-4.1-nano&quot;<br>  )<br><br>  chat_mod_server(&quot;chat&quot;, chat)<br>  <br>  # Use reactiveValues for mutable state<br>  values &lt;- reactiveValues(<br>    last_turn_count = 0,<br>    tokens = 0,<br>    cost = 0<br>  )<br>  <br>  # Only update when turns actually change<br>  observe({<br>    invalidateLater(1000)  # Check every second<br>    <br>    current_turns &lt;- length(chat$get_turns())<br>    <br>    # Only recalculate if turns have actually changed<br>    if (current_turns != values$last_turn_count) {<br>      values$last_turn_count &lt;- current_turns<br>      <br>      # Update metrics only when needed<br>      tokens_df &lt;- chat$get_tokens()<br>      values$tokens &lt;- if(nrow(tokens_df) &gt; 0) sum(tokens_df$tokens, na.rm = TRUE) else 0<br>      values$cost &lt;- chat$get_cost(include = &quot;all&quot;)<br>    }<br>  })<br>  <br>  # Clean reactive outputs<br>  output$session_cost_chat &lt;- renderText({<br>    sprintf(&quot;$%.4f&quot;, values$cost)<br>  })<br>  <br>  output$session_tokens_chat &lt;- renderText({<br>    as.character(values$tokens)<br>  })<br>}<br><br>shinyApp(ui, server)</pre><h3>Key Implementation Details</h3><h3>1. Efficient State Management</h3><p>Using reactiveValues() provides a clean way to manage mutable state across the application, avoiding unnecessary re-computations.</p><h3>2. Update Logic</h3><p>The code only recalculates costs and tokens when the conversation actually changes (detected by monitoring turn count).</p><h3>Production Considerations</h3><p>When deploying this pattern in production applications, you might use it to consider:</p><ul><li><strong>Rate Limiting</strong>: Add logic to prevent excessive usage</li><li><strong>User Budgets</strong>: Implement per-user cost limits</li><li><strong>Historical Tracking</strong>: Store usage data for analytics</li><li><strong>Multiple Models</strong>: Track costs across different LLM providers</li></ul><h3>Conclusion</h3><p>Adding cost and token tracking to your Shinychat applications is both straightforward and essential. The ellmer package’s built-in methods make it easy to provide transparency to users while giving developers the insights they need to optimize their AI-powered applications. If you’re using Python, the chatlas <a href="https://posit-dev.github.io/chatlas/reference/Chat.html#chatlas.Chat.get_cost">Chat object</a>, also from Posit, has similar token usage and cost tracking methods you should check out. Note that ellmer <a href="https://ellmer.tidyverse.org/news/index.html">seems to retrieve pricing info</a> from the LiteLLM GitHub repo and have emphasized treating token costs provided from the package as approximations before. The same probably also applies to chatlas.</p><p>This pattern has proven useful in <strong>diagrambot</strong> and can easily be adapted to any Shinychat-based application. Your users will appreciate the transparency, and you’ll have the data needed to make informed decisions about model selection and usage optimization.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c3f692e12f25" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Putting words in Claude’s mouth using ellmer]]></title>
            <link>https://parmsam.medium.com/putting-words-in-claudes-mouth-using-ellmer-bcd0a15a457f?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/bcd0a15a457f</guid>
            <category><![CDATA[set]]></category>
            <category><![CDATA[message]]></category>
            <category><![CDATA[claude]]></category>
            <category><![CDATA[ellmer]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Sat, 28 Jun 2025 23:51:01 GMT</pubDate>
            <atom:updated>2025-07-15T17:55:08.732Z</atom:updated>
            <content:encoded><![CDATA[<h4>Pre-scripting Claude responses with ellmer’s flexible Chat object</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lk9hZqh7KH-h58s_EEiW-w.png" /><figcaption><strong>Illustration of a friendly yellow robot with two antennas, smiling on an orange background. A speech bubble above its head says ‘Custom Conversations.’ The title at the top reads ‘Putting words in Claude’s mouth using ellmer.</strong></figcaption></figure><p>I&#39;ve recently been using <a href="https://ellmer.tidyverse.org/index.html">ellmer</a> a lot for <a href="https://github.com/search?q=owner%3Aparmsam+ellmer&amp;type=repositories">different fun projects</a> on my Github. I love the <a href="https://ellmer.tidyverse.org/reference/Chat.html#method-Chat-get_turns">R6 Chat object</a> that the package uses to send messages to an LLM provider. I recently realized that there is a <a href="https://ellmer.tidyverse.org/reference/Chat.html#method-set-turns-">method in the object to set</a> the turns to whatever you want. This reminded me of an <a href="https://github.com/anthropics/courses/blob/master/anthropic_api_fundamentals/02_messages_format.ipynb">Anthropic training</a>, where they show you how you can pass your own series of messages (as long as they comply with the convention) through to the model.</p><p>This technique essentially lets you craft the conversation history that Claude sees, giving you precise control over how the assistant responds. Each <a href="https://ellmer.tidyverse.org/reference/Turn.html">Turn</a> represents one exchange in the conversation, with a role (user or assistant) and the content of that exchange. By setting up these turns manually, you can establish patterns, demonstrate specific response styles, or create few-shot learning examples.</p><p>The applications for this are quite powerful. You could get a conversation from one model and seamlessly continue it with another model. You might establish a consistent persona or response format across multiple interactions. Or you can create training examples that teach Claude to respond in a very specific way to certain types of input.</p><p>Let me show you how this works with a simple sentiment analysis <a href="https://reprex.tidyverse.org/">reprex</a> where we &quot;teach&quot; Claude to classify pickle-related tweets as either POSITIVE or NEGATIVE. This example is straight from the <a href="https://github.com/anthropics/courses/blob/master/anthropic_api_fundamentals/02_messages_format.ipynb">Anthropic training</a>.</p><pre>``` r<br>library(ellmer)<br>#&gt; Warning: package &#39;ellmer&#39; was built under R version 4.3.3<br><br>chat &lt;- chat_anthropic()<br>#&gt; Using model = &quot;claude-sonnet-4-20250514&quot;.<br><br>turns &lt;- list(<br>  Turn(role = &quot;user&quot;, contents = list(ContentText(&quot;Unpopular opinion: Pickles are disgusting. Don&#39;t @ me&quot;))),<br>  Turn(role = &quot;assistant&quot;, contents = list(ContentText(&quot;NEGATIVE&quot;))),<br>  Turn(role = &quot;user&quot;, contents = list(ContentText(&quot;I think my love for pickles might be getting out of hand. I just bought a pickle-shaped pool float&quot;))),<br>  Turn(role = &quot;assistant&quot;, contents = list(ContentText(&quot;POSITIVE&quot;))),<br>  Turn(role = &quot;user&quot;, contents = list(ContentText(&quot;Seriously why would anyone ever eat a pickle?  Those things are nasty!&quot;))),<br>  Turn(role = &quot;assistant&quot;, contents = list(ContentText(&quot;NEGATIVE&quot;)))<br>)<br><br>chat$set_turns(turns)<br><br>chat$chat(&quot;Just tried the new spicy pickles from @PickleCo, and my taste buds are doing a happy dance! 🌶️🥒 #pickleslove #spicyfood&quot;)<br>#&gt; POSITIVE<br><br>chat<br>#&gt; &lt;Chat Anthropic/claude-sonnet-4-20250514 turns=8 tokens=134/5 $0.00&gt;<br>#&gt; ── user [0] ────────────────────────────────────────────────────────────────────<br>#&gt; Unpopular opinion: Pickles are disgusting. Don&#39;t @ me<br>#&gt; ── assistant [0] ───────────────────────────────────────────────────────────────<br>#&gt; NEGATIVE<br>#&gt; ── user [0] ────────────────────────────────────────────────────────────────────<br>#&gt; I think my love for pickles might be getting out of hand. I just bought a pickle-shaped pool float<br>#&gt; ── assistant [0] ───────────────────────────────────────────────────────────────<br>#&gt; POSITIVE<br>#&gt; ── user [0] ────────────────────────────────────────────────────────────────────<br>#&gt; Seriously why would anyone ever eat a pickle?  Those things are nasty!<br>#&gt; ── assistant [0] ───────────────────────────────────────────────────────────────<br>#&gt; NEGATIVE<br>#&gt; ── user [134] ──────────────────────────────────────────────────────────────────<br>#&gt; Just tried the new spicy pickles from @PickleCo, and my taste buds are doing a happy dance! 🌶️🥒 #pickleslove #spicyfood<br>#&gt; ── assistant [5] ───────────────────────────────────────────────────────────────<br>#&gt; POSITIVE<br>```<br><br>&lt;sup&gt;Created on 2025-06-28 with [reprex v2.0.2](https://reprex.tidyverse.org)&lt;/sup&gt;</pre><p>As you can see, by providing Claude with a few examples of how to classify pickle-related sentiment, it learned the pattern and correctly identified the enthusiastic tweet about spicy pickles as POSITIVE. This approach gives you another level of control over how the assistant responds to you, making it particularly useful for tasks requiring consistent formatting or specific response patterns. By crafting synthetic assistant responses in your conversation history, you can effectively demonstrate exactly how you want the model to behave without needing actual prior interactions. This technique opens up interesting possibilities for creating more sophisticated interactions with language models, whether you’re building specialized tools or just experimenting with different ways to guide AI responses.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bcd0a15a457f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Package & tools I learned about at posit::conf(2024)]]></title>
            <link>https://parmsam.medium.com/package-tools-i-learned-about-at-posit-conf-2024-dbdd118ec14f?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/dbdd118ec14f</guid>
            <category><![CDATA[posit]]></category>
            <category><![CDATA[conf]]></category>
            <category><![CDATA[tools]]></category>
            <category><![CDATA[package]]></category>
            <category><![CDATA[2024]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Tue, 27 Aug 2024 02:24:00 GMT</pubDate>
            <atom:updated>2024-08-27T02:35:23.912Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/270/0*La_ERS3VSQXC_e-p" /><figcaption>Relaxed Kermit The Frog GIF by Muppet Wiki: <a href="https://giphy.com/gifs/muppetwiki-kermit-the-frog-jim-henson-rOGuft1jgiq66zpQI2">https://giphy.com/gifs/muppetwiki-kermit-the-frog-jim-henson-rOGuft1jgiq66zpQI2</a></figcaption></figure><p><a href="https://posit.co/conference/">Posit Conf 2024</a> in Seattle was great! Just like <a href="https://parmsam.medium.com/package-tools-i-learned-about-at-posit-conf-2023-95dc402e5467">my post from last year</a>, here’s a list of packages, tools, and resources I learned more about at the conference.</p><h3>Packages</h3><ul><li>cards — <a href="https://insightsengineering.github.io/cards/latest-tag/">https://insightsengineering.github.io/cards/latest-tag/</a>, <a href="https://github.com/insightsengineering/cards">https://github.com/insightsengineering/cards</a></li><li>xportr — <a href="https://atorus-research.github.io/xportr/index.html">https://atorus-research.github.io/xportr/index.html</a></li><li>admiral — <a href="https://pharmaverse.github.io/admiral/">https://pharmaverse.github.io/admiral/</a></li><li>gtsummary — <a href="http://www.danieldsjoberg.com/gtsummary">http://www.danieldsjoberg.com/gtsummary</a></li><li>tfrmt — <a href="https://gsk-biostatistics.github.io/tfrmt/">https://gsk-biostatistics.github.io/tfrmt/</a></li><li>labelled — <a href="https://larmarange.github.io/labelled/">https://larmarange.github.io/labelled/</a></li><li>matte — <a href="https://atorus-research.github.io/matte/">https://atorus-research.github.io/matte/</a></li><li>crew — <a href="https://wlandau.github.io/crew/">https://wlandau.github.io/crew/</a></li></ul><h3>Quarto extensions</h3><ul><li>closeread — <a href="https://closeread.netlify.app/">https://closeread.netlify.app/</a> , <a href="https://github.com/qmd-lab/closeread">https://github.com/qmd-lab/closeread</a></li><li>quarto-live — <a href="https://r-wasm.github.io/quarto-live/">https://r-wasm.github.io/quarto-live/</a>, <a href="https://github.com/r-wasm/quarto-live">https://github.com/r-wasm/quarto-live</a></li></ul><h3>AI tools</h3><ul><li>Recraft — <a href="https://www.recraft.ai">https://www.recraft.ai</a></li><li>Scribe — <a href="https://scribehow.com/">https://scribehow.com</a></li><li>Descript — <a href="https://www.descript.com/">https://www.descript.com/</a></li><li>Embedding.io — <a href="https://www.embedding.io/">https://www.embedding.io/</a></li></ul><h3>Books</h3><ul><li>Not the End of the World: How We Can Be the First Generation to Build a Sustainable Planet — <a href="https://www.amazon.com/dp/031653675X/?coliid=I2GCGMSTBM8O2M&amp;colid=SN2SYH9862VT&amp;psc=1&amp;ref_=list_c_wl_lv_ov_lig_dp_it">https://www.amazon.com/dp/031653675X/?coliid=I2GCGMSTBM8O2M&amp;colid=SN2SYH9862VT&amp;psc=1&amp;ref_=list_c_wl_lv_ov_lig_dp_it</a></li><li>Factfulness: Ten Reasons We’re Wrong About the World — and Why Things Are Better Than You Think — <a href="https://www.amazon.com/dp/1250107814/?coliid=I3OLO6YV0VIEU1&amp;colid=SN2SYH9862VT&amp;psc=1&amp;ref_=list_c_wl_lv_ov_lig_dp_it">https://www.amazon.com/dp/1250107814/?coliid=I3OLO6YV0VIEU1&amp;colid=SN2SYH9862VT&amp;psc=1&amp;ref_=list_c_wl_lv_ov_lig_dp_it</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dbdd118ec14f" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Generating Data Dictionaries from R Dataframes]]></title>
            <link>https://parmsam.medium.com/generating-data-dictionaries-from-r-dataframes-9582ce2f6732?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/9582ce2f6732</guid>
            <category><![CDATA[r]]></category>
            <category><![CDATA[dataframes]]></category>
            <category><![CDATA[labelled]]></category>
            <category><![CDATA[data-dictionary]]></category>
            <category><![CDATA[generate]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Mon, 19 Aug 2024 02:45:01 GMT</pubDate>
            <atom:updated>2024-08-27T02:12:05.027Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*MnIWBz9SthYf9FJf" /><figcaption>Photo by <a href="https://unsplash.com/@waldemarbrandt67w?utm_source=medium&amp;utm_medium=referral">Waldemar</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>When working with data in R, it&#39;s often helpful to include metadata such as the full name of columns, data types, and lengths. This metadata can be stored in label attributes within R dataframes, which is particularly useful when dealing with large or complex datasets with many columns.</p><h3>Checking for Label Attributes in Dataframes</h3><p>In R, not all dataframes come with label attributes by default. However, if these attributes are present, they provide valuable context about your data. You can check if your dataframe includes label attributes by using the str() function. This function will display the structure of your dataframe, including any label attributes.</p><p>Alternatively, if you’re using the RStudio IDE, you can use the View() function to visually inspect your dataframe. When you hover over the column names, any associated label attributes will be displayed as a tooltip.</p><h3>Using the labelled Package for Managing Column Labels</h3><p>If your dataframe doesn’t have label attributes, or if you want to manage or add labels, the labelled package is a great tool. This package is particularly useful for working with data imported from SAS, SPSS or Stata, where label attributes are more common.</p><p><a href="https://larmarange.github.io/labelled/">Manipulating Labelled Data</a></p><h4>Installing and Loading the labelled Package</h4><p>First, install and load the labelled package:</p><pre>install.packages(&quot;labelled&quot;)<br>library(labelled)</pre><h4>Example: Generating a Data Dictionary</h4><p>Let’s say you have imported a dataset from a XPT file using the haven package, which preserves the label attributes. You’ve confirmed that this has useful column labels we could use to create a data dictionary.</p><pre>library(haven)<br>library(labelled)<br><br># Importing a sas7bdat file<br>url &lt;- &quot;https://github.com/phuse-org/phuse-scripts/raw/master/data/adam/cdisc/adae.xpt&quot;<br>df &lt;- read_xpt(url)<br><br># Check the structure to see the label attributes<br>str(df)<br><br># Create a data dictionary using those attributes<br>generate_dictionary(df)</pre><h3>Conclusion</h3><p>Utilizing label attributes in R can significantly enhance the usability of your dataframes, especially when dealing with large or complex datasets. By leveraging the labelled package&#39;s <a href="https://larmarange.github.io/labelled/articles/look_for.html">generate_dictionary</a>() function, you can easily create comprehensive data dictionaries that make your data more understandable and accessible. You can also use the package to add labels into existing dataframes using <a href="https://larmarange.github.io/labelled/articles/intro_labelled.html#variable-labels">var_label</a>().</p><p>Whether you’re working with data imported from SPSS, Stata, or SAS files, incorporating label attributes into your workflow can save time and reduce errors, making your analysis more efficient.</p><h3>Learn More</h3><p><a href="https://www.pipinghotdata.com/">Shannon Pileggi</a> had a great talk from this year’s Posit Conf on this topic. It should be posted on the <a href="https://www.youtube.com/@PositPBC/videos">Posit Youtube Channel</a> later this year. You can check out her very thorough blog post on this topic to learn more:</p><p><a href="https://www.pipinghotdata.com/posts/2020-12-23-leveraging-labelled-data-in-r/">PIPING HOT DATA: Leveraging labelled data in R</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9582ce2f6732" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Bunch of Quarto Extensions]]></title>
            <link>https://parmsam.medium.com/building-a-bunch-of-quarto-extensions-c16e9e13c700?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/c16e9e13c700</guid>
            <category><![CDATA[revealjs]]></category>
            <category><![CDATA[plugins]]></category>
            <category><![CDATA[extension]]></category>
            <category><![CDATA[quarto]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Fri, 02 Aug 2024 14:05:27 GMT</pubDate>
            <atom:updated>2024-08-24T11:26:17.542Z</atom:updated>
            <content:encoded><![CDATA[<h3>Building a Bunch of Quarto Extensions for Presentations</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P2E1kiFOmRvHfLXrGRJang@2x.jpeg" /><figcaption>Photo by <a href="https://www.callmefred.com">Call Me Fred</a> on <a href="https://unsplash.com/?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Lately, I’ve been diving deep into the world of Quarto Extensions in my free time. I’ve found myself creating functionalities that I wished I had for my presentation slides. Here’s a breakdown of the different Quarto extensions I’ve developed to support the RevealJS format. I’ve shared these on the official <a href="https://quarto.org/docs/extensions/listing-revealjs.html">Quarto RevealJS plugins page</a> too.</p><h3>Speech Recognition Extension</h3><p>This extension allows for real-time speech recognition during presentations, enhancing accessibility and interactivity. It lets you verbally control your slides. Check it out here: <a href="https://github.com/parmsam/quarto-speech">GitHub — parmsam/quarto-speech</a>.</p><h3>Subtitles Extension</h3><p>Add live subtitles to your presentations with ease. This extension is perfect for making your content accessible to a broader audience. Explore it here: <a href="https://github.com/parmsam/quarto-subtitles">GitHub — parmsam/quarto-subtitles</a>.</p><h3>Text-to-Speech (TTS) Extension</h3><p>This TTS extension reads out the content of your slides, providing an additional layer of accessibility and engagement for folks who may want to replay your slides. You can find it here: <a href="https://github.com/parmsam/quarto-tts">GitHub — parmsam/quarto-tts</a>.</p><h3>Live Webcam Video Feed Extension</h3><p>Integrate a live webcam feed into your presentations to create a more dynamic and personal experience. Learn more about it here: <a href="https://github.com/parmsam/quarto-webcam">GitHub — parmsam/quarto-webcam</a>.</p><h3>Flashcards Extension</h3><p>A simple yet powerful tool to add flashcards to your presentations, perfect for quizzes and interactive learning sessions. Check it out here: <a href="https://github.com/parmsam/quarto-flashcards">GitHub — parmsam/quarto-flashcards</a>.</p><h3>Excalidraw Extension</h3><p>Open an empty Excalidraw canvas within your presentations, allowing for real-time drawing and brainstorming. Explore this extension here: <a href="https://github.com/parmsam/quarto-excalidraw">GitHub — parmsam/quarto-excalidraw</a>.</p><h3>Multiple Choice Quiz Extension</h3><p>Add interactive multiple-choice quiz questions to your presentation slides, making them more engaging and educational. Learn more about it here: <a href="https://github.com/parmsam/quarto-quiz">GitHub — parmsam/quarto-quiz</a>.</p><p>Each of these extensions brings unique functionality to the RevealJS format, making presentations more interactive, accessible, and engaging. I hope you find them as useful as I have!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c16e9e13c700" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Package & tools I learned about at posit::conf(2023)]]></title>
            <link>https://parmsam.medium.com/package-tools-i-learned-about-at-posit-conf-2023-95dc402e5467?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/95dc402e5467</guid>
            <category><![CDATA[conf]]></category>
            <category><![CDATA[package]]></category>
            <category><![CDATA[posit]]></category>
            <category><![CDATA[2023]]></category>
            <category><![CDATA[tools]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Tue, 26 Sep 2023 15:50:09 GMT</pubDate>
            <atom:updated>2023-09-27T12:21:06.823Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*SgpKbEyBGL3cy3bt" /><figcaption>Kermit the Frog at typewriter: <a href="https://giphy.com/gifs/muppets-LmBsnpDCuturMhtLfw">https://giphy.com/gifs/muppets-LmBsnpDCuturMhtLfw</a></figcaption></figure><p><a href="https://posit.co/conference/">Posit Conf 2023</a> in Chicago was awesome! Here’s a list of packages and tools I learned about (or learned more about) at the conference. I’m making this list so it’s easier for me or others to explore documentation or source code. Tools followed by links. Here’s a link to the <a href="https://github.com/parmsam/posit-conf-2023-notes/tree/main">repo with my notes</a>, for more info. Looking forward to next year’s conference in Seattle.</p><ul><li>{shinylive} for R— <a href="https://posit-dev.github.io/r-shinylive/">https://posit-dev.github.io/r-shinylive, /</a><a href="https://github.com/posit-dev/r-shinylive">https://github.com/posit-dev/r-shinylive</a></li><li>Shinylive Quarto extension (Python and R)— <a href="https://quarto-ext.github.io/shinylive/">https://quarto-ext.github.io/shinylive/</a>, <a href="https://github.com/quarto-ext/shinylive">https://github.com/quarto-ext/shinylive</a>, <a href="https://github.com/posit-dev/r-shinylive">https://github.com/posit-dev/r-shinylive</a></li><li>Shinylive for R editor to run, write, and share Shiny for R apps directly in browser — <a href="https://shinylive.io/r/examples/">https://shinylive.io/r/examples/</a></li><li>{shinyuieditor} now out of alpha — <a href="https://rstudio.github.io/shinyuieditor/">https://rstudio.github.io/shinyuieditor/</a>, <a href="https://github.com/rstudio/shinyuieditor">https://github.com/rstudio/shinyuieditor</a></li><li>Shiny for Python — <a href="https://shiny.posit.co/py/">https://shiny.posit.co/py/</a>, <a href="https://github.com/posit-dev/py-shiny">https://github.com/posit-dev/py-shiny</a></li><li>{bslib} &gt;v0.5 — <a href="https://rstudio.github.io/bslib/index.html">https://rstudio.github.io/bslib/index.html</a>, <a href="https://github.com/rstudio/bslib">https://github.com/rstudio/bslib</a></li><li>webR — <a href="https://docs.r-wasm.org/webr/latest/">https://docs.r-wasm.org/webr/latest/</a>, <a href="https://github.com/r-wasm/webr">https://github.com/r-wasm/webr</a></li><li>Chatstream — <a href="https://wch.github.io/chatstream/">https://wch.github.io/chatstream/</a>, <a href="https://github.com/wch/chatstream">https://github.com/wch/chatstream</a></li><li>openplayground (for LLMs)— <a href="https://nat.dev/">https://nat.dev/</a>, <a href="https://github.com/nat/openplayground">https://github.com/nat/openplayground</a></li><li>h2ogpt — <a href="https://gpt.h2o.ai/">https://gpt.h2o.ai/</a>, <a href="https://github.com/h2oai/h2ogpt">https://github.com/h2oai/h2ogpt</a></li><li>Codeowners files in Github — <a href="https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners">https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners</a></li><li>Github Copilot with RStudio (in daily build for now) — <a href="https://dailies.rstudio.com/">https://dailies.rstudio.com/</a>, <a href="https://colorado.posit.co/rsc/rstudio-copilot/#/TitleSlide">https://colorado.posit.co/rsc/rstudio-copilot/#/TitleSlide</a></li><li>R Packages book now in 2e — <a href="https://r-pkgs.org/">https://r-pkgs.org/</a></li><li>{teal} — <a href="https://insightsengineering.github.io/teal/latest-tag/">https://insightsengineering.github.io/teal/latest-tag/</a>, <a href="https://github.com/insightsengineering/teal">https://github.com/insightsengineering/teal</a></li><li>{tfrmt} — <a href="https://gsk-biostatistics.github.io/tfrmt/">https://gsk-biostatistics.github.io/tfrmt/</a>, <a href="https://github.com/GSK-Biostatistics/tfrmt">https://github.com/GSK-Biostatistics/tfrmt</a></li><li>{riskscore} — <a href="https://github.com/pharmaR/riskscore">https://github.com/pharmaR/riskscore</a></li><li>{riskmetric} —<a href="https://pharmar.github.io/riskmetric/">https://pharmar.github.io/riskmetric/</a>, <a href="https://github.com/pharmaR/riskmetric">https://github.com/pharmaR/riskmetric</a></li><li>{slushy} — <a href="https://gsk-biostatistics.github.io/slushy/">https://gsk-biostatistics.github.io/slushy/</a>, <a href="https://github.com/GSK-Biostatistics/slushy">https://github.com/GSK-Biostatistics/slushy</a></li><li>duckdb — <a href="https://duckdb.org/">https://duckdb.org/</a>, <a href="https://github.com/duckdb/duckdb">https://github.com/duckdb/duckdb</a></li><li>{duckplyr} — <a href="https://duckdblabs.github.io/duckplyr/">https://duckdblabs.github.io/duckplyr/</a>, <a href="https://github.com/duckdblabs/duckplyr">https://github.com/duckdblabs/duckplyr</a></li><li>{dbtplyr} —<a href="https://emilyriederer.github.io/dbtplyr/#!/overview">https://emilyriederer.github.io/dbtplyr/</a>, <a href="https://github.com/emilyriederer/dbtplyr">https://github.com/emilyriederer/dbtplyr</a></li><li>siuba —<a href="https://siuba.org/">https://siuba.org/</a>, <a href="https://github.com/machow/siuba">https://github.com/machow/siuba</a></li><li>{vetiver} — <a href="https://vetiver.rstudio.com/">https://vetiver.rstudio.com/</a>, <a href="https://rstudio.github.io/vetiver-r/">https://rstudio.github.io/vetiver-r/</a>, <a href="https://github.com/rstudio/vetiver-r/">https://github.com/rstudio/vetiver-r/</a></li><li>{tidymodels} — <a href="https://tidymodels.tidymodels.org/">https://tidymodels.tidymodels.org/</a>, <a href="https://github.com/tidymodels/tidymodels">https://github.com/tidymodels/tidymodels</a>, <a href="https://www.tidymodels.org/">https://www.tidymodels.org/</a>, <a href="https://www.tmwr.org/">https://www.tmwr.org/</a></li><li>{targets} — <a href="https://docs.ropensci.org/targets/">https://docs.ropensci.org/targets/</a>, <a href="https://github.com/ropensci/targets">https://github.com/ropensci/targets</a></li><li>{epoxy} — <a href="https://pkg.garrickadenbuie.com/epoxy/">https://pkg.garrickadenbuie.com/epoxy/</a>, <a href="https://github.com/gadenbuie/epoxy">https://github.com/gadenbuie/epoxy</a>, <a href="https://www.garrickadenbuie.com/talk/epoxy-super-glue/">https://www.garrickadenbuie.com/talk/epoxy-super-glue/</a></li><li>Quarto shortcode extensions — <a href="https://quarto.org/docs/extensions/listing-filters.html">https://quarto.org/docs/extensions/listing-filters.html</a>, <a href="https://github.com/rich-iannone/quarto-icons-examples">https://github.com/rich-iannone/quarto-icons-examples</a>, <a href="https://github.com/mcanouil/awesome-quarto">https://github.com/mcanouil/awesome-quarto</a></li><li>Quartodoc — <a href="https://machow.github.io/quartodoc/get-started/overview.html">https://machow.github.io/quartodoc/get-started/overview.html</a>, <a href="https://github.com/rich-iannone/quarto-icons-examples">https://github.com/rich-iannone/quarto-icons-examples</a></li><li>Parametrized Quarto — <a href="https://quarto.org/docs/computations/parameters.html#knitr">https://quarto.org/docs/computations/parameters.html#knitr</a>, <a href="https://github.com/jadeynryan/2023_posit-parameterized-quarto/blob/main/2023_posit-parameterized-quarto.qmd">https://github.com/jadeynryan/2023_posit-parameterized-quarto/</a></li><li>Formatting extension for Quarto called qformat — <a href="https://github.com/rich-iannone/qformat">https://github.com/rich-iannone/qformat</a></li><li>Quarto typst — <a href="https://quarto.org/docs/prerelease/1.4/typst.html">https://quarto.org/docs/prerelease/1.4/typst.html</a>, <a href="https://github.com/typst/typst">https://github.com/typst/typst</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=95dc402e5467" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Icebreakers and Tomato Timers in Shiny for Python]]></title>
            <link>https://parmsam.medium.com/icebreakers-and-tomato-timers-in-shiny-for-python-bf43a2b94731?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/bf43a2b94731</guid>
            <category><![CDATA[shiny]]></category>
            <category><![CDATA[tomato-timer]]></category>
            <category><![CDATA[pomodoro]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[shiny-for-python]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Sat, 16 Sep 2023 16:40:51 GMT</pubDate>
            <atom:updated>2023-09-16T16:40:51.720Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JgA2HU2FVFcIzN-E" /><figcaption>Photo by <a href="https://unsplash.com/@edoneil?utm_source=medium&amp;utm_medium=referral">Ed O&#39;Neil</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><p>Here’s a quick update on what I’ve been up to with <a href="https://shinylive.io/py/">Shiny for Python</a>. Last month, I cooked up a couple applications during my downtime, just for kicks.</p><h4>Icebreaker-py</h4><p>Meet Icebreaker-py, a source for randomized icebreaker questions. The dataset for this tool comprises <a href="https://github.com/parmsam/icebreaker-py/blob/main/data/icebreakers.csv">around 100 unique questions</a> that I curated with the assistance of ChatGPT. In addition to generating questions, I’ve integrated some user-friendly features:</p><ul><li>Randomize: Spice things up with the ‘R’ key to generate a new question. Use the slider to select up to five questions.</li><li>Copy icebreakers: A quick press of the ‘C’ key copies the question to your clipboard.</li><li>Toggle Difficulty: Dial the challenge up or down with the ‘D’ key.</li></ul><p>Perhaps ChatGPT got a bit carried away with the emojis, but hey, who’s counting? 😅 Check it out for yourself here: <a href="https://github.com/parmsam/icebreaker-py">Icebreaker-py on GitHub</a>.</p><h4>Pomotimer-py</h4><p>Pomotimer-py presented a slightly steeper learning curve. Inspired by traditional Pomodoro timers, I recreated some apps I’ve found useful for enhancing my productivity. This project could give you valuable insights into the following:</p><ul><li>Navbar Layouts: How to structure an intuitive navigation interface.</li><li>Modals: Pop-up elements to interact with the user.</li><li>Shiny Reactivity: Real-time updates without having to refresh the page.</li></ul><p>Curious? Take a look at the repository: <a href="https://github.com/parmsam/pomotimer-py">Pomotimer-py on GitHub</a>.</p><p>Both projects were fun to build and deepened my understanding of Shiny for Python. They’re live for you to use, remix, or draw inspiration from. Enjoy!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bf43a2b94731" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AI Assistants Maximized]]></title>
            <link>https://parmsam.medium.com/ai-assistants-maximized-30f093fdc216?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/30f093fdc216</guid>
            <category><![CDATA[short-books]]></category>
            <category><![CDATA[programmer]]></category>
            <category><![CDATA[quarto]]></category>
            <category><![CDATA[ai-assistant]]></category>
            <category><![CDATA[tips-and-tricks]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Mon, 24 Jul 2023 21:56:59 GMT</pubDate>
            <atom:updated>2023-08-27T22:49:03.822Z</atom:updated>
            <content:encoded><![CDATA[<h4>Tips and Tricks for Programmers: a short book</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/0*44bncIxOQOUk6dFJ" /><figcaption><a href="https://giphy.com/gifs/southpark-south-park-deep-learning-s26e4-qAtZM2gvjWhPjmclZE">https://giphy.com/gifs/southpark-south-park-deep-learning-s26e4-qAtZM2gvjWhPjmclZE</a></figcaption></figure><p>I started working on a short guidance book with tips and tricks for use of AI tools such as <a href="https://chat.openai.com/">ChatGPT</a>, <a href="https://bard.google.com/">Bard</a>, <a href="https://github.com/features/copilot">Github Copilot</a> or <a href="https://openai.com/dall-e-2">DALL-E</a>. So far, it collects different use cases that I’ve run into as a programmer. Example prompts are also provided with a few of the use cases. This book is created using <a href="https://quarto.org/">Quarto</a>. It’s hosted on Github pages, with the source code available on <a href="https://github.com/parmsam/tips-and-tricks-ai-tools">Github</a>.</p><p>It’s still a work in progress, but I thought I’d share it in a blog post.</p><ul><li><a href="https://parmsam.github.io/tips-and-tricks-ai-tools/">AI Assistants Maximized</a></li><li><a href="https://github.com/parmsam/tips-and-tricks-ai-tools">GitHub - parmsam/tips-and-tricks-ai-tools: AI Assistants Maximized: a book (WIP)</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=30f093fdc216" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Date Countdown Apps using Shiny for Python]]></title>
            <link>https://parmsam.medium.com/date-countdown-apps-using-shiny-for-python-d1fa0a424b39?source=rss-dff427493333------2</link>
            <guid isPermaLink="false">https://medium.com/p/d1fa0a424b39</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[shiny]]></category>
            <category><![CDATA[apps]]></category>
            <category><![CDATA[countdown]]></category>
            <category><![CDATA[py-shiny]]></category>
            <dc:creator><![CDATA[Sam Parmar]]></dc:creator>
            <pubDate>Wed, 21 Jun 2023 00:01:32 GMT</pubDate>
            <atom:updated>2023-08-15T20:19:00.947Z</atom:updated>
            <content:encoded><![CDATA[<h4>Personalized Event and Birthday Countdowns</h4><figure><img alt="dispicible me countdown gif" src="https://cdn-images-1.medium.com/max/500/0*pIQeV_0bHRtcP6Bg" /><figcaption><a href="https://giphy.com/gifs/countdown-C0NhnyKT89QdO">https://giphy.com/gifs/countdown-C0NhnyKT89QdO</a></figcaption></figure><p>Alright, let’s keep it short. <a href="https://shiny.posit.co/py/">Shiny for Python</a> is a Python library that lets you build cool apps in Python. <a href="https://shiny.posit.co/py/docs/shinylive.html">Shinylive</a> lets you Shiny for Python apps entirely in the web browser. What’s nice is that you can even pull live data from your <a href="https://support.google.com/docs/answer/183965?hl=en&amp;co=GENIE.Platform%3DDesktop">Google Spreadsheets that you’ve made public</a> into your Shinylive apps.</p><p>Here are two examples (see repo link below). One’s a <a href="https://parmsam.github.io/date-countdown-py/birthdays">birthday countdown</a> app with a slider for upcoming birthdays and a search bar to quickly find someone’s day. The other’s an <a href="https://parmsam.github.io/date-countdown-py/events">event countdown</a> app, listing what’s coming up and allowing event name searches.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F3pykoGHJO8nMTquG095Lg.png" /><figcaption>Birthday countdown app with days remaining text output</figcaption></figure><p><a href="https://github.com/parmsam/date-countdown-py/">GitHub - parmsam/date-countdown-py: Example date countdown apps built using Shiny for Python</a></p><p>Want to learn more? Check out the link below to dive into Shiny for Python. Think of your own simple project that can use the library. This one took me about an hour or two after work. The documentation on the official website is great with tons of examples.</p><p><a href="https://shiny.rstudio.com/py/">Shiny for Python</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d1fa0a424b39" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>