📄 aggregates.pm
字号:
return $c;
}
sub code_output
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
my $if = $self->output_field()->input_field()->getvar();
$self->hash() eq ''
? $c->code("\$MEDIAN_COUNT_$of++ ")
: $c->code("\${\$MEDIAN_COUNT_$of}++ "); # hash
$c->over();
$c->code("if (++\$MEDIAN_$of\{qq{$if}} == 1);@{[ $self->prinfo() ]}");
$c->back();
return $c;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Aggregates::Variance;
use base qw(ETL::Pequel3::Type::Aggregates::Abstract);
use Class::STL::ClassMembers
Class::STL::ClassMembers::DataMember->new(name => 'name', default => 'variance'),
Class::STL::ClassMembers::DataMember->new(name => 'valid_types', default => 'amount|numeric|date'),
Class::STL::ClassMembers::DataMember->new(name => 'description', default => 'Output ( sum squares / count ) - ( mean ** 2); sum_squares is each value in the distribution squared (** 2); count is the number of values in the distribution.');
use Class::STL::ClassMembers::Constructor;
sub code_init
{
my $self = shift;
my $c = shift || ETL::CodeStyler::Program::Perl->new();
$c->code("my \%VARIANCE_@{[ $self->output_field()->name() ]};@{[ $self->prinfo() ]}");
return $c;
}
sub code_reset
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
$c->code("\%VARIANCE_@{[ $self->output_field()->name() ]} = ();@{[ $self->prinfo() ]}");
return $c;
}
sub code_output_final
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
$c->code("@{[ $self->output_field()->getvar() ]} = ");
$c->over();
$c->open_block("(");
$c->open_block("(");
$c->code("\$VARIANCE_$of\{_SUM_SQUARES}");
$c->code("/ (\$VARIANCE_$of\{_COUNT} == 0 ? 1 : \$VARIANCE_$of\{_COUNT})");
$c->close_block();
$c->code("-");
$c->open_block("(");
$c->open_block("(");
$c->code("\$VARIANCE_$of\{_SUM}");
$c->code("/ (\$VARIANCE_$of\{_COUNT} == 0 ? 1 : \$VARIANCE_$of\{_COUNT})");
$c->close_block();
$c->code("** 2");
$c->close_block();
$c->close_block();
$c->code(";@{[ $self->prinfo() ]}");
$c->back();
return $c;
}
sub code_output
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
my $if = $self->output_field()->input_field()->getvar();
$c->code("\$VARIANCE_$of\{_SUM} += $if;@{[ $self->prinfo() ]}");
$c->code("\$VARIANCE_$of\{_SUM_SQUARES} += $if ** 2;@{[ $self->prinfo() ]}");
$c->code("\$VARIANCE_$of\{_COUNT}++;@{[ $self->prinfo() ]}");
return $c;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Aggregates::Stddev;
use base qw(ETL::Pequel3::Type::Aggregates::Abstract);
use Class::STL::ClassMembers
Class::STL::ClassMembers::DataMember->new(name => 'name', default => 'stddev'),
Class::STL::ClassMembers::DataMember->new(name => 'valid_types', default => 'amount|numeric|date'),
Class::STL::ClassMembers::DataMember->new(name => 'description', default => 'Output the square-root of variance.');
use Class::STL::ClassMembers::Constructor;
sub code_init
{
my $self = shift;
my $c = shift || ETL::CodeStyler::Program::Perl->new();
$c->code("my \%STDDEV_@{[ $self->output_field()->name() ]};@{[ $self->prinfo() ]}");
return $c;
}
sub code_reset
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
$c->code("\%STDDEV_@{[ $self->output_field()->name() ]} = ();@{[ $self->prinfo() ]}");
return $c;
}
sub code_output_final
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
$c->code("@{[ $self->output_field()->getvar() ]} = ");
$c->over();
$c->code("sqrt");
$c->open_block("(");
$c->open_block("(");
$c->code("\$STDDEV_$of\{_SUM_SQUARES}");
$c->code("/ (\$STDDEV_$of\{_COUNT} == 0 ? 1 : \$STDDEV_$of\{_COUNT})");
$c->close_block();
$c->code("-");
$c->open_block("(");
$c->open_block("(");
$c->code("\$STDDEV_$of\{_SUM}");
$c->code("/ (\$STDDEV_$of\{_COUNT} == 0 ? 1 : \$STDDEV_$of\{_COUNT})");
$c->close_block();
$c->code("** 2");
$c->close_block();
$c->close_block();
$c->code(";@{[ $self->prinfo() ]}");
$c->back();
return $c;
}
sub code_output
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
my $if = $self->output_field()->input_field()->getvar();
$c->code("\$STDDEV_$of\{_SUM} += $if;@{[ $self->prinfo() ]}");
$c->code("\$STDDEV_$of\{_SUM_SQUARES} += $if ** 2;@{[ $self->prinfo() ]}");
$c->code("\$STDDEV_$of\{_COUNT}++;@{[ $self->prinfo() ]}");
return $c;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Aggregates::Range;
use base qw(ETL::Pequel3::Type::Aggregates::Abstract);
use Class::STL::ClassMembers
Class::STL::ClassMembers::DataMember->new(name => 'name', default => 'range'),
Class::STL::ClassMembers::DataMember->new(name => 'valid_types', default => 'amount|numeric|date'),
Class::STL::ClassMembers::DataMember->new(name => 'description', default => 'Output the maximum value minus the minimum value in a distribution.');
use Class::STL::ClassMembers::Constructor;
sub code_init
{
my $self = shift;
my $c = shift || ETL::CodeStyler::Program::Perl->new();
$c->code("my \%RANGE_@{[ $self->output_field()->name() ]};@{[ $self->prinfo() ]}");
return $c;
}
sub code_reset
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
$c->code("\%RANGE_@{[ $self->output_field()->name() ]} = ();@{[ $self->prinfo() ]}");
return $c;
}
sub code_output_final
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
$c->code("@{[ $self->output_field()->getvar() ]} =");
$c->over();
$c->code("\$RANGE_$of\{_MAX}");
$c->code("- \$RANGE_$of\{_MIN}");
$c->code(";@{[ $self->prinfo() ]}");
$c->back();
return $c;
}
sub code_output
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
my $if = $self->output_field()->input_field()->getvar();
$c->code("\$RANGE_$of\{_MIN} = $if");
$c->over();
$c->code("if");
$c->open_block("(");
$c->code("!defined(\$RANGE_$of\{_MIN})");
$c->code("||");
$c->open_block("(");
$c->code("defined($if)");
$c->code("&& $if < \$RANGE_$of\{_MIN}");
$c->close_block();
$c->close_block();
$c->code(";@{[ $self->prinfo() ]}");
$c->back();
$c->code("\$RANGE_$of\{_MAX} = $if");
$c->over();
$c->code("if");
$c->open_block("(");
$c->code("!defined(\$RANGE_$of\{_MAX})");
$c->code("||");
$c->open_block("(");
$c->code("defined($if)");
$c->code("&& $if > \$RANGE_$of\{_MAX}");
$c->close_block();
$c->close_block();
$c->code(";@{[ $self->prinfo() ]}");
$c->back();
return $c;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Aggregates::Mode;
use base qw(ETL::Pequel3::Type::Aggregates::Abstract);
use Class::STL::ClassMembers
Class::STL::ClassMembers::DataMember->new(name => 'name', default => 'mode'),
Class::STL::ClassMembers::DataMember->new(name => 'description', default => 'Output the most frequently occuring score or scores (space delimited) in a distribution.');
use Class::STL::ClassMembers::Constructor;
sub code_init
{
my $self = shift;
my $c = shift || ETL::CodeStyler::Program::Perl->new();
$c->code("my \%MODE_@{[ $self->output_field()->name() ]};@{[ $self->prinfo() ]}");
return $c;
}
sub code_reset
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
$c->code("\%MODE_@{[ $self->output_field()->name() ]} = ();@{[ $self->prinfo() ]}");
return $c;
}
sub code_output_final
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
my $keys = $self->hash() eq '' ? "keys \%MODE_$of" : "keys \%{\$MODE_$of}";
$c->code("@{[ $self->output_field()->getvar() ]} = ");
$c->over();
$c->code("join");
$c->open_block("(");
$c->code("' ',");
$c->code("&");
$c->open_block();
$c->code("sub");
$c->open_block();
$c->code("my \@top;");
$c->code("foreach my \$k");
$c->open_block("(");
$c->code("sort");
$c->open_block("{");
$c->code("\$MODE_$of\{\$b} <=> \$MODE_$of\{\$a}");
$c->close_block();
$c->code("$keys");
$c->close_block();
$c->open_block();
$c->code("last if (\$MODE_$of\{\$k} != \$MODE_$of\{\$_[0]});");
$c->code("push(\@top, \$k);");
$c->close_block();
$c->code("\@top;");
$c->close_block();
$c->close_block();
$c->open_block("(");
$c->open_block("(");
$c->code("sort");
$c->open_block("{");
$c->code("\$MODE_$of\{\$b} <=> \$MODE_$of\{\$a}");
$c->close_block();
$c->code("$keys");
$c->close_block();
$c->code("[0]");
$c->close_block();
$c->close_block();
$c->code(";@{[ $self->prinfo() ]}");
$c->back();
return $c;
}
sub code_output
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
my $of = "@{[ $self->output_field()->name() ]}@{[ $self->hash() ]}";
my $if = $self->output_field()->input_field()->getvar();
$c->code("\$MODE_$of\{qq{$if}}++;@{[ $self->prinfo() ]}");
return $c;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Aggregates::Serial;
use base qw(ETL::Pequel3::Type::Aggregates::Abstract);
use Class::STL::ClassMembers
Class::STL::ClassMembers::DataMember->new(name => 'name', default => 'serial'),
Class::STL::ClassMembers::DataMember->new(name => 'require_input_field', default => 0),
Class::STL::ClassMembers::DataMember->new(name => 'valid_types', default => 'amount|numeric'), #TODO: date
Class::STL::ClassMembers::DataMember->new(name => 'description', default => '');
use Class::STL::ClassMembers::Constructor;
sub code_init
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
#> $self->output_field()->pequel_type()->name() eq 'date'
#> ? $c->code("my \$_SERIAL_@{[ $self->output_field()->name() ]} = @{[
#> defined($self->output_field()->serial_start()) ? $self->output_field()->serial_start() : '<today>'
#> ]};")
#> : $c->code("my \$_SERIAL_@{[ $self->output_field()->name() ]} = @{[
#> defined($self->output_field()->serial_start()) ? $self->output_field()->serial_start() : '0'
#> ]};");
$c->code("my \$_SERIAL_@{[ $self->output_field()->name() ]} = @{[ $self->output_field()->serial_start() ]};@{[ $self->prinfo() ]}");
return $c;
}
sub code_output_final
{
my $self = shift;
my $c = shift || ETL::Pequel3::CodeStyler::Program::Perl->new();
#> $self->output_field()->pequel_type()->name() eq 'date'
#> ? $c->code("@{[ $self->output_field()->getvar() ]} = do { \$_SERIAL_@{[ $self->output_field()->name() ]} = &date_next_day(...); ... };");
$c->code("@{[ $self->output_field()->getvar() ]} = ++\$_SERIAL_@{[ $self->output_field()->name() ]};@{[ $self->prinfo() ]}");
return $c;
}
}
# ----------------------------------------------------------------------------------------------------
{
package ETL::Pequel3::Type::Aggregates::Catalogue;
use base qw(ETL::Pequel3::Type::Catalogue);
use Class::STL::ClassMembers
Class::STL::ClassMembers::DataMember->new(name => 'catalogue_name', default => 'aggregates'),
Class::STL::ClassMembers::DataMember->new(name => 'target_mem_name', default => 'name'),
Class::STL::ClassMembers::DataMember->new(name => 'element_type', default => 'ETL::Pequel3::Type::Aggregates::Abstract');
use Class::STL::ClassMembers::SingletonConstructor;
sub new_extra
{
my $self = shift;
$self->push_back(
ETL::Pequel3::Type::Aggregates::Count->_new(),
ETL::Pequel3::Type::Aggregates::CountDistinct->_new(),
ETL::Pequel3::Type::Aggregates::Min->_new(),
ETL::Pequel3::Type::Aggregates::Max->_new(),
ETL::Pequel3::Type::Aggregates::Minimum->_new(),
ETL::Pequel3::Type::Aggregates::Maximum->_new(),
ETL::Pequel3::Type::Aggregates::Sum->_new(),
ETL::Pequel3::Type::Aggregates::SumDistinct->_new(),
ETL::Pequel3::Type::Aggregates::First->_new(),
ETL::Pequel3::Type::Aggregates::Last->_new(),
ETL::Pequel3::Type::Aggregates::Flag->_new(),
ETL::Pequel3::Type::Aggregates::Distinct->_new(),
ETL::Pequel3::Type::Aggregates::Avg->_new(),
ETL::Pequel3::Type::Aggregates::AvgDistinct->_new(),
ETL::Pequel3::Type::Aggregates::Serial->_new(),
ETL::Pequel3::Type::Aggregates::ValuesAll->_new(),
ETL::Pequel3::Type::Aggregates::ValuesUniq->_new(),
ETL::Pequel3::Type::Aggregates::Mean->_new(),
ETL::Pequel3::Type::Aggregates::Median->_new(),
ETL::Pequel3::Type::Aggregates::Variance->_new(),
ETL::Pequel3::Type::Aggregates::Stddev->_new(),
ETL::Pequel3::Type::Aggregates::Range->_new(),
ETL::Pequel3::Type::Aggregates::Mode->_new(),
#> stderr (standard error) = stddev / count-square-root (eg: 28.56 / square-root 14 = 28.56 / 3.74 = 7.6
# --> stddev(f) / sqrt(count(*))
#> bool_and -- true if all input values are true, otherwise false
#> every -- same as bool_and
#> bool_or -- true if at least one input value is true, otherwise false
#> bit_and -- the bitwise AND of all non-null input values, or null if none
#> bit_or -- the bitwise OR of all non-null input values, or null if none
);
return $self;
}
sub catalogue
{
my $self = shift;
my $xml_node = shift;
foreach ($self->to_array()) {
my $s_xml = $xml_node->createChild("aggregate-type");
$s_xml->attribute('aggregate-name', $_->name());
my $m_xml = $s_xml->createChild("property");
$m_xml->attribute('valid-types', $_->valid_types());
}
}
}
# ----------------------------------------------------------------------------------------------------
1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -