2018年2月23日金曜日

Java 7以降を使う場合の、ソケット通信の実装の仕方

Java 7以降でソケット通信を実装する場合、大きく3つのやり方がある。

  1. java.net.socket を使う方法
  2. java.nio.channel.ServerSocketChannel を使う方法
  3. java.nio.channel.AsynchronousServerSocketChannel を使う方法

java.net.socket は最も古典的な方法で、入出力操作(接続の待ち受けや送受信処理)がブロッキングで行われる。つまり、それらの処理をしている間、他のことができない。
自前でスレッドをたてれば並行に処理できるのだけど、スレッド管理はオーバヘッドを伴うので、多くの接続をさばくようなサーバプログラムの場合、スレッドを濫用するのは望ましくない。

java.nio.channel.ServerSocketChannel は、J2SE 1.4から導入されたNew I/O(NIO)のAPI。入出力操作についてブロッキングとノンブロッキングのどちらかを選んで使うことができる。
ノンブロッキングの場合、セレクタ(java.nio.channels.Selector)という分配器みたいなオブジェクトを使う。入出力操作をするメソッドは完了を待たずに(=ブロックせずに)returnし、セレクタに問い合わせることで入出力操作の結果を受け取れる、というイメージ。

java.nio.channel.AsynchronousServerSocketChannel は、Java SE7から導入されたNIO.2のAPI。ServerSocketChannelと似た作りだが、ノンブロッキングでの入出力操作がしやすいよう、より強化されている。


java.nio.channel.AsynchronousServerSocketChannel を使う場合、入出力操作の結果の受け取り方には大きく2つの方法がある。
1つ目は、コールバック。つまり、入出力操作の呼び出し時に、コールバック関数を登録し、処理完了時にそちらが呼び出される。
2つ目は、Futureオブジェクトを使う方法。入出力操作を呼び出した際に、返り値としてFutureクラスのオブジェクトを受け取る。このFutureオブジェクトに対して、任意のタイミングでアクセスすることで、結果(あるいは結果が出る前の状態)を取得できる。

例えば accept メソッドは以下2パターン用意されており、前者が上記2つ目、後者が上記1つ目に対応する。

  • Future<AsynchronousSocketChannel> accept()
  • <A> void accept(A attachment, CompletionHandler<AsynchronousSocketChannel,? super A> handler)


というわけで、ノンブロッキングかつリアルタイムに処理を進めたいのであれば、java.nio.channel.AsynchronousServerSocketChannel のコールバックの仕組みを使うのが良さそう。
具体的な使い方は、JavaDocを参照: https://docs.oracle.com/javase/jp/8/docs/api/java/nio/channels/AsynchronousServerSocketChannel.html

上記acceptメソッド(コールバック版)にて、CompletionHandlerの型引数にAsynchronousSocketChannelが指定されている。コールバック関数側は、「接続待ち」の結果として、このAsynchronousSocketChannelオブジェクト(=接続相手との通信チャネル)を受け取る。


AsynchronousSocketChannelクラスのreadメソッドは、接続相手からの通信パケットを読み出す操作である。これもノンブロッキングで呼び出せるようになっており、上記と同様、Futureを使うパターンと、コールバックを使うパターンとがある。
readメソッドには以下の4種類が存在し、1つ目がFutureパターン、2つ目以降がコールバックパターンである。

  • Future<Integer> read(ByteBuffer dst)
  • <A> void read(ByteBuffer[] dsts, int offset, int length, long timeout, TimeUnit unit, A attachment, CompletionHandler<Long,? super A> handler)
  • <A> void read(ByteBuffer dst, A attachment, CompletionHandler<Integer,? super A> handler)
  • <A> void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<Integer,? super A> handler)

3つ目と4つ目の違いは、タイムアウト関連のパラメータの有無。タイムアウトが指定されていると、一定時間経過後、読み取り処理はInterruptedByTimeoutExceptionで終了する。

