20190327の新人プログラマ応援に関する記事は3件です。

デザインパターン ~Interpreter~

1. はじめに

GoFのデザインパターンにおける、Interpreterパターンについてまとめます。

2. Interpreterパターンとは

  • Interpreterという英単語は、通訳という意味になります。
  • Interpreterパターンは、何らかの形式で書かれたファイルの中身を、「通訳」の役目を果たすプログラムで解析・表現する方式です。
  • GoFのデザインパターンでは、振る舞いに関するデザインパターンに分類されます。

3. サンプルクラス図

Interpreter.PNG

4. サンプルプログラム

テキストファイルに書かれた言語を構文解析するプログラムです。
構文解析対象テキストで使う言語の文法ではBNF記法を使います。

<program> ::= program <command list>
<command list> ::= <command>* end
<command> ::= <repeat command> | <primitive command>
<repeat command> ::= repeat <number> <command list>
<primitive command> ::= go | right | left
  • <program>・・・トークン program の後にコマンドの列が続いたもの、になります。
  • <command list>・・・が0個以上繰り返したあとトークン end が続いたもの、になります。
  • <command>・・・繰り返しコマンドまたは基本コマンドのいずれか、になります。( | は or を表す)
  • <repeat command>・・・トークン repeat のあとに繰り返し回数が続き,さらにコマンドの列が続いたもの、になります。
  • <primitive command>・・・go または right または left 、になります。

4-1. Contextクラス

構文解析のための前後関係を表すクラスです。

Context.java
import java.util.StringTokenizer;

public class Context {

    private StringTokenizer tokenizer;
    private String currentToken;

    public Context(String text) {
        tokenizer = new StringTokenizer(text);
        nextToken();
    }

    public String nextToken() {
        if (tokenizer.hasMoreTokens()) {
            currentToken = tokenizer.nextToken();
        } else {
            currentToken = null;
        }
        return currentToken;
    }

    public String currentToken() {
        return currentToken;
    }

    public void skipToken(String token) throws Exception {
        if (!token.equals(currentToken)) {
            throw new Exception("Warning: " + token + " is expected, but " + currentToken + " is found.");
        }
        nextToken();
    }

    public int currentNumber() throws Exception {
        int number = 0;
        try {
            number = Integer.parseInt(currentToken);
        } catch (NumberFormatException e) {
            throw new Exception("Warning: " + e);
        }
        return number;
    }
}

4-2. Nodeクラス

構文木の「ノード」となるクラスです。

Node.java
public abstract class Node {
    public abstract void parse(Context context) throws Exception;
}

4-3. ProgramNodeクラス

に対応するクラスです。

ProgramNode.java
// <program> ::= program <command list>
public class ProgramNode extends Node {

    private Node commandListNode;

    public void parse(Context context) throws Exception {
        context.skipToken("program");
        commandListNode = new CommandListNode();
        commandListNode.parse(context);
    }

    public String toString() {
        return "[program " + commandListNode + "]";
    }
}

4-4. CommandNodeクラス

に対応するクラスです。

CommandNode.java
// <command> ::= <repeat command> | <primitive command>
public class CommandNode extends Node {

    private Node node;

    public void parse(Context context) throws Exception {
        if (context.currentToken().equals("repeat")) {
            node = new RepeatCommandNode();
            node.parse(context);
        } else {
            node = new PrimitiveCommandNode();
            node.parse(context);
        }
    }

    public String toString() {
        return node.toString();
    }
}

4-5. RepeatCommandNodeクラス

に対応するクラスです。

RepeatCommandNode.java
// <repeat command> ::= repeat <number> <command list>
public class RepeatCommandNode extends Node {

    private int number;
    private Node commandListNode;

    public void parse(Context context) throws Exception {
        context.skipToken("repeat");
        number = context.currentNumber();
        context.nextToken();
        commandListNode = new CommandListNode();
        commandListNode.parse(context);
    }

    public String toString() {
        return "[repeat " + number + " " + commandListNode + "]";
    }
}

4-6. CommandListNodeクラス

に対応するクラスです。

