なずブログ

インフラSE、Java開発、リモートワークエンジニアな人のメモ帳

オブジェクト指向でFizzBuzz イン JAVA ~手続き型で考えるとわかんない~

f:id:nazuna_0124:20170329192937p:plain

わかりやすく、表題ではオブジェクト指向と書きましたが、

いつも通り自信なし。オブジェクト主体って言いたいです。


昨日の鯛焼きで気がついたことの続きです。

オブジェクト主体でならすぐ出来るのに、手続き型で思いつかない!!


今回のお題はこちらです。


・3人で実際にFizzBuzzをやってみた。

・それぞれ苦手倍数があり、1%の確率で間違える。

・開始数字と回答順は固定。

・10回戦して勝敗を表示。


さっくりとやってみて確認すると問題発生!すぐ気づくべきだったかも…


3人だと順番によって苦手倍数が回ってこないので負けがありません


4人ですることに変更。ついでに、間違える確率を指定できるように。

(ほんと、こういう変更が簡単なのです)


ソースはこんなかんじ。Mainはわかりやすさ重視!!

本当はPersonは配列にして、ちゃんと回答順を入れ替えるべきかなって思います。


Main.java

public class Main {

    public static void main(String[] args) {

   //名前、苦手倍数、苦手倍数が回ってきたときの誤答率です。
        Person bob = new Person("ボブ", 3, 1);
        Person ken = new Person("ケン", 5, 1);
        Person emily = new Person("エミリー", 15, 1);
        Person tom = new Person("トム", 3, 2);

        for (int i = 0; i < 10; i++) {
            Judge j = new Judge();
            while (j.game == true) {

                emily.answer(j);
                System.out.println(j.game);
                if (j.game == false) {
                    break;
                }

                ken.answer(j);
                System.out.println(j.game);
                if (j.game == false) {
                    break;
                }

                bob.answer(j);
                if (j.game == false) {
                    break;
                }
                System.out.println(j.game);

                tom.answer(j);
                if (j.game == false) {
                    break;
                }
                System.out.println(j.game);
            }
        }
        System.out.println("ボブの負け数:" + bob.loose);
        System.out.println("ケンの負け数:" + ken.loose);
        System.out.println("エミリーの負け数:" + emily.loose);
        System.out.println("トムの負け数:" + tom.loose);

    }
}


Person.java

public class Person {
    String name ;
    int loose = 0;
    int weakNum;
    int missRate;
    
    Person(String name,int num ,int missRate){
        this.name = name;
        this.weakNum = num;
        this.missRate = missRate;
    }
    
    void answer(Judge j) {
        String res = "";
        
        if(j.cnt % 15 == 0){
            res = "FizzBuzz";
        }else if(j.cnt % 3 == 0){
            res = "Fizz";
        }else if(j.cnt % 5 == 0){
            res = "Buzz";
        }else{
            res = String.valueOf(j.cnt);
        }
        
        //一定の確率で間違う処理
        if(j.cnt % this.weakNum == 0){
            int rnd = new java.util.Random().nextInt(99) +1 ;
            
            if (rnd <= this.missRate){
                res = "miss!";
            }
                   
        }
        
        System.out.println(this.name + ":"  + res);        
        j.check(this,res);
    }  
}


Judge.java

public class Judge {
    int cnt =1;
    int endCnt = 10000;
    boolean game = true;

    Boolean check(Person p ,String answer) {
        int counter = this.cnt ;
        String correct;

            if(counter % 15 == 0){
                correct = "FizzBuzz";
            }else if(counter% 3 == 0){
                correct = "Fizz";
            }else if(counter % 5 == 0){
                correct = "Buzz";
            }else{
                correct = String.valueOf(counter);
            }
        
        if(answer.equals(correct) == true){
            this.cnt++;
            
            if ( this.cnt >= this.endCnt){
                return false;
            }else{
                return true;
            }
            
        }else{
            p.loose ++;
            this.game = false ;
            return false;
        }      
    }    
}


