Petit guide rapide pour les Pythonistas souhaitant devenir Rustaceans.


Python
1. Conventions et guidelines
PEP8
2. Tooling
  • requirements.txt
  • setup.py
  • PyPI
  • pip
  • setuptools & poetry pour distribuer des libs
  • pipenv pour la gestion des dépendances
  • twine pour uploader un package
  • venv pour isoler un env
  • pyenv pour gérer ≠ versions de Python
  • pydoc & Sphinx pour générer la doc
  • Python pour interpréter/ compiler
  • ipython comme REPL
  • ipdb pour debugguer
3. Librairies et frameworks
4. Python like features
  • dict
  • constructor avec valeurs par défaut
  • itertools
  • hashlib
5. Hello world
if __name__ == "__main__":
    print("Hello, World")

6. Types
age = 33
name = 'olivier'
weight = 75.3
cartoons = ['riri', 'fifi', 'loulou']
ages = {
    'riri': 7,
    'fifi': 7,
    'loulou': 7,
}




7. Fonctions
def substract(a: int, b: int) -> int:
    """Substracts b from a"""
    return a - b

8. Manipulation de listes


cartoons = ["riri", "fifi", "loulou"]
print(cartoons[0])  # riri
cartoons.append("donald")
print(len(cartoons))  # 4
print(cartoons[2:])  # ["loulou", "donald"]

for cartoon in cartoons:
    print(cartoon)

for i, cartoon in enumerate(cartoons):
    print(f"{cartoon} at {i}")

# Lexicographical order
cartoons.sort()

# Reversed lexicographical order
cartoons.sort(reverse=True)

# Sort by length
cartoons.gpg(key=len)


9. Range
for i in range(0,6,2):
   print(i) # 0, 2, 4
    
10. Manipulation de dictionnaires (hash map)
# Create new dict
cartoons_age = {}
cartoons_age["riri"] = 7
cartoons_age["fifi"] = 7
cartoons_age["loulou"] = 7

# or using for loop
cartoons_age = {}
for cartoon, age in [("riri", 7), ("fifi", 7), ("loulou", 7)]:
    cartoons_age[cartoon] = age

# or using a list
cartoons_age = dict([("riri", 7), ("fifi", 7), ("loulou", 7)])

# or using key values
cartoons_age = {
    "riri": 7,
    "fifi": 7,
    "loulou": 7,
}

cartoons_age["donald"] = 45
print(cartoons_age["riri"])  # 7
print("riri" in cartoons_age)  # True

del cartoons_age["loulou"]

for cartoon in cartoons_age:  # Keys
    print(cartoon)

for cartoon, age in cartoons_age.items():  # Keys & values
    print(f"{cartoon} is {age} years old")
































11. Lire contenu d'un fichier
from pathlib import Path

with Path("/tmp/mon_fichier.txt").open() as fp:
    #  Iterate over lines
    for line in fp:
        print(line.strip())






12. Exceptions/ Retour d'erreur
def div(a, b):
    if b == 0:
        raise ValueError("Division par 0 impossible")
    return a / b

try:
    div(1, 0)
except ValueError:
    print('Oops an error occurred!')





13. "Printer" des objets
class Cartoon:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
      return str(self.__dict__)

riri = Cartoon(
    name='Riri',
    age=7,
)

print('{!r}'.format(riri))  
# {'name': 'Riri', 'age': 7}

14. Set (hashSet)

cartoons = set()
cartoons.add("riri")
cartoons.add("fifi")
cartoons.add("loulou")
cartoons.add("loulou")

# or using literal syntax
cartoons = {'riri', 'fifi', 'loulou', 'loulou'}

# or using an iterator
cartoons = set(['riri', 'fifi', 'loulou', 'loulou'])

# Manipulation sur les sets
cartoons = {'riri', 'fifi', 'loulou', 'donald', 'picsou'}
some_cartoons = {"donald", "picsou"}

# difference
print(cartoons.difference(some_cartoons))
# {'riri', 'fifi', 'loulou'}

# intersection
print(cartoons.intersection(some_cartoons))  
# {'donald', picsou}

# union
print(cartoons.union(some_cartoons))
# {'riri', 'fifi', 'loulou', 'donald', 'picsou'}
















15. while et for loops
# While loop
counter = 0
while counter < 10:
    print(counter)
    counter += 1

# infinite while loop
while True:
    print("Infinite loop")

# infinite while loop with break
counter = 0
while True:
    print(counter)
    counter += 1
    if counter >= 10:
        break


# while loop with continue
counter = 0
while True:
    counter += 1
    if counter == 5:
        continue
    print(counter)
    if counter >= 10:
        break

# For loop over a list
for cartoon in ["riri", "fifi", "loulou"]:
    print(cartoon)

# Enumerating indexes
for  i, cartoon in enumerate(["riri", "fifi", "loulou"]):
    print(f"{cartoon} at index {i}")

# For in a range
for number in range(0, 100):
    print(number)  # from 0 to 99







16. Flask vs Rocket
from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return 'Hello Python'


if __name__ == '__main__':
    app.run(port=8080)

17. Request vs Reqwest
import requests

url = 'https://httpbin.org/ip'

try:
    resp = requests.get(url)
except HTTPError as err:
    msg = f"error: cannot get {url} - {err}"
    raise SystemExit(msg)

assert resp.status_code == 200

print(f"The response content is: {resp.content}")





18. JSON encoding decoding
import json

# Decode/Deserialize
cartoon_data = '''{
    "name": "riri",
    "age": 7
}'''

cartoon = json.loads(cartoon_data)

# Do things like with any other Python data structure
print(f"{cartoon['name']} was born {cartoon['age']} years ago")

# Encode/Serialize
serialized = json.dumps(obj)
print(f"The serialized value is: {serialized}")












19. Object oriented
class Soldier:
    def __init__(self, name: str):
        self.name = name

    def present(self, other_family_name: str):
        print(f"Hi M. {other}, I'm solider {self.name}")

# ...

soldier = Soldier("Ryan")
soldier.present("Bond")
Rust
1. Conventions et guidelines
RustAPI Guidelines
2. Tooling
4. Python like features
5. Hello world
fn main() {
  println!("Hello, World");
}
6. Types
use std::collections::HashMap;

fn main() {
    let age = 33;
    let name = "olivier";
    let weight = 75.3;
    let mut cartoons = vec!["riri", "fifi", "loulou"];

    let mut ages = HashMap::new();
    ages.insert("riri", 7);
    ages.insert("fifi", 7);
    ages.insert("loulou", 7);
}
7. Fonctions
/// Substracts b from a
fn substract(a: i32, b: i32) -> i32 {
  a - b
}
8. Manipulation de listes
fn main() {
    let mut cartoons = vec!["riri", "fifi", "loulou"];
    println!("{}", cartoons[0]);  // riri
    cartoons.push("donald");
    println!("{}", cartoons.len());  // 4
    println!("{:?}", &cartoons[2..]);  // ["loulou", "donald"]

    for cartoon in &cartoons {
        println!("{}", cartoon);
    }

    for (i, cartoon) in cartoons.iter().enumerate() {
        println!("{} at {}", i, cartoon);
    }

    // Lexicographical order
    cartoons.sort();

    // Reversed lexicographical order
    cartoons.sort_by(|a, b| b.cmp(a));

    // Sort by length
    cartoons.sort_by_key(|a| a.len());
}
9. Range
for i in (0..6).step_by(2) {
    println!("{}", i);  // 0, 2, 4
}
10. Manipulation de dictionnaires (hash map)
use std::iter::FromIterator;
use std::collections::HashMap;

fn main() {

    // Create new HashMap
    let mut cartoons_ages = HashMap::new();
    cartoons_ages.insert("riri", 7);
    cartoons_ages.insert("fifi", 7);
    cartoons_ages.insert("loulou", 7);

    // or using a loop
    let mut cartoons_ages = HashMap::new();
    for &(name, age) in [("riri", 7), ("fifi", 7), ("loulou", 7)].iter() {
        // Possible to remove & and use iter().clone()
        cartoons_ages.insert(name, age);
    }

    // or using an Array
    let mut cartoons_ages: HashMap<&str, i32> =
        [("riri", 7), 
         ("fifi", 7), 
         ("loulou", 7)]
        .iter().cloned().collect();

    // or using a Vec (Iterator)
    let mut cartoons_ages: HashMap<&str, i32> =
        HashMap::from_iter(
            vec![
               ("riri", 7),
               ("fifi", 7),
               ("taz", 7)
            ]
        );

    cartoons_ages.insert("donald", 45);
    println!("{}", cartoons_ages["fifi"]);  // 7
    println!("{}", cartoons_ages.contains_key("fifi")); // true
    cartoons_ages.remove("loulou");


    for name in cartoons_ages.keys() {  // Keys
      println!("{}", name);
    }

    for (name, age) in &cartoons_ages {  // Keys & values
      println!("{} is {} years old", name, age);
    }

}

Alternative
Ajouter la dependency dans Cargo.toml
[dependencies]
maplit = "*"

Puis utiliser juste:
#[macro_use] extern crate maplit;

let map = hashmap!{
    "riri" => 7,
    "fifi" => 7,
    "loulou" => 7,
};
11. Lire contenu d'un fichier
use std::io::{BufReader, BufRead};
use std::fs::File;
use std::path::Path;

fn main () {
    let fp = File::open(Path::new("/tmp/mon_fichier.txt")).unwrap();
    let file = BufReader::new(&fp);
    for line in file.lines() {
        //  Iterate over lines
        println!("{}", line.unwrap());
    }
}
12. Exceptions/ Retour d'erreur
fn div(a: f64, b: f64) -> Result {
    if b == 0 {
        Err("Division par 0 impossible")
    } else {
        Ok(a / b)
    }
}

fn main() {
    match div(1, 0) {
        Ok(_) => {},
        Err(_) => println!("Oops an error occurred!"),
    };
}
13. "Printer" des objets
#[derive(Debug)]
struct Cartoon {
    name: String,
    age: i32
}

fn main() {
    let riri = Cartoon {name: "Riri".into(), age: 7};
    println!("{:#?}", riri);
    // Actor {name: "Riri", age: 7 }
}




14. Set (hashSet)
use std::collections::HashSet;
use std::iter::FromIterator;

fn main() {
    let mut cartoons = HashSet::new();
    cartoons.insert("riri");
    cartoons.insert("fifi");
    cartoons.insert("loulou");
    cartoons.insert("loulou");

    // from an iterator
    let mut cartoons: HashSet<&str> = HashSet::from_iter(vec!["riri", "fifi", "loulou", "loulou"]);

    // deduplication
    println!("{:?}", cartoons); 
    // {"riri", "fifi", "loulou"}

    // Manipulation sur les hashSet
    let mut cartoons: HashSet<&str> = HashSet::from_iter(vec!["riri", "fifi", "loulou", "loulou", "donald", "picsou"]);
    let mut some_cartoons: HashSet<&str> = HashSet::from_iter(vec!["donald", "picsou"]);

    // difference
    cartoons.difference(&some_cartoons); 
    // ["riri", "fifi", "loulou"]

    // intersection
    cartoons.intersection(&some_cartoons); 
    // ["riri"]

    // union
    cartoons.union(&some_cartoons); 
    // ["red", "fifi", "loulou, "donald", "picsou"]
}

Alternative
Ajouter la dependency dans Cargo.toml
[dependencies]
maplit = "*"

Puis utiliser juste:
#[macro_use] extern crate maplit;

let cartoons = hashset!{"riri", "fifi", "loulou", "loulou"};
15. while et for loops
fn main() {

    // While loop
    let mut counter = 0;
    while counter < 10 {
        println!("{}", counter);
        counter += 1;
    }

    // infinite while loop
    loop {
        println!("Infinite loop");
    }

    // infinite while loop with break
    let mut counter = 0;
    loop {
        println!("{}", counter);
        counter += 1;
        if counter >= 10 { break; }
    }

    // infinite while loop with continue
    let mut counter = 0;
    loop {
        counter += 1;
        if counter == 5 { continue; }
        println!("{}", counter);
        if counter >= 10 { break; }
    }

    // for loop over a list
    for cartoon in ["riri", "fifi", "loulou"].iter() {
        println!("{}", cartoon);
    }

    // Enumerating indexes
    for (i, cartoon) in ["riri", "fifi", "loulou"].iter().enumerate() {
        println!("{} at index {}", cartoon, i);
    }

    // for in a range
    for number in 0..100 {
        println!("{}", number);  
        // from 0 to 99
    }
}
16. Flask vs Rocket
#![feature(plugin)]
#![plugin(rocket_codegen)]

extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello Rust"
}

fn main() {
    rocket::ignite().mount("/", routes![index]).launch();
}
17. Request vs Reqwest
extern crate reqwest;
use std::io::Read;

fn main() {
    let url = "https://httpbin.org/ip";

    let mut resp = match reqwest::get(url) {
        Ok(response) => response,
        Err(e) => panic!("error: could not perform get request {}", e),
    };

    assert!(resp.status().is_success());

    let mut content = String::new();
    resp.read_to_string(&mut content).expect("valid UTF-8");

    println!("The response content is: {}", content);
}
18. JSON encoding decoding
extern crate serde;
extern crate serde_json;

#[macro_use]
extern crate serde_derive;

#[derive(Serialize, Deserialize)]
struct Cartoon {
    name: String,
    age: u8,
}

fn main() {
    // Decode/Deserialize
    let cartoon_data = r#"{"name": "riri", "age": 7}"#;

    let c: Cartoon = match serde_json::from_str(cartoon_data) {
        Ok(cartoon) => cartoon,
        Err(e) => panic!("error: could not deserialize: {}", e),
    };

    // Do things just like with any other Rust data structure.
    println!("{} was born {} years ago.", c.name, c.age);

    // Encode/Serialize
    let serialized = serde_json::to_string(&c).unwrap();
    println!("The serialized value is: {}", serialized);
}
19. Object oriented
struct Soldier {
    name: String
}

impl Soldier {

    pub fn new<S>(name: S) -> Soldier where S: Into {
        Soldier { name: name.into() }
    }
    
    pub fn present>(&self, other_family_name:S) {
        println!("Hi M. {}, I'm {}", other_family_name.into(), self.name);
    }     
    
}

fn main() {
    let soldier = Soldier::new("Ryan");
    soldier.present("Bond");
}