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に組み入れてもらうと多くの人が助かるかもしれません。