<?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: nk_Enuke</title>
    <description>The latest articles on DEV Community by nk_Enuke (@nk_maker).</description>
    <link>https://dev.to/nk_maker</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1784539%2F383feba9-c5aa-4fbc-b78e-e0da16e905b7.png</url>
      <title>DEV Community: nk_Enuke</title>
      <link>https://dev.to/nk_maker</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nk_maker"/>
    <language>en</language>
    <item>
      <title>Kaggle:Trying to Reproduce the 1st Place NeurIPS Polymer Prediction Solution (Scaled-Down Experiment)</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Sun, 22 Mar 2026 16:37:24 +0000</pubDate>
      <link>https://dev.to/nk_maker/trying-to-reproduce-the-1st-place-neurips-polymer-prediction-solution-scaled-down-experiment-5d72</link>
      <guid>https://dev.to/nk_maker/trying-to-reproduce-the-1st-place-neurips-polymer-prediction-solution-scaled-down-experiment-5d72</guid>
      <description>&lt;h2&gt;
  
  
  A post-competition reproduction attempt by someone with a chemistry background
&lt;/h2&gt;

&lt;p&gt;The NeurIPS Open Polymer Prediction 2025 competition challenged about 2,000 teams to predict five physical properties of polymers from their chemical structure (SMILES strings).&lt;/p&gt;

&lt;p&gt;I have a background in chemistry, so after the competition ended I read through James Day's 1st place writeup and tried to reproduce the approach as best I could. With a late submission, I got a &lt;strong&gt;Private LB score of 0.08180&lt;/strong&gt; — which should be roughly equivalent to &lt;strong&gt;8th place&lt;/strong&gt; out of 2,240 teams. Though of course, this was done after the competition closed, so it should be taken with a grain of salt.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This article describes a &lt;strong&gt;scaled-down reproduction experiment&lt;/strong&gt;. All solution design credit goes to James Day. My goal was simply to see how far I could get reproducing his approach with limited resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;James Day's 1st Place Writeup:&lt;br&gt;
&lt;a href="https://www.kaggle.com/competitions/neurips-open-polymer-prediction-2025/writeups/1st-place-solution" rel="noopener noreferrer"&gt;https://www.kaggle.com/competitions/neurips-open-polymer-prediction-2025/writeups/1st-place-solution&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/nkwork9999" rel="noopener noreferrer"&gt;
        nkwork9999
      &lt;/a&gt; / &lt;a href="https://github.com/nkwork9999/NeurIP2025_mytrial_following_1st_solution" rel="noopener noreferrer"&gt;
        NeurIP2025_mytrial_following_1st_solution
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Reproducing the 1st Place NeurIPS Polymer Prediction 2025 Solution&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Top-8 equivalent score (0.08180) on the Private Leaderboard using CodeBERTa-small&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This repository contains a reproduction of &lt;a href="https://www.kaggle.com/competitions/neurips-open-polymer-prediction-2025/discussion" rel="nofollow noopener noreferrer"&gt;James Day's 1st place solution&lt;/a&gt; for the &lt;a href="https://www.kaggle.com/competitions/neurips-open-polymer-prediction-2025" rel="nofollow noopener noreferrer"&gt;NeurIPS - Open Polymer Prediction 2025&lt;/a&gt; Kaggle competition.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is a reproduction study, not original work. All credit for the solution design goes to the original authors. The purpose is to verify reproducibility and provide a working codebase for the community.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Competition Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task:&lt;/strong&gt; Predict 5 polymer properties (Tg, FFV, Tc, Density, Rg) from chemical structure (SMILES)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric:&lt;/strong&gt; Weighted Mean Absolute Error (wMAE)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale:&lt;/strong&gt; 2,240 teams, $50,000 prize pool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ground truth:&lt;/strong&gt; Averaged from multiple molecular dynamics simulation runs&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Results&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;Rank&lt;/th&gt;
&lt;th&gt;Team&lt;/th&gt;
&lt;th&gt;Score (wMAE)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;James Day&lt;/td&gt;
&lt;td&gt;0.07536&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Ezra&lt;/td&gt;
&lt;td&gt;0.07722&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Ghy HUST CS&lt;/td&gt;
&lt;td&gt;0.07820&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;CoderGirlM&lt;/td&gt;
&lt;td&gt;0.08144&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;-&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;This reproduction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.08180&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Dmitry Uarov&lt;/td&gt;
&lt;td&gt;0.08271&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Late submission score of &lt;strong&gt;0.08180&lt;/strong&gt; — equivalent to 8th place out…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/nkwork9999/NeurIP2025_mytrial_following_1st_solution" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Clone the repo and install dependencies to run the pipeline yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nkwork9999/NeurIP2025_mytrial_following_1st_solution.git
&lt;span class="nb"&gt;cd &lt;/span&gt;NeurIP2025_mytrial_following_1st_solution

pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The training notebooks are designed to run on Google Colab (L4 GPU, ~7 hours). Open the notebooks in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Train CodeBERTa&lt;/strong&gt; — Fine-tune with SMILES augmentation and 5-fold CV&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Train AutoGluon&lt;/strong&gt; — Tabular model on RDKit descriptors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ensemble &amp;amp; submit&lt;/strong&gt; — Combine predictions and apply post-processing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Refer to the repo's README for the full walkthrough.&lt;/p&gt;


&lt;h2&gt;
  
  
  Competition Overview
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The Task
&lt;/h3&gt;

&lt;p&gt;Given a polymer's SMILES notation, predict five molecular-dynamics-simulated physical properties:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tg&lt;/td&gt;
&lt;td&gt;Glass transition temperature&lt;/td&gt;
&lt;td&gt;degC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FFV&lt;/td&gt;
&lt;td&gt;Fractional free volume&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tc&lt;/td&gt;
&lt;td&gt;Thermal conductivity&lt;/td&gt;
&lt;td&gt;W/(m*K)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Density&lt;/td&gt;
&lt;td&gt;Density&lt;/td&gt;
&lt;td&gt;g/cm^3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rg&lt;/td&gt;
&lt;td&gt;Radius of gyration&lt;/td&gt;
&lt;td&gt;angstrom&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  The Sparse Label Problem
&lt;/h3&gt;

&lt;p&gt;The defining challenge of this competition was &lt;strong&gt;extreme label sparsity&lt;/strong&gt;. Not every polymer had all five properties measured — the number of available samples varied widely across targets.&lt;/p&gt;
&lt;h3&gt;
  
  
  Evaluation Metric
&lt;/h3&gt;

&lt;p&gt;Weighted Mean Absolute Error (wMAE), normalized by each property's value range, with higher weights assigned to properties with fewer samples. In other words, &lt;strong&gt;the rarest labels matter most&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  James Day's 1st Place Solution
&lt;/h2&gt;

&lt;p&gt;Day's winning approach was an ensemble of three models:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ModernBERT-base&lt;/strong&gt; — Treats SMILES as text, with a regression head for property prediction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AutoGluon&lt;/strong&gt; — A tabular model using RDKit descriptors and Morgan fingerprints as features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uni-Mol 2&lt;/strong&gt; — A pretrained model that accounts for 3D molecular structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most surprising finding: &lt;strong&gt;a code-pretrained ModernBERT-base outperformed chemistry-specific models&lt;/strong&gt;. SMILES notation resembles source code — parentheses, symbols, and repeating structural patterns — so a tokenizer trained on code captures SMILES structure remarkably well. I found this genuinely fascinating. It makes sense that SMILES, being string-based, can benefit from large language models, but the fact that a code-pretrained model specifically has an advantage was unexpected.&lt;/p&gt;
&lt;h3&gt;
  
  
  Insights from 2nd and 3rd Place
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2nd place (Ezra):&lt;/strong&gt; Simply converting Tg units from Celsius to Fahrenheit dramatically improved the score. Achieved a high rank with ExtraTreesRegressor — a relatively simple model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3rd place (Hongyu Guo):&lt;/strong&gt; GATv2Conv (6 layers) + Morgan fingerprints, with post-hoc linear regression calibration.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  My Reproduction: Design Decisions
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why CodeBERTa-small?
&lt;/h3&gt;

&lt;p&gt;Day used ModernBERT-base (125M parameters). I went with &lt;strong&gt;CodeBERTa-small (84M parameters)&lt;/strong&gt; — honestly, I simply wanted to try things out easily on Google Colab. Training had to fit within the L4 GPU time limit (~7 hours), and I wanted to get something running quickly without too much setup.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pipeline Architecture
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMILES --&amp;gt; CodeBERTa-small --&amp;gt; Regression Head --&amp;gt; 5 properties
                                    | (ensemble)
SMILES --&amp;gt; RDKit features --&amp;gt; AutoGluon --&amp;gt; 5 properties
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each target is trained with 5-fold cross-validation. At inference, 30 rounds of test-time augmentation (TTA) are applied.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Key Technique: Random SMILES Augmentation
&lt;/h2&gt;

&lt;p&gt;This is the &lt;strong&gt;single most impactful technique&lt;/strong&gt; in the pipeline.&lt;/p&gt;
&lt;h3&gt;
  
  
  SMILES Are Not Unique
&lt;/h3&gt;

&lt;p&gt;The same molecule can be represented by &lt;strong&gt;hundreds of different SMILES strings&lt;/strong&gt;, depending on the atom traversal order:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example: Ethanol
  Canonical: CCO
  Random 1:  OCC
  Random 2:  C(O)C
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;RDKit's &lt;code&gt;MolToSmiles(mol, canonical=False, doRandom=True)&lt;/code&gt; generates randomized SMILES on the fly.&lt;/p&gt;
&lt;h3&gt;
  
  
  Training: 10x Augmentation
&lt;/h3&gt;

&lt;p&gt;Each epoch presents the same molecule with a different SMILES representation (10x augmentation). This forces the model to learn &lt;strong&gt;representation-invariant molecular features&lt;/strong&gt; rather than memorizing a specific string.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SMILESDataset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smiles_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aug_factor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smiles_list&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;labels&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aug_factor&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__len__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aug&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__getitem__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;ri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smiles&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;smi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;random_smiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;smiles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ri&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;  &lt;span class="c1"&gt;# Random SMILES each time
&lt;/span&gt;        &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Inference: TTA with Median Aggregation
&lt;/h3&gt;

&lt;p&gt;At test time, 30 random SMILES variants are generated per molecule, and the &lt;strong&gt;median&lt;/strong&gt; prediction is taken as the final output. Median is preferred over mean to suppress outlier predictions.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;predict_tta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;smiles_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_tta&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;all_preds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_tta&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;aug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;random_smiles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;smiles_list&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;preds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;aug&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;all_preds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_preds&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Aggregate with median
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Personal note: I find this technique quite intriguing. It feels somewhat analogous to adding noise to images in computer vision augmentation. I would have expected that randomizing the SMILES string might introduce confusing signals, but it actually works surprisingly well.&lt;/p&gt;


&lt;h2&gt;
  
  
  Post-Processing Tricks
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Tg Distribution Shift Correction
&lt;/h3&gt;

&lt;p&gt;There is a known distribution shift between the train and test Tg values. Adding &lt;code&gt;std * 0.5644&lt;/code&gt; to the predictions corrects for this shift. It is a rather analog/manual method, but it turned out to be quite effective.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tg_std&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;std&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;tg_shift&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tg_std&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5644&lt;/span&gt;
&lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Tg&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;tg_shift&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The coefficient &lt;code&gt;0.5644&lt;/code&gt; was found via grid search on out-of-fold predictions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Direct Match
&lt;/h3&gt;

&lt;p&gt;When a test SMILES exactly matches a training SMILES, the known training value is used directly instead of the model prediction. Simple but effective.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TARGETS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;iterrows&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SMILES&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;SMILES&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;notna&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;submission&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Leaderboard Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;th&gt;Team&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1st&lt;/td&gt;
&lt;td&gt;James Day&lt;/td&gt;
&lt;td&gt;0.07536&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2nd&lt;/td&gt;
&lt;td&gt;Ezra&lt;/td&gt;
&lt;td&gt;0.07722&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3rd&lt;/td&gt;
&lt;td&gt;Ghy HUST CS&lt;/td&gt;
&lt;td&gt;0.07820&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7th&lt;/td&gt;
&lt;td&gt;CoderGirlM&lt;/td&gt;
&lt;td&gt;0.08144&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;--&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;This reproduction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.08180&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8th&lt;/td&gt;
&lt;td&gt;Dmitry Uarov&lt;/td&gt;
&lt;td&gt;0.08271&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  What I Could Not Reproduce
&lt;/h2&gt;

&lt;p&gt;The biggest missing piece was &lt;strong&gt;Uni-Mol 2&lt;/strong&gt;, the 3D molecular structure model that was part of the 1st place ensemble. I was unable to reproduce this component — I did not have the required software environment set up, and the compute requirements were beyond what I had available. This was a clear limitation of my attempt.&lt;/p&gt;

&lt;p&gt;It made me wish there were lighter-weight methods for incorporating 3D molecular structure information. If something like a lightweight 3D-aware featurizer existed that could run on a single GPU, it would make these kinds of reproduction experiments much more practical.&lt;/p&gt;


&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;There are many summary articles about top competition solutions, but fewer attempts to actually write the code, run the pipeline, and verify the results. I wanted to try doing that here, even in a scaled-down form.&lt;/p&gt;

