見出し画像

【Console Application】練習01 4【学習記】

基本文法を学んだ後によくある練習課題みたいなやつをやる話🤤

Q.
やりすぎだったって?
A.
Java や OC みたいな古典的な宣言して代入して集計してって処理を書くのが筋だったっぽい🤪
→回答見たら自分がやっていたのは小学生の算数の問題を数学の公式で解いた感じになってた🙄

#学習記 #練習問題
#Kotlin #Swift #Java #Objective_C

基準になるコードの話をしている記事はこちら

【Console Application】練習01【学習記】
https://note.com/sayka/n/n7b2ba075664f

以前のまとめはこちら

【Console Application】基本文法 29【学習記】
https://note.com/sayka/n/n935c7bb3ad56?magazine_key=m7bb64c6a359f


練習01を解いた事で得られた知見

それじゃ練習問題01を解いてのまとめ、はっじまるよー🤪
まずはソースが1画面に収まったからそれぞれ撮ったので貼っておこうね🤤

Kotlin
Java
Swift
Objective-C

それで、終わったから回答見たのね?
ここには載せないけど、古い Java の課題そのまま移植しただけなんじゃない?これ?って感じの回答だった🤤
それと同時に理解した…自分は やりすぎたのだ… と🙄
初心者が学習して最初の課題なんだから単純な構築論ロジックで組む課題に決まってるのにやれ初期化子だのなんだのってやってたわけ…😞ただの空回り

自作のだとエラーメッセージは1種しかないからって再利用兼圧縮のため変数に入れてるけど、回答だと1つ検査して1つ println でベタ打ちして次のエラーもまた println にベタ打ち…
乱数配列も自作のは初期化子で1発だけど回答だと宣言した後に乱数を1つずつ for で入れて…合計も for で足し算して…ってなってた🤤
しかも御丁寧に関数化して再利用可能になってた… Java とか OCObjective-C で機能無いの当たり前じゃん、課題もそういうの使わない前提で回答が書かれてる🙄
算数の問題を数学の公式で解いてドヤってる状態🤪
まぁ、プログラムの世界は学校のテストみたいに「教えてない方法で解いたので✕」という事は無く「動けば勝ち」なのでこれでヨシ!👈🤪

当然ながら、拡張性は回答の方が優れていて機能の修正も行いやすいと思われる🤤
欠点は行数が多いのでちょっと追いかけにくいところ。
自作のは1画面に収まってるのもあってコードを追いかけるのはかなり楽なんだけど、最適化に近いので拡張性に乏しい🙄
できなくはないけど配列とかの宣言を分離したりで割と手間がかかるかな🤔
メンテしやすさを考えたら今回の自作のは最適解というかは微妙🤪
Kotlin が Java を喰おうとしてるなら回答の様ないにしえの機能の関数化をいちいちやる方針の方が良く、 Android 開発主体でしかないなら専用処理を書く方が多いだろうから自作の様な圧縮の方がやりやすいかなとは思う🤤


print

回答を見てから気がついた
println 使えば \n 書かなくて良かった事に…😞
そしたら print("${errmsg}\n") じゃなく println(errmsg) になってすっきりだったのに…🤪

Java にも println は有るけどフォーマットが使えないのでどちらが良いかは完全に好みかなと思う🤔
以前みたく printflnJV とか作ったら使いやすいかも🤤

Swift の print は元々改行込みで出力されテンプレートも使えるので妙な文字列結合演算子を書かなくて済むのが良いところかな🤤
ライブラリ作ってて調べた時チラっと見たけど Optional 変数の場合で nil だと何も挿入しないんだったかな。地味に有り難いよね🤔
でもこの \(...) の中で nil 合体演算子使おうとするとうまくいかない事があるので要注意かな🙄

OC は printf という名前を定着させた諸悪の根源 C 言語の系譜であーる🤤
だけど char* でしか受け取らなくて毎回 NSString を .UTF8String って付けてやらなくちゃならなくてテラめんどくさいので OC で printf を多用したい人は NSString を受け取る printfOC みたいなのを作ってしまうのがいいかな🤔

