perl 入门项目 Demo 点餐系统

这是一个使用Perl处理订单信息的程序,涉及正则表达式用于日期和客户名称的提取,类的继承实现不同食物对象,文件读写操作记录订单与结果,以及全局变量管理库存。程序分析订单并报告每日销售总额,按日期、客户和食品类别进行汇总。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

视频
 
 
1. 正则
2. 类的继承使用
3. 文件读写
4. 全局变量的使用
5. 数组
6. 哈希 (map)
 

 

订单信息

order.txt

customer Marry order 2 cup of vegetable_soup, 1 white_bread ,2020-01-03;
2020-01-03, customer John : 2 cups of broth ,and 3 white_bread ,4 cups of vegetable_soup,;
customer Alex 5 cups broth,and 2 wheat_bread ,2020-01-03;

customer John 1 cups broth ,and 3 white_bread ,2020-01-04;
customer Alex 2 cups vegetable_soup 2020-01-04;
2020-01-04, customer Marry order 55 cup of vegetable_soup, 5 white_bread;

2020-01-05, 5 cups broth ,and 1 wheat_bread  customer John;
2020-01-05, 5 cups vegetable_soup ,and 10 white_bread  customer Alex;
2020-01-05, 2 cups broth ,and 10 wheat_bread  customer Marry;

运行结果

 

目录结构与运行结果

 

代码

main.pl

#!/usr/bin/perl

BEGIN{push @INC, "D:/wks_perl/dish_perl/util";}
BEGIN{push @INC, "D:/wks_perl/dish_perl/obj";}

use utf8;
use warnings;
use strict;


binmode(STDOUT,":encoding(gbk)");
#标准输出使用gbk作为编码格式,也可以把gbk改为gb2312
binmode(STDIN,":encoding(gbk)");
binmode(STDERR,":encoding(gbk)");


use Global_setting;
use Reg_util;
use File_util;
use Common_util;



sub main{
	my @orders=File_util->read_file("./doc/order.txt");

	# 初始化 log
	File_util->cratre_overwrite_file("./doc/res.txt","");

	my $size = @orders;
	my $cur_date="";
	my %data=();

	for (my $i=0;$i<$size;$i++){
		my $line=$orders[$i];
		$line=Reg_util->remove_end_space($line);

		File_util->append_file("./doc/res.txt",$line);

		my $date=Reg_util->get_date($line);
		my $customer=Reg_util->get_customr_name($line);
		File_util->append_file("./doc/res.txt","customer:$customer\n");
		if($date cmp  $cur_date){
			$cur_date=$date;
			Global_setting->reset_max_num();
		}
		if(!exists($data{$date})){
			 $data{$date}=();
		}

		my @order_array=Common_util->get_order_array($line);

		$data{$date}{$customer}=\@order_array;
	}

	Common_util->report(%data);

}



&main();

Food.pm

package Food;
use utf8;
use warnings;
use strict;

sub new{
	my $class = shift;
	my $self = {
		_name => shift,
		_price => shift,
	};
	bless $self,$class;
	return $self;
}

sub set_name{
	my ($self,$new_name)= @_;
	if (defined ($new_name)){
		$self->{_name} = $new_name;
		return 1;
	}
	else {
		return 0;
	}
}

sub get_name{
	my($self)=@_;
	return $self->{_name};
}

sub set_price{
	my ($self,$new_price)= @_;
	$self->{_price} = $new_price if defined($new_price);
}

sub get_price{
	my($self) = @_;
	return $self->{_price};
}

1;

Bread.pm

package Bread;

use utf8;
use warnings;
use strict;


use Global_setting;
use Food;

use base qw(Food);

sub new {
	my $class = shift;

	my $self = $class->SUPER::new(shift, shift);	
	
	# 添加更多属性
	$self->{_units}   = shift;

	# bless $self, $class;

	$self;
}

sub order{
	my($self,$order_num)=@_;
	if($order_num>$Global_setting::white_bread_discount_num and $self->{_name} eq Global_setting::WHITE_BREAD){
		$self->{_price}*=0.8;
	}
	$self->{_units}=$order_num;
}

sub print_self {
	my($self)=@_;
	my $str= "bread:name:".$self->{_name}.",price:".$self->{_price}.",units:".$self->{_units}."\n";

	File_util->append_file("./doc/res.txt",$str);
}



1;

Soup.pm

package Soup;

use utf8;
use warnings;
use strict;

use Global_setting;
use Food;

use base qw(Food);

sub new {
	my $class = shift;
	my $self = $class->SUPER::new(shift, shift);	
	
	# 添加更多属性
	$self->{_cups}   = shift;
    # bless $self, $class;
	$self;
}