結果は至って普通に考えて出現頻度の低い15倍数が苦手のエミリーが強いです。


頻出の3倍で2%間違えるトムは激弱。エミリーを6%まで誤答率を引き上げると

だいたいおんなじ感じになるので、ほとんど出現率依存な雰囲気。


数学的にはさっぱりわかりませんが!!


というわけで、何の言語でも構いませんので、

ふつーに今回のお題を作っていただける方大募集です!

職業訓練の授業63日目~JAVA:オブジェクト指向、カプセル化

f:id:nazuna_0124:20170303232129p:plain

みんなに伝えたい。たんぽぽオムライスで挫折したわたしが


ドレス・ド・オムライスに出会った日のことを!


なにこれ簡単だし、見た目も綺麗だし、これでいいじゃん!!


というわけで、本日のお題はオブジェクト指向に続きつつカプセル化のお話です。


とりあえずオブジェクトにしておけばよいという考えのもと

コードを作っているとなんとなくそれっぽくなります。


なんでもvariantで変数宣言してたVBAを思い出しますが、

だんだん、ただの変数のデータ型扱いです。


文字列<配列<連想配列<オブジェクト の順番で拡張されてる感じ。


これでいいじゃん!かどうかは、全く保証できませんが、引き続きこのままです。


本日の追加お題はカプセル化です。隠蔽とも呼ばれますね。


先生の解説ではメンバのアクセス制御ってことでした。


Readは出来るけど、Writeは出来ないプロパティ作成や、

プロパティへの入力検査をオブジェクト側に持たせる使い方が代表例。


後者に関しては使い方にまだ迷ってます。


例ではtrhow でエラーを出してしまって、コンパイル自体が通らない使い方。


ユーザー入力の検査には使えないやり方です。

格納時のメソッドで返り値として成否を行うのか、

別途Booleanをもたせるのか悩ましいところ。


オブジェクト主体で作成していると、妙な拡張のしやすさがが楽しいです。


昨日更新した鯛焼きも、上げた時点でのやり方を手続き型にしたら問題なかったのですが、


たくさんの鯛焼き機を用意するタイプに変更したところ、

手続き型での方法をパっと思いつかなくて、びっくりしました


雪だるま式(アジャイル型というほどちゃんとしてない)で

コード書いてくわたしにとってはひじょーに向いてそうです。


なんだかたのしくなってきました!


オブジェクト指向の解説の不思議な熱の入り方がちょっとだけ

わかった本日の授業でした。

オブジェクト指向を習ったばかりの初心者がJAVAで鯛焼きを焼いてみた

f:id:nazuna_0124:20170403224602p:plain

忙しいというのに、思いついたら試さずにはいられない!

インスタンスの説明でよくでてくる鯛焼きのおはなしです。


オブジェクト指向っぽく書くとこうなる気がする……?というもの。

仮定としてはこんなかんじ。

  • 鯛焼き機が2種類ある。
  • 鯛焼き機Aは1回焼くたびに50個焼ける。絶対壊れない。
  • 鯛焼き機Bは1回に100個焼ける。でも1%の確率で壊れる
  • それぞれに100回焼かせる。Bは壊れたらその時点でお休み。
  • 100回焼き勝負をの勝敗をカウント。それを10回実施して勝敗数を表示する。



ごめんね…あまりいい問題思いつかなくて…

結果はどんな感じになると思いますですか???



適当に連打した感じでは 3:7 、4:6でBが勝つほうが多かったです。


2:8以上でBが圧勝するのは結構あり、Aが勝つのはあんまり見ないという感じ。


実行結果です。

f:id:nazuna_0124:20170412224347p:plain


それでは肝心のソースです。4つのクラスから出来てます。

継承?は習ってないので、いまのところこれが限界。


Main.java

