#ScryptoClassof2022 Week 10 from Rustacean to Scryptonaut!

Welcome to week 10 of #ScryptoClassof2022 where we finally begin actually getting our hands dirty with Scrypto! Last week we ended with some challenges from the end of chapter 8 so I wanted to share some solutions to these first.

Given a list of integers, use a vector and return the median (when sorted, the value in the middle position) and mode (the value that occurs most often; a hash map will be helpful here) of the list.

use std::collections::HashMap;

fn main() {
    let numbers = vec![1, 1, 1, 4, 5, 2, 4, 4, 5, 1]; //creating a list of random numbers
    let odd_length_numbers = vec![2, 2, 4]; //creating another list of random numbers to make sure 
                                            //code can get median of both even and odd amount of numbers
    
    let average = mean(&numbers);
    println!("Average is: {}", average);
    
    let med = median(&numbers);
    println!("Median is: {}", med);
    
    let odd_length_median = median(&odd_length_numbers);
    println!("Median for odd length vector is: {}", odd_length_median);
    
    let my_mode = mode(&numbers);
    println!("Mode is {}", my_mode);
}
 
fn mean(numbers: &[i32]) -> f64 {
    let mut sum = 0.0; // 1. sum the number in the vector
    for num in numbers {
        sum += *num as f64;
    }
    sum / numbers.len() as f64 // 2. Devide by the length of the vector.
}
    // Another possible solution:
    // let sum = numbers.iter().fold(0, |acc, curr| acc + curr);
    // sum as f64 / numbers.len() as f64


fn median(numbers: &[i32]) -> f64 {
    // 1. Sort the vector
    // 2. Return middle number
    // if the vector has an even length we return
    // the mean of the two middle numbers
    let mut sorted_numbers = numbers.to_vec();
    sorted_numbers.sort();
    let middle = sorted_numbers.len() / 2;
    if sorted_numbers.len() % 2 == 0 {
        return mean(&vec![sorted_numbers[middle], sorted_numbers[middle - 1]]);
    }
    sorted_numbers[middle] as f64
}
    
fn mode(numbers: &[i32]) -> i32 {
    let mut map = HashMap::new();
    for num in numbers {
        let count = map.entry(num).or_insert(0);
        *count += 1;
    }
    println!("Map of occurences {:?}", map);
    let mut max_value = 0;
    let mut mode = 0;
    for (key, value) in map {
        if value > max_value {
            max_value = value;
            mode = *key;
        }
    }
    mode
}

Convert strings to pig latin. The first consonant of each word is moved to the end of the word and “ay” is added, so “first” becomes “irst-fay.” Words that start with a vowel have “hay” added to the end instead (“apple” becomes “apple-hay”). Keep in mind the details about UTF-8 encoding!

use std::{collections::HashMap, io};

const VOWELS: [&str; 5] = ["a", "e", "i", "o", "u"];

fn main() {
    let original_word = String::from("Scrypto");
    let pig_latin_version = convert_to_pig_latin(&original_word);
    println!("{} in piglatin is {}", original_word, pig_latin_version);
}

fn convert_to_pig_latin(word: &str) -> String {
    // The first consonant of each word
    // is moved to the end of the word and
    // “ay” is added, so “first” becomes “irst-fay
    // Words that start with a vowel have “hay”
    // added to the end instead
    // (“apple” becomes “apple-hay”)
    let (first, rest) = word.split_at(1);
    let is_vowel = VOWELS.contains(&first);
    if is_vowel {
        return format!("{}-{}", word, "hay");
    }
    format!("{}-{}ay", rest, first)
}

Using a hash map and vectors, create a text interface to allow a user to add employee names to a department in a company. For example, “Add Sally to Engineering” or “Add Amir to Sales.” Then let the user retrieve a list of all people in a department or all people in the company by department, sorted alphabetically

use std::{collections::HashMap, io};

