IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

JavaでjQueryライクにXMLを操作する

github.com

jOOXというライブラリを使えば良さそうです。

嵌ったところは

DOCTYPEがあると読み込んでくれないので、その場合、自分でxmlファイルを読み込む必要がある。

childrenメソッドでセレクタでタグを2個指定するのは動かない模様。(findなら複数指定できる模様)

出力は、xml宣言とかはつけてくれない。なので自分で出力する必要がある。

joox example

Unfoldの使いどころ

haskellのコーディングでfoldrは頻繁に使う印象がありますが。その双対(で、あってるのかな?)のunfoldは、あまり使わない印象があります。というか、使いどころのイメージがつかめませんでした。

この前、n進数間の変換に使えることに気づきました。 が、n進数間の変換にunfoldを使うのは、教科書の定番のようです。教科書をしっかり読むべきでした。

Programming in Haskellの7.9の練習問題6など。

[https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0Haskell-Graham-Hutton/dp/4274067815:title]

実際にやりたかったことは、数値をバイナリにすることだったのですが、

generate :: (Num a, Integral b, B.Bits b) => b -> Maybe (a, b)
generate val =
  if val == 0
    then Nothing
    else Just (fromIntegral $ val B..&. 0xFF, val `B.shift` (-8))

を定義しておくと、

 > :t Data.List.unfoldr generate 0x0efed
Data.List.unfoldr generate 0x0efed :: Num a => [a]
 > Data.List.unfoldr generate 0x0efed
[237,239]
 >
 > :t Data.ByteString.unfoldr generate 0x0efed
Data.ByteString.unfoldr generate 0x0efed :: B8.ByteString
 > Data.ByteString.unfoldr generate 0x0efed
"\237\239"

ができます。

unfolrを使い分けることによって、結果を変えることができます。

Data.BinaryのputとputByteString

ByteStringBinaryクラスのインスタンスになっているので、putputByteStringは同じものかと思ったのですが、差がありました。

Data.Binary

 > runPut $ put $ BSL.pack [0xFF,0xFE,0xFD]
"\NUL\NUL\NUL\NUL\NUL\NUL\NUL\ETX\255\254\253"
 > runPut $ putLazyByteString $ BSL.pack [0xFF,0xFE,0xFD]
"\255\254\253"
 ```

実装を見ると```ByteString```の```Binary```のインスタンスは、バイト列だけでなく、その長さの情報もデコードしています。

Haskellのerrorで嵌る

次のような作りかけのコードを書いていました。errorの部分はあとで修正していくつもりでした。コーディングが進んで、errorの部分をコーディングする段階に来たのですが、show tの内容が出力されませんでした。

paramMetaData2TypeString_ (VAR   tipe len)      =
  case tipe of
    (VARLEN_BYTELEN_TYPE   t) ->
      case t of
        INTNTYPE -> case (lengthTYPE_VARLEN len) of
                        0x01 -> "tinyint"
                        0x02 -> "smallint"
                        0x04 -> "int"
                        0x08 -> "bigint"
        _          -> error  "not yet implemented. type=" ++ (show t)  -- TODO

結局errorの後に$が抜けているだけなのです。

ただ、$がなくてもタイプチェックになってしまうのが落とし穴でした。

 >
 > :t error
error :: [Char] -> a
 > error "foo"
*** Exception: foo
CallStack (from HasCallStack):
  error, called at <interactive>:25:1 in interactive:Ghci2
 > :t error "foo"
error "foo" :: a

> -- $をつけない

 > error "foo" ++ show "bar"
"*** Exception: foo
CallStack (from HasCallStack):
  error, called at <interactive>:27:1 in interactive:Ghci2
 > :t error "foo" ++ show "bar"
error "foo" ++ show "bar" :: [Char]

> -- $をつける

 > error $ "foo" ++ show "bar"
*** Exception: foo"bar"
CallStack (from HasCallStack):
  error, called at <interactive>:32:1 in interactive:Ghci2
 > :t error $ "foo" ++ show "bar"
error $ "foo" ++ show "bar" :: a
 >

Haskellの時間で嵌る

UTCTimeDay`DiffTimeから構成されます。DiffTimeはドキュメントに0 <= t < 86401sの範囲と記載されていますが、範囲以上でも動いてしまうようです。

 > y = secondsToDiffTime 60 * 60 * 24
 > z2 = UTCTime (fromGregorian 2018 11 17) y
 > z2
2018-11-17 23:59:60 UTC
 > y = secondsToDiffTime 60 * 60 * 24 + 1
 > z2 = UTCTime (fromGregorian 2018 11 17) y
 > z2
2018-11-17 23:59:61 UTC
 > y = secondsToDiffTime 60 * 60 * 24 + 100
 > z2 = UTCTime (fromGregorian 2018 11 17) y
 > z2
2018-11-17 23:59:160 UTC

Javaのlambdaやstreamのベストプラクティスは?

ラムダ式のベストプラクティス

Best Practices using Java 8 Lambdas | Baeldung

StreamAPIコーディング規約

coding-standards/Javaコーディング規約.md at 8f152d2a7c6853f14345fbd9f10a9a0b14525e1f · future-architect/coding-standards · GitHub

StreamAPIパフォーマンス注意点

coding-standards/Javaコーディング規約.md at 8f152d2a7c6853f14345fbd9f10a9a0b14525e1f · future-architect/coding-standards · GitHub

The perilously long lambda

Java 8 idioms: Why the perfect lambda expression is just one line

  • その他
    • Streamの処理では、副作用のある処理は書かない
    • Streamの処理ラムダ式は1行(ブロックを必要としない)とする。-> 2行以上(ブロックを必要とする)の時は、関数インターフェースを使う。
    • (ラムダ式内の処理は短い前提のもと)ラムダ式の変数名はx, y, z等の短い文字を使う。
    • ラムダ式は共有しない。使い捨て前提
import java.util.Arrays;

public class Main {

    public static void main(String[] args) {
        String[] list01 = {"a", "b", "c"};

        String[] ret01 = Arrays.stream(list01)
                               .map(Main::addSquareBracket)
                               .toArray(String[]::new);

        Arrays.stream(ret01).forEach(System.out::println); // debug
    }

    private static String addSquareBracket(String s) {
        return "[" + s + "]";  // 複雑な処理のつもり
    }
    
}

SQLServer Management Studioの上位200件の編集で、decimal(38,0)は扱えない模様

直接セルを入力しようとすると20桁までしか受け付けてくれません。38桁の値をSQLで設定した後にみると、<ファイルを読み取れません>となります。

update TBL_DECIMAL set x_decimal_38_0 = 99999999999999999999999999999999999999 where x_id = 13;

f:id:naotoogawa:20181028120911p:plain