プログラマーであれば、コーディングは手がかかり、エラーの多発する業務であることはご存知のはず。プログラムやウェブアプリケーションが機能する仕組みを考えると同時に、専門知識を持たないチームメンバーや株主などに向けてそれを噛み砕いて説明するのは、やりがいはあるものの、一筋縄ではいきません。

そこで救世主の如く登場するのが、疑似コードです。

疑似コードとは、シンプルな自然言語とプログラミング言語の要素を組み合わせたもの。プログラミングの世界に飛び込んだばかりの初心者であっても、あるいは経験豊富な開発者であっても、疑似コードの書き方を習得しておけば、作業時間を削減することができます。

今回は、この疑似コードについて掘り下げていきます。具体的な使用方法や、擬似コードが開発者にとって欠かせないものである理由についてもご説明します。

早速本題に入りましょう。

擬似コードについて動画での解説もご用意しています。

擬似コードとは

疑似コードとは、アルゴリズムや関数などのコードを自然言語とプログラミング言語の要素を組み合わせたものです。

実際には実行できないことから、「疑似」コードと呼ばれます。コーディングのロジックを説明したり、他のメンバーも交えて計画を立てる際に有用です。誰もが理解しやすい方法でプログラムの手順を記述しつつ、特定のプログラミング言語に後で変換できるよう、ある程度まで詳細化されています。

疑似コードの簡単な例として、サイトやアプリの訪問者に対して、名前付きのメッセージを表示する基本的なロジックを見てみます。

PROCESS GreetUser
    INPUT userName
    DISPLAY "Hello, " + userName + "!"
END

上記は、実際の言語やフレームワークの構文ではありません。PROCESS(処理)、DISPLAY(表示)、+のような、簡単な言葉やプログラミング要素で構成し、コーディングの知識のない人でも理解できるようになっています。

コードの意図を自然言語を使って表現することで、IT業界における「言語の壁」を乗り越えることができるのが、疑似コードの強み。これについては、次のセクションで詳しくご説明します。

擬似コードのメリット

疑似コードの大きなメリットの1つは、特定の言語の構文や構造に縛られることなく、コードを書くことができること。これによって、実際のコードを記述したり、デバッグしたりすることなく、プログラムや関数のロジックの誤りを容易に発見することができます。

さらに、疑似コードはさまざまなプログラミング言語に簡単に変換できるため、複数の言語を扱う開発者が、言語間で自分のアイデアを示すのにも便利です(Node.jsのスクリプトLaravel開発者に説明できることを想像してみてください)。疑似コードは、アイデアや機能を提案する共通言語として使用できるため、チームでプロジェクトを進行する際にも非常に役立ちます。

以下、初心者と上級者どちらにも該当する擬似コードのメリットを見てみましょう。

  • 生産性の向上─プロセスの手順を擬似コードで示すことで、特定のプログラミング言語に絞り込む前にコードを計画することができるため、作業を効率化できる。ひいてはミスを回避し、デバッグの必要性も減る。
  • 読みやすい─誰でも理解できるようにシンプルに書かれているため、チームで作業している場合や、古いコードの見直しが必要な場合に便利。
  • 高度な柔軟性─特定のプログラミング言語に縛られることがないため、さまざまな言語への変換が容易。複数の言語を扱い、言語間でアイデアを変換する場合に便利。
  • 共同作業の円滑化─開発チームでのコミュニケーションおよび共同作業を行う際の共通言語として理想的。また、開発者がアイデアを明確かつ簡潔に伝えることができるため、同じプロジェクトに関与する他のチームメンバーへの共有も容易に。
  • ローカル管理─実行形式ではないため、本格的なアプリのようにオンラインで運用したり、外部スクリプトに接続する必要なし。ローカルマシン上のファイル、クラウドファイル、またはメールにコピーして、作成・保存することが可能。

また、疑似コードは開発プロセスのどの段階であっても簡単に実装可能です。コーディングの進捗を問わず、必要な時に使用して、上記で挙げたような恩恵を受けることができます。

擬似コードの主な使用事例

疑似コードは柔軟性が高く、プログラミングの領域以外でもその使い道は多岐に渡ります。

開発者に想定される主な使用事例は、以下のようなものが挙げられます。

  • プロセスの計画と設計─プロセス、関数、アルゴリズムの計画に使用。特定のプログラミング言語で実装する前にロジックを計画して、正しく機能するかを確認することができる。
  • 専門知識のない利害関係者へのアイデアの共有─プロジェクトマネージャーや顧客など、IT技術者ではないステークホルダー(役員や株主などの利害関係者)にプロセスやアルゴリズムをわかりやすく説明するために使用。
  • チームでの共同作業─個々のプログラミング知識に関係なく、開発チーム内で円滑にコミュニケーションをとり、共同作業を行うための共通言語として使用。
  • 異なるプログラミング言語にコードを変換─特定のプログラミング言語やスクリプト言語に縛られることがないため、簡単かつ即座に別の言語に変換することができる(複数の言語を扱う開発チームにとって便利)。
  • プログラミングの学習─構文にとらわれずにプログラムの論理と構造に集中できることから、プログラミング基礎の教育や習得に有用。

以上はほんの一例であり、他にもさまざまな用途が考えられます。擬似コードの可能性は無限大です。

擬似コードの書き方

疑似コードの正しい書き方というのは定められていません。柔軟性が高く、特定の構文規則を設けることができないのがその理由です。

PascalやBasicのような言語では、構文固有の疑似コードガイドラインを発表していますが、一般的な用語を使用し、ロジックに矛盾がなければ、いかようにも疑似コードを書くことができます。

とは言え、大多数の開発者が遵守している基本的な手順とガイドラインがありますので、参考にしてみてください。

擬似コードの記述手順

擬似コードの一般的な書き方の手順を見ていきましょう。

  1. テキストエディターを開くテキストエディターまたはHTMLエディターで書くのが一般的です。
  2. 目標を定義する:プログラムまたは関数の目的を決定します。
  3. 目標を細分化する:決定した目標を管理しやすい大きさに細分化します。これによって、目標をより明確に考えることができ、必要時に必要な場所で動作するように、分割した要素を整理することが容易になります。
  4. 細分化した目標を整理する:プログラムのステップを論理的な順序で書き出します。自然言語で書き、制御構造や型キャストなど、特定のプログラミング構造やメソッドは使用しないように注意。
  5. 行をインデントする:プログラムの構造をわかりやすく示すために、インデント(字下げ)を使用します。例えば、ループの中にあるコード行はインデントしましょう。
  6. テスト:記述した擬似コードをテストして、筋が通っているかどうかを確認します。口頭で説明したり、他の人に読んでもらったりしてもらうと効果的です。

疑似コードを書き終えたら、実行可能なスクリプトに変換します。オープンソースのGitリポジトリに追加したり、自己学習を行ったり、StackOverflowや開発コミュニティで意見交換したり、プロジェクト外でもプログラミングスキルを磨くことができます。

擬似コードの構成要素

先にも触れた通り、疑似コードには定義された構文はないものの、開発者の間でよく利用されるパターンは存在します。

シーケンス

特定の順序で実行されるステートメントのグループで、一連の単純な動作を実行したり、繰り返したりするのに使用します。擬似コードでよく使用されるシーケンスコマンドには、INPUTSETPRINTREADDISPLAYSHOWCALCULATEなどがあります。

以下、シーケンスコマンドを使用した疑似コードの記述例です。

PROCESS CalculateCost
    INPUT price, quantity
    SET cost = price * quantity
    PRINT "The cost is: " + cost
END

上記は、価格と数量を受け取り、掛け合わせて費用を算出して結果を表示するCalculateCostという処理を定義するものです。

条件文

プログラムがある条件に基づいて判断し、条件を満たした(または満たさない)場合に、特定のステートメントを実行するように指示するものです。IF-ELSEIF-IF ELSE-ELSE、およびCASEステートメントは、擬似コードで頻繁に使用されます。

