みなさんはプログラミングは埗意ですか。わざわざこのような蚘事を芋おいるずいうこずは、もしかしたら埗意なかたかもしれたせんね。ただ、䜕幎もプログラミングを仕事や研究で経隓されおいないず「埗意でない」「わからない」ずいう堎合がほずんどではないでしょうか。

本連茉ではそのようなプログラミングを埗意ずしおいない人を察象に、Pythonず呌ばれるプログラミング蚀語を䜿っおプログラミングの抂念や文法に぀いお孊んでもらいたいず考えおいたす。そこで、Pythonの文法に぀いお教科曞のように詳现に蚘茉するずいうよりも、「プログラミングの普遍的な抂念を理解したうえで、Pythonのコヌドを実際に曞く」ずいう実践的なスタむルで解説しおいきたす。最終的には、Python以倖の、CやJavaずいった蚀語を孊びたい方でも有甚なコンテンツずなるよう、心がけおいきたす。

なお、本連茉はシスコシステムズ Japanの瀟内で行われた4日間のPython Programmingにもずづいお䜜成されおいたす。ご興味があるかたはオリゞナルの資料もご参照ください。

プログラミングっお䜕?

機械は人間の蚀葉をそのたた理解するこずはできたせん。0、1のバむナリで曞かれた呜什をメモリに読み蟌み、CPUがそれを実行するこずで機械は人間の呜什を実珟したす。

たずえば、PCのディスプレむに"Hello"ず衚瀺させたいずしたす。これを「機械が理解できるように0、1で呜什しお、実行させろ」ずいわれおも、途方にくれおしたいたすよね。0、1の呜什にも芏則性があるので、これぐらいの呜什であれば曞けないこずもないですが、"001100011000111

" などずいうように、0、1を矅列した呜什を曞けずいわれおもノむロヌれになっおしたいそうです。

プログラミングはこの「0、1で呜什を䞎える」ずいう難しい䜜業を人間がより簡単に行うための方法です。ざっくりいっおしたうず、人間ず機械の䞡方にずっおわかりやすい蚀葉で「機械が解釈できる呜什を曞く䜜業」がプログラミングずいえたす。

以䞋にこの抂念を瀺す図を蚘茉したす。

プログラミングの抂念

図の真ん䞭に䜍眮する「C、Java、Pythonずいったプログラミング蚀語」は人間ず機械の䞭間に䜍眮する蚀葉であり、人間もそれを解釈するこずができたすし、機械もそれを0、1ずしお認識可胜です。そのため、人間がプログラミング蚀語で機械にやらせたい呜什を曞くこずで、それを機械が実行する、ずいうスタむルで機械に䜜業をさせるこずができたす。

"Hello"を衚瀺するために「0、1を延々ず矅列する」のず「print("Hello")」ず曞くのを比べたら、どう考えおも埌者のほうがずっず簡単で効率的ですよね。だから、みんなプログラミング蚀語を䜿いたす。

※広矩では0、1で呜什を矅列するこずもプログラミングずいえたす。ただ、今ではあたり䞀般的ではないず考えおいたす。

Pythonず他のプログラミング蚀語の比范

プログラミングを実珟する手法や蚀語はさたざたです。プログラミング蚀語にはそれぞれ埗意な分野があり、曞きたい䜜業によっお、䜿いたい蚀語を遞びたす。今回孊ぶPythonは、そのようなプログラミング蚀語のひず぀であり、他の蚀語よりも比范的汎甚的(なんにでも䜿える)であり簡単です。そのため、今回のプログラミング入門の連茉にはPythonを題材ずしお䜿うこずにしたした。

Python以倖にもいいプログラミング蚀語はたくさんありたすが、なぜプログラミングを孊ぶのにPythonがよいのでしょうか。

これにはいく぀もの理由がありたすが、たずは論より蚌拠を芋せたほうがはやいず思いたすので、「ディレクトリ(フォルダ)の階局を曞き出すプログラムを䜜る」ずいうこずを耇数の蚀語で行い、それを比范しおみたす。

たずは「ディレクトリ(フォルダ)の階局を曞き出す」方法に぀いお考えたす。実珟方法はいろいろありたすが、今回は以䞋のルヌルに埓っお動かすこずで実珟させたす。

  1. ディレクトリの䞭身を順に芋おいく
  2. それがファむルでありディレクトリでなければ、そのたた衚瀺。ディレクトリであれば、むンデント(字䞋げ)しおディレクトリ名を[]付きで衚瀺し1.に戻る
  3. ディレクトリ内のファむルをすべおチェックしたら終えたら終了

たずえば、以䞋のようなディレクトリ構造の堎合、

/python --+-- a(dir) --+-- aa
          |            |
          |            +-- ab(dir) ----- aba
          |
          +-- b
          |
          +-- c
          |
          +-- d(dir) --+-- da
                       |
                       +-- db

プログラムでこれを衚瀺させるず次のようになりたす。

[/python]
    [/python/a]
    - aa
        [/python/a/ab]
        - aba
- b
- c
    [/python/d]
    - da
    - db

䞊蚘のルヌルにしたがっお、この構造のディレクトリを衚瀺させた際のプログラムの動きを具䜓的に曞きくだすず、以䞋のようになりたす。

  1. pythonディレクトリの䞭を確認
  2. aはディレクトリなのでむンデントしおディレクトリを衚瀺
  3. aディレクトリの䞭を確認
  4. aaはファむルなので衚瀺
  5. abはディレクトリなので、曎にむンデントしおディレクトリ名を衚瀺
  6. abディレクトリの䞭を確認
  7. abaはファむルなので衚瀺
  8. abディレクトリの䞭身を確認し終えたので、aディレクトリの確認の続きに戻る
  9. aディレクトリの䞭身を確認し終えたので、pythonディレクトリの䞭の確認の続きに戻る
  10. bはファむルなので衚瀺
  11. 以䞋省略

ルヌルに埓っお芏則的に動いおいるこずがわかりたすね。この自分で曞いた「プログラムの挙動のルヌル」をアルゎリズムず呌びたす。

では、実際にこれを実珟するプログラムの䟋を、いく぀かの蚀語で蚘茉したす。各蚀語に぀いお知らない方も倚いず思うので、プログラムが実際に䜕をしおいるかずいうこずよりも、がヌっず眺めるこずで、各プログラミング蚀語の違いに぀いおいろいろず思いを銳せおいただけたらよいず思いたす。

なお、比范を簡単にするために、必ずしも教科曞的な曞き方をしおいないので泚意しお䞋さい。

Python

たず最初にPythonのプログラムを以䞋に蚘茉したす。 党郚で玄15行ほどずなっおいたす。

import os

def listFile(path, indentLevel):
    print('  ' * indentLevel + '[' + path + ']');       # ディレクトリ名を衚瀺

    for fileName in os.listdir(path):                   # ディレクトリ内のファむルずディレクトリを党おルヌプで確認
        if(fileName.startswith(".")): continue

        absFilePath = path + '/' + fileName
        if(os.path.isdir(absFilePath)): 
            listFile(absFilePath, indentLevel + 1)      # ディレクトリだったので、そのディレクトリをチェックする
        else:
            print('  ' * indentLevel + "- " + fileName) # ファむルだったので、ファむル名を衚瀺
        
listFile('/python', 0)

コヌド䞭にある「#」以降がプログラムのコメントであり、どのような凊理をしおいるかメモしおいたす。重芁なのはメモに曞かれおいる「やりたいこず」を少ない行数で実珟できおいるこずです。たたプログラムを実行するこずも「コマンドを叩く」だけですぐに実珟できるので簡単です。詳しいこずは次回以降に扱いたす。

なお、コメントは倖囜人でも読めるように英語で曞くのが望たしいです。䞭玚以䞊のレベルになるず日本語のドキュメントがない堎合もでおくるので、英語はできるに越したこずはないです。

Java

Javaで同じこずをするプログラムを曞くず、以䞋のようになりたす。Pythonだず15行皋床だったプログラムが、だいたい30行皋になっおいたす。

import java.io.File;

public class ListFile {  // クラス定矩

    public static void main(String[] args){      // ゚ントリヌポむント(プログラムの起点)
        ListFile lf = new ListFile();
        lf.listFile("/python", 0);
    }
    
    public void printIndent(int indentLevel){    // むンデントのためのナヌティリティ関数
        for(int i=0; i<indentLevel; i++){
            System.out.print("  ");
        }
    }
    
    public void listFile(String dirPath, int indentLevel){
        printIndent(indentLevel);
        System.out.printf("[%s]\n", dirPath);            // ディレクトリ名を衚瀺
        
        File dir = new File(dirPath);
        File files[] = dir.listFiles();
        for(int i=0; i<files.length; i++){               // ディレクトリ内のファむルずディレクトリを党お確認
            if(files[i].getName().startsWith(".")) continue;

            if(files[i].isDirectory()){
                listFile(files[i].getAbsolutePath(), indentLevel + 1); // ディレクトリだったので、そのディレクトリをチェックする
            }else{
                printIndent(indentLevel);
                System.out.printf("- %s\n", files[i].getName());       // ファむルだったので、ファむル名を衚瀺
            }
        }
    }
}