&lt;p&gt;This article may contain errors or misunderstandings — I would appreciate any corrections or feedback. If you notice something off, please feel free to leave a comment or open an issue on the repo.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/nkwork9999" rel="noopener noreferrer"&gt;
        nkwork9999
      &lt;/a&gt; / &lt;a href="https://github.com/nkwork9999/NeurIP2025_mytrial_following_1st_solution" rel="noopener noreferrer"&gt;
        NeurIP2025_mytrial_following_1st_solution
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Reproducing the 1st Place NeurIPS Polymer Prediction 2025 Solution&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Top-8 equivalent score (0.08180) on the Private Leaderboard using CodeBERTa-small&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This repository contains a reproduction of &lt;a href="https://www.kaggle.com/competitions/neurips-open-polymer-prediction-2025/discussion" rel="nofollow noopener noreferrer"&gt;James Day's 1st place solution&lt;/a&gt; for the &lt;a href="https://www.kaggle.com/competitions/neurips-open-polymer-prediction-2025" rel="nofollow noopener noreferrer"&gt;NeurIPS - Open Polymer Prediction 2025&lt;/a&gt; Kaggle competition.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; This is a reproduction study, not original work. All credit for the solution design goes to the original authors. The purpose is to verify reproducibility and provide a working codebase for the community.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Competition Overview&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Task:&lt;/strong&gt; Predict 5 polymer properties (Tg, FFV, Tc, Density, Rg) from chemical structure (SMILES)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metric:&lt;/strong&gt; Weighted Mean Absolute Error (wMAE)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale:&lt;/strong&gt; 2,240 teams, $50,000 prize pool&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ground truth:&lt;/strong&gt; Averaged from multiple molecular dynamics simulation runs&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Results&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Rank&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Team&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Score (wMAE)&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;James Day&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.07536&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Ezra&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.07722&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Ghy HUST CS&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.07820&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;CoderGirlM&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.08144&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;-&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;This reproduction&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;strong&gt;0.08180&lt;/strong&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Dmitry Uarov&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;0.08271&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;Late submission score of &lt;strong&gt;0.08180&lt;/strong&gt; — equivalent to 8th place out…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/nkwork9999/NeurIP2025_mytrial_following_1st_solution" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>datascience</category>
      <category>machinelearning</category>
      <category>science</category>
      <category>kaggle</category>
    </item>
    <item>
      <title>Fixing DuckDB Extension Deadlock: From Query Strings to LIST Types</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Wed, 03 Sep 2025 15:00:00 +0000</pubDate>
      <link>https://dev.to/nk_maker/fixing-duckdb-extension-deadlock-from-query-strings-to-list-types-10c2</link>
      <guid>https://dev.to/nk_maker/fixing-duckdb-extension-deadlock-from-query-strings-to-list-types-10c2</guid>
      <description>&lt;p&gt;My Project on Github&lt;br&gt;
&lt;a href="https://github.com/nkwork9999/icedduck" rel="noopener noreferrer"&gt;https://github.com/nkwork9999/icedduck&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;When implementing a data visualization extension for DuckDB, I encountered a critical issue: executing SQL queries within a scalar function context caused the entire database to deadlock. The original implementation looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This causes deadlock!&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;x_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x_query_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;y_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_query_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Solution: Using LIST Types
&lt;/h2&gt;

&lt;p&gt;Instead of accepting SQL query strings and executing them within the function, the solution was to accept pre-aggregated LIST types directly. This approach is both safer and more idiomatic for DuckDB extensions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Changes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Function Signature Update&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before: Accepting query strings&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;bar_chart_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScalarFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bar_chart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;BarChartFunction&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// After: Accepting LIST types&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;bar_chart_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScalarFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"bar_chart"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
     &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DOUBLE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
     &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;BarChartArrayFunction&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Extraction Logic&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Extract data from LIST types&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;x_list_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;x_list_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNull&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;x_list_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;LogicalTypeId&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;x_children&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ListValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x_list_value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x_children&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;x_data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;x_data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;x_children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Use
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Build the Rust chart viewer:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;rust_hello_duck
cargo build &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Build the DuckDB extension:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;make clean
make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running the Extension
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Start DuckDB&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;duckdb&lt;/span&gt;

&lt;span class="c1"&gt;-- Load the extension&lt;/span&gt;
&lt;span class="k"&gt;LOAD&lt;/span&gt; &lt;span class="s1"&gt;'build/release/extension/quack/quack.duckdb_extension'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Create sample data&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="nb"&gt;DECIMAL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Electronics'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Clothing'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Food'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Generate bar chart using LIST aggregation&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;bar_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="s1"&gt;'Sales Chart'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Happens
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;LIST()&lt;/code&gt; functions aggregate the data in DuckDB's query engine&lt;/li&gt;
&lt;li&gt;The aggregated data is passed to the extension function&lt;/li&gt;
&lt;li&gt;The function writes the data to a temporary file&lt;/li&gt;
&lt;li&gt;A separate Rust process is spawned to display the chart using Iced GUI&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Advanced Usage
&lt;/h2&gt;

&lt;p&gt;You can use more complex aggregations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Group by month and sum revenues&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;monthly_data&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; 
        &lt;span class="k"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_revenue&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;monthly_sales&lt;/span&gt;
    &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;month&lt;/span&gt;
    &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_revenue&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;bar_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;LIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_revenue&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'Monthly Revenue Analysis'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;monthly_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Avoid Nested Queries&lt;/strong&gt;: Never execute SQL queries within DuckDB function implementations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Aggregate Types&lt;/strong&gt;: LIST types are perfect for passing collections of data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separate Concerns&lt;/strong&gt;: Data aggregation happens in SQL, visualization in the extension&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process Isolation&lt;/strong&gt;: GUI applications should run in separate processes to avoid threading issues&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Performance Benefits
&lt;/h2&gt;

&lt;p&gt;This approach is not only safer but also more performant:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No query parsing overhead within the function&lt;/li&gt;
&lt;li&gt;Direct memory access to aggregated data&lt;/li&gt;
&lt;li&gt;Better query optimization by DuckDB's planner&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The complete implementation demonstrates how proper function design can avoid common pitfalls in database extension development while providing a clean, efficient interface for users.&lt;/p&gt;

</description>
      <category>duckdb</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Building a Real-time Data Visualization Extension for DuckDB with Rust and Iced</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Mon, 01 Sep 2025 09:58:18 +0000</pubDate>
      <link>https://dev.to/nk_maker/building-a-real-time-data-visualization-extension-for-duckdb-with-rust-and-iced-3edf</link>
      <guid>https://dev.to/nk_maker/building-a-real-time-data-visualization-extension-for-duckdb-with-rust-and-iced-3edf</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article demonstrates how to create a DuckDB extension that generates interactive charts using Rust and the Iced GUI framework. We'll build a system that executes SQL queries and displays the results as bar charts in a native window, bridging the gap between database analytics and visual representation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Project Setup and Architecture&lt;/li&gt;