public class Main {
    public static void main(String[] args) {
       Judge j = new Judge();
       
       for (int k = 0 ; k<10 ; k++){
            TaiyakiBoxA boxA = new TaiyakiBoxA() ;
            TaiyakiBoxB boxB = new TaiyakiBoxB();
            
            for(int i = 0 ; i<100;i++){
                 boxA.yaku();
                 
                 //Bはこわれてなかったら焼く
                 if(boxB.status == true){
                    boxB.yaku(); 
                 }   
             }
             //100回焼きの結果表示
             j.result(boxA, boxB);
        } 
        //総合結果発表
        j.sumResult(); 
    }
}


TaiyakiBoxA.java

public class TaiyakiBoxA {
    int count = 0;
    Boolean status = true;
    
    void yaku(){
        this.count += 50 ;
    }
}


TaiyakiBoxB.java

public class TaiyakiBoxB {
    int count = 0;
    Boolean status = true;
    
    void yaku(){
        this.count += 100 ;
        
        int rnd = new java.util.Random().nextInt(99) +1;

        if (rnd == 1){
            this.status = false ;
        }
    }
}


Judge.java

public class Judge {
        int aWin = 0;
        int bWin = 0;
        int draw = 0;
        
    void result (TaiyakiBoxA a , TaiyakiBoxB b){
        String str ;
        
        if (a.count > b.count){
            str = "Aの勝ち!";
            this.aWin += 1;
        }else if(b.count > a.count){
            str = "Bの勝ち!";
            this.bWin += 1;
        }else{
            str = "引き分け!!";
            this.draw +=1 ;
        }
        
        System.out.println("A:" + a.count + "個" + " " +"B:" + b.count + "個" + " " + str );
    }
    
    void sumResult(){
        System.out.println("Aの勝利数:" + this.aWin + " " +"Bの勝利数" + this.bWin + " 引き分け" + this.draw);
    }
}


はて。。。なんで、これ作ったのか忘れてしまいました…


え、えと オブジェクト指向比喩を使っで説明してくれるのは

このMain.javaのすっきり感を伝えたいからのようなのです。

(少なくとも先生は)


Mainだけ追っていくと、Boxに焼かせて、勝敗の審判をJudgeさんに任せている。

これが現実と同じように見えるのだそうです。


書いておきながら自分であんまり腑に落ちてないですが

普通に書いたら違いがわかるのかも??? 


いつか作って見るかも!

いつかはこないフラグ

職業訓練の授業62日目~JAVA:オブジェクト指向の全体像~

f:id:nazuna_0124:20170303054656p:plain

目標の100記事に今月中には到達する見込みです。

100記事も書けばいくらわたしでも、ちゃんとした記事が書けるようになってるはず!!


そんな風に思っていた時期もありました。


結果はご覧の有り様。特に成長は見られません。

むしろスタイルとして固まってこじらせている感すらあります。


なんだかたくさんの読者登録を頂いて大変恐縮してます。

うっかり、たくさん拝見しにいくと自分と比べてだんだん落ち込んでいくので

ちょっと控え気味。


なんでそんなにきれいなデザインで長文書けるの!?


半ば逆切れしつつ、本日のお題です。


文章力自体に疑問を持ってるさなかにとうとう来ました。オブジェクト指向の解説です。


まずは先生の説明をざっくりとまとめ。

生まれた経緯

数万行もあるプログラムではクラス、メソッド分割では対応しきれない。

大規模開発に対応するために考え出された

学ぶためのコツ

今までの基本文法は、こう書かないとダメ、正解を学ぶ考え方。

オブジェクト指向は全体の捉え方、文法の組み合わせ方を学ぶ。

理解やイメージが大切

定義

開発時にもちいる部品化の考え方

明確な思想に則って部品化をおこなう

メリット

プログラムの変更が容易。

一部を簡単に転用できる。

ラクして楽しくいいものを作れる