sub get_avaialable_num {
	my($self)=@_;
	# print "get_avaialable_num name:".$self->{_name}."\n";
	if($self->{_name} eq Global_setting::VEGETABLE_SOUP)
	{
		return Global_setting::MAX_VEG_SOUP_PER_DAY - $Global_setting::cur_veg_soup_num;
	} elsif($self->{_name} eq Global_setting::BROTH) 
	{
		return Global_setting::MAX_BROTH_PER_DAY - $Global_setting::cur_broth_num;
	}else{
		return 0;
	}
}

sub amend_cur_num{
	my($self)=@_;
	if($self->{_name} eq Global_setting::VEGETABLE_SOUP){
		$Global_setting::cur_veg_soup_num+=$self->{_cups};
		return 1;
	}elsif($self->{_name} eq Global_setting::BROTH){
		$Global_setting::cur_broth_num+=$self->{_cups};
		return 1;
	}else{
		return 0;
	}
}

sub order{
	my($self,$order_num)=@_;+		
	my $avail_num=get_avaialable_num($self);
	if($avail_num<$order_num){
		$self->{_cups}=$avail_num;
	}else{
		$self->{_cups}=$order_num;
	}
	amend_cur_num($self);
}

sub print_self {
	my($self)=@_;
	my $str="soup:name:".$self->{_name}.",price:".$self->{_price}.",cups:".$self->{_cups}."\n";
	File_util->append_file("./doc/res.txt",$str);

}


1;

Common_util.pm

package Common_util;

use utf8;
use warnings;
use strict;



use Reg_util;
use Global_setting;
use Soup;
use Bread;

sub get_order_array {
	my($class,$line)=@_;
	my @res;

	my @line_arr=split /,/,$line;
	foreach my $line_item (@line_arr){
		my @nums=Reg_util->get_numbers($line_item);

		if(Reg_util->contain($line_item,Global_setting::VEGETABLE_SOUP,1)){

			my $object =new Soup( Global_setting::VEGETABLE_SOUP,$LB::veg_soup_price,0);

			$object->order($nums[0]);
			if($object->{_cups}>0)
			{
				push @res,$object;
			}

		}elsif(Reg_util->contain($line_item,Global_setting::BROTH,1)){
			my $object =new Soup();
			$object->set_name(Global_setting::BROTH);
			$object->set_price($LB::broth_price);


			$object->order($nums[0]);

			if($object->{_cups}>0)
			{
				push @res,$object;
			}

		}elsif(Reg_util->contain($line_item,Global_setting::WHITE_BREAD,1)){
			
			my $object =new Bread();
			$object->{_name}=Global_setting::WHITE_BREAD;
			$object->{_price}=$LB::white_bread_price;


			$object->order($nums[0]);
			if($object->{_units}>0)
			{
				push @res,$object;
			}

		}elsif(Reg_util->contain($line_item,Global_setting::WHEAT_BREAD,1)){
			my $object =new Bread();
			$object->{_name}=Global_setting::WHEAT_BREAD;
			$object->{_price}=$LB::wheat_bread_price;
			$object->order($nums[0]);
			if($object->{_units}>0)
			{
				push @res,$object;
			}
		}else{
			;
		}
		

	}

	# log
	for my $item (@res){
		$item->print_self();
	}
	File_util->append_file("./doc/res.txt","----------------------------------------------------\n");
	

	return @res;
}