&lt;li&gt;Creating the Rust Library with FFI&lt;/li&gt;
&lt;li&gt;Building the C++ Extension Wrapper&lt;/li&gt;
&lt;li&gt;Implementing the Iced Chart Viewer&lt;/li&gt;
&lt;li&gt;Handling macOS Threading Constraints&lt;/li&gt;
&lt;li&gt;Dynamic Data Visualization&lt;/li&gt;
&lt;li&gt;Troubleshooting and Lessons Learned&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Chapter 1: Project Setup and Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Our architecture consists of three main components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A C++ DuckDB extension that provides SQL functions&lt;/li&gt;
&lt;li&gt;A Rust library exposed via FFI (Foreign Function Interface)&lt;/li&gt;
&lt;li&gt;A standalone Iced application for rendering charts&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Directory Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iced_duck/
├── src/                    # C++ extension
│   ├── quack_extension.cpp
│   └── include/
│       └── quack_extension.hpp
├── rust_hello_duck/        # Rust library
│   ├── Cargo.toml
│   ├── src/
│   │   ├── lib.rs
│   │   └── bin/
│   │       └── chart_viewer.rs
├── CMakeLists.txt
└── Makefile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Chapter 2: Creating the Rust Library with FFI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic FFI Setup
&lt;/h3&gt;

&lt;p&gt;We started with a simple Rust library exposing C-compatible functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nb"&gt;c_char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CString&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;rust_hello_world&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;c_char&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CString&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from Duck!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.into_raw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;rust_hello_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;c_char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CString&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Learnings
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory Management&lt;/strong&gt;: Always provide a free function for allocated strings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safety Attributes&lt;/strong&gt;: Modern Rust requires explicit unsafe markers for FFI functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform Compatibility&lt;/strong&gt;: Handle different library extensions (.dylib, .so, .dll)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Chapter 3: Building the C++ Extension Wrapper
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dynamic Library Loading
&lt;/h3&gt;

&lt;p&gt;The C++ extension loads the Rust library at runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;rust_lib&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dlopen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lib_path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;c_str&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;RTLD_LAZY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;rust_lib&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Warning: Could not load Rust library&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Get function pointers&lt;/span&gt;
&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;rust_hello_world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rust_hello_world_fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;dlsym&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rust_lib&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"rust_hello_world"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Registering SQL Functions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;auto&lt;/span&gt; &lt;span class="n"&gt;rust_hello_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ScalarFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rust_hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;LogicalType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RustHelloScalarFun&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ExtensionUtil&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RegisterFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rust_hello_func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Chapter 4: Implementing the Iced Chart Viewer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Chart Application Structure
&lt;/h3&gt;

&lt;p&gt;We created a separate binary for the chart viewer to handle GUI rendering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ChartApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ChartData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Application&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ChartApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Theme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;iced&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChartData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Element&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.width&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Fill&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Fill&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nd"&gt;column!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data.title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="nf"&gt;.spacing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Canvas Drawing
&lt;/h3&gt;

&lt;p&gt;The actual chart rendering uses Iced's canvas API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Program&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ChartApp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;iced&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="n"&gt;_theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;iced&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;mouse&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Cursor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Geometry&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Frame&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="c1"&gt;// Draw bars&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data.y_data&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;max_value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;chart_height&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="nf"&gt;.fill_rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nn"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bar_width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="nf"&gt;.into_geometry&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Chapter 5: Handling macOS Threading Constraints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;On macOS, GUI applications must run on the main thread. Our initial approach using &lt;code&gt;thread::spawn&lt;/code&gt; resulted in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread '&amp;lt;unnamed&amp;gt;' panicked at:
on macOS, `EventLoop` must be created on the main thread!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;We launched the chart viewer as a separate process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;rust_show_chart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;c_char&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rust_hello_duck/target/release/chart_viewer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.spawn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CString&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Chart viewer launched"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.into_raw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CString&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="nf"&gt;.into_raw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Chapter 6: Dynamic Data Visualization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SQL Function Interface
&lt;/h3&gt;

&lt;p&gt;We created a &lt;code&gt;bar_chart&lt;/code&gt; function that accepts SQL queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;bar_chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'SELECT category FROM sales'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="s1"&gt;'SELECT amount FROM sales'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="s1"&gt;'Sales by Category'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Data Transfer
&lt;/h3&gt;

&lt;p&gt;Instead of complex JSON serialization, we used a simple text format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Save data to file&lt;/span&gt;
&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ofstream&lt;/span&gt; &lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/tmp/duckdb_chart_data.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;title_str&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;x_data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// comma-separated&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;y_data&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// comma-separated&lt;/span&gt;
&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Chapter 7: Troubleshooting and Lessons Learned
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common Issues Encountered
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Library Path Resolution&lt;/strong&gt;: Always try both relative and absolute paths&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deadlocks in Query Execution&lt;/strong&gt;: The &lt;code&gt;context.Query()&lt;/code&gt; method can cause deadlocks when called from within a DuckDB function&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type Compatibility&lt;/strong&gt;: Careful handling of numeric types between C++ and Rust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build System Complexity&lt;/strong&gt;: Managing both CMake and Cargo builds requires coordination&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Best Practices
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Simple&lt;/strong&gt;: Begin with basic FFI functions before adding complexity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debug Incrementally&lt;/strong&gt;: Add print statements at each stage of execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle Errors Gracefully&lt;/strong&gt;: Always provide fallback behavior&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Cross-platform Early&lt;/strong&gt;: Platform-specific issues can be significant&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;This project demonstrates the power of combining different technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DuckDB for SQL processing&lt;/li&gt;
&lt;li&gt;Rust for safe systems programming&lt;/li&gt;
&lt;li&gt;Iced for modern GUI development&lt;/li&gt;
&lt;li&gt;FFI for language interoperability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While the integration presents challenges, particularly around threading and build systems, the result is a powerful system that can transform SQL query results into interactive visualizations.&lt;/p&gt;

&lt;p&gt;The complete source code and additional examples are available in the project repository. Feel free to extend this foundation with additional chart types, improved error handling, or real-time data updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Enhancements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Support for multiple chart types (line, pie, scatter)&lt;/li&gt;
&lt;li&gt;Real-time data streaming&lt;/li&gt;
&lt;li&gt;Interactive chart features (zoom, pan, tooltips)&lt;/li&gt;
&lt;li&gt;Better error handling and user feedback&lt;/li&gt;
&lt;li&gt;Cross-platform installer generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding, and may your data always be beautifully visualized!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>BigQuery AI - Building the Future of Data:Day1</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Tue, 19 Aug 2025 15:00:00 +0000</pubDate>
      <link>https://dev.to/nk_maker/bigquery-ai-building-the-future-of-dataday1-54k</link>
      <guid>https://dev.to/nk_maker/bigquery-ai-building-the-future-of-dataday1-54k</guid>
      <description>&lt;h1&gt;
  
  
  Overview
&lt;/h1&gt;

&lt;p&gt;The goal is to build a prototype that processes unstructured data held by companies (chat logs, PDFs, screenshots, recordings, etc.) using BigQuery's AI capabilities to solve real-world business problems.&lt;br&gt;
I'm currently studying GCP data engineering and thought this would be perfect, so I decided to participate.&lt;br&gt;
The content is unique in that you select from 3 approaches (minimum 1 selection):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilizing BigQuery's generative AI features&lt;/li&gt;
&lt;li&gt;Vector search: ML.GENERATE_EMBEDDING, VECTOR_SEARCH, etc.&lt;/li&gt;
&lt;li&gt;Integrated analysis of structured/unstructured data: Object Tables, ObjectRef, Multimodal DataFrame, etc.
Also, the evaluation criteria are different from typical Kaggle competitions:&lt;/li&gt;
&lt;li&gt;Technical Implementation (35%): Code quality, effective use of BigQuery AI&lt;/li&gt;
&lt;li&gt;Innovation and Creativity (25%): Novelty of solution, business impact&lt;/li&gt;
&lt;li&gt;Demo and Presentation (20%): Clarity of problem definition, documentation quality&lt;/li&gt;
&lt;li&gt;Assets (20%): Quality of blog/video, public GitHub repository&lt;/li&gt;
&lt;li&gt;Bonus (10%): Feedback, survey submission&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Competition Without Dataset
&lt;/h1&gt;

&lt;p&gt;The most distinctive feature is that no data is provided&lt;br&gt;
Participants are free to choose and use publicly available datasets...&lt;br&gt;
For example, the following datasets are recommended:&lt;br&gt;
BigQuery public datasets overview page&lt;br&gt;
BigQuery public dataset marketplace&lt;br&gt;
Image datasets provided through Cloud Storage&lt;/p&gt;

&lt;h1&gt;
  
  
  Code Reading
&lt;/h1&gt;

&lt;p&gt;Code by Dao Sy Duy Minh&lt;br&gt;
&lt;a href="https://www.kaggle.com/code/daosyduyminh/simple-tutorial-weather-forecasting" rel="noopener noreferrer"&gt;https://www.kaggle.com/code/daosyduyminh/simple-tutorial-weather-forecasting&lt;/a&gt;&lt;br&gt;
Demonstrates 3 approaches for weather forecasting using BigQuery.&lt;br&gt;
Appears to be using Hanoi weather data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Python and Prophet
It seems you can use Prophet through bigquery.Client().&lt;/li&gt;
&lt;li&gt;BigQuery ML
You can retrieve datasets with dataset = bigquery.Dataset(dataset_id) and use them directly.
Usage is as simple as writing client.query(train_query), requiring relatively little code.&lt;/li&gt;
&lt;li&gt;BigQuery Generative AI
Large-scale predictions are possible using FROM AI.FORECAST&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>kaggle</category>
      <category>machinelearning</category>
      <category>prophet</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>Kaggle Diary: MITSUI&amp;CO. Commodity Prediction Challenge: Day 1</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Mon, 18 Aug 2025 08:00:00 +0000</pubDate>
      <link>https://dev.to/nk_maker/kaggle-diary-mitsuico-commodity-prediction-challenge-day-1-3kl4</link>
      <guid>https://dev.to/nk_maker/kaggle-diary-mitsuico-commodity-prediction-challenge-day-1-3kl4</guid>
      <description>&lt;h2&gt;
  
  
  Competition URL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/competitions/mitsui-commodity-prediction-challenge/rules#7-competition-data" rel="noopener noreferrer"&gt;https://www.kaggle.com/competitions/mitsui-commodity-prediction-challenge/rules#7-competition-data&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;The objective of this competition is to develop accurate and stable prediction models for commodity prices, which seems relatively straightforward. The data is lightweight, and unlike recent competitions that require high-spec PCs just to participate, I felt this was something I could actually join, so I decided to give it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data
&lt;/h2&gt;

&lt;p&gt;The dataset consists of multiple time series data obtained from financial markets worldwide, including various financial products such as metals, futures, US stocks, and foreign exchange. The markets include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LME: London Metal Exchange&lt;/li&gt;
&lt;li&gt;JPX: Japan Exchange Group&lt;/li&gt;
&lt;li&gt;US: Various US securities exchanges&lt;/li&gt;
&lt;li&gt;FX: Foreign Exchange&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1,977 columns - quite a large-scale dataset&lt;/li&gt;
&lt;li&gt;4 markets: LME (London metals), JPX (Japan), US (US stocks), FX (foreign exchange)&lt;/li&gt;
&lt;li&gt;424 targets: Single commodity returns and differences between commodity pairs&lt;/li&gt;
&lt;li&gt;1-4 day lags: Split into test_labels_lag_[1-4].csv&lt;/li&gt;
&lt;li&gt;Need to consider lags due to financial institution holidays and processing time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prediction
&lt;/h2&gt;

&lt;p&gt;Apparently, the actual leaderboard isn't very useful, as the evaluation is based on how well predictions match actual values after the competition ends.&lt;/p&gt;

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

&lt;p&gt;Reading public code shared by maverick_ss_26.&lt;/p&gt;

&lt;h3&gt;
  
  
  Examining Code to Verify if the Leaderboard is Really Invalid
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/code/maverickss26/commodity-price-prediction-v1" rel="noopener noreferrer"&gt;https://www.kaggle.com/code/maverickss26/commodity-price-prediction-v1&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Preprocessing and Other Tips
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Check data quality by summing null values: &lt;code&gt;.isnull().sum()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Display missing values using histograms&lt;/li&gt;
&lt;li&gt;Use Prophet time series model&lt;/li&gt;
&lt;li&gt;Express price volatility using standard deviation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  About Prophet Model Options
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;changepoint_prior_scale&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Trend change flexibility (smaller = more stable)
&lt;/span&gt;&lt;span class="n"&gt;interval_width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.95&lt;/span&gt;  &lt;span class="c1"&gt;# 95% confidence interval for predictions
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  General Example of Prophet Usage
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;prophet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Prophet&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="c1"&gt;# Data preparation (required: ds and y columns)
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ds&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2024-01-01&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2024-01-02&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2024-01-03&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# Dates
&lt;/span&gt;    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;110&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Values to predict
&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Create and train model
&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Prophet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create future dates
&lt;/span&gt;&lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make_future_dataframe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;periods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 7 days ahead
&lt;/span&gt;
&lt;span class="c1"&gt;# Execute prediction
&lt;/span&gt;&lt;span class="n"&gt;forecast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ds&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yhat&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yhat_lower&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;yhat_upper&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be used quite easily like this.&lt;br&gt;
It appears that the test data contains training data, which shows that the leaderboard is meaningless.&lt;/p&gt;

</description>
      <category>kaggle</category>
      <category>machinelearning</category>
      <category>prophet</category>
    </item>
    <item>
      <title>Reading CSVs with varying column counts that pandas cannot read using DuckDB</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Sat, 16 Aug 2025 07:26:27 +0000</pubDate>
      <link>https://dev.to/nk_maker/reading-csvs-with-varying-column-counts-that-pandas-cannot-read-using-duckdb-clh</link>
      <guid>https://dev.to/nk_maker/reading-csvs-with-varying-column-counts-that-pandas-cannot-read-using-duckdb-clh</guid>
      <description>&lt;h1&gt;
  
  
  What are CSV files with varying column counts?
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6, 54
58,81,62
75,84,64,21,55
20,71,55,32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are what they look like.&lt;br&gt;
For example, there are cases where CSV files output from devices have rows below the first line that contain more columns than expected.&lt;/p&gt;
&lt;h1&gt;
  
  
  Let's try converting this file to a pandas DataFrame
