<?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: Tensor Labs</title>
    <description>The latest articles on DEV Community by Tensor Labs (@tensorlabs).</description>
    <link>https://dev.to/tensorlabs</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%2F738517%2Ff5825f30-281d-4419-aa44-c1185defad0c.jpg</url>
      <title>DEV Community: Tensor Labs</title>
      <link>https://dev.to/tensorlabs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tensorlabs"/>
    <language>en</language>
    <item>
      <title>Observation State Made Simple</title>
      <dc:creator>Tensor Labs</dc:creator>
      <pubDate>Tue, 13 Jan 2026 07:42:43 +0000</pubDate>
      <link>https://dev.to/tensorlabs/observation-state-made-simple-2n0h</link>
      <guid>https://dev.to/tensorlabs/observation-state-made-simple-2n0h</guid>
      <description>&lt;p&gt;If you ever made any research or play around the source code for Uniswap v3 or Raydium CLMM, you most likely would stumble upon the observation array. To the uninitiated, it looks like a series of random, massive integers.&lt;/p&gt;

&lt;p&gt;But in an amazing way these numbers are the feats of financial engineering. they allow a liquidity pool to act as it's very own On-Chain Oracle without requiring an external price such as Chainlink or Pyth Network.&lt;/p&gt;

&lt;p&gt;In this article, we would skim through the math that makes Concentrated Liquidity Market Maker (CLMM) observation states work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Problem: Liquidity Manipulation
&lt;/h2&gt;

&lt;p&gt;In V2 AMMs, the current price is very dangerous,  flash loan attack can be used to buy massive amount of Token A, driving price up using that inflated price as collateral to borrow against a lending protocol, and then dumping the token—all in one block.&lt;br&gt;
To fix this, CLMMs make use of Time-Weighted Average Price &lt;strong&gt;TWAP&lt;/strong&gt; to efficiently calculate TWAP on-chain by using the Observation State.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transforming Price into Ticks
&lt;/h2&gt;

&lt;p&gt;In a CLMM, we don't track the price directly, We track the &lt;strong&gt;Ticks&lt;/strong&gt;. The price(P) and tick (i) are related by: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjze369ahlppm6ujbsvxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjze369ahlppm6ujbsvxp.png" alt=" " width="242" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By taking the logarithm, we get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1a8s6sa0exdsn5jpa81r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1a8s6sa0exdsn5jpa81r.png" alt=" " width="242" height="52"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why do we do this? Because math with exponents is hard for computers to average, but math with integers (ticks) is easy. When we move into "Tick Space," we are essentially working in a logarithmic scale where multiplication turns into addition.&lt;/p&gt;

&lt;p&gt;The Accumulator Pattern&lt;br&gt;
The Observation State uses an Accumulator. Instead of storing every price change, the contract stores a "running total" of the price-time product.&lt;/p&gt;

&lt;p&gt;Whenever a swap happens, the contract updates the tickCumulative:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8s4k64p25urc969tlin.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8s4k64p25urc969tlin.png" alt=" " width="267" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a (subset of t): The new cumulative value.&lt;/li&gt;
&lt;li&gt;i (subset of current): The current active tick.&lt;/li&gt;
&lt;li&gt;Delta t: The number of seconds since the last update&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At 12:00:00, the tick is 10 and the cumulative total is 1,000,000.&lt;/li&gt;
&lt;li&gt;At 12:00:10, a swap happens. 10 seconds have passed.&lt;/li&gt;
&lt;li&gt;New Cumulative: $1,000,000 + (10 \times 10) = 1,000,100$.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reconstructing the Average
&lt;/h2&gt;

&lt;p&gt;To find the average price between two timestamps t(subset 1) and t(subset 2), a developer just needs to fetch two observations from the state array.The math for the Average Tick ($\bar{i}$) is:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yb863w95qgz4q5c9gg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5yb863w95qgz4q5c9gg6.png" alt=" " width="176" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have the average tick, you convert it back to the human-readable &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uaw897v7kkh00tbhggh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7uaw897v7kkh00tbhggh.png" alt=" " width="176" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This result is a Geometric Mean. It is mathematically superior for finance because it represents the "true" center of a percentage-based move, making it much harder for a single whale to skew the average with a brief spike.&lt;/p&gt;

&lt;h2&gt;
  
  
  Liquidity Tracking
&lt;/h2&gt;

&lt;p&gt;The Observation State also tracks secondsPerLiquidityCumulative. This allows protocols to see how much liquidity was active at specific price ranges.&lt;/p&gt;

&lt;p&gt;The formula follows the same accumulator logic:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fch85a421uch6u528vrnf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fch85a421uch6u528vrnf.png" alt=" " width="312" height="74"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This allows external contracts to verify not just the price, but the depth of the market during a specific window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Tip: Cardinality
&lt;/h2&gt;

&lt;p&gt;By default, most CLMM pools only store one observation (the most recent one). If you are building a lending protocol or a dApp that needs 30-minute price history, you must call the increaseObservationCardinalityNext function.&lt;/p&gt;

&lt;p&gt;This "slots" more space in the array, allowing the pool to store more history (e.g., 100 observations instead of 1).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Summary&lt;/strong&gt;&lt;br&gt;
The Observation State is a "compressed" history of the pool. By storing the integral of the tick over time, CLMMs provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Gas Efficiency: Only one update per block.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security: High resistance to Flash Loan attacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Independence: No need for off-chain oracles.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>algorithms</category>
      <category>architecture</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Building a Simple Email Spam Classifier in Rust with SmartCore</title>
      <dc:creator>Tensor Labs</dc:creator>
      <pubDate>Wed, 25 Jun 2025 10:49:25 +0000</pubDate>
      <link>https://dev.to/tensorlabs/building-a-simple-email-spam-classifier-in-rust-with-smartcore-4k3n</link>
      <guid>https://dev.to/tensorlabs/building-a-simple-email-spam-classifier-in-rust-with-smartcore-4k3n</guid>
      <description>&lt;p&gt;Machine learning is often associated with Python, but the Rust ecosystem is quickly catching up! In this article, I’ll walk you through building a simple email spam classifier in Rust using the &lt;a href="https://github.com/smartcorelib/smartcore" rel="noopener noreferrer"&gt;SmartCore&lt;/a&gt; machine learning library. This project is perfect for Rustaceans curious about ML, or anyone looking for a practical, hackable example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Rust for Machine Learning?
&lt;/h2&gt;

&lt;p&gt;Rust is known for its safety, speed, and growing ecosystem. While Python dominates the ML world, Rust offers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory safety&lt;/strong&gt; without garbage collection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blazing fast&lt;/strong&gt; execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong type system&lt;/strong&gt; for fewer runtime errors&lt;/li&gt;
&lt;li&gt;A rapidly expanding set of data and ML libraries&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We’ll build a K-Nearest Neighbors (KNN) classifier that predicts whether an email address is spam or real, based on simple features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The length of the email address&lt;/li&gt;
&lt;li&gt;The number of special (non-alphanumeric) characters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our dataset is a CSV file with two columns: &lt;code&gt;spam&lt;/code&gt; and &lt;code&gt;real&lt;/code&gt;, each containing example email addresses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Dataset
&lt;/h2&gt;

&lt;p&gt;Here’s a sample of our &lt;code&gt;public/spam.csv&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spam,real
winner@spammy.com,john.doe@example.com
cheapmeds@pharmacy.com,info@company.com
bankalert@fraud.com,support@service.com
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;Below is the full Rust code for the classifier. It reads the CSV, extracts features, trains a KNN model, evaluates accuracy, and lets you check if any email is spam.&lt;/p&gt;