各言語で print や printf の実装に違いが有るので多言語クロス開発する予定がある場合はフォーマッターを別で通して出力という二段構成で組む方が移植はしやすいと思う🤤


コマンドライン引数

これは取得方法が違うのは Swift のみかな🤔
でも OC との互換性を持たせるためなのか、実行ファイル名が引数に含まれるので忘れているとハマる🤪
このコマンドライン引数は結構厄介なシロモノで、確か windows はコンソール起動とデスクトップでファイルドロップだと入力される状態に違いが出るんだったかな🙄
まぁ Windows で Swift 使って Windows アプリ作る様な人はほぼ居ないと思うので考慮しなくても良いんだろうけど🤤

コマンドライン引数については基本的にはコンソールアプリとしてプロジェクトを作成すれば困る事は余り無いけど、コンソールからも起動できるデスクトップアプリを作ろうとするとまた難しい問題が出てくるだろうからそういうのを探してるなら今この段階ではこの記事は全く参考にならないかな🤤


文字列が数値かどうか判定

これで一番困ったのは OC 😞
文字列を数値にする関数は幾つか用意されてるんだけど調べてすぐ出てくるやつはいずれも「非数でも0」を返す仕様かな🙄
そういうのを調べた記事が有って nil.integerValue でも 0 が返ってくるらしいのよね🤔

Objective-Cにおいて [nil intValue] がエラー無く0を返す理由
https://qiita.com/cha84rakanal/items/6771c788eb93c2eb68dd

結局探し回って得られたのは「正規表現で捜査する」🙄
そういう検査ライブラリが有っても良さそうだけど無いのよね😞
あとなんか NSString の仕様らしいんだけど match 式を表す文字列で \d みたいのは警告が出て、警告無くすには \\d にする必要があるのだとか🙄
まぁ与えてるのが文字列なのでそうなるのかなと。いいじゃんね?そんくらい🤪
(なお、直さなくても有効らしい)


乱数配列

今回キモになった部分🤤
配列を希望の枠数で、初期化子で乱数を詰め込む… C の系譜 OC/OC++ では勿論無理🙄
でももしかしたらラムダ式を理解したらできたりしないかな…🤤
なんかできそうな気もするけど配列の初期化子に使えるかどうかは今の段階では判らない。 C++ の達人じゃ、ないからね自分は🤪

Java でもインスタントなんたらで初期化に式を書けるっぽいけど研究不足😞
課題的にはそこまで無理しなくても伝統的な代入でヨシってなるみたいなのでそういう意味では安心🤤

Swift は初期化子こそ書けないけど器を用意newしてそのまま map 参照化して中身を注入するっていう JavaScript でよく見る多段ラッピングみたいな技法が使えるのが特徴かな🤤
この方法の存在により用意した配列を const定数 化できるのが強みかなって思うし入れる中身が自由自在にしやすい🤤

Kotlin は最初から初期化式が書けるようになってた🤤
これが良い事なのかどうかはさておいて配列のライブラリとしてはもしかしたら重いコンパイルだったりしないかなってのが今回の懸念点🤔
最初に取り掛かったのが Kotlin だったから「わーいらくちーん♪」くらいだったんだけど Swift や他に移植していて「もしかしてこのライブラリは重いのでは?🙄」という疑念が生まれた🤪
機能が無い、即ちその分ライブラリは軽い、なのよね。
果たしてどっちが良いのかな?って感じだけど学習負荷コストは明らかに Kotlin の方が軽いので AndroidKotlin VS iOSSwift だとやっぱ Kotlin 有利になっちゃうかなって思う🙄
KotlinAndroid はどっちのデスクトップ OS でも開発できるけど SwiftiOS は(できなくはないけどほぼ) Mac のみだから障壁ハードルは 1 枚 2 枚どころの騒ぎではないよねこれは😞

因みに学習課題としての回答では const 化は命題ではないので var で定義して普通に for で詰め込んでましたとさ🤤

………
式が長くなるけど OC は [NSMutableArray array] は
[NSArray arrayWithArray:{/* NSMutableArray に詰め込んで return するラムダ式またはクロージャ */}]
で通るのでは…🙄イマサラだけど


並べ替えsort

これは元の乱数配列を「破壊しても良いか」どうかで手法が変わってくる項目だった🤤
自作みたく最後に纏めて出力する場合、非破壊ソートが無い場合、一旦複製をしてからソートに掛ける、という手法になる🤔
非破壊の場合は大体が結果の配列を返り値にするのでそのまま初期化子として利用してしまえる🤤
多分ここも同じ様な圧縮式ラムダやクロージャを書いて const 化する事ができるだろうなって思う🤔
まぁ const 化が大好きな人結構居るみたいだから知ってて損は無い手法なのかなと思うけど現在の学習状態だとちょっとまだできない🤪
JSJavaScript にもラムダは有るけれどあんまり ES6 はさわれてないのでラムダの理解が進んでないのよね😞


集計

これは新環境である Kotlin と Swift が両方共、配列に集計用の何かしかの機能が実装されてた🤔
Kotlin は総計を求めるずばりの関数を備えてる🤤
Swift は総計を行う為の処理式が書けるようになってた🙄
Kotlin の実装やコンパイルが重くなるのかもと感じたのはここの部分を Swift でやってた時かな🤔
パッと見のやり方が $0 + $1 みたいのばっかりで「お前はシェルスクリプトかよ」ってなったけど OC からの延長線上に居る言語なら入っていても不思議ではない実装なのよね🤤
でもこれ、式は自分で書いてねって方針なので重くなるも軽くなるもコーダー書く人次第、一方 Kotlin は標準実装…🙄
何回も書くけど標準実装が多い程ライブラリとしては重くなるのよね。だからどちらが良いかっていうとその辺りは秤にかけないとわからない🤔
処理を書くのに1時間くらい彷徨った Swift と一発一瞬ググってすぐ出る Kotlin 、開発は軽いが動作は重い…?この程度で?しかしプロジェクトの規模が大きくなるとそういう部分はチリツモなわけで果たして…というのを見切る部分が「仕事だったら要る」かなって思う🤪

まぁ究極的には動けば「ヨシ!👈🤪」


平均

地味に時間取られたのがこれ🙄
整数を小数の型にしてからやらないといけないけど、このやり方が各言語で見事にバラバラ😞
古い体系の Java と OC は同じでできてるかなって感じだけどこれはプリミティブ参照ではない裸の値を言語側がどのように「ラップしてくれるか」次第になるのかなって感じかな🙄
一番安全なのは Swift の Float(num) だと思う。 null 安全的に、だけど🤤
num.toFloat とか (float)num は num が Optional だと式が凄い面倒な事になりそうなのは明らかだけど Float(num) なら Optional かどうかの処理を含めて委ねてしまえるとこが安心🤤(手抜き


配列の中身をカンマ区切りで

はい、来ました、2つ目の山場🙄
所謂いわゆる join の実装次第で変わっちゃう🤪

Swift が一番苦労したけど、今考えたら OC のライブラリ使える筈だし Array は NSArray だと思うから OC でやった componentsJoinedByString が使えるのでは?って思ったけどもう完全に手遅れ🤪終了済みだから
Java は print によって無理やり表示を結合してるけどこれは Kotlin や Swift で「追加の変数無しに dump を出力する」を命題に組んだ結果なので print の項で書いた様に一旦表示用の文字列へフォーマットして、という手順の方が後に誰かが手を入れる事になった場合親切かなと思う🤤
(なお、それやると使用メモリ爆増する模様)


次回は

手元の学習のやつで次はクラスになってるんだけど「これは何だろう?」ってのが幾つかあるからそれを調べようかな🤤
Kotlin に有って Java に無い、 Swift や OC では違う概念、とかそういう手合の調査になるかな🤔
ファイルはその後w


いいなと思ったら応援しよう!