&lt;/h1&gt;

&lt;p&gt;So, let's mindlessly convert it to a pandas DataFrame with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
df = pd.read_csv("./csv_file1.csv")
print(df)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This resulted in the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pandas.errors.ParserError: Error tokenizing data. C error: Expected 3 fields in line 3, saw 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This seems to mean that line 3 had 5 columns when 3 were expected, causing an error.&lt;br&gt;
It appears that pandas looks at the first few lines (2 lines in this case, though it's unclear if 2 is the default) to determine the number of columns in the DataFrame. So when there are more columns than expected, it results in an error and the data cannot be read.&lt;/p&gt;
&lt;h1&gt;
  
  
  Solution 1: Find the maximum number of columns and fill the DataFrame with empty values for missing parts
&lt;/h1&gt;

&lt;p&gt;So I thought I could open the CSV file with something other than pandas, find the maximum number of columns, and then fill rows with fewer columns with empty values. Here's the code I created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
with open('./csv_file1.csv', 'r', encoding='utf-8') as file:
    lines = file.readlines()
comma_count_max = max(line.count(',') for line in lines)
columns = [f'col_{i+1}' for i in range(comma_count_max + 1)]
data = []
for line in lines:
    row_data = line.strip().split(',')
    # Add empty strings as needed
    if len(row_data) &amp;lt; len(columns):
        row_data += [''] * (len(columns) - len(row_data))
    data.append(row_data)
df = pd.DataFrame(data, columns=columns)
print(df)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since pandas gives an error when reading, I open the file with Python's open() function and find the line with the most commas among all lines. The number of commas + 1 gives us the maximum number of columns, so then I fill rows with fewer columns with empty strings.&lt;br&gt;
The result is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  col_1 col_2 col_3 col_4 col_5
0     6    54                  
1    58    81    62            
2    75    84    64    21    55
3    20    71    55    32      
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This achieves the requirement, but for example...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6, 54
58,81,62,,,,,
75,84,64,21,55
20,71,55,32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For data like this, the result would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  col_1 col_2 col_3 col_4 col_5 col_6 col_7 col_8
0     6    54                                    
1    58    81    62                              
2    75    84    64    21    55                  
3    20    71    55    32        
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is fine for a few rows, but I thought it would be quite heavy to do the process of opening CSV files and adding maximum comma count data to each row for large files.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution 2: Use DuckDB's null_padding option
&lt;/h1&gt;

&lt;p&gt;DuckDB's read_csv has a null_padding option that fills blank parts with null values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import duckdb
con = duckdb.connect(database=":memory:")
print(con.sql("SELECT * FROM read_csv('csv_file1.csv',null_padding=true)"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running these three lines of code gives us...?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ column0 │ column1 │ column2 │ column3 │ column4 │ column5 │ column6 │ column7 │
│  int64  │  int64  │  int64  │  int64  │  int64  │ varchar │ varchar │ varchar │
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│       6 │      54 │    NULL │    NULL │    NULL │ NULL    │ NULL    │ NULL    │
│      58 │      81 │      62 │    NULL │    NULL │ NULL    │ NULL    │ NULL    │
│      75 │      84 │      64 │      21 │      55 │ NULL    │ NULL    │ NULL    │
│      20 │      71 │      55 │      32 │    NULL │ NULL    │ NULL    │ NULL    │
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It automatically fills up to the maximum number of columns with nulls and even creates headers for the maximum number of columns.&lt;br&gt;
(Though naturally, the number of columns created matches the maximum number of commas.)&lt;br&gt;
By the way, when you want to convert to a DataFrame:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import duckdb
con = duckdb.connect(database=":memory:")
print(con.sql("SELECT * FROM read_csv('csv_file1.csv',null_padding=true)").df())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding .df() at the end like this converts it to a pandas DataFrame.&lt;br&gt;
If you're facing this issue, please give it a try! 🙌&lt;/p&gt;

</description>
      <category>dataengineering</category>
      <category>duckdb</category>
      <category>csv</category>
      <category>programming</category>
    </item>
    <item>
      <title>DuckDB 1.20 Released! Exploring the New Features</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Wed, 30 Apr 2025 11:12:59 +0000</pubDate>
      <link>https://dev.to/nk_maker/duckdb-120-released-exploring-the-new-features-2lmi</link>
      <guid>https://dev.to/nk_maker/duckdb-120-released-exploring-the-new-features-2lmi</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;DuckDB has been updated to version 1.20. 🙌&lt;br&gt;&lt;br&gt;
It seems that various features have been added, so I tried out some of the new functionality mentioned in the official blog.&lt;/p&gt;
&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://duckdb.org/2025/02/05/announcing-duckdb-120.html" rel="noopener noreferrer"&gt;https://duckdb.org/2025/02/05/announcing-duckdb-120.html&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Codename for this Update
&lt;/h2&gt;

&lt;p&gt;The codename for this release is "Histrionicus"&lt;br&gt;&lt;br&gt;
This refers to the Harlequin Duck (scientific name: Histrionicus histrionicus) that lives in cold rivers in North America, Greenland, Iceland, and Eastern Russia.&lt;br&gt;&lt;br&gt;
The Japanese name is "Shinorigamo," and they apparently fly to coastal areas of Hokkaido and the Tohoku region in winter.&lt;br&gt;&lt;br&gt;
I looked at some images, but since I've always lived in the western part of Japan, it has an appearance I don't think I've seen before. 🦆&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Python Code Setup
&lt;/h2&gt;

&lt;p&gt;I'm using the following code to enable DuckDB in Python (the usual setup):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;duckdb&lt;/span&gt;

&lt;span class="c1"&gt;# Create an in-memory DuckDB database
&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;duckdb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;:memory:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ① RANDOM() update now outputs more types of random numbers
&lt;/h3&gt;

&lt;p&gt;In this update, the random output has been changed from 32-bit to 64-bit.&lt;br&gt;&lt;br&gt;
So the previous limit:&lt;br&gt;&lt;br&gt;
32-bit maximum: 4,294,967,295 variations&lt;br&gt;&lt;br&gt;
has become:&lt;br&gt;&lt;br&gt;
64-bit maximum: 18,446,744,073,709,551,615 variations&lt;/p&gt;

&lt;p&gt;I tried the following code to test this. I generated 5 billion random numbers (note: this takes about 10 minutes).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Generate a large number of random numbers
&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
SELECT 
    COUNT(DISTINCT random_value) AS unique_count,
    MIN(random_value) AS min_value,
    MAX(random_value) AS max_value
FROM (
    SELECT CAST(RANDOM() * (2 ** 63) AS BIGINT) AS random_value
    FROM range(1, 5000000000)
) AS subquery
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# Execute the query and get results
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;max_32bit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;32-bit maximum: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_32bit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;max_64bit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;64-bit maximum: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;max_64bit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┬────────────┬─────────────────────┐
│ unique_count │ min_value  │      max_value      │
│    int64     │   int64    │        int64        │
├──────────────┼────────────┼─────────────────────┤
│   4999999093 │ 3023944772 │ 9223372031664709632 │
└──────────────┴────────────┴─────────────────────┘

32-bit maximum: 4294967295
64-bit maximum: 18446744073709551615
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looking at the output, it seems the unique values indeed exceed the 32-bit limit of about 4.3 billion types.&lt;br&gt;&lt;br&gt;
(I'm not completely sure if this is the meaning of the update.)&lt;/p&gt;
&lt;h3&gt;
  
  
  ② Map return values changed from lists to single values
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'k'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'v'&lt;/span&gt;&lt;span class="p"&gt;])[&lt;/span&gt;&lt;span class="s1"&gt;'k'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This creates a dictionary (map) with k and v, and when called with key k, the result should be v.&lt;br&gt;&lt;br&gt;
When running this code previously, the result was apparently:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;['v']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the update, it's now:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────────┐
│ "map"(main.list_value('k'), main.list_value('v'))['k'] │
│                        varchar                         │
├────────────────────────────────────────────────────────┤
│ v                                                      │
└────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could be a significant change for those who have been using map, as the return value has changed from a list to a single string.&lt;/p&gt;

&lt;h3&gt;
  
  
  ③ Adding primary keys to existing tables
&lt;/h3&gt;

&lt;p&gt;It seems you can now add primary keys to tables you've already created!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alice&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bob&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Charlie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;David&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Eve&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Create table (initially without primary key)
&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CREATE OR REPLACE TABLE tbl AS SELECT * FROM data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;result_df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM tbl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result_df&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALTER TABLE tbl ADD PRIMARY KEY (id);&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT INTO tbl VALUES (5, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Frank&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;, 50)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After adding a primary key to the existing table, if you try to insert data with ID 5 which already exists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;con.sql("INSERT INTO tbl VALUES (5, 'Frank', 50)")
duckdb.duckdb.ConstraintException: Constraint Error: Duplicate key "id: 5" violates primary key constraint.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's rejected due to the primary key constraint that prevents duplicate values.&lt;/p&gt;

&lt;p&gt;Also, previously you couldn't insert data with the same ID as a record you had deleted, but that has been improved and is now possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
DELETE FROM tbl WHERE id = 1;
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
INSERT INTO tbl VALUES (1, &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Dareka&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;,100);
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM tbl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The insertion succeeds as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────┬─────────┬───────┐
│  id   │  name   │  age  │
│ int64 │ varchar │ int64 │
├───────┼─────────┼───────┤
│     2 │ Bob     │    30 │
│     3 │ Charlie │    35 │
│     4 │ David   │    40 │
│     5 │ Eve     │    45 │
│     1 │ Dareka  │   100 │
└───────┴─────────┴───────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ④ 🦆🦆🦆
&lt;/h3&gt;

&lt;p&gt;Surprisingly, you can now use 🦆 as a separator when reading CSV files!&lt;br&gt;&lt;br&gt;
This means you can use 4-byte characters (the duck emoji is apparently 4 bytes) as separators.&lt;/p&gt;

&lt;p&gt;So if you have a CSV file with this data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a🦆b
hello🦆world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM read_csv(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;csv_file1.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;,sep = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;🦆&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get this result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────┬─────────┐
│    a    │    b    │
│ varchar │ varchar │
├─────────┼─────────┤
│ hello   │ world   │
└─────────┴─────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It splits nicely.&lt;/p&gt;

&lt;p&gt;However, if you create a CSV like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a🇯🇵b
hello🇯🇵world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM read_csv(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;csv_file1.csv&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;,sep = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;🇯🇵&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get this error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;duckdb.duckdb.InvalidInputException: Invalid Input Error: The delimiter option cannot exceed a size of 4 bytes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because 🇯🇵 exceeds 4 bytes (apparently it's 6 bytes) and can't be used as a separator. I found it interesting to think about emoji byte sizes, which I'd never considered before.&lt;/p&gt;

&lt;p&gt;I also thought it was quite remarkable that the original text used the English word "emoji." Looking it up, I found that emoji were first used in 1999 in NTT DoCoMo's i-mode service for mobile phones. I've been using emoji since the feature phone era but didn't know this history. They were standardized globally and spread as "emoji" in 2011.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑤ strict_mode to only read CSVs that follow RFC 4180
&lt;/h3&gt;

&lt;p&gt;There are many types of CSV files, including haphazard ones like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1,2,3
a,b,c,d,e,f,g
h
i,j,k,l
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the update, you can now enforce reading only CSVs that follow the strict CSV standard (RFC 4180).&lt;br&gt;&lt;br&gt;
If you want to read non-compliant CSVs, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'rfc_4180-defiant.csv'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strict_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could be useful for filtering out messy CSVs when you want to use reliable data sources.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⑥ SQL column and table name aliases can now be set at the beginning without using AS
&lt;/h3&gt;

&lt;p&gt;Normally in SQL, you use AS for aliases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;some_long_and_winding_expression&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_column_name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;e2&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;
    &lt;span class="n"&gt;long_schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;some_long_table_name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;short_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tbl&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this update, you can now set column names like this (which is indeed more readable):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;e1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;some_long_and_winding_expression&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a_column_name&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt;
    &lt;span class="n"&gt;t1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;long_schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;some_long_table_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;t2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;short_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tbl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are many other updates, and more details will apparently be written in a blog post in the near future, which I'm looking forward to. 🙌&lt;/p&gt;

</description>
      <category>duckdb</category>
      <category>sql</category>
      <category>csv</category>
    </item>
    <item>
      <title>A story about prototyping a 'Desktop Directory Structure Visualization Tool' with Tauri</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Wed, 25 Sep 2024 22:00:20 +0000</pubDate>
      <link>https://dev.to/nk_maker/a-story-about-prototyping-a-desktop-directory-structure-visualization-tool-with-tauri-16oc</link>
      <guid>https://dev.to/nk_maker/a-story-about-prototyping-a-desktop-directory-structure-visualization-tool-with-tauri-16oc</guid>
      <description>&lt;p&gt;[Overview]&lt;br&gt;
You might feel strange hearing about desktop visualization (since the desktop is already visible).&lt;br&gt;
However, after recently trying out BI tools, I felt that the necessary information isn't visualized by default.&lt;br&gt;
So I thought I'd create an app for myself that could visualize the information that comes out of the tree command.&lt;/p&gt;

&lt;p&gt;[URL]&lt;br&gt;
&lt;a href="https://github.com/nkwork9999/tree_viz/tree/vizonly" rel="noopener noreferrer"&gt;https://github.com/nkwork9999/tree_viz/tree/vizonly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[Purpose]&lt;br&gt;
Create and publish a personal application.&lt;br&gt;
Visualize folder structure in a tree format.&lt;br&gt;
Open folders when clicked.&lt;/p&gt;

&lt;p&gt;[Frameworks Used]&lt;br&gt;
Tauri (Rust × TypeScript): Allows writing desktop application GUI with React.&lt;br&gt;
ReactFlow: Create flowchart diagrams with React.&lt;br&gt;
MUI: Used for screen creation.&lt;/p&gt;

&lt;p&gt;[What I'm Happy About]&lt;br&gt;
Although it was my first time properly creating a desktop application as a hobby, Tauri is so excellent that the app launches at lightning speed with a double-click.&lt;br&gt;
Backend processing is also fast. 🙌&lt;/p&gt;

&lt;p&gt;[Learnings]&lt;br&gt;
I was able to work with Rust, which increased the number of things I want to learn and frameworks I want to try next (creating my own OS, WASM, data analysis with Rust, etc.)&lt;br&gt;
Learned how to output data from the backend using the ReactFlow library. (Can it be used for ER diagrams too?)&lt;br&gt;
Being able to write desktop application GUIs in React means not having to learn specific syntax for GUI libraries for each language. (If Tauri can establish itself...)&lt;/p&gt;

&lt;p&gt;[Unclear Points]&lt;br&gt;
Implementation of the tree command in the backend... How to handle security and application publishing (publishing to App Store, how to write terms of service, etc.)&lt;br&gt;
Apparently, a dialog asking for permission appears by default when launching the tool.&lt;br&gt;
Also, logic (DTM application files) seems to be recognized as directories, and the cause of this is unclear.&lt;br&gt;
There are many other unclear points remaining.&lt;br&gt;
In conclusion, for the time being, I won't publish it on the App Store, but will make it public on GitHub.&lt;br&gt;
I would appreciate any comments or feedback. 🙏&lt;/p&gt;

</description>
      <category>tauri</category>
      <category>devops</category>
      <category>rust</category>
      <category>react</category>
    </item>
    <item>
      <title>Tauri dialog instead of window.confirm</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Mon, 19 Aug 2024 15:04:28 +0000</pubDate>
      <link>https://dev.to/nk_maker/tauri-dialog-instead-of-windowconfirm-32dn</link>
      <guid>https://dev.to/nk_maker/tauri-dialog-instead-of-windowconfirm-32dn</guid>
      <description>&lt;p&gt;&lt;strong&gt;[Background]&lt;/strong&gt;&lt;br&gt;
I used window.confirm to confirm actions before calling backend processes. But, Tauri’s dialog are also available,so I tried to use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Conclusion]&lt;/strong&gt;&lt;br&gt;
window.confirm has minimal customization.&lt;br&gt;
But Tauri’s dialog has various customizations.&lt;br&gt;
This could be useful when you don't need many customization just like MUI.&lt;/p&gt;

&lt;p&gt;Before&lt;/p&gt;

&lt;p&gt;typescript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { invoke } from "@tauri-apps/api/tauri";

const executeCommands = () =&amp;gt; {
    invoke&amp;lt;string&amp;gt;("command");
};

...

const handleCommand = async () =&amp;gt; {
    const Confirm = await window.confirm("Do you want to execute the hello command?");
    if (Confirm) {
        executeCommands();
    }
};

...

return (
  &amp;lt;div&amp;gt;
      &amp;lt;button onClick={handleCommand}&amp;gt;Execute&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After&lt;/p&gt;

&lt;p&gt;typescript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { invoke } from "@tauri-apps/api/tauri";
import { dialog } from "@tauri-apps/api";

const executeCommands = () =&amp;gt; {
    invoke&amp;lt;string&amp;gt;("command");
};

...

const handleCommand = async () =&amp;gt; {
    const Confirm = await dialog.ask("Do you want to execute the hello command?", "Ask Dialog");
    if (Confirm) {
        // yes
        executeCommands();
    }
};

...

return (
  &amp;lt;div&amp;gt;
      &amp;lt;button onClick={handleCommand}&amp;gt;Execute&amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In tauri.conf.json&lt;/p&gt;

&lt;p&gt;json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "tauri": {
    "allowlist": {
      "all": false,
      "dialog": {
        "confirm": true,
        "open": true,
        "ask": true
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>tauri</category>
      <category>rust</category>
    </item>
    <item>
      <title>[Rust]How to make string handing to frontend on tauri app</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Thu, 25 Jul 2024 21:58:04 +0000</pubDate>
      <link>https://dev.to/nk_maker/rusthow-to-make-string-handing-to-frontend-on-tauri-app-4h2c</link>
      <guid>https://dev.to/nk_maker/rusthow-to-make-string-handing-to-frontend-on-tauri-app-4h2c</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[tauri::command]
pub fn simple_command()-&amp;gt;String{
    "String".to_string()
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to return a string in a Tauri command,add to_string() to the end of the string just like this.&lt;br&gt;
This allows you to pass any string to the frontend like React.&lt;/p&gt;

</description>
      <category>tauri</category>
      <category>rust</category>
      <category>devops</category>
      <category>developer</category>
    </item>
    <item>
      <title>[Rust]get file name</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Mon, 22 Jul 2024 22:09:25 +0000</pubDate>
      <link>https://dev.to/nk_maker/rustget-file-name-3pka</link>
      <guid>https://dev.to/nk_maker/rustget-file-name-3pka</guid>
      <description>&lt;p&gt;Mypath.file_name().unwrap().to_string_lossy().into_owned();&lt;/p&gt;

&lt;p&gt;Mypath:type of object &lt;br&gt;
file_name():method of retreaving tail of path and return Option&amp;lt;&amp;amp;OsStr&amp;gt;&lt;br&gt;
unwrap(): method of retreaving Option type&lt;br&gt;
to_string_lossy():method of changing to string(lossy is just like forced)&lt;br&gt;
.into_owned():method of changing to string have Cow&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>[Rust]Making struct for getting directory path</title>
      <dc:creator>nk_Enuke</dc:creator>
      <pubDate>Sun, 21 Jul 2024 22:10:17 +0000</pubDate>
      <link>https://dev.to/nk_maker/rustmaking-struct-for-getting-directory-path-2322</link>
      <guid>https://dev.to/nk_maker/rustmaking-struct-for-getting-directory-path-2322</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Serialize, Deserialize)]
struct DirNode{
    name:String,
    children:Vec&amp;lt;DirNode&amp;gt;,
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1:#[derive(Serialize, Deserialize)]&lt;br&gt;
Making serialize and deserialize for struct to json&lt;br&gt;
2:struct DirNode{}&lt;br&gt;
Making struct named DirNode&lt;br&gt;
3:children:Vec&lt;br&gt;
'children' retain subdirectory's list.It means to make recursively storing a list of DirNode.&lt;br&gt;
DirNode can contain multiple DirNode.&lt;br&gt;
So 'children' can have subdirectories.&lt;br&gt;
4:Vec&lt;br&gt;
Making array can have multiple values by using heap allocation.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>tauri</category>
    </item>
  </channel>
</rss>
