プログラミングで初学者のときにつまづいたこと
プログラミングでつまづいてきたことというブログ記事を見たので、私も書いてみます。
satoru-takeuchi.hatenablog.com
自己紹介
記事をリンクしたお2人と違って大したプログラマではないですが、システムエンジニアとして働いて10年経ってみて今の仕事が向いていると思っているところです。
大学でC言語とJavaを習って、仕事はWeb系で主にJavaを使用しています。
以下、つまづいたことです。だいたい古いのから新しいものになっています。
代入文
a = 1 b = 2 c = a + b
でcが3になるのは分かったのだが、
a = a + 1
これを見て、"左右が等しくない。"と混乱し、そこで思考が止まってしまった。 半年後くらいに代入文という言葉を覚え、上記は"a + 1を計算した結果をaに入れる"だということが分かった (が慣れるまでにはもう少しかかった)。
アルゴリズム
プログラムそれ自体よりもアルゴリズムでつまづく(大学の授業で習った。言語はC言語。)
バブルソートわからない。わかってもコードに落とし込めない。2重ループが難しすぎる。
こんなに便利な世の中なのに、並び替えをするのにいちいち自前でプログラミングをしなければいけないなんて、どうなっているのだと思った。 (色々と認識が間違っていた)
Java
オブジェクト、インスタンス、クラス
用語の説明を何度読んでも理解ができない。他にもとにかく馴染みのないカタカナ語が多すぎて嫌になった。
あるとき、C言語の構造体に関数を足したのがクラスだと気づきそこから理解が進んだ。が、C言語を習っていなかったらと思うと震える。
Javaのオブジェクト指向 (継承、ポリモーフィズム、カプセル化)
惑星クラスを拡張したのが、水星クラス、金星クラス、土星クラスとか、 犬クラスだったら"ワン"と鳴いて、猫クラスだったら"ミャー"と鳴くとか、何に使うかがわからなかった。 値の隠蔽(カプセル化)が重要という割に、setterで値を操作できているではないか、と思った。
理解できるようになったのは、Javaのデザインパターンを読んでから。
ちなみに"オブジェクト指向とは何か"はこちらの記事でWindows95を開発した中島聡さんの言葉を引用しています。
インターフェース
インターフェースも何に使うか長年の疑問だった。実装がないとは何の役にも立たないのではないか。
確かこの本だったと思うけど、"例えば、自動販売機、外側に見える部分がちゃんと仕様通りに動いていれば、中に人が入っていて、手でジュースを出してもよい。自動販売機の、外から見える部分がインターフェース、中の機械とかが実装"、といったことがイラスト付きで書いてあって、その図がシュールで印象に残った。この例からなんとなく理解し始めたように思う。
その後、"仕様と実装を分けて考える"ということができるようになってきたのでインターフェースの使い所もはっきりしてきた。
Rubyのmap関数
array.map {|i| i * 2 }
で、なぜ各配列の値が2倍されるのか分からなかった。Javaしかほぼやってこなかったので、変換後の配列が定義されていないことが不思議だった。
JavaのMapとRubyのmapは全くの別物ということに思い当たったのと(JavaのMapはRubyのhash)、 とりあえずJavaでの記法(for文を使うもの)と対比させて覚えた。
プログラミング以外でのつまづきも多い
リンク先での記事でも「オブジェクト」「スタック」「ヒープ」が多義語で分かりにくかったとの記載があったが、 自分の場合は「ドメイン」「インスタンス」が多義語で混乱した。がこれはプログラミングではないもの(プログラミングの周辺知識ではあるが)も含まれているので機会があれば書きたい。
最近はプログラミング言語それ自体というより、周辺のツールで使用される概念や用語の理解に苦労する。 最近だとDockerの用語の理解でつまづいた。
あとがき
書きながら、プログラム始めたばかりのころ 全然コードが動かなくて吐きそうになったのを思い出しました。
とりあえず私から言えることは、Javaは最初に学ぶような言語ではないということです。
eclipseのJavadocの警告設定の各設定値の意味【後編】
Javadocの記述が不完全なときに警告を出そうとして、どのような設定があるか調べたメモです。
チーム開発でJavadocをどの程度書くかどうか、意識を統一するのにこの記事をご活用いただければと思います。
前編の記事
未指定の Javadoc タグ
"未指定の Javadoc タグ"をONにすると、メソッドに定義されていてJavadocに記載されていないパラメータや例外などがある場合に警告を出します。
メンバーの可視性を次のように設定
設定した可視性以上のJavadocのみ、"未指定の Javadoc タグ"の警告を出します。
オーバーライドしたメソッドの実装を無視
Javaでは、オーバーライドしたメソッドのJavadocは、子クラスの内容で親クラスの内容を上書きした内容となります。
以下の例では、子クラスでdescriptionと変数x
の記述を上書きし、他のparamとreturnについては、親クラスの記述が引き継がれています。
"オーバーライドしたメソッドの実装を無視"をOFFにすると、オーバーライドしたメソッドであっても、未指定の Javadoc タグがある場合には警告を出します。
ただし、@Override
アノテーションが付いている場合、警告は出ません。
詳しい仕様と仕様が策定された経緯につきましてはこちらをご覧ください。
メソッド型パラメータを無視
メソッド型パラメータとは、
ジェネリックメソッドにおいて、メソッドの戻り値の型の直前に書かれた<T>
などの型の仮型パラメータのことです。
(参考:
Java ジェネリクス(クラス、メソッドを定義する) - Qiita
)
"メソッド型パラメータを無視"がONのときは、この<T>
のためのJavadoc(@param <T>
)がなくても警告を出しません。
OFFにすると、警告を出します↓
未指定の Javadoc コメント
"未指定の Javadoc コメント"をONにすると、Javadocが記載されていない場合に警告を出します。
"メンバーの可視性を次のように設定"を"Protected"にした時の表示です↓
メンバーの可視性を次のように設定
設定した可視性以上のJavadocのみ、警告を出します。
オーバーライドしたメソッドの実装を無視
"オーバーライドしたメソッドの実装を無視"をONにすると、オーバーライドしたメソッドにJavadocが無くても警告を出しません。
オーバーライドしたメソッドは、Javaでは親クラスのJavadocが使用されるため、指定しなくても問題ないことが多いかもしれません。
"オーバーライドしたメソッドの実装を無視"をOFFにすると、オーバーライドしたメソッドにも警告を出します。
"未指定の Javadoc タグ > オーバーライドしたメソッドの実装を無視"
の設定とは違い、こちらは@Override
アノテーションのあるなしでの挙動の違いはありません。
オーバーライドしたメソッドに親と同じ内容のJavadocを書ときは、{@inheritDoc}
タグを使うと便利です。
/** * {@inheritDoc} */ @Override public int calcA(int x, int y, int z) { return x + y + z + 1; }
参考: オーバーライドしたメソッドのJavadoc - 気付いたとき、気が向いたとき。by ykhr
環境
- eclipse 2019-12 (https://mergedoc.osdn.jp/ からPleiades All in One Eclipse(Mac 64 bit/Full Edition/Java)をダウンロードしました)
あとがき
"未指定の Javadoc タグ > オーバーライドしたメソッドの実装を無視" の設定が自分の想定と違った動作をしたので意外と苦戦しました。
参考サイト
eclipseのJavadocの警告設定の各設定値の意味【前編】
Javadocの記述が不完全なときに警告を出そうとして、どのような設定があるか調べたメモです。
チーム開発で、Javadocをどの程度書くかどうか、意識を統一するのにこの記事をご活用いただければと思います。
Javadocの警告設定
Javadocの書き方がよくないときに警告を出す設定の場所は、
設定 > Java > コンパイラー > Javadoc
です。
Javadocコメントを処理
"Javadocコメントを処理"をONにすると、Javadocとメソッドが連携されます。 変数名を選択したときにJavadocのparamの変数名もハイライトされます。
ONのとき↓
OFFのとき↓
また、ONにすると、変数のリネーム時にJavadocのparamの変数も同時に変更されます。
ONのとき↓
OFFのとき↓
誤った形式の Javadoc コメント
"誤った形式の Javadoc コメント"をONにすると、波かっこが閉じていないときなどに警告を出します。
メンバーの可視性を次のように設定
設定した可視性以上のJavadocのみ、警告を出します。
可視性をProtectedにしたときに、PublicとProtedtedメソッドのにのみ警告が出て、パッケージとPrivateのメソッドに警告は出ません↓(タグ引数の検証をONにしたときの警告)
タグ引数の検証 (@param, @throws, @exceptions, @see, @link)
"タグ引数の検証"をONにすると、@param
, @throws
, @exceptions
, @see
, @link
に
指定されたクラスやメソッドが存在しないときに警告を出します。
min1という引数はメソッドに存在しないため、警告が出ます↓
Nowhere.nomthod
という存在しないクラスとメソッドを参照しているので警告が出ます↓
不可視参照をレポート
"不可視参照をレポート"をONにすると、 不可視なメソッドなどを参照をしたときに警告を出します。不可視な参照とは、例えば他のクラスのprivateなメソッドや定数です。
他のクラス(SamplePrivateクラス)のprivateな定数(DEFAULT_NAME
)を参照しているので、警告が出ます↓
使用すべきでない参照をレポート
"使用すべきでない参照をレポート"をONにすると、非推奨(Deprecated
)となったメソッドや変数を参照したときに警告します。
タグ記述の欠落
"タグ記述の欠落"の設定では、
@param 変数名
や@return
などのタグのあとの記述が無いときに警告を出します。
@return タグの検証
ではその名の通り、@return
タグの後に何も書かれていなければ警告を出します。その他のタグの後には何も書かれていなくても警告を出しません。
全ての標準タグを検証
にすると、全ての標準タグにおいて、タグの記述がない場合に警告を出します。標準タグとは
javadoc - Java API ドキュメントジェネレータ
に記載されているタグです。
後編
長くなったので続きます。
環境
- eclipse 2019-12 (https://mergedoc.osdn.jp/ からPleiades All in One Eclipse(Mac 64 bit/Full Edition/Java)をダウンロードしました)
参考サイト
eclipseの警告表示の重大度レベルごとの挙動
前回の記事で、eclipseの警告レベルをどれにするか迷ったので、各重大度レベルでの挙動を確認しました。
eclipseの警告表示の設定
eclipseを使用していると、黄色の波線と警告マーク(3角形の中に!
)が表示されたことがあるでしょう。
これらの設定は、
設定 > Java > コンパイラー > エラー/警告
で変更可能です。
エラー、警告、情報、無視の違い
エラー/警告の設定では、eclipseが問題を検出したときにの重大度を設定できます。
重大度レベルごとのeclipseの挙動です。
重大度レベル | 表示 |
---|---|
エラー | 問題がある箇所に赤の点線が引かれ、該当する行及びファイル名にバツ(× )印がつきます。さらに、プログラムの実行時に"必要なプロジェクトでのエラー"のダイアログが表示されます。("続行"を押すと実行できます。) |
警告 | 問題がある箇所に黄色の点線が引かれ、該当する行及びファイル名にエクスクラメーションマーク(! )がつきます。実行時にダイアログは出ません。 |
情報 | 問題がある箇所に青の波線が引かれ、該当する行及びファイル名に"i"マークがつきます。実行時にダイアログは出ません。 |
無視 | 何も表示しません。 |
エラー
エラーの時の表示です。
実行時にダイアログが表示されます↓
警告
警告の時の表示です。
情報
情報の時の表示です。
無視
無視の時は何も表示されません。
エラー、警告、情報の一覧を表示する
現在のワークスペースの警告の一覧を表示するには、ウィンドウ > ビューの表示 > その他 > 一般 > マーカー
を開きます。
"マーカー"のビューに現在のワークスペース内に存在するエラーや警告が表示されます。各項目をクリックすると該当箇所へジャンプすることができます。
以上、eclipseの警告設定と各重大度レベルごとの挙動でした。
環境
うっかりミスを防ぐeclipseおすすめ設定6つ【後編】
前編に引き続き、うっかりミスを防止(警告)するeclipseの設定をまとめました。
前編の記事
セミコロン2つを検知
行末のセミコロンを間違って2つ打ってしまうのもありがちなミスです。
設定 > Java > コンパイラー > エラー/警告 > 潜在的なプログラミングの問題 > 空のステートメント
の警告レベルを、"情報"にします。
設定前↓
設定後↓
マウスオーバーするとセミコロンの除去がサジェストされます↓
何も記述されていないブロックを検出
何も記述されていないブロックを検出する方法です。 何も書かれないブロックが必要な場合もあります。そんなときはコメントを書いておくか消しててほしいものです。
設定 > Java > コンパイラー > エラー/警告 > コード・スタイル > 何も記述のない空のブロック
の警告レベルを、"警告"にします。
設定前↓
設定後↓
空ブロックにコードかコメントを書くように促されます↓
@Overrideのつけ忘れを防ぐ
オーバーライドしたメソッドに@Override
アノテーションが付いていない場合に警告します。
設定 > Java > コンパイラー > エラー/警告 > 注釈 > '@Override' 注釈の欠落
の警告レベルを、"警告"にします。
設定前↓
設定後↓
@Overrideをつけるようにとの警告が表示されるようになりました↓
環境
- eclipse 2019-12 (https://mergedoc.osdn.jp/ からPleiades All in One Eclipse(Mac 64 bit/Full Edition/Java)をダウンロードしました)
あとがき
以上、うっかりミスを防ぐためのおすすめeclipse設定でした。書きながら、とりあえず
設定 > Java > コンパイラー > エラー/警告
の"無視"となっているところを全て"情報"以上にすればよいのではと思うのでした。
うっかりミスを防ぐeclipseおすすめ設定6つ【前編】
こんにちは。プログラミングでうっかりミスをしてしまうブログ主です。特にスペルミスがひどいです。 レビューで指摘されると申し訳無い気持ちになるので、そのようなうっかりミスを防止(警告)するeclipseの設定をまとめました。
空白の表示
空白タブ、全角空白、改行文字などを表示するオプションです。
設定 > 一般 > エディター > テキスト・エディター > 空白文字を表示
にチェックを入れます。
次に、可視性の構成
をクリックして全てチェックを入れます。
設定前↓
設定後↓
タブは^
、スペースは.
、全角スペースは□
で表示されました。改行コードは、LF(Unixの改行コード)は↓
、CRLF(Windowsの改行コード)は⏎
で表示されます。
チーム開発時にONにしてほしいオプションナンバー1です。空白とタブを混ぜると後々見にくさの原因になります。
スペルチェック
スペルをチェックをするオプションです。
設定 > 一般 > エディター > テキスト・エディター > スペル > スペル・チェックを使用可能にする
にチェックを入れます。
設定前↓
設定後↓
赤の波線が出ている箇所にマウスオーバーすると、修正の候補が表示されます↓
Javadocのチェック
Javadocの@param
などの項目がメソッドの定義と一致しているかをチェックするオプションです。リファクタリングのときにJavadocを修正し忘れることはよくあるので入れておきたい設定です。
設定 > Java > コンパイラー > Javadoc
を開き、以下のような設定にします。
各設定項目の挙動についてはこちらの記事をご覧ください。
設定前↓
設定後↓
メソッドで宣言されていないパラメータがJavadocにあると警告を出します↓
returnに何も記述されていないと警告を出します↓
存在しないクラスやメソッドを参照すると警告を出します↓
メソッド宣言にあって、Javadocに無いパラメータがあるときに警告を出します↓
環境
- eclipse 2019-12 (https://mergedoc.osdn.jp/ からPleiades All in One Eclipse(Mac 64 bit/Full Edition/Java)をダウンロードしました)
後編に続く
長くなったので続きます。
Pythonで辞書が格納されたリストを複数のキーで並べ変える
辞書を格納したリストがある時、複数キーで並び変える方法を紹介します。例えば、以下のような辞書が格納された配列で、まずprice順に並び変え、priceが同じだったら、weightの順番に並び変えたい場合の方法です。
list1 = [ {'name': 'ぶどう', 'price': 5000, 'weight': 1000}, {'name': 'もも', 'price': 3000, 'weight': 2000}, {'name': 'りんご', 'price': 5000, 'weight': 5000}, {'name': 'バナナ', 'price': 1500, 'weight': 1000}, {'name': 'メロン', 'price': 5000, 'weight': 1200}, {'name': 'マンゴー', 'price': 10000, 'weight': 900}, {'name': 'みかん', 'price': 1500, 'weight': 5000}, ]
keyにitemgetterを使用する
辞書の値で並び替える場合、itemgetter
関数が便利です。
参考: ソート HOW TO — Python 3.8.1 ドキュメント
itemgetter
を使用するときは、
パラメータに辞書のキー名を並び替えの優先順位の順に書きます。
sorted(list, key=itemgetter(第1キー, 第2キー, 第3キー))
まずprice順に並び変え、priceが同じだったら、weightの順番に並び変えたい場合はsorted
関数のキーにitemgetter('price', 'weight')
を指定します。
コードと並べ替えの結果です。
from operator import itemgetter # list1は上記のlist1と同様 list1 = [...] # 並べ替え sorted_list = sorted(list1, key=itemgetter('price', 'weight')) # 出力 print(f"{'name':<8}{'price':>8}{'weight':>8}") print('-' * 24) for item1 in sorted_list: print(f"{item1['name']:<8}{item1['price']:>8}{item1['weight']:>8}") # name price weight # -------------------------------- # バナナ 1500 1000 # みかん 1500 5000 # もも 3000 2000 # ぶどう 5000 1000 # メロン 5000 1200 # りんご 5000 5000 # マンゴー 10000 900
priceで最初に並べ替え、priceが同じ場合はweightで並び替えられています。デフォルトなのでいずれも昇順で並び替えられています。
keyにlambda関数を使用する
より一般的に複数のキーで並び替えたいときは、keyに指定する関数の戻り値にタプルを指定します。
例えば、グラム単価(price/weight)で並び替えた後、同じグラム単価であれば、priceで並び替えるようなプログラムは以下になります。
# list1は上記のlist1と同様 list1 = [...] # 並べ替え sorted_list = sorted(list1, key=lambda item: (item['price'] / item['weight'], item['price'])) # 出力 print(f"{'name':<8}{'price(1g)':>10}{'price':>8}{'weight':>8}") print('-' * 34) for item1 in sorted_list: print(f"{item1['name']:<8}{item1['price'] / item1['weight']:>10.2f}{item1['price']:>8}{item1['weight']:>8}") # name price(1g) price weight # ---------------------------------- # みかん 0.30 1500 5000 # りんご 1.00 5000 5000 # バナナ 1.50 1500 1000 # もも 1.50 3000 2000 # メロン 4.17 5000 1200 # ぶどう 5.00 5000 1000 # マンゴー 11.11 10000 900
グラム単価で並び替えた後、同じグラム単価であれば、priceで並び替えることができました。 マンゴーのグラム単価高いですね。
以上でPythonで辞書が格納されたリストを複数のキーで並べ変えることができました。
環境
- Python: 3.7