&lt;p&gt;Repo -&amp;gt; &lt;a href="https://github.com/DevWonder01/rust-ml" rel="noopener noreferrer"&gt;https://github.com/DevWonder01/rust-ml&lt;/a&gt;&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;smartcore&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;linalg&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;basic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DenseMatrix&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;smartcore&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;neighbors&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;knn_classifier&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;KNNClassifier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;smartcore&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;accuracy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Deserialize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&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;error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&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;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[derive(Deserialize,&lt;/span&gt; &lt;span class="nd"&gt;Serialize,&lt;/span&gt; &lt;span class="nd"&gt;Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;spam&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;real&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&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;count_special_chars&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;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&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;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.chars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.filter&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="nf"&gt;.is_alphanumeric&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.count&lt;/span&gt;&lt;span class="p"&gt;()&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;process_data&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;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DenseMatrix&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&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="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;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;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"public/spam.csv"&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&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;rdr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&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;data&lt;/span&gt;&lt;span class="p"&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="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="p"&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="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;rows&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rdr&lt;/span&gt;&lt;span class="nf"&gt;.records&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;record&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&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;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="nf"&gt;.deserialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&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;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Features for spam email&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="py"&gt;.spam&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;count_special_chars&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;email&lt;/span&gt;&lt;span class="py"&gt;.spam&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="nf"&gt;.push&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="c1"&gt;// Features for real email&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="py"&gt;.real&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;count_special_chars&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;email&lt;/span&gt;&lt;span class="py"&gt;.real&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;labels&lt;/span&gt;&lt;span class="nf"&gt;.push&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="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&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;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;DenseMatrix&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;rows&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="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&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;matrix&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&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;labels&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;matrix&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;predict_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;knn&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;KNNClassifier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DenseMatrix&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&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;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;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;features&lt;/span&gt; &lt;span class="o"&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;email&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;count_special_chars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;f64&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;feature_slice&lt;/span&gt; &lt;span class="o"&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="n"&gt;features&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&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;prediction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;knn&lt;/span&gt;&lt;span class="nf"&gt;.predict&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;DenseMatrix&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_2d_array&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;feature_slice&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;prediction&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} is predicted as SPAM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} is predicted as REAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&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;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;dyn&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;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="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&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="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Train KNN classifier&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;knn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KNNClassifier&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;matrix&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;labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Predict on the training data&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;predictions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;knn&lt;/span&gt;&lt;span class="nf"&gt;.predict&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;matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Calculate accuracy&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;accuracy&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;labels&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;predictions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Accuracy: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Example: check if a single email is spam&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;test_email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"winner@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;predict_email&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;knn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Feature Engineering:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
For each email, we extract two features: the length and the number of special characters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model Training:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We use SmartCore’s KNN classifier, training it on all the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prediction:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The model predicts whether a new email address is spam or real based on its features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Evaluation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The code prints the model’s accuracy on the training data.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Running the Project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add dependencies&lt;/strong&gt; to your &lt;code&gt;Cargo.toml&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;   &lt;span class="py"&gt;smartcore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.3"&lt;/span&gt;
   &lt;span class="py"&gt;serde&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"derive"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="py"&gt;csv&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Place your dataset&lt;/strong&gt; at &lt;code&gt;public/spam.csv&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run the project:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   cargo run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Try more advanced features (e.g., domain analysis, word counts)&lt;/li&gt;
&lt;li&gt;Split your data into training and test sets for a more realistic evaluation&lt;/li&gt;
&lt;li&gt;Experiment with other algorithms in SmartCore&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Rust is ready for machine learning experimentation! With libraries like SmartCore, you can build, train, and deploy ML models with the safety and speed Rust is famous for.&lt;br&gt;&lt;br&gt;
Give it a try and let’s grow the Rust ML community together!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Questions or suggestions? Drop a comment below or connect with me!&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  rustlang #machinelearning #rustml #emailsecurity #opensource
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Setting Up Your Ultimate Linux Dev Environment: Rust, Docker &amp; More!</title>
      <dc:creator>Tensor Labs</dc:creator>
      <pubDate>Wed, 04 Jun 2025 15:18:31 +0000</pubDate>
      <link>https://dev.to/tensorlabs/setting-up-your-ultimate-linux-dev-environment-rust-docker-more-nhi</link>
      <guid>https://dev.to/tensorlabs/setting-up-your-ultimate-linux-dev-environment-rust-docker-more-nhi</guid>
      <description>&lt;p&gt;Are you a developer working on a Debian-based Linux system (like Ubuntu or Kali Linux) and looking for a streamlined way to set up your development environment with Rust, essential build tools, and Docker? Look no further!&lt;br&gt;
This article walks you through a powerful Bash script that automates the installation of these crucial tools, getting you up and running quickly.&lt;br&gt;
Why Automate Your Dev Environment Setup?&lt;br&gt;
Setting up a new machine or ensuring consistency across multiple development environments can be tedious and error-prone. Automation with a script like this ensures:&lt;br&gt;
Consistency: Every setup is identical, reducing "it works on my machine" issues.&lt;br&gt;
Speed: Install everything in minutes, not hours.&lt;br&gt;
Reliability: Reduces human error during complex installations.&lt;br&gt;
Reproducibility: Easily recreate your environment whenever needed.&lt;br&gt;
The Automation Script Explained&lt;br&gt;
Let's dive into the script and understand what each section does.&lt;/p&gt;
&lt;h1&gt;
  
  
  !/bin/bash
&lt;/h1&gt;
&lt;h1&gt;
  
  
  This script automates the setup of a comprehensive development environment
&lt;/h1&gt;
&lt;h1&gt;
  
  
  on Debian-based Linux systems (like Ubuntu or Kali Linux).
&lt;/h1&gt;
&lt;h1&gt;
  
  
  It includes Rust, essential build tools, and Docker with Docker Compose.
&lt;/h1&gt;
&lt;h1&gt;
  
  
  Exit immediately if a command exits with a non-zero status.
&lt;/h1&gt;

&lt;p&gt;set -e&lt;/p&gt;

&lt;p&gt;echo "Starting development environment setup..."&lt;/p&gt;
&lt;h1&gt;
  
  
  !/bin/bash: The shebang line, indicating that the script should be executed with Bash.
&lt;/h1&gt;

&lt;p&gt;set -e: A critical command that ensures the script will exit immediately if any command fails. This prevents partial or broken installations.&lt;br&gt;
echo: Used throughout the script to provide clear feedback on the installation progress.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Rust Programming Language
Rust is a modern systems programming language known for its performance, memory safety, and concurrency. rustup is its official installer and toolchain manager.
# --- 1. Install Rust Programming Language ---
echo "--- Installing Rust Programming Language ---"
# Install rustup and the Rust toolchain
curl --proto '=https' --tlsv1.2 -sSf &lt;a href="https://sh.rustup.rs" rel="noopener noreferrer"&gt;https://sh.rustup.rs&lt;/a&gt; | sh&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;
  
  
  Update your shell environment for the current session
&lt;/h1&gt;
&lt;h1&gt;
  
  
  This ensures cargo and rustc commands are immediately available
&lt;/h1&gt;

&lt;p&gt;source "$HOME/.cargo/env"&lt;br&gt;
echo "Rust installation complete. PATH updated for current session."&lt;/p&gt;

&lt;p&gt;This section downloads and runs the rustup script, which installs the Rust compiler (rustc) and its package manager (cargo). The source "$HOME/.cargo/env" command updates your shell's PATH for the current session, making Rust commands immediately available.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Essential Build Tools
Many software projects, including some Rust crates, rely on underlying C/C++ libraries. build-essential provides the core compilers and utilities needed for this.
# --- 2. Install Essential Build Tools ---
echo "--- Installing Essential Build Tools ---"
# Update package lists
sudo apt update&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;
  
  
  Install build-essential (includes gcc, g++, make)
&lt;/h1&gt;

&lt;p&gt;sudo apt install -y build-essential&lt;br&gt;
echo "Build essential tools installed."&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;``&lt;code&gt;sudo apt update&lt;/code&gt; refreshes your package lists, and &lt;code&gt;sudo apt install -y build-essential&lt;/code&gt; installs &lt;code&gt;gcc&lt;/code&gt;, &lt;code&gt;g++&lt;/code&gt;, &lt;code&gt;make&lt;/code&gt;, and other crucial tools required for compiling C/C++ code. The &lt;code&gt;-y&lt;/code&gt; flag automatically confirms prompts.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Install Additional Development Dependencies
&lt;/h3&gt;

&lt;p&gt;This section includes specific libraries and tools that are often required for various development tasks, especially those involving Perl or secure communication.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
# --- 3. Install Additional Development Dependencies (Perl, OpenSSL dev, pkg-config) ---
sudo apt-get install -y \
    perl \
    perl-base \
    perl-modules \
    libssl-dev \
    pkg-config
echo "Additional development dependencies installed."


Here, perl and its base modules are installed. libssl-dev provides development headers for OpenSSL, essential for projects dealing with SSL/TLS encryption. pkg-config helps manage compilation flags for libraries.
4. Install libudev-dev
libudev-dev is a development library for udev, which handles device events in Linux. It's often a dependency for Rust crates that need to interact with hardware, such as USB devices.
# --- 4. Install libudev-dev ---
echo "--- Installing libudev-dev ---"
sudo apt-get install -y libudev-dev
echo "libudev-dev installed."


