PR
Profile
Search this site.
MOBILE
qrcode
Others
<< Ploom TECH:新フレーバー:ストロベリーマンゴー / レモンティー | main | Linux:Ubuntu:6年前のPCにインストール >>
Ruby:Loto7:抽選番号カウント機能を作る その2

前回コードは、正確には期待していた事ができていなかったので、コードを修正。

 

期待した結果になっていなかった箇所。

 

    # 抽選番号の抽出
    def number_lottery
        loto7_csv.map{ |item| item[5, 7] }
    end

 

結果 =>

[["No.1", "No.2", "No.3", "No.4", "No.5", "No.6", "No.7"], ["#", "#", "#", "#", "#", "#", "#"], ["7", "10", "12", "17", "23", "28", "34"], ["20", "24", "29", "31", "33", "34", "35"],  〜 ["1", "11", "18", "19", "21", "29", "37"]]

 

CSVのデータを取得する際に、1行目2行目も取得してしまっていた。

単純にカウントするだけなら、1行目2行目のデータはカウントしないので要件は満たしていたのだけれど、やっぱり妥協したくなかったので、コードを修正する事に。

 

 

今回修正したコードは、以下。

 

    # CSVデータの抽出 抽選番号No.1〜No.7だけ
    def csv_get
        CSV.foreach("#{csv_file_path}") do |num|
            if num[0] != "#"     # [#]行は無視
                next if @csv_data.concat(num[5,7])
            end
        end
        @csv_data
    end

 

結果 =>