CommandListNode.java
import java.util.ArrayList;

// <command list> ::= <command>* end
public class CommandListNode extends Node {

    private ArrayList list = new ArrayList();

    public void parse(Context context) throws Exception {
        while (true) {
            if (context.currentToken() == null) {
                throw new Exception("Missing 'end'");
            } else if (context.currentToken().equals("end")) {
                context.skipToken("end");
                break;
            } else {
                Node commandNode = new CommandNode();
                commandNode.parse(context);
                list.add(commandNode);
            }
        }
    }

    public String toString() {
        return list.toString();
    }
}

4-7. PrimitiveCommandNodeクラス

に対応するクラスです。

PrimitiveCommandNode.java
// <primitive command> ::= go | right | left
public class PrimitiveCommandNode extends Node {

    private String name;

    public void parse(Context context) throws Exception {
        name = context.currentToken();
        context.skipToken(name);
        if (!name.equals("go") && !name.equals("right") && !name.equals("left")) {
            throw new Exception(name + " is undefined");
        }
    }

    public String toString() {
        return name;
    }
}

4-8. 構文解析対象テキスト

構文解析対象となるテキストです。

program.txt
program end
program go end
program go right go right go right go right end
program repeat 4 go right end end
program repeat 4 repeat 3 go right go left end right end end

4-9. Mainクラス

メイン処理を行うクラスです。

Main.java
import java.io.BufferedReader;
import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        try {
            BufferedReader reader = new BufferedReader(new FileReader("program.txt"));
            String text;
            while ((text = reader.readLine()) != null) {
                System.out.println("text = \"" + text + "\"");
                Node node = new ProgramNode();
                node.parse(new Context(text));
                System.out.println("node = " + node);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4-10. 実行結果

text = "program end"
node = [program []]
text = "program go end"
node = [program [go]]
text = "program go right go right go right go right end"
node = [program [go, right, go, right, go, right, go, right]]
text = "program repeat 4 go right end end"
node = [program [[repeat 4 [go, right]]]]
text = "program repeat 4 repeat 3 go right go left end right end end"
node = [program [[repeat 4 [[repeat 3 [go, right, go, left]], right]]]]

5. メリット

Interpreterパターンを利用することで、規則の追加や変更が容易になります。
Interpreterパターンの特徴の1つに、「1つの規則を1つのクラスで表す」というものが挙げられます。つまり、新しい規則を追加する場合はNodeクラスのサブクラスを追加するだけで良くなります。
また、規則を修正する場合も、Nodeクラスのサブクラスを修正するだけになります。

6. GitHub

7. デザインパターン一覧

8. 参考

今回の記事、及びサンプルプログラムは、以下の書籍を元に作成させて頂きました。

大変分かりやすく、勉強になりました。感謝申し上げます。
デザインパターンやサンプルプログラムについての説明が詳細に書かれていますので、是非書籍の方もご覧ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

手を動かしてプログラミングをする意味

はじめに

こんにちは。

僕はこの4月で社会人生活3年目を迎えます。大学はがっつりプログラミング系の専攻を学んでまして、卒業後エンジニアの仕事をしています。僕の今までのQiitaの記事はJavaScript関連の記事が中心に書かせていただいたのですが、今回の記事ではいつもの記事と全然違う記事を書いていこうかなと思います。

今回の記事は「プログラミング」ってどうやって勉強するんだろう?ということを自分なりにまとめてみました。実際自分自身も大学入学するまで「プログラミング」というものをまったく知らなかったし、どんな勉強すればいいねん?と嘆いていたので、もし同じ境遇の方々がいたら、役に立ててもらえると幸いです。

※軽めの自己紹介
プログラミング7年目(底辺)
フロントエンド系のエンジニアをしています。
仕事はほぼJavaScriptしかいじっていませんので、JavaScript関連には慣れてきましたが「日々勉強は怠らず」をモットーに頑張っています。ほかの技術(Golang,AWS)も勉強中です。

この記事の対象

  • 4月から社会人として「新人エンジニア」になる人(特に大学であまりプログラミングをやっていなかった人)
  • 未経験からエンジニアになりたい
  • 大学(高校)からプログラミングを学ぶ人

要はこの記事の対象は、

  • 全然プログラミングとかやってこなかったけど来月からエンジニアだ...やばい...」って思う人
  • プログラミングに興味あるけどどうやって勉強しようかな...?」って思う人
  • これからプログラミングを学ぶんだ!頑張ろう!」って思う人

を対象にしています。

今までプログラミングは「覚える」ものだと思っていた

大学や会社の研修の中でプログラミング系の教科書や参考書を買ったりすると思います。僕に関していうと、大学では最初にC言語を勉強することになったので、参考書として最初に買ったのは「苦しんで覚えるC言語」という参考書を買いました。この参考書を買った理由は単純に名前で選びました。「どうせプログラミングなんて苦しむものだろ!買っちゃえ!」っていう心情からこの本を買ったんですが、この本の内容を丸暗記しようとしたことが間違いの始まりですね。

参考:苦しんで覚えるC言語

プログラミングの暗記は多分意味がない

この本の内容を覚えたら、大学のどんな課題も楽勝だぜ!って思って暗記を始めましたが、結論から申し上げると楽勝どころか、課題に負ける方が圧倒的に多かったです。(今考えるとなにやってるんだ...と思います...)

え、この問題、【進〇ゼミ】でやった問題だ!!!!!!!この問題もらったぜ!!!!!」とは残念ながらなりません。参考書でててくる問題がそのまま大学の課題や定期試験で出ることなどまずないです(あったら奇跡だと思った方がいいです)。部分的に似ている問題はでてくるかもしれませんが。たとえば、大学の先生が「この問題、一語一句そのまま変えずテストに出すぞ!」と言ったなら、それは暗記したほうがいいかもしれません。

僕が重要だと思うのは参考書で出てくる用語・文法・問題をどのような形で勉強するかかが大事だと思っています。この捉え方によって、いろんなプログラムを書く効率性や柔軟性が変わってくると考えています。ここでいう「用語・文法・問題」は下の箇条書きでまとめています。

  • 用語
    • プログラミング業界(IT業界)で出てくる言葉
      • 例:コンパイラ、メモリ、OS、ネットワーク
  • 文法
    • プログラミングをする上でのルール事項
      • 例:変数宣言時はC言語では〇〇で、JavaScriptでは□□だよ~。
  • 問題
    • 参考書等で出てくるサンプル問題(とその解答例)
      • 例:次の〇〇をC言語で実装せよ。

まずは参考書で抑えておくべき用語や文法は覚えましょう。特に文法に関して言うならば、これから何回も出てくるフレーズ等(例:条件文、関数、継承)があるので抑えておきましょう。参考書で出てくる問題はそのまま覚えるのではなく、流れをつかんだうえで勉強しましょう。

例えば以下の問題があるとします。

2つの整数の大きい方を選ぶ関数を作成しなさい。2つの int 型引数を取り、大きい方の数値を戻り値として返すこと。

簡単な問題を選びましたが、「この問題が来たらこのコードだ!」って言って参考書の回答のプログラムを読んでそのまま貼り付けて「はいはい、わかりましたー」はもちろんだめです。問題の流れをとらえましょう。

問題の流れを紙に書く(視覚化する)

僕は、最初はよく紙で問題の流れを視覚化して、自分がちゃんと問題が理解できるレベルまで問題をかみ砕いて、そのあとにPCでプログラムを書いていました(iPadのメモ機能+ペンでも可)。
この視覚化した図は、人に説明するときにすごく便利になります。「こういう機能を実装するので、こんなプログラムを書きました」って口では言えるんですが、聞いた相手が具体的なイメージをもっているかはわかりません。そのイメージをより分かりやすくするために流れを視覚化してしましょう。

この問題でいうと以下の通りです。

問題2つの整数の大きい方を選ぶ関数を作成しなさい。2つの int 型引数を取り、大きい方の数値を戻り値として返すこと。

=====考え方=====
1. 「2つの整数」→ int型を定義する(この整数の範囲ってどうなのかな~?負の数も扱っていいのかな~?)。
2. 「大きい方を選ぶ」→ 比較(この2つの整数に対してif文だね~。)
3. 「関数を作成しなさい」→ 関数を作る(function(){}みたいな形だね~。)
4. 「大きい方の数値を戻り値として返すこと」→return文を使う。戻り値は整数。(int 関数名(引数){return}みたいな形だね~~)
=============
という感じで問題を細分化していきます。問題文をかみ砕いていくと文法単位で扱えるようになります。ここで初めて「進〇ゼミでやった問題だ!!(問題というよりも見たことあるフレーズじゃん!!)」って感覚が生まれます。ちなみに先ほどの問題の解答例は以下です。

//大きい数値を返す関数を定義
int MaxValueChoice(int num1,int num2){
    if(num1 > num2){//比較
        return num1 //戻り値
    }else{
        return num2
    }
}

プログラミングは暗記というよりも、プログラミングで何を実装したいかのイメージを細分化して、その細かい部分(要素)を1つ1つ作り、それを重ねることでプログラミングが上達するのでないかなと思います。文法とかも忘れちゃってもGoogle先生で検索して引っ張り出すこともできるので安心してください。しかし、ただイメージするだけではなく、先ほどの「プログラミングを視覚化する」といったような行程同様に「手を動かしてプログラミングをすること」も大事になってきます。

※プログラミングの考え方等は「リーダブルコード」にまとめられていて、読みやすくわかりやすいです。
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

手を動かしてプログラミング(アウトプット)するだけで全然違う

手を動かして、プログラミングを勉強するだけで全然違います。またその自分が作ったプログラムを誰かに説明することも大事だと考えています。例えばチームでプログラムを作っていると必ずと言っていいほど、誰かから聞かれます。

このコードの意図を教えて

ここで「仕様書にそうやって書いていましたー」と言いたくなります。きっと我々が書いているプログラムは当たり前ですけど、1行1行ちゃんと意味があります。たかが1行改行したことでも変数を宣言することでも意味はちゃんとあります。チームでプログラムを作るうえで上司等に説明をする機会があると思いますが、自分ひとりでプログラミングの勉強をする中でも、自分が作ったプログラム1行1行をちゃんと説明できるように心がけましょう。そしてその訓練を積み重ねていってください。

また実行結果も確認しましょう。実行結果はうまくいけば自分が意図した結果が出てくるとは思いますが、うまくいかないとエラーが吐かれます。「なんやねん!このエラー!やめた!」って言って逃げたくなる気持ちもわかります。ただ逃げるのではなく、Googleで調べたり人に聞くことでエラーを解決することもプログラミングの一工程です。プログラミングはうまくいかないこと(自分が実装したいことがうまく表現できないこと)の方が多いです。最初は地道にプログラムの1行1行とにらめっこして、「こうでもない、ああでもない」と言いながら1日が過ぎるかもしれません。でもプログラミングってそういうものです。「最初は」と言いましたが、僕は今でも意味わからないエラーが出てきて、Googleに助けてもらっている日々です。プログラミングはプログラムを書いて、エラーが出て、調べて、修正して、またエラーが出て、、、(以下ループ)といったような形で日々学んでいくものだと思います。プログラムを書くという作業を起点にいろいろ成長すると思うので、ぜひ手を動かしてプログラミングしていきましょう!

逆を言うと本を読んで、プログラミングが理解したという感情は捨てましょう。正確にいうならば「プログラミングの土台ができていない上で、本を眺めてコードを理解する」のはやめましょう。プログラミング文法が理解でき、プログラミング等のアウトプットの練習をそれなりにしているのであれば、復習がてらにコードを眺めるのはいいことだと思います。どの学問でもそうですが基本という土台が崩れると誤った解釈がおこるかもしれません。プログラミングの土台というのは明確に定まったものではありませんが、例として、文法の基礎基本を繰り返して、自分で考えたプログラムが数千行程度書いて、実行結果がうまくいったら、土台ができているとみなしてもいいかもしれません。

このように、地道な訓練の中を通じて、プログラミングの文法を学び、色々考えながら自分のプログラムを作り、エラーと戦い、そのプログラムを実行することで自分のプログラミングとしての土台ができると思います。

まとめ

プログラミングは難しいです。しかし、プログラミングに対して「楽しい」という感情が少しでも現れると、それは1歩成長したことだと思います。プログラミングは1週間で完璧になるようなものではないし、そもそも完璧になれません。なので、地道に進むしかないです。地道に頑張るしかないと思います。

あとはプログラミングのモチベーションを保つために、自分がやっていることは達成感を積み重ねることです。例えば毎日1個だけでもいいので、できた(理解した)ことをメモしましょう。今日はこういう関数を作った、また別の日にはその関数にこういう機能を加えた、またまた別の日はポインタについてのプログラムを書いた、とかとか。プログラミングのモチベーションの保ち方は人それぞれかもしれませんが、なににせよ続けることが大事だと思います。

今回のこの記事は50%自分のために書いた感じもあります。最近Qiitaのトレンド等で書いてある記事やプログラムを見て、「ああ~~すごいなあ~~いつかこうなりたいなあ~~」って思っただけで、結局寝るといったことが多かったので、初心に戻って「手を動かしてプログラムを書く」ことを忘れずに頑張ろうかなと思って書きました。また、4月から社会人スタートだったりといろんな挑戦が始まると思いますが、あきらめず頑張ってください!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

手を動かしてプログラミングをする意味【新人向け】

はじめに

こんにちは。

僕はこの4月で社会人生活3年目を迎えます。大学はがっつりプログラミング系の専攻を学んでまして、卒業後エンジニアの仕事をしています。僕の今までのQiitaの記事はJavaScript関連の記事が中心に書かせていただいたのですが、今回の記事ではいつもの記事と全然違う記事を書いていこうかなと思います。

今回の記事は「プログラミング」ってどうやって勉強するんだろう?ということを自分なりにまとめてみました。実際自分自身も大学入学するまで「プログラミング」というものをまったく知らなかったし、どんな勉強すればいいねん?と嘆いていたので、もし同じ境遇の方々がいたら、役に立ててもらえると幸いです。

※軽めの自己紹介
プログラミング7年目(底辺)
フロントエンド系のエンジニアをしています。
仕事はほぼJavaScriptしかいじっていませんので、JavaScript関連には慣れてきましたが「日々勉強は怠らず」をモットーに頑張っています。ほかの技術(Golang,AWS)も勉強中です。

この記事の対象

  • 4月から社会人として「新人エンジニア」になる人(特に大学であまりプログラミングをやっていなかった人)
  • 未経験からエンジニアになりたい
  • 大学(高校)からプログラミングを学ぶ人

要はこの記事の対象は、

  • 全然プログラミングとかやってこなかったけど来月からエンジニアだ...やばい...」って思う人
  • プログラミングに興味あるけどどうやって勉強しようかな...?」って思う人
  • これからプログラミングを学ぶんだ!頑張ろう!」って思う人

を対象にしています。

今までプログラミングは「覚える」ものだと思っていた

大学や会社の研修の中でプログラミング系の教科書や参考書を買ったりすると思います。僕に関していうと、大学では最初にC言語を勉強することになったので、参考書として最初に買ったのは「苦しんで覚えるC言語」という参考書を買いました。この参考書を買った理由は単純に名前で選びました。「どうせプログラミングなんて苦しむものだろ!買っちゃえ!」っていう心情からこの本を買ったんですが、この本の内容を丸暗記しようとしたことが間違いの始まりですね。

参考:苦しんで覚えるC言語

プログラミングの暗記は多分意味がない

この本の内容を覚えたら、大学のどんな課題も楽勝だぜ!って思って暗記を始めましたが、結論から申し上げると楽勝どころか、課題に負ける方が圧倒的に多かったです。(今考えるとなにやってるんだ...と思います...)

え、この問題、【進〇ゼミ】でやった問題だ!!!!!!!この問題もらったぜ!!!!!」とは残念ながらなりません。参考書でててくる問題がそのまま大学の課題や定期試験で出ることなどまずないです(あったら奇跡だと思った方がいいです)。部分的に似ている問題はでてくるかもしれませんが。たとえば、大学の先生が「この問題、一語一句そのまま変えずテストに出すぞ!」と言ったなら、それは暗記したほうがいいかもしれません。

僕が重要だと思うのは参考書で出てくる用語・文法・問題をどのような形で勉強するかかが大事だと思っています。この捉え方によって、いろんなプログラムを書く効率性や柔軟性が変わってくると考えています。ここでいう「用語・文法・問題」は下の箇条書きでまとめています。

  • 用語
    • プログラミング業界(IT業界)で出てくる言葉
      • 例:コンパイラ、メモリ、OS、ネットワーク
  • 文法
    • プログラミングをする上でのルール事項
      • 例:変数宣言時はC言語では〇〇で、JavaScriptでは□□だよ~。
  • 問題
    • 参考書等で出てくるサンプル問題(とその解答例)
      • 例:次の〇〇をC言語で実装せよ。

まずは参考書で押さえておくべき用語や文法は覚えましょう。特に文法に関して言うならば、これから何回も出てくるフレーズ等(例:条件文、関数、継承)があるので押さえておきましょう。参考書で出てくる問題はそのまま覚えるのではなく、流れをつかんだうえで勉強しましょう。

例えば以下の問題があるとします。

2つの整数の大きい方を選ぶ関数を作成しなさい。2つの int 型引数を取り、大きい方の数値を戻り値として返すこと。

簡単な問題を選びましたが、「この問題が来たらこのコードだ!」って言って参考書の回答のプログラムを読んでそのまま貼り付けて「はいはい、わかりましたー」はもちろんだめです。問題の流れをとらえましょう。

問題の流れを紙に書く(視覚化する)

僕は、最初はよく紙で問題の流れを視覚化して、自分がちゃんと問題が理解できるレベルまで問題をかみ砕いて、そのあとにPCでプログラムを書いていました(iPadのメモ機能+ペンでも可)。
この視覚化した図は、人に説明するときにすごく便利になります。「こういう機能を実装するので、こんなプログラムを書きました」って口では言えるんですが、聞いた相手が具体的なイメージをもっているかはわかりません。そのイメージをより分かりやすくするために流れを視覚化してしましょう。

この問題でいうと以下の通りです。

問題2つの整数の大きい方を選ぶ関数を作成しなさい。2つの int 型引数を取り、大きい方の数値を戻り値として返すこと。

=====考え方=====
1. 「2つの整数」→ int型を定義する(この整数の範囲ってどうなのかな~?負の数も扱っていいのかな~?)。
2. 「大きい方を選ぶ」→ 比較(この2つの整数に対してif文だね~。)
3. 「関数を作成しなさい」→ 関数を作る(function(){}みたいな形だね~。)
4. 「大きい方の数値を戻り値として返すこと」→return文を使う。戻り値は整数。(int 関数名(引数){return}みたいな形だね~~)
=============
という感じで問題を細分化していきます。問題文をかみ砕いていくと文法単位で扱えるようになります。ここで初めて「進〇ゼミでやった問題だ!!(問題というよりも見たことあるフレーズじゃん!!)」って感覚が生まれます。ちなみに先ほどの問題の解答例は以下です。

//大きい数値を返す関数を定義
int MaxValueChoice(int num1,int num2){
    if(num1 > num2){//比較
        return num1 //戻り値
    }else{
        return num2
    }
}

プログラミングは暗記というよりも、プログラミングで何を実装したいかのイメージを細分化して、その細かい部分(要素)を1つ1つ作り、それを重ねることでプログラミングが上達するのでないかなと思います。文法とかも忘れちゃってもGoogle先生で検索して引っ張り出すこともできるので安心してください。しかし、ただイメージするだけではなく、先ほどの「プログラミングを視覚化する」といったような行程同様に「手を動かしてプログラミングをすること」も大事になってきます。

※プログラミングの考え方等は「リーダブルコード」にまとめられていて、読みやすくわかりやすいです。
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック

手を動かしてプログラミング(アウトプット)するだけで全然違う

手を動かして、プログラミングを勉強するだけで全然違います。またその自分が作ったプログラムを誰かに説明することも大事だと考えています。例えばチームでプログラムを作っていると必ずと言っていいほど、誰かから聞かれます。

このコードの意図を教えて

ここで「仕様書にそうやって書いていましたー」と言いたくなります。きっと我々が書いているプログラムは当たり前ですけど、1行1行ちゃんと意味があります。たかが1行改行したことでも変数を宣言することでも意味はちゃんとあります。チームでプログラムを作るうえで上司等に説明をする機会があると思いますが、自分ひとりでプログラミングの勉強をする中でも、自分が作ったプログラム1行1行をちゃんと説明できるように心がけましょう。そしてその訓練を積み重ねていってください。

また実行結果も確認しましょう。実行結果はうまくいけば自分が意図した結果が出てくるとは思いますが、うまくいかないとエラーが吐かれます。「なんやねん!このエラー!やめた!」って言って逃げたくなる気持ちもわかります。ただ逃げるのではなく、Googleで調べたり人に聞くことでエラーを解決することもプログラミングの一工程です。プログラミングはうまくいかないこと(自分が実装したいことがうまく表現できないこと)の方が多いです。最初は地道にプログラムの1行1行とにらめっこして、「こうでもない、ああでもない」と言いながら1日が過ぎるかもしれません。でもプログラミングってそういうものです。「最初は」と言いましたが、僕は今でも意味わからないエラーが出てきて、Googleに助けてもらっている日々です。プログラミングはプログラムを書いて、エラーが出て、調べて、修正して、またエラーが出て、、、(以下ループ)といったような形で日々学んでいくものだと思います。プログラムを書くという作業を起点にいろいろ成長すると思うので、ぜひ手を動かしてプログラミングしていきましょう!

逆を言うと本を読んで、プログラミングが理解したという感情は捨てましょう。正確にいうならば「プログラミングの土台ができていない上で、本を眺めてコードを理解する」のはやめましょう。プログラミング文法が理解でき、プログラミング等のアウトプットの練習をそれなりにしているのであれば、復習がてらにコードを眺めるのはいいことだと思います。どの学問でもそうですが基本という土台が崩れると誤った解釈がおこるかもしれません。プログラミングの土台というのは明確に定まったものではありませんが、例として、文法の基礎基本を繰り返して、自分で考えたプログラムが数千行程度書いて、実行結果がうまくいったら、土台ができているとみなしてもいいかもしれません。

このように、地道な訓練の中を通じて、プログラミングの文法を学び、色々考えながら自分のプログラムを作り、エラーと戦い、そのプログラムを実行することで自分のプログラミングとしての土台ができると思います。

まとめ

プログラミングは難しいです。しかし、プログラミングに対して「楽しい」という感情が少しでも現れると、それは1歩成長したことだと思います。プログラミングは1週間で完璧になるようなものではないし、そもそも完璧になれません。なので、地道に進むしかないです。地道に頑張るしかないと思います。

あとはプログラミングのモチベーションを保つために、自分がやっていることは達成感を積み重ねることです。例えば毎日1個だけでもいいので、できた(理解した)ことをメモしましょう。今日はこういう関数を作った、また別の日にはその関数にこういう機能を加えた、またまた別の日はポインタについてのプログラムを書いた、とかとか。プログラミングのモチベーションの保ち方は人それぞれかもしれませんが、なににせよ続けることが大事だと思います。

今回のこの記事は50%自分のために書いた感じもあります。最近Qiitaのトレンド等で書いてある記事やプログラムを見て、「ああ~~すごいなあ~~いつかこうなりたいなあ~~」って思っただけで、結局寝るといったことが多かったので、初心に戻って「手を動かしてプログラムを書く」ことを忘れずに頑張ろうかなと思って書きました。また、4月から社会人スタートだったりといろんな挑戦が始まると思いますが、あきらめず頑張ってください!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む