table {
border-collapse: collapse;
width: 100%;
margin-bottom: 1rem;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
pre {
background-color: #f8f8f8;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
}
24、创建一个名为 Does::ToHash 的角色,该角色将对象的属性转换为哈希。扩展 User 类以使用此角色并进行测试。
创建
Does::ToHash
角色的代码如下:
package Does::ToHash;
use Moose::Role;
sub to_hash {
my $self = shift;
my @attributes = map { $_->name } $self->meta->get_all_attributes;
my %hash;
foreach my $attribute (@attributes) {
my $value = $self->$attribute;
next if ref $value;
$hash{$attribute} = $value;
}
return \%hash;
}
1;
扩展
User
类以使用
Does::ToHash
角色的代码如下:
package User;
use Moose;
with 'Does::ToHash';
use Digest::MD5 'md5_hex';
use namespace::autoclean;
has username => ( is => 'ro', isa => 'Str', required => 1 );
has password => ( is => 'ro', isa => 'Str', writer => '_set_password',);
sub BUILD {
my $self = shift;
$self->_set_password(md5_hex($self->password));
}
sub password_eq {
my ( $self, $password ) = @_;
$password = md5_hex($password);
return $password eq $self->password;
}
__PACKAGE__->meta->make_immutable;
1;
测试代码如下:
use Data::Dumper;
my $user = User->new( username => 'Ovid', password => 'Corinna',);
print Dumper($user->to_hash);
25、编写一个名为 unique 的子例程,该子例程返回数组中的唯一元素,且元素顺序与它们在原始列表中出现的顺序相同,并对其进行测试。
以下是实现该功能的代码:
use Test::Most;
sub unique {
my @array = @_;
my %seen;
my @unique;
foreach my $element (@array) {
push @unique, $element unless $seen{$element}++;
}
return @unique;
}
my @have = unique( 2, 3, 5, 4, 3, 5, 7 );
my @want = ( 2, 3, 5, 4, 7 );
is_deeply @have, @want, 'unique() should return unique elements in order';
done_testing;
26、修改 unique 子例程的测试,通过对实际数组和预期数组进行排序,以确保唯一元素是有序的。
可将测试代码修改为:
is_deeply [ sort @have ], [ sort @want ], 'unique() should return unique() elements in order';
这样就对
@have
和
@want
数组都进行了排序,从而保证比较时能确保唯一元素是有序的。
27、编写一个子例程 reciprocal 来计算一个数的倒数,处理非数字输入和除以零的情况,并对其进行测试。
以下是实现该功能的代码:
use Test::Most;
use Carp 'croak';
use Scalar::Util 'looks_like_number';
sub reciprocal {
my $number = shift;
unless ( looks_like_number($number) ) {
croak("Argument to reciprocal() must be a number");
}
unless ($number) {
croak("Illegal division by zero");
}
return 1 / $number;
}
throws_ok { reciprocal([]) } qr/Argument to reciprocal() must be a number/, 'Passing non - numbers to reciprocal() should fail';
# diag reciprocal([]); 这行代码会因为前面的异常抛出而无法正常执行,应注释或删除
# 这里可以添加更多测试用例,例如测试正常数字输入
is(reciprocal(2), 0.5, 'Reciprocal of 2 should be 0.5');
done_testing;
上述代码定义了
reciprocal
子例程,用于计算一个数的倒数。它会检查输入是否为数字以及是否为零,若不符合要求则抛出错误。同时使用
Test::Most
模块对
reciprocal
子例程进行了测试。
28、变量$second、$fourth和$sixth中哪些值为真,已知$second为含单个空格的字符串,$fourth值为‘0.0’,$sixth值为’false’。
`$second`、`$fourth` 和 `$sixth` 的值都为真。因为在 Perl 里,非空字符串(像含单个空格的字符串、`'0.0'`、`'false'`)都会被当作真。
29、创建 @celsius 数组。
一种创建
@celsius
数组的方法如下:
my @fahrenheit = ( 0, 32, 65, 80, 212 );
my @celsius = map { ($_ - 32) * 5/9 } @fahrenheit;
30、代码打印 1 到 10 的数字,若要让这些数字分行打印,该如何修改代码
假设在 Perl 中使用简单的循环打印 1 到 10 的数字,原代码可能类似:
```perl
for (1..10) { print $_; }
若要分行打印,可在 print 语句中添加换行符,修改后的代码如下:
for (1..10) { print $_ . "
"; }
31、给定一个数组,编写代码计算其平均值并打印数组元素和平均值
以下是实现该功能的 Perl 代码:
my @numbers = (1, 2, 3, 4, 5); # 示例数组
my $sum = 0;
foreach my $num (@numbers) {
$sum += $num;
}
my $average = $sum / scalar @numbers;
print "数组元素: ", join(", ", @numbers), "
";
print "平均值: $average
";
这段代码首先定义了一个数组
@numbers
,然后遍历数组计算元素的总和,接着计算平均值,最后打印数组元素和平均值。你可以根据需要修改
@numbers
数组的内容。
32、指出代码中 C – style for 循环的逻辑错误并给出修正方案
在代码示例
my $i = 0;
for (;$i < 10;) {
$i++;
print "$i";
}
中,逻辑错误在于打印数字前先执行了
$i++
,导致打印的数字是从
1 到 10
,而不是从
0 到 9
。
修正方案
将
$i++
移到
print
语句之后,即:
my $i = 0;
for (;$i < 10;) {
print "$i";
$i++;
}
33、在 ‘add your code here’ 处编写代码,为哈希 %stat_for 的每个键赋一个 2 + int(rand(6)) + int(rand(6)) 的随机值
foreach my $stat (keys %stat_for) {
my $random = 2 + int(rand(6)) + int(rand(6));
$stat_for{$stat} = $random;
}
34、编写完整代码,为哈希 %stat_for 的 strength、intelligence、dexterity 键赋一个 2 + int(rand(6)) + int(rand(6)) 的随机值,若随机值小于 6 则重新生成,最后打印结果
以下是完整的 Perl 代码:
use strict;
use warnings;
my %stat_for = (
strength => undef,
intelligence => undef,
dexterity => undef,
);
foreach my $stat (keys %stat_for) {
my $random;
do {
$random = 2 + int(rand(6)) + int(rand(6));
} while ($random < 6);
$stat_for{$stat} = $random;
}
print <<"END_CHARACTER";
Strength: $stat_for{strength}
Intelligence: $stat_for{intelligence}
Dexterity: $stat_for{dexterity}
END_CHARACTER
此代码先定义了哈希
%stat_for
,接着遍历其键,为每个键生成一个
2 + int(rand(6)) + int(rand(6))
的随机值,若值小于 6 就重新生成,最后打印哈希中各键的值。
35、创建一个包含 1 到 5 的数组 @first,通过引用赋值给 @second,打印 @first 和 @second,写出代码
my @first = (1, 2, 3, 4, 5);
my @second = @first;
print "@first
";
print "@second
";
36、给定一个表示销售数据的哈希 $sales,其键为销售人员,值为销售数量,编写代码计算销售总和。
以下是一个示例代码,假设
$sales
是一个哈希引用,其键为销售人员,值为销售数量:
use strict;
use warnings;
use diagnostics;
# 假设的销售数据
my $sales = {
jim => 2,
john => 7,
mary => 1,
alice => 4,
pablo => 10,
katherine => 4,
};
my $total_sales = 0;
while ( my ( $salesperson, $num_sales ) = each %$sales ) {
$total_sales += $num_sales;
}
print "销售总和为: $total_sales
";
这段代码遍历哈希中的每个键值对,将每个销售人员的销售数量累加到
$total_sales
变量中,最后输出销售总和。
37、对于给定的分数哈希表,如何正确获取键为 Jim 和 Mary 对应的分数
可以使用以下两种方式:
使用切片:
perl
my ( $jim, $mary ) = @$score_for{ qw{jim mary} };
单独赋值:
perl
$jim = $score_for->{jim};
$mary = $score_for->{mary};
38、编写一个子程序计算传入数字的平均值,并打印出给定数字列表的平均值
以下是一个用 Perl 编写的示例代码来实现该功能:
sub calculate_average {
my @numbers = @_;
my $sum = 0;
foreach my $num (@numbers) {
$sum += $num;
}
my $average = $sum / scalar @numbers;
return $average;
}
my @number_list = (1, 2, 3, 4, 5);
my $result = calculate_average(@number_list);
print "给定数字列表的平均值是: $result
";
以上代码定义了一个名为
calculate_average
的子程序,它接收一组数字作为参数,计算这些数字的总和并除以数字的数量得到平均值,最后返回该平均值。在主程序中,我们创建了一个数字列表并调用该子程序,将结果打印输出。
39、请编写代码计算并打印传入数字 1、5、18、3、5 的平均值。
以下是使用 Python 实现的代码:
numbers = [1, 5, 18, 3, 5]
average = sum(numbers) / len(numbers)
print(average)
若使用 Perl 语言,则代码如下:
#!/usr/bin/perl
use strict;
use warnings;
my @numbers = (1, 5, 18, 3, 5);
my $sum = 0;
foreach my $num (@numbers) {
$sum += $num;
}
my $average = $sum / scalar @numbers;
print $average, "
";
40、请编写一个名为 average 的子例程,该子例程要能判断传入的参数是否为数字,若传入的参数不是数字则抛出错误,并且计算传入数字参数的平均值。例如,当传入 1 5 18 bob 3 5 时,要能正确处理。
以下是实现该功能的代码:
use Scalar::Util 'looks_like_number';
use Carp 'croak';
sub average {
my @numbers = @_;
my $total = 0;
foreach my $number (@numbers) {
if ( not looks_like_number($number) ) {
croak "$number doesn't look like a number";
} else {
$total += $number;
}
}
return $total / @numbers;
}
print average(qw< 1 5 18 bob 3 5>);
41、请编写一个 make_multiplier 子例程,返回一个能将传入参数与指定数字相乘的子例程,并进行测试
以下是实现代码:
sub make_multiplier {
my $number = shift;
return sub {
return shift(@_) * $number;
};
}
my $times_seven = make_multiplier(7);
my $times_five = make_multiplier(5);
print 21 == $times_seven->(3) ? "yes
" : "no
";
print 20 == $times_five->(4) ? "yes
" : "no
";
上述代码定义了
make_multiplier
子例程,它接受一个数字作为参数,返回一个匿名子例程。匿名子例程接受一个数字并返回该数字与
make_multiplier
传入数字的乘积。之后创建了
$times_seven
和
$times_five
两个子例程引用,并进行了测试。
42、请编写一个 sum 子例程,使用递归方法计算传入参数的总和,如传入 1, 93, 3, 5
以下是实现该功能的代码:
sub sum {
return 0 unless @_;
my ( $head, @tail ) = @_;
return $head + sum(@tail);
}
print sum( 1, 93, 3, 5 );
43、编写一个子程序,它接受一个数字作为参数,并返回一个新的子程序,新子程序接受一个参数并将其与传入的数字相乘。
以下是使用 Perl 实现该功能的代码:
sub multiplier_creator {
my $number = shift;
return sub {
my $input = shift;
return $input * $number;
};
}
你可以使用以下方式调用这个子程序:
my $multiply_by_five = multiplier_creator(5);
print $multiply_by_five(3); # 输出 15
44、编写一个递归子程序来计算传入参数的总和。
以下是一个在 Perl 中编写的递归子程序,用于计算传入参数的总和:
sub sum_recursive {
my @numbers = @_;
if (scalar @numbers == 0) {
return 0;
} else {
my $first = shift @numbers;
return $first + sum_recursive(@numbers);
}
}
你可以使用以下方式调用这个子程序:
my $result = sum_recursive(1, 2, 3, 4, 5);
print $result; # 输出 15
45、编写代码,从标准输入读取内容并打印出来。
在Perl中,可以使用以下代码从标准输入读取内容并打印出来:
while (my $line = <STDIN>) {
print $line;
}
这段代码使用
while
循环不断从标准输入读取每一行内容,将其存储在变量
$line
中,然后使用
print
函数将其打印出来,直到没有更多输入为止。
46、请编写代码实现打印输入内容
在 Perl 中,可使用如下代码实现打印输入内容:
print <STDIN>;
此代码会读取标准输入的内容并将其打印出来。若要逐行读取并打印,可使用循环:
while (my $line = <STDIN>) {
print $line;
}
47、请编写代码实现跳过空白行和注释行后打印输入内容
以下是使用 Python 实现跳过空白行和注释行后打印输入内容的代码示例:
# 假设输入内容存储在一个列表中,模拟读取文件的行
input_lines = [
'这是一行正常内容',
'# 这是注释行',
' ',
'另一行正常内容'
]
# 遍历输入的每一行
for line in input_lines:
# 去除行首尾的空白字符
line = line.strip()
# 检查行是否为空或为注释行(假设注释以 # 开头)
if line and not line.startswith('#'):
print(line)
上述代码会遍历输入的每一行,去除行首尾的空白字符,然后检查行是否为空或为注释行,如果不是则打印该行。
如果输入内容来自文件,可以将
input_lines
替换为文件读取的操作,例如:
with open('your_file.txt', 'r', encoding='utf-8') as file:
for line in file:
line = line.strip()
if line and not line.startswith('#'):
print(line)
这样就可以从文件中读取内容,跳过空白行和注释行后打印。
48、请编写代码将命令行参数中的数字转换为对应的字符并打印出来
以下是使用 Python 实现将命令行参数中的数字转换为对应字符并打印的代码:
import sys
for arg in sys.argv[1:]:
try:
num = int(arg)
char = chr(num)
print(char)
except ValueError:
print(f'{arg} 不是有效的数字。')
except OverflowError:
print(f'{arg} 超出字符编码范围。')
在上述代码中,
sys.argv
用于获取命令行参数,
sys.argv[0]
是脚本本身的名称,所以从
sys.argv[1:]
开始遍历参数。对于每个参数,尝试将其转换为整数,再使用
chr()
函数将整数转换为对应的字符并打印。如果参数无法转换为整数,会捕获
ValueError
异常;如果数字超出字符编码范围,会捕获
OverflowError
异常。
49、请编写代码将命令行参数中的每个单词拆分为字符,打印每个字符的 Unicode 码点
以下是一个使用 Perl 编写的示例代码来实现此功能:
#!/usr/bin/perl
use strict;
use warnings;
foreach my $word (@ARGV) {
my @chars = split //, $word;
foreach my $char (@chars) {
my $codepoint = ord($char);
print "字符: $char, Unicode 码点: $codepoint
";
}
}
将上述代码保存为一个
.pl
文件,例如
unicode_codepoints.pl
,然后在命令行中运行:
perl unicode_codepoints.pl your words here
它会将每个单词拆分为字符并打印出每个字符的 Unicode 码点。