["7", "10", "12", "17", "23", "28", "34", "20", "24", "29", "31", "33", "34", "35", "2", "7", "8", "11", "14", "23", "31", "12", "13", "22", "23", "24", "28", "29", "1", "3", "4", "5", "16", "21", "28", "5", "15", "19", "23", "30", "34", "35", "1", "3", "5", "7", "27", "29", "33", "2", "21", 〜 ……

 

CSVの1列目、#が入っている行を取得しないようにしたかった。

また修正前に使っていた配列の配列を平坦化した配列にする「flatten」は、「concat」で平坦化している。

 

ここまでは、割と簡単に修正できた……のだが、次ですごく詰まった……

 

    # 抽選番号のカウント処理
    def lottery_count
        37.times do |item|
            @lottery = csv_get
            item = @lottery.count("#{@i}")
            puts "#{@i} は #{item} 回出ています".rjust(14)

            @lottery.clear
            @i += 1
        end    
    end

 

カウントの処理。

そして、解決してくれたのは「clear」メソッド。

「clear」がない場合、以下の結果になる……

 

  1 は 56 回出ています

2 は 110 回出ています

3 は 147 回出ています

4 は 236 回出ています

5 は 235 回出ています

6 は 354 回出ています

7 は 392 回出ています

8 は 424 回出ています

9 は 621 回出ています

 

カウント数が明らかにおかしい……

一つ一つの処理を整理したところ、カウントするインスタンンス変数「@lottery」を繰り返すところで、繰り返した分だけ@lotteryを呼び出していたというのが問題だった。

つまり、下記の状態。

 

["7", "10", "12", "17", "23", "28", "34", "20", "24", "29", "31", "33", "34", "35", "2", "7", "8", "11", "14", "23", "31", "12", "13", "22", "23", "24", "28", "29", "1", "3", "4", "5", "16", "21", "28", "5", "15", "19", "23", "30", "34", "35", "1", "3", "5", "7", "27", "29", "33", "2", "21", "28", "29", "30", "32", "36", "3", "4", "15", "23", "27", "30", "36", "1", "2", "3",〜 ……

["7", "10", "12", "17", "23", "28", "34", "20", "24", "29", "31", "33", "34", "35", "2", "7", "8", "11", "14", "23", "31", "12", "13", "22", "23", "24", "28", "29", "1", "3", "4", "5", "16", "21", "28", "5", "15", "19", "23", "30", "34", "35", "1", "3", "5", "7", "27", "29", "33", "2", "21", "28", "29", "30", "32", "36", "3", "4", "15", "23", "27", "30", "36", "1", "2", "3",〜 ……

 

37.times で繰り返した分だけ@lotteryが増えていき、その全部をカウントしているので、カウント数が狂っていった。

それを解決してくれたのが、配列の中身を空にしてくれる「clear」

これで毎回、最後に配列を空の状態にする事で、@lotteryが増えていかない状態に。

ここの、配列を空にする方法がなんとも分からずにいたのだが、リファレンス読んでようやく解決。

リファレンス、すごく大事です。

 

<-------------------------------------------------------->

■前回のコード

 

##### loto7 抽選番号カウントプログラム

 

# CSVライブラリの読み込み
require 'csv'
 

class Loto7NumberTimes
    
    # インスタンス変数の初期化
    def initialize
        @filepath = "./csv/loto7_log.csv"
        @i = 1
        @csv_data
        @loto7
    end
    
    # CSVファイルのフルパス取得
    def log_file_path
        File.expand_path("#{@filepath}")
    end
    
    # CSVデータの取得
    def loto7_csv
        @csv_data = CSV.read(log_file_path)
    end
    
    # 抽選番号の抽出
    def number_lottery
        loto7_csv.map{ |item| item[5, 7] }
    end
    
    # 抽選番号のカウント
    def lottery_count
        while @i < 38
            @loto7 = number_lottery.flatten.count("#{@i}")
            puts "#{@i} は #{@loto7} 回出ています".rjust(14)
            @i += 1
        end
    end

end

 

loto7numtimes = Loto7NumberTimes.new
loto7numtimes.lottery_count

 

<-------------------------------------------------------->

■修正したコード

 

##### loto7 抽選番号カウント

# CSVライブラリの読み込み
require 'csv'
# require '../benchmark/process_measure.rb'

class Loto7NumberCount
    
    # インスタンス変数の初期化
    def initialize
        @csv_path = "./csv/loto7_log.csv"
        @csv_data = []
        @i = 1
        @lottery
    end
    
    # CSVファイルのフルパス取得
    def csv_file_path
        File.expand_path("#{@csv_path}")
    end
    
    # CSVデータの抽出 抽選番号No.1〜No.7だけ
    def csv_get
        CSV.foreach("#{csv_file_path}") do |num|
            if num[0] != "#"     # [#]行は無視
                next if @csv_data.concat(num[5,7])
            end
        end
        @csv_data
    end

 

    # 抽選番号のカウント処理
    def lottery_count
        37.times do |item|
            @lottery = csv_get
            item = @lottery.count("#{@i}")
            p "#{@i} は #{item} 回出ています".rjust(14)
            @lottery.clear
            @i += 1
        end    
    end
        
end

loto7_num_count = Loto7NumberCount.new
loto7_num_count.lottery_count

 

結果 =>

 1 は 56 回出ています

 2 は 55 回出ています

 3 は 49 回出ています

 4 は 59 回出ています

 5 は 47 回出ています

 6 は 59 回出ています

 7 は 56 回出ています

 8 は 53 回出ています

 9 は 69 回出ています

10 は 51 回出ています

11 は 54 回出ています

12 は 47 回出ています

13 は 64 回出ています

14 は 51 回出ています

15 は 69 回出ています

16 は 45 回出ています

17 は 55 回出ています

18 は 45 回出ています

19 は 48 回出ています

20 は 49 回出ています

21 は 68 回出ています

22 は 47 回出ています

23 は 66 回出ています

24 は 60 回出ています

25 は 45 回出ています

26 は 56 回出ています

27 は 57 回出ています

28 は 63 回出ています

29 は 51 回出ています

30 は 60 回出ています

31 は 58 回出ています

32 は 52 回出ています

33 は 42 回出ています

34 は 57 回出ています

35 は 61 回出ています

36 は 66 回出ています

37 は 47 回出ています

 

しかし修正はできたのだけれど、ここまで作ってみて、なんだかコードが汚くなってしまった。

ということは、きっともっと簡潔に書けるのだと思うけれど、いまの知識ではこれ以上は無理。

 

一旦、抽選番号をカウントするプログラムはこれで終了。

また、別の機能を作ることに移ろうと思うが、いつかもっと綺麗なコードに直す。

 

JUGEMテーマ:コンピュータ

| Ruby | 22:02 | - | - | このページのトップへ
スポンサーサイト
| - | 22:02 | - | - | このページのトップへ