RSS

日々のメモ書き

Debian Developerが綴るメモ

Haskellでエンコード周辺

SJISのファイルを扱うのに苦労した。適当にやるとinvalite byte sequenceとエラー吐かれて終了。きちんと変換しないといけない。

import Codec.Text.IConv
import Data.ByteString.Lazy.Char8 (pack, unpack)
import qualified Data.ByteString.Lazy.Char8 as BS
import Codec.Binary.UTF8.String

inFile = "z_sjis.txt"

main = do 
  cs <- BS.readFile inFile
  let u8s = convert "CP932" "UTF-8" cs
  -- OK
  BS.putStr u8s 
  putStr $ decodeString (unpack  u8s) 
  -- NG
  putStr (unpack  u8s)
  putStr (unpack (convert "UTF-8" "ISO-2022-JP" u8s))  
  putStr (unpack (convert "UTF-8" "EUC-JP" u8s))
  putStr (unpack (convert "UTF-8" "CP932" u8s))

z_sjis.txtをShift JISで作成する。どういう理屈かいまいちわかってないがdecodeStringもかけないといけないらしい。ターミナルで吐かせているだけだとなんとなく読めるようになったりするのできちんと検証が必要。以下のようにして数値にして確認した。

$ runghc ex_iconv.hs |perl -n -e '@s=unpack("C*", $_);print "[@s]\n"'

haskell でCSVファイル

ほんとはcsv-conduitでやりたがったが挙動不審のため取り止め。1行目に1カラムしかないと2行目以降も1カラムしか読まないとかいまいちよくわからん動作をする。ヘッダ行だけ特別な取扱をするのかどうかとも思ったが解読できず。

かわりにtext.CSVを使った。

import Text.CSV

inFile = "z_in.csv"
outFile = "z_out.csv"

main = do 
  s <- parseCSVFromFile inFile
  putStrLn $ either show printCSV s
  putStrLn $ either (\x->"") (show . (map length)) s

parseCSVFromFileで IO(Either parseError CSV)が返ってくる。CSVはStringのリストのリストになっている。

オーストラリア戦

多分いろいろあるのだろうが最後のFKの笛でなにもかもがわからなくなった、みたいな投げ遣りなことを言うのはどうかと思うが基準がさっぱりわからない主審だったのは間違いない。

イラクとオマーンが引き分けた結果、日本が独走ってなんだこのアホグループは。

引き続きサッカー

ポーランド(1-1)ギリシャ。EURO2012開幕戦。間延びしたラインでスペースめがけて蹴り込むかドリブル突破だけじゃねーか。ヨーロッパ中堅国より日本のほうが間違いなく上。

カタール(1-4)韓国。韓国は昔のアジア専用のサッカーに戻ったどうでもいいチームになっていた。カタールはもっとひどい。WC返上しろよ。

ヨルダン戦

6-0で勝ってもまだ文句のつける余地があるとは贅沢になったもんだ。はっはっは。

オーストラリアにも勝ってさっさと決めてしまおう。

logwatchの追加設定

logのレポートツールに独自の監視設定を追加した。btrfsがときどきcheck sumエラーを吐くのでその検出のため。

/etc/logwatch/conf/services/btrfs.conf を追加。どのログを監視するかの設定

Titles = "BtrFS"

LogFile = messages

*OnlyService = kernel:
*RemoveHeaders

/etc/logwatch/scripts/services/btrfs にログの処理スクリプトを書く。

#!/usr/bin/perl


while (defined($ThisLine = )){
        print $ThisLine if $ThisLine =~ /btrfs .* csum/;
}
exit(0);

StateTを使う(応用編)

こんな感じでユーザーの入力で足し算をするプログラムを書いてみた。StateTを使ってIOを処理している。

import Control.Monad.State
import Control.Exception
import Prelude hiding (catch)
import System.IO

count :: StateT Int IO ()
count = do 
  n <- get
  l <- liftIO $ do
    putStrLn $ "Total =  " ++ (show n)
    putStr $ "Input integer or 'q' >> "
    hFlush stdout
    getLine
  if l == "q" then
    return ()
    else do
    num <- liftIO $ (readIO l) `catch` 
                     (\e -> return (e::SomeException) >> 
                            putStrLn "parse error" >> return 0)
                            
    modify (+num)
    count

main = do
  s <- execStateT count 0
  putStrLn $ "Final total = " ++ (show s)

Stateモナドを使う

こんな感じで。

import Control.Monad.State

--count :: State Int String
count :: State Int ()
count = do 
  n <- get
  put (n+1)
  return ()

countP :: StateT Int IO ()
countP = do 
  n <- get
  liftIO $ putStrLn $ "0: " ++ (show n)
  put (n+1)
  n <- get 
  liftIO $ putStrLn $ "1: " ++ (show n)
  return ()

main = do
  print $ runState count 1
  putStrLn "---"
  print $ evalState count 1
  putStrLn "---"
  print $ execState count 1
  putStrLn "---"
  print $ runState count (execState count 2)
  putStrLn "---"
  print $ runState (sequence [count,count]) 1
  putStrLn "---"
  runStateT countP 1
  putStrLn "---"
  runStateT (sequence [countP, countP]) 10
  return ()

出力結果。

((),2)
---
()
---
2
---
((),4)
---
([(),()],3)
---
0: 1
1: 2
---
0: 10
1: 11
0: 11
1: 12

Haskellでパスワード生成

まあSystem.Entropyを使って乱数の初期化をしてみたかったというだけなんだが…。ほんとにこれが真に安全な初期化なのかどうかはわからない。

乱数列からパスワードを生成する処理も気に食わない。

{-# LANGUAGE DeriveDataTypeable #-}

import Crypto.Random
import System.Entropy
import System.Random
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import Data.Word
import Data.List.Split
import System.Console.CmdArgs


pass_str_l = ['a'..'z']
pass_str_u = ['A'..'Z']
pass_str_n = ['0'..'9']
pass_str = BS8.pack (pass_str_l ++ pass_str_u ++ pass_str_n)

data Opts = Opts {
  opt_length :: Int, 
  opt_number  :: Int
  } deriving (Show, Data, Typeable)
  

opts = Opts {
  opt_length   = 8
                 &= explicit 
                 &= name "length" 
                 &= help "password length"
  , opt_number  = 10
                 &= explicit 
                 &= name "number" 
                 &= help "number of password" 
  } &= summary "Hoge foo bar"
     
main = do
  args <- cmdArgs opts
  entropy <- getEntropy 16
  let rs = randomRs (0, (BS8.length pass_str - 1)) (mkStdGen (bs2int entropy))
  mapM_ putStrLn (splitEvery (opt_length args)
            (map (\x -> BS8.index pass_str x) 
             (take ((opt_length args) * (opt_number args)) rs)))
  where 
    bs2int bs = BS.foldl shift8 0 bs
    shift8 i w8 = i * (2^8) + (fromIntegral (toInteger w8))
      

エジプト戦

一人で3失点を演出した山村さんマジパネェっす。ボランチは本職じゃないという言い訳があったようだがCBでも使い物にならんということがはっきりした。なんだあの軽いチェックとよくわからんポジショニングは。解説の福西さんは名指しで批判したかけていたのを抑えてしゃべってたな。

SBの高徳も良いとは言えない出来だった。大岩のほうは論外だが。鈴木も褒めないけど。DFラインだけがいまだに難しい。なんとかならんのか。

ところでエジプトが登録してない選手を使った件はどうなったんだ?ほんとうなら日本の勝ちになるんじゃないのか?

< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 >