2014-11-27 23:02:08 -08:00
|
|
|
|
package DDG::Goodie::PeriodicTable;
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# ABSTRACT: Chemical symbols, atomic masses and numbers for chemical elements
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
2015-02-22 12:09:29 -08:00
|
|
|
|
use strict;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
use DDG::Goodie;
|
|
|
|
|
use YAML::XS qw(Load);
|
2015-01-03 20:59:13 -08:00
|
|
|
|
use List::Util qw(first);
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
zci answer_type => 'periodic_table';
|
|
|
|
|
zci is_cached => 1;
|
|
|
|
|
|
|
|
|
|
name 'Periodic Table';
|
2015-04-23 06:59:01 -07:00
|
|
|
|
description 'Chemical symbols, atomic masses and numbers for chemical elements';
|
|
|
|
|
primary_example_queries 'rubidium', 'chemical symbol for argon', 'atomic mass of nitrogen', 'atomic number of oxygen';
|
|
|
|
|
secondary_example_queries 'atomic weight of Na', 'what is the chemical symbol for argon', 'chemical name for He';
|
2014-11-27 23:02:08 -08:00
|
|
|
|
category 'physical_properties';
|
|
|
|
|
topics 'science';
|
|
|
|
|
code_url 'https://github.com/duckduckgo/zeroclickinfo-goodies/blob/master/lib/DDG/Goodie/PeriodicTable.pm';
|
2015-04-23 06:59:01 -07:00
|
|
|
|
attribution github => [ 'zblair', 'Zachary D Blair' ],
|
2015-04-23 07:07:12 -07:00
|
|
|
|
github => ['skywickenden', 'Sky Wickenden'];
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
my @elements = @{ Load( scalar share('elements.yml')->slurp ) };
|
|
|
|
|
|
|
|
|
|
# Triggers
|
2015-04-23 06:59:01 -07:00
|
|
|
|
my @element_triggers = [map { lc($_->[2]) } @elements];
|
|
|
|
|
triggers start => $element_triggers[0];
|
|
|
|
|
triggers any => 'atomic mass', 'atomic weight', 'atomic number', 'proton number', 'chemical symbol', 'chemical name for';
|
|
|
|
|
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
# Handle statement
|
|
|
|
|
handle query_lc => sub {
|
|
|
|
|
|
|
|
|
|
my $query = $_;
|
|
|
|
|
|
|
|
|
|
# Determine if this is a query for atomic mass or atomic number
|
|
|
|
|
my $is_mass_query = $query =~ /atomic mass|atomic weight/;
|
2015-04-23 06:59:01 -07:00
|
|
|
|
my $is_atomic_query = $query =~ /atomic number|proton number/;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
|
|
|
|
# Strip out irrelevant words in the query
|
2015-04-23 06:59:01 -07:00
|
|
|
|
$query =~ s/(?:atomic (?:mass|weight|number)|proton number|of|the|for|element|elemental|chemical symbol|what is|chemical name for)//g;
|
2014-11-27 23:02:08 -08:00
|
|
|
|
$query =~ s/^\s+|\s+$//g;
|
|
|
|
|
return unless $query;
|
|
|
|
|
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# Look for a matching element or symbol in the table
|
2015-01-03 20:59:13 -08:00
|
|
|
|
my $match = first { lc $_->[2] eq $query || lc $_->[3] eq $query } @elements or return;
|
2015-04-23 06:59:01 -07:00
|
|
|
|
my ( $atomic_number, $atomic_mass, $element_name, $element_symbol, $element_type ) = @{$match};
|
2014-11-27 23:02:08 -08:00
|
|
|
|
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# Default to displaying chemical symbol info.
|
|
|
|
|
my $title = $element_name;
|
|
|
|
|
my $subtitle = "Atomic number $atomic_number. Atomic mass $atomic_mass u.";
|
|
|
|
|
my $raw = "$element_symbol, chemical symbol for " . lc($element_name);
|
2014-11-27 23:02:08 -08:00
|
|
|
|
if ($is_mass_query) {
|
2015-04-23 06:59:01 -07:00
|
|
|
|
$title = "$atomic_mass u";
|
|
|
|
|
$subtitle = "$element_name - atomic mass";
|
|
|
|
|
$raw = "$element_name ($element_symbol), atomic mass $atomic_mass u"
|
2014-11-27 23:02:08 -08:00
|
|
|
|
}
|
2015-04-23 06:59:01 -07:00
|
|
|
|
elsif ($is_atomic_query) {
|
|
|
|
|
$title = "$atomic_number";
|
|
|
|
|
$subtitle = "$element_name - atomic number";
|
|
|
|
|
$raw = "$element_name ($element_symbol), atomic number $atomic_number"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $raw,
|
|
|
|
|
structured_answer => {
|
|
|
|
|
id => "periodic_table",
|
|
|
|
|
name => "Periodic Table",
|
|
|
|
|
data => {
|
|
|
|
|
badge => $element_symbol,
|
|
|
|
|
title => $title,
|
|
|
|
|
subtitle => $subtitle,
|
|
|
|
|
description => ""
|
|
|
|
|
},
|
|
|
|
|
templates => {
|
|
|
|
|
group => "icon",
|
|
|
|
|
elClass => {
|
|
|
|
|
bgColor => get_badge_color($element_type),
|
|
|
|
|
iconBadge => "tx-clr-white"
|
|
|
|
|
},
|
|
|
|
|
variants => {
|
|
|
|
|
iconBadge => "medium"
|
|
|
|
|
},
|
|
|
|
|
options => {
|
|
|
|
|
moreAt => 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-11-27 23:02:08 -08:00
|
|
|
|
};
|
|
|
|
|
|
2015-04-23 06:59:01 -07:00
|
|
|
|
# Decide on a color to use when displaying the element badge based on its group.
|
|
|
|
|
sub get_badge_color {
|
|
|
|
|
my ($element_type) = @_;
|
|
|
|
|
|
|
|
|
|
# metmetal–metalloid–nonmetal etc is currently split into only 5 color groups.
|
|
|
|
|
# https://github.com/duckduckgo/zeroclickinfo-goodies/issues/927
|
|
|
|
|
my $badge_color = "bg-clr--red";
|
|
|
|
|
if ($element_type eq "Alkali metal") { $badge_color = "bg-clr--gold" }
|
|
|
|
|
elsif ($element_type eq "Alkaline earth metal") { $badge_color = "bg-clr--gold" }
|
|
|
|
|
elsif ($element_type eq "Lanthanide") { $badge_color = "bg-clr--red" }
|
|
|
|
|
elsif ($element_type eq "Actinide") { $badge_color = "bg-clr--red" }
|
|
|
|
|
elsif ($element_type eq "Transition metal") { $badge_color = "bg-clr--red" }
|
|
|
|
|
elsif ($element_type eq "Post-transition metal") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Metalloid") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Polyatomic nonmetal") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Diatomic nonmetal") { $badge_color = "bg-clr--green" }
|
|
|
|
|
elsif ($element_type eq "Noble gas") { $badge_color = "bg-clr--blue-light" }
|
|
|
|
|
elsif ($element_type eq "Unknown") { $badge_color = "bg-clr--red" }
|
|
|
|
|
|
|
|
|
|
return $badge_color;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-27 23:02:08 -08:00
|
|
|
|
1;
|