ネットで調べて出てきたSwiftコードを精読してみた

実装に困ったらstackoverflow先生に頼るのはよくあることですが、そのままコピペするのはいけません。「これってどうしてこういう実装になったの?」「stackoverflowからコピペしました!」だと怒られる気がします。*1そこで、今回は僕が参考にしたソースを精読して理解したいと思います。

想定されるレベル感はSwift書き始めたばかりくらいの人です。

今回の元ネタはこちらです。

ios - How do I resize the UIImage to reduce upload image size - Stack Overflow

画像をサイズ縮小するにはどうしたらいいか?という問いです。 最も+を得ている回答は以下のとおりです。

extension UIImage {
    func resized(withPercentage percentage: CGFloat) -> UIImage? {
        let canvasSize = CGSize(width: size.width * percentage, height: size.height * percentage)
        UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(origin: .zero, size: canvasSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
    func resized(toWidth width: CGFloat) -> UIImage? {
        let canvasSize = CGSize(width: width, height: CGFloat(ceil(width/size.width * size.height)))
        UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        draw(in: CGRect(origin: .zero, size: canvasSize))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

(Xcode 8.2.1 • Swift 3.0.2)

では書いていきます。

1行目

extensionは型を拡張するときに使います。これをするとUIImageのインスタンスimageがあったときに、 imgae.resized(withPersentage: 0.1) で使えるようになります。

2行目

withPercentageは外部引数、percentageは内部引数です。 CGFloat型とFloat型の違いはなんだろう?と思って調べたところ、以下の通りだそうです。

Float型とDouble型はCocoaでも用途によって明確に使い分けられています。たとえば、画面上の座標に使用されるCocoaのCGFloat型は、32ビットのプラットフォームではFloat型、64ビットのプラットフォーム型ではDouble型になります。

どうしてこのような使い分けになっているかはちょっと分かりませんでした。 処理自体は、引数で指定したpercentage分だけ、画像の大きさを小さくするというものです。辺の長さが半分なら0.5を指定します。

3行目

CGSizeは縦横のサイズを指定するクラス。関連したものにCGRect、CGPointがあります。

4行目

UIGraphicsBeginImageContextWithOptionsはbitmap-basedなImageをOptionつきで作成できるクラス。scaleをこのクラスでは定義していないけど何故か動いている。気になってdefinitionにさかのぼったが、どうやらUIImageのopen varらしい。

5行目

deferは遅延実行です。

リソースの解法など、そのあとの実行フローの内容にかかわらず、スコープの退出時に確実に実行されて欲しい処理の記述に利用します。

で、何が実行されているかと言うとUIGraphicsEndImageContext()ですが、要するにUIGraphicsBeginImageContextWithOptionsの対になるもので、画像の描画を終わらせるために活用するものだと思います。開始と終了がワンセットだから、この位置でdeferされているのでしょうか。*2

6行目

draw(in: CGRect)は、元々のUIImageを引数で指定した大きさに変換して再描画する処理です。CGRect()では、座標とサイズの設定が行われています。origin: .zeroの方は、座標を表しているから、元のところから動かさないの意味?

7行目

UIGraphicsGetImageFromCurrentImageContext()は、現在の"Context"にあるImageを取得するというものです。 つまり、4行目~7行目でUIGraphicsBeginImageContextWithOptions→UIGraphicsGetImageFromCurrentImageContext→UIGraphicsEndImageContextの流れが記述されているということになります。

8行目以降

大きさの設定方法以外全部同じなので省略

まとめ

振り返ってみるとそこまで難しい処理をやっているわけではなく、Contextの生成→Imageを作成→Contextの削除という流れがあるとわかりました。一つでもちゃんと読んで理解できると、他の類似のソースを見たときに何が違っているのか理解しやすくなりますね。

参考

石川・西山『改訂新版 Swift実践入門』

https://developer.apple.com/documentation/uikit/1623912-uigraphicsbeginimagecontextwitho?language=objc

https://developer.apple.com/documentation/uikit/1623933-uigraphicsendimagecontext

https://developer.apple.com/documentation/uikit/uiimage/1624092-draw

https://developer.apple.com/documentation/coregraphics/cgrect/1454856-init

*1:社畜ちゃん』の後輩ちゃんもどっかで怒られていました

*2:他の例を見ると、deferを使わずにreturnの直前に置いているのもあるので、活用は好みの問題なのかなとも思いました。

レビュー『独学プログラマー』

こちらの書籍のレビューです。

独学プログラマー Python言語の基本から仕事のやり方まで

独学プログラマー Python言語の基本から仕事のやり方まで

結構軽い書籍で、僕は秋葉原有隣堂併設のカフェで1時間くらいで一周しました。 その結果、これは手元に置いておきたいと思って購入しました。

対象となる読者層

本文中にははっきり書かれていなかったと思いますが、

  • プログラミングに興味がある人~始めて1~2年以内の人
    • 特に「興味があるけど何したらいいかわからない」人
  • 「独学」と聞いて心躍る人

がいいと思います。

内容

良いところ

「次何したらいいか」がわかる

プログラミングの入門本にありがちなのは、「文法は分かったけどこれで何をすればいいの?」となる場合があることです。 すでにプログラミング関連の職種についている人は別ですが、独学、すなわち自分の意思や興味から始めている人にとっては、次にやれることがたくさん示されているこの本は非常に役に立つと思います。

参考となる書籍やサイトがたくさん挙げられている

前に上げた良いところの続きです。 内容の項を見ると分かりますが、紹介されているトピックは幅広いですが、その分内容は簡単なものにとどまっています。 それの補完として、様々な参考書籍やサイトが数多く挙げられていて参考になります。

それだけでもすごいのですが、さらに良いのは日本語訳者が日本語のサイトや書籍を追加で紹介してくれていることです。 とてもたくさん紹介されているのでそこから選ぶのが悩ましい。

個人的感想

今の僕にとっては、どう学ぶかという方法論ももちろん大事ですが、そろそろ実際にモノを作ろうぜという段階だな~と思います。(今まで何も作ってなかったというわけではないです、たぶん)

レビュー #マンガでわかるDocker

お久しぶりです。アレクです。

『マンガでわかるDocker 』を電子書籍版で購入し、ひと通り試したのでレビューします。

 

良い点

ターゲット層が明確かつ、そのターゲットに見合ったレベル感

レベル感は購入ページに書いてありますが、「・Dockerを初めて使う方」「・かつ、コマンドラインをさわったことがある方」です。

そのような人が持ちやすい、「Dockerってよく聞くけどどんな機能を持っているの?」「使うとどんなメリットがあるの?」という疑問に簡潔に答えています。

イラストかわいい

Daemonちゃんかわいい。俺も悪魔だと思ってました。わかばちゃんの表情も豊かになったような気がするかわいい。

Dockerを動かせる

入門本らしく、本の内容に従って進めていくと、Dockerを動かすことができます。

改善点

コマンドをたたいても期待通りに動作しない

P21のコマンドを実行したところ、本文中と異なる結果となりました。 f:id:alek3:20180506133053p:plain

ちょっと残念…… ちなみに docker run --rm -it alpine すると起動します。

その他

  • ページ数分かんないなあと思って買ったけどもう一度見たら書いてあった。ポンコツ乙。
  • 28ページのマンガなので良くも悪くもすぐ読み終わる。
  • Docker動かないよーと泣きついたら@HKDnetさんが教えてくれました。ありがとう@HKDnet

ボードゲーム会を再び企画してみた

こちらの記事の続編になります。

alek3.hatenablog.com

第2回を開催しました。

構想

もともと継続的にやっていこうという気持ちで始めた企画ですので、第2回は第1回の終了後すぐに計画し始めました。

前回の反省として、女性率が低いというのがありましたが、今回は主要メンバーに女性が加わり、非常に心強い体制となりました。

準備

ほぼ前回と変わらず、興味ありそうな人に声をかけていました。しかし、その人数は増えました。ブログやTwitterなどの発言に反応してくれる方がそれなりにいて、その方たちにアプローチしていたためです。

ゲームに関しては、やはり僕以外の人たちがめっちゃ所有していて、毎度驚かされています。

当日

12名の方がいらっしゃいました。女性は4名いました。

割とキャパギリギリでした。直前のキャンセル・参加があるなかで、今回の人数に落ち着いたのは幸運でした。

今回はゲーム中の写真を撮ろうと思っていましたが、顔が映っているのしかない*1ので今回も画像なしです。

12名の参加者がいるので、途中から2テーブルに分けて進行しました。メンバーは都度シャッフルしていました。

No. テーブル① テーブル②
インサイダーゲーム(全体)
ハゲタカのえじき タピオカミルクティー、ムッジーナ
ボブジテン、ドブル タイムボム
ペンギンパーティ、ゴキブリポーカー ダイ公望

テーブル①が僕の参加していたテーブルです。

感想としては、No.②ですね。このタームではテーブル②に全女性が集まっていました。(このことは次の反省にも繋がります。)

女性たちが楽しそうに遊んでいるのを横目に僕達が殺伐*2とした戦いを繰り広げるという、なかなか趣のある時間でした。

また、今回はいろんな方がおかしや飲み物をさしいれていただいて感激しました。ちなみに僕もアルフォートを買っていったのですが、別の方とモロ被りしてしまいました。

反省

①狭い

なんとなく感じていましたが、20㎡という会場で12人は狭いという意見がありました。次回以降、広い会場を探すか、人数を絞るか、非常に悩ましいです。

②僕のインストが下手

インサイダーゲームのインストって意外と難しくないですか?

③チーム分けでのアンチパターン

先に断っておくとここは長いです。

ボドゲのプレー人数は多くても8人くらいが上限なので、今回は2テーブルに分けて進行しました。

チームの分け方は、No.②では「ゲームの候補を二つ(ガチとゆるふわ)挙げてやりたい方を選ぶ」、No.③④は「ランダム」でした。

どちらが良い方法かというと、ランダムベースだと思います。逆に、ゲームの候補を二つ出して、やりたい方を選ぶ、という方法はあまり良くないなと思いました。

なぜか?候補に出した二つのゲームはそれぞれ、カウンティングが重要な「ガチ」枠と、見た目もきれいな「ゆるふわ」枠にわけられます。

このとき、参加者*3にとってのメリットとデメリットは以下のとおりです。

  • メリット
    • 自分のやりたいゲームを遊べる
  • デメリット
    • 「やってみたら意外と面白かった」という体験が減る
    • 遊ぶメンバーが偏る
    • メンバーの固定化を招く
    • ガチ側の人はゆるふわゲームはやりたくないのかなと思われる。(またはその逆)

女性参加者の中にはボドゲ自体初めてという方もいらしたので、最初からガチ枠を選ぶ人はあまりいないと思います。結果上記の通りNo.②ではメンバーが偏りました。

一方、No.③ではタイムボムという人狼と似た思考を要求するゲームを、多くのボドゲ未経験者が遊びました。結果として、タイムボムはその日に一番ウケたゲームとなりました。

これには「やってみたら意外と面白かった」という要素が多少なりとも入ったのかなと思います。

まとめ

次回もよりよい企画にしたいですね。

*1:顔が映っていなければ載せて良いのかというのもある。

*2:6人でのハゲタカのえじきは運の要素が強い

*3:主催者の目的も、参加者により楽しんでもらうことです

UIDatePickerからIntを取り出す、およびその逆(Swift4、初心者向け)

最近、Swiftを書き始めました。主にモバイルアプリを動かすための言語なので、いろいろ分からんところが多かったです。

はまったところもいくつかあり、今回は日付について、書こうと思います。

UIDatePicker←→年月日のInt

直接的にはまったところは、UIDatePickerから年月日の値をそれぞれInt型の変数で取り出す、およびその逆です。 結論としては、コードは以下のようになります。

 // Int → Date Picker

let calendar: Calendar = Calendar(identifier: .gregorian) 
let year = 2018 
let month = 2 
let day = 18 

let dateComponent = DateComponents(year: year, month: month, day: day) 
let date = calendar.date(from: dateComponent)! 
dateComponent .setDate(date, animated: false) 
// Date Picker → Int 

let calendar = Calendar(identifier: .gregorian) 
let pickerDate = datePicker.date 
let dateComponents = calendar.dateComponents([.year, .month, .day], from: pickerDate ) 

let year = dateComponents.year! 
let month = dateComponents.month! 
let day = dateComponents.day! 

DateとNSDate

UIDatePickerの使い方をネットでググると、NSDateをセットしろという内容の記事にあたることがあります。 しかし、上記の通りNSDateは使用していませんし、UIDatePickerのsetDateメソッドでも記載がありません。

それもそのはずで、Swift3からはNS〇〇型はおおむねNSをとった〇〇型に移行している感じです。*1

2014年にSwiftが登場して以降、Objective-C→Swiftという流れがあり、Swiftでも毎年のように1→2→3→4とバージョンが上がっています。3から4はそうでもないですが、それ以外は大きな変更です。 ググるときには、Swift3がリリースされた2016年9月*2以降の記事かどうかのチェックが必要だと改めて思いました。

もくもく会に参加しました #rettypy (Python学習記録⑥)

こちらのもくもく会に参加してきました。

retty.connpass.com

@shinyorkeさん主催の人気のもくもく会のようで、僕はなんとかすぐに予約*1できました。

が、当日あろうことか僕は遅刻をかましてしまいます。申し訳ありませんでした。

主催者に中に入れてもらってもくもく会参加となりました。

実はもくもく会自体が初めてだったので、どんなもんかと思って来ましたが、

割りと静か

という印象でした。マジでもくもくじゃん……。とはいえこれはもくもく会や、その時のメンツによってかわってくるようです。

お昼ごはんは外で食べました。僕が行ったのはこちら→旬彩 本多 (しゅんさい ほんだ) (赤羽橋/割烹・小料理屋) - Retty

f:id:alek3:20180210125954j:plain

うまかった。

雑談ではshinyorkeさんの野球データの話が面白かったです。分析手法というよりは、その前段階の話です。例えば、

  • ピッチングに関しては、どこに投げたか、球速、回転数など、かなり細かくデータが取れる。
  • 日本とアメリカではデータの活用法、すなわちピッチャーのバッターに対する対策の立て方が違う。アメリカの方がアバウト。なぜなら、アメリカでは30のチーム同士で戦うため、そもそも同じピッチャー対バッターの対戦が少ないから。

戻ってきてからはまたずっと作業していました。今度はちょいちょい会話しているところもありましたね。

会場の様子↓

ちなみに僕はここに写ってなくてさらに左の方の机で作業していました。

ところで僕自身何をしていたか書くのをすっかり忘れていたのですが、こちらの技術書を写経していました↓

gihyo.jp

三角関数のグラフを出力して喜んでいたり、Pandasの基本的な項目を学習していたりしました。

日が暮れて少し空気がひんやり*2してきたころ、「成果発表会をするよ」と言われました。

ぼく(成果発表とは……?)

先ほど言ったとおりもくもく会初参加の僕は知らなかったのですが、もくもく会はだいたい最後に今日の成果を皆で共有します。

僕は資料等を全く作っていなかったので、慌てて数分で作り発表しました。

僕みたいな拙い発表でもフィードバックを頂けて、本当に感謝しています。

他の発表だと、色の表現方法には、RGBを使う方法とインデックスカラーを用いる方法があるという話が初めての内容で興味深かったです。

そんなわけで、参加して非常によかったと思っています。次回も参加します。

*1:数時間で予約いっぱいになった記憶があります。結局なんやかんやあって結構繰り上げがあったように見えます。

*2:実際ちょっと寒かった。最近冷え性気味。

PyQレビュー(Python学習記録⑤)

こちらの記事の続きです。

alek3.hatenablog.com

本日、ライトプランを解約しました。1ヶ月と1日での解約となります。

実績

だいたい全部解いての解約ですね。残りの1割については、これやっている意味ないなと感じて飛ばしたものです。

サイト上では所要時間68時間と書いてありますが、半分以下の時間で終わりました。多分別言語をやったことがある人は同じくらいの時間で終わります。

良い点・悪い点追加

基本的に良い点については前回の記事と同様です。問題を解いて即座にフィードバックをもらえるのは大変ありがたいです。

また、サクサク進むので、自分勉強しているぜという感覚が湧いてきてそれも良いです。

悪い点に関しては追加で一点挙げると、「クエスト内の問題を解かないと次の問題を見ることができない」ことです。

例えば以下の画像は、「list,for文」について学習する章となります。

f:id:alek3:20180204163644p:plain

「ループの利用」という文の下に四角形が7つありますが、これは全部で7問ありますよーという意味になります。

サービスに登録すると、この問題を見ることができますが、なんと1問目しか見ることができません。問題を正解して初めて次の問題を読むことができます。

とりあえず問題を全部見たいと思っても全然見れなくて、非常にストレスフルだなと思いました。

まとめ

改善して欲しいところもありましたが、Pythonの文法を学ぶにはベストなサービスだと感じました。文法を学んだ上で、Webアプリケーション、データ分析、機械学習といったトピックに進むといいのかなと思います。