口頭の指示からプログラムを組み立てる力
― C#で5人の生徒情報を並び替えて表示する課題を通して ―
はじめに
現場や授業では、「仕様書」や「設計書」ではなく、講師や上司からの口頭指示で課題を受けることがあります。
このような状況では、聞き取った内容を自分で仕様に落とし込む力が求められます。
今回は、ある授業中に出された「生徒情報を並び替えて表示する」という課題の口頭指示を受け、それを元にC#のプログラムを構築する過程をまとめました。
🎙️ 実際の口頭指示(想定会話)
講師:
えーと、次の課題なんですけど…
5人の生徒がいる教室をイメージしてください。
まず、生徒の一覧表を作ってみてください。
生徒の情報は「名前・身長・住所」でお願いします。
(少し考えて)
あ、ごめんなさい。住所と身長の順番を入れ替えてください。
表示する時には「名前、住所、身長」の順で出力してください。
(さらに追加)
次に、その一覧を身長順(昇順)に並べて表示してみましょう。
あと、住所順(五十音順)でも並び替えて表示できると良いですね。
(最後に)
すいません、情報の一番目に生徒IDをつけてください。
IDは1から順番で構いません。
(言い忘れました・・・)
あ、プロジェクト名は、StudentRosterSorterにしましょう
🧠 指示から仕様を読み取る
要素 | 内容 |
---|---|
生徒数 | 5人 |
保持情報 | ID(番号)・名前・住所・身長 |
表示① | 入力順に表示(表示順:ID, 名前, 住所, 身長) |
表示② | 身長順(昇順)で表示 |
表示③ | 住所順(五十音順)で表示 |
🏗️ Studentクラスを定義する
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; } // 表示では身長より先
public int Height { get; set; }
}
✅ 身長と住所の定義順は内部構造では自由だが、表示順は指示に従う必要があるという理解が大切。
🧪 ダミーデータの作成
以下のように、生徒5人分の情報を用意します。
var students = new List<Student>
{
new Student { Id = 1, Name = "佐藤", Address = "東京", Height = 160 },
new Student { Id = 2, Name = "鈴木", Address = "神奈川", Height = 170 },
new Student { Id = 3, Name = "高橋", Address = "千葉", Height = 165 },
new Student { Id = 4, Name = "田中", Address = "埼玉", Height = 172 },
new Student { Id = 5, Name = "伊藤", Address = "茨城", Height = 158 },
};
🔁 並び替え処理の実装(LINQ)
身長順(昇順)でソート:
var heightSorted = students.OrderBy(s => s.Height).ToList();
住所順(五十音順)でソート:
var addressSorted = students.OrderBy(s => s.Address).ToList();
🖨️ 出力用の関数(メソッド)を定義
結果の表示は、メソッドにまとめてみましょう
static void DisplayStudents(List<Student> list)
{
foreach (var s in list)
{
Console.WriteLine($"ID: {s.Id}, 名前: {s.Name}, 住所: {s.Address}, 身長: {s.Height}cm");
}
}
🔄 表示時には、住所→身長の順で出力されていることに注目。
💻 完成プログラム全体
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StudentRosterSorter
{
class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int Height { get; set; }
}
class Program
{
static void Main()
{
var students = new List<Student>
{
new Student { Id = 1, Name = "佐藤", Address = "東京", Height = 160 },
new Student { Id = 2, Name = "鈴木", Address = "神奈川", Height = 170 },
new Student { Id = 3, Name = "高橋", Address = "千葉", Height = 165 },
new Student { Id = 4, Name = "田中", Address = "埼玉", Height = 172 },
new Student { Id = 5, Name = "伊藤", Address = "茨城", Height = 158 },
};
Console.WriteLine("【入力順】");
DisplayStudents(students);
Console.WriteLine("\n【身長順(昇順)】");
var heightSorted = students.OrderBy(s => s.Height).ToList();
DisplayStudents(heightSorted);
Console.WriteLine("\n【住所順(五十音順)】");
var addressSorted = students.OrderBy(s => s.Address).ToList();
DisplayStudents(addressSorted);
}
static void DisplayStudents(List<Student> list)
{
foreach (var s in list)
{
Console.WriteLine($"ID: {s.Id}, 名前: {s.Name}, 住所: {s.Address}, 身長: {s.Height}cm");
}
}
}
}
📝 まとめ
- 口頭で与えられた曖昧な指示を正しく解釈し、仕様に落とし込むことが重要。
- クラス設計、Listの扱い、LINQによる並び替え、整形出力の基本が学べる良課題。
- 特に「表示順と内部の定義順が違っていてもよい」ことは、実務でも頻出の考え方。
🧩 発展課題(応用として)
- 一番背の高い生徒だけを表示する
- 「茨城」に住んでいる生徒を抽出する
- 名前の五十音順に並び替える
- 身長が160cm以上の生徒だけを表示する
以下のサンプルでは、元の課題で定義されている Student クラスと students リストをそのまま使い回し、LINQ を使って各発展課題を実装しています。
1. 一番背の高い生徒だけを表示する
var tallest = students.OrderByDescending(s => s.Height).First(); // 最初が最大値
Console.WriteLine($"一番背の高い生徒: {tallest.Name}({tallest.Height}cm)");
2. 「茨城」に住んでいる生徒を抽出する
var ibarakiStudents = students .Where(s => s.Address == "茨城");
foreach (var s in ibarakiStudents)
{
Console.WriteLine($"{s.Name}({s.Height}cm, 住所: {s.Address})");
}
3. 名前の五十音順に並び替える
既定の OrderBy(s => s.Name) だけだと、.NET(Windows)の日本語カルチャではJIS X 0208 のコード順(Shift_JIS のバイト順)で比較が行われるため、あいうえお順にはなりません。
実際、Shift_JIS の先頭バイト順で見ると…
伊(0x88C9)→ 高(0x8D82)→ 佐(0x8DB2)→ 田(0x9363)→ 鈴(0x97E9)
…という並びになり、先ほどの結果(伊藤→高橋→佐藤…)と一致します。
あいうえお順で並べるには
名称(漢字)ではなく、読み仮名(ふりがな)でソートするのがもっとも確実です。
以下の例では、Student クラスに Reading プロパティを追加し、そこに全員の読み仮名を入れてから LINQ でソートします。
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Reading { get; set; } // 五十音順ソート用の読み仮名
public int Height { get; set; }
public string Address { get; set; }
}
// Mainメソッド
var students = new List<Student>
{
new Student { Id = 1, Name = "佐藤", Reading = "さとう", Address = "東京", Height = 160 },
new Student { Id = 2, Name = "鈴木", Reading = "すずき", Address = "神奈川", Height = 170 },
new Student { Id = 3, Name = "高橋", Reading = "たかはし", Address = "千葉", Height = 165 },
new Student { Id = 4, Name = "田中", Reading = "たなか", Address = "埼玉", Height = 172 },
new Student { Id = 5, Name = "伊藤", Reading = "いとう", Address = "茨城", Height = 158 }
}
var sortedByReading = students.OrderBy(s => s.Reading);
Console.WriteLine("名前の五十音順:");
foreach (var s in sortedByReading)
Console.WriteLine($"- {s.Name}(ID: {s.Id})");
このようにすれば、出力は
伊藤五郎(ID: 5)
佐藤花子(ID: 2)
鈴木次郎(ID: 3)
高橋四郎(ID: 4)
田中太郎(ID: 1)
と、純粋に「あ→さ→す→た→た」の順(※たかはし→たなか の順序も正しく)になります。
なぜ漢字のままだとダメなのか
- Windows の標準日本語ロケール(ja-JP)では、内部的に JIS X 0208 の行番号・セル番号順(Shift_JIS のバイト列順)でソートします。
- これが「字典式」や「画数順」とは違い、厳密な五十音(あいうえお)順ではありません。
なぜふりがなだといいのか
ふりがな(Reading)の文字列は純粋なひらがなで構成されていて、ひらがなの Unicode コードポイント自体が五十音順(「あ」→「い」→「う」→「え」→「お」…)に並んでいます。
- ひらがな Unicode コードポイント順
- 「あ」…U+3042
- 「い」…U+3044
- 「う」…U+3046
- 「え」…U+3048
- 「お」…U+304A
…というふうに、Unicode 上の並びがそのまま五十音の並びになっているためです
まとめ
- 漢字でソート → JIS コード順になる
- 読み仮名でソート → 実際のあいうえお順になる
そのため、名前のあいうえお順を保証したい場合は、必ず「ふりがな(Reading)」をデータとして持たせてソートしてください。
4. 身長が160cm以上の生徒だけを表示する
var tallStudents = students.Where(s => s.Height >= 160);
foreach (var s in tallStudents)
{
Console.WriteLine($"{s.Name}({s.Height}cm)");
}
これらのサンプルを元に、実データや表示形式を調整して発展課題に取り組んでみてください。
課題を含めた全てのコード
using System;
using System.Collections.Generic;
using System.Linq;
namespace StudentRosterSorter
{
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Reading { get; set; } // 五十音順ソート用の読み仮名
public int Height { get; set; }
public string Address { get; set; }
}
class Program
{
static void Main()
{
var students = new List<Student>
{
new Student { Id = 1, Name = "佐藤", Reading = "さとう", Address = "東京", Height = 160 },
new Student { Id = 2, Name = "鈴木", Reading = "すずき", Address = "神奈川", Height = 170 },
new Student { Id = 3, Name = "高橋", Reading = "たかはし", Address = "千葉", Height = 165 },
new Student { Id = 4, Name = "田中", Reading = "たなか", Address = "埼玉", Height = 172 },
new Student { Id = 5, Name = "伊藤", Reading = "いとう", Address = "茨城", Height = 158 }
};
Console.WriteLine("【入力順】");
DisplayStudents(students);
Console.WriteLine("\n【身長順(昇順)】");
var heightSorted = students.OrderBy(s => s.Height).ToList();
DisplayStudents(heightSorted);
Console.WriteLine("\n【住所順(五十音順)】");
var addressSorted = students.OrderBy(s => s.Address).ToList();
DisplayStudents(addressSorted);
var tallest = students.OrderByDescending(s => s.Height).First(); // 最初が最大値
Console.WriteLine($"一番背の高い生徒: {tallest.Name}({tallest.Height}cm)");
var sortedByReading = students.OrderBy(s => s.Reading);
Console.WriteLine("名前の五十音順:");
foreach (var s in sortedByReading)
Console.WriteLine($"- {s.Name}(ID: {s.Id})");
var tallStudents = students.Where(s => s.Height >= 160);
foreach (var s in tallStudents)
{
Console.WriteLine($"{s.Name}({s.Height}cm)");
}
}
static void DisplayStudents(List<Student> list)
{
foreach (var s in list)
{
Console.WriteLine($"ID: {s.Id}, 名前: {s.Name}, 住所: {s.Address}, 身長: {s.Height}cm");
}
}
}
}
🎤 おわりに
この課題は、「聞いてすぐ作る力」「曖昧さを整理する力」「順序や整形に気を配る力」など、プログラミングに必要な本質的な力を育ててくれます。
特に初心者にとっては、「言われたことをそのまま写す」のではなく、「言われた内容の意図を読み取る」という姿勢が重要であることを体感できる機会です。
ディスカッション
コメント一覧
まだ、コメントがありません