use std::collections::HashMap; use time::Date; use trueskill_tt::{History, BETA, MU, P_DRAW}; fn main() { let mut csv = csv::Reader::open("examples/atp.csv").unwrap(); let mut composition = Vec::new(); let mut results = Vec::new(); let mut times = Vec::new(); let time_format = time::format_description::parse("[year]-[month]-[day]").unwrap(); for row in csv.records() { if &row["double"] == "t" { composition.push(vec![ vec![row["w1_id"].to_string(), row["w2_id"].to_string()], vec![row["l1_id"].to_string(), row["l2_id"].to_string()], ]); } else { composition.push(vec![ vec![row["w1_id"].to_string()], vec![row["l1_id"].to_string()], ]); } results.push(vec![1, 0]); let time = Date::parse(&row["time_start"], &time_format) .unwrap() .midnight() .assume_utc() .unix_timestamp(); times.push(time as u64); } let mut h = History::new( composition, results, times, HashMap::new(), MU, 1.6, BETA, 0.036, P_DRAW, ); h.convergence(); /* composition, results, times, priors, MU, BETA, SIGMA, GAMMA, P_DRAW, */ /* let mut priors = HashMap::new(); for k in ["aj", "bj", "cj"] { let player = Player::new( Gaussian::new(25.0, 25.0 / 3.0), 25.0 / 6.0, 0.15 * 25.0 / 3.0, N_INF, ); priors.insert(k.to_string(), player); } let mut h1 = History::new( composition, results, times, priors, MU, BETA, SIGMA, GAMMA, P_DRAW, ); */ /* let columns = data .lines() .skip(1) .map(|line| { let columns = line.split(',').collect::>(); Column { w1_id: columns[3], w2_id: columns[3], l1_id: columns[3], l2_id: columns[3], double: columns[3], } }) .collect::>(); */ // match_id,double,round_number,w1_id,w1_name,w2_id,w2_name,l1_id,l1_name,l2_id,l2_name,time_start,time_end,ground,tour_id,tour_name // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /* import pandas as pd #sudo pip3 install trueskillthroughtime from trueskillthroughtime import * import time from datetime import datetime # Data df = pd.read_csv('input/history.csv', low_memory=False) columns = zip(df.w1_id, df.w2_id, df.l1_id, df.l2_id, df.double) composition = [[[w1,w2],[l1,l2]] if d == 't' else [[w1],[l1]] for w1, w2, l1, l2, d in columns ] times = [ datetime.strptime(t, "%Y-%m-%d").timestamp()/(60*60*24) for t in df.time_start] #start = time.time() h = History(composition = composition, times = times, sigma = 1.6, gamma = 0.036) h.convergence(epsilon=0.01, iterations=10) #end = time.time() #print(end-start) */ } mod csv { use std::fs::File; use std::io::{self, BufRead, BufReader, Lines}; use std::ops; use std::path::Path; pub struct Reader { header_map: Vec, lines: Lines>, } impl Reader { pub fn open>(path: P) -> Result { let mut lines = File::open(path).map(BufReader::new)?.lines(); let header_map = if let Some(header) = lines.next() { let header = header?; header.split(',').map(Into::into).collect::>() } else { Vec::new() }; Ok(Self { header_map, lines }) } pub fn records(&mut self) -> Records<'_> { Records { header_map: &self.header_map, lines: &mut self.lines, } } } pub struct Records<'a> { header_map: &'a Vec, lines: &'a mut Lines>, } impl<'a> Iterator for Records<'a> { type Item = Record<'a>; fn next(&mut self) -> Option { let line = self.lines.next()?; Some(Record { header_map: self.header_map, columns: line.unwrap().split(',').map(Into::into).collect::>(), }) } } pub struct Record<'a> { header_map: &'a Vec, columns: Vec, } impl<'a> ops::Index<&str> for Record<'a> { type Output = str; fn index(&self, index: &str) -> &Self::Output { &self.columns[self .header_map .iter() .position(|header| header == index) .unwrap()] } } }