2016年11月18日金曜日

LPICの学習

 LPICの資格というのがある。ただ、検定料が高く、101から順に受けないといけないらしい。LPICのテキストはLinuxを使うためにはとても役に立つ。試験は受けないけれど、テキストで学習するだけで、十分役立つかなと思っている。
 早速、インストールのためのスクリプト作成で、役に立った。

(1)プロキシーの設定スクリプトをこんなふうに考えてみた
rm /etc/apt/apt.conf
echo -n "0:No proxy 1:proxy(NoAuth) 2:proxy(Auth):"
read yn
if [ $yn = "0" ]; then
 :
else
  cp apt_skt.conf /etc/apt/apt.conf
  echo -n "input ip-address & port for proxy(e.g.  172.*.*.*:port):"
  read iport
  sed -i -e "s/userpass@ipport/$iport/g" /etc/apt/apt.conf
    if [ $yn = "2" ]; then
          echo -n "input userID & password for proxy(e.g. user:pass):"
          read pwd
          sed -i -e "s/$iport/$pwd@$iport/g" /etc/apt/apt.conf
    fi
fi


(2)インストール失敗したら、再インストールするためのスクリプトを考えてみた
apt-get install samba mysql-server tomcat7
をUbuntu12.04でスクリプトで実行しようとしたけれど、どうもうまくいかない。14.04ではうまくいくようだけど、依存ライブラリが古いためいろいろひっかかるのかもしれない。数回繰り返すとなんとかなるようなので、
apt-get update --fix-missing
#*************reInstall*********
spath='/etc/samba'
tpath='/var/lib/tomcat7'
mpath='/etc/mysql'

while :
do
    if [ ! -d $spath ]; then
     apt-get install -y --fix-missing samba
    else
            break
    fi
done


while :
do
    if [ ! -d $tpath ]; then
     apt-get install -y --fix-missing tomcat7           
    else
         break
    fi
done

while :
do
    if [ ! -d $mpath ]; then
      apt-get install -y --fix-missing mysql-server
     else
      break
    fi
done

************
これでうまくいくと思ったが、なぜか、sambaがうまくインストールできない。
ディレクトリの有無でインストールのチェックというのはだめなようなので、プロセスをチェックするようにしてみた。
これで試してみようと思う。
while :
do
   sc=$(ps -e | grep 'samba' | wc -l)
    if [ $sc = "0" ]; then
     apt-get install -y --fix-missing samba
    else
            break
    fi
done

結果。。。なぜか、うまくいきませんでした。
原因を考えていますが、今のところ不明
こんなやり方は 邪道なのだろうか。。
スクリプトって、同期的に動いているのか 非同期なのか、そのへんも
関係しているんだろうか

素直に ひとつひとつ apt-get installするしかないようだ




2016年10月25日火曜日

指定したフォルダ以下のJPG画像データを一括して圧縮し、上書きするツール

共有フォルダに、必要以上に大きいサイズのJPGファイルが増えて、困っているとき、JPGを指定したサイズに圧縮できると便利です。

画像の一括圧縮は、以前は、Vixというツールで手動でやっていた作業です。
http://myutaro.blogspot.jp/2016/04/blog-post_20.html

これだと、その都度、設定が必要で、毎日、自動で行うことは難しいので、自作ツールを作ってみました。
毎日、タイムスケジューラで、起動して、少しずつ処理をすすめるソフトを作ってみました。

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

Imagemagickのmogrify.exeというコマンドツール(GPL)を、ツールの中で利用させてもらっています。

一度に、いくつのフォルダを処理するか、横幅サイズの指定、どのフォルダ以下に指定するか
などを設定として保存できるようにしています。

2016年8月16日火曜日

VisualStudioでGit(覚書)

しばらくぶりに、VisualStudioでGitを使おうとしたら、やり方を忘れてしまっていた。
試行錯誤の結果、なんとかできるようになる。

また、同じ苦労をしないように、覚書を作成してみた。

新規作成するための手順
Web Browserでの設定
1 MS社のTeamServiceにアカウントを登録
2 Account Settings(右上に歯車のアイコン)をクリック
3 Overviewのタブで New team procectをクリックして、プロジェクト名を入力
  gitを選択しておく
VisualStudioでの設定(VS2013の場合)
1 チームエクスプローラーのウインドウを表示する設定にする
2 チームエクスプローラーの「チームプロジェクトへの接続」(コンセントプラグの絵)をクリック>
チームプロジェクトの選択...をクリック>サーバを選択(未登録なら追加、URLはTeamFoundationServerのURLを指定)>チームプロジェクトで必要なプロジェクト名にチェック入れる
3 チームエクスプローラーの「ホーム」(家のアイコン)をクリック>「ソリューション」で、新規作成..をクリック>ここで、作成するプロジェクト名やフォルダ名は先ほどのプロジェクト名と一致させておくとわかりやすい。
※ここで、2の後に、3で新規作成するのが一番スムーズのようです。すでにあるプロジェクトを使いたいときも、いったん、新規作成してから、あとで、使いたいプロジェクトの必要ファイル(すでにできているgitファイルなどは上書きしないように注意)をRepos
フォルダの中の該当プロジェクトに上書きしたほうが、確実のようです。もう少しスマートな方法がありそうですが、、、、。

以後、PushやFetchをしたいとき
 ソースに変更があったら>「プロジェクト」で、「変更」をクリック>コミットメッセージを入力>「コミット」してからPush
 リモートに変更があればFetchしてから、ソースを変更という感じで使っています。

2016年7月21日木曜日

Asus T90chiを起動時に無線Lanに自動接続するバッチファイルの作り方

SSIDが隠蔽されているためか、うまく、再起動時にWIFIに接続できない不具合?(仕様?)があるようなので、自動接続するバッチファイルをいれたところ、うまく動作しましたので、覚書としてアップしました。

1 すべてのプロファイルを書き出します。
netsh wlan export profile folder=保存先

"WiFi-abc.xml"のようなファイルが保存されます。


2 バッチファイルを作成 wconnect.batを次のように作成します。
netsh wlan add profile filename="c:\指定フォルダ\WiFi-abc.xml" user=all
netsh wlan set profileparameter name=abc keyMaterial=キー nonBroadcast=yes
netsh wlan connect name=abc

nonBroadcast=yesを指定しないと、SSIDが隠蔽されている場合はうまくきませんでした。

3 スタートアップにwconnect.batのショートカットを置いておきます
起動時にバッチファイルを起動し、abcに接続します。


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とした
あとは、暗号化の設定を親機に合わせると、接続できるようになった。

2016年5月29日日曜日

VPN接続で、WEBの速度低下

 VPN接続で、離れたところのLocalLanに接続してみている。なぜか、WEBの速度が遅くなる。セグメントも変えてみた。それでも遅い。
 ひょっとして、ゲートウエイが2か所設定されているから?試しに、VPNの「リモートネットワークでディフォルトゲートウエイを使う」にチェックが入っていたのをはずしたら、速くなったようだ。2つのゲートウエイにパケットを送っていたため遅かったということだろうか。

2016年5月27日金曜日

WIFIの設定も、なかなか大変、特に中継器など入ると複雑

複数のAPと中継器の設定の機会があったが、予想以上に時間がかかってしまった。
およそ、以下の手順で行うといいようだ。
①機器付属のマニュアルにしたがって、APモードにして、クリップの先などでリセットかける
②機器付属のマニュアルにしたがって、できればクロスLANケーブルで1対1でつなぎ、指定したURLにアクセス(http://192.168.云々というアドレスが多い)。やむを得ないときはWIFIでつないで設定する(中継器等)
 このとき、つなげるPCのipアドレスをいったん192.168.云々に合わせる必要がある。
 例 APが192.168.11.100なら 192.168.11.101等とし、ネットマスクは255.255.255.0でよい。設定が固定Ipアドレスになっていたら、変更前の値をメモしてあとで、もどす必要がある。
③指定したアカウント、パスワードでログイン
④ネットワークでなんらかの制限がかかっていることがあるので、管理者に連絡する必要も出てくることがある。
⑤クライアントPCのMACアドレスを調べる 
⑥クライアントPCのMACアドレスを登録
⑦暗号等の制限かけない状態で、接続できるか確かめてから、少しずつ制限かけていくと、やりやすい。
⑧うまく接続できそうであれば、暗号化 WPA2-PSK AES を行う。 暗号化キーはできれば統一する。 
⑨⑧の統一とともに、SSIDも統一すると、ローミングができてよい。
⑩SSIDの隠蔽を行う(Any接続なしに) この後は 手入力でSSIDを入力する必要が出てくる。
⑪最後に、MACアドレス制限をかける。
⑫APのIpアドレスを、ネット環境に合わせて設定しなおす。
 ②の設定をもとにもどして、APに変更したURLでアクセスできるか確認。
※MACアドレス制限をかける場合、中継器のMACアドレスを親機に登録必要だが、若干の変換が必要だった(これは仕様?)

sambaで特定のユーザでの読み書き

http://www.atmarkit.co.jp/flinux/rensai/linuxtips/184sambaspuser.html
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/183sambauniuser.html
これらのリンクを参考にさせていただいた。

特定のフォルダで、書き込めないといったトラブルが起きるので
force userを使って、読み書きのユーザをひとつに決めてみた。
これで少し様子をみてみたい。

2016年5月22日日曜日

WN-G54/R4とMZK-MF300Nをローミング可能に

 WIFIのアクセスポイントにローミングという便利な機能があるとは知らず、今まで、APが切り替わったら、その都度、SSIDをクリックしたりして接続していた。
 SSIDや、暗号化の設定を同じにするとローミングができるということを知り、試してみた。メーカーが異なっていても、ちょっと古い機種でもOkのようだ。
 タブレットなど、移動しても、途切れることなくそのまま使えるので便利だ。
***********
 ただ、WN-G54/R4という機種は、ネットで見るとわかるように、いろいろと設定しずらい機種のようだ。いったん、この機械をルータにつないで、リセットかけることで、オートブリッジモードになるらしい。いったん、はずして、ローカルのポートからこの機械の設定画面を見るよいようだ。
 最初、WN-G54/R4のグローバル側のポートを上流のローカル(ルータの)のLANポートにつないでいる。すると、WN-G54/R4のIpアドレスは、違うネットワークアドレスになってしまう。グローバル側とローカル側は必ず違うセグメントにしなければならないので、当然なのだけれど、しばらくこれに気づかずにいる。WN-G54/R4のローカル側のポートを上流のローカル(ルータの)のLANポートにつなぐことで、無事、同じセグメントで、管理できるようになった。

2016年5月21日土曜日

アプリケーションの削除にはgeekが便利

Windowsのコントロールパネルにあるプログラムのアンインストールではうまく削除できない場合がたまにある。そういうときは、geekというソフトがいいようだ。おそらく、レジストリと実際のファイルの状態が一致しないと標準のアンインストール機能がうまくいかないのだろうと予想される。

2016年5月18日水曜日

vs.net2013をプロキシー認証で使う

vs2013をインストールしたが、プロキシー認証が必要な環境のため、苦労する。
https://blogs.msdn.microsoft.com/rido/2010/05/06/how-to-connect-to-tfs-through-authenticated-web-proxy/
このリンクが参考になりました。

using System;
using System.Net; 
namespace Rido.AuthProxy
{
    public class AuthProxyModule : IWebProxy
    { 
        ICredentials crendential = new NetworkCredential("proxy.user", "password"); 
        public ICredentials Credentials
        {
            get
            {
                return crendential;
            }
            set
            {
                crendential = value;
            }
        }

        public Uri GetProxy(Uri destination)
        {
            return new Uri("http://proxy:8080", UriKind.Absolute);
        }

        public bool IsBypassed(Uri host)
        {
            return host.IsLoopback;
        } 
    }
}
"proxy.user", "password"とhttp://proxy:8080"を環境に合わせて書きかえて、コンパイル
すればOkでした。(C#でdllファイルを作成)
そしてそのRido.AuthProxy.dllファイルを、%PROGRAMFILES\Microsoft Visual Studio 10.0\Common7\IDEのフォルダにそれを置いて、そのフォルダにあるdevenv.exe.config というファイルの中に以下のように追加します。
<system.net>
    <defaultProxy>
      <module type="Rido.AuthProxy.AuthProxyModule, Rido.AuthProxy"/>
    </defaultProxy>
  </system.net>

これで、解決しました。プロキシー認証ぐらい、IDEでできるようにしてほしいものですが。。。

2016年5月14日土曜日

ルータの設定ではまる

 某メーカのルータを標準のセグメントから変更して使っていたが、これまで、DHCPサーバ機能はOFFとしていた。たまたま、使う状況になったものの、なんとしても設定ができない。
 試しに、標準のセグメント192.168.11.0/24にしてやったら、すんなり設定できた。こういうこともあるのんだと、新たな発見。ちょっとしたバグ?でしょうか。

2016年5月4日水曜日

vmware ブリッジで接続

 Vmware のネットワーク接続には、NAT、ホストオンリー、ブリッジといった方法がありますが、これまでブリッジについてはなかなかうまくいきませんでした。
 原因は、ホスト側のアダプタの設定にあったようです。
 http://ameblo.jp/toomohiko/theme-10085331061.html を参考にさせていただき解決しました。
 物理NICの設定(プロパティ)で、VMware Bridge Protoclというのが入っていなかったことがうまくいかない原因でした。ネットワークのタブで、インストール...のボタンをクリックして、このプロトコルを探して追加したらうまくいきました。
 仮想サーバ(ゲスト)のIpアドレスを指定して、ファイアーウオールの必要なポートを開けてやると、PCの外からも仮想サーバ(ゲスト)にアクセスできるようになりました。NATの場合と違うのは、外からもアクセスできること、また、同じセグメントになっていることです。

 使い道としては、違うOSでのサーバの構築テストがあげられます。また、OSやハードが変わると、ソフトの更新も迫られる場合がよくありますが、仮想化して丸ごと保存しておいて、ブリッジ接続すれば、いつまでも、古いソフトをサーバーで使っていくことも可能かもしれません。

2016年4月28日木曜日

WIndows10に何としてもNETFramework3.5がインストールできない現象

 古いバージョンの.NETソフトは、3.5でないと動かなかったりするようだが、windows10には、この3.5が標準では入ってないようで、インストールを求められ、続行を求められるものの、途中でエラーで停止してしまう現象が起きた。
 おそらく、ファイアウオールかプロキシーか、ネットワーク途中の何かかが影響しているのだろうが、ネット検索なども行いながら、原因究明にだいぶ時間を費やしてしまう。古いバージョンのソフトが皆使えないとなると非常に困るからだ。
 結局、ネット上にある情報でいろいろやってみたが、うまくいかず。対処療法になるけれど、NetFrameWork3.5のオンライン版でなく、フルセット版をダウンロードしてなんとかうまくいった。
 このへんは細かいところだけれど、以前のMS社だったら、こういう細かいところまで対処してくれていたような気がする。システムが複雑になったせいもあるのかもしれないが、複雑さへの対応が追いついてない気がする。こういうところにこそ、AI(機械学習)など適用して欲しい。(ビッグーデータが揃わないと無理?まれなエラーは、なかなかビッグデータとは成り得ないか。。。)
*******************
 その後、やはり、NetFramework3.5がインストールできないものがある。WinodowsUpdateもしっかり行わないとだめだという情報もあるので、アップデートしてみる。ところが、できない。
 MS社で、win10用のアップデート修正ツールが出てたので試したら、不具合が解消した。アップデートの修正が必要というのも、ややこしい話です。windows10も、出始めなのでいろいろ不具合がありそうです。

2016年4月23日土曜日

Javascriptでクロージャ

PythonによるWebスクレイピング P154を読んでいたら こんなjavascriptのスクリプトが出てきた。

<script>
var fibonacci=function(){
 var a=1;
 var b=1
 return function(){
  var temp=b;
  b=a+b;
  a=temp;
  return b;
 }
}

var fibInstance=fibonacci();
console.log(fibInstance()+" is in the Fibonacci sequence");
console.log(fibInstance()+" is in the Fibonacci sequence");
console.log(fibInstance()+" is in the Fibonacci sequence");
console.log(fibInstance()+" is in the Fibonacci sequence");
console.log(fibInstance()+" is in the Fibonacci sequence");
</script>


○ 参考までに、プログラミングF# P55にクロージャの例としてこういうのがのっていた。
>let gereratePowerOfFunc baseValue=(fun exponent -> baseValue ** exponent);;
>let powerOfTwo=generatePowerOfFunc 2.0;;
>powerOfTwo 8.0;;
 val it:float =256.0
2.0がどこに保持されているか。。値がスコープ内にあれば、その値を使用でき、またその値も関数によって返されることがある。

P209では、クロージャとは、内部あるいはネストされた関数において、関数に引数を明示的に指定せずとも何らかの値にアクセスできることを表す用語です。...
 >let mult i lst=List.map(fun x->x*i) lst;;
    val mult: int -> int list -> int list
  >mult 10 [1;3;5;7];;
    val it:int list=[10;30;50;70]



 

2016年4月20日水曜日

サブフォルダ含め、画像を一括して縮小し、上書き保存する方法

 共有フォルダデータをバックアップしているが、写真のサイズが大きくなっているため、ハードディスクが満杯になり、そろそろ限界に達している。バックアップ用のハードディスクにあまりお金もかけてられないので、バックアップデータのみ、写真サイズを縮小しようかと考えている。その方法をまとめてみた。

Vixというフリーソフトを用意します。Vectorなどで以前から出ているソフトです。
①処理したい共有フォルダを指定する。
②該当フォルダ以下のサブフォルダも指定するには、
  メニュー>画像>統合変換>出力のタブで、 「変換先対象フォルダ」の「サブフォルダも対象」にチェックを入れます。
③同じ場所に、縮小した写真をリサイズしたいなら、②の出力のタブで、「出力先」で「画像と同じフォルダ」を選択します。
④写真はほぼJPEGだと思われますので、メニュー>画像>統合変換>フォーマットのタブで、「種類」のところはJPEGを選択します。
⑤サイズの指定は、メニュー>画像>統合変換>リサイズのところで、「リサイズを行う」にチェックを入れます。そして、「横幅指定」にチェックを入れて、サイズを指定してください。「800」~「1000」程度でも、Webとか、ちょっとした原稿で利用するには十分でないかと思います。

2016年4月18日月曜日

PythonによるWebスクレイピング

Pythonの実践的プログラミングがとても参考になる本だ。
Nグラムについての説明があった。

2グラムで、何回出現したか カウントするプログラム P116を参考にちょっと試してみた。
input=['abc','test','abc','test','hello','xyz','hello','xyz']
output=dict()
for i in range(len(input)-2+1):
  newNGram = " ".join(input[i:i+2])
  if newNGram in output:
    output[newNGram] += 1
  else:
    output[newNGram] = 1

これを実行すると
outputは {'hello xyz':2 ,'test abc':1 ,'abc test':2,'test hello':1,'xyz hello':1}
という具合になった。
" ".join(input[i:i+2])は、inputから抽出した2語をスペースでつなぐようだ。

2016年4月5日火曜日

Windowsサーバでアクセス制限をバッチファイルで一括処理 Part2

 echo y | cacls d:\test /t /e /g username:f
といった感じのコマンドをエクセルで編集し、txt保存し、拡張子をbatに変えることで
たくさんの処理を一括でやってみた。

いろいろ調べると、さまざまなことができるようだ。
http://www.atmarkit.co.jp/ait/articles/0603/04/news013.html
などを参考にさせていただく。

①/g アクセス権(RやWなど)のみの追加(すべて置換は/p F指定なら/pでもOKか?)
②/e 既存のACLの内容はそのままで、ACLの追加、編集(つけないと、すべて破棄され、それまで設定されたユーザーの設定が消える。/gや/pで指定したACLのみとなる)

③/t フォルダ階層を再帰的にスキャンする
④アクセス制限を削除するには/r usernameと/eを使用する(/eがないとエラーらしい)。
echo y | cacls * /t /e /r username
これで、usernameeへのACLエントリをすべて削除

たとえば、一番上の階層のみ勝手にフォルダやファイルを作成できないようにするためには
たぶん /tをはずし /gでなく /pとして
 echo y | cacls d:\test /e /p username:r
となる。ただ、削除はできるようだ。

******************
 削除とファイルやフォルダの作成禁止にするにはどうするか、Windowsの場合、いろいろ調べたもののこれはという方法が見つからない。意外に簡単な方法があるのかもしれないが。(実際、Linuxなどはchmodを使えばすぐできるのだが、、、)
 苦し紛れに以下のような方法でやってみた。

 testフォルダ以下の全員のフォルダやファイル削除禁止
  icacls e:\test\* /deny everyone:(DE)

  testフォルダ以下への全員のフォルダやファイル作成禁止
 icacls e:\test /deny everyone:(WD)
 icacls e:\test /deny everyone:(AD)

なお、解除するには
 icacls e:\test /remove everyone
 icacls e:\test\* /remove everyone


2016年3月26日土曜日

.NETからPythonを使う

.NETとpythonの連携についての記事があった。この方法だと、確かにコンパイルしなおさなくても、簡単に、ソフトの動作を細かく調整できて、便利かもしれない。
https://codezine.jp/article/detail/2187?p=2

http://ironpython.codeplex.com/releases/view/5141から.dllファイルを持ってきて、参照に追加するだけで、動作するので、設定も簡単だ。

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim pe As PythonEngine = New PythonEngine()
        pe.Globals.Add("MyButton", Me.Button1)
        pe.ExecuteFile("1st.py")
    End Sub

1.pyは
# coding: utf-8
#最初の例(MyButtonをGlobalで共有)
MyButton.Text = "スクリプトを実行"
のような感じでいいようだ。

Postfixとmailutilsでメール送信

Vmware上で、メール送信を試してみた。HDD残量が少なくなったとき、メールで知らせたりいろいろ応用がきく。

Postfixとmailutilsをインストールし、/etc/postfix/main.cfにいろいろ設定を追加する。

メールサーバの設定に合わせて変更が必要である。
mydestinationに、自分の利用しているメールサーバを追加する。
mynetworksに自分のローカルネットワークを追加
smtp_user_tlsは自分の環境ではコメントアウトしていいようだ。

relayhost=[自分のメールサーバアドレス]:587  通常のISPはこの形
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/isp_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain,login,digest-md5,cram-md5

[mail.asahi-net.or.jp]:587 mailユーザ名:パスワード というファイルを/etc/postfix/isp_passwdにおき
# postmap /etc/postfix/isp_passwd
とするとハッシュ化されるらしい
service postfix restart

メール送信は
mail dist@abc.jp -aFrom:myname@abc.jp
でOkでした。
送信者名を指定しないとroot@abc.jpという形になってしまうようです。


以下のリンクを参照させていただきました
http://d.hatena.ne.jp/shibainu55/20100620/1277904550
http://askubuntu.com/questions/405058/postfix-start-error-port-25-address-already-in-use

2016年3月24日木曜日

HerokuでPythonを少し動かしてみた

Herokuでは、Ruby,scala、java、pythonなど主要な言語をクラウドで使える。今回は、最近学び始めたばかりのPythonをちょっとばかりためしてみた。

Edit hello/views.py. At the beginning, add a line to import the os module:
import os
Now modify the index method so that it repeats an action depending on the value of the TIMES environment variable:
def index(request):
    times = int(os.environ.get('TIMES',3))
    return HttpResponse('Hello! ' * times)
heroku local will automatically set up the environment based on the contents of the .env file in your local directory. Edit the .env file to add:
TIMES=2

 これはconfig varの説明のところ。うまく動作せず、いろいろ試行錯誤してみた。
エラーメッセージを見たらインデントがどうのこうのと英語で書いてあった。
pythonはインデントが重要であることを忘れていた。インデントをそろえたらうまく動作した。

 要するに、ローカルに.envというファイルを作成してTIMES=2としておけば、これを読むようだ。
もしこのファイルがなければディフォルトで3を読む。(os.environ.get('TIMES',3)の3はそういう意味のようだ。)
 こういったちょっとしたことも、検索しても出てこない。慣れてない言語は手間取る。Pythonはグローバルスタンダートなのに、日本語の情報が少ないのが気になる。でも、わりと覚えやすく使いやすい言語といえるかもしれない。scalaやHaskelほどではないが、ほどほどに関数型としても使えるようだ。

2016年2月14日日曜日

非同期ワークフロー パラレル計算 F#

http://d.hatena.ne.jp/rhasumi/20101209/p1のサイトを参照させてもらいました。

試しに、1000000回で実行時間を比べたら、ノンパラレルでないほうが速かったようなので
10000000回に一桁回数を増やしたところ、パラレルのほうが速くなりました。
シミュレーションの計算などで活用すると便利なようです。

let Runif seed n =
  let r = new System.Random(seed)
  let ans:float[] = Array.zeroCreate n
  for i in 0..(n-1) do
    ans.[i] <- r.NextDouble()
  ans

let Parallel' n =
    let r = new System.Random()
    [for x in 1..2 -> async { return Runif (r.Next ()) n }]
    |> Async.Parallel
    |> Async.RunSynchronously

let nonParallel' n =
    let r = new System.Random()
    [for x in 1..2 -> Runif (r.Next ()) n ]



[<EntryPoint>]
let main argv =
    let sw = System.Diagnostics.Stopwatch()
    sw.Start()
    let rs=[nonParallel' 10000000]
    sw.Stop()
    System.Console.WriteLine("nonParrallel Time elapsed: {0}", sw.Elapsed)
    sw.Reset()

    sw.Start()
    let rs=[Parallel' 10000000]
    sw.Stop()
    System.Console.WriteLine("Parrallel Time elapsed: {0}", sw.Elapsed)
    sw.Reset()

    System.Console.ReadKey() |> ignore
    0 // 整数の終了コードを返します

F#の非同期ワークフロー

http://fsharp.web.fc2.com/#非同期ワークフロー
を参考にさせていただいた。

 [<EntryPoint>]
let main args =
     let task1 = async { while true do printf "a" }
     let task2 = async { while true do printf "b" }  
     Async.RunSynchronously (Async.Parallel [task2]) ①
     Async.Start  task1 ②
     0
これだと、bしか表示されない。つまり、①が終わらない限り、②は実行されない。

①と②を逆にすると
 [<EntryPoint>]
let main args =
     let task1 = async { while true do printf "a" }
     let task2 = async { while true do printf "b" }  
     Async.Start  task1 ②
     Async.RunSynchronously (Async.Parallel [task2]) ①
     0
これだと、bとaが交互に表示される。つまり、②が終わらなくても、①が実行される。
以前はStartはSpawn、RunSynchronouslyはRunだった?ようです。

2016年2月13日土曜日

C#とF#の連携2

http://www.infoq.com/jp/articles/pickering-fsharp-async
上記のサイトを参考にさせいていただきました。
C#のGUIで、いろいろ試してみました。

F#側は
namespace Library1
open System
open System.Collections.Generic
open System.IO
open  Microsoft.FSharp.Control.CommonExtensions
open  System.Diagnostics
open  System.Text.RegularExpressions
module FSLib =
 let  path = @"\\192.168.1.1\HomeICT\test"
 let  readFile filePath =
     // open and read file
     let  fileStream = File.OpenText(filePath)
     let  text = fileStream.ReadToEnd()
     // find all the "words" using a regex
     let  word = new  Regex("\w+")
     let  matches = word.Matches(text)
     let  words  = seq{ for m in  matches -> m.Value }
     // count unique words using a set
     let uniqueWords = Set.ofSeq words
     // print the results
     let name = Path.GetFileNameWithoutExtension(filePath)
     sprintf "%s - Words: %d Unique words: %d "  name matches.Count  uniqueWords.Count
 let xt2 =
     let filePaths = Directory.GetFiles(path)
     [for filePath in filePaths -> readFile filePath]

C#側は

using System;
using System.Linq;
using System.Windows.Forms;
using Library1;
using System.Collections.Generic;
using Microsoft.FSharp.Collections;
途中省略
 private void button2_Click(object sender, EventArgs e)
        {
            //FSharpList<string> xt2 = FSLib.xt2;   最初、この2行でやってみたけれど
            //listBox2.Items.AddRange(xt2.ToArray());  めんどうなので、1行にまとめてみたらOKでした
            listBox2.Items.AddRange(FSLib.xt2.ToArray());

        }


2016年2月6日土曜日

WEBソフトはブラウザによる微妙な調整が必要

 グループウエアの改良に少しずつ取り組む。<img src='path'>を使った画像挿入の機能を入れてみた。IEでは、通常のファイルパスで指定してもOKだったが、ChromeやEdgeではhttp://で指定してやらないとだめだということがわかった。といっても、ファイルの削除等の処理は、ファイルパスを使う必要があるので、思ったより複雑になってしまった。
 画像は、HTML5の機能で、ファイルサイズを縮小する機能があるので、縦サイズをそろえてからアップロードするようにしてみた。
 
 WEBソフトというのは、ブラウザによって微妙に動かなかったり、動いたりするということにあらためて気づかされる。将来的に、ブラウザも変わっていけば、それに合わせてソフトも変えていかなければならないということになるのだろうか。

2016年1月31日日曜日

プログラミングF#入門

P257 10章計算式が参考になった。
 コンピューテンション式という言い方が、今は一般的らしいが、ネット等でいろいろ調べてみたが、いまいちすっきりしなかった。この書籍も、最初1回読んだだけでは理解出来なかったが、再度挑戦してみたら、だいぶ意味がつかみやすくなった。やはり、書籍を読むこととネットでいろいろな具体例に触れることの両方が大切だとあらためて感じる。
 通常のコーディングだと、複雑になりやすいパターンを、独自の定義により簡潔に表すことができるようになるようだ。最初の設計は大変だろうが、いったんできてしまえば、コーディングをわかりやすく簡潔にできるということのようだ。

2016年1月30日土曜日

実践F#関数型プログラミング入門 P377

リスト10-7 再帰を利用してwhileループを作る
 let rec myWhile(condition,behavior,arg)=
 if condition(arg) then myWhile(condition,arg,behavior(arg))
 else arg;;
と本の通りやってみたが、エラー
そこで、
let rec myWhile(condition,behavior,arg) =
   if condition(arg) then myWhile(condition,behavior,behavior(arg))
   else arg;;
としたら動いた。
ただ、正誤表にないので、ひょっとして自分の基本的間違いなのか?よくかわからない。

2016年1月28日木曜日

実戦F# 関数型プログラミング P295

8.15.3 パラメタライズド アクティブパターン

リスト 8-70 を少し変えて、いろいろ試してみた。
let (|Mul|_|) m n = if n%m=0 then Some(n/m) else None;;

let fizzbuzz3 = function
    | Mul 15 nm -> printfn("FizzBuzz  15で割ると%d") nm
    | Mul 3 nm -> printfn("Fizz 3で割ると%d") nm
    | Mul 5 nm -> printfn("Buzz 5で割ると%d") nm
    | n -> printfn("%d") n;;

fizzbuzz3 30;;
FizzBuzz 15で割ると2

nが入力となるようだ。nmのところが、Someの中身になるようだ。

つぎに、入力を表示するためにつぎのようにしてみた。
let fizzbuzz2 input =
 match input with
    | Mul 15 nm -> printfn("%d is FizzBuzz") input
    | Mul 3 nm -> printfn("%d is Fizz") input
    | Mul 5 nm -> printfn("%d is Buzz") input
    | input -> printfn("%d") input;;

fizzbuzz2 3;;
3 is Fizz

いずれにしても、
let (|Mul|_|) m n   ①
では、引数の最後のnが入力と考え、let (|Mul|_|) mまでがカリー化した?関数とみなしているようだ。
そして、Mul 15 nm ②
のMul 15にinputや入力を適用し、結果がnmに返り値となって表れる。ということのようだ。入力と返り値が、①でも②でも最後の項だけれど、①では入力 ②までは出力 となっているところが まぎらわしい。

アクティブパターンは、F#独自の機能のようだけれど、うまく活用するとプログラムが
簡潔になるらしい。書籍を読むだけでなく、実際に、いろいろ試してみたほうが理解しやすいようだ。

2016年1月23日土曜日

SQLのLEFT JOINの活用

 グループウエアで、未読管理をしていたが、既読の場合にログにとして記録していく方式をとっていたため、時間がたつにつれ、どうしても反応が遅くなることに気がついた。
 EXISTSでサブクエリなど使うことなど検討したが、どうやらもっといい方法があることを、たまたまネット上で見つける。
 http://kkoudev.github.io/blog/2013/09/14/sql/
上記のサイトを参考にさせていただきました。わかりやすく説明されています。
 実際LEFT JOINで、いろいろ検索条件をしぼってやってみたところ、レスポンスが劇的に改善しました。

2016年1月3日日曜日

Vb.netからF#を呼び出してみる

F#を少し使ってみた。関数型言語に共通するのは、副作用の多いGUIが使いにくいところらしい。(F#でイベントを駆使すれば、いろいろ便利ではあるようだけど?)妥協案としてVB.netでGUI(View)部分を作って、副作用なしのロジック部分はF#を使うというのはどうだろうか。
http://ameblo.jp/ns-programming-memo/entry-11241535796.html
を参考にさせった。C#でも、VBでも、可能。vs2015で試した。

①Vb.netで、プロジェクトを作成。
②ソリューションエクスプローラで、新しいプロジェクトとして、F#のライブラリを選択
③Library1.fsで
 module Modulex
 let x a b = a*b;;
④VBのプロジェクトの参照で、参照の追加で、同じソリューションのフォルダにできている
Library1を追加
⑤vb.netでボタンを貼り付けて
 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MsgBox(Modulex.x(2, 3).ToString)
    End Sub
などとしてみたら、うまく動作することが確認できた。

**************
関数であれば
namespace Library1
open System
 module FSLib =
  let fsFunc=new Func<string,string>(fun s -> s+s)
がF#側にあれば、C#側では
 listBox1.Items.Add(Library1.FSLib.fsFunc("test"));
のように呼び出すこともできるようだ。
ただし、F#のライブラリはその都度、コンパイルしないと反映しないようだ。
**************
リストであれば
namespace Library1
open System
open System.Collections.Generic
module FSLib =
  let  Avg( array : List<float>) =
   let list = List.ofSeq(array)
   List.average list
をF#側とすれば、C#側では
List<double> myInts = new List<double> { 5, 6, 7.5 };
            double avg = Library1.FSLib.Avg(myInts);
            textBox2.Text = avg.ToString() ;
のような感じである。
ちょっとした、変換は必須のようである。
*****************
配列などは F#で
 let  text= File.OpenText( @"c:\test.csv").ReadToEnd().Split([|','|])
で取得した配列を
 textBox2.Text = FSLib.text[0];
のようにC#に渡すこともできるようだ。

let xx = [1..3] |> List.toArray
 let x2= [1..3]
というF#により
  textBox2.Text = FSLib.xx[0].ToString() ;や
  textBox2.Text = FSLib.x2[1].ToString();なども可能なようだ