Skip to content

Commit

Permalink
Minor improvements (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecardleitao authored Dec 6, 2023
1 parent 535540c commit 804546c
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 75 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ geoutils = {version="*", default_features = false}
# read airport names
csv = {version="*", default_features = false}

#
# async utilities
async-trait = "*"
async-recursion = "1.0"
futures = "0.3"

# logging
log = "*"
Expand All @@ -35,12 +37,11 @@ log = "*"
azure_storage = "*"
azure_storage_blobs = "*"
azure_core = "*"
futures = "0.3"
bytes = "1.5"
async-recursion = "1.0"

[dev-dependencies]
tinytemplate = "1.1"
clap = { version = "4.4.6", features = ["derive"] }
tokio = {version="1.0", features=["rt", "macros", "rt-multi-thread"]}
simple_logger = "*"
num-format = "*"
24 changes: 13 additions & 11 deletions examples/dk_jets.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Use of Danish private jets

{from_date} to {to_date}, Danish private jets emitted
{emissions_tons.claim} tons of CO2e[^5], the equivalent of what **{dane_years.claim} Danes**
emit in a year[^4].
{from_date} to {to_date}, all Danish private jets emitted
{emissions_tons.claim} tons of CO2e[^1], or what **{dane_years.claim} Danes** emit in a year[^2].
{number_of_private_jets.claim} private jets alone[^3] jeopardize the efforts of millions
of Danes that every day act to reduce their emissions.

Of these,
* {number_of_legs_less_300km} trips were less than 300 km and could have been replaced by
Expand All @@ -11,14 +12,15 @@ Of these,
a first class ticket on a commercial aircraft, which would have emitted
~{ratio_commercial_300km}x less CO2[^5].

Billionaires and companies alike are incapable of regulating their emissions,
recklessly destroying the common good.
Ban private jets now and until they emit what equivalent means of transportation would emit.
The use of private jets by billionaires and large companies alike is an insult
to Danes and Danish companies alike that are doing everything they can to
keep for our future.

## References
> Ban private jets _now_
[^2]: {number_of_legs.source} - retrieved on {number_of_legs.date}
[^4]: {dane_years.source} - retrieved on {dane_years.date}
[^5]: {emissions_tons.source} - retrieved on {emissions_tons.date}
## References

Copyright Jorge Leitão, released under [CC0](https://creativecommons.org/public-domain/cc0/) - No Rights Reserved.
[^1]: {emissions_tons.source}, in {number_of_legs.claim} trips[^4] - retrieved on {emissions_tons.date}
[^2]: {dane_years.source} - retrieved on {dane_years.date}
[^3]: {number_of_private_jets.source} on {number_of_private_jets.date}
[^4]: {number_of_legs.source} - retrieved on {number_of_legs.date}
131 changes: 71 additions & 60 deletions examples/dk_jets.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::{collections::HashMap, error::Error, sync::Arc};
use std::{collections::HashMap, error::Error};

use clap::Parser;
use futures::{StreamExt, TryStreamExt};
use num_format::{Locale, ToFormattedString};
use simple_logger::SimpleLogger;

use flights::{emissions, load_aircraft_types, load_aircrafts, Class, Fact, Position};
use time::macros::date;
use flights::{emissions, load_aircraft_types, load_aircrafts, Aircraft, Class, Fact, Leg};
use time::{macros::date, Date};

fn render(context: &Context) -> Result<(), Box<dyn Error>> {
let path = "all_dk_jets.md";
Expand All @@ -27,11 +28,12 @@ fn render(context: &Context) -> Result<(), Box<dyn Error>> {
pub struct Context {
pub from_date: String,
pub to_date: String,
pub number_of_legs: Fact<usize>,
pub emissions_tons: Fact<usize>,
pub number_of_private_jets: Fact<String>,
pub number_of_legs: Fact<String>,
pub emissions_tons: Fact<String>,
pub dane_years: Fact<String>,
pub number_of_legs_less_300km: usize,
pub number_of_legs_more_300km: usize,
pub number_of_legs_less_300km: String,
pub number_of_legs_more_300km: String,
pub ratio_commercial_300km: String,
}

Expand All @@ -51,6 +53,35 @@ struct Cli {
backend: Backend,
}

async fn legs(
from: Date,
to: Date,
aircraft: &Aircraft,
client: Option<&flights::fs_azure::ContainerClient>,
) -> Result<Vec<Leg>, Box<dyn Error>> {
let dates = flights::DateIter {
from,
to,
increment: time::Duration::days(1),
};

let tasks = dates.map(|date| async move {
Result::<_, Box<dyn Error>>::Ok(
flights::positions(&aircraft.icao_number, date, 1000.0, client)
.await?
.collect::<Vec<_>>(),
)
});

let positions = futures::stream::iter(tasks)
// limit concurrent tasks
.buffered(50)
.try_collect::<Vec<_>>()
.await?;

Ok(flights::real_legs(positions.into_iter().flatten()))
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
SimpleLogger::new()
Expand Down Expand Up @@ -78,70 +109,50 @@ async fn main() -> Result<(), Box<dyn Error>> {
let aircrafts = load_aircrafts(client.as_ref()).await?;
let types = load_aircraft_types()?;

let dk_private_jets = aircrafts
let private_jets = aircrafts
.into_iter()
// is private jet
.filter(|(_, a)| types.contains_key(&a.model))
// is from DK
.filter(|(a, _)| a.starts_with("OY-"))
.collect::<HashMap<_, _>>();

let number_of_private_jets = Fact {
claim: private_jets.len().to_formatted_string(&Locale::en),
source: format!(
"All aircrafts in [adsbexchange.com](https://globe.adsbexchange.com) whose model is a private jet and tail number starts with \"OY-\""
),
date: "2023-11-06".to_string(),
};

let to = time::OffsetDateTime::now_utc().date() - time::Duration::days(1);
let from = date!(2021 - 01 - 01);

let from_date = from.to_string();
let to_date = to.to_string();

let dates = flights::DateIter {
from,
to,
increment: time::Duration::days(1),
};

let iter = dates
.map(|date| {
let client = client.as_ref();
dk_private_jets
.iter()
.map(move |(_, a)| flights::positions(&a.icao_number, date.clone(), 1000.0, client))
})
.flatten();

let positions = futures::stream::iter(iter)
// limit to 5 concurrent tasks
.buffer_unordered(100)
.try_collect::<Vec<_>>()
.await?;
let positions = positions.into_iter().flatten().collect::<Vec<_>>();

// group by aircraft
let mut positions = positions.into_iter().fold(
HashMap::<Arc<str>, Vec<Position>>::default(),
|mut acc, v| {
acc.entry(v.icao().clone())
.and_modify(|positions| positions.push(v.clone()))
.or_insert_with(|| vec![v]);
acc
},
);
// sort positions by datetime
positions.iter_mut().for_each(|(_, positions)| {
positions.sort_unstable_by_key(|x| x.datetime());
let client = client.as_ref();
let legs = private_jets.iter().map(|(_, aircraft)| async {
legs(from, to, aircraft, client)
.await
.map(|legs| (aircraft.icao_number.clone(), legs))
});

// compute legs
let legs = positions
.into_iter()
.map(|(icao, positions)| (icao, flights::real_legs(positions.into_iter())))
.collect::<HashMap<_, _>>();
let legs = futures::future::join_all(legs).await;
let legs = legs.into_iter().collect::<Result<HashMap<_, _>, _>>()?;

let number_of_legs = Fact {
claim: legs.iter().map(|(_, legs)| legs.len()).sum::<usize>(),
source: format!("[adsbexchange.com](https://globe.adsbexchange.com) between {from_date} and {to_date} and all aircraft whose tail number starts with \"OY-\" and model is a private jet"),
date: to.to_string()
claim: legs
.iter()
.map(|(_, legs)| legs.len())
.sum::<usize>()
.to_formatted_string(&Locale::en),
source: format!(
"[adsbexchange.com](https://globe.adsbexchange.com) between {from_date} and {to_date}"
),
date: to.to_string(),
};

let commercial_to_private_ratio = 10.0;
let commercial_emissions_tons = legs
.iter()
.map(|(_, legs)| {
Expand All @@ -150,8 +161,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
.sum::<f64>()
})
.sum::<f64>();
let commercial_to_private_ratio = 10.0;
let emissions_tons_value = commercial_emissions_tons * commercial_to_private_ratio;
let emissions_tons = Fact {
claim: (commercial_emissions_tons * commercial_to_private_ratio) as usize,
claim: (emissions_tons_value as usize).to_formatted_string(&Locale::en),
source: format!("Commercial flights would have emitted {commercial_emissions_tons:.1} tons of CO2e (based on [myclimate.org](https://www.myclimate.org/en/information/about-myclimate/downloads/flight-emission-calculator/) - retrieved on 2023-10-19). Private jets emit 5-14x times. 10x was used based on [transportenvironment.org](https://www.transportenvironment.org/discover/private-jets-can-the-super-rich-supercharge-zero-emission-aviation/)"),
date: "2023-10-05, from 2021-05-27".to_string(),
};
Expand All @@ -171,24 +184,22 @@ async fn main() -> Result<(), Box<dyn Error>> {
date: "2023-10-08".to_string(),
};

let dane_years = format!(
"{:.0}",
emissions_tons.claim as f32 / dane_emissions_tons.claim as f32
);
let dane_years = (emissions_tons_value / dane_emissions_tons.claim) as usize;
let dane_years = Fact {
claim: dane_years,
claim: dane_years.to_formatted_string(&Locale::en),
source: "https://ourworldindata.org/co2/country/denmark Denmark emits 5.1 t CO2/person/year in 2019.".to_string(),
date: "2023-10-08".to_string(),
};

let context = Context {
from_date,
to_date,
number_of_private_jets,
number_of_legs,
emissions_tons,
dane_years,
number_of_legs_less_300km: short_legs,
number_of_legs_more_300km: long_legs,
number_of_legs_less_300km: short_legs.to_formatted_string(&Locale::en),
number_of_legs_more_300km: long_legs.to_formatted_string(&Locale::en),
ratio_commercial_300km: format!("{:.0}", commercial_to_private_ratio),
};

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ fn distance(from: (f64, f64), to: (f64, f64)) -> f64 {
}

/// An iterator between two [`time::Date`]s in increments
#[derive(Clone, Copy)]
pub struct DateIter {
pub from: time::Date,
pub to: time::Date,
Expand Down
1 change: 0 additions & 1 deletion src/types.csv
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ FA8X Dassault Falcon 8X https://www.dassaultfalcon.com/aircraft/overview-of-the-
F900 Dassault Falcon 900 https://www.dassaultfalcon.com/aircraft/overview-of-the-fleet/ 2023-10-03
EA40 Eclipse 400 https://en.wikipedia.org/wiki/Eclipse_400 2023-10-03
EA50 Eclipse 500 https://en.wikipedia.org/wiki/Eclipse_500 2023-10-03
E190 Embraer Lineage 1000 https://executive.embraer.com/global/en/lineage-1000e 2023-10-03
E50P Embraer Phenom 100 https://executive.embraer.com/global/en/phenom-100ev 2023-10-03
E55P Embraer Phenom 300 https://executive.embraer.com/global/en/phenom-300e 2023-10-03
GL5T Global 5500 https://businessaircraft.bombardier.com/en/aircraft/global-5500 2023-10-03
Expand Down

0 comments on commit 804546c

Please sign in to comment.