【パワー系PG】データを整数型で表現しないで列挙型を使え
あなたのプログラム、「intを不必要に多用」してませんか?
どの言語にもenumみたいな列挙型ってあると思うんだ。
C言語における、intとenumによる実装の違いを紹介しよう。
intを使ったときの実装
#include <stdio.h> int main(void){ int warningRate; //2桁入力【例:36】 scanf("%02d", &warningRate); int signal; if(warningRate < 50){ signal= 0; } else if(warningRate < 75){ signal= 1; } else{ signal= 2; } switch(signal){ case 0: printf("緑、今日も平和だ"); break; case 1: printf("黄、危ない予感"); break; case 2: printf("赤、逃げろー!"); break; } }
読ませる側や保守・運用を考えない
パワー系PGの臭いがする!!
enumを使ったときの実装
#include <stdio.h> enum Signal{ Green, Yellow, Red, }; int main(void){ int warningRate; //2桁入力【例:36】 scanf("%02d", &warningRate); enum Signal s; if(warningRate < 50){ s = Green; } else if(warningRate < 75){ s = Yellow; } else{ s = Red; } switch(s){ case Green: printf("緑、今日も平和だ"); break; case Yellow: printf("黄、危ない予感"); break; case Red: printf("赤、逃げろー!"); break; } }
【パワー系PG】ハードコーディングはやめてDBMSを使いたい
あなたのプログラム、「ハードコーディング」してませんか?
ハードコーディングとは簡単に言うと以下のような感じ
内容としては業務データをプログラムで作っている処理。
int input; scanf("%d", &employeeNo); if(employeeNo< 1&& employeeNo> 100){ //①の業務データ } else if(employeeNo< 101 && employeeNo> 200){ //②の業務データ } else if(employeeNo< 201 && employeeNo> 300){ //③の業務データ } else if(employeeNo< 301 && employeeNo> 400){ //④の業務データ } else if(employeeNo< 401 && employeeNo> 500){ //⑤の業務データ } else if(employeeNo< 501 && employeeNo> 600){ //⑥の業務データ } else if(employeeNo< 601 && employeeNo> 700){ //⑦の業務データ } else if(employeeNo< 701 && employeeNo> 800){ //⑧の業務データ }
あっ、パワー系PGが書いたコードか!!!
さて、上のコードで気になるのが何点か。
- 1とか100とか101とか200って何ぞ??
- コード量にパワーを感じる
コードを書いていない側からすると
色々気になってくるコードだね。
卒業する方法
- 1とか100とか101とか200って何ぞ??
- コード量にパワーを感じる
仰る通りです。
パワー感じますよね。
1とか100とか101とか、パッと見、数値の意味がわからんちんですな。
そもそも、
業務データを取り扱うときは
プログラムにガリガリ書くべきではないです。
まあ、当たり前の話です。
業務データを取り扱うときは
プログラムに直接持たせるのではなく、
DBMS(データベース管理システム)を使いましょう。
言語とDBMSを連携するには相応のライブラリや
フレームワークを流用するのが筋です。
DBMSも、色々種類があるので何か自分に合うものを探すと良いです。
例えば「C言語とMySqlの連携」を例に挙げるなら、
以下の記事辺りを参考にしてください。
d.hatena.ne.jp
ぐぐればいくらでも出ます。
あと、データベースにアクセスするためには
SQL文というのを覚えないといけません。
まあ単純な文なら一瞬で覚えられます。
cfm-art.sakura.ne.jp
書き方のイメージとして以下のような形式。
SELECT [営業所種別] FROM [従業員テーブル] WHERE [従業員番号]
SQL文はライブラリやフレームワークによって
プログラム内に記載できます。
例えば、WHEREの後には条件を記載するのですが、
条件に先ほど定義したemployeeNoを渡すこともできます。
※その場合はemployeeNoに対するレコードをDBからもらえます。
ですので、
データベースから引っこ抜いた営業所種別のレコードをそのまま流用すれば
プログラムとしては数行で済むわけです。
業務データはDBMSを使おう。
「パワー系PG」は卒業したい
こんにちは。
突然ですが、あなたのプログラムからパワーは感じませんか?
- 1ファイルに数千行も記載してる?
- 機能分割がきちんとできていない?
- 同じコードをコピペしている?
- 変数を連番に命名している?
- 変数名が適当?
- 1行に無理やりロジックを詰め込む?
- 似たようなリテラルを直書きしてる?
さて、本来はプログラムにパワー(気合)を込めるべきなのでしょうか?
自分はそうは思いません。
成果物に対して、
可能な限り少ないコード量で人が読めるコーディングをすべきです。
気合で書いたコードは以下の問題があります。
- バグが発生したとき、何千行もあるコードを人が気合で見ることになる
- バグを修正するとき該当箇所が複数箇所にコピペされており、修正箇所の網羅と修正漏れが怖い
- 適当な変数名を定義したりリテラルを直書きしたりで、該当行で何の処理をしているのかまったくわからない
- 1行にやりたいことを詰めすぎて処理が追えない
適当に箇条書きしましたが、とにかく恐ろしいです。
このように、頭を使わないで
とにかく「コピペ」や「一時的な解決にしかならないコーディング」等、
コーディングをパワープレイで済ませようとする人のことを
「パワー系PG」と呼んでます。
「パワー系PG」はまともなPGではありません。
自分のプログラムにパワーを感じてきたら
要注意です。
パワー系PGは卒業して、
効率を重視する面倒くさがり屋で優秀なPGになろう。
C言語でうるう年計算・月の末日計算・曜日計算を一通り書いた
学生の課題あるあるのプログラム。
各関数は全部落ちてるソースをパクっただけ。
fudebaco.com
edu.clipper.co.jp
C言語入門:うるう年判定プログラム:Geekなぺーじ
#include <stdio.h> int main(void){ int year; //yyyyで入力する!例「1970」 scanf("%d", &year); int month; //mmで入力する!例「01」 scanf("%02d", &month); char weekdays[7][4] = {"日","月","火","水","木","金","土"}; int lastday = GetLastDay(year, month); for(int today = 1; today < lastday + 1; ++today){ printf("%02d年%02d月%02d日 ",year,month,today); int weekday = GetWeekday(year, month, today); printf("%s曜日\n",weekdays[weekday]); } return 0; } int IsLeapYear(int year){ if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) { printf("%02d年はうるう年\n", year); return 1; } else { printf("%02d年はうるう年ではない\n", year); return 0; } } int GetWeekday( int y, int m, int d ){ if( m < 3 ) { y--; m += 12; } return ( y + y/4 - y/100 + y/400 + ( 13*m + 8 )/5 + d )%7; } int GetLastDay(int year, int month){ int l; int lmdays[] = {31,29,31,30,31,30,31,31,30,31,30,31}; int mdays[] = {31,28,31,30,31,30,31,31,30,31,30,31}; int lastday; l = IsLeapYear(year); if (l == 1) { lastday = lmdays[month - 1]; } else { lastday = mdays[month - 1]; } printf("%02d年%02d月の末日は%d日\n",year,month,lastday); return lastday; }
入力
1992 02
出力
1992年はうるう年 1992年02月の末日は29日 1992年02月01日 土曜日 1992年02月02日 日曜日 1992年02月03日 月曜日 1992年02月04日 火曜日 1992年02月05日 水曜日 1992年02月06日 木曜日 1992年02月07日 金曜日 1992年02月08日 土曜日 1992年02月09日 日曜日 1992年02月10日 月曜日 1992年02月11日 火曜日 1992年02月12日 水曜日 1992年02月13日 木曜日 1992年02月14日 金曜日 1992年02月15日 土曜日 1992年02月16日 日曜日 1992年02月17日 月曜日 1992年02月18日 火曜日 1992年02月19日 水曜日 1992年02月20日 木曜日 1992年02月21日 金曜日 1992年02月22日 土曜日 1992年02月23日 日曜日 1992年02月24日 月曜日 1992年02月25日 火曜日 1992年02月26日 水曜日 1992年02月27日 木曜日 1992年02月28日 金曜日 1992年02月29日 土曜日
テーマをカスタマイズした
背景色が地味だったのと、透明感を持たせたいなーと言うことで
コンテンツのアルファ値を変更しやした!!
デザインCSSに以下の記述を追加。
#container-inner{ background-color: rgba(46, 46, 46, 0.93); } .entry-inner blockquote{ background-color: rgba(46, 46, 46, 0); }
引用が追随して透過されなかったので、
entry-innerクラスの引用文に対して直接透過を指定しやした。
透明感がでてすっきりしたぜ。
C#で文字列を弄るなら正規表現を使いたい
ファイル名に拡張子をつけていないので、
ファイルを保存する際に、
拡張子を追記して保存するようにしたい
と仰る方を見かけたので一つサンプルコードを。
文字列操作なんて不要!
なら、正規表現で置き換えてみよう。
↓無理やり文字列の後尾に「.png」を追加するプログラム
using System; using System.Text.RegularExpressions; public class Program{ public static void Main(){ string fileName = Console.ReadLine(); if(fileName == null){ Console.WriteLine("入力に文字を入れてください。"); return; } if(fileName.Contains(".")){ Console.WriteLine("拡張子を.pngに置き換えます"); fileName = Regex.Replace(fileName,@"(?<=\.)(.*)","png"); } else{ fileName = string.Concat(fileName , ".png"); } Console.WriteLine(fileName); } }
追記
↑のやつ
「aaaa.hoge.fuga」ってやると
「aaaa.png」になる。駄目コード。
ってか、少し調べてたらこんなクラスがあったで。。。
Path.ChangeExtension メソッド (String, String) (System.IO)
正規表現なんて不要!
なら、ChangeExtensionで置き換えてみよう。
↓無理やり文字列の後尾に「.png」を追加するプログラム(Ver2)
using System; public class Program{ public static void Main(){ string fileName = Console.ReadLine(); if(fileName == null){ Console.WriteLine("入力に文字を入れてください。"); return; } fileName = System.IO.Path.ChangeExtension(fileName, "png"); Console.WriteLine(fileName); } }
え?
1行で済むやないかーーーーーい
.NET様様だね。