2つ目のものは、やや特殊で、タイムアウト関連パラメータの他、offsetとlengthを指定できるようになっている。また、dstsはバイトバッファの配列になっている。
配列内の、offsetで指定した位置以降の各バッファに、順にバイトが読み込まれていく。例えば、読み取り対象が計20バイトで、配列dstsの各要素の長さが8、offsetが2の場合は、以下のようになる。
dsts[0] : 無し
dsts[1] : 無し
dsts[2] : 1~8バイト目まで
dsts[3] : 9~16バイト目まで
dsts[4] : 17~20バイト目まで
lengthは、アクセスされるバッファ数の上限。上記のケースでlengthが2であれば、dsts[4]にはバイトが読み込まれないことになる。
この方式は、複数の固定長ヘッダがつらなるようなメッセージを読み取る時に役に立つことがあるらしい。(と言っても、後から分割しなくて済むという程度か。)

2018年2月11日日曜日

IntelliJ IDEAでターミナル⇔エディタ間移動のショートカット

最近、IntelliJ IDEAに乗り換えた。

ツールウィンドウとしてターミナルを出しておけるので、そこからgitコマンドを打ったりしている。

このターミナルと、エディタ(=現在のタブ)との間を、キーボードショートカットで行ったり来たりできるようにしたい。

デフォルトでは、「Alt+F12」でエディタ⇒ターミナルの移動ができる。
のだが、ターミナル⇒エディタの移動はひと工夫しないとできない様子。

※参考:https://stackoverflow.com/questions/21134438/how-to-jump-from-intellij-terminal-to-editor-with-shortcut/23860667

以下のような方策があるらしい。
・もう一度「Alt+F12」を押す(エディタに移動できるが、ターミナルは閉じてしまう)
・「Alt+2」を2回押す(ターミナルに「2」が入力されてしまうことがある)
・「Alt+Home」でナビゲーションバーに移動した後、「ESC」でエディタに移動
・File⇒Settings⇒Tools⇒Terminal⇒Override IDE shortcuts、のチェックを外した上で、「ESC」を使う

ターミナルは開いたままにしておきたいし、ワンアクションで移動したいので、ひとまず上記4つ目の方法を選択。
しばらく使ってみて様子を見る。

2017年2月5日日曜日

Kindleオーナーライブラリで書籍を更新したいとき



  1. Amazon.co.jpのアカウントサービス⇒デジタルコンテンツ⇒コンテンツと端末の管理
  2. 前月にオーナーライブラリで登録した本を選択し、削除またはアクションメニューから利用を終了




2017年1月29日日曜日

puttyで自動再接続

Windows上からputtyでSSH接続するとき、接続先のSSHサーバとのあいだのネットワークが一時的に切断されたりしても、自動で再接続するようにしたい。

ぐぐるとpfwdを使うとかbitvise ssh clientを使うとか、いくつか方法が出てくるのだけど、手元の環境ではいずれもいまひとつうまく動かない面があったので、別の方法をとることにした。

具体的には、以下のとおり。

  • puttyのセッション設定でkeep aliveを有効にして、切断をクライアント側から検知できるようにする
  • pagentで秘密鍵のパスフレーズ入力を自動化する
  • plink使ってログインおよび再接続するバッチファイルを作る

1点目のkeep aliveについては、puttyの設定画面⇒Connection⇒「Seconds between keepalives」を0以外の値にしておく。自分は10秒にした。

pagentを使うと、このあと述べるplinkでSSHログインするとき、秘密鍵のパスフレーズを自動で入れてくれる。
使い方は簡単で、puttyに同梱されているpagent.exeを実行するとタスクトレイにpagentのアイコンが出る。
右クリックしてAdd Keyから秘密鍵を登録すればOK。

plinkはputtyをコマンドラインから実行するもの。

$ plink <セッション名> -l <ログインユーザ名>

こんな感じで接続できる。

plinkを使って作成したバッチファイルは、こんな感じ。

@echo off
cd <plink.exeがあるディレクトリ>
echo starting connection...
plink <セッション名> -l <ログインユーザ名>

:LOOP
echo starting connection...
plink <セッション名> -l <ログインユーザ名>
timeout <次の再接続まで待つ秒数>
goto LOOP


サーバ側の再起動時とかも、このバッチファイルが動いていれば、自動で再接続しにいってくれる。
注意点として、pagentは再起動すると1回はパスフレーズ入れないといけないので、バッチファイルをスタートアップに入れたとしても、クライアント側(Windows)を再起動したあとに自動で接続、とはならない。

再接続の間隔を徐々に伸ばしていったりとか、ターミナル開かないようにしたりとか、凝る余地は色々ありそうだけど、ひとまず手軽に自動再接続ということで。

2015年8月30日日曜日

複数プロキシ切り替えのシェルスクリプト

Ubuntuで,ターミナルから複数のプロキシを切り替えるスクリプト.

#!/bin/bash

echo '--------------------------------------'
echo 'Proxy Settings'
echo '--------------------------------------'

menu1='SHOW CURRENT PROXY'
menu2='DISABLE'
menu3='SET [hoge.co.jp]'
menu4='SET [foo.co.jp]'
menu5='QUIT'

select menu in "$menu1" "$menu2" "$menu3" "$menu4" "$menu5"
do
    if [ -z "$menu" ]; then
        continue
    else
        break
    fi
done

case "$menu" in
    "$menu1" )
        printenv | grep proxy
        $BASH_SOURCE ;;
    "$menu2" )
        unset http_proxy
        unset https_proxy
        unset ftp_proxy
        unset no_proxy
        echo 'printenv | grep proxy'
        printenv | grep proxy
        $BASH_SOURCE ;;
    "$menu3" )
        export http_proxy='http://hoge.co.jp:8080/'
        export https_proxy='https://hoge.co.jp:8080/'
        export ftp_proxy='ftp://hoge.co.jp:8080/'
        export no_proxy='localhost,127.0.0.1'
        echo 'printenv | grep proxy'
        printenv | grep proxy
        $BASH_SOURCE ;;
    "$menu4" )
        export http_proxy='http://foo.co.jp:8090/'
        export https_proxy='https://foo.co.jp:8090/'
        export ftp_proxy='ftp://foo.co.jp:8090/'
        export no_proxy='localhost,127.0.0.1'
        echo 'printenv | grep proxy'
        printenv | grep proxy
        $BASH_SOURCE ;;
    "$menu5" )
        echo bye ;;
esac

直接実行すると,スクリプト内での環境変数の変更が,スクリプト終了時に破棄されてしまう.
なので,sourceコマンドで呼び出す.

$ source proxyswitch.sh

エイリアスを設定しておくと使いやすい.



ついでに,Windowsで同じようなことをやるバッチ.

@echo off
:Menu
cls
echo --------------------------------------
echo Proxy Settings
echo --------------------------------------
echo 1:SHOW CURRENT PROXY
echo 2:ENABLE
echo 3:DISABLE
echo 4:SET [hoge.co.jp]
echo 5:SET [foo.co.jp]
echo q:QUIT
echo --------------------------------------
echo Attention: it changes registry settings.
echo --------------------------------------

set Slt=nul
set /p Slt="input:"

if '%Slt%'=='1' goto Set_1
if '%Slt%'=='2' goto Set_2
if '%Slt%'=='3' goto Set_3
if '%Slt%'=='4' goto Set_4
if '%Slt%'=='5' goto Set_5
if '%Slt%'=='q' goto :eof

goto Menu

:Set_1
FOR /F "TOKENS=1,2,*" %%A IN ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable') DO IF "%%A"=="ProxyEnable" SET enable=%%C
FOR /F "TOKENS=1,2,*" %%A IN ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer 2^>nul') DO IF "%%A"=="ProxyServer" SET proxy=%%C
if %enable%==0x0 echo [disabled]  (%proxy%)
if %enable%==0x1 echo [enabled]  %proxy%
pause
goto :Menu

:Set_2
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /f /v ProxyEnable /t reg_dword /d 1
echo Proxy ON
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer
pause
goto :Menu

:Set_3
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /f /v ProxyEnable /t reg_dword /d 0
echo Proxy OFF
pause
goto :Menu

:Set_4
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /t REG_SZ /d hoge.co.jp:8080 /f
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer
pause
goto :Menu

:Set_5
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /t REG_SZ /d foo.co.jp:8090 /f
reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer
pause
goto :Menu


2015年8月28日金曜日

Ubuntuでターミナルからgoogle検索できるようにする

Ubuntu等のLinuxで,ターミナルから以下の動作を呼び出せるようにしたい.

  • chromiumブラウザに新規タブを開く
  • 開いたタブで,指定したキーワードでgoogle検索を実行

~/.bashrc に以下の内容を追記する.

function google() {
      QUERY=''
      for arg in $@; do
          if [ "$arg" = "$1" ]; then
              QUERY=${QUERY}${arg}
          else
              QUERY=${QUERY}+${arg}
          fi
      done
      chromium-browser www.google.co.jp/search\?q=${QUERY} &
}

