PlayframeworkのFormで要素が一つのcase classと仲良くする
要素が一つのcase classがあると困ること
例えば下のようなcase classをやり取りしたい時、JSONではちょっと困りますよね。
case class LongValue(value: Long) { require(value % 2 == 0) }
JSONの方は仕方なくこうして、
{ "longValue": { "value": 20 } }
そして Form はこう
def hoge() = Form( "longValue" -> mapping( "value" -> longNumber.verifying(_ % 2 == 0) )(LongValue.apply)(LongValue.unapply) )
これだけならまだ良いけどこれが配列で…とかになるともう面倒ですよね。
それにせっかくcase classで require を指定してるのに verifying でチェックするのもなんか面倒ですよね。
専用の Formatter を用意する
こんな感じのFormatterを用意してやるといい感じにできます。
def formatter[T](f:String => T) = new Formatter[T] { override val format = None override def bind(key: String, data: Map[String, String]): Either[Seq[FormError], T] = try { data.get(key) match { case Some(v) => Right(f(v)) case _ => Left(Seq(FormError(key, "error.required", Nil))) } } catch { case _: Exception => Left(Seq(FormError(key, s"error.${key}", Nil))) } override def unbind(key: String, value: T): Map[String, String] = Map(key -> value.toString) } val longValue = of[LongValue](formatter(s => LongValue(s.toLong)))
これを使うとJSONはこう
{ "longValue": 20 }
Form はこう
Form(
"longValue" -> longValue
)
LongValue 配列だったとしてもこんなので済みます。
Form(
"longValue" -> list(longValue)
)
必要であれば標準の optional や verifying も使えます。
Form(
"longValue" -> optional(longValue.verifying(_.value <= 10))
)
さらに、他のcase classをつかいたくなったときにはこうです。
case class IntValue(value: Int) val intValue:FieldMapping[IntValue] = of[IntValue](formatter(s => IntValue(s.toInt)))
普通にマッピング書くよりすこしコード量増えてしまいますが、要素が一つのcase classが頻繁に登場するようであれば Form はむしろスッキリするのではないでしょうか
IntelliJ IDEAでsbtのテストをステップ実行する方法
ここで紹介されていた方法がうまく行かなかったのでsbt0.13.13で実行可能な最小構成を作成。
Defaults.testSettings では test/main/scala 以下のテストが共有されないらしいので、代わりに Defaults.testTasks を使えばいいらしい。
初めての WPF デスクトップ アプリケーション
初めてのWPF
MSから公開されいているこのチュートリアルをやってみましょう!
チュートリアル: 初めての WPF デスクトップ アプリケーション
何かがおかしい
最後までやってみましたか?
ListBoxには何も表示されないですよね?
実はこのチュートリアル間違ってます。
プログラミングコンテストで便利なIntelliJプラグイン CHelperを使う
テストしてないってそれ
プログラミングコンテストで解答が毎回正しいかチェックするためにいちいち実行、サンプル入力、目視確認とか死ぬほど面倒くさいですよね?
僕は面倒臭いです。
でもUnitTest書くのはそれの比にならないくらい面倒くさいですよね?
僕は面倒臭いです。
でもテストしないのはライオンのようなものに襲われる恐怖がありますよね?
みんなあんまりどうやってチェックしてるのか知らないのですごい人を参考にすることにしましょう。
なんか便利そうなの使ってますね。
これがCHelperです。
www.youtube.com
PaizaでJavaはどれだけのタイムがでるか?
Paiza Online Hackason Lite4
マンガ版「エンジニアでも恋がしたい!」〜転職初日にぶつかった女の子が同僚だった件〜|paizaオンラインハッカソン4 Lite
ここでちょっと気になったことがあるのでメモ程度に
検証
case 1で検証します。
問題が非常に単純でアルゴリズムによる差がほぼ出ないことが期待できるためです。
import java.io.BufferedReader; import java.io.InputStreamReader; public class Main { public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int sum = 0; for(int i = 0; i < n; i++){ sum += Integer.parseInt(br.readLine()); } System.out.println(sum); } }
無難にやればこんな感じの回答になるかと思います。
これで提出するとこんな感じ。
マンガ版「エンジニアでも恋がしたい!」〜転職初日にぶつかった女の子が同僚だった件〜|paizaオンラインハッカソン4 Lite
全部0.07sで満点ですね。
これもうこれ以上短くするのは結構厳しいです。
でもそもそもこの0.07sってなんなの?気になりますよね
そこでイカのソースを使います。
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Date; public class Main { public static void main(String[] args) throws Exception { Date start = new Date(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(br.readLine()); int sum = 0; for(int i = 0; i < n; i++){ sum += Integer.parseInt(br.readLine()); } Date end = new Date(); if( (end.getTime() - start.getTime()) <= 1 ) System.out.println(sum); } }
これを実行すれば処理が1msより遅ければ答えが出力されないハードモードになります。
当店甘えは許しておりませんので。
これを実行した結果はこちら
マンガ版「エンジニアでも恋がしたい!」〜転職初日にぶつかった女の子が同僚だった件〜|paizaオンラインハッカソン4 Lite
なんと全部通っています!しかし0.07s変わらず!
これたぶんJVMの起動時間なんかも含まれているんじゃないかなって気がします。
ということでJavaで挑戦する人は0.07sに達していれば十分な速度を出せているといって問題ないかと思います。
ところで
そもそも0.07sでなんで遅いと思ったのかというのこれを見たからです。
※集計結果を詳しく見るを開いてください
天才火消しエンジニア霧島「もしPMおじさんが丸投げを覚えたら」|paizaオンラインハッカソンLite
0.01s早くね?この回答出した人やばくね?って思ったけどそもそもどうやってもこれでなくね?って話
ただしサーバーの混み具合等によって結果が変動することは明記されていますので、
空いてる時間にやればコレくらいの速度は出るものなのかもしれません。
つまりよりいい結果を出すには、空いている時間にいい結果がでるまでサーバーのご機嫌ガチャを回しまくるのが近道なのではないでしょうか。
C# で登録済みDSNを取得する
using (Microsoft.Win32.RegistryKey odbcDriversKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources")) { if (odbcDriversKey != null) { foreach(string dns in odbcDriversKey.GetValueNames()) { // some process } } }



