--- title: はじめて実用的な目的でPerlを用いた author: kazu634 date: 2007-12-26 url: /2007/12/26/_764/ wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:3527;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - diary - Perl ---

 現在私は予備校の寮でパートとして働いている。そこでは、退寮日を寮生全体に尋ね、その日時と部屋番号、そして寮費の納入方式(一括or二回or月払い)に応じて一月に引き落とされる金額が決定される。そこで私は、これをPerlで計算させようと決意した。四月からはこれぐらいできないといけないだろうし。今ならいっぱい失敗することもできるしね。プログラミングの初歩をかじったことのある人による、Perl体験日記。


計算方法の分析

B棟

寮費の支払い方式 1/16-1/31 2/1-2/15 2/16-2/29 3/1-3/15
一括 (12月)光熱費+概算光熱費(10,000) (12月)光熱費+概算光熱費(10,000) (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(30,000)+3月分寮費(2,300×日数)
二回 (12月)光熱費+概算光熱費(10,000) (12月)光熱費+概算光熱費(10,000) (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(30,000)+3月分寮費(2,300×日数)
月払い (12月)光熱費+概算光熱費(10,000) (12月)光熱費+概算光熱費(10,000)+2月分寮費(66,300) (12月)光熱費+概算光熱費(20,000)+概算光熱費(66,300) (12月)光熱費+概算光熱費(30,000)+2月分寮費(66,300)+3月分寮費(2,300×日数)

C棟

寮費の支払い方式 1/16-1/31 2/1-2/15 2/16-2/29 3/1-3/15
一括 (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(30,000) (12月)光熱費+概算光熱費(40,000)+3月分寮費(2,900×日数)
二回 (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(30,000) (12月)光熱費+概算光熱費(40,000)+3月分寮費(2,900×日数)
月払い (12月)光熱費+概算光熱費(20,000) (12月)光熱費+概算光熱費(20,000)+2月分寮費(84,700) (12月)光熱費+概算光熱費(30,000)+概算光熱費(84,700) (12月)光熱費+概算光熱費(40,000)+2月分寮費(84,700)+3月分寮費(2,900×日数)

必要になるもの

 計算方法の分析ができたので、次は引き落とし金額を求めるのに必要となるデータについて考えた。基本的には、

ということが判明。『新版Perl言語プログラミングレッスン入門編』を参考にCSVからデータを吸い上げる方法がわかる。だがここで、退寮日の記述方式が「月/日」という形式だと現状の自分の手には余ると判断。「退寮日」を「退寮する月」と「退寮する日」に分割することでこの問題の回避をはかった。従って、用意するCSVには

  1. CSVファイル
    1. 部屋番号
    2. 退寮する月
    3. 退寮日
    4. 12月分光熱費

という構成にすることにした。このデータはExcelを使えば簡単に作れるだろうから、後はPerlで計算する部分を作る。*1

はまった部分

できたもの

use strict;
use warnings;
# temp.csv を開く。存在しなければ、スクリプトを終了する
open (FILE, 'temp.csv') or die "$!";
while (my $line = <FILE>) {
# 一行ずつ読み込んで、@dataに格納する
my @data = split(/,/, $line);
# temp.csvの構造は
# 棟,部屋番号,支払い方法,退寮する月,退寮する日,12月分光熱費
# ちなみに支払い方法:
# 1 : 一括払い 2 : 二回払い 3 : 月払い
# だから、
# @data[0] --> 棟 // @data[1] --> 部屋番号 // @data[2] --> 支払い方法
# @data[3] --> 退寮する月 // @data[4] --> 退寮する日
# @data[5] --> 光熱費
# B棟の人の場合
if ($data[] eq "B"){
print $data[] . $data[1] . ",";
# 一括と二回は同じ計算式なので、
# ここでは同じものとして扱う
if ($data[2] == 1 || $data[2] == 2){
# 1/16~2/15のとき
if (($data[3] == 1 && $data[4] >= 16) || ($data[3] == 2 && $data[4] <= 15)) {
# 支払う金額は、「10,000 + 12月分光熱費」
print 10000 + $data[5] . "\n";
# 2/16~2/29のとき
} elsif ($data[3] == 2 && $data[4] <= 29) {
# 支払う金額は、「20,000 + 12月分光熱費」
print 20000 + $data[5] . "\n";
# 3/1~3/15のとき
} elsif ($data[3] == 3 && $data[4] <=15) {
# 支払う金額は、「30,000 + 12月分光熱費 + 3月分寮費」
print 30000 + $data[5] + (2300 * $data[4]) . "\n";
} else {
print "data out of range!\n";
}
# 月払いの時
} elsif ($data[2] ==3) {
# 1/16~1/31の時
if ($data[3] == 1 && $data[4] <= 31) {
# 支払う金額は、「10,000 + 12月分光熱費」
print 10000 + $data[5] . "\n";
# 2/1~2/15のとき
} elsif ($data[3] == 2 && $data[4] <= 15) {
# 支払う金額、「10,000 + 66300 + 12月分光熱費」
print 10000 + 66300 + $data[5] . "\n";
# 2/16~2/29のとき
} elsif ($data[3] == 2 && $data[4] <= 29) {
# 支払う金額は、「20,000 + 66,300 + 12月分光熱費」
print 20000 + 66300 + $data[5] . "\n";
# 3/1~3/15のとき
} elsif ($data[3] == 3 && $data[4] <= 15){
# 支払う金額は、
#「30,000 + 66,300 + 3月分寮費(2300 * 日数) + 12月分光熱費」
print 30000 + 66300 + (2300 * $data[4]) + $data[5] . "\n";
} else {
print "data out of range!\n";
}
}
}
# C棟の人の場合
if ($data[] eq "C"){
print $data[] . $data[1] . ",";
# 一括と二回は同じ計算式なので、
# ここでは同じものとして扱う
if ($data[2] == 1 || $data[2] == 2){
# 1/16~2/15のとき
if (($data[3] == 1 && $data[4] >= 16) || ($data[3] == 2 && $data[4] <= 15)) {
# 支払う金額は、「20,000 + 12月分光熱費」
print 20000 + $data[5] . "\n";
# 2/16~2/29のとき
} elsif ($data[3] == 2 && $data[4] <= 29) {
# 支払う金額は、「30,000 + 12月分光熱費」
print 30000 + $data[5] . "\n";
# 3/1~3/15のとき
} elsif ($data[3] == 3 && $data[4] <=15) {
# 支払う金額は、「40,000 + 12月分光熱費 + 3月分寮費」
print 40000 + $data[5] + (2900 * $data[4]) . "\n";
} else {
print "data out of range!\n";
}
# 月払いの時
} elsif ($data[2] ==3) {
# 1/16~1/31の時
if ($data[3] == 1 && $data[4] <= 31) {
# 支払う金額は、「20,000 + 12月分光熱費」
print 20000 + $data[5] . "\n";
# 2/1~2/15のとき
} elsif ($data[3] == 2 && $data[4] <= 15) {
# 支払う金額、「20,000 + 84700 + 12月分光熱費」
print 20000 + 84700 + $data[5] . "\n";
# 2/16~2/29のとき
} elsif ($data[3] == 2 && $data[4] <= 29) {
# 支払う金額は、「30,000 + 84,700 + 12月分光熱費」
print 30000 + 84700 + $data[5] . "\n";
# 3/1~3/15のとき
} elsif ($data[3] == 3 && $data[4] <= 15){
# 支払う金額は、
#「40,000 + 84,700 + 3月分寮費(2900 * 日数) + 12月分光熱費」
print 40000 + 84700 + (2900 * $data[4]) + $data[5] . "\n";
} else {
print "data out of range!\n";
}
}
}
}
close(FILE);

今後の課題

こんなのを見つけた:

Perlデータマンジング―データ加工のテクニック集

*1:「Excelですべて作ってしまえば」という声もあるけれど、何十もの括弧で区切られる数式をいちいちやるのが面倒くさかったりして