fn main() {
    let mut employee_directory = HashMap::new();

    loop {
        println!("Enter a command like \"Add <Person> to <Department>\"");
        let mut command = String::new();

        io::stdin()
            .read_line(&mut command)
            .expect("Failed to read command");

        let command: &str = command.trim();
        println!("You entered {}", command);
        let mut iter = command.split_whitespace();
        let person = match iter.nth(1) {
            Some(p) => p,
            None => {
                println!("1. Please enter a valid command");
                continue;
            }
        };
        // let person = iter.nth(1).expect("Invalid command!");
        let department = match iter.nth(1) {
            Some(d) => d,
            None => {
                println!("2. Please enter a valid command");
                continue;
            }
        };

        let employees = employee_directory.entry(String::from(department)).or_insert(vec![]);
        employees.push(String::from(person));

        println!("Employee directory: {:?}", employee_directory);
        // let department = iter.nth(3).expect("Invalid command!");
    }
}

These are obviously not the only possible solutions to these problems, but hopefully they can get you moving in the right direction if you get stuck on your own attempts.

Here is Youtuber Tom McGurl going over this code for these examples.

Scrypto time. Just like for the Rust portion of this class, I am going to be using these threads as just a place to keep my notes on what I find useful and where I have found answers to the questions I have along the way. These notes will be constantly evolving until I am confident enough with Scrypto to compile a more organized an in depth guide. All comments/corrections/suggestions are welcomed!

https://docs.radixdlt.com/main/scrypto/introduction.html

This link above will be your best friend for a while. Read through every tab in the Scrypto section from start to finish to both learn the fundamentals of Scrypto and to know where these materials can be found when you will inevitably need to refer back to them.

This is the repo for the various Scrypto examples that the following videos will cover. I would go ahead and clone it so that you have all the code handy and it will be easier to follow along with the dev event videos.

The first video I would watch is the first introduction to Scrypto from Russel. Many things have changed since the release of this video. We still have buckets, vaults, badges, and proofs, but the code and syntax has come a long way and had a lot of changes done to it. The fundamentals are all the same though. Watch the video, follow concepts, but don’t necessarily follow along with the code for this first one.

Here is the Dev event from Lisbon:

This is the dev event from Austin. I highly recommend watching this entire event. It is extremely important to understand how and why Scrypto is designed the way it is and the Radix team do a great job at clearly explaining this before the coding workshops.

5:08 - Piers presentation

19:02 - Matt Hines why DeFi is the future

56:32 - How smart contracts work on Radix vs. Solidity

1:38:23 - Clement presents Hello World

1:52:18 - Clement presents Gumball Machine

2:09:37 - Clement presents Bored Gumball Club NFTs

2:35:21 - Clement presents Event ticket system

1:38:23 - Clement presents Radiswap

This is the most recent dev event where Omar goes through the coding examples. It is also an excellent one to watch all of the way through (but if you are short on time please watch all of the coding workshops).

Problems I have come across:

Rust Analyzer extension not working
As I have been working through Rust tutorials, I have saved all of my projects in a folder named “Rust”. I have been pretty confused for a while now because rust-analyzer extension has never worked for me. I have just had that Rust folder open showing all of the projects as subfolders and I open each folder this way. The proper way to do this is to open each folder directly in VS Code so your extension actually works and shows pop up hints, auto code completion, etc. There is a method though to make the extension work. If you have a project with many crates inside of it (like how I was using my generic rust folder) you can modify the settings.json file in .vscode to point to each crate’s .toml file like this:

Using local variables
When you see something like $account, $component, $package used, this is a local variable being assigned to store the actual address for each of these items. It makes the code a bit easier to manage. These are also reset when using the resim reset command so make sure to export them again each time you try an example. It will look like this to store account:

Mac/Linux
export account=989834392239349823498234892349238298

Windows powershell
$account=“989834392239349823498234892349238298”

Other random links:
adding color code to your Radix transaction manifest

Omar’s Radex example

Dex challenge

Oracle challenge

Lending platform challenge

Challenge submissions

Thanks for reading and please support these great projects for helping us out!

Radup.io
Delphibets.com
Ociswap.com
Scryptochaps.com
Cerberrads.com
Radixdltstaking.com
Spikebrosnft.com
NattyRadishes.com
Radixscan.io

1 Like