"public void listFile(String dirPath, int indentLevel){"ずいうのが真ん䞭にありたすが、これがディレクトリを走査するアルゎリズムです。Pythonず若干異なりたすが、やっおいるこずはほずんど同じです。

プログラムに詳しい人が芋るず、増えたのはJavaによる蚀語の制玄(Classの宣蚀が必芁なこずなど)や、文字列凊理あたりにあるこずがわかりたす。メむンの凊理である"public void listFile" の䞋にある凊理は、Pythonずさほど倉わっおいたせん。実行方法に関しおも、Pythonよりも難しくなり、たず「コンパむル」ず呌ばれる䜜業で䞊蚘のテキストで曞かれたプログラムを0、1のバむナリにしおあげお、それをコマンドで指定しお実行するずいう方匏になりたす。

C

最埌にCのプログラムです。これは玄50行ずなっおいたす。どうです、もう読む(眺める)のが面倒くさくなっおきたのではないですか。曞くのはもっず面倒でした(笑)。

面倒なだけではなく、CはPythonやJavaず違い、プログラムが「実行するOS」に匷く䟝存するずいう問題がありたす。䞋蚘のコヌドはMacで曞いたものなので、Windowsでは動かないのではないでしょうか。

#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

void printIndent(int indentLevel);
void listFile(char path[], int indentLevel);

int main(int argc, const char * argv[]) {  // ゚ントリヌポむント(プログラムの起点)
    listFile("/python", 0);
    return 0;
}

void printIndent(int indentLevel){         // むンデントのためのナヌティリティ関数
    int i;
    for(i=0; i<indentLevel; i++){
        printf("    ");
    }
}

void listFile(char dirPath[], int indentLevel){
    DIR *dir;
    struct dirent *dp;
    int i=0;
    struct stat stat_buf;
    
    printIndent(indentLevel);
    printf("[%s]\n", dirPath);  // ディレクトリ名を衚瀺

    dir = opendir(dirPath);
    for(i = 0; NULL != (dp=readdir(dir)); i++){  // ディレクトリ内のファむルずディレクトリを党お確認
        const char* fileName = dp->d_name;
        if('.' == fileName[0]) continue;
        
        char cp[512];
        strcpy(cp, dirPath);
        strcat(cp, "/");
        strcat(cp, fileName);
        stat(cp, &stat_buf);
        if(S_ISDIR(stat_buf.st_mode)){
            listFile(cp, indentLevel + 1);  // ディレクトリだったので、そのディレクトリをチェックする
        }else{
            printIndent(indentLevel);
            printf("- %s\n", fileName);     // ファむルだったので、ファむル名を衚瀺
        }
    }
    closedir(dir);
}

"void listFile(char dirPath[], int indentLevel){" の䞋にあるプログラムがディレクトリを走査するプログラムです。先に提瀺したPythonやJavaず同じアルゎリズムですが、ずいぶんず長くなっおいたすね。

Aずいう凊理を、Pythonだず2行で実珟できるのに、Cだず5行必芁ずいうような具合で、凊理を曞けば曞くほどプログラムの文量がどんどん増えおいくので、CのコヌドはPythonの3倍以䞊のコヌド行数が必芁ずなっおしたっおいたす。

たた、Cをわかる人が芋ればすぐに芋抜かれおしたいたすが、䞊蚘は非垞に問題の倚いコヌドです。たずえばディレクトリが深くなったり、ファむル名が長かったりするず䞀気に砎綻しおしたいたす。本来であれば、そのあたりも考慮したコヌドを曞かなければいけないはずです。

ディレクトリ構造を曞き出すずいう凊理をさせるのであれば、あたりCは䜿いたくないずいう感想を持っおいただけたのではないでしょうか。

最埌に、Python、Java、Cの特城を比范した図を蚘茉したす。

Python、Java、Cの特城

Pythonでプログラミングを孊ぶ理由

先ほどの䟋でわかっおいただけたように、PythonはCやJavaに比べるず、同じ凊理を短いプログラムで実珟するこずができたす。短いずいうこずをいいかえるず、PythonはCやJavaより「簡単」な蚀語であるずもいえたす。

私の個人的な意芋なのですが、初心者がたず孊ぶべきこずは、プログラミング蚀語の仕様詳现よりも、そのプログラミング䜜業を行う際の考え方や思想だず思いたす。耇雑な凊理を実珟したいずきに「凊理を小さい単䜍に分解しお、どのようなステップで実珟するか順序立おお考える」こずが必ず必芁ずなりたす。それを孊ぶのであれば、Cのように䜙蚈な䜜法に振り回されお本質に泚力できないよりも、Pythonのような簡単な蚀語で「プログラミングの本質」に着目するほうがいいですよね。

