見出し画像

未経験者のための『コードを学ぼう』ガイド-6

この記事は『コードを学ぼう』の副読本シリーズの最終回です。
『コードを学ぼう』の各章を整理・解説し、より本格的なプログラミング学習に(立ち往生せず)進むことを目的としています。

在宅でできるスキルとして、プログラミングに興味を持っている人に向けて書きます。
複数の記事に分かれています、順に読み進んでください。

このシリーズの構成 ▶︎このnote
 未経験者のための『コードを学ぼう』ガイド-1
   ⬇︎ 
 iPadで『コードを学ぼう』
 Macで『コードを学ぼう』
   ⬇︎
 未経験者のための『コードを学ぼう』ガイド-2
 未経験者のための『コードを学ぼう』ガイド-3
   ⬇︎
 未経験者のための『コードを学ぼう』ガイド-4
 未経験者のための『コードを学ぼう』ガイド-5
▶︎未経験者のための『コードを学ぼう』ガイド-6

・画像クリックで拡大表示できます

画面がiPadとMacでは少し違う部分があります。
この記事の画面キャプチャはライトモードのiPadで、文字サイズは少し大きくしています。

ページタイトルの後ろの「🔶」印は課題のページ、⏺は練習のページです。


15 配列の章 【コードを学ぼう2】

コードを学ぼう 2 の最後の章です。
この記事でここまで体験してきた Swift の初歩を総ざらいしてください。

配列は同じ型の多くの変数を順にしまうことのできる入れ物

配列」は英語では Array です。
配列は同じ型の複数の値を順番に保存するための入れ物で、型の一種です。

この章の「はじめに」では配列にアイスクリームサンデーの各材料に対応するアイコンであらわしていました。
これは説明のためのイメージです。
絵文字がこのアイコンに近いですが、絵文字は文字なので引用符で囲って書かなければいけません


15-1 情報をまとめて保存 🔶

数値の配列の初期化を学びます。

このステージでは入力済みのコードがあります。

//コメントの印です。
二つのスラッシュから行末までの文字列はコメントです。
コメントはコードの実行には影響しません、コードの説明などを書きます。

このステージはコードを入力する前に実行するように書かれています。
実際に実行し確認してください。

配列で「キャラ」を置く行の座標を指定しています。
[0, 1, 3, 4] の指定(初期状態)で実行し、「キャラ」が立っている座標と付き合わせしてください。
ブロックをタップするとした図のように座標を表示します。

画像2

「キャラ」の立っていないところの行の座標を、配列 rows に追加しすべてのブロックに「キャラ」が立つ状態にするのが目標です。
このページではコードではなく、配列のデータだけを追加します。

コードにはカッコがたくさん登場します。
ここでカッコの主な役割を簡単に書きます。
※すべてのカッコは半角文字(英数記号の中間)です。

()  丸カッコ 
関数の引数を囲みます。計算の順序指定にも使います。

{ } 波カッコ 
コードを囲みます。

[ ] 角カッコ 
配列などデータを囲みます。

コード(プログラミング言語)ではカッコの対応は重要です。
対応する閉じカッコがないとエラーになります(Playgroundsでは赤丸を表示します)。


エラー画面を表示したら

どのステージも何度も実行すると次のようなエラー画面を表示するようです。

画像3

この場合はまず「完了」をタップして「ソースのコンパイルエラー」を閉じます。
次に別の(次または前の)ページに切り替え、すぐにこのページに戻します
ページが切り替わったときに Playgroundsアプリはまっさらな状態から、このページの見えていないコードをなどを読み込み実行の準備をします。
ライブビューでアニメーションが正常に開始すれば、実行可能な状態になります。

このエラーを表示しても、あなたの使い方が悪いわけではありません
実行ボタンをタップしてもすぐに実行がはじまらない場合にも、ページ切り替えが有効のようです。

このようなエラーの発生はデバイスのメモリなどに影響を受けている可能性があります。
ちなみに私のデバイスは iPad Pro 9.7インチの初代のものです、4年も使い続けています(このためメモリの余裕も少ない)。


15-2 反復処理を試す ⏺

配列データを for in ループで使う方法を学びます。

コードを学ぼう 1 で for ループは数値の範囲で回数を指定していました。
for 定数名 in 範囲 { //以下省略
範囲は 1...5 のように書きます。

配列を使う場合は for 定数名 in 配列 { // 以下省略 と書きます。
定数は for の { から } の中だけで使うことができます。
定数の型は配列の要素の型になります。
この for文は配列の要素数だけ繰り返します。

説明文で例として載っているコードは

for currentColumn in columns {

となっています。
columns は整数の配列なので、定数 currentColumn の型は Int になります。
ループする回数は、配列 columns の要素数と同じになります。

このページの説明文では『currentColumn(現在の列)はcolumns(列)配列の値を保持するための変数です。』とありますが、変数ではなく定数です。
currentColumn は変更することはできません


15-3 プロックを積む 🔶

Coordinate型の配列の初期化とループで使う練習です。

ここでは配列の要素が整数ではなく、Coordinate型のインスタンスです。

Coordinate型もコードを学ぼう専用の型です。
列と行ふたつの整数情報をひとまとまりで扱うための型です。

また引数に Coordinate型のインスタンスを渡すことのできる、新しい placeメソッドが登場しています。
Coordinate型のインスタンスはラベル at: に渡します。

ここでもステージのブロックをタップすると座標を少しの間表示します。

赤丸は文法エラーのしるし

配列にCoordinate型のインスタンスを追加する時、コードの行頭に赤丸が表示されました。
この赤丸をタップすると、内容を確認できます。

画像5

この場合はセパレータ(区切り文字のことです)が見つからないためのエラーでした。
Coordinateの初期化を二つならべた状態なので、一つ目の初期化(つまり、一つ目のデータ)でエラーになっています。

この例ではエラー表示に「修正」ボタンがあります。
「修正」ボタンで区切り文字としてカンマを挿入し、文法エラーを解消してくれます。

「修正」ボタンは文法エラーを解消するためのシンプルな方法を提供します。
残念ながら、いつも正しく修正してくれるとは限りません
コード全体の意図とは無関係に変更するため、別のエラーが発生する場合もあります。

配列のデータはカンマで区切って初期化します。
区切りのカンマの入力をわすれると、このようにエラー(文法エラー)を表示します。


>余談<
ここでライブビューの表示が乱れた場合がありました。
ブロックは6面体のはずですが、2面しか表示されていませんでした。
その後エラーがでたので、内部で問題が発生していたようです。
ページを切り替えやりなおすと、同じコードで問題なく正常に表示できました。

画像4

こちらは、ページを切り替えた直後の正常なライブビュー表示です。

画像6


15-4 順番に並べる 🔶

配列に項目を追加/削除するメソッドを学びます。

バイト以外の「キャラ」の名前が Blu、Hoperと書かれています。

このステージでは配列で利用可能なメソッドがたくさん登場します。
詳しくはこの記事の後半にまとめました。
「順番に並べる」の説明文にも remove(at: Int)、append(newElement: Element)、insert(newElement: Element, at: Int)が登場しました。
それぞれのメソッドは配列のインスタンスにドット表記で使います。
それぞれのメソッドの働きとインデックスの関係はこの章の「はじめに」で確認してください。

配列のどの要素を消すかなどの指定にはインデックスを使います。
配列のインデックスはゼロからはじまる整数です。
三つの要素を持つ配列はインデックス ゼロ から 2 が各要素に対応します。
要素が三つの配列でインデックス3の要素を削除するコードは実行時にエラーが発生します。
それ以上実行を続けることはできません。

このステージのコードにもコメントが書かれています。
「ワープを削除します。」のワープは抜け穴、型はPortalでしたね。

削除するとインデックスがずれる部分があることに注意してください。
配列のインスタンスにドット表記を入力するとショートカットバー/ショートカットリストに配列で利用可能なメソッドが並びます。

画像7

各「キャラ」の身長はステージを回転させ(必要なら拡大して)確かめてください。

削除によるインデックスのずれは「はじめに」のアニメーションがとてもわかりやすいので、見直してください。


15-5 配列に追加する 🔶

空の配列に要素を追加する練習です。

ここでは配列の型としての宣言方法が登場します。
整数なら var index: Int = 0 などと書きます。
変数や定数宣言ではコロンの次に型名を書きます。
配列では [要素の型] と書きます。

整数型の配列は [Int] 、Coordinate型の配列なら [Coordinate] です。

[要素の型] は配列の書き方の一つです。
初期化の書き方に近く、一般的な書き方です。

からっぽの配列の初期化は [ ] と書きます。
これでは要素の型が不明なので、変数または定数に配列の型の指定が必要なのです。

Swiftではからの配列の初期化も別の書き方があります。

このステージの課題はブロックの配置です。
「キャラ」は使いません。
「キャラ」の移動はありませんが、ブロックの配置はゆっくり進むので「一番速く実行」がおすすめです。


15-6 島を作る ⏺

からっぽの配列に追加する練習です。

島 island と海 sea 二つの配列を作り、範囲指定で切り分けてください。
ブロックの配置はこれまでと同じです。

海(水)は説明文の方法が使えます。
水はブロックよりも低いので、ブロックを取り除かなければ見えません

worldインスタンスで利用可能なメソッドがずいぶん増えてきましたね。
実際のプログラミングに近づいていますよ。


15-7 取り除いた値を追加する 🔶

配列の removeメソッド削除した項目を関数値で返します
この関数値を使う練習です。

これまで関数はコマンドのように何かの処理を行うものでした。
関数には引数でデータを渡すことができますが、処理した結果を返すこともできます。
その処理した結果を「関数値」と呼びます。
データなので型が決まっています。

このステージの例のコードはこれまで出てきていない使い方です。
頭の中が『⁇』になるのが普通です。

var rightColumn = world.column(7)
newArray.append(rightColumn.remove(at: 1))

まずコードの1行目 worldインスタンスの column(7) メソッドは 第7カラムのブロックの座標をすべて返すメソッドです。
つまり座標の配列を返す関数です。
1行目の rightColumn 変数の型は「 Coordinate 型の配列」になります。

2行目はもっと『?』ですね、(大丈夫です)分解して考えましょう。

先頭の newArray は配列のインスタンスです。
定義済みとして使っています。

newArray.append( の部分は配列のインスタンス newArray に要素を追加するメソッドです。

appendメソッドの引数は rightColumn.remove(at: 1) です。
これは配列のインスタンス rightColumn から指定インデックスの要素を削除するコードです。

配列の remove(at:) メソッドは、実は削除した要素を関数値で返します
関数値は利用しても良く・利用しなくても良いので、これまでの例ではメソッドの機能だけ利用し関数値は使っていませんでした。

newArray.append(rightColumn.remove(at: 1)) とすると rightColumn のインデックス1を削除し、削除した要素をappendメソッドの引数に渡すことになります。
これで削除した要素を newArray の最後に追加します。

world.column(7) も rightColumn.remove(at: 1) の部分も値を返すメソッドを使っていました。

このページの二つ目の例は各行で完結した、値を返すメソッドの例のようです。
説明の一番下の 1 2 3 がこのページの課題です。
入力済みコードとコメントを参考に、1 2 3 の順番でコードを追加してください。
でもこの説明だけでは、いまいちわかりません。

このページも実行するとヒントがかわります。
ブロックを積むのに時間がかかるので「一番速く実行」がおすすめです。

画像8

ループでひとつずつ削除しそこに「キャラ」を配置するので、このように階段状に並ぶと完成です。
(このコードは配列の最後を削除しました。)


15-8 インデックスの範囲外エラーを直す 🔶

配列の範囲外エラーを体験し修正する練習です。

自分のコードが原因のエラーは、開発中は普通に発生します
エラーになれることが大切です。

このステージは実行すると下画面のように赤丸を表示して止まります。

画像9

「Index out of range」(インデックスが範囲外)を最後の行で表示しています。
teamBlu 配列の要素の数を確認し、インデックスを修正すればこの実行時エラーは発生しません。

説明文の配列に「キャラ」のインスタンスを入れて、インデックスを指定してメソッドを実行させる方法は読み直し確認してください。

なお for in 配列 を使うとすべての要素を利用でき、インデックスの範囲外エラーにはなりません。
ただし『すべての要素を順番に処理する』の制約が付いてしまいます。
一部だけ使う場合や、配列内部の順番とは別の順にしたい場合は使えません。


15-9 地形を作る 🔶

配列の要素数を示す count プロパティを使い範囲外エラーを避ける練習です。

for文を使ってインデックスを増やしながら、最大を超えないようなコードを作る。
これは通常のプログラミングでも頻繁に使うやり方です。
説明のとおりにコードを入力してください。

ブロックを積み上げるのは意外に時間がかかります。
実行は「一番速く実行」がおすすめです。
(積み上げるブロックの数が多いと、それも時間がかかります)

このコードではインデックスの最大チェックは入力済みになっています。
次画面のようにインデックスをゼロに戻す部分をコメントにして、実行するとインデックスの範囲エラーで実行が止まることを確認できます。

画像10

ぜひ、このようにエラーを発生させてください
エラーに慣れ、エラーの対処方法にも慣れると今後のプログラミングが楽になりますよ。
(エラーに神経質になる必要はまったくありません。どんどんエラーを出してください。)
英語の表示にも慣れてください

ステージをクリアした後にヒント部分(評価)の説明もじっくり読んでくださいね。


15-10 ランダムな地形 ⏺

ランダム関数を使う練習です。

このページで使う randomInt もコードを学ぼう専用の関数です。
二つの引数で指定した範囲の乱数を関数値で一つ返します。

このページは入力済みのコードがたくさんあります。
コメントに従い、何を置くかなどを決め、コードを入力し、実行して結果を確認してください。
もし予想と違うなら、原因を考え修正するクセを付けましょう。


15-11 違う方法で配列を作る 🔶

関数やメソッドを使って配列を作る練習です。

新しい world インスタンスのメソッド existingCharacters(at:) は引数で渡した座標の配列にいるキャラクターを配列で返すメソッドです。
Character型インスタンスの配列を関数値で返します。
似たようなメソッドに existingExperts(at:) もあります。
こちらは特定の座標配列にいる「エキスパート」の配列を返します。

実行には時間がかかりますが、たくさんの「キャラ」が動くのは壮観ですね。


15-12 配列の技 ⏺

かなりの行数のコードです。
コード内のコメントを読み何をしているかを理解する練習です。
コードの一部を変更して実行し結果を確認してみましょう。

1行が長いコードは全画面で確認すると見やすくなります。

画像11

メソッドの説明は iPadのPlaygroundsなら「ヘルプ」で確認できます。

画像12

Macの場合もショートカットリストの候補長押しでヘルプは表示できます。

書かれているコードを確認し、挙動を予想してください。
それから実行し、予想どおりか確認しましょう。

目的を決めて少し修正し、実行して確認を繰り返していくと、コードのはたらきが実感できるはずです。


15-13 ステージを作る 🔶

最終課題です。
これまで学んだことを自由に組み合わせ実行しましょう。

ショートカットバー/ショートカットリストから候補を選ぶことでコードを組み立てていきましょう。
1行もない状態で書くのがむずかしければ、別のページからコピーペーストをためしてください。

一部だけコピーペーストすると、定義が不足などエラーを表示する場合があります。
エラーの内容をよく見て対応してください。

行数の少ないコードからはじめ、正常にかつ意図のとおり実行できることを確認しながら進めるのが良いと思います。

『コードを学ぼう 2』はページごとに新しいことが登場し、コードの行数も多くクリアするのが楽ではなかったですね。
得られたものも多かったはずです、アプリ作りにだいぶ近づいていますよ。

『配列』について次の説明で整理してください


15-14 データ構造

「データ構造」難しいことばですね。
「データつまり中の情報がどんなふうに入っているか」に注目します。
配列は同じ型の情報が順番に並んでいるのが特徴です。

『コードを学ぼう 2』では整数の配列を使いました。
ここでは文字列の配列で説明します。
コード部分は Playgrounds アプリの空白テンプレートに入力し実行できます。

配列の単純な例 
次の例は"松", "竹", "梅"と三つの文字列を入れた配列 rankName を用意します。

var rankName = ["松", "竹", "梅"]

この例では三つの値を入れました。
この一行で rankName は文字列が入った配列として初期化されます。
型を指定する場合には次のように書くこともできます。

var rankName: [String] = ["松", "竹", "梅"]

先頭の"松"がゼロで順に番号で取り出します。
この番号は「インデックス」(index)です。
番号は『添字』(そえじ)と呼ぶ場合もあります。(英語では subscript )

subscript はSwiftではインデックスでアクセスするようにプログラムする場合使うキーワードでもあります。
初歩・初級の範囲ではないので説明は割愛します。

rankName[0]     // 松
rankName[2]     // 梅

先頭の松はゼロ、竹は1、梅は2が対応します。

配列の宣言 
空の配列変数を宣言して後から要素を追加するには次のようにします。

var coins: [Int] = [ ]

配列の型を : [Int] で定めています。= [ ] で空にしています。

上のコード例では [ と ] の間に空白を置いています。
空白文字(スペース)は語の区切りに使います。
区切り以外の意味は持っていないので配列のデータは、いくつ空白を置いてもからっぽの状態に変わりありません。


値の追加 
coins には Int型の値を入れます。appendは引数をひとつ持つ配列型のメソッドです。

coins.append(20)


配列と繰り返し処理 
すべての値を順に取り出すには for in を使います。
inの次には範囲ではなく配列の変数名を書くと配列の中身を先頭から順に最後まで取り出して繰り返すループ処理になります。

次のコードは文字列の配列のすべての要素を順に取り出しスペースを区切りで連結します。
name は取り出した一つの文字列です。
それを連結結果用変数 allRank に連結し、区切り文字スペースひとつをさらに連結しそれを繰り返します。

var allRank = ""   // 文字数ゼロの文字列に初期化
for name in rankName {
   allRank = allRank + name + " "   // +で文字列を連結
}
allRank

ループを終了後 allRank の値は "松 竹 梅 " となります。

Playgroundsでは実行すると行ごとに結果を確認できます。
上のコードの最後の行のように変数名/定数名だけを書き実行するとその変数/定数の内容を確認できます。

画像13


このような「反復処理」は英語で iteration です。


範囲外に注意 
存在しないインデックスを参照しようとすると、実行時のエラーが発生します。

rankName[3]     // 0から2にしか値なし 実行時エラー

エラー表示は「Index out of range」となります。
「範囲外エラー」は英語では array out of bounds error です。


配列操作 
配列の操作は append() など配列型が備えているメソッドを使います。
ここでは最も基本的なメソッドを紹介します。

最後に追加 
最後に要素を追加するには append() メソッドを使います。

rankName.append("日替わり")

最後ではなく、どこに追加するかを指定する場合は insert(_:at:) メソッドを使います。(挿入を参照してください)


削除 
最後の要素を削除する removeLast()、先頭を削除する removeFirst() 、インデックスを指定して削除する remove(at:) 、すべて削除する removeAll() があります。

rankName.removeLast()
rankName.removeFirst()
rankName.remove(at:1)
rankName.removeAll()

要素数がゼロで removeLast() など不正な削除(その削除を実行できない場合)をすると実行時のエラーになります。
remove(at:) メソッドや removeFirst() で削除すると削除したインデックス以降はすべてひとつずれ全体の要素数もひとつ減ります


挿入 
位置を指定して挿入は insert(newElement: Element, at: Int) メソッドを使います。挿入位置インデックスはゼロが先頭で要素数-1まで指定できます。

rankName = ["松", "竹", "梅"]
rankName.insert("スペシャル", at: 0)


配列のプロパティ 
配列は型の一種です。
いろいろなプロパティを持っていますが、ここでは特に重要はふたつのプロパティだけ紹介します。


配列は空か 
isEmpty プロパティ は要素数がゼロであれば true を返します。
空でなければ false を返します。

rankName.isEmpty


要素数 
配列の要素数は count プロパティで確認できます。

let numberOfRank = rankName.count

要素数を返す count は実際に数を数えるため、実行に時間がかかります。
for in 配列 など要素数が不要の使い方がおすすめです。
空っぽかどうかを調べるだけなら isEmpty を使ってください。

以上が配列のまとめ(ただし概要)です。


・・・


コードを学ぼう 1 と 2 をやりきりました!

もしパスしたステージがあれば、戻って再挑戦してください。
ここまでやったので、別のやり方が見えてくるかもしれません。

プログラミング言語 Swift の初歩の練習を終えたのです。
ここまで楽しく進めた人はぜひ続けてください
続ければアプリ作りに近づきます。


解答例

コードを学ぼう 1 & 2 教師用ガイド 
iBooksで読める日本語のApple公式ガイドです。無料です。
この中のカギアイコンが解答例、☆アイコンがコーディングスキルでどちらも参考になります。

『コードを学ぼう 1 & 2 教師用ガイド』の最後のアップデートは2018年8月です。
一方最新版の「コードを学ぼう」は2019年10月にアップデートされています。
解答例のコードが古いために何か違いがあるかもしれません。
英語版 Learn to Code 1 & 2 Teacher Guide の最後のアップデートは2019年4月です。
英語版の解答例が最新の可能性もありますが、確認していません。

このガイドの中で「コードを学ぼう 1 と 2 は“小学校高学年以上を対象とした授業を想定しています”」と書かれています。
※2018年3月より前のバージョンでは「中学生以降向け」と書かれていました。

小学生の場合は、すぐに疑問に答えることのできる人が身近にいることが望ましいと思います。


簡単ではないが不可能でもない!

アプリ作りにもSwift言語はそのまま使えます。
Mac や iPad も開発にそのまま使えます。

アプリのプログラミングにはさらにいくつかSwiftのルールを知り慣れなければなりません。

「コードを学ぼう」では説明されていない「辞書」や「オプショナル」それに「クロージャ」「ジェネリック」「クラスと継承」など初学者にはやっかいな部分もあります。

さらに「フレームワーク」と呼ばれるアプリ用の部品群も使わなければなりません。
そのために私の書いた『Swift5初級ガイド』を役立ててください。

お知らせ
電子書籍『Swift5初級ガイド』をAppleのブックストアから出しています。
サンプルは無料です。MacでもiPadでもiPhoneでも読めます。
Swift 5.2に対応した第5版がダウンロード可能です。(ご購入済みの場合は無料アップデートです)
ブックストアから一度購入すると今後のアップデートは無料で読めます。

5宣伝store

お知らせ
noteにアプリ開発に向けてほかにも記事を書いています。
出発点としてはこちらの記事はどうでしょう:


お知らせ
有料記事をまとめて読めるマガジンもあります。(宣伝ばかりで恐縮です)
各記事は無料でおよそ半分読むことができます、ためしに読んでみてじっくりご検討ください。

SwiftUIの基本から説明しています。


Playgroundを使いますがSwiftUIとしてはより深い内容です。


はじめてiOS用プログラミングをするための情報をまとめています。
MacでXcodeを使います。


『iOSアプリを作ろう』シリーズの次のステップです。


さあ、プログラミングの世界へさらにふみ出しましょう!

ここから先は

0字
このマガジンは著者への支援のためのものです。

未経験者のための『コードで学ぼう』ガイドシリーズをまとめて読めるマガジンです。★注意★現在このマガジンで読めるnoteはすべて無料で読める…

今後も記事を増やすつもりです。 サポートしていただけると大変はげみになります。