手続き型との違い

先頭から順番に命令として記述している手続き型に対して、

現実世界の模倣として表現。

オブジェクトの責務

行動責任、情報保持責任の2つをもっている。

責任をはたすために

属性と操作を持つ


こんな感じで説明されたあと、オブジェクト指向の全体像を説明せよというお題が出題。

自分で考えて書いて、周りの人たちに発表する授業形態でした。


さて、あらためていろんなオブジェクト指向の説明を聞いての感想です


比喩使っての説明はうんざりです


印象としては、たとえば… 手紙からメール、メールからLINEにやりとりが変わったときに、

いかにメールがすごいかを説明されている感じです。


初心者なので先入観があんまりないのです。

わざわざ例えなくてもだいじょーぶ!


そんなわけで今のところの結論

  • オブジェクト指向」として理解しなくていい
  • クラスの作り方、使いまわし方、オブジェクトの利用方法を頑張って覚えてね
  • データはオブジェクトで表現しておくとよいかも


いつもどおりの雑な理解ですが、おいておいてとりあえず作ってみようと思います!

職業訓練の授業61日目~JAVA:クラス、パッケージ~

f:id:nazuna_0124:20170303232129p:plain

最近ちょっとだけ考えてたことがあります。

それはプログラミングの基礎段階でどこまでもつまづく人

プラグラミングの道を諦めたほうがよいかです。


トータルで50時間i以上はソース書いてるはずですが、FizzBuzzあたりで

戸惑うのをどうしようという。


ふと自分を振り返ってみたら、わたしがforループを問題なく使えるようになったのって

VBAでいろいろ作り始めてから半年くらいは経ってました


そう考えると気にしなくていいよーな気もします。


ただ、わたしはあんまりプラグラミングに向いてないので安心材料にはならないとゆー気も……。


好きなもの作って内に覚えられるのがベストですが、教える方としてはこれ大変なんですよねぇ。


わかんなくても楽しいなら続けたほうがいいんじゃないかなーというのが今のところの結論。


さて、話を戻しまして本日のお題です。


PHPでみるとクラスは新しいのですが、JAVAでみるとそれしかないので

今まで使ってたところの枠組み説明に収まりました。


VBAでいうところの標準モジュールかな。


インスタンスやコンストラクタの説明がまだなので、解説方法としては珍しい?

先生なりのやり方に期待です!


続いてパッケージです。パッケージの命名にはルールがあるよーという話と、

JAVAで何か呼び出すといつも長い原因です。


IDEにはクラスにパッケージを宣言すると、エラーを表示して

パケージ作って移動することができます。


若干この辺はNetbeansよりeclipseのほうが親切。

Netbeansはエディタ部分の左側にある電球マークをクリックですよ!!

(かなり迷った)


アルゴリズムの演習が多いので少し飽き気味です。


大規模開発に使うがゆえの学習コストの高さでしょうか。

めげずにやってみます!

職業訓練の授業60日目~JAVA:オーバーロード、基礎の復習

f:id:nazuna_0124:20170306210455p:plain


なずなは レベルがあがった!

なずなは オーバーロードを覚えた!!


本日のお題は名前のかっこよさに定評のあるオーバーロードです。


ぐぐったときや、動画でよく使われてるのに、意味がわからなくてイライラしてた単語です。

これでわかりました。は~ すっきり!


ただし、用途まではしっかり把握できてません。この辺は別にまとめたいです。


オーバーロードを学ぶ上での注意点は2つ。


  1. 要するに条件付きで同名のメソッドが作れるよ機能

  2. 用語が似てるオーバーライドとは別物だと思って良い


とりあえず2です。この違いがわかりにくいというのは、鍋と庖丁の違いがわからないというかんじ。


料理を作るための道具ってまで拡張すると同じですが、用途や役割は別です。


1はそのまんま、普段だめなのに条件満たせせば使えるよというもの。

そして問題はどんなときに使うの?です。

これが正直わからない… ひとまず思いついた分です!

今回は時間があまりないのでコード省略!


1. データ型の違いを吸収

データ型が違うだけでやること同じなのに、新しいメソッド作るのめんどくさ!

に対応できます。


2. 引数の省略に利用

関数でよくみますよね。引数いれるかどうかで戻り値に影響があるってタイプ。

ああいうのが作りやすくなりそうです。


3. 変更に対して柔軟に対応できる

これだけちゃちゃっと書いてみます。

正直いい例ではないのですが

public class Main{
  public static void main(String[] args) { 
       Keishou("たろう");
       Keishou("はなこ"); 
    }
    
    public static void Keishou(String name){
        System.out.println("おはよう!" + name + "さん");
    }
}

たとえば、男女問わずさん付けで呼んでいたとします。

これをもし、男女別の授業のときだけ「くん」と「ちゃん」に分けたくなったみたいなケースです。

public class Main{
    public static void main(String[] args) { 
       //朝の挨拶
       Keishou("たろう");
       Keishou("はなこ"); 
       
       //男女別授業の出席確認
        Keishou("たろう","男の子");
        Keishou("はなこ","女の子");
    }
    
    public static void Keishou(String name){
        System.out.println("おはよう!" + name + "さん");
    }
    
    public static void Keishou(String name , String sex){
        if (sex.equals("男の子")){
            System.out.println("おはよう!!!" + name + "くん");
        }else{
            System.out.println("おはよう!!!" + name + "ちゃん");
        }
    }

元の処理に影響与えること無く、分岐をかけられるってことですね。


4.処理の分岐 

分岐ができるから、柔軟に対応できるって意味ではあります。


おおむねこんなところでしょうか。

ポイントはなぜ別名じゃなくて同名にするのかになるんですが、

案外すっきりした答えは難しいです。


System.out.println(1);

System.out.println(“hello”);

System.out.println(1.1);


上記みたいに引数の型が違ってもちゃんと返ってくるのはこれのおかげといっていい?


そうするとデータ型指定のめんどくささを補完する機能というのが最有力かもです。

PHP初心者にこそ使ってほしいIDEの3つの機能~覚えたてこそ快適な環境で~

f:id:nazuna_0124:20170403224602p:plain

20日から噂の合同企業面談会があります。

少々忙しくなってしまうので、いまのうちに気になるところをさくっと更新。


また、この件に関してはわたしが始めたばっかりの頃に見つけられなかったことに

地味に腹がたってます。


昔のわたしにも見つけさせるべく、ほぼ同じ内容の記事を何度かあげようかと思っていたり。


配列くらいまでの基礎知識を覚えたあたりからが対象。

素早く間違えるために欲しい機能として下記3つです。



この辺がほしいので、諦めてIDEを使いましょう


今回はNetbensさんでgifだけ紹介しますが、おおむね同じ機能が外でもあるはずです。


実行機能

f:id:nazuna_0124:20170409223818g:plain


コードを入力したらすぐためす!

ブラウザにうつって更新とかめんどいのです。



テンプレート機能

f:id:nazuna_0124:20170409224601g:plain


一種の単語登録です。短い入力で呼び出しできます。


<?php ?> の複数回入力は本当にしんどいです…


evでのよびだしは自分で追加したもの。すぐ上の変数を格納するらしく、すばらしー!

デバッグ機能

f:id:nazuna_0124:20170409225550g:plain

昨日書いた記事が元ネタです。

shokuren.hateblo.jp


0.3で分岐したいのに入ってこないなー あれー???

ってなときの確認用。1行ずつ進める機能です。


学校では知らない人いっぱいいるのですよ!


なんだかんだプログラムは自分の作りたいものが作れるようになってからが本番です。


基礎だけで挫折してはもったいないので、初心者のうちこそ快適な環境を!!