Skip to content

Instantly share code, notes, and snippets.

@dennisjbell
Created September 16, 2020 00:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dennisjbell/3c7c99e441ea81087d56211cb558dde7 to your computer and use it in GitHub Desktop.
Save dennisjbell/3c7c99e441ea81087d56211cb558dde7 to your computer and use it in GitHub Desktop.
Breathe - calculate death in minutes for a given room dimension
#!/usr/bin/env perl
use List::Util qw/sum reduce/;
use Data::Dumper;
use Pry;
print STDERR "ERROR: Specify 3 dimensions of the room\n"
if (@ARGV != 3) || grep {$_ !~ /\d+(\.\d+)?/} @ARGV;
my @room_in_ft = @ARGV;
# @room_in_ft = (6,2.5,2.1); # Coffin less a 66l person
my $litre_per_cubic_foot = 28.31685;
my @components = qw/Nitrogen Oxygen Argon CarbonDioxide CarbonMonoxide Other/;
my %initial_concentrations = (
Nitrogen => 78.08400,
Oxygen => 20.94760,
Argon => 0.9340,
CarbonDioxide => 0.0314
); # https://www.thoughtco.com/chemical-composition-of-air-604288
# 12 - 20 per minute normal for average adult
#https://www.medicalnewstoday.com/articles/324409#adults
my $breath_rate = 16; # repetitions per minute
# https://www.reference.com/science/much-oxygen-inhale-exhale-b763252ad5727e56
my $breath_capacity = 8; # litres per minute
my $breath_convertion = 5; # percent of oxygen converted to CO2 and CO
# https://www.sciencedirect.com/science/article/pii/S0954611104000034
my $eCO_ppm = 5;
# Initialize
my $time = 0;
my %current_concentrations = (%initial_concentrations);
$current_concentrations{CarbonMonoxide} = 0;
$current_concentrations{Other} = 100 - sum(values(%current_concentrations));
my $volume = $litre_per_cubic_foot * reduce {$a * $b} @room_in_ft;
my $max_co2 = 4.0; # percent, or 40,000 ppm - https://www.cdc.gov/niosh/idlh/124389.html
my $max_co = 0.12; # percent, or 1200 ppm - https://www.cdc.gov/niosh/idlh/630080.html
# https://www.reference.com/science/much-oxygen-inhale-exhale-b763252ad5727e56
my $min_o2 = 6.0;
my $feel_o2 = 19.5;
sub breathe {
$air_in_lungs = inhale();
respire($air_in_lungs);
exhale($air_in_lungs);
}
sub inhale {
my $contents = {};
$contents->{$_} = ($breath_capacity/$breath_rate) * $current_concentrations{$_} / 100 for keys(%current_concentrations);
$volume = $volume - sum(values %$contents);
return $contents;
}
sub respire { # convert inhaled air to air that will be exhaled
my $contents = shift;
my $new_co = sum(values(%$contents)) * $eCO_ppm / 1000000;
my $used_o2 = sum(values(%$contents)) * $breath_convertion / 100 ;
$contents->{Oxygen} -= $used_o2;
$contents->{CarbonDioxide} += $used_o2 - $new_co;
$contents->{CarbonMonoxide} += $new_co;
}
sub exhale {
my $contents = shift;
my $air = {};
$air->{$_} = ($volume) * $current_concentrations{$_} / 100 + $contents->{$_} for keys(%current_concentrations);
$volume = sum(values(%$air));
$current_concentrations{$_} = ($air->{$_}/$volume*100) for keys(%current_concentrations);
printf "%s,%s,%s,%s,%s,%s,%s\n", $time, map {$current_concentrations{$_}} @components;
}
my %effects = ();
printf "Time,%s,%s,%s,%s,%s,%s\n", @components;
while ($time < 7*24*60 && keys(%effects) < 4) {
breathe();
$time += 1/$breath_rate;
if ($current_concentrations{Oxygen} < $feel_o2 && ! $effects{feeling_o2_depletion}) {
$effects{feeling_o2_depletion} = $time;
}
if ($current_concentrations{Oxygen} < $min_o2 && ! $effects{death_from_lack_o2}) {
$effects{death_from_lack_o2} = $time;
}
if ($current_concentrations{CarbonDioxide} > $max_co2 && ! $effects{death_from_co2}) {
$effects{death_from_co2} = $time;
}
if ($current_concentrations{CarbonMonoxide} > $max_co && ! $effects{death_from_co}) {
$effects{death_from_co} = $time;
}
}
print STDERR Dumper(\%effects);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment