今日の新聞の記事のタイトルである。
ノルウェー政府は来年3月開催予定の核兵器禁止条約締約国会議にオブザーバー参加をすることを明らかにした。北大西洋条約機構(NATO)の加盟国が会議への参加を表明するのは初めての由。
同国内では政府が条約に署名するよう求める声が高まっている。2019年の調査では有権者の78%が政府は条約に署名すべきたと回答。
ノルウェーでは政権交代が実現。中道左派・労働党と中央党の少数連立政権が誕生。この政府による参加表明である。
今日の新聞の記事のタイトルである。
ノルウェー政府は来年3月開催予定の核兵器禁止条約締約国会議にオブザーバー参加をすることを明らかにした。北大西洋条約機構(NATO)の加盟国が会議への参加を表明するのは初めての由。
同国内では政府が条約に署名するよう求める声が高まっている。2019年の調査では有権者の78%が政府は条約に署名すべきたと回答。
ノルウェーでは政権交代が実現。中道左派・労働党と中央党の少数連立政権が誕生。この政府による参加表明である。
LibreLogoに関するブログを書いていたらPythonのタートル・グラフィックスことが気になった。
書架を見たら「Turbo Graphics」(安齋利洋・伊吹龍著;1987年)という昔使った本が目についた。これはTurbo Pascalを使ったグラフィックスの本である。この中にタートル・グラフィックスの例題が沢山あるので今回はこれらをPythonのタートル・グラフィックスで書いてみた。なるべく忠実に例題をなぞるようにした。
例題1:kame
#coding: utf-8
import turtle
def sugata( center, size):
for i in range(6):
painter = center.clone()
painter.fd(size)
painter.rt(120)
painter.fd(size)
center.rt(60)
def kame( position, size):
sugata( position, size)
if __name__ == '__main__':
turtle.clearscreen()
position = turtle.Turtle()
position.ht()
position.lt(90)
kame( position, 200)
多少気になったのは以下の部分である:
painter = center.clone()
Pascalでは単なる代入文でpainter=centerとなっている。Pythonでは代入文によるオブジェクトの代入はできない。copyモジュールのcopyメソッドを使ってみたが描画の一部が消えてしまう。deepcopyではTkinterのエラーがでる。Pythonのタートル・グラフィックのドキュメントにあったclone()で期待した通りの描画が得られた。clone()とcopyメソッドの相違は不明。
【結果の描画】
なお描画ではカメ印(?)は隠してある。
もう一つ実例を考える。
【実例2】
TO sugata nagasa
REPEAT 2 [
FORWARD nagasa
LEFT 120 ]
HOME
END
TO kame nagasa
kakudo = 0
REPEAT 6 [
sugata nagasa
kakudo = kakudo + 60
RIGHT kakudo ]
END
PENCOLOR “black”
HOME
kame 200
日本語化すると:
やるべきこと sugata nagasa
繰り返し 2 [
前へ nagasa
左へ120 ]
定位置へ
記述終わり
やるべきこと kame nagasa
kakudo = 0
繰り返し 6 [
sugata nagasa ;やるべきことsugata実行
kakudo = kakudo + 60
右へ kakudo ]
記述終わり
ペンの色 “black”
定位置へ
kame 200 ;やるべきことkame実行
HOMEは「定位置へ」とした。インデントを使うと少し見やすくなる。
【結果の描画】
こんなプログラムを考える:
TO draw length n
IF n = 0 [
STOP ]
angle = 60
FORWARD length * n
LEFT angle
draw length n-1
RIGHT 2 * angle
draw length n-1
LEFT angle
BACK length * n
END
PENCOLOR “black”
draw 20 5
HOME
PENCOLOR “red”
draw 22 5
大文字のみの単語はLibreLogoの既約語である。この既約語を日本語で表現する。
例えば以下の様にしてみた:
やるべきこと draw length n
もしも n = 0 [
実行終了 ]
angle = 60
前へ length * n
左へ angle
draw length n-1
右へ 2 * angle
draw length n-1
左へ angle
後へ length * n
記述終わり
ペンの色 “black”
draw 20 5 ;やるべきことdrawの実行
定位置へ
ペンの色 “red”
draw 22 5 ;やるべきことdrawの実行
TO(やるべきこと)、END(記述終わり)あたりが難しい。プログラミングで使われている英単語は短くそれ自身では符牒のようなものだ。日本語化ではそれに捉われず多少冗長でも機能が明確になるような語句にするとよいと思った。
LibreOfficeのWriter(文書処理)は一つの機能としてタートル・グラフィックスのためのプログラミング環境を提供している。それがLibreLogoである。文書処理の中にプログラミング環境を提供するという発想が面白い。コンピュータ・プログラミングの敷居を低めることができるかもしれない。LOGOに似た言語が使える。LibreLogoの詳細はここにある。
早速使ってみる。再帰関数が動くか確かめた。以下が使った再帰関数の一例である。
【再帰関数】
TO draw length n
IF n = 0 [ STOP ]
angle = 60
FORWARD length * n
LEFT angle
draw length n-1
RIGHT 2 * angle
draw length n-1
LEFT angle
BACK length * n
END
draw 20 5
TO draw length nからENDまでが再帰関数の定義である。大文字ばかりの単語はLibreLogoの既約語である。これには日本語が使える。
【実行結果】
LibreLogoで再帰処理ができることが解った。
Libreofficeのダイアログ画面上で一組の画像をアニメーションのように自動的に順次見せるAnimatedImageControlを使ってみた。
このAnimatedImageControlを使ったBasic言語による雛形はここにある。これをPythonに翻訳した。注意点は:
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
import unohelper
def python_macro_clipart_anim(*arg):
#
#シート
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#データのある行数を調べる
sRange = sheet.getCellRangeByName("A1")
sCursor=sheet.createCursorByRange(sRange)
sCursor.collapseToCurrentRegion()
MaxDataRow = sCursor.Rows.Count-1
ui.Print(MaxDataRow)
items=[]
imageURLs=[]
for i in range(MaxDataRow):
item = sheet.getCellByPosition(0, i+1 ).String
filePath = sheet.getCellByPosition(1, i+1 ).String
#ui.Print(item)
#ui.Print(filePath)
items.append(item)
imageURLs.append(uno.systemPathToFileUrl(filePath))
imageURLsT=tuple(imageURLs)
#
#ダイアログ
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dialogM = smgr.createInstance('com.sun.star.awt.UnoControlDialogModel')
# Size of DialogM
dlgWth = 500
dlgHgt = 400
dialogM.Width = dlgWth
dialogM.Height = dlgHgt
dialogM.Title = "クリップアート・アニーション"
#ダイアログの生成とモデルの登録
dialog = smgr.createInstance('com.sun.star.awt.UnoControlDialog')
dialog.setModel(dialogM)
#
#
animCtrlModel = smgr.createInstance('com.sun.star.awt.AnimatedImagesControlModel')
animCtrlModel.insertImageSet(0, imageURLsT)
animCtrlModel.StepTime = 1000
animCtrlModel.AutoRepeat = False
animCtrlModel.ScaleMode = 1
#アニメーション・コントロールの登録
animateCtrl = smgr.createInstance('com.sun.star.awt.AnimatedImagesControl')
animateCtrl.setModel(animCtrlModel)
#
dialog.addControl("animated", animateCtrl)
POSSIZE = uno.getConstantByName("com.sun.star.awt.PosSize.POSSIZE")
animateCtrl.setPosSize(10, 10, 1000, 900, POSSIZE)
#
#窓の生成そしてこの窓をダイアログ画面として使う
window = smgr.createInstance('com.sun.star.awt.Toolkit')
dialog.createPeer(window,None) # None : OK / none : NG
#
animateCtrl.startAnimation()
dialog.execute()
dialog.dispose()
属性StepTime=1000で個々画像を一秒間表示するはずだがこの値を変えて表示時間に変化はない。また属性AutoRepeat = Falseで一組の画像の表示は一度のはずだが繰り返し表示される。
紀元前4000年ごろの金石併用時代のウクライナ周辺の考古学の本(英文)を読んでいると出土した陶器の破片に穀物の種による圧痕があり当時の栽培植物が推定できるという記述によく遭遇する。その栽培植物の一つにMillet(英語)がある。このMilletは英和辞書では①アワ(粟)、②キビ(吉備)となっている。併記されている学名がPanicum sativumとなっていることからこの植物はキビであることがわかる。
キビはインド原産であるが、アワは中央アジア、インド亜大陸などが原産地となっていてキビ以上に人類の食料として重要であったことが示唆されている、古代中国では北の地方ではアワが主食であった由。「米」という漢字も本来はアワを示す文字であったといわれている。米は華南のものであった。西から来た「米」が粟だったのかもしれない。
ダイアログの部品の一つにImageControlがある。ダイアログに複数の画像を表示する機能を持ったコントロールである。いろんな使い道がありそうであるがここでは多数のクリップアートを表示する一種のカタログを作ってみることにする。
上図のようにCalcのシート上にクリップアートのタイトルと画像ファイルへのpathが書かれたものがあるとする。マクロではこのシート上のデータを読み込んでダイアログ上にこれらのクリップアートが閲覧できる一種のカタログを作る。
ImageControlの詳細はここにある。特に重要な属性は
ファイルpathのURL形式への変換(またはその逆)はPythonでは以下のunoモジュールが使える:
path = "/home/foo/Documents/file.odt"
url = uno.systemPathToFileUrl(path)
path = uno.fileUrlToSystemPath(url)
カタログはダイアログ画面に納まらないので垂直スクロールの機能を付ける。
【実行画面】
【マクロ】
#coding: utf-8
import uno
import screen_io as ui
import unohelper
from com.sun.star.awt import XActionListener
from com.sun.star.awt import XAdjustmentListener
#「スクロールバー」の処理
class MyAdjustmentListener(unohelper.Base, XAdjustmentListener):
def __init__(self, dlgHgt, catHgt, labs, imcs):
self.labs = labs
self.imcs = imcs
self.scrollVMax=100
self.dlgHgt=dlgHgt
self.catHgt=catHgt
self.labsPositionY0 = []
self.imcsPositionY0 = []
for i, lab in enumerate(labs):
print(lab.PositionY, imcs[i].PositionY)
self.labsPositionY0.append(lab.PositionY)
self.imcsPositionY0.append(imcs[i].PositionY)
def adjustmentValueChanged(self, event):
ratio = event.Value/self.scrollVMax
print(ratio)
for i,lab in enumerate(self.labs):
lab.PositionY = self.labsPositionY0[i]-(self.catHgt - self.dlgHgt)*ratio
self.imcs[i].PositionY = self.imcsPositionY0[i]-(self.catHgt - self.dlgHgt)*ratio
#print(event.Type)
#print(event.Value)
def python_macro_clipart(*arg):
#
#シート
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.Sheets[0]
#データのある行数を調べる
sRange = sheet.getCellRangeByName("A1")
sCursor=sheet.createCursorByRange(sRange)
sCursor.collapseToCurrentRegion()
MaxDataRow = sCursor.Rows.Count-1
ui.Print(MaxDataRow)
items=[]
filePaths=[]
for i in range(MaxDataRow):
item = sheet.getCellByPosition(0, i+1 ).String
filePath = sheet.getCellByPosition(1, i+1 ).String
#ui.Print(item)
#ui.Print(filePath)
items.append(item)
filePaths.append(filePath)
#
#ダイアログ
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.getServiceManager()
dialogM = smgr.createInstance('com.sun.star.awt.UnoControlDialogModel')
# Size of DialogM
dlgWth = 150
dlgHgt = 200
dialogM.Width = dlgWth
dialogM.Height = dlgHgt
dialogM.Title = "クリップアート・カタログ"
#
#コントロールの作成・登録
tabIndex = 0
#スクロールバー
scb1 = dialogM.createInstance('com.sun.star.awt.UnoControlScrollBarModel')
tabIndex += 1
scrollVMin=0
scrollVMax=100
scb1.Name = 'ScrollBar'
scb1.TabIndex = tabIndex
scb1.PositionX = dlgWth-10
scb1.PositionY = 0
scb1.Width = 10
scb1.Height = dlgHgt
scb1.Orientation=1
scb1.ScrollValueMin = scrollVMin
scb1.ScrollValueMax = scrollVMax
scb1.LiveScroll= 1
dialogM.insertByName('ScrollBar', scb1)
#タイトル・画像の登録
imageX = 100
imageY = int(imageX*3/4)
labs=[]
imcs=[]
for i in range(MaxDataRow):
#タイトル
lab2 = dialogM.createInstance('com.sun.star.awt.UnoControlFixedTextModel')
labY=10+(imageY+10+10)*i
tabIndex += 1
lab2.Name = items[i]
lab2.TabIndex = tabIndex
lab2.PositionX =10
lab2.PositionY =labY
lab2.Width = dlgWth - 10
lab2.Height = 10
lab2.Label = items[i]
lab2.Align = 0 # 0 : Left / 1 : Center / 2 : Right
lab2.Border = 0
dialogM.insertByName(items[i], lab2)
labs.append(lab2)
#画像
imc2 = dialogM.createInstance('com.sun.star.awt.UnoControlImageControlModel')
imcY = labY+10
tabIndex += 1
imc2.Name = items[i]
imc2.TabIndex = tabIndex
imc2.PositionX = 10
imc2.PositionY = imcY
imc2.Width = imageX
imc2.Height = imageY
imc2.ImageURL = uno.systemPathToFileUrl(filePaths[i])
imc2.ScaleMode = 1
dialogM.insertByName(items[i]+'image', imc2)
imcs.append(imc2)
#最終的なチェックボックス表の高さ
catHgt=imcY + (imageY + 10)
# Create the dialog and set the model
#ダイアログの生成とモデルの登録
dialog = smgr.createInstance('com.sun.star.awt.UnoControlDialog')
dialog.setModel(dialogM)
#コントロールの登録
cmdScb1 = dialog.getControl('ScrollBar')
#エヴェント監視(スクロールバー)
scb1_listener = MyAdjustmentListener(dlgHgt, catHgt, labs, imcs)
cmdScb1.addAdjustmentListener(scb1_listener)
#
#窓の生成そしてこの窓をダイアログ画面として使う
window = smgr.createInstance('com.sun.star.awt.Toolkit')
dialog.createPeer(window,None) # None : OK / none : NG
#
dialog.execute()
dialog.dispose()
今朝の新聞の記事のタイトルである。
熱いものに触ると熱く感じたり、ものを掴むとものの感触がえられるのは神経細胞の末端にその刺激を感ずる受容体があるからである。
今年のノーベル医学・生理学賞はこれら受容体を発見したデービット・ジュリアス米カリフォルニア大学教授と米ハワード・ヒューズ医学研究所のアダム・バタフーティアン博士が受賞した。
基礎的な研究が受賞したことは大変に喜ばしいことである。
今朝のラジオの地方ニュースである。
仙台にあるウシの放牧場で放牧しているウシに蝿などが集るのを減らす試みとして放牧しているウシに顔料でシマウマのような縞模様を描いてみた。
虫を追い払う仕草の頻度は模様を付けていないウシと比較すると7割程度減少するという結果になった由。有効らしい。ただ同じ実験の二回目ではこの値は3割と落ちてくる。虫も学習しているのかもしれない。
因みのシマウマの縞模様は多くの人の興味を引くらしくその効果については実に多くの説がある。詳しくはここを参照してもらいたい。