5. Install Docker
Docker is a game-changer for containerizing applications, ensuring consistent environments from development to production.
# --- 5. Install Docker ---
echo "--- Installing Docker ---"
# Install necessary packages for Docker's repository
sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "Docker GPG key added."

# Set up the stable Docker repository
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
echo "Docker repository added."

# Update apt package index again after adding the new repository
sudo apt-get update

# Install Docker Engine
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
echo "Docker Engine installed."

# Add user to docker group
sudo usermod -aG docker "$USER"
echo "User '$USER' added to the 'docker' group. IMPORTANT: You must log out and log back in (or reboot) for this change to take effect."


This section adds Docker's official repository and GPG key, then installs the Docker Engine, CLI, and containerd.io. Crucially, it adds your current user to the docker group, allowing you to run Docker commands without sudo (after a re-login).
6. Install Docker Compose
Docker Compose simplifies the management of multi-container Docker applications, allowing you to define your services in a single docker-compose.yml file.
# --- 6. Install Docker Compose ---
echo "--- Installing Docker Compose ---"
# Download Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Apply executable permissions
sudo chmod +x /usr/local/bin/docker-compose

# Change ownership (optional but good practice)
sudo chown "$USER" /usr/local/bin/docker-compose
echo "Docker Compose downloaded and permissions set."

# Verify Docker Compose installation
echo "Verifying Docker Compose installation:"
docker-compose --version

echo "Development environment setup complete!"
echo "Remember to log out and log back in (or reboot) to apply Docker group changes."


This final section downloads the Docker Compose binary, makes it executable, and sets its ownership. A verification step confirms the installation.
How to Run the Script
Save the script: Copy the entire script content into a file (e.g., setup_dev_env.sh).
Make it executable: Open your terminal and run:
chmod +x setup_dev_env.sh


Execute the script:
./setup_dev_env.sh

You will be prompted for your sudo password as needed.
Important: After the script finishes, remember to log out and log back in (or reboot your system) to ensure that your user's membership in the docker group takes effect.
Conclusion
With this script, you can quickly set up a powerful and consistent development environment on your Debian-based Linux machine, equipped with Rust, essential build tools, Docker, and Docker Compose. This automation saves time and reduces friction, letting you focus on what matters most: building amazing software!
Happy coding!
#Linux #Ubuntu #KaliLinux #Rust #Docker #DockerCompose #DevSetup #Automation #BashScripting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
    </item>
    <item>
      <title>rust</title>
      <dc:creator>Tensor Labs</dc:creator>
      <pubDate>Tue, 26 Nov 2024 09:50:33 +0000</pubDate>
      <link>https://dev.to/tensorlabs/rust-2mij</link>
      <guid>https://dev.to/tensorlabs/rust-2mij</guid>
      <description></description>
      <category>rust</category>
    </item>
    <item>
      <title>Switching from Chainlink VRF to Pyth Entropy</title>
      <dc:creator>Tensor Labs</dc:creator>
      <pubDate>Mon, 25 Nov 2024 18:02:50 +0000</pubDate>
      <link>https://dev.to/tensorlabs/switching-from-chainlink-vrf-to-pyth-entropy-2h5b</link>
      <guid>https://dev.to/tensorlabs/switching-from-chainlink-vrf-to-pyth-entropy-2h5b</guid>
      <description>&lt;p&gt;As decentralized applications (dApps) continue to evolve, the demand for robust, transparent, and cost-effective solutions is ever-growing. In the world of prediction markets, derivative sand blockchain gaming, randomness plays a crucial role in determining outcomes that users can trust. Historically, Chainlink’s VRF (Verifiable Random Function) has been the go-to solution for generating secure random numbers on-chain. However, with the rise of innovative alternatives like Pyth Entropy, the landscape is shifting.&lt;/p&gt;

&lt;p&gt;We’ll walk through the key differences between both services, discuss the benefits of Pyth Entropy, and provide a detailed look at the Solidity code behind the transition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Randomness Matters in Blockchain Applications
&lt;/h2&gt;