保存したら,以下のコマンドで,有効化する.

$ source ~/.bashrc 


これで,ターミナルで

$ google hoge foo bar 

などと入力すると,「hoge」「foo」「bar」でAND検索ができる.

TildaやGuakeのようなドロップダウン型のターミナルで使うと便利.


2015年7月3日金曜日

LGL22のダウングレード

2015/6/23のソフトウェア更新によって,LGL22のSIMフリー化が塞がれた.

http://k-tai.impress.co.jp/docs/news/20150623_708303.html

ソフトウェア更新をもとに戻すための手順のメモ.

1. ダウンロード

  • LGUnitedMobileDriver: http://www.lg.com/jp/support-mobile/lg-LGL22
  • LG Flash Tool 2014: http://forum.xda-developers.com/showthread.php?t=2797190
  • LGL2220D_00.kdz: http://forum.xda-developers.com/showpost.php?p=51177684

2. インストール

  • LGUnitedMobileDriverをインストール
  • LG Flash Tool 2014のzipファイルを解凍
  • LGL2220D_00.kdzは,上記zipファイル解凍でできたフォルダに入れておく

3. PCとLGL22の接続

  • LGL22の電源をOFFにする
  • ボリュームアップボタンを押しながらUSBケーブルを接続
  • 以上により,Download modeとして起動する

4. COMポート設定

  • PCのデバイスマネージャを開き,ポート(COMとLPT)を展開
  • LGE AndroiNet USB Serial Port(COM**)を右クリック→プロパティを開く
  • ポートの設定→詳細設定→COMポート番号のプルダウンからCOM41を選択

5. LGFlashTool実行

  • LGFlashTool2014.exeを起動
  • 「Select KDZ file」でLGL2220D_00.kdzを選択
  • 「Normal Flash」を押す
  • 次の画面で「START」を押す
  • 次の画面で「OK」を押す
  • 途中,何かダイアログが出るが,プログレスバーは進んでいる.そのままダイアログを放置して,プログレスバーが100%になるまで待つ.

2014年5月7日水曜日

EPSのbounding boxを自動調節

論文作成時に,画像を載せるためにEPSファイルを使う場合について.
WindowsでpptxからEPSを作る場合,EPSプリンタでファイル出力した後にGhostviewからbounding boxを設定するという方法があるが,毎回Ghostviewを開くのはけっこう面倒.

Epstoolというのを使えばコマンドラインから自動調節できるらしいが,自分の環境ではうまく動かなかった.
そこで,ghostscriptのコマンドを使ってbounding boxを自動調節するバッチを作った.

ghostscriptのオプションで「-sDEVICE=bbox」とすると,指定したソースファイルのbounding boxを(必要最小限な領域で)計算して返してくれる.

gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=bbox <ファイル名>

その結果を使って,EPSファイルの中身を書き換えれば良い.
書き換えはただのテキスト置換なので,いくらでもやりようはあると思う

@echo off
setlocal enabledelayedexpansion

set currentpath=%cd%
set /p src_filename="Source File Name: "
set /p dst_filename="New File Name: "

gswin32c -q -dNOPAUSE -dBATCH -sDEVICE=bbox %src_filename% 2> tmp.txt
set /p bbox=”” < tmp.txt
del tmp.txt

<src_filename内の「%%BoundingBox:」で始まる行を変数bboxの値で置き換えてdst_filenameに書き出す処理>

endlocal
pause

EPSファイル書き換えの注意点として,EPSファイル冒頭部に「%%BoundingBox: (atend)」から始まる行がある場合,bounding boxはファイル末尾に記載されているため,そちらを書き換える必要がある.(冒頭部は書き換えない)

2014年2月24日月曜日

Outlookの予定表をAndroidのカレンダーから読めるようにする

会社の予定表はOutlookで管理されているのだけど,これを社外でも確認できるようにしたい.
というわけで,

  • Outlookからサーバにカレンダーを定期upload
  • Android上でサーバから定期read

という感じのことがやりたい.

準備として,フリーのWebDAVサーバのアカウントを作る.
今回は,Driveeを使った.
アカウントを作ると,以下がWebDAVサーバのURLとなる.

 https://ユーザ名.drivee.jp/