以下は、IF-ELSEのスクリプトを疑似コードで使用した例です。

IF user = returning
    PRINT "Welcome back!"
ELSE
    PRINT "Welcome!"

過去に訪問したことのあるユーザーに対して「おかえりなさい!」のメッセージを表示し、新規ユーザーには「ようこそ!」を表示する処理を定義しています。

イテレーション

比較的長い関数やプロセスの中で一連の手順を繰り返すものです。リスト内の複数の項目に対して同じ処理を実行したり、特定の条件が満たされるまで処理を繰り返したりする際に使用されます。

反復処理には、FORWHILEDO-WHILEなど、さまざまな種類のループを使用可能です。

以下は、FORループで数値のリストを繰り返し処理する擬似コード例です。

PROCESS PrintWholeList
    INPUT listOfNumbers 
    FOR each number in listOfNumbers
    PRINT number
    END FOR
END

上記では、PrintWholeListプロセスが数値のリストを受け取り、そのリストを繰り返し処理し、各数値を画面に表示します。FORループによって、このプロセスはリストの各項目に対してPRINTコマンドを繰り返し実行します。

これについては、一般的な擬似コードを使用して同じことを実行することも。DO-WHILEの代わりに、REPEATUNTILという言葉を使用するのが通例です。

PROCESS PrintWholeList
    INPUT listOfNumbers 
    SET counter = 0
    REPEAT
    PRINT listOfNumbers[counter]
    SET counter = counter + 1
    UNTIL counter = length of listOfNumbers
END

これは擬似コードの柔軟性の高さがわかる良い例で、名前、言葉、構文の断片を自由に入れ替えることができます。重要なのは、誰でも理解できる一般的な言葉を使いながら、ロジックの一貫性を保つことです。

上記にご紹介した構成要素は、後ほどご紹介する擬似コードの例でも登場します。

擬似コードのベストプラクティス

先に述べたように、擬似コードはプログラミング言語ではないため、厳密な構文というものは存在しませんが、疑似コードを効率的に書くためのヒントがいくつかあります。

  1. 自然言語を使用─誰もが理解しやすいように、専門用語ではなく自然言語を用いる。
  2. シンプルに─複雑な言語や構文の使用は避け、アルゴリズムやプロセスのステップを明確かつ簡潔に表現する。
  3. 具体的に─変数名や値など、できるだけ具体的に記述する。
  4. 不必要な情報は省略大文字と小文字の使い分けや、セミコロンの使用/不使用は気にせず、シンプルに記述することに重点を置くこと。
  5. プログラミング要素を取り入れる─特定のプログラミング言語で書くべきではないが、ループ、条件文、関数呼び出しなどの要素を取り入れることで、関係者もプログラミングについて簡単に理解することができる。
  6. インデントで階層を表現─インデントでプログラムのステップの階層を表現することで、論理と構造の理解が容易に。

このようなヒントを取り入れることで、特定のプログラミング言語やスクリプト言語で関数やアルゴリズムを実装する際の手引きとなる、優れた疑似コードを書くことができます。

擬似コード例と他言語への変換方法

ここからは擬似コード例とさまざまな言語やフレームワークへの変換方法をご紹介していきます。

PHP

まず始めに、与えられたリストの数字をすべて足し算するロジックを模倣した疑似コードを書いてみます。

PROCESS FindTotal
    INPUT listOfNumbers
    SET sum = 0
    FOR EACH number IN listOfNumbers
    SET sum = sum + number
    END FOR
    PRINT sum
END

この擬似コードのロジックは、以下のような手順を踏みます。

  1. 関数に名前をつける
  2. エンドユーザーから数値のリストを取得
  3. 変数sumを作成し、計算された数値の合計を格納
  4. リストの数字を1つずつ繰り返し、各数値をsumの合計に加算
  5. すべての数値が加算されたら、反復処理(ループ)を終了
  6. すべての数値を加算した最終的な合計を表示
  7. 関数を終了

これを踏まえて、この疑似コードを他の言語やフレームワークに変換してみます。PHPに変換する場合は、以下のようになります。