&lt;p&gt;Randomness ensures fairness and unpredictability in dApps, especially in use cases like gaming, lotteries, and prediction markets. Without a trusted source of randomness, dApps risk exposing themselves to manipulation or biases that could undermine user trust.&lt;/p&gt;

&lt;p&gt;In a simple Coin Flip Game, randomness determines whether the outcome is heads or tails. Thus, ensuring the randomness source is reliable is critical to maintaining fairness&lt;/p&gt;

&lt;h2&gt;
  
  
  Chainlink’s VRF
&lt;/h2&gt;

&lt;p&gt;The Chainlink VRF has been the industry standard for generating verifiable random numbers on-chain, it ensures that random numbers used in a smart contract are unpredictable. The randomness is generated off-chain and then verified on-chain, providing both security and transparency.&lt;br&gt;
Key Features of Chainlink VRF Integration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Subscription Model: Users need to set up and fund a Chainlink subscription.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verifiable Randomness: Random numbers are generated and verified by the Chainlink network.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gas Costs: Chainlink VRF involves higher gas fees due to off-chain processing and interaction with the Chainlink oracle network.&lt;br&gt;
Sample Chainlink VRF Solidity Code for Coin Flip.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function playWithVRF(bool face) external payable {
        Bet memory bet = _playWithVRF();
        coinTossBets[bet.id].face = face;

        emit PlaceBet(bet.id, bet.user, face);
    }

    function _playWithVRF() internal returns (Bet memory) {
        uint256 requestId = s_vrfCoordinator.requestRandomWords(
            VRFV2PlusClient.RandomWordsRequest({
                keyHash: keyHash,
                subId: s_subscriptionId,
                requestConfirmations: requestConfirmations,
                callbackGasLimit: callbackGasLimit,
                numWords: numWords,
                // native payment = false, means chainlink will charge user $LINK tokens (cheaper method)
                // native payment = true, means chainlink will charge ETH 
                extraArgs: VRFV2PlusClient._argsToBytes(
                    VRFV2PlusClient.ExtraArgsV1({nativePayment: false})
                )
            })
        );

        Bet memory newBet = Bet(
            false,
            msg.sender,
            requestId,
            block.timestamp,
            false
        );
        _userBets[msg.sender].push(requestId);
        bets[requestId] = newBet;
        return newBet;
    }

    function fulfillRandomWords(
        uint256 _requestId /* requestId */,
        uint256[] calldata randomWords
    ) internal override {
        CoinTossBet storage coinTossBet = coinTossBets[_requestId];
        Bet storage bet = bets[_requestId];
        uint256 roller = randomWords[0] % 2;

        bool[2] memory coinSides = [false, true];
        bool rolledCoinSide = coinSides[roller];
        coinTossBet.rolled = rolledCoinSide;

        if (rolledCoinSide == coinTossBet.face) {
            bet.resolved = true;
            bet.betStatus = true;
            emit Roll(bet.id, bet.user, coinTossBet.face, rolledCoinSide);
        } else {
            bet.resolved = true;
            bet.betStatus = false;
            emit Roll(bet.id, bet.user, coinTossBet.face, rolledCoinSide);
        }

        emit Roll(bet.id, bet.user, coinTossBet.face, rolledCoinSide);
    }

    function getBetData(uint256 id) public view returns (Bet memory betData) {
        Bet storage data = bets[id];
        return data;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Enter Pyth Entropy: A New Standard for On-Chain Randomness
&lt;/h2&gt;

&lt;p&gt;While Chainlink VRF provides an excellent solution, Pyth Entropy presents several advantages for dApps , particularly in terms of gas efficiency, flexibility, and integration with the existing Pyth Network ecosystem. Pyth Entropy is a randomness generator that ensures decentralized and verifiable randomness on-chain, just like VRF, but offers a more streamlined and cost-efficient model.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Why Switch to Pyth Entropy?&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower Fees: Pyth Entropy requires fewer resources than Chainlink VRF, leading to lower transaction costs for users.&lt;/li&gt;
&lt;li&gt;Direct Integration with Pyth Network: dApps which already uses Pyth for its price feeds, making the integration of Entropy a natural fit.&lt;/li&gt;
&lt;li&gt;Scalability: As a dApp expands its product offerings, using a more scalable solution like Pyth Entropy ensures that future random-based features can be easily integrated.&lt;/li&gt;
&lt;li&gt;Faster Response Times: Since Pyth Entropy processes directly on-chain, the randomness is returned faster than with off-chain processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;*&lt;em&gt;Sample Pyth Entropy Solidity Code for Coin Flip:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function getProvider() external view returns (address) {
        address p = entropy.getDefaultProvider();
        return p;
    }

    function getFlipFee() public view returns (uint256 fee) {
        fee = entropy.getFee(entropyProvider);
    }

    function entropyCallback(
        uint64 sequenceNumber,
        address,
        bytes32 randomNumber
    ) internal override {
        uint256 _s = uint256(sequenceNumber);
        CoinTossBet storage coinTossBet = coinTossBets[_s];
        Bet storage bet = bets[_s];
        bool rolled = uint256(randomNumber) % 2 == 0;

        coinTossBet.rolled = rolled;

        if (rolled == coinTossBet.face) {
            bet.resolved = true;
            bet.betStatus = true;
            emit Roll(bet.id, bet.user, coinTossBet.face, rolled);
        } else {
            bet.resolved = true;
            bet.betStatus = false;

            emit Roll(bet.id, bet.user, coinTossBet.face, rolled);
        }

        emit Roll(bet.id, bet.user, coinTossBet.face, rolled);
        emit FlipResult(sequenceNumber, uint256(randomNumber) % 2 == 0);
    }

    function getEntropy() internal view override returns (address) {
        return address(entropy);
    }

    function flipWithPyth(
        bool face,
        bytes32 userRandomNumber
    ) external payable {
        address provider = entropy.getDefaultProvider();
        uint256 fee = entropy.getFee(provider);

        if (msg.value &amp;lt; fee) {
            revert CoinFlipErrors.InsufficientFee();
        }

        uint64 sequenceNumber = entropy.requestWithCallback{value: fee}(
            provider,
            userRandomNumber
        );

        uint256 _s = uint256(sequenceNumber);
        emit FlipRequest(sequenceNumber);
        Bet memory newBet = Bet(false, msg.sender, _s, block.timestamp, false);
        _userBets[msg.sender].push(_s);
        bets[_s] = newBet;

        coinTossBets[newBet.id].face = face;

        emit PlaceBet(newBet.id, newBet.user, face);
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;The decision to transition from Chainlink VRF to Pyth *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Entropy is more than just a technical upgrade for any dApp. It’s a step toward a more scalable, cost-effective future that aligns with the platform’s goals of transparency and user-centric design.&lt;br&gt;
As Pyth Entropy continues to grow in adoption, we expect to see more projects making the switch, particularly those already embedded in the Pyth ecosystem.&lt;br&gt;
The decision to transition from Chainlink VRF to Pyth Entropy is more than just a technical upgrade for any dApp. It’s a step toward a more scalable, cost-effective future that aligns with the platform’s goals of transparency and user-centric design.&lt;br&gt;
As Pyth Entropy continues to grow in adoption, we expect to see more projects making the switch, particularly those already embedded in the Pyth ecosystem.&lt;/p&gt;

&lt;p&gt;To get access to the full Solidity code and hardhat environment use 👇&lt;br&gt;
&lt;a href="https://github.com/DevWonder01/Onchain-Randomization" rel="noopener noreferrer"&gt;Repo Link&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;don’t forget to follow me on&lt;br&gt;
&lt;a href="https://x.com/devwonder01" rel="noopener noreferrer"&gt;https://x.com/devwonder01&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/DevWonder01" rel="noopener noreferrer"&gt;https://github.com/DevWonder01&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pyth&lt;br&gt;
&lt;a href="https://docs.pyth.network/entropy" rel="noopener noreferrer"&gt;https://docs.pyth.network/entropy&lt;/a&gt; — docs&lt;/p&gt;

&lt;p&gt;Chainlink&lt;br&gt;
&lt;a href="https://vrf.chain.link/" rel="noopener noreferrer"&gt;https://vrf.chain.link/&lt;/a&gt; — subscription manager&lt;br&gt;
&lt;a href="https://docs.chain.link/vrf" rel="noopener noreferrer"&gt;https://docs.chain.link/vrf&lt;/a&gt; — docs&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