次に,Outlookの「ホーム」タブにある「オンラインで公開」から上記WebDAVサーバのURLを設定する.
すると,Driveeにicsファイルがuploadされる.

Android側では,今回はICSSyncというアプリを使った.
Playストアからインストールして,アプリを起動し,「Add feed」からuploadしたicsファイルのURLを設定する.
URLは,Outlookの「オンラインで公開」から「発行オプションの変更」を選ぶと確認できる.

 https://ユーザ名.drivee.jp/****_の予定表.ics

のようになっているはず.

閲覧は,Androidのカレンダーアプリから行なう.
カレンダーアプリのメニューから「カレンダーを表示する」を選ぶと,一覧の中に「ICSSync」のカレンダーがあるはず.
チェックが入っているのに表示されない場合は,一度チェックを外してカレンダー画面に戻ってから,再度「カレンダーを表示する」でチェックを入れると表示されるかも.


2014年2月7日金曜日

IEEEのLaTeXテンプレート

IEEEはLaTeXのテンプレートを公開している.

http://www.ieee.org/conferences_events/conferences/publishing/templates.html

が,これが意外とくせもので,

・図のキャプションが強制的に左寄せになる
・paragraphの間に余分なスペースが入る

といった問題が生じることがある.
CTANで配布している版を使うと,解消される.

http://www.ctan.org/tex-archive/macros/latex2e/contrib/IEEEtran/

バージョン番号は変わらない(2014/2/7時点でどちらも1.8)が,CTANのほうが微妙に新しくてあちこち修正されているみたい.

subfigのキャプションを括弧付きで参照する

LaTeXで図を縦方向や横方向に2つ以上並べたい場合,subfig.styを使用する.
例えば縦に2つ並べる時は,以下のような感じ.


\usepackage[caption=false]{subfig}

  :
  :

\begin{figure}[!t]
  \centering
  \subfloat[副キャプション1]{
    \includegraphics[width=\linewidth]{****.eps}
    \label{fig_sub1}
  }
  \\
  \subfloat[副キャプション2]{
    \includegraphics[width=\linewidth]{****.eps}
    \label{fig_sub2}
  }
  \caption{全体キャプション}
  \label{fig_1}
\end{figure}

で,図の番号を参照する時に,普通に

図\ref{fig_sub1}

とか書くと,「図1a」「図1b」のように出てきたりするが,これを「図1(a)」「図1(b)」のように括弧付きにしたい場合にどうしたら良いかという話.

前置きが長くなったが,やり方は簡単で,

図\ref{fig_1}\subref{fig_sub1}

とすればOK.


参考ページ: http://tex.stackexchange.com/questions/16291/adding-parentheses-around-subfig-references

2014年2月6日木曜日

英文論文でマルバツ表を作る

英語で論文を書く際,こんな感じの表を書きたくなることがある.

機能1機能2
手法1×
手法2×

LaTeXだと「\begin{table}~」で表を作ればいいのだが,問題はセルの中身で,英語だと普通○×は使わない.
じゃ何を使うのかというと,以下のようなパターンがあるらしい.(いずれも前者が該当,後者が非該当の意味)

・チェックマーク(「レ」みたいなやつ)とバツマーク(×)
・チェックマークと空欄
・「yes」と「no」

今回は,チェックマークとバツマークを使う場合について.
LaTeXの場合,チェックマークについては

\usepackage{amssymb}

しておいて「\checkmark」で表示できる.
バツマークは「\times」が使えるので,これで表をつくると下のような感じになる.


なんかイマイチだな・・・という人は,pifont.styを使うのもオススメ.

pifont.styは以下からDLできる.


ダウンロードして解凍したら,コマンドプロンプトで解凍先フォルダに移動し,以下のコマンドを実行する.

platex pifont.ins

すると,解凍先フォルダにpifont.styができあがっているので,これをtexファイルと同じ場所に突っ込んでおく.で,

\usepackage{pifont}
\newcommand{\cmark}{\ding{51}}%
\newcommand{\xmark}{\ding{55}}%

としておくと,「\cmark」「\xmark」でそれぞれいい感じのチェックマークとバツマークが使えるようになる.
例えば下のような感じ.





2014年1月16日木曜日

PC再起動時に,前回開いていたPower Pointファイルをまとめて開く

Windows Updateをかけると,PCの再起動を迫られることがよくある.
何の因果かPower Pointを5枚も10枚も開いていた場合,再起動した後にそれらをひとつひとつ開き直すのはめんどくさい. 特にファイルの保管場所がバラバラだとこの上なくめんどくさい.
そこで,現在開いているPower Pointファイルの場所(ファイルパス)を記憶しておいて,再起動後にそれらをまとめて開くためのプログラムを書いた. 言語はC#.(実はC#触るの初めてなので環境構築からだった)
仕様は,
  • 起動するとコンソール上に「save」「open」のメニューが出る
  • saveを選ぶと,現在開いているpptファイルのパス一覧を表示し,ユーザのデスクトップフォルダに保存する.
  • openを選ぶと,前回デスクトップに保存したファイルからパスを読み込んで,まとめて開いてくれる
という感じ.で,コードは以下. 命名とか色々適当なのはスルーで.

using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using PowerPoint = Microsoft.Office.Interop.PowerPoint;
using Microsoft.VisualBasic;

namespace PPTSO{
    class PPT{
        private string save_file = "C:\\Users\\" + System.Environment.UserName + "\\Desktop\\PPTSO.txt";

        static void Main(string[] args){
            PPT ppt = new PPT();
            if (!File.Exists(ppt.save_file)){
                File.Create(ppt.save_file).Close();
            }
            while (true){
                Console.Clear();
                Console.WriteLine("s: save current ppt files");
                Console.WriteLine("o: open previous ppt files");
                Console.WriteLine("q: quit");
                Console.Write("input: ");
                string menu = Console.ReadLine();
                Console.WriteLine(menu);
                if (menu.Equals("s")){
                    ppt.savePPT();
                }else if (menu.Equals("o")){
                    ppt.openPPT();
                }else if (menu.Equals("q")){
                    break;
                }else{
                    Console.WriteLine("input error. press any key...");
                    Console.ReadKey();
                }
            }
        }

        public void savePPT(){
            Interaction.CreateObject("PowerPoint.Application", "");
            PowerPoint.Application pApp = (PowerPoint.Application)Interaction.GetObject(null, "PowerPoint.Application");
            foreach (PowerPoint.DocumentWindow dw in pApp.Windows){
                Console.WriteLine("{0}", dw.Presentation.FullName);
            }
            string yn;
            Console.WriteLine("--------------------");
            Console.WriteLine("are you sure to save? y/n");
            while (true){
                yn = Console.ReadLine();
                if (yn.Equals("n")){
                    return;
                }else if (yn.Equals("y")){
                    break;
                }else{
                    Console.WriteLine("input error. press \"y\" or \"n\":");
                }
            }
            FileStream fs = new FileStream(save_file, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);
            foreach (PowerPoint.DocumentWindow dw in pApp.Windows){
                sw.Write(dw.Presentation.FullName + "\r\n");
            }
            sw.Close();
            fs.Close();
        }

        public void openPPT(){
            string path;
            List<string> pathList = new List<string>();
            FileStream fs = new FileStream(save_file, FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            while ((path = sr.ReadLine()) != null){
                pathList.Add(path);
                Console.WriteLine(path);
            }
            sr.Close();
            fs.Close();
            string yn;
            Console.WriteLine("--------------------");
            Console.WriteLine("are you sure to open? y/n");
            while (true){
                yn = Console.ReadLine();
                if (yn.Equals("n")){
                    return;
                }else if (yn.Equals("y")){
                    break;
                }else{
                    Console.WriteLine("input error. press \"y\" or \"n\":");
                }
            }
            List<string> openedPathList = new List<string>();
            Interaction.CreateObject("PowerPoint.Application", "");
            PowerPoint.Application pApp = (PowerPoint.Application)Interaction.GetObject(null, "PowerPoint.Application");
            foreach (PowerPoint.DocumentWindow dw in pApp.Windows){
                openedPathList.Add(dw.Presentation.FullName);
            }
            PowerPoint.Presentations pPt = new PowerPoint.Application().Presentations;
            foreach (string str in pathList){
                if (openedPathList.Contains(str)) continue;
                pPt.Open(str);
            }
        }
    }
}








相関係数の検定

論文を書く時など,シミュレーション実験の結果から相関係数を算出することがある.
参考程度であれば相関係数を出しただけで終えても良いのだが,論文等に載せる場合は算出した相関係数に意味があるか否かを調べる必要がある.
どういうことかと言うと,相関係数の算出に用いたデータはあくまでもサンプルであり,真の相関係数が求まっているわけではない.

つまり,母集団から標本を取り出して計算した結果に過ぎないので,もし使用した標本が外れ値だらけで,母相関係数との間に大きなずれがあれば,意味のない値ということになってしまう.
そこで,母相関係数ρ=0であるという帰無仮説をたてて,有意性の検定を行なう.
これを無相関検定と呼ぶ.手順は次の通り.(rは相関係数,nはサンプル数)
  1. 帰無仮説をたてる:「相関が無い(ρ=0)」
  2. 対立仮説をたてる:「相関がある(ρ≠0)
  3. 有意水準を決める:通常は1%か5%
  4. 自由度*を求める:自由度=サンプル数-2
  5. t値を計算する:t=r * ((n-2)/(1-r^2))^(1/2)
  6. t分布表を見て,該当する自由度の箇所の水準値をt値が上回っていれば,帰無仮説は棄却(対立仮説を採択)
  7. 6.と逆の場合には,帰無仮説を採択
エクセルで求める場合,まず以下でt値を計算する.

 t=ABS(相関係数*SQRT(サンプル数-2)/SQRT(1-相関係数^2))
次に,以下でp値を計算する.

 p=TDIST(t値, 自由度, 2)
pが有意水準を下回っていれば,帰無仮説を棄却できる(相関係数が有意であると言える).


※参照ページ

※自由度
 母集団からサンプル数nで標本を取り出す場合について考える.標本平均を母平均と一致させるためには,n-1個のサンプルは自由に選んでも良いが,残りの1つで標本平均を調節しなければならない.この,自由に選べる数「n-1」が自由度.
 大雑把な理解としては,相関係数の場合は,相関を見る対象である2つの母集団が存在するため,自由度が2減る.従って,「サンプル数-2」が自由度となる.


2014年1月14日火曜日

jEditにスペルチェック機能を追加する

jEditにはSpell Checkというスペルチェック用のプラグインが用意されている.
Spell Checkを使うには,事前にAspellをインストールしておく必要がある.
Aspellはオープンソースのスペルチェッカーで,Spell CheckはjEdit側からこのAspellの機能を呼び出すためのプログラム.
Aspellのインストール方法についてはTeX Wikiに詳しい説明がある.
Windowsの場合,Aspell Win32版の配布ページから本体と辞書をダウンロードして,順にインストールする.記事執筆時点(2014.1.15)では,
  • 本体: Aspell-0-50-3-3-Setup.exe
  • 辞書: aspell-en-0.50-2-3.exe
なお,英語以外の言語の辞書もあるので必要に応じてインストールする.
Aspellをインストールしてbinフォルダにパスを通すと,コマンドプロンプトから以下のコマンドでテキストファイルのスペルチェックが可能.

aspell --lang=en -c ファイル名

例えば,以下のようなテキストファイルを用意する.

test text.
tets text.

これに対し,コマンドプロンプトで上記のコマンドを実行すると,下図のようになる.



画面下に出ている選択肢から例えば「1」を選ぶと,当該箇所が「test」に書き換えられる.

さて,jEdit側.
Spell Check pluginをインストールして,plugin optionsからSpell Checkのオプション画面を開く.
「Aspell Engine」という項目があるのでそこを開き,aspell.exeの場所を指定しておく.
(例えば,C:\Program Files (x86)\Aspell\bin\aspell.exe)

「General」という項目で,「Spell-checking engine」のところを「Aspell」に設定する.
その下にある「Refresh list」を押してから辞書として「en」を選択する.

これで準備はひとまず完了.
テキストファイルを開いた状態で,プラグインメニューからSpell Checkを選び「Spell check selection」を実行すると,スペルチェックしてくれる.
他にもいくつかメニューがあるので,状況に応じて使い分けすると良い.

なお,「Browse user dictionaries」を実行するとファイルブラウザ側でユーザ辞書のディレクトリが開く.
間違って変な単語をAdd(ユーザ辞書に追加)してしまった場合は,この辞書を修正する.
ただし,jEdit上で修正しても,反映されなかった.
たぶん,jEdit側で起動時に読み込んで,終了後に変更されていたら書き戻す感じになっている? jEditを終了した状態で修正し,修正後にjEditを再起動したらうまくいった.