2014年12月29日月曜日

tomcatを使うにあたって、eclipseの中では文字化けしないのに、startup.bat起動だと文字化け(windows)

ファイルアップロードの際、全角ファイル名部分が文字化けする現象にしばらく悩まされる。
Linuxでは問題なく、また、Windowsでもeclipseからtomcatで動かしている間は問題なかったのでしばらく気づかなかった。startup.batでtomcatを動かすと発生する不具合です。

server.xml web.xml コンテキスト設定等 文字コード関連の指定について
いろいろチェックするけれど、なかなか分からない。

ストリーム関連の文字コードについて、いろいろ調べた結果
原因は、アップロードを行うサーブレットの中にあることが判明。
ServletInputStream in = request.getInputStream();

in.readLine(b,0,bufsize)
というように、ストリームとしてデータを読み込み、そこから文字を取り出すため
str = new String(b,0,count-2);としていたが、これではだめらしく
str = new String(b,0,count-2,"UTF-8");としたら、うまくいった。


2014年12月23日火曜日

完全順列について

順列の中で、もとの順番とまったく一致しないものを完全順列というらしい。これをもとめるアルゴリズムを考えてみた。もっと、無駄のない方法がありそうだ(Haskellなんかだと、数行ですむようですが)が、このへんで妥協してみた。
なお、何通りか表すのがモンモール数というらしく、こちらは漸化式がWikiにあったので、それをもとにすぐ作ることができた。
#include "stdafx.h"
#include <iostream>
using namespace std;
 const int imax=5;
 int lst[imax],kekka[imax];
  void shori(int level);
double shori2(int level);
int coun;
int _tmain(int argc, _TCHAR* argv[])
{
coun=0;
int i;
cout<<endl<<"全部で"<<shori2(imax)<<endl;
for (i=0;i<imax;i++){
kekka[i]=-1;
}
shori(0);
char dummy[1];
cin>>dummy;
return 0;
}
double shori2(int level) {//モンモール数
double x;
if(level>2){
x=(level-1)*(shori2(level-1)+shori2(level-2));
}
else{
if(level==1) x=0;
if(level==2) x=1;
}
return x;
}
void shori(int level) {//完全順列
int i,ii;
bool flg;
for(ii=0;ii<imax;++ii){
flg=true;
for(i=0;i<level;i++){
if(kekka[i]==ii){
flg=false;//親ですでに使われていないかチェック
break;
}
}
       if(level!=ii && flg) {//同じ順番で親でないときはOK
kekka[level]=ii;//ここでいったん確定
 if (level==imax-1){//最深レベルで出力
for(i=0;i<imax;i++){
printf("%d ", kekka[i]);
}
printf("=No.%d\n",coun) ;
 coun=coun+1;
     }
  shori(level+1);
  kekka[level]=-1;
}
}
}


2014年12月14日日曜日

scalaスケーラブルプログラミング P393

構造的サブ型について
 Animal  {type SuitableFood = Grass}
  基底型(Animal)の型を 規定(Refine)する。

そして、基底型が指定されてないことも(その場合AnyRefが基底型になるそうだ)

def using[T <: {def colse():Unit},S] (obj:T) (operation:T => S) = {
 val result =operation(obj)
 obj.close()
 result
}
このusingを使えば、 {def colse():Unit}で規定(close()メソッドを持つ型だけ)されたものをサポートするようにできるとか。上限境界を使っている。
これをうまく使えば、応用範囲は広いように思う。が、使いこなせるには、相当な慣れが必要なように思う。

scalaスケーラブルプログラミング P374

リスト 19.10 最適化された関数型待ち行列
class Queue[+T] private (
  private[this] var leading: List[T],
 private[this] var trailing: List[T]
) {
 private def mirror() =
  if (leading.isEmpty) {
   while (trailing.isEmpty) {
    leading =trailing.head::leading
   tariling=trailing.tail
 }
}
def head: T= {
 mirror()
 leading.head
}
def tail:Queue[T] = {
 mirror()
 new Queue(leading.tail,trailing)
}
def enqueue[U >: T](x: U) =
  new Queue[U] (leading,x :: trailing)
}


head操作が繰り返されても、tailingからleadingへのコピーは高々1度しか行われない。
mirrorにより、leadingとtailingは中身が変化しているから。
ちなみに、リスト19.1のほうは、leadingもtrailingもvalのため、
def head = mirror.leading.headが、連続してもその都度、
def mirror = if (leading.isEmpty) new Queue(trailing.reverse,Nil) else this
が行われてしまうらしい。このとき、leading.isEmpty=trueなら、その都度tailing.reverseが
おこなわれてしまうということらしい。(def headでは、新たなQueueを返してもいないため、もとのleadingが変化しないから)

以下の
 while (!trailing.isEmpty) {
    leading =trailing.head::leading
   tariling=trailing.tail
 }
の部分は、leadingが空のときのみ行われる。
trailingが空になるまで、trailingのtailが新たにtailingとなり
trailingのheadが、leadingの先頭に追加されている。つまり、反転されてleadingに移動している。

************
ここまで読んで、scalaの実行速度を落とさないようにするには、けっこう気を付けていく
必要があるのだと感じた。

2014年12月10日水曜日

シェルスクリプト 文字置換

シェルスクリプトをソフトのセットアップに使えないかと思いいろいろ試している。
設定ファイルの一部を書き換えるときなど、置換で行う方法を考えてみた。
ファイルの書き換え方がわからず、仕方なく、あまりいい方法でないが
とりあえずできればいいだろうという感じで、このようにしてみた。

echo "id:"
read id
echo "pass:"
read pas
sed -e "s/abc/$id/" -e "s/def/$pas/" config.txt >config,tmp
rm config.txt
mv config.tmp config.txt

************
その後、-iコマンドで直接ファイルを書き換えできることを知りました。
sed -i -e "s/abc/$id/" -e "s/def/$pas/" config.txt
これでいいようです

2014年12月7日日曜日

scalaスケーラブルプログラミング P369


19章の後半の変位指定アノテーションのあたりから難しい。
 クラスを宣言するトップレベルのポジションは陽性に分類されるとある。ネストの中のポジションはディフォルトではそれを囲む部分と同じだが、変化する例外がある。それは、メソッドの値パラメーターのポジションでは、メソッドの外のポジションの分類が反転するとある。メソッドの型パラメーターのポジションでも反転すると言っている。

P370でQueue[T]の定義で、Tがenqueueメソッドのパラメーターの型として現れる。Tが現れるその位置は陰性ポジションなので、、、とあるが、ここがよく理解できない。
なお、リスト19.4参照とあるが、19.1のこと?だろうか

class Queue[T]{
----------------
        def enqueue(x: T) =
          new Queue(leading, x :: trailing)    
    }

※おおざっぱにいって、戻り値なら、共変(陽性)とするが
 引数なら、反変(陰性)となるということなんだろうか?

そこで、少しもどってP365のリスト19.5が次のような場合を考える
class Cell[+T](init:T){
  private[this] var current = init
  def get = current
  def set(x:T){current =x}
これが、もしコンパイルできたとする。(実際はできないが)
val c1=new Cell[String]("abc")
val c2:Cell[Any]=c1 ←Cellは共変なので、これはOK
c2.set(1)
val s:String=c1.get
となり、コードの型に矛盾はないものの、String型の変数にInt型の値を代入することとなり、エラーとなる。

P372で、さらに具体例で、※の部分を説明している。
リスト19.8の
trait Function1[-S,+T] { 云々 }
の意味するところは、Sが反変、Tが共変  そして S =>T なる形の関数を展開したものらしい。
そしてリスト19.9で
info :Book => AnyRefには、Publication=>Stringの関数が使われている。
引数は Book extends Publication  Sのほう
戻り値は String extends AnyRef   Tのほう
ということで 矛盾ない構成になっている感じはする。ん~、ややこしい。




2014年12月1日月曜日

scala スケールプログラミング P.340

varを持っていても、純粋関数型になる例が出ている。

http://d.hatena.ne.jp/plasticscafe/20100906/1283745561
を参考にさせていただいた。

class Keyd {
 def computeKey: Int = ...//この処理には時間がかかる
...
}

class MemoKeyed extends Keyd {
  private var keyCache :Option{Int] =None
  override def computeKey: Int = {
 if (!keyCache.isDefined) keyCache = Some(super.computeKey)
 keyCache.get
 }
}

①MemoKeydのcomputeKeyでは、一回目はkeyCacheがないので、スーパークラスの
computeKeyメソッドで処理した値がkeyCacheに入る。keyCacheからデータが取り出される。
②二回目は、スーパークラスのcomputeKeyメソッドで処理はとばして、一回目に入れていた
値が、keyCacheから取り出される。
①、②いずれにしろ、同じ値がcomputeKeyからは、出てくるということで、純粋関数型とみなせる
ということのようだ。

2014年11月29日土曜日

scala スケーラブルプログラミング P306

mapとflatmapについての説明が出ていた。

List.range(1,5) flatmap (
      i=> List.range(1,i) map (j => (i,j))
     )
これが、どうなるか、たどってみた。
List.range(1,5)はList(1,2,3,4)
i=1であれば List.range(1,1) map (j => (1,j))は なし?
i=2               List.range(1,2) map (j => (2,j))は (2,1)
i=3               List.range(1,3) map (j => (3,j))は (3,1),(3,2)
i=4               List.range(1,4) map (j => (4,j)) は (4,1),(4,2),(4,3)
これらがflatmapで連結されて、List((2,1),(3,1),(3,2),(4,1),(4,2),(4,3))
となるようだ。



2014年11月28日金曜日

scalaスケールプログラミング P293

挿入ソートのプログラムが出ていた。挿入ソートのアルゴリズムも、昔見たような記憶もあるが、もう忘れている。少し整理して考えてみた。

def isort(xs: List[Int]):List[Int] =
 if(xs.isEmpty) Nil
 else insert(xs.head,isort(xs.tail))
def insert(x:Int,xs;List[Int]):List[Int] =
 if(xs.isEmpty || x <= xs.head)x::xs
else xs.head::insert(x,xs.tail)

isort(List())=Nil
isort(List(1))=insert(1,isort(List()))=insert(1,Nil)=List(1,Nil)

isort(List(2,1))=insert(2,isort(List(1)))=insert(2,List(1,Nil))=1::insert(2,Nil)=1::List(2,Nil)
=List(1,2,Nil)

isort(List(3,2,1))=insert(3,isort(List(2,1))=insert(3,List(1,2,Nil))=1::insert(3,List(2,Nil))
        ①          ②
=1::2::insert(3,Nil)=1::2::List(3,Nil)=List(1,2,3,Nil)

①isortはinsertで表せる。②insertの中のisortは最終的にソートされたListになっているが、
これに、③insertが再帰で適用されて、ソートされたListの適切な位置に挿入されれば、終了となる。 ということのようだ。

2014年11月26日水曜日

scalaスケーラブルプログラミング P287

数式整形クラスの説明が最後にあった

case BinOp(op,left,right) => 
 val opRec =precedens(op)
 val l= format(left,opPrec)
 val r=format(right,opPrec+1)
 val oper =l beside elem(" "+op" ") beside r
 if (enclPrec <= opPrec) oper
 else elem("(") beside oper beside elem(")")

BinOp(”-”、Var("a"),BinOp("-",Var("b"),Var("c")))
がa-(b-c)となる。

rのほうはopPrec+1となっている理由が説明されているが、ちょっとみただけではわからない。
そこで、例によって丁寧にゆっくりたどってみると。。。

l=format(Val("a"),5) r=format(BinOp("-",Var("b"),Var("c")),5+1)
となる

BinOp("-",Var("b"),Var("c"))は
l=format(Val("b"),5)  r=format(Val("c"),5+1)
Oper= b -c
enclPrec=5+1 opPrec=5なので
elseのほうになり、(b-c)
確かにそうなることが確認はできる。。でも、なんかすっきりしない。

左側は当然優先だから、+1しなくてもいいけど、右側は優先したいとき、はっきりわかるように+1とするという とらえ方でいいのだろうか?

2014年11月25日火曜日

Wake ON LAN

マジックパケットをVB.netで送るソフトを
http://vbdotnetmsde.sblo.jp/article/4109822.html
を参考にして作ってみた。


Button1を設定データ保存するときクリック
Timer1 StatusStrip1 を使う
項目名の最後に*をつけたものについては、ソフト起動時にmagicパケットを送るようにしています。
imaxを10として、10台のPCまで登録できるようにした。
imaxを増やせば、何台までも設定できる。


*****************
Public Class Form1
    Private testButtons As System.Windows.Forms.Button()
    Private macad As System.Windows.Forms.TextBox()
    Private komoku As System.Windows.Forms.TextBox()
    Dim scount As Integer
    Dim imax As Integer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        imax = 10
        Dim i As Integer
        Me.testButtons = New System.Windows.Forms.Button(imax) {}
        Me.macad = New System.Windows.Forms.TextBox(imax) {}
        Me.komoku = New System.Windows.Forms.TextBox(imax) {}
        Dim txt, stxt() As String
        Try
            txt = My.Computer.FileSystem.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory + "config.dat")
        Catch ex As Exception
            txt = ""
        End Try
        For i = 0 To imax - 1
            Me.testButtons(i) = New System.Windows.Forms.Button
            'プロパティ設定
            Me.testButtons(i).Name = (i).ToString()
            Me.testButtons(i).Text = "起動" + (i).ToString()
            Me.testButtons(i).Size = New System.Drawing.Size(50, 25)
            Me.testButtons(i).Location = New Point(20, 40 + i * 30)
            'イベントハンドラに関連付け
            Me.Controls.Add(Me.testButtons(i))
            AddHandler Me.testButtons(i).Click, AddressOf Me.testButtons_Click
            '項目名
            Me.komoku(i) = New System.Windows.Forms.TextBox()
            Me.komoku(i).Name = "00" + (i).ToString()
            Me.komoku(i).Size = New System.Drawing.Size(200, 15)
            Me.komoku(i).Location = New Point(100, 40 + i * 30)
            'Me.komoku(i).Visible = True
            Me.Controls.Add(Me.komoku(i))
            'mac address()
            Me.macad(i) = New System.Windows.Forms.TextBox()
            Me.macad(i).Name = "0" + (i).ToString()
            Me.macad(i).Size = New System.Drawing.Size(110, 15)
            Me.macad(i).Location = New Point(320, 40 + i * 30)
            Me.macad(i).Visible = True
            Me.Controls.Add(Me.macad(i))
            If txt <> "" Then
                stxt = txt.Split(",")
                Me.komoku(i).Text = stxt(2 * i)
                Me.macad(i).Text = stxt(2 * i + 1)
            Else
                Me.komoku(i).Text = "None"
                Me.macad(i).Text = "None"
            End If
            Try
                macad(i).Text = My.Computer.FileSystem.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory + Str(i).Trim + ".txt")
                komoku(i).Text = My.Computer.FileSystem.ReadAllText(System.AppDomain.CurrentDomain.BaseDirectory + Str(i).Trim + ".txk")
            Catch ex As Exception
            End Try
        Next i
        For i = 0 To imax - 1
            If Microsoft.VisualBasic.Right(komoku(i).Text, 1) = "*" Then
                magic(i)
            End If
        Next
        Timer1.Enabled = True
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim txt As String
        txt = ""
        For i = 0 To imax - 2
            txt = txt + komoku(i).Text.Trim + "," + macad(i).Text.Trim + ","
        Next
        txt = txt + komoku(imax - 1).Text.Trim + "," + macad(imax - 1).Text.Trim
        My.Computer.FileSystem.WriteAllText(System.AppDomain.CurrentDomain.BaseDirectory + "config.dat", txt, False)
    End Sub
    Private Sub testButtons_Click(ByVal sender As Object, ByVal e As EventArgs)
        Dim num As Integer
        num = Val(CType(sender, System.Windows.Forms.Button).Name)
        magic(num)
    End Sub
    Private Sub magic(ByVal num As Integer)
        Dim sMac As String
        Dim btPacket() As Byte = New Byte(17 * 6 - 1) {}
        Dim sMacArray(5) As String
        Dim btMac(5) As Byte
        Dim iCounter As Integer
        Dim iMacCounter As Integer
        Dim objeClient As New System.Net.Sockets.UdpClient()
        sMac = macad(num).Text
        sMacArray(0) = sMac.Substring(0, 2)
        sMacArray(1) = sMac.Substring(2, 2)
        sMacArray(2) = sMac.Substring(4, 2)
        sMacArray(3) = sMac.Substring(6, 2)
        sMacArray(4) = sMac.Substring(8, 2)
        sMacArray(5) = sMac.Substring(10, 2)
        For iCounter = 0 To 5
            btMac(iCounter) = Long.Parse(sMacArray(iCounter), Globalization.NumberStyles.HexNumber)
        Next
        For iCounter = 0 To 5
            btPacket(iCounter) = &HFF
        Next
        For iCounter = 1 To 16
            For iMacCounter = 0 To 5
                btPacket(iCounter * 6 + iMacCounter) = btMac(iMacCounter)
            Next
        Next
        objeClient.Connect(Net.IPAddress.Broadcast, 40000)
        objeClient.Send(btPacket, btPacket.Length)
    End Sub
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        scount = scount + 1
        ToolStripStatusLabel1.Text = "終了までの秒数:" + (30 - scount).ToString + "sec"
        If scount >= 30 Then
            End
        End If
    End Sub
End Class

2014年11月23日日曜日

scalaスケーラブルプログラミング

関数型のプログラミングということで、Haskellの本を読んだついでに
scalaの本も読んでみた。機能豊富で、なかなか本を読むのも大変。。

10章で2Dレイアウトライブラリーなるものを構成し、最後に
P.203で、螺旋模様をつくるプログラムがでていた。
何の説明もないので、最初は見ても良く分からなかったが
ネットでの説明なども参考にしながら何とか解決。

import Element.elem
object Spiral {
  val space = elem(" ")
  val corner = elem("+")
  def spiral(nEdges:Int, direction: Int):Element = {
    if(nEdges == 1) elem("+")
    else{
      val sp = spiral(nEdges -1, (direction + 3) % 4)
      def verticalBar = elem('|', 1, sp.height)
      def horizontalBar = elem('-', sp.width, 1)

      if(direction == 0)
        (corner beside horizontalBar) above (sp beside space)
      else if(direction == 1)
        (sp above space) beside (corner above verticalBar)
      else if(direction == 2)
        (space beside sp) above (horizontalBar beside corner)
      else
        (verticalBar above corner) beside (space above sp)
    }
  }
  def main(args:Array[String]) {
    val nSides = args(0).toInt
    println(spiral(nSides, 0))
  }
}
 (direction + 3) % 4のところで、directionは最初0でその後、3,2,1,0,,,を繰り返すことで
上辺、左辺、下辺、右辺をつなげていく動作をしているようだ。
spの中身は再帰的になっているので、spの中に内側の螺旋があり、その中にまた内側の螺旋があり、、を繰り返すということになるようです。

2014年11月22日土曜日

OricoからのcsvデータとMoneyからのエクスポートデータを比較するソフト

OricoからのデータをMoneyへ取り込めなくはないようですが、Moneyを使って自分が把握しているもの以外の請求がないか、確認するために使っています。クレジットを使うのも神経を使う必要はありそうです。不正使用や、誤入力ということも絶対無いとはいえませんので。。。


Vb.net 2012を使ったソフトです。OricoからのcsvデータとMoneyからのエクスポートデータを比較する機能をもたせています。

今まで、手作業で、一致するか確認していたのが、時間短縮なりそうです。
一致したデータは、別のtextboxに移動させるようにしています。


Public Class Form1
    '実行ファイルまたはそのショートカットに、2つのcsvファイル(MoneyからのエクスポートデータとOricoからのcsvデータ)を一緒にドラッグ&ドロップすると、起動して使用できる。

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim files As String() = System.Environment.GetCommandLineArgs()
        If files.Length > 1 Then
            TextBox1.Text = "" : TextBox2.Text = ""
            TextBox1.Text = files(1)
            TextBox2.Text = files(2)
            Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("shift_jis")
            TextBox4.Text = trim(My.Computer.FileSystem.ReadAllText(TextBox1.Text, enc))
            TextBox5.Text = trim(My.Computer.FileSystem.ReadAllText(TextBox2.Text, enc))
        Else
        End If
    End Sub

    Private Function trim(st As String) As String
        Dim tmp() As String
        trim = ""
        tmp = st.Split(vbCrLf)
        Dim sst(), a, b, c, d, e As String
        For i = 0 To tmp.Length - 1
            e = ""
            Try
                sst = tmp(i).Split(",")
                a = sst(0) : b = sst(1) : e = (sst(8) + sst(9)).Replace("\", "").Replace("""", "")
            Catch ex As Exception
                'もういっぽうのエクセルデータならよめるはず
                Try
                    sst = tmp(i).Split(",")
                    b = sst(1) : c = sst(2) : d = sst(4).Replace(".0000", "").Replace("-", "")
                Catch ex2 As Exception
                    Continue For
                End Try

                trim = trim + b + "," + c + "," + d + vbCrLf
                Continue For
            End Try
            trim = trim + a + "," + b + "," + e + vbCrLf
        Next
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim st, tmp1(), tmp2() As String
        st = TextBox4.Text
        tmp1 = st.Split(vbCrLf)
        Dim r1(tmp1.Length) As String
        Dim r1flg(tmp1.Length) As Boolean
        For i = 0 To tmp1.Length - 1
            r1(i) = tmp1(i)
        Next
        st = TextBox5.Text
        tmp2 = st.Split(vbCrLf)
        Dim r2(tmp2.Length) As String
        Dim r2flg(tmp2.Length) As Boolean
        For i = 0 To tmp2.Length - 1
            r2(i) = tmp2(i)
        Next
        Dim tmpx1(), tmpx2() As String
        TextBox3.Text = ""
        For i = 0 To tmp1.Length - 1
            r1flg(i) = True
        Next
        For i = 0 To tmp2.Length - 1
            r2flg(i) = True
        Next
        For i = 0 To tmp1.Length - 1
            For j = 0 To tmp2.Length - 1
                If r1flg(i) = False Or r2flg(j) = False Then
                Else
                    Try
                        tmpx1 = r1(i).Split(",")
                        tmpx2 = r2(j).Split(",")
                        ' MsgBox(tmpx1(2) + "?" + tmpx2(2))
                        If Val(tmpx1(2)) = Val(tmpx2(2)) Then
                            Dim reps As New String(" "c, 6 - tmpx1(2).Length)
                            TextBox3.Text = TextBox3.Text + reps + tmpx1(2) + "  <-" + tmpx1(0) + "_" + tmpx1(1) + "=" + tmpx2(0) + "_" + tmpx2(1) + vbCrLf
                            r1flg(i) = False : r2flg(j) = False
                        End If
                    Catch ex As Exception
                    End Try
                End If
            Next
        Next
        TextBox4.Text = ""
        For i = 0 To tmp1.Length - 1
            If r1flg(i) = True Then
                TextBox4.Text = TextBox4.Text + r1(i) + vbCrLf
            End If
        Next
        TextBox5.Text = ""
        For i = 0 To tmp2.Length - 1
            If r2flg(i) = True Then
                TextBox5.Text = TextBox5.Text + r2(i) + vbCrLf
            End If
        Next
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
'sortingの機能
        Dim st, tmp1(), tmp As String
        st = TextBox3.Text
        tmp1 = st.Split(vbCrLf)
        Dim r1(tmp1.Length) As String
        For i = 0 To tmp1.Length - 1
            r1(i) = tmp1(i)
        Next
        For i = 0 To tmp1.Length - 1
            For j = i + 1 To tmp1.Length
                If r1(i) > r1(j) Then
                    tmp = r1(i)
                    r1(i) = r1(j)
                    r1(j) = tmp
                End If
            Next
        Next
        TextBox3.Text = ""
        For i = 0 To tmp1.Length - 1
            TextBox3.Text = TextBox3.Text + r1(i) + vbCrLf
        Next
    End Sub
End Class

ネットにアクセスして正規表現を駆使してデータを取り込みつつ、自分の入力したデータを比較できるような家計簿ソフトであればさらに効率的なんですが。

Qtを試してみる

Qt Creater3.1.2を チュートリアルを見ながら試してみた。
チュートリアルの通り、コーディングしてもエラーが発生する。
どうやら、dllは、手動で入れてやる必要があるようだ。
エラーメッセージにしたがって、Windows用のDllを入れてみたところ動作した。
Android,Linux,Macなど様々なOSで動かせるというのがいい。
.netと使い方が似ているところもある。イベントトリガーとイベントハンドラの関係を シグナルとスロットというらしい? それらの接続もしやすいようになっているし、随所に使いやすい工夫がされている。
ただ大変なのは、最新の情報がほとんど英語ということのようだ。

2014年11月20日木曜日

Windows Updateができなくなったパソコン

職場のPCが、突然Windows Updateができなくなって、困ってしまった。
「現在サービスが実行されていないため、Windows Update で更新プログラムを確認できません。
このコンピューターの再起動が必要な可能性があります。」
こんな表示がでる。

例によって、ネットで調べたが、コントロールパネルのサービスで、Windows Updateのサービスを開始するとよいということなので、確かめてみたが、すでに起動している。

Fix itを使ってみるといいという情報もあったので、やってみたが、復旧しない。

スクリプトを作成し、バッチファイルで、コマンドを実行する方法も試したがうまくいかない。

さて、どうしたものかと、あれこれ試行錯誤して、1時間ぐらい粘ったがどうしてもうまくいかない。
あきらめかけて、再インストールかと思ったが、念のため、もう一度、ネットで調べたら
新しい情報を見つける。
http://alphafocus.cocolog-nifty.com/blog/2012/05/tips-windowsupd.html
これも、スクリプトを作成して、実行する方法だったが、こちらの方の方法でやったところうまくいった。

マイクロソフトでぜひ把握してもらって、Fix itに組み入れてもらうと多くの人が助かるかもしれません。

2014年10月17日金曜日

accessのテーブルリンクをモジュールで変更する方法(覚え書き)

ネットの情報を参考に、accessのテーブルリンクをモジュールを使って
変更する方法を考えてみた


Sub HenkoLink(path, tbname)
Dim db As DAO.Database, tb As DAO.TableDef
    Set db = CurrentDb
    Set tb = db.TableDefs(tbname)
    tb.Connect = ";DATABASE=" + path + ";TABLE=" + tbname + ";pwd=****"
    tb.RefreshLink
End Sub

Sub LinkHenkoMacro()
pathd = InputBox("path=\\***\")

'テーブル数が多いときは配列で
Dim tbname(15), dm As String
tbname(1) = "テーブル1"
tbname(2) = "テーブル2"
tbname(3) = "テーブル3"

For i = 1 To 3
 Call HenkoLink(pathd + "test1.mdb", tbname(i))
Next i

'配列使わず、ひとつずつやるなら
Call HenkoLink(pathd + "test2.mdb", "テーブル4")


End Sub


2014年10月6日月曜日

プログラミングHaskell P143 exprs関数について

P143 exprs関数の適用についても、少しくわしく考えてみた。
(途中の式表現は、正しい表現と言えないところもありかも...)

exprs ::[Int]->[Expr]
exprs [] = []
exprs [n]=[Val n]
exprs ns = [e | (ls,rs) <-split ns,  l  <- exprs ls,  r  <- exprs rs,    e <- combine l r ]

combine :: Expr -> Expr -> [Expr]
combine l r = [App o l r | o<- ops]

ops  :: [Op]
ops =[Add,Sub,Mul,Div]

exprs [1,2,3]=[e| (ls,rs) <-split [1,2,3],  l  <- exprs ls,  r  <- exprs rs, e <- combine l r ]
  (ls,rs) <-split [1,2,3]は、次の2とおり
([1],[2,3])           ([1,2],[3])
ひとつめで l  <- exprs ls,  r  <- exprs rs,  e <- combine l r を考えて
  exprs ls=exprs [1]=[Val 1]  
exprs rs=exprs [2,3]= [e | (ls,rs) <-split [2,3],  l  <- exprs ls,  r  <- exprs rs,    e <- combine l r ]
= [e |([2,],[3]),  l  <- exprs [2],  r  <- exprs [3],    e <- combine l r ]
= [e |([2,],[3]), [Val 2], [Val 3],    e <- combine [Val 2] [Val3] ]
=[App Add (Val2) (Val3),App Sub …..4種類の演算]

[Val 1]と[App Add (Val2) (Val3),App Sub …..4種類の演算]についても4種類の演算がある

ふたつめも同様に可能

こんな感じで、すべての演算を表せそうだ。

プログラミングHaskell P142 split関数

プログラミングHaskell 読んでみた。 P142でsplit関数の適用がよくわからなかったので
自分なりに、丁寧にたどってみた。

split  :: [a]->[([a],[a])]
split[] =[]
split[_]=[]
split (x:xs) = ([x],xs) : [(x : ls , rs) | ( ls , rs ) <- split xs]

split [4]=[]

split [3,4]= ([3],[4]): [(3 : ls , rs) | ( ls , rs ) <- split [4]]
         =([3],[4]): [(3: ls , rs) | ( ls , rs ) <- []] = ([3],[4])
split [2,3,4]=([2],[3,4]): [(2 : ls , rs) | ( ls , rs ) <- ([3],[4]) ]
          ==([2],[3,4]): [(2 :[3] ,[4]) ]= [([2],[3,4]),([2,3] ,[4]) ]
split [1,2,3,4]
=([1],[2,3,4]):[(1:ls,rs) | (ls,rs)<- [([2],[3,4]),([2,3] ,[4]) ] ]
=([1],[2,3,4]):[(1:[2],[3,4]),(1:[2,3],[4])]
=([1],[2,3,4]):[[1,2],[3,4]),([1,2,3],[4])]

という感じでいいのだろうか

2014年9月19日金曜日

32bitWindowsにfessをインストールするときは要注意

全文検索を使ってみようと調べたらfessが、使いやすい感じがして、試してみた。(以前はnamazuなどがあったが)
PCに負荷がかかりそうなので、古いPCを使っているLinuxはやめにして、新しいPC(といっても32bitだが)のWin7でやってみた。
ところが、なかなかうまくいかない。
・最新版fessでやってみたが、うまく動作しない。ちょっと古い9.0.2だとうまくいった。標準では、Dosプロンプト画面を表示しっぱなしでないと、サーバーとして動作してくれない。いちおう、端末としても使うPCなので、Windowsのサービスとして登録し、Dos画面は出ないようにした。
最初は、うまくいかない。service.bat installなるコマンドが拒否される。コマンドプロンプトを管理者として実行する。それでも、だめ、原因は、tomcat7.exeが64bit版だかららしい。32bit版のtomcatからtomcat7.exe、tomcat7w.exeをもってきて、上書きしたら動いた。
 localhostとして、アクセスはできたが、他のPCからアクセスできない。ファイアウォールだろうと思って、設定を追加。受信規則に8080ポートを許可とする。これで、やっとうまくいった。
*********
その後、うまくいったと思ったが、どうも、クロールがうまくいかない。思い切ってfessをver4に落としてみたらうまくいった。tomcatの組み合わせがうまくいってないのだろうかどうか?詳細は不明。
**************
その後、また不具合が発生する。ループリダイレクトとのこと。よくわからないので、今度は、もう一度ver9.0.2を試す。tomcat7.exe tomcat7w.exeは32bit版である。今回は、なぜか、クロールができた。はたして、このまま安定運用できるか。
***********************
とりあえず、今のところ安定して稼働している。

fessはTomcatで動いているので、WindowsでTomcatを使う方法を、このセットアップを通して知ることができた。
ポイントは、JAVA_HOMEとJRE_HOMEの環境変数を変更して再起動すること。
startup.batでtimcatが起動すること。他はLinuxとだいたい同じかも。

******************
fess稼働して数ヶ月 なんとか動いていたが、Win7の端末で動かしていたので、さすがに無理があったようだ。端末として使うと、どうしても負荷があるため、通常のソフトが遅くなる。ということで、使用はやめにした。専用のサーバでないときついようだ。残念ながら、メモリ、HDD、CPUそれぞれかなり余裕のあるPCでないと難しいようだ。

2014年8月14日木曜日

coq-hurry P10 練習問題

10ページの練習問題2問をやってみる
1問目 Exercise on sorting
 Define a function that takes a list as input and returns true when it has less than 2 elements or when the first element is smaller than or equal to the second one. Then define a function that takes a list as input and returns true exactly when this list is sorted.
 入力としてリストをとる関数を定義し、戻り値はリストの要素が2未満か最初の要素が2番目の要素以下のときTrueとなる関数を定義せよ。それからリストが完全にソート済みならTrueとなる関数を定義せよ。

最初、なかなかうまくいかない。
Fixpoint check_fs2 l := match l with nil => true | a::nil => true | a1::a2::tl => if leb a1 a2 then check_fs2 (a2::tl) else false end.
このように一つの関数でできそうな気がしたが、なぜかエラーとなる。まだ、coqの使い方が
よくわかっていない。

こういうときは、少し時間を置くことにしている。しばらくして、再挑戦したらできた。
問題で説明しているように、2つの関数でやってみた。最初の関数は、2つの要素の比較だけ行い、再帰はさせないようにした。もうひとつの関数で再帰を使ったらうまくいった。
もう少しスマートな方法がありそうだが、、、、。

Fixpoint check_fs l := match l with nil => true | a::nil => true | a1::a2::tl => if leb a1 a2 then true else false end.
Fixpoint check_sort l := match l with nil => true | a::tl => if check_fs (a::tl) then check_sort tl else false end.
これで、なんとかうまくいった。

2問目 Exercise on counting
 Knowing that the Coq system provides a function beq_nat to compare two natural numbers,
define a function count_list that takes a natural number and a list and returns the nubmer of times the natural number occurs in the list.

これについては
Fixpoint count_list n l s:= match l with nil => s | a::tl => if beq_nat n a then count_list n tl s+1 else count_list n tl s end.
としてみた。ただ、3つめの引数はムダなので、できればなくしたい。
その方法がよくわからない。

ネットで検索するとすでに、解答されている方がいた。
Fixpoint count_list2 n l:= match l with nil => 0 | a::tl => if beq_nat n a then 1+count_list2 n tl else count_list2 n tl  end.
これでいいようだ。
 nil=>0のところを、nil=>sにしようとこだわりすぎたようだ。自身の戻り値に1をたすならば、戻り値に1が累積されていくということに気づかなかった。自分が考えた引数に1をたしていくやり方だと、最後の関数で表示せざるをえないので、nil=>sとなり、スマートな方法とはいえない。




2014年8月2日土曜日

今年は、豊作

 畑を借りているが、今年は思い切ってトマト15株植えた。雨が少ないため、豊作。食べきれないほどとれる。買えば1個100円近くするので、もとがとれたか。
 カラスの害が心配で、ネットをかぶせたのもよかったかも。。
 手入れは、最低限のわき芽とり、サンボルドーによる消毒ぐらいか。

 ナスは7株。ゴーヤ、つるなしいんげんなども1畝ずつ。きゅうりは、1株で十分だ。
 防草シートを使っているが、除草は はっきりいって、かなり手抜きしている。

 

2014年7月11日金曜日

sambaでワード、エクセルが読み取り専用になる不具合

 sambaをちょっと特殊な使い方をしている。それぞれの共有フォルダにユーザーを割り当てて、パスワードがないとアクセスできないようにしているが、それと同時に、hosts allowを使って、特定のIPアドレスのクライアントからもアクセスできるようにしている。(同一フォルダを別名の共有フォルダとして)
 結果的に、これがよくなかったらしく、ときどき、別の人が作成したファイルを開けない現象が発生した。なぜか、最初は原因がつかめなかったけれど、要するに、さまざまなユーザーのファイルができるため、アクセス権限が一致しないことが原因のようだった。
force create mode
force directory mode
でなんとか、その場をしのいだ。
 でも、それでもまだ似たような現象が発生した。ls -llで確認すると、どうやら+の記号がついてる(aclが設定されてしまっている)とそうなるということが判明。。そうならないためには、
nt acl support = no
を付け加える必要があったようだ。これで、しばらく様子を見てみよう。 それから、
setfacl -R -b /ディレクトリ名
として、aclを削除しておくことも必要なようだ。

*********************
上記の方法で解決したと思ったものの、まだ、読み取り専用になる現象が発生する。
いろいろ調べると、可能性のあることとして、

dos filetimes = Yes
dos filetime resolution = Yes
の設定を追加したほうがいいらしいこと。

エクスプローラの[整理] > [レイアウト] > [詳細ウィンドウ]と[プレビューウィンドウ]のチェックを外したほうがいいらしいこと

*****************
これでも、まだ だめ?なようなので、さらに調べると
oplocks = No
blocking locks = No
の記述をしたほうがいいという情報もあったので、試してみた。

今のところ、読み取り専用になる現象は発生してないようだ。

2014年7月6日日曜日

mdbファイルの破損

 マイクロソフトaccessのmdbファイルが壊れた。よくあることで、これまでは、最適化で、ほとんど修正できていましたが、今回は手こずりました。
 テーブル(auto incrementのインデックス有)のところどころの行がなぜか、表示されたりされなかったりしました。そのため、mdbファイルを操作しているクライアントソフトも、一部動作しません。欠番の行に挿入はできない仕様のようです。
 結局、いったんデータをエクセルにエクスポートしてから、全レコードを削除し、エクセルデータから再度、インポートしたところ、うまく復活できました。
 なぜこういうことになったか、原因はわかりませんが、やはり、データベースはMysqlとか、実績のあるものに、変えていく必要があるのかもしれません。

2014年6月25日水曜日

javaで、renameToを使うとき気を付けること

renameToを使ってServletを作っていた時のことです。
windowsでは、うまくファイルの移動ができていたのに、
Linuxで動かしたら、うまくいかないという現象に悩まされました。
権限の問題?だろうかといろいろ試行錯誤しても、結局うまくいかず。
例によってネットの情報を探していたら解決策がありました。

http://kaede.jp/2014/04/05170305.html
この情報で救われました。
moveFileだと、Linuxでもだいじょうぶであることが判明。
なんとか解決しました。
Javaもなかなか難しいものです。

wdCalendarを試してみた

GoogleカレンダーのクローンタイプのソフトでwdCalendarというものがあったので
試してみた。認証も不要で、施設、備品貸し出し簿などに使うと便利そうである。

こちらのリンクがとても参考になりました。
http://web.chaperone.jp/w/index.php?jQuery%2FwdCalendar
ただ、若干、手直しが必要でした。

apache2のerror.logを参考に、
dbconfig.phpの11行目で :を;に修正
また、mysqlで使うために mysqlの設定に書き換えました。(コメントを参照すればOk)
そして、これでOkかと思いきや、、削除ができません。
なかなか、原因がつかめずにいましたが、、
どうやら、function removeCalendar という関数の中のDeleteのためのqueryの記述が
なぜか違っていたようです。

function removeCalendar($id){
  $ret = array();
  try{
    $db = new DBConnection();
    $dbh= $db->getConnection();
    $sql = "delete from ".$db->getTbl()." where `id`=" . $id;
       if(mysql_query($sql)==false){→これを→   if($dbh->query($sql)==false){
    と直したらうまくいきました。




2014年6月21日土曜日

cokkie 全角を扱うには

Javaで全角のクッキーを扱うには少し手間がかかる。

servletでも、JSPでも
 request.setCharacterEncoding("UTF-8");を入れないとだめだようだ。

あとは
Cookie cookie = new Cookie("filtermoji",URLEncoder.encode(filtermoji, "UTF-8"));
といった感じだ。


デコードは
 sfiltermoji = URLDecoder.decode(filtermoji.getValue(),"UTF-8");
となる




eclipseの使い方

eclipseの使い方になかなか慣れない。

他環境で開発したものを配備すると、その都度
ライブラリの参照として、tomcatのライブラリ(外部jarの追加で)、独自のライブラリ(jarの追加)、JREなど追加必要なようだ。
コンパイラの設定で、JDKのバージョン変更すると、再度 すべて ビルドしなおすようだ。

また、JAVAのビルドパスの確認も必要。(ソースのフォルダと出力フォルダの設定など)
これらがきちんと設定なっているか確認が必要なようだ。

また、tomcatのホームもきちんとなっているか、確認が必要。
ウインドウ>設定>Tomcatで確認できる。これが、実際にソースやコンパイル済みの
ものがあるところと同じ所を指定してないと、ソースを変更しても、反映されないという
変なことになってしまう。


たぶんもっと簡単にやる方法があるのだろうが、、、。

2014年6月14日土曜日

sqlite3のインストールできない>やっと解決

 sqlite3 --versionとすると

SQLite header and source version mismatch
が表示される。
いろいろ調べてみるが、なかなか解決できない。


ようやく参考サイトを見つけた。
http://www.railstation.eu/blog/artikel/compiling-sqlite-on-ubuntu

それによると
 find /usr/lib/i386-linux-gnu -name 'libsqlite3.so.*'
とすると、
/usr/lib/i386-linux-gnu/libsqlite3.so.0
/usr/lib/i386-linux-gnu/libsqlite3.so.0.8.6
が表示される。
すでにあるものがじゃましているらしい。

/usr/localの中にインストールしているので、それを使う必要がある。
そこで、古いものを削除して、シンボリックをはるといいようだ。
> rm $( find /usr/lib/i386-linux-gnu/ -name 'libsqlite3.so.*' )
> ln -s /usr/local/lib/libsqlite3.so.0.8.6 /usr/lib/i386-linux-gnu/libsqlite3.so.0

※PCのエラーに関しては、あきらめず、情報を探すと誰かがアップしてくれているものです。感謝!ただし、国内だけとは限らないので、改めて、もう少し英語力をつけておけば、、と感じる今日この頃。

2014年6月13日金曜日

tomcatのデプロイの失敗

 サーバーにtomcatのアプリケーションマネージャーを使っても、うまくデプロイできない現象が起こりました。これで、かなりはまってしまいました。ログファイルをチェックして、サイトで調べました。
 どうやら、javaのバージョンが、開発環境と、サーバー環境で一致しないとそういうことが起こることらしいと言うのはわかってきたのですが、試しに、サーバのjavaのバージョンを上げてもうまくいかないので、どうしたものかと、、。
 結局、eclipseのWindow>設定>java>コンパイラーで、1.6にしたらうまくいったようです。たまたま、WIN8で、1.7のもので、コンパイルしたものが、残っていたのが原因だったようです。
 これに気づくのに4日間くらいかかってしまいました。

2014年4月28日月曜日

HFコンバータキットの製作

TT@北海道さんが設計し頒布されているHFコンバータキットを作ってみました。

HFコンバータキットの頒布元
http://ttrftech.tumblr.com/kit/hfconv

 HFコンバータキットが届いてから、すでに3ヶ月以上たっていますが、組み立てへの取りかかりが遅く、また、へたな半田付けでうまくいかず、今日になってようやくうまく動作させることができました。
 TT@北海道さんからは、部品の追加やら、質問をさせていただいたりと、本当にお世話になりました。良心的な値段でありながら、いろいろサポートしていただきありがたかったです。

○準備物
 テスター、半田ごて(30W)、半田、ピンセット、フラックス、ルーペ&老眼鏡
 ルーペは100均で買ったスタンドつきのものです。あまり倍率は大きくないですが、老眼鏡と併用してなんとか頑張りました。できれば、倍率が高いもののほうが、半田付けの不具合発見にはよかったかもしれません。
 最初は、空気で吸い取る半田吸い取り器も使っていましたが、部品がどこへいったか分からなくなるようでした。そこで、それはやめにして、オーソドックスにハンダ吸い取り線を使うことにしました。
テスターは、私が中学生の頃に買ったもので、すでに ん十年が経過したものです。
上方に見えるのがAMラジオ受信のために使ったループアンテナ
(古いコンポについてきたもの)です。
○製作
 説明書にしたがって、部品を取り付けていきました。YouTubeなどで、SMDの半田付けのコツを見てから取りかかりましたが、けっこう手こずりました。部品はピンセットではさむだけでは、動いてしまうので、きちんと押さえながらハンダをつけないとならないようです。
 写真でお見せするのが恥ずかしい半田付けですが、下の写真ができあがったものです。一度でうまく動作しなかったのですが、TT@北海道さんから、コツをお聞きしたりしたおかげで、なんとか、完成することができました。



 リレーも取り付けて、電源ONのときは、AMラジオのアンテナに、OFFのときは、FMアンテナのほうに切り替わるようにしています。HF帯のアンテナでも用意できれば、アマチュア無線のワッチもしてみたいところですが。残念ながら、ん十年前に、HFアンテナはすべて売り払ってしまって、ありません。
 ソフトはSDR#を使い、Raspberry Pi をラジオサーバとして使っています。RaspberryPiをWebから操作して、リモートでコンバータの電源のON OFFできればおもしろいかな とも思っています。



 表面実装、SDRなど、いずれも初めての経験で 難しいものだと思いましたが、それだけにうまくできたときの達成感は大きいものです。こういったすばらしいキットを提供してくださったTT@北海道さんに感謝申し上げます。



2014年4月19日土曜日

Tomcat 全角ファイル名のダウンロード

tomcatで、jsp等で、ファイル名が全角の場合、ダウンロードがうまくいかないときがあり、原因が分からずにいたが、ネット上で、情報を見つける。どうやら、tomcatにcharsetを伝える必要があるらしい。
 srver.xmlのConnectorの要素にURIEncoding="UTF-8"を追加するとみごとに解決した。
  <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" />

2014年4月12日土曜日

Linux USB HDDの接続について(覚え書き)

このところ、UbuntuなどにUSBのHDDを接続したり、内蔵HDDを交換したりという機会が多い。
そのつど、サイトで検索してやり方を調べている。
概略は次の手順が必要なようだ。
すでに何らかのマウントしている状態なら、いったんアンマウントが必要。
PartedといったGUIツールなどが便利なようだ。CUIでやるには、少し面倒かも。。
このツールでフォーマットもできる。
NTFSフォーマットのUSBHDDをそのまま使うことも考えたが、どうも不安を感じてやめた。
その後、blkidでUUIDを取得
そして、sudo /etc/fstabで
UUID=33a99478d28e458f9e625d79a28bdb32 /data ext4 defaults 0 0
などと追加していくようだ

2014年4月6日日曜日

eclipseでtomcatを使う(覚書)

久しぶりに、Javaの開発環境をつくってみた。初心者のため、結構、細かいところでつまづくことが多い。
今後のために、覚書を作成してみた。


0 まずpleiades版 eclipse入手
1 eclipse 日本語を入手する。pleiades_1.4.0.zip これを解凍して、英語版のeclipseに上書き
2 tomcatPluginV33.zipを解凍してcom.sysdeo.eclipse.tomcat_3.3.0を tomcatのpluginフォルダに入れる
2 jdkはjdk-8-windows-i586.exeを使う
3 mysql-installer-community-5.6.17.0.msiでmysqlをインストール
4 mysql-connector-java-gpl-5.1.30.msiでコネクタを入手
5 eclipseにwarファイルを取り込むため、拡張子をwarからjarに変更しておく  
6 apache-tomcat-6.0.39-windows-x86.zipも入手


eclipseの設定
ウインドウ>設定>Tomcat選択 tomcatバージョン選択して、tomcatホームを6で解凍したフォルダに指定

コンテキスト宣言モードはコンテキスト・ファイルを選択して、ディレクトリも指定する。
こうしないと、Tomcat Webアプリケーションマネージャでデプロイ解除(配備解除)ができないようだ。


ウインドウ>パースペクティブのカスタマイズ>ショートカット>Java選択 Tomcatプロジェクトにチェック入れる

ファイル>新規>Tomcatプロジェクタが表示されるようになる これを選択し、プロジェクト名入力
workspaceのフォルダにはすでに作成途中のフォルダを持ってくることも可能

 ファイル>インポート>一般のアーカイブファイル>次へ>5のjarファイルを参照から選択し、宛先を指定して解凍することも可能
※Tomcat Webアプリケーションマネージャで、デプロイ(配備)も可能。その際は.warファイルで指定。


パッケージエクスプローラーで、プロジェクト名を右クリック>プロパティ>ライブラリー>外部jar追加で、4で解凍したライブラリを追加

tomcatボタンが表示されないときは
ウィンドウ>パースペクティブのカスタマイズ>コマンドグループ可用性
使用可能なコマンドグループのTomcatにチェック

2014年3月6日木曜日

sdr# FMのノイズ軽減

 FM放送の受信では、マルチパス?等が原因でノイズがどうしても入りやすい。
sdr#では、受信帯域の位置をずらすとなぜかノイズが軽減できる。
(中心の赤い線をdrag&dropで右か左(どちらがいいかは試す必要あるかも)に少しずらし→再度周波数をFrequency Managerで合わせるとOk)
このへんの理由はよくわからない。

2014年2月27日木曜日

rtl_tcpでoffset tuning

SDR#を使わせていただいている。
rtl_tcpの機能はとても便利である。ただどうしてもノイズが多いようだ。特にraspberry Piを受信サーバにすると、有線LANのノイズらしきものがかなりある。
そこで、offset Tuningが有効なようなので、rtl_tcpでも使えないか調べてみた。rtl_tcpのほうにはその機能があるけれど、クライアント側のsdr#では、その機能は省略されているようだった。
sdr#でもsourceを公開していたので、それをもとに、機能を追加して修正してみた。

修正ポイントとしては、
private const byte CMD_SET_OFFSET_TUNING = 0xa;
というようなコマンドを追加してやるとうまくいった。

チェックボックスをダイアログに追加して
 private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            _owner.OffsetTunig  = checkBox1.Checked;
        }

プロパティとしての追加は
       public bool OffsetTunig
        {
            get { return _offsetTuning; }
            set
            {
                _offsetTuning = value;
                SendCommand(CMD_SET_OFFSET_TUNING, _offsetTuning ? 1 : 0);
            }
        }
という具合に

ノイズの少ない聞きやすいFM音声(ステレオ)になりました。

2014年2月22日土曜日

rtl_tcp自動起動

http://ttrftech.tumblr.com/post/37834957647/raspberry-pi-remote-rtl2832u-sdr-server-and-rtl-tcp
を参考にさせていただいた。
LAN経由で、sdrを試みる。

でも、なぜか、自動起動しない。
sudo update-rc.d -n rtl_tcp start 99 5の最後を2 3 4 5としたら
うまくいきました。

USBワンセグで、SDR

USBワンセグが、SDRに使えると言うことで試してみた。まずはFMラジオを聴くなどして利用している。1000円前後で買えるので、コスパが良い。

SDR#というソフトはソースも公開されているので、VC#2012で、少しカスタマイズ。
rlt_tcpで、LAN経由で聴くのですが、回線が細い場合もあるので、サンプルレートの初期値が最低で起動するようにビルド。

RTLTCPのRTLtcpSettingsで
 samplerateComboBox.SelectedIndex = 3;を9に変更






raspberry PiでGPIOをWEBから操作

GPIOをPHPで操作できないか試してみた。権限の関係でうまくいかない。

とりあえず gpio4on.phpとして
 <?php
var_dump(exec("echo 4 > /sys/class/gpio/export"));
var_dump(exec("echo out > /sys/class/gpio/gpio4/direction"));
exec("echo 1 > /sys/class/gpio/gpio4/value",$arr,$res);
print_r( $arr );
var_dump( $res );

?>
などと試して見るがだめ

そこで、sdrhf.php
<?php
var_dump(exec("sudo php -f gpio4on.php"));
?>
と試してみたらうまくいった。

まだまだ、Linuxは勉強不足。

***************

/etc/sudoersに
www-data ALL = NOPASSWD: /path/to/script.sh
のようにして、特定のスクリプトに実行権限を与える必要も

2014年1月3日金曜日

Raspberry PiでVPNに挑戦4

IPV6のグローバルアドレスは、変更なることがあるので、変更あったとき自動でメール送ってもらうようにした。
ssmtpとインストールして、if-up.dにスクリプトを入れてみた。
ifconfig | grep "inet6" | mail -s "ipv6 change" ****@***.net.jp

その都度、変更の手間はあるが、今のところこれしか思いつかない

2014年1月1日水曜日

Raspberry PiでVPNに挑戦3

ようやくAufsをいれてfsprotectもうまく動くようになったものの、apacheが自動起動しない。
lighttpdを試しても同じ症状。ネットでいろいろ調べても分からない。

/var/logのディレクトリをRAMに作成しており、起動時ごとに作成するようにしていたが、
これがよくなかったようだ。error.logが書けないというエラーメッセージが出たことから
ピンときた。
どうせ、fsprotectが動けば、logも結局はメモリに書き込まれるので、この記述はなしにした。
そうしたら解決した。

それにしても、オープンソースで、しかも省エネのパソコン(安価な)でここまでできるとは、すごいことになってきたものだと思う。


Raspberry PiでVPNに挑戦2

カーネル再構築うまくいったと思ったら、どうもipv6が動作しない。
しばらく原因つかめずにいた。interfacesにも記述しているし、、と、モジュールがロードされているか確認するとよいことに気づく。
まったく、モジュールがないということが判明、どうやら、修正したモジュールの入ったlibディレクトリの本体へのコピーが間違っていた。
cp -r lib / とすべきところを cp -r lib /lib とやってしまったという基本的ミス。

これで、ようやく解決