Compare commits
No commits in common. "main" and "v0.1.2" have entirely different histories.
2 changed files with 18 additions and 36 deletions
|
|
@ -1,9 +1,9 @@
|
||||||
# smogon stats
|
# smogon stats
|
||||||
turn <https://smogon.com/stats/> chaos json files into [SQLite](https://sqlite.org) databases
|
turn <https://smogon.com/stats/> chaos json files into [SQLite](https://sqlite.org) databases
|
||||||
|
|
||||||
you can find pre-generated dbs at <https://pyrope.net/mon/stats>, and you can [fiddle](https://sqlite.org/fiddle) with them in your browser or on your own computer.
|
you can find pre-generated dbs at <https://pyrope.net/mon/stats> (currently only 2025-02), and you can [fiddle](https://sqlite.org/fiddle) with them in your browser or on your own computer.
|
||||||
|
|
||||||
## examples (2025-02)
|
## examples
|
||||||
```sh
|
```sh
|
||||||
smogon-stats gen9ou-1500.json -o gen9ou-1500.sqlite
|
smogon-stats gen9ou-1500.json -o gen9ou-1500.sqlite
|
||||||
sqlite3 gen9ou-1500.sqlite -markdown "SELECT name, format('%.2f%%', usage * 100) as usage FROM mon WHERE mon.usage > 0.04 ORDER BY mon.usage DESC LIMIT 10"
|
sqlite3 gen9ou-1500.sqlite -markdown "SELECT name, format('%.2f%%', usage * 100) as usage FROM mon WHERE mon.usage > 0.04 ORDER BY mon.usage DESC LIMIT 10"
|
||||||
|
|
|
||||||
50
src/main.rs
50
src/main.rs
|
|
@ -17,7 +17,7 @@ fn main() {
|
||||||
if let Err(e) = run(config) {
|
if let Err(e) = run(config) {
|
||||||
log::error!("{e}");
|
log::error!("{e}");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
|
|
@ -27,10 +27,7 @@ fn run(
|
||||||
}: Config,
|
}: Config,
|
||||||
) -> Result<(), AppError> {
|
) -> Result<(), AppError> {
|
||||||
if fs::exists(&output_file)? {
|
if fs::exists(&output_file)? {
|
||||||
log::warn!(
|
log::warn!("{output_file:?} already exists: creating the db will probably fail");
|
||||||
"{} already exists: creating the db will probably fail",
|
|
||||||
output_file.display()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsing the stats is slow but doing it first avoids creating empty tables
|
// parsing the stats is slow but doing it first avoids creating empty tables
|
||||||
|
|
@ -55,7 +52,7 @@ fn run(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(clap::Parser)]
|
#[derive(clap::Parser)]
|
||||||
#[command(version, about)]
|
#[command(about)]
|
||||||
struct Config {
|
struct Config {
|
||||||
#[arg()]
|
#[arg()]
|
||||||
input_file: PathBuf,
|
input_file: PathBuf,
|
||||||
|
|
@ -83,47 +80,41 @@ fn create_tables(conn: &mut Connection) -> rusqlite::Result<()> {
|
||||||
"
|
"
|
||||||
BEGIN;
|
BEGIN;
|
||||||
CREATE TABLE mon (
|
CREATE TABLE mon (
|
||||||
name TEXT NOT NULL,
|
name STRING NOT NULL,
|
||||||
usage REAL,
|
usage REAL,
|
||||||
viability_ceiling REAL
|
viability_ceiling REAL
|
||||||
);
|
);
|
||||||
CREATE TABLE ability (
|
CREATE TABLE ability (
|
||||||
mon TEXT NOT NULL,
|
mon STRING NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name STRING NOT NULL,
|
||||||
usage REAL NOT NULL
|
usage REAL NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE move (
|
CREATE TABLE move (
|
||||||
mon TEXT NOT NULL,
|
mon STRING NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name STRING NOT NULL,
|
||||||
usage REAL NOT NULL
|
usage REAL NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE item (
|
CREATE TABLE item (
|
||||||
mon TEXT NOT NULL,
|
mon STRING NOT NULL,
|
||||||
name TEXT NOT NULL,
|
name STRING NOT NULL,
|
||||||
usage REAL NOT NULL
|
usage REAL NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE tera (
|
CREATE TABLE tera (
|
||||||
mon TEXT NOT NULL,
|
mon STRING NOT NULL,
|
||||||
type TEXT NOT NULL,
|
type STRING NOT NULL,
|
||||||
usage REAL NOT NULL
|
usage REAL NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE team (
|
CREATE TABLE team (
|
||||||
mon TEXT NOT NULL,
|
mon STRING NOT NULL,
|
||||||
mate TEXT NOT NULL,
|
mate STRING NOT NULL,
|
||||||
usage REAL NOT NULL
|
usage REAL NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE cc (
|
CREATE TABLE cc (
|
||||||
mon TEXT NOT NULL,
|
mon STRING NOT NULL,
|
||||||
opp TEXT NOT NULL,
|
opp STRING NOT NULL,
|
||||||
percentage REAL NOT NULL,
|
percentage REAL NOT NULL,
|
||||||
stddev REAL NOT NULL
|
stddev REAL NOT NULL
|
||||||
);
|
);
|
||||||
CREATE TABLE spread (
|
|
||||||
mon TEXT NOT NULL,
|
|
||||||
nature TEXT NOT NULL,
|
|
||||||
evs TEXT NOT NULL,
|
|
||||||
usage REAL NOT NULL
|
|
||||||
);
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
|
|
@ -204,14 +195,6 @@ fn insert_stats(conn: &mut Connection, stats: &Stats) -> rusqlite::Result<()> {
|
||||||
(mon, opp, percentage, stddev),
|
(mon, opp, percentage, stddev),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (spread, usage) in &data.spreads {
|
|
||||||
let (nature, evs) = spread.split_once(':').unwrap();
|
|
||||||
tx.execute(
|
|
||||||
"INSERT INTO spread VALUES (?1, ?2, ?3, ?4)",
|
|
||||||
(mon, nature, evs, usage / mon_count),
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tx.commit()?;
|
tx.commit()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -275,5 +258,4 @@ struct Data {
|
||||||
checks_and_counters: HashMap<Box<str>, (f32, f32, f32)>,
|
checks_and_counters: HashMap<Box<str>, (f32, f32, f32)>,
|
||||||
#[serde(rename = "usage")]
|
#[serde(rename = "usage")]
|
||||||
usage: Option<f32>,
|
usage: Option<f32>,
|
||||||
spreads: Counts,
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue