64bit環境で動作させる方法

C++/STL等で作成した外部DLLを参照したプログラムをデバッグする際には注意が必要。アプリケーションのプロパティ設定をいくら変えてもテストプログラムのアーキテクチャを変更しないと、実行時エラーとなりデバッグできない。

上の画像のように、「テスト」−「テスト設定」−「既定のプロセッサアーキテクチャ」から「x64」にチェックを入れる。

画像ファイルを読み込むDLLをデバッグしていたので、MSTestではリソース画像が使えないのかと別のところで悩んで時間を使ってしまった。

※この作業はVisual Studioの起動毎にやる必要があるようである。どこかでデフォルトを設定できるのだろうか…。

ScrollViewerとListBoxが入れ子になった場合のスクロール

ScrollViewrとListBoxが入れ子になっているとき、ListBoxはスクロールバーが表示されていなくても、マウスカーソルの位置によっては親のScrollViewerが動かないことがあります。

これはBubble Eventが子エレメントでハンドルされてしまっていることが原因なので、スクロールイベントScrollChangedのメソッド内でe.Handledをfalseにしてやればいいと思います。(未確認)

これをXAMLで行いたい場合には(DataTemplate内でListBox等を定義している場合はこちらの方法しか使えない)、ScrollViewer.CanContentControl="False"を子エレメントに指定すれば良いようです。

<ScrollViewer>
    <Grid>
        <ListBox ScrollViewer.CanContentScroll="False" ItemsSource="{Binding}">
        </ListBox>
    </Grid>
</ScrollViewer>

Notice: Use of undefined constantをVim置換で修正

PHPの古いコードをみると、配列の引数にkeyをダイレクトに記述しているために

Notice: Use of undefined constant

のエラーが頻発していることがある。

こんなやつ。
http://kforce-ueda.hatenablog.com/entry/2014/01/21/121812


これをVimの置換機能を使って修正する方法。

:%s/\$_GET\[([a-zA-Z0-9_]+)\]/\$_GET\[\'\1\'\]/gc

余計なキャラクタまでエスケープしてるかもしれないが、aptana + vrapper環境だとこれでできた。

doxygenのインストールとDoxyfileの設定

UbuntuDoxygenを使う方法と、普段、Fortranを使う際に使用しているDoxyfileの設定をメモしておこうと思います。

Ubuntuへのインストールはapt-getを使えば簡単。グラフを描画するためのGraphvizも一緒にインストールします。

sudo apt-get install doxygen graphviz

テンプレートは-gオプションを使うと自動生成できる。使うときは、doxygenの後ろにdoxyfileをそのまま指定すればよい。

$ doxygen -g doxyfile

Configuration file `doxyfile' created.

Now edit the configuration file and enter

  doxygen doxyfile

to generate the documentation for your project

Fortran仕様にするためにはいくつかの設定を変更する必要がある。グラフ表示等のオプションをYESにする。

カスタマイズ後のDoxyfileでdiffをとった結果を示す。バージョンが1.7.6と1.8.1で異なるのでオプションが若干異なってしまっている。違いの検討はまた今度。

29c29
< PROJECT_NAME           = "My Project"
---
> PROJECT_NAME           = "Fortran Project"
35c35
< PROJECT_NUMBER         =
---
> PROJECT_NUMBER         = 0.1
64c64
< CREATE_SUBDIRS         = NO
---
> CREATE_SUBDIRS         = YES
154c154
< JAVADOC_AUTOBRIEF      = NO
---
> JAVADOC_AUTOBRIEF      = YES
162c162
< QT_AUTOBRIEF           = NO
---
> QT_AUTOBRIEF           = YES
187c187
< TAB_SIZE               = 8
---
> TAB_SIZE               = 4
223c223
< OPTIMIZE_FOR_FORTRAN   = NO
---
> OPTIMIZE_FOR_FORTRAN   = YES
242a243,251
> # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
> # comments according to the Markdown format, which allows for more readable
> # documentation. See http://daringfireball.net/projects/markdown/ for details.
> # The output of markdown processing is further processed by doxygen, so you
> # can mix doxygen, HTML, and XML commands with Markdown formatting.
> # Disable only in case of backward compatibilities issues.
> 
> MARKDOWN_SUPPORT       = YES
> 
349c358
< EXTRACT_ALL            = NO
---
> EXTRACT_ALL            = YES
354c363,367
< EXTRACT_PRIVATE        = NO
---
> EXTRACT_PRIVATE        = YES
> 
> # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.
> 
> EXTRACT_PACKAGE        = YES
359c372
< EXTRACT_STATIC         = NO
---
> EXTRACT_STATIC         = YES
442c455
< FORCE_LOCAL_INCLUDES   = NO
---
> FORCE_LOCAL_INCLUDES   = YES
543,548d555
< # If the sources in your project are distributed over multiple directories
< # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
< # in the documentation. The default is NO.
< 
< SHOW_DIRECTORIES       = NO
< 
669c676
< FILE_PATTERNS          =
---
> FILE_PATTERNS          = *.f90 *.inc
675c682
< RECURSIVE              = NO
---
> RECURSIVE              = YES
778c785
< SOURCE_BROWSER         = NO
---
> SOURCE_BROWSER         = YES
783c790
< INLINE_SOURCES         = NO
---
> INLINE_SOURCES         = YES
795c802
< REFERENCED_BY_RELATION = NO
---
> REFERENCED_BY_RELATION = YES
801c808
< REFERENCES_RELATION    = NO
---
> REFERENCES_RELATION    = YES
817c824
< USE_HTAGS              = NO
---
> USE_HTAGS              = YES
861c868
< HTML_OUTPUT            = html
---
> HTML_OUTPUT            = docs
937,942d943
< # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
< # files or namespaces will be aligned in HTML using tables. If set to
< # NO a bullet list will be used.
< 
< HTML_ALIGN_MEMBERS     = YES
< 
950a950,960
> # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
> # entries shown in the various tree structured indices initially; the user
> # can expand and collapse entries dynamically later on. Doxygen will expand
> # the tree to such a level that at most the specified number of entries are
> # visible (unless a fully collapsed tree already exceeds this amount).
> # So setting the number of entries 1 will produce a full collapsed tree by
> # default. 0 is a special value representing an infinite number of entries
> # and will result in a full expanded tree by default.
> 
> HTML_INDEX_NUM_ENTRIES = 100
> 
1120c1130
< GENERATE_TREEVIEW      = NO
---
> GENERATE_TREEVIEW      = YES
1129,1133d1138
< # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
< # and Class Hierarchy pages using a tree view instead of an ordered list.
< 
< USE_INLINE_TREES       = NO
< 
1179c1185
< MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
---
> MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
1213c1219
< GENERATE_LATEX         = YES
---
> GENERATE_LATEX         = NO
1472c1478
< MACRO_EXPANSION        = NO
---
> MACRO_EXPANSION        = YES
1600c1602
< HAVE_DOT               = NO
---
> HAVE_DOT               = YES
1654a1657,1665
> # If the UML_LOOK tag is enabled, the fields and methods are shown inside
> # the class node. If there are many fields or methods and many nodes the
> # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
> # threshold limits the number of items for each type to make the size more
> # managable. Set this to 0 for no limit. Note that the threshold may be
> # exceeded by 50% before the limit is enforced.
> 
> UML_LIMIT_NUM_FIELDS   = 10
> 
1680c1691
< CALL_GRAPH             = NO
---
> CALL_GRAPH             = YES
1688c1699
< CALLER_GRAPH           = NO
---
> CALLER_GRAPH           = YES
1769c1780
< DOT_MULTI_TARGETS      = YES
---
> DOT_MULTI_TARGETS      = NO

日付やシステム時間の取得方法

Fortran90以降の機能です。
忘れやすいので例によってサンプルプログラムにまとめました。

日付の取得にはdate_and_time関数を使用します。

program main
    implicit none

    integer date_time(8)
    character(len=10) sys_time(3)
    call date_and_time(sys_time(1), sys_time(2), sys_time(3), date_time)

    write(*,*) "date_and_time"

    write(*, '(a)') "<< argument 1-3 >>"
    write(*, '(a, 1x, a)') "year, month, date : ", sys_time(1)
    write(*, '(a, 1x, a)') "time              : ", sys_time(2)
    write(*, '(a, 1x, a)') "time zone         : ", sys_time(3)
    write(*,*)

    write(*, '(a)') "<< argument 4   array>>"
    write(*, '(a, 1x, i6)') "year             : ", date_time(1)
    write(*, '(a, 1x, i6)') "month            : ", date_time(2)
    write(*, '(a, 1x, i6)') "date             : ", date_time(3)
    write(*, '(a, 1x, i6)') "time zone[min.]  : ", date_time(4)
    write(*, '(a, 1x, i6)') "hour             : ", date_time(5)
    write(*, '(a, 1x, i6)') "minute           : ", date_time(6)
    write(*, '(a, 1x, i6)') "second           : ", date_time(7)
    write(*, '(a, 1x, i6)') "milli second     : ", date_time(8)
end program main

実行結果

 date_and_time
<< argument 1-3 >>
year, month, date :  20140218  
time              :  155431.688
time zone         :  +0900     
 
<< argument 4   array>>
year             :    2014
month            :       2
date             :      18
time zone[min.]  :     540
hour             :      15
minute           :      54
second           :      31
milli second     :     688

システム時間にはsystem_time関数を使用します。引数にする整数のバイト長で扱える範囲が変わることを知ったので、kind=4とkind=8の両方を比較しています。
kind=4だと、2日ほど計算が進むと一週しそう。

program main
    implicit none

    write(*,*) "system_clock function"
    write(*,*) "<< kind=4 >>"
    call print_time4()
    write(*,*) "<< kind=4 >>"
    call print_time8()

contains

subroutine print_time4()
    integer(kind=4) :: icount, icount_rate, icount_max

    call system_clock(COUNT=icount, COUNT_RATE=icount_rate, &
        & COUNT_MAX=icount_max)

    write(*, '(a, 1x, i20)') "icount       ", icount
    write(*, '(a, 1x, i20)') "icount_rate  ", icount_rate
    write(*, '(a, 1x, i20)') "icount_max   ", icount_max

end subroutine print_time4

subroutine print_time8()
    integer(kind=8) :: icount, icount_rate, icount_max

    call system_clock(COUNT=icount, COUNT_RATE=icount_rate, &
        & COUNT_MAX=icount_max)

    write(*, '(a, 1x, i20)') "icount       ", icount
    write(*, '(a, 1x, i20)') "icount_rate  ", icount_rate
    write(*, '(a, 1x, i20)') "icount_max   ", icount_max
end subroutine print_time8

end program main

結果

 system_clock function
 << kind=4 >>
icount                   659766089
icount_rate                  10000
icount_max              2147483647
 << kind=4 >>
icount            1392706756609384
icount_rate                1000000
icount_max     9223372036854775807

インスタンスの元となるオブジェクトを返すtypesモジュール

http://d.hatena.ne.jp/leetmikeal/20140214/1392375216

前回の記事で、変数の型をisinstance関数を使用してチェックできると書きました。

このスクリプトを実行します。

#!/usr/bin/python
# -*- coding:utf-8 -*-

def func_inst():
    return "func inst"

if __name__ == '__main__':
    print type(func_inst)
    print isinstance(func_inst, function)

結果

<type 'function'>
Traceback (most recent call last):
  File "failed.py", line 9, in <module>
    print isinstance(func_inst, function)
NameError: name 'function' is not defined

あれ?エラーになりました。func_instは"function"のインスタンスではないようです。関数オブジェクトはtype関数で拾ってきた文字列では識別できません。

色々調べてみると、こういうモジュールが見つかりました。
http://docs.python.jp/2.7/library/types.html

これを使うと、

#!/usr/bin/python
# -*- coding:utf-8 -*-

import types

def func_inst():
    return "func inst"

if __name__ == '__main__':
    print type(func_inst)
    print isinstance(func_inst, types.FunctionType)
<type 'function'>
True

オブジェクトや変数の型を確認する方法(関数オブジェクトの型名)

Python 2.7

Pythonで型を調べる方法は簡単で、isinstanceという組み込み関数を使用します。

listかどうかを調べる際は、

if isinstance([], list):
  print "this is list type."

if isinstance(1, int):
  print "this is integer type."

というふうにします。

listやintはオブジェクトであり、[]や1はそれぞれのオブジェクトのインスタンスです。

Pythonでは関数の引数は型を限定しない(全てオブジェクトなので)使い方ができるので、型を調べることで引数に応じて処理を分けるという仕組みが実現出来ます。

それでは、関数オブジェクトの型名は何でしょうか?また、クラスの型名は何でしょうか?それはtype関数を使用することで調べることができます。

Pythonでは全ての変数や関数はオブジェクトなので、引数として渡すことができるのですが、その際に渡った引数の型を調べて処理を分けるときには、型の種類を知らなくてはなりません。型が何かを調べる際にはtype関数を使用します。

type関数でいろんなオブジェクトの型を調べたサンプルを書きました。

#!/usr/bin/python
# -*- coding:utf-8 -*-

import os

class OwnClass():
    def __init__(self):
        self.param = 123
    
    def func(self):
        print self.param
        return True

if __name__ == '__main__':
    owc = OwnClass()

    print "string     's'              is '%s'" % (type("s"))
    print "integer    1                is '%s'" % (type(1))
    print "float      0.1              is '%s'" % (type(0.1))
    print "float      1.0e-3           is '%s'" % (type(1.0e-3))
    print "list       []               is '%s'" % (type([]))
    print "tuple      ()               is '%s'" % (type(()))
    print "None                        is '%s'" % (type(None))
    print "function   'int'            is '%s'" % (type(int))
    print "function   'type'           is '%s'" % (type(type))
    print "module     'os'             is '%s'" % (type(os))
    print "member     'os.path.sep'    is '%s'" % (type(os.path.sep))
    print "method     'os.path.exists' is '%s'" % (type(os.path.exists))
    print "my class   'owc'            is '%s'" % (type(owc))
    print "my member  'owc.param'      is '%s'" % (type(owc.param))
    print "my method  'owc.func'       is '%s'" % (type(owc.func))

出力は以下のようになります。

string     's'              is '<type 'str'>'
integer    1                is '<type 'int'>'
float      0.1              is '<type 'float'>'
float      1.0e-3           is '<type 'float'>'
list       []               is '<type 'list'>'
tuple      ()               is '<type 'tuple'>'
None                        is '<type 'NoneType'>'
function   'int'            is '<type 'type'>'
function   'type'           is '<type 'type'>'
module     'os'             is '<type 'module'>'
member     'os.path.sep'    is '<type 'str'>'
method     'os.path.exists' is '<type 'function'>'
my class   'owc'            is '<type 'instance'>'
my member  'owc.param'      is '<type 'int'>'
my method  'owc.func'       is '<type 'instancemethod'>'