début plotting, pour l'instant ça marche pas
This commit is contained in:
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -60,6 +60,12 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.10"
|
||||
@@ -71,6 +77,15 @@ dependencies = [
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
@@ -149,6 +164,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"csv",
|
||||
"itertools",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"serde",
|
||||
|
||||
@@ -8,6 +8,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
argh = "0.1.12"
|
||||
csv = "1.2.2"
|
||||
itertools = "0.13.0"
|
||||
rand = "0.8.5"
|
||||
rand_chacha = "0.3.1"
|
||||
serde = "1.0.188"
|
||||
|
||||
66
src/io.rs
66
src/io.rs
@@ -1,20 +1,66 @@
|
||||
use super::repartition::*;
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
const FORMAT_TEXT: &'static str = "<html>
|
||||
use super::repartition::*;
|
||||
use itertools::Itertools;
|
||||
|
||||
impl Repartition {
|
||||
pub fn to_json(&self) -> String {
|
||||
let participants = self
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|t| vec![t.from.clone(), t.to.clone()])
|
||||
.dedup()
|
||||
.collect_vec();
|
||||
let mut str_nodes = String::new();
|
||||
for p in participants {
|
||||
str_nodes += &format!(
|
||||
"{{
|
||||
\"data\": {{
|
||||
\"id\":\"{}\",
|
||||
\"label\":\"{}\"
|
||||
}},
|
||||
}},",
|
||||
p.name, p.name
|
||||
);
|
||||
}
|
||||
let mut str_edges = String::new();
|
||||
for t in &self.0 {
|
||||
str_edges += &format!(
|
||||
"{{
|
||||
\"data\": {{
|
||||
\"id\":\"{}-{}\",
|
||||
\"label\":\"{}€\",
|
||||
\"source\":\"{}\",
|
||||
\"target\":\"{}\",
|
||||
}}
|
||||
}},",
|
||||
t.from.name,
|
||||
t.to.name,
|
||||
t.amount as f32 / 100.,
|
||||
t.from.name,
|
||||
t.to.name,
|
||||
)
|
||||
}
|
||||
"[".to_owned() + &str_nodes + "," + &str_edges + "]"
|
||||
}
|
||||
}
|
||||
|
||||
const FORMAT_STRING: &'static str = "<html>
|
||||
<head>
|
||||
<script src=\"/home/jfelderh/Prog/Repartition Alpes/cytoscape.min.js\"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id=\"graph\" style=\"width: auto;height: 500px;\"></div>
|
||||
|
||||
<h3>Balance totale (doit être égal à zéro) : {}€</h3>
|
||||
<h3>Balance totale (doit être égal à zéro) : TOTAL_BALANCE €</h3>
|
||||
|
||||
<script type=\"text/javascript\">
|
||||
var cy = cytoscape({
|
||||
|
||||
container: document.getElementById('graph'), // container to render in
|
||||
|
||||
elements:{},
|
||||
elements:ELEMENTS,
|
||||
|
||||
style: [ // the stylesheet for the graph
|
||||
{
|
||||
@@ -48,3 +94,15 @@ style: [ // the stylesheet for the graph
|
||||
|
||||
</body>
|
||||
";
|
||||
use super::repartition::*;
|
||||
pub fn plot_repartition(rep: &Repartition) {
|
||||
let text_html = FORMAT_STRING
|
||||
.to_string()
|
||||
.replace("TOTAL_BALANCE", &rep.total_balance().to_string())
|
||||
.replace("ELEMENTS", &rep.to_json());
|
||||
fs::write("/tmp/repartition.html", text_html).expect("Could not write into /tmp/");
|
||||
Command::new("firefox")
|
||||
.arg("/tmp/repartition.html")
|
||||
.output()
|
||||
.expect("Could not run firefox");
|
||||
}
|
||||
|
||||
@@ -37,12 +37,16 @@ fn main() {
|
||||
let repartition_file = fs::File::open(filename).expect("not able to read file");
|
||||
let mut csv_reader = csv::ReaderBuilder::new()
|
||||
.has_headers(false)
|
||||
.delimiter(b';')
|
||||
.delimiter(b',')
|
||||
.from_reader(repartition_file);
|
||||
|
||||
let user_list = csv_reader
|
||||
.records()
|
||||
.map(Result::unwrap)
|
||||
.map(|r| {
|
||||
dbg!(&r);
|
||||
r
|
||||
})
|
||||
.map(|record| User {
|
||||
name: record[0].parse::<String>().unwrap().trim_end().to_string(),
|
||||
balance_cents: (record[1].parse::<f64>().unwrap() * 100.) as i32,
|
||||
@@ -67,9 +71,11 @@ fn main() {
|
||||
serde_json::to_string_pretty(&best_repartition).unwrap()
|
||||
);
|
||||
} else if let Some(filename) = args.transfert_list_filename {
|
||||
dbg!(&filename);
|
||||
let repart: Repartition =
|
||||
serde_json::from_reader(fs::File::open(filename).expect("not able to read file"))
|
||||
.expect("unable to read file");
|
||||
io::plot_repartition(&repart);
|
||||
} else {
|
||||
println!("No parameter given, exiting");
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::cmp::min;
|
||||
use std::{cmp::min, collections::HashSet};
|
||||
|
||||
use rand::prelude::*;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct User {
|
||||
pub name: String,
|
||||
pub email: String,
|
||||
@@ -85,11 +85,13 @@ pub struct Transfer {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Repartition(Vec<Transfer>);
|
||||
pub struct Repartition(pub Vec<Transfer>);
|
||||
|
||||
type Evaluation = (usize);
|
||||
|
||||
impl Repartition {
|
||||
pub fn total_balance(&self) -> i32 {
|
||||
self.0.iter().map(|t| t.amount as i32).sum()
|
||||
}
|
||||
pub fn evaluate(&self) -> Evaluation {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user