{ "cells": [ { "cell_type": "markdown", "id": "c1517920-b1f6-440c-b5c8-4df6bec2fbc1", "metadata": {}, "source": [ "# Google Colab Rust Setup\n", "\n", "The following cell is used to set up and spin up a Jupyter Notebook environment with a Rust kernel using Nix and IPC Proxy. " ] }, { "cell_type": "code", "execution_count": null, "id": "fbf50b02-3730-4aa0-af49-16c1546fd09e", "metadata": {}, "outputs": [], "source": [ "!wget -qO- https://gist.github.com/wiseaidev/2af6bef753d48565d11bcd478728c979/archive/3f6df40db09f3517ade41997b541b81f0976c12e.tar.gz | tar xvz --strip-components=1\n", "!bash setup_evcxr_kernel.sh" ] }, { "cell_type": "markdown", "id": "60c8d72c-b011-4360-b368-d540b8d7361a", "metadata": {}, "source": [ "## Iterators and Closures" ] }, { "cell_type": "markdown", "id": "38339871-7f3d-49d8-9b4f-e77f9e2a88da", "metadata": {}, "source": [ "### Anatomy of an Iterator" ] }, { "cell_type": "code", "execution_count": 3, "id": "a163999f-7353-4fb9-88cf-61ac934c34f0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The sum of the first 10 prime numbers is: 129\n" ] } ], "source": [ "fn is_prime(n: u32) -> bool {\n", " if n <= 1 {\n", " return false;\n", " }\n", " for i in 2..(n / 2 + 1) {\n", " if n % i == 0 {\n", " return false;\n", " }\n", " }\n", " true\n", "}\n", "\n", "fn sum_of_primes(n: u32) -> u32 {\n", " (2..).filter(|&x| is_prime(x)).take(n as usize).sum()\n", "}\n", "\n", "let n = 10;\n", "let result = sum_of_primes(n);\n", "println!(\"The sum of the first {} prime numbers is: {}\", n, result);" ] }, { "cell_type": "markdown", "id": "95f2fdfa-0f86-4959-9ab7-5aa92de36ea9", "metadata": {}, "source": [ "### Key Traits: Iterator and IntoIterator" ] }, { "cell_type": "code", "execution_count": 4, "id": "125e0cb0-88a3-49c3-bb79-c6b78171ec60", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Item: 42\n", "Item: 100\n", "Item: 7\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "struct MyCollection {\n", " data: Vec<i32>,\n", "}\n", "\n", "impl MyCollection {\n", " fn new() -> Self {\n", " MyCollection { data: Vec::new() }\n", " }\n", "\n", " fn add(&mut self, value: i32) {\n", " self.data.push(value);\n", " }\n", "}\n", "\n", "impl IntoIterator for MyCollection {\n", " type Item = i32;\n", " type IntoIter = std::vec::IntoIter<Self::Item>;\n", "\n", " fn into_iter(self) -> Self::IntoIter {\n", " self.data.into_iter()\n", " }\n", "}\n", "\n", "\n", "let mut collection = MyCollection::new();\n", "\n", "collection.add(42);\n", "collection.add(100);\n", "collection.add(7);\n", "\n", "for item in collection {\n", " println!(\"Item: {}\", item);\n", "}" ] }, { "cell_type": "markdown", "id": "2c4bb2d5-57a3-4075-b044-0898cb18a41e", "metadata": {}, "source": [ "### Creating Iterators with `from_fn` and `successors`" ] }, { "cell_type": "code", "execution_count": 7, "id": "a501d270-db4d-474b-a37c-1439aff79ad6", "metadata": {}, "outputs": [], "source": [ ":dep rand = {version=\"0.8.5\"}" ] }, { "cell_type": "code", "execution_count": 9, "id": "e43f6159-0e97-40f9-8fb1-702ac600f60c", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.026231996097305532, 0.3638420476998353, 0.529187247261019, 0.3697265864723026, 0.9199704902784379, 0.0578703524231724, 0.2434883502345343, 0.1948597360516151, 0.38109952692955174, 0.47026570340584917]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "use rand::random;\n", "\n", "use std::iter::from_fn;\n", "\n", "let lengths: Vec<f64> =\n", " from_fn(|| Some((random::<f64>() - random::<f64>()).abs()))\n", " .take(1000)\n", " .collect();\n", "lengths[..10]" ] }, { "cell_type": "code", "execution_count": 11, "id": "a27b5c86-6134-4823-8484-019668dd97ad", "metadata": {}, "outputs": [], "source": [ ":dep num = {version=\"0.4.1\"}" ] }, { "cell_type": "code", "execution_count": 13, "id": "743e0887-3158-4a61-b6c5-152579c472e1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Escaped after 96 steps.\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "use num::Complex;\n", "use std::iter::successors;\n", "\n", "fn escape_time(c: Complex<f64>, limit: usize) -> Option<usize> {\n", " let zero = Complex { re: 0.0, im: 0.0 };\n", "\n", " let result = successors(Some(zero), |&z| Some(z * z + c))\n", " .take(limit)\n", " .enumerate()\n", " .find(|(_i, z)| z.norm_sqr() > 4.0);\n", "\n", " match result {\n", " Some((i, _z)) => Some(i),\n", " None => None,\n", " }\n", "}\n", "\n", "let c = Complex { re: -0.7, im: 0.27015 };\n", "let limit = 1000;\n", "\n", "match escape_time(c, limit) {\n", " Some(steps) => println!(\"Escaped after {} steps.\", steps),\n", " None => println!(\"Did not escape within {} steps.\", limit),\n", "}" ] }, { "cell_type": "code", "execution_count": 14, "id": "95d8e464-7461-4da3-9378-bfb599a8a864", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fibonacci sequence (first 8 numbers): [1, 1, 2, 3, 5, 8, 13, 21]\n" ] } ], "source": [ "fn fibonacci() -> impl Iterator<Item = usize> {\n", " let mut state = (0, 1);\n", " std::iter::from_fn(move || {\n", " state = (state.1, state.0 + state.1);\n", " Some(state.0)\n", " })\n", "}\n", "\n", "let result: Vec<usize> = fibonacci().take(8).collect();\n", "\n", "let expected = vec![1, 1, 2, 3, 5, 8, 13, 21];\n", "\n", "assert_eq!(result, expected);\n", "\n", "println!(\"Fibonacci sequence (first 8 numbers): {:?}\", result);" ] }, { "cell_type": "markdown", "id": "fb679a2d-a3d3-4e8a-8ac4-e80114bd0040", "metadata": {}, "source": [ "### Drain Methods" ] }, { "cell_type": "code", "execution_count": 17, "id": "512ad7b2-b6ea-4a7b-a02b-04dabe326551", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\"art\"" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let mut outer = \"Earth\".to_string();\n", "\n", "let inner = String::from_iter(outer.drain(1..4));\n", "\n", "assert_eq!(outer, \"Eh\");\n", "\n", "inner" ] }, { "cell_type": "markdown", "id": "88919fcd-07ec-47d5-8ca9-7a5ed088420e", "metadata": {}, "source": [ "### Iterator Adapter Methods" ] }, { "cell_type": "code", "execution_count": 18, "id": "004baf75-87f2-469b-93da-f4b16310bd9b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 4, 9, 16, 25]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let numbers = vec![1, 2, 3, 4, 5];\n", "\n", "let squared: Vec<i32> = numbers.into_iter().map(|x| x * x).collect();\n", "\n", "squared" ] }, { "cell_type": "code", "execution_count": 19, "id": "6c832e12-9e25-44ed-9547-133150726c51", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6, 8, 10]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let numbers = 1..=10;\n", "\n", "let evens: Vec<i32> = numbers.into_iter().filter(|x| x % 2 == 0).collect();\n", "\n", "evens" ] }, { "cell_type": "markdown", "id": "63ba2c2d-58e9-4eb4-b80e-59de8af58675", "metadata": {}, "source": [ "### Building Custom Iterators" ] }, { "cell_type": "code", "execution_count": 21, "id": "875abcbf-9769-4347-9f60-b9f42fd7b3fa", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n", "3\n", "5\n", "7\n", "11\n", "13\n", "17\n", "19\n", "23\n", "29\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "struct PrimeGenerator {\n", " current: u32,\n", "}\n", "\n", "impl Iterator for PrimeGenerator {\n", " type Item = u32;\n", "\n", " fn next(&mut self) -> Option<Self::Item> {\n", " loop {\n", " self.current += 1;\n", " if is_prime(self.current) {\n", " return Some(self.current);\n", " }\n", " }\n", " }\n", "}\n", "\n", "fn is_prime(num: u32) -> bool {\n", " if num <= 1 {\n", " return false;\n", " }\n", "\n", " for i in 2..(num / 2 + 1) {\n", " if num % i == 0 {\n", " return false;\n", " }\n", " }\n", "\n", " true\n", "}\n", "\n", "let prime_sequence = PrimeGenerator { current: 1 };\n", "\n", "for prime in prime_sequence.take(10) {\n", " println!(\"{}\", prime);\n", "}" ] }, { "cell_type": "markdown", "id": "90c524bf-4542-4f49-844e-1a23297b8c85", "metadata": {}, "source": [ "### Lazy Evaluation" ] }, { "cell_type": "code", "execution_count": 22, "id": "784b82e1-b9c9-4696-a87e-58db53ce046a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 4, 6, 8, 10]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let numbers = vec![1, 2, 3, 4, 5];\n", "\n", "let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();\n", "\n", "doubled" ] }, { "cell_type": "markdown", "id": "f83b51dd-d82c-477d-922a-bb2d53e230e3", "metadata": {}, "source": [ "### Advanced Techniques" ] }, { "cell_type": "markdown", "id": "057dbe3d-35b3-4802-a203-be7487390e9d", "metadata": {}, "source": [ "#### flat_map" ] }, { "cell_type": "code", "execution_count": 23, "id": "0b06ea30-1017-41f6-a769-ecb23215a3c8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['R', 'u', 's', 't', 'i', 's', 'a', 'w', 'e', 's', 'o', 'm', 'e']" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let words = vec![\"Rust\", \"is\", \"awesome\"];\n", "\n", "let letters: Vec<char> = words.iter()\n", " .flat_map(|&word| word.chars())\n", " .collect();\n", "\n", "letters" ] }, { "cell_type": "markdown", "id": "4ee6c89b-de65-4d46-8bcf-1a0d10839e4c", "metadata": {}, "source": [ "#### take and skip" ] }, { "cell_type": "code", "execution_count": 24, "id": "0de6c26a-7933-4981-b3ce-d81dcccfe432", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[4, 5, 6, 7]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n", "\n", "let selected_numbers: Vec<i32> = numbers.iter()\n", " .skip(3)\n", " .take(4)\n", " .cloned()\n", " .collect();\n", "\n", "selected_numbers" ] }, { "cell_type": "markdown", "id": "bc860a6f-7390-4e3f-83ba-048755a1aa83", "metadata": {}, "source": [ "#### peekable" ] }, { "cell_type": "code", "execution_count": 25, "id": "094ed404-00c2-43ee-a344-4a60765799c8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The next number is: 1\n", "The next number is: 2\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let mut numbers = vec![1, 2, 3, 4, 5].into_iter().peekable();\n", "\n", "if let Some(&next_number) = numbers.peek() {\n", " println!(\"The next number is: {}\", next_number);\n", "} else {\n", " println!(\"No more numbers to process.\");\n", "}\n", "\n", "let _ = numbers.next();\n", "\n", "if let Some(&next_number) = numbers.peek() {\n", " println!(\"The next number is: {}\", next_number);\n", "} else {\n", " println!(\"No more numbers to process.\");\n", "}" ] }, { "cell_type": "markdown", "id": "0dbdaca2-fe3f-4b12-bb7e-84c9aec3a5fa", "metadata": {}, "source": [ "#### filter_map" ] }, { "cell_type": "code", "execution_count": 29, "id": "f02f50e5-1a2e-4357-af94-7461cd88d1d9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[42, 19, 27, 33]" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "use std::str::FromStr;\n", "\n", "let text = \"The numbers are: 42, 19, invalid, 27, 33\";\n", "\n", "let parsed_numbers: Vec<i32> = text\n", " .split(',')\n", " .map(str::trim)\n", " .filter_map(|s| {\n", " let s = s\n", " .chars()\n", " .skip_while(|&c| !c.is_digit(10))\n", " .collect::<String>();\n", " if !s.is_empty() {\n", " i32::from_str(&s).ok()\n", " } else {\n", " None\n", " }\n", " })\n", " .collect();\n", "\n", "parsed_numbers" ] }, { "cell_type": "markdown", "id": "ff04472d-8a50-4a6c-93c2-a724352494be", "metadata": {}, "source": [ "#### fuse" ] }, { "cell_type": "code", "execution_count": 30, "id": "24908d21-f8dc-4408-b449-87164be34a59", "metadata": {}, "outputs": [], "source": [ "struct Unpredictable(bool);\n", "\n", "impl Iterator for Unpredictable {\n", " type Item = &'static str;\n", "\n", " fn next(&mut self) -> Option<Self::Item> {\n", " if self.0 {\n", " self.0 = false;\n", " Some(\"totally the last item\")\n", " } else {\n", " self.0 = true;\n", " None\n", " }\n", " }\n", "}\n", "\n", "let mut unpredictable = Unpredictable(true);\n", "assert_eq!(unpredictable.next(), Some(\"totally the last item\"));\n", "assert_eq!(unpredictable.next(), None);\n", "assert_eq!(unpredictable.next(), Some(\"totally the last item\"));\n", "\n", "let mut reliable = Unpredictable(true).fuse();\n", "assert_eq!(reliable.next(), Some(\"totally the last item\"));\n", "assert_eq!(reliable.next(), None);\n", "assert_eq!(reliable.next(), None);" ] }, { "cell_type": "markdown", "id": "b0353fcc-fd74-4934-b49d-89a3e29638f2", "metadata": {}, "source": [ "#### flatten" ] }, { "cell_type": "code", "execution_count": 31, "id": "542051bf-fb22-49f6-bf39-a176129a8eb6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Course: Computer Science, Students Enrolled: 1\n", "Course: Physics, Students Enrolled: 2\n", "Course: Biology, Students Enrolled: 1\n", "Course: Math, Students Enrolled: 1\n", "Course: Chemistry, Students Enrolled: 1\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "use std::collections::HashMap;\n", "\n", "let mut student_courses = HashMap::new();\n", "student_courses.insert(\"Alice\", vec![\"Math\", \"Physics\"]);\n", "student_courses.insert(\"Bob\", vec![\"Computer Science\", \"Chemistry\"]);\n", "student_courses.insert(\"Charlie\", vec![\"Physics\", \"Biology\"]);\n", "\n", "let course_enrollment: HashMap<&str, usize> = student_courses\n", " .values()\n", " .flatten()\n", " .fold(HashMap::new(), |mut enrollment, course| {\n", " *enrollment.entry(course).or_insert(0) += 1;\n", " enrollment\n", " });\n", "\n", "for (course, count) in &course_enrollment {\n", " println!(\"Course: {}, Students Enrolled: {}\", course, count);\n", "}" ] }, { "cell_type": "markdown", "id": "4ae01099-ab85-47dd-aef9-541f62ba8357", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "id": "2c1f55e2-ad37-4088-9bc0-802070a5a928", "metadata": {}, "source": [ "### Closures" ] }, { "cell_type": "markdown", "id": "617c08b2-766e-4bf3-b54c-67f829c08ce1", "metadata": {}, "source": [ "#### Variable Capture in Closures" ] }, { "cell_type": "markdown", "id": "208fa7f6-9f0b-46c9-a18d-2494e87f3926", "metadata": {}, "source": [ "#### Borrowing Variables" ] }, { "cell_type": "code", "execution_count": 32, "id": "6fbb30ea-d914-46e2-965f-52f906f05b5a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[5, 10, 15, 20, 25]" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let multiplier = 5;\n", "let numbers = vec![1, 2, 3, 4, 5];\n", "\n", "let multiplied: Vec<i32> = numbers.iter().map(|x| x * multiplier).collect();\n", "\n", "multiplied" ] }, { "cell_type": "markdown", "id": "e669bf4a-5ada-47be-b23c-f24343f2642a", "metadata": {}, "source": [ "#### Moving Variables" ] }, { "cell_type": "code", "execution_count": 35, "id": "63b1e2dd-0f8c-4f8a-8d4d-33a7dc0d2123", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello, Rust!\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fn main() {\n", " let message = \"Hello, Rust!\".to_string();\n", "\n", " let greet = || {\n", " let message = message;\n", " println!(\"{}\", message);\n", " };\n", "\n", " greet();\n", "\n", " // greet();\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "c581c3fb-bf21-43ad-9aa7-fd8ec0e08831", "metadata": {}, "source": [ "### Closures and Fn, FnMut, FnOnce Traits" ] }, { "cell_type": "markdown", "id": "8b3342a7-9a39-45f7-99ba-0118538c9a35", "metadata": {}, "source": [ "#### Fn Closures" ] }, { "cell_type": "code", "execution_count": 38, "id": "22e55751-2627-4683-8d37-9772da5fe813", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counter: 0\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fn main() {\n", " let counter = 0;\n", "\n", " let print_counter = || {\n", " println!(\"Counter: {}\", counter);\n", " };\n", "\n", " print_counter();\n", "\n", " // counter += 1;\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "3ff15650-26a4-4a89-86a2-8874decbbfb8", "metadata": {}, "source": [ "#### FnMut Closures" ] }, { "cell_type": "code", "execution_count": 39, "id": "14cb0a3c-7077-4319-8a3d-860b6f4b92ce", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Counter: 1\n", "Counter: 2\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fn main() {\n", " let mut counter = 0;\n", " let mut increment = || {\n", " counter += 1; // <3>\n", " println!(\"Counter: {}\", counter);\n", " };\n", "\n", " increment();\n", " increment();\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "5f715e3a-ed2b-4f1a-b74f-65329e1e5fa5", "metadata": {}, "source": [ "#### FnOnce Closures" ] }, { "cell_type": "code", "execution_count": 40, "id": "d5f652b0-1d91-4367-bb6c-3d4ed011798a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sum: 15\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fn main() {\n", " let numbers = vec![1, 2, 3, 4, 5];\n", " let consume_numbers = || {\n", " let numbers = numbers;\n", " let sum: i32 = numbers.iter().sum();\n", " println!(\"Sum: {}\", sum);\n", " };\n", "\n", " consume_numbers();\n", " // consume_numbers(); // <7>\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "34dce128-1e81-4827-a620-85e6c279ac5a", "metadata": {}, "source": [ "### Working with Iterators for Efficient Data Processing" ] }, { "cell_type": "markdown", "id": "ca96c6c4-e099-45ec-b46c-21f2a46f3913", "metadata": {}, "source": [ "#### Accumulating Data with `fold`" ] }, { "cell_type": "code", "execution_count": 41, "id": "0ed35e01-80c0-4cdd-b927-dc74a3a2731f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "15" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "let numbers = vec![1, 2, 3, 4, 5];\n", "\n", "let sum: i32 = numbers.iter().fold(0, |acc, x| acc + x);\n", "\n", "sum" ] }, { "cell_type": "markdown", "id": "960b1d46-2958-448c-b1ed-67c3b6abcfc8", "metadata": {}, "source": [ "#### Chaining Iterators with `chain`" ] }, { "cell_type": "code", "execution_count": 42, "id": "b07078ca-97f1-4c80-ac64-7bf24cdae2b1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Combined and doubled: [2, 4, 6, 8, 10, 12]\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fn main() {\n", " let numbers1 = vec![1, 2, 3];\n", " let numbers2 = vec![4, 5, 6];\n", "\n", " let combined: Vec<i32> = numbers1\n", " .iter()\n", " .chain(numbers2.iter())\n", " .map(|x| x * 2)\n", " .collect();\n", "\n", " println!(\"Combined and doubled: {:?}\", combined);\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "8fb3bd80-99ab-4ccd-ace5-a567b3c9c099", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "id": "30a339d7-6011-42cb-a520-734796fdd507", "metadata": {}, "source": [ "### Applying Iterators and Closures to Practical Examples" ] }, { "cell_type": "markdown", "id": "e2e7169d-c9ff-4ac3-9f7a-4b1d7ba655be", "metadata": {}, "source": [ "#### Use Case 1: Text Analysis" ] }, { "cell_type": "code", "execution_count": 43, "id": "f6ded3de-6b97-482e-9998-04e6d3782112", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Word Frequencies: {\"learn\": 2, \"fun\": 1, \"makes\": 1, \"to\": 1, \"you\": 1, \"that\": 1, \"and\": 1, \"when\": 1, \"it\": 1, \"language\": 1, \"easy\": 1, \"rust\": 4, \"programming\": 1, \"a\": 1, \"is\": 2}\n" ] } ], "source": [ "let text = \"Rust is a language that makes it easy to learn Rust and Rust programming is fun when you learn Rust\";\n", "\n", "let word_freq: HashMap<String, u32> = text\n", " .split_whitespace()\n", " .map(|word| word.to_lowercase())\n", " .filter(|word| !word.is_empty())\n", " .fold(HashMap::new(), |mut map, word| {\n", " *map.entry(word.to_string()).or_insert(0) += 1;\n", " map\n", " });\n", "\n", "println!(\"Word Frequencies: {:?}\", word_freq);" ] }, { "cell_type": "markdown", "id": "7a000ab6-10bb-4b1b-af1e-a547961212ff", "metadata": {}, "source": [ "#### Use Case 2: Image Processing" ] }, { "cell_type": "code", "execution_count": 44, "id": "21c6e430-eb9a-4ddb-a8e4-e87200a74aab", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Image after processing: [Pixel { red: 200, green: 100, blue: 50 }, Pixel { red: 144, green: 200, blue: 100 }]\n" ] } ], "source": [ "#[derive(Debug)]\n", "struct Pixel {\n", " red: u8,\n", " green: u8,\n", " blue: u8,\n", "}\n", "\n", "let mut image: Vec<Pixel> = vec![\n", " Pixel {\n", " red: 100,\n", " green: 50,\n", " blue: 25,\n", " },\n", " Pixel {\n", " red: 200,\n", " green: 100,\n", " blue: 50,\n", " },\n", " // ... more pixels\n", "];\n", "\n", "image.iter_mut().for_each(|pixel| {\n", " pixel.red = pixel.red.wrapping_mul(2);\n", " pixel.green = pixel.green.wrapping_mul(2);\n", " pixel.blue = pixel.blue.wrapping_mul(2);\n", "});\n", "\n", "println!(\"Image after processing: {:?}\", image);" ] }, { "cell_type": "markdown", "id": "7f7e591a-6eda-48db-9887-4399aecea9a8", "metadata": {}, "source": [ "#### Use Case 3: Data Filtering and Transformation" ] }, { "cell_type": "code", "execution_count": 46, "id": "a0b355e0-9ee2-4760-a314-d33bdd157aad", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Discounted Products: [Product { name: \"Widget A\", price: 8.0, in_stock: true }]\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#[derive(Debug)]\n", "struct Product {\n", " name: String,\n", " price: f64,\n", " in_stock: bool,\n", "}\n", "\n", "fn main() {\n", " let products = vec![\n", " Product {\n", " name: String::from(\"Widget A\"),\n", " price: 10.0,\n", " in_stock: true,\n", " },\n", " Product {\n", " name: String::from(\"Widget B\"),\n", " price: 15.0,\n", " in_stock: false,\n", " },\n", " // ... more products\n", " ];\n", "\n", " let discount = 0.2;\n", "\n", " let discounted_products: Vec<Product> = products\n", " .into_iter()\n", " .filter(|product| product.in_stock)\n", " .map(|mut product| {\n", " product.price -= product.price * discount;\n", " product\n", " })\n", " .collect();\n", "\n", " println!(\"Discounted Products: {:?}\", discounted_products);\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "fa25757d-4d18-4292-b98b-8182ebf9c72f", "metadata": {}, "source": [ "#### Use Case 4: Processing Sensor Data" ] }, { "cell_type": "code", "execution_count": 47, "id": "319f1ebc-31b6-4a76-88cc-5ba0c5f5f27f", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Anomalous Readings: [SensorReading { timestamp: 3, value: 23.0 }]\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#[derive(Debug)]\n", "struct SensorReading {\n", " timestamp: u64,\n", " value: f64,\n", "}\n", "\n", "fn main() {\n", " let sensor_data = vec![\n", " SensorReading {\n", " timestamp: 1,\n", " value: 20.0,\n", " },\n", " SensorReading {\n", " timestamp: 2,\n", " value: 22.0,\n", " },\n", " SensorReading {\n", " timestamp: 3,\n", " value: 23.0,\n", " },\n", " // ... more readings\n", " ];\n", "\n", " let threshold = 22.0;\n", "\n", " let anomalies: Vec<&SensorReading> = sensor_data\n", " .iter()\n", " .filter(|&reading| reading.value > threshold)\n", " .collect();\n", "\n", " println!(\"Anomalous Readings: {:?}\", anomalies);\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "00a5a00e-d53d-4487-8898-de4d0df805f3", "metadata": {}, "source": [ "#### Use Case 5: Financial Calculations" ] }, { "cell_type": "code", "execution_count": 48, "id": "fe2ab707-af71-412a-8920-bbdc9eb8693a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final Balance: 150.0\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#[derive(Debug)]\n", "struct Transaction {\n", " amount: f64,\n", " transaction_type: String,\n", "}\n", "\n", "fn main() {\n", " let transactions = vec![\n", " Transaction {\n", " amount: 100.0,\n", " transaction_type: String::from(\"Deposit\"),\n", " },\n", " Transaction {\n", " amount: -50.0,\n", " transaction_type: String::from(\"Withdrawal\"),\n", " },\n", " // ... more transactions\n", " ];\n", "\n", " let balance = transactions.iter().fold(0.0, |acc, transaction| {\n", " if transaction.transaction_type == \"Deposit\" {\n", " acc + transaction.amount\n", " } else {\n", " acc - transaction.amount\n", " }\n", " });\n", "\n", " println!(\"Final Balance: {:?}\", balance);\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "cc0df9a2-495b-490a-9b16-f9e5301ea92d", "metadata": {}, "source": [ "#### Use Case 6: Sorting" ] }, { "cell_type": "code", "execution_count": 49, "id": "dd450be4-e1b2-4a65-86ea-a7a064df42a6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Product: Headphones - Price: $149.99\n", "Product: Smartphone - Price: $599.99\n", "Product: Laptop - Price: $799.99\n" ] }, { "data": { "text/plain": [ "()" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "struct Product {\n", " name: String,\n", " price: f64,\n", "}\n", "\n", "fn main() {\n", " let mut products = vec![\n", " Product {\n", " name: \"Laptop\".to_string(),\n", " price: 799.99,\n", " },\n", " Product {\n", " name: \"Headphones\".to_string(),\n", " price: 149.99,\n", " },\n", " Product {\n", " name: \"Smartphone\".to_string(),\n", " price: 599.99,\n", " },\n", " ];\n", "\n", " products.sort_by(|a, b| a.price.partial_cmp(&b.price).unwrap());\n", "\n", " for product in &products {\n", " println!(\"Product: {} - Price: ${}\", product.name, product.price);\n", " }\n", "}\n", "\n", "main()" ] }, { "cell_type": "markdown", "id": "6fb7d6c2-7514-4652-ae01-329df90832ff", "metadata": {}, "source": [ "\n", "---\n", "---" ] } ], "metadata": { "kernelspec": { "display_name": "Rust", "language": "rust", "name": "rust" }, "language_info": { "codemirror_mode": "rust", "file_extension": ".rs", "mimetype": "text/rust", "name": "Rust", "pygment_lexer": "rust", "version": "" } }, "nbformat": 4, "nbformat_minor": 5 }