sub report {
	my($class,%data)=@_;

	my %sum_by_date=();
	my %sum_by_customer=();
	my %sum_by_name=();

	for my $date (keys %data){
		my %tmp=%{$data{$date}};
		for my $customer (keys  %tmp){
			my @order=@{$data{$date}{$customer}};
			foreach my $item (@order){


				# 取出数据
				my $name=$item->{_name};
				my $price=$item->{_price};
				my $num;
				if(($name eq Global_setting::VEGETABLE_SOUP) || ($name eq Global_setting::BROTH)){
					$num = $item->{_cups};
				}else{
					$num = $item->{_units};
				}

				my $money=$num*$price;


				if(!exists($sum_by_date{$date})){
					$sum_by_date{$date}=$money;
				}else{
					$sum_by_date{$date}+=$money;
				}

				if(!exists($sum_by_customer{$customer})){
					$sum_by_customer{$customer}=$money;
				}else{
					$sum_by_customer{$customer}+=$money;
				}

				if(!exists($sum_by_name{$name})){
					$sum_by_name{$name}=$money;
				}else{
					$sum_by_name{$name}+=$money;
				}
			}
		}
	}

	File_util->append_file_and_print("./doc/res.txt","=====Final SUM beg========================================\n");

	my $sum=0;
	my @date_list= keys %sum_by_date;
	@date_list = sort(@date_list);
	foreach my $date (@date_list){
		my $money=$sum_by_date{$date};
		
		File_util->append_file_and_print("./doc/res.txt","date $date sum:".$money."\n");
		
		$sum+=$money;
	}

	File_util->append_file_and_print("./doc/res.txt","sum:".$sum."\n");
	File_util->append_file_and_print("./doc/res.txt","-----------------------------------------------------------\n");

	$sum=0;
	while (my($customer,$money) = each(%sum_by_customer)){ 
		File_util->append_file_and_print("./doc/res.txt","customer $customer sum:".$money."\n");
		$sum+=$money;
	}

	File_util->append_file_and_print("./doc/res.txt","sum:".$sum."\n");

	File_util->append_file_and_print("./doc/res.txt","-----------------------------------------------------------\n");
	
	$sum=0;
	while (my($name,$money) = each(%sum_by_name)){ 
		File_util->append_file_and_print("./doc/res.txt","name $name sum:".$money."\n");
		$sum+=$money;
	}

	File_util->append_file_and_print("./doc/res.txt","sum:".$sum."\n");
	File_util->append_file_and_print("./doc/res.txt","=====Final SUM end========================================\n");
}

1;

File_util.pm

package File_util;
use utf8;
use warnings;
use strict;

use Reg_util;

sub read_file {
	my($class,$file_path)=@_;
  	open(MYFILE,$file_path)||die "err: $!\n";
	# @array = <MYFILE>;
	my @array;
	while($_ = <MYFILE>){
		if(Reg_util->contain_words($_)==1){
			$_=Reg_util->remove_end_space($_);
			$_ =Reg_util->remove_begin_space($_);
			push @array,$_;
		}
	}

	close MYFILE;
	return @array;
}


sub append_file {
	my($class,$file_path,$str)=@_;
  	open(MYFILE,">>".$file_path)||die "err: $!\n";
  	print MYFILE $str;
	close MYFILE;
}

sub append_file_and_print {
	my($class,$file_path,$str)=@_;
	append_file($class,$file_path,$str);
	print $str;
}


sub cratre_overwrite_file {
	my($class,$file_path,$str)=@_;
  	open(MYFILE,">".$file_path)||die "err: $!\n";
  	print MYFILE $str;
	close MYFILE;
}


sub readable {
	my($class,$file_path)=@_;
	return 1 if(-r $file_path);
	0;
}


sub writeable {
	my($class,$file_path)=@_;
	return 1 if(-w $file_path);
	0;
}

sub is_exists {
	my($class,$file_path)=@_;
	return 1 if(-e $file_path);
	0;
}

sub is_empty {
	my($class,$file_path)=@_;
	return 1 if(-z $file_path);
	0;
}


sub file_size {
	my($class,$file_path)=@_;
	return (-s $file_path);
}



sub is_file {
	my($class,$file_path)=@_;
	return 1 if(-f $file_path);
	0;
}


sub is_dir {
	my($class,$file_path)=@_;
	return 1 if(-d $file_path);
	0;
}

sub is_text_file {
	my($class,$file_path)=@_;
	return 1 if(-T $file_path);
	0;
}

sub is_binary_file {
	my($class,$file_path)=@_;
	return 1 if(-B $file_path);
	0;
}

sub write_file {
	my($class,$file_path,$str)=@_;
	if(is_exists("",$file_path)){
		append_file("",$file_path,$str);
	}else{
		cratre_overwrite_file("",$file_path,$str);
	}
}

1;

Global_setting.pm

package Global_setting;
use utf8;
use warnings;
use strict;


# 汤的种类
use constant { 
    VEGETABLE_SOUP   => 'vegetable_soup',
    BROTH   => 'broth',
};

# 面包的种类
use constant {
    WHITE_BREAD => 'white_bread',
    WHEAT_BREAD => 'wheat_bread',
};

# 每日最大供应量
use constant {
    MAX_VEG_SOUP_PER_DAY   => 5,
    MAX_BROTH_PER_DAY   => 5,
};


# 全局变量 当前供应量

$LB::veg_soup_price=4;
$LB::broth_price=9;

$LB::white_bread_price=3;
$LB::wheat_bread_price=5;


our $cur_broth_num=0;
our $cur_veg_soup_num=0;


our $white_bread_discount_num=2;


sub reset_max_num {
	# 清除供应量
	$cur_broth_num =0;
	$cur_veg_soup_num=0;

	# 每天涨价1元
	$LB::veg_soup_price+=1;
	$LB::broth_price+=1;
	$LB::white_bread_price+=1;
	$LB::wheat_bread_price+=1;
}


1;

Reg_util.pm


package Reg_util;
use utf8;
use warnings;
use strict;


sub contain {
	my ($class,$word,$target,$ignore_cap)=@_;
	$_=$word;
	if($ignore_cap){
		return 1 if /$target/i;
	}else{
		return 1 if /$target/;
	}
	0;
}

sub contain_space {
	my ($class,$word)=@_;
	$_=$word;
	return 1 if /\p{Space}/;
	0;
}

sub contain_words {
	# 包含数字或符号
	my ($class,$word)=@_;
	$_=$word;
	return 1 if /\w/;
	0;
}


sub is_digit{
	my ($class,$num)=@_;
	my $reg1 = qr/^-?\d+(\.\d+)?$/;
	my $reg2 = qr/^-?0(\d+)?$/;
	return 1 if ( $num =~ $reg1 && $num !~ $reg2 );    
	0;
}


sub contain_digit {
	my ($class,$word,$target)=@_;
	$_=$word;
	# (?# return 1 if /\p{Digit}/;)
	return 1 if /\d/;
	0;
}


sub to_lower { 
	# 转成小写
	my ($class,$word)=@_;
	$word =~ tr/A-Z/a-z/;
	$word;
}

sub to_cap {
	# 转成大写
	my ($class,$word)=@_;
	$word =~ tr/a-z/A-Z/;
	$word;
}



sub replace {
	# 替换
	my ($class,$word,$tar,$replace,$ignore_cap) = @_;
	if($ignore_cap==1){
		$word =~ s/$tar/$replace/i;
	}else{
		$word =~ s/$tar/$replace/;
	}
	$word;
}


sub get_numbers {
	# 找出数字并存放在一个数组里返回
	my ($class,$str)=@_;
	my @d = $str =~/[\-\d]?[\d]*[\.]?[\d]+/g;
	@d;
}



sub get_first_match {
	# 截取匹配后的第一个字符
	my ($class,$str,$criteria)=@_;
	my @d =$str =~/$criteria[\s]+(.*?)[\s;,]/;
	$d[0];
}

sub get_customr_name {
	my ($class,$str)=@_;
	$str = get_first_match($class,$str,"customer");
	$str = remove_end_space($class,$str);
	$str = remove_begin_space($class,$str);
}

sub get_date {
	# 截取匹配后的第一个字符2021-05-01
	my ($class,$str)=@_;
	# @d = $str =~/[\d]+[\-\d]+[\-\d]+/g;
	my @d = $str =~/[\d]+[\-][\d]+[\-][\d]+/g;
	$d[0];
}



sub remove_end_space {
	my ($class,$str)=@_;
	$str =~ s/[\r\n\s]$//; 
	$str;
}

sub remove_begin_space {
	my ($class,$str)=@_;
	$str =~ s/^[\s\t]+//; 
	$str;
}

1;

main.pl

#!/usr/bin/perl

BEGIN{push @INC, "D:/wks_perl/dish_perl/util";}
BEGIN{push @INC, "D:/wks_perl/dish_perl/obj";}

use utf8;
use warnings;
use strict;


binmode(STDOUT,":encoding(gbk)");
#标准输出使用gbk作为编码格式,也可以把gbk改为gb2312
binmode(STDIN,":encoding(gbk)");
binmode(STDERR,":encoding(gbk)");


use Global_setting;
use Reg_util;
use File_util;
use Common_util;



sub main{
	my @orders=File_util->read_file("./doc/order.txt");

	# 初始化 log
	File_util->cratre_overwrite_file("./doc/res.txt","");

	my $size = @orders;
	my $cur_date="";
	my %data=();

	for (my $i=0;$i<$size;$i++){
		my $line=$orders[$i];
		$line=Reg_util->remove_end_space($line);

		File_util->append_file("./doc/res.txt",$line."\n");

		my $date=Reg_util->get_date($line);
		my $customer=Reg_util->get_customr_name($line);
		File_util->append_file("./doc/res.txt","customer:$customer\n");
		if($date cmp  $cur_date){
			$cur_date=$date;
			Global_setting->reset_max_num();
		}
		if(!exists($data{$date})){
			 $data{$date}=();
		}

		my @order_array=Common_util->get_order_array($line);

		$data{$date}{$customer}=\@order_array;
	}

	Common_util->report(%data);

}



&main();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值