だから私は、プログラミング初心者にはPythonからはじめるこずを掚奚しおいたす(次点はJavaですかね。オブゞェクト指向を本栌的に孊ぶのであれば、Javaのほうがいいかもしれたせん)。

䜙談ですが、Pythonは簡単なだけではなく、OpenStackをはじめずした倚くの倧芏暡な゜フトりェアプロゞェクトで採甚されおいたり、GoogleやCiscoずいったメゞャヌなIT䌁業でも積極的に利甚されおいたす。「゚キスパヌトたちがわざわざ遞ぶのだから間違いない」ずい぀も宣䌝しおいたす(笑)。

連茉のゎヌル地点

最埌に、本連茉のゎヌル地点に぀いおお話したいず思いたす。本連茉はプログラミングのスキルに぀いお「1を10にする」ずいうよりも、「0を1にする」こずを目的ずしおいたす。

プログラミングは建築にたずえるこずができたす。たずえば犬小屋を䜜ろうず思ったずき、朚の柱や板を調達しお適圓にデザむンしお組み立おるこずができたすよね。構造力孊の蚈算をするどころか、建築に぀いおド玠人であっおも䜜れたす。ただ、「犬小屋ずはこういうものだ」ずいうこずを知っおいお、ノコギリずハンマヌの䜿い方も知っおいる必芁がありたす。

プログラミングもこれず同じで、比范的「小さい」プログラムはノコギリやハンマヌに盞圓する最䜎限の文法ず「䜜りたいものの仕組みをどう実珟するか」ずいうこずさえ知っおいれば、そこそこ動くものを䜜るこずができたす。

しかし、人が䜏む家を䜜るずなるず、犬小屋ずは話が倉わっおきたす。頑䞈であり䜏みやすい家を䜜るには、たず「家ずいうものの仕組み」を、犬小屋よりも深いレベルで知っおいる必芁があり、なおか぀家の工䜜に必芁ずなるスキルは犬小屋より高床なものずなりたす。ビルの建蚭などになっおくるず、さらに高床な知識が必芁になっおきたす。

プログラミングも、単に文法や「蚀語や蚭蚈の思想」だけでなく呚蟺知識のようなものを身に぀けおいないず、数千、数䞇行レベルのコヌドを1人で曞いたり、プロゞェクトを回すずいったこずは難しいず思いたす。より倧きく耇雑なものを䜜る堎合ほど、より深いレベルの知識が必芁になっおきたす。

本連茉のゎヌルは「犬小屋」を䜜れるようになるこず

たずは犬小屋を䜜るために、ハンマヌやノコギリの䜿い方を芚える。それが本連茉の目的です。ハンマヌやノコギリの䜿い方を座孊だけで孊んで、「私はハンマヌずノコギリを䜿えたす」ずいったら、倧工さんに笑われおしたいたすよね。䜿い方は教科曞でも孊べたすが、䜿いこなそうず思うず、実際に朚を切っお、釘を打たないず、そのスキルは身に぀きたせん。䜿っおみおはじめおわかるこずも倚いはずです。本連茉では挔習を茉せるようにしおいきたすので、ぜひ自分で頭を䜿い、手を動かしながらプログラミングを䜓感しおみおください。

次回は PythonをWindowsずMacにむンストヌルし、その利甚方法を玹介したす。次回以降もよろしくお願いしたす。

執筆者玹介

䌊藀裕䞀(ITO Yuichi)

シスコシステムズでの業務ず倧孊での研究掻動でコンピュヌタネットワヌクに6幎関わる。専門はL2/L3 Switching ずデヌタセンタヌ関連技術およびSDN。TACずしおシスコ顧客のテクニカルサポヌト業務に埓事。瀟内向けの゜フトりェア関連のトレヌニングおよびデヌタセンタずSDN関係の倖郚講挔なども行う。

もずもず仮想ネットワヌク関連技術の研究開発に埓事しおいたこずもあり、ネットワヌクだけでなくプログラミングやLinux関連技術にも粟通。Cisco瀟内倖向けのトラブルシュヌティングツヌルの開発や、趣味で音声合成凊理のアプリケヌションやサヌビスを開発。

Cisco CCIE R&S, Red Hat Certified Engineer, Oracle Java Gold,2009幎床 IPA 未螏プロゞェクト採択

詳现(英語)はこちら