function findTotal($listOfNumbers) {
    $sum = 0;
    foreach ($listOfNumbers as $number) {
    $sum += $number;
    }
    echo $sum;
}

Node.js

続いて、訪問者の現在時刻を取得し、時刻に応じて適切な挨拶を送信する疑似コードを見てみます。

PROCESS TimedGreeting
    GET userTime
    IF userTime > 6:00 + < 12:00
    PRINT "Good morning!"
    ELSE IF userTime > 12:00 + < 18:00
    PRINT "Good afternoon!"
    ELSE
    PRINT "Good evening!"
END

この擬似コードのロジックは、以下の通り。

  1. 関数に名前をつける
  2. ユーザーの時刻を検索
  3. 時刻が午前6時から午後12時の間であれば、「おはようございます!」というメッセージを表示
  4. 時刻が午後12時から午後6時の間であれば、「こんにちは!」というメッセージを表示
  5. それ以外の時刻では「こんばんは!」というメッセージを表示
  6. 関数を終了

Node.jsに変換すると、以下のようになります。

function timedGreeting() {
    const userTime = new Date();
    if (userTime.getHours() > 6 && userTime.getHours() < 12) {
    console.log('Good morning!');
    } else if (userTime.getHours() > 12 && userTime.getHours() < 18) {
    console.log('Good afternoon!');
    } else {
    console.log('Good evening!');
    }
}

Python

次に、ユーザーから渡された文字列(この例では文章)を反転させるロジックを疑似コードで記述してみます。

PROCESS ReverseString
    INPUT string
    SET reversed_string = reverse of string
    PRINT "The reversed sentence is: ", reversed_string
END

この擬似コードのロジックは以下の通り。

  1. 関数に名前をつける
  2. ユーザーに文字列の入力を促し、入力された文字列を受け取る
  3. ユーザーが入力した文字列の値を変数に格納
  4. 格納された文字列の値を分割して反転し、その結果を新たな変数に格納
  5. 反転された文字列を画面に表示
  6. 関数を終了

これをPythonに変換すると以下のようになります。

string = input("Enter a sentence: ")
reversed_string = string[::-1]
print("The reversed sentence is: ", reversed_string)

なお、擬似コードよりも変換したコードの方が短くなることがありますが、ロジックが正しく、コードが正常に機能する限りは問題ありません。

日常生活におけるプロセス

その読みやすさと柔軟性から、擬似コードはコーディングとは関係のないプロセスを定義するのにも使用可能です。

例えば、「寝室の壁をペンキで塗る」手順を疑似コードで書き出すとしたら、以下のような感じになるでしょう。

PROCESS PaintBedroom
    INPUT color
    PREPARE bedroom
    REMOVE furniture from room
    COVER floors with drop cloth
    TAPE off trim
    PAINT walls
    SETUP ladder
    LOAD paint roller with paint
    ROLL paint onto walls
    ALLOW paint to dry
    FINISH
    REMOVE tape and drop cloth
    REPLACE furniture
    DISPOSE of trash
END

もちろん、寝室のペンキ塗りはコンピュータとは無関係の物理的な作業であるため、これをプログラミング言語に変換する必要はありません。とは言え、このように擬似コードのベストプラクティスと習慣に従えば、日常生活の何気ないプロセスにさえも容易に疑似コードを取り入れられることがわかります。

まとめ

日々多忙な開発者は、一分一秒たりとも無駄にできません。そのため、作業時間、労力、ストレスをできる限り削減できるような戦略を取り入れ、生産性を向上させることが重要です。

疑似コードは、扱う言語を問わず、すべての開発者にとって作業を効率化するのに有効な手段。余計なツールや負荷を加えることなく、ワークフローに簡単に統合することができます。コードの記述やテストなど、細かな作業に着手する前に、疑似コードで簡潔に計画を立てることで作業を効率化、ミスを回避し、チームメンバーとの共同作業に一貫性を確保可能です。

他にも擬似コードの使い方をご存知ですか?以下のコメント欄で、ぜひお聞かせください。