File Coverage

blib/lib/Chemistry/PeriodicTable.pm
Criterion Covered Total %
statement 88 88 100.0
branch 17 20 85.0
condition 16 18 88.8
subroutine 15 15 100.0
pod 5 5 100.0
total 141 146 96.5


line stmt bran cond sub pod time code
1             package Chemistry::PeriodicTable;
2             our $AUTHORITY = 'cpan:GENE';
3              
4             # ABSTRACT: Provide access to chemical element properties
5              
6             our $VERSION = '0.0502';
7              
8 2     2   626920 use Moo;
  2         15482  
  2         9  
9 2     2   3242 use strictures 2;
  2         2618  
  2         77  
10 2     2   609 use Carp qw(croak);
  2         3  
  2         78  
11 2     2   995 use File::ShareDir qw(dist_dir);
  2         46838  
  2         123  
12 2     2   1126 use List::SomeUtils qw(first_index);
  2         26367  
  2         231  
13 2     2   2083 use Text::CSV_XS ();
  2         46306  
  2         99  
14 2     2   1046 use namespace::clean;
  2         22523  
  2         15  
15              
16              
17             has symbols => (is => 'lazy', init_args => undef);
18              
19             sub _build_symbols {
20 1     1   591 my ($self) = @_;
21              
22 1         3 my $file = $self->as_file;
23              
24 1         3 my %data;
25              
26 1         8 my $csv = Text::CSV_XS->new({ binary => 1 });
27              
28 1 50       127 open my $fh, '<', $file
29             or die "Can't read $file: $!";
30              
31 1         2 my $counter = 0;
32              
33 1         65 while (my $row = $csv->getline($fh)) {
34 119         131 $counter++;
35              
36             # skip the first row
37 119 100       167 next if $counter == 1;
38              
39 118         1459 $data{ $row->[2] } = $row;
40             }
41              
42 1         11 close $fh;
43              
44 1         41 return \%data;
45             }
46              
47              
48             has header => (is => 'lazy', init_args => undef);
49              
50             sub _build_header {
51 1     1   354 my ($self) = @_;
52              
53 1         3 my $file = $self->as_file;
54              
55 1         3 my @headers;
56              
57 1         33 my $csv = Text::CSV_XS->new({ binary => 1 });
58              
59 1 50       174 open my $fh, '<', $file
60             or die "Can't read $file: $!";
61              
62 1         66 while (my $row = $csv->getline($fh)) {
63 1         11 push @headers, @$row;
64 1         2 last;
65             }
66              
67 1         13 close $fh;
68              
69 1         18 return \@headers;
70             }
71              
72              
73             sub as_file {
74 3     3 1 1664 my ($self) = @_;
75              
76 3         5 my $file = eval { dist_dir('Chemistry-PeriodicTable') . '/Periodic-Table.csv' };
  3         24  
77 3 50 33     381 $file = 'share/Periodic-Table.csv'
78             unless $file && -e $file;
79              
80 3         7 return $file;
81             }
82              
83              
84             sub number {
85 2     2 1 578 my ($self, $string) = @_;
86 2         3 my $n;
87             # looking for a symbol
88 2 100       5 if (length $string < 4) {
89 1         25 $n = $self->symbols->{ ucfirst $string }[0];
90             }
91             # looking for an element name
92             else {
93 1         2 for my $symbol (keys %{ $self->symbols }) {
  1         21  
94 48 100       609 if (lc $self->symbols->{$symbol}[1] eq lc $string) {
95 1         14 $n = $self->symbols->{$symbol}[0];
96 1         6 last;
97             }
98             }
99             }
100 2         18 return $n;
101             }
102              
103              
104             sub name {
105 2     2 1 6 my ($self, $string) = @_;
106 2         3 my $n;
107 2         2 for my $symbol (keys %{ $self->symbols }) {
  2         37  
108 96 100 100     1887 if (
      100        
109             ($string =~ /^\d+$/ && $self->symbols->{$symbol}[0] == $string)
110             ||
111             (lc $self->symbols->{$symbol}[2] eq lc $string)
112             ) {
113 2         48 $n = $self->symbols->{$symbol}[1];
114 2         11 last;
115             }
116             }
117 2         15 return $n;
118             }
119              
120              
121             sub symbol {
122 4     4 1 8 my ($self, $string) = @_;
123 4         6 my $s;
124 4         4 for my $symbol (keys %{ $self->symbols }) {
  4         62  
125 183 100 100     3576 if (
      100        
126             ($string =~ /^\d+$/ && $self->symbols->{$symbol}[0] == $string)
127             ||
128             (lc $self->symbols->{$symbol}[1] eq lc $string)
129             ) {
130 4         21 $s = $symbol;
131 4         7 last;
132             }
133             }
134 4         26 return $s;
135             }
136              
137              
138             sub value {
139 3     3 1 9 my ($self, $key, $string) = @_;
140 3         10 my $v;
141 3     19   9 my $idx = first_index { $_ =~ /$string/i } @{ $self->header };
  19         70  
  3         56  
142 3 100 100     23 if ($key !~ /^\d+$/ && length $key < 4) {
143 1         14 $v = $self->symbols->{$key}[$idx];
144             }
145             else {
146 2         5 $key = $self->symbol($key);
147 2         5 for my $symbol (keys %{ $self->symbols }) {
  2         23  
148 87 100       136 next unless $symbol eq $key;
149 2         22 $v = $self->symbols->{$symbol}[$idx];
150 2         10 last;
151             }
152             }
153 3         22 return $v;
154             }
155              
156             1;
157              
158             __END__