2016年6月26日日曜日

yieldについて

MSDNにはyieldを使う例として
        static void Main(string[] args)
        {
            // Display powers of 2 up to the exponent of 8:
            foreach (int i in Power(2, 8))
            {
                Console.Write("{0} ", i);
            }
        }
public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;

        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }
がのっていた。Listなら以下のようになる?

        public static List<int> Power(int number, int exponent)
        {
            int result = 1;
            List<int> rs = new List<int> { };
            for (int i = 0; i < exponent; i++)
            {
                result = result * number;
                rs.Add(result);
            }
            return rs;
        }


2016年6月12日日曜日

レシートからMoneyへの転送補助ツール&CSVのOFX変換

レシートをスキャンして、文字認識データの入ったPDFにして、pdfDoctというフリーソフトでテキストデータを作成し、それをこのソフトで読むと、OFXデータを作成できるので、それをMoneyに読み込ませることができます。(本当は、ソフトの中で、PDFのテキストデータの読み取りをしたかったのですが、うまくいきませんでした。今後の課題です。)
ReadMeドキュメントを作成していませんが、ソースは公開しています。

まとめて、複数レシートをOCRすれば、レシートからの手入力から解放されそうです。
ただし、OCRが完全でないと文字化けもあるので、ところどころ、手で修正はどうしても必要かと思います。また、それぞれの店名毎に、年月日・値段・備考抽出用の正規表現を登録できるようにしています。

https://drive.google.com/file/d/0B4pVdxZ3b8JAMzNGVnRQQnREYVk/view?usp=sharing

上記ソフトへの追加機能として
CSVデータをOFXへ変換するツールも メニューに追加してみた。
マニュアルなしで、しかも操作性を考慮してないので、わかりにくいと思います。
そのうち、改良したいと考えていますが、とりあえず、覚え書き的なものとしてアップしておきます。
銀行によって、CSV形式がまったく違うため、合わせるのに少し手間取りましたが、
Linqをうまく活用すると、少し楽に、わかりやすくプログラミングできるような気がします。
1行の中に、処理の流れをある程度わかりやすくまとめられるところが、すっきりしていいようです。
ただ、ちょっと複雑になると、別に関数を作った方がいいような気もしますが。

2016年6月11日土曜日

カンマのあるデータをCSVに保存

カンマがデータ内にあると、CSVに保存するのがやっかいだ。
いろいろ方法がありそうだけど、とりあえず、保存前にカンマを<C>とか適当な文字に変えて
読み出しで、再度 カンマにもどす方法でやってみた。

strList.Add(dataGridView1[j, i].Value.ToString().Replace(",","<C>"));
で書き込み

string[] rowo =  row.Select(x => x.Replace("<C>", ",")).Cast<string>().ToArray();
dataGridView1.Rows.Add(rowo);
で読み出してみる。CastやToArrayの使い方が、いまいち呑み込めていないので
http://gushwell.ldblog.jp/archives/52048411.html
を参考にさせていただいた。 



2016年6月6日月曜日

Linqを少し使ってみた

プログラミングの効率を上げるには、LINQは なかなか便利な機能だ。

レシートのスキャンデータから、Money用のOFXデータを作成するようなソフトを
作ってみようかと考えている。LINQを少し使ってみた。

○例えば、指定フォルダのファイルをcomboboxに取り込む ためには
 public static IEnumerable<string> SearchDir(string dirPath, string str)
        {
            // 指定フォルダーのファイル列挙
            DirectoryInfo di = new DirectoryInfo(dirPath);
            IEnumerable<System.IO.FileInfo> fiList = di.GetFiles("*.pdf", SearchOption.TopDirectoryOnly);

            return
                fiList
                .Where(fi =>   
                       (0 <= fi.Name.IndexOf(str, StringComparison.CurrentCultureIgnoreCase)))
                .Select(fi => fi.FullName); // フルパスに変換
        }

private void comboBox1_DropDown_1(object sender, EventArgs e)
        {
            comboBox1.Items.Clear();
            foreach (string path in SearchDir(textBox2.Text, ".pdf"))
            {

                comboBox1.Items.Add(path);
            }
        }

○ 複数ページのPDFのレシートからテキストを抽出し、そのテキストデータをページデータに分割する処理は

 textBox1.Text = File.ReadAllText(System.IO.Path.GetDirectoryName(filename)+"\\"+ System.IO.Path.GetFileNameWithoutExtension(filename)+".txt", System.Text.Encoding.GetEncoding("shift_jis"));

            string txtall = textBox1.Text;
            string[] delimiter = { "---------------------------------- Page" };
            receipt = txtall.Split(delimiter , StringSplitOptions.None);

             shpName=receipt.Select(rc => shop_c(rc)).ToArray();
            string[] idx = receipt.Select(rc => rc.Substring(0, 5)).ToArray();            

            comboBox2.Items.AddRange(idx);

  private string shop_c(string txt)
        {
            string[] shopd = listBox1.Items.Cast<string>().ToArray();//あらかじめ登録してある店名のデータがレシートの中にあれば、店名を出力
            string sst="";
            foreach (string st in shopd)
            {
                if (txt.IndexOf(st) >= 0)
                {
                    sst= st;
                   
                }
            }
            return sst;
        }

Ipv6を使ったVPNその後

 SoftetherVPNをraspberryPiで使っていたが、ある日突然、使えなくなる。プロバイダに問い合わせても、なかなか原因がわからず、ルータも最新のものに変更するも、うまくいかない。
 とうやら、片方がNGNの閉域網で、片方がオープンなIpv6であることが原因ということが、だいぶたってから判明する。こちらとしては、なんとなく、そんな気がしていたが、メールや電話でのやりとりでプロバイダに理解してもらうまで時間がかかる。Ipv6を使うユーザーは、まだ少ないのでやむをえないのかもしれない。
 結局、http://www.ntt-west.co.jp/kochi/info/tejun_PR-400NE.pdf
というリンクを参照するように、言われこの通り設定をしたら、もとのNGNの閉域網にもどることができた。遅延時間が少ないこと、セキュリティ的にも閉域網だから少しは安心であることなど、メリットもあるようだ。将来的には、オープンなIpv6に移行していくんだろうけれど。

softetherをしばらくぶりで動かすと、ブリッジがうまく動作しなかった。物理NICとうまく接続できないというメッセージが出る。イーサネットのプロパティを見ると、「SoftEther Lightweight Network Protocol」という項目のチェックが外れていたので、チェックを入れてみたら、うまく動作した。

2016年6月5日日曜日

itextsharpを試してみる

PDFからテキストデータの抽出を試してみる。
ネット上の情報によると

 var filename = comboBox1.Text;
            var text = new StringBuilder();

            using (var pdfReader = new PdfReader(filename))
            {
                var strategy = new SimpleTextExtractionStrategy();            

                for (int pageNum = 1; pageNum <= pdfReader.NumberOfPages; pageNum++)
                {
                    // 1ページまるごとテキスト化      
                    var lines = PdfTextExtractor.GetTextFromPage(pdfReader, pageNum,strategy);
                    text.Append(pageNum.ToString()+"::::::::::::::::::::"+lines+"\r\n");
   
                }
 
            }
            textBox1.Text = text.ToString();

}

という具合になっているが、これで実行すると、どうしても、ページの内容が累積していってしまい。
なぜかよくわからないけれど、試しに、
PdfTextExtractor.GetTextFromPage(pdfReader, pageNum,strategy);のstrategyを削除して
PdfTextExtractor.GetTextFromPage(pdfReader, pageNum);としたら
うまくいった。ストラテジーは不要のようだ。

MZK-MF300Nをコンバータモードにしてみた(覚え書き)

MZK-MF300Nをコンバータモードにしてみた。
・親機がMACアドレス制限をかけているので、親機にMACアドレスを登録
・LANの設定では、DHCPを最初自動にしたが、うまくいかずクライアントのモードにしてみた。
・無線モードはB+G+Nとした
あとは、暗号化の設定を親機に合わせると、接続できるようになった。