2016年1月31日日曜日

Mac OSX El Capitanの日本語入力について

MacのOSX、El Capitanにしてみました。(いつも通り、しばらく様子を見ていました。brewとかなんだかんだ入れているので、いきなりは怖いです)

こちらはWindowsほど劇的な変化はありませんでしたが、使い勝手で一番戸惑ったのが「日本語入力」です。デフォルトが自動変換になってました。Google日本語入力でもありましたが、強力な予測変換で、ユーザーが変換の意思を「スペースキー」を押さなくてもいいようにしてくれるんですが、自分的にはこれ大嫌いです。

OSが勝手に漢字変換を、意図しないタイミングでしてしまうのと、その瞬間どうしてもPCの動きが止まります。よどみなくタイピングしている最中に、意図しない漢字変換されてしまうとものすごいストレスを感じます。もうすぐに「自動変換」をオフしてしまいました。
MSとかApple、Googleはこの辺どう考えているんだろう?仕事でPC使っている人間には、どう考えても今の予測変換の実装はマイナスにしかなりません。(まだ、ガラケーやスマホの予測変換みたに、別領域に変換候補がでてきて、ユーザーが必要ならそれを選ぶ方式なら我慢できますが、入力しているカーソル部分で強制的に第一候補を表示してしまうのは困る。)変換候補を別領域に表示、選択はファンクションキーがいいと思うんだが、どうなんだろう?日本語意外の他の「非英語圏」のUIはどんな使い心地なのか気になります。

windows10について

自分のメインPC(Core2 Quad win7 64bit)を何時かwin10にしないといけないと思いながら、タイミングを計ってきました。他のPCは特に考えずに適当に更新をトライしてましたが、こいつだけは銀行のHP見たりするヤツなんで慎重です。
win10も発表から何度かUpdateがされ、金融機関から最初は出ていた更新を待ってくれという警告もなくなったので、そろそろ試してみるかとやってみました。

最初に感じたのが、とにかく時間がかかること!まあ、OSのメインバージョンの更新なんだから、当たり前なんですが問題は更新後です。
自宅のPCで、EPSONのノートPC(Win7)がWin10に更新できませんでしたが(最後に問題が発生しました。HDDのパーティションの切り方が特殊なようです)、プリンタ・スキャナのドライバが最初は対応してくれず、ドライバの再登録などして何とか使えるようになりました。
後、更新後しばらくは「無茶苦茶遅い!」と感じました。Win10にしたら快適になると聞いていたんですが、「ダメじゃん」という感じ。調べてみると、暫くの間は「自動メンテナンス」で調整をする時間が必要なようです。数時間から1日くらいPCの電源入れっぱなしにして、MSとデータ交換しないといけないようです。

また、安定しても基本認証にMSとインターネットで通信しまくる仕様のようで、パフォーマンスモニタとか見てると、いつもネットワーク通信しています。そうそう、PCへのログイン・アカウントがそれまでのから、強制的にMSのアカウントに切り替えられてしまいました。(設定の途中で、MSのアカウント入力をさせる箇所があり、そこで入力してしまったせいでしょう)これではネットワークがない状況だとどうなるんだろう、という感じです。(最初から、ネットワークなしの状況で設定してればいいんでしょうが、一旦ネットワークがある状況で設定してしまうと、その後はタイムアウト待ちをするしかない?)

前回のWin8がひどい出来だったので、ほとんどWin7の操作に戻った感じですが、全体的に「常時オンライン」が前提のOSになってしまったようです。これはこれで、鬱陶しい!反応が鈍くなるんですよ。しかし、セキュリティの事を考えたらWin10に更新せざるをえません。付き合い方を考えるしかありませんね。

後、困ったのがウイルス対策ソフトのDefenderです。Google Drive等からファイルをDLすると自動的にスキャンしているようなんですが、時間が10~20秒くらいかかり、その間ファイル名の変更ができません。(Defenderがファイルをつかんでいるから)ちょっとこれにはまいりました。何とかなりませんかね。(時間がかかりすぎ。もしかしてパターンチェックか、データをMSに送っているのか?)

2016年1月6日水曜日

python:virtualenvメモ

ここのところchainer, TensorFlowとpythonを使ってみることが多かったのですが、他の方はよく

$ virtualenv

というコマンドを使って、そこに環境を構築していました。名前からすると「何らか」の仮想環境を構築するものなのでしょう。ちょっと調べてみると、python専用のライブラリを「試しで」作るときに、メインの環境にダメージを与えないようにするものでした。要は、VMwareやDocker(こっちの方が間隔的に近い)の様な仮想環境ですが、python限定なのが特別です。(ただ、試しにやってみたら、頑張れば、その中でのみ連携して動くJavaやc++のライブラリ、プログラムも入れれそうな感じです。ただ、Javaやc++のライブラリが特別な別のパッケージを要求していると、かなり大変そう。)

1.インストール
pipコマンドが使えるようになっているなら簡単です。

$ pip install virtualenv

これだけです。(中身は10行くらいのpythonスクリプトです)

2.仮想環境の構築
以下のコマンドだけです。

$ virtualenv testenv

これで、testenv/というディレクトリが作成され、配下に以下のディレクトリが作られます。

bin/ include/ lib/ local/

ここに当該OS環境におけるpython環境がコピーされてきます。(後で追加したpackage等は入っていません。使いたい場合はここで再構築です。)

3.仮想環境の実行
この環境でpythonのあるpackageを試してみたくなったら、以下の手順になります。

$ cd testenv
$ source bin/activate

この"activate"は先ほどコピーされたbin/以下に入っており、これを実行することにより、pythonバイナリ、ライブラリはtestenv/以下のものを参照するようになります。(プロンプトにtestenvの文字が追加され、仮想環境下で動いていることがわかります)
つまり、この環境下で"pip"コマンドでインストールすると、testenv/以下にインストールされることになり、本体OSのpythonには影響を与えません。

4.仮想環境の終了
以下のコマンドです。

$ deactivate


5.仮想環境の削除
お試しが終了して、必要なくなったらディレクトリ毎削除すればOKです。

$ rm -rf testenv/


と、非常にお手軽に色々なpythonのパッケージを試すことができます。


2015年12月30日水曜日

TOPPERSにトライ

自分は組み込み系のプログラムを作る仕事はほとんどしたことがないのですが、最近IoTが騒がれており、Raspberry Piもいじっているので小型のRTOS(リアルタイムOS)に興味がでてきました。
ただ、RTOSというのは通常特殊なメーカから販売されている高価なものしか使ってみたことがなく(しかも組み込み用途では使ったことありません)、オープンソースで手頃なものというとITRONになります。
TOPPERSというITRONの実装がかなり有名なようで、ぐぐると結構かかります。調べてみると、純粋なITRONの仕様から少し拡張されているようですが、活動が2015年現在でも活発に行われており、勉強用にLinux/Windows上でも動作できるエミュレータがついているとか。いきなりRaspberry Piにインストール、という前にちょっと勉強がてらLinux上で動かすのにトライしてみました。
(注:結論を先に述べておきますが、結局失敗しました。どうもLinux上のエミュレータの実装が、かなり古いLinux(おそらくkernel2.6系?)の時から更新されていないようで、今のUbuntu等のkernel3.x系で動かすのはかなり困難が伴うようです

1.TOPPERSのDL
TOPPERSのHP(http://www.toppers.jp/)に行ってみると、様々なバージョンがあるのにびっくりしました。各バージョンがどんな内容かひと通り読むだけで結構時間がかかりましたが、とりあえずスタンダードな以下をDLしてきました。

・TOPPERS/JSP-1.4.4.1

2.TOPPERSのビルド
以下のコマンドでLinuxエミュレータ上で動くものができるようです。(Linuxでは、sample1というプログラムが動くそうです)

$ ./configure -C linux
$ make depend
$ make

ところが当然ながら問題がでてきます。

(1)configureのperlスクリプトでエラーがでる。
configure:40lineで以下の行があります。

require "getopt.pl";

これ、perlのスクリプト起動時のオプションを拾ってくる機能拡張モジュールらしいんですが、現在では使われておらず、以下の様にするようです。

use Getopt::Std;
あと、Getoopt()→getopt()にする。

TOPPERSのMLの2012年にこの指摘があり、提案するとありましたがいまだに採用されていないようです。他の箇所にも同じような所がありましたが、修正してconfigureは通しました。

(2)make dependで、cfg/cfgがないと怒られる。
TOPレベルにcfg/というディレクトリがあるのですが、どうもここのビルドが実行されていないようです。make dependの段階でこれが必要ということは、configureの時点でアーキテクチャに応じてcfg/cfgがビルドされていることを期待しているんでしょうが、先の(1)の修正だけではまだ問題があったようです。
とりあえず手動でビルドして、cfg/cfgを作ります。
→これは、動かしたいTASKの登録をここでしておくので、先に設定をしてビルドしておくものだと判明。

(3)makeでエラー
さて、(2)までの修正でmake dependはパスしました。やっとビルドですが、以下の様なエラーがでてきました。

In file included from ../kernel/task.c:47:0:
../config/linux/cpu_context.h: In function ‘activate_context’:
../config/linux/cpu_context.h:74:35: error: ‘JB_PC’ undeclared (first use in this function)
     ((int *) &(tcb->tskctxb.env))[JB_PC] = (int) activate_r;
                                   ^
../config/linux/cpu_context.h:74:35: note: each undeclared identifier is reported only once for each function it appears in
../config/linux/cpu_context.h:75:35: error: ‘JB_SP’ undeclared (first use in this function)
     ((int *) &(tcb->tskctxb.env))[JB_SP] = (int)(((VB *) tcb->tinib->stk) +

何のことやらさっぱりですが、どうも自分の環境のライブラリには、"JB_PC", JB_SP"の定義がない、と怒られています。
そもそも、これらのdefineが何なのかぐぐってみると、cの関数で、setjmp()/longjmp()のための定義とのことでした。それらは本来以下の場所に定義されているようです。

/usr/include/setjmp.h
/usr/include/bits/setjmp.h

一つ目が2つ目をincludeしており、そこが肝心な部分なんですが、自分の環境(Ubuntu-14.04)ではそもそも2つ目のincludeが位置が違い、内容も大幅に変わっていて、JB_PC/JB_SPとかのdefineがありません。
bits/setjmp.hの定義場所が、CPUのアーキテクチャ毎のところになっていました。そもそも、このsetjmp()/longjmp()が何者なのかですが、c++等で例外処理にthrow→catchが使われていますが、cの時代にはこれが使われていたようです。つまり、ある関数を実行中(これが大事!)にエラーが発生したことを検知した場合、強制的に別のエラー処理用の関数にジャンプする関数だそうです。
かなりやばい系の関数ですが、当然その実装のためには様々なCPUのレジスタの退避とかしないと、エラー処理なんてできません。kernel2.x系の頃は、なんとかc言語だけで実装していたのを、kernel3.x系になったところでCPUアーキテクチャ別にしたようです。(性能とか、完全な動作を考えるとまともな考えですね。)
doc/linux.txtを見てみると、kernel2.2/glibc2.1の頃に作られた模様...、ちょっとこれはお手上げです。(・_・)


さてそうなるととりあえず自分ではお手上げの状態です。自分はc言語で、setjmp()/longjmp()を使ったことないので、既存のエミュレータをどう改修したらいいかわかりません。
自分のところにはまだ別の環境があるので、そちらで動かないか試してみます。


PS@20151231
自分の持っているVMPlayerの環境に、CentOS4と古いバージョンがありました。これで試してみると、

・(1)の問題は発生しません。やはりPerlの古い使い方のようです。
・makeで別の問題が発生しました。
 ../config/linux/tool_config.h:70: undefined reference to `software_term_hook'
ぐぐってみると、2007年に同じ問題にぶつかった人がMLに残していましたが、問題の箇所の関数はjsp-1.4.2のころは全部コメントアウトしてあったのが、jsp-1.4.3からコメントアウトが外されていて、エラーがでるようになったとのこと。別途、関数定義例があり、それを使ってビルド終了。

サンプルの、./jspが動くようになりました!ただコマンドをシリアルから入力することになっていますが、Linuxエミュレータ上で./jspプロセスのシリアルにどうやってつないだらいいのかわかりません。ttyで送ってみましたがダメでした。
まあ、とりあえず動かせる環境はできたんで、後はこれで勉強してみます。



2015年12月26日土曜日

gitによる開発に関して:特定部分を別branchで管理し、master等にコピーしたい

最近、悩んでいるのがgitの操作方法についてです。しかもやりたいことが少し特殊です。

・プログラムの開発をしているが、異なるbranchで開発しているもののうち、自分の担当している部分だけmasterに持ってきて(コピー)、全体の試験がしたい

通常ならば、branch間でmergeすればいいんですが、そうすると自分が使っているdevelop branchにある別のフォルダの内容がmasterと完全に別内容にしているため、それができない!
本来なら、リポジトリのディレクトリ設計の時に考慮しておくべきことなんですが、それに失敗した例です。ただ開発が最終局面にきていて、いまさらリポジトリの再設定をしてしまうと、これまでの各ファイルの改定履歴がリセットされてしまいます。(git等のバージョン管理システムではよくあることですが、ファイルのディレクトリの位置を変えただけでも、当該ファイルの履歴が消えてしまいます。せいぜい、当該ファイルが移動されたよ、というログが残る程度です。subversionは特別に履歴を引き継ぐオプションがあるようですが、特別扱いのようです。詳細は後の雑談で。)開発が結合試験に入っているため、ログが消えるのはかなり痛いです。

開発が終わってしまえば、ログが消えてもまだ我慢できますが、このフェーズではきついです。mergeできなくてもコピーだけでもできればいい・・・、最後はbranchを切り替えて、一旦別の場所にコピーしておいて、再度master branchに切り替え、(手動で)コピーしようかと考えました。色々とぐぐってみると、かなりトリッキーな技があるようですが、最終的に以下のコマンドで可能なことがわかりました。

$ git branch master
$ git checkout develop /home/hoge/git/repo/A/B
                    (branch名) (path名:フルパスで!)

これでdevelop branchのBディレクトリ以下のファイルがmaster branchのBディレクトリ以下にコピーされてきます。(master, developともrepo/以下のディレクトリ構造は基本的に同じはずですから、コピー元を規定するだけで問題ないはずです。万一、構造が変わっていたりすると・・・、ちょっと考えないと。)もちろん、modifyのstatusになりますので、commitとしとくなりしとかないといけません。(当然、ログには「developからコピーしたよ」等入れておきましょう)

注:上記checkoutではpath名をフルパスで規定しています。ぐぐったサンプルでは如何にもリポジトリのtopからのpath名と推測できるような書き方がしてあるものばかりでしたが、どうもフルパスが必要なようです。

具体的に例を示します。

1.gitリポジトリの作成

$ mkdir git/repo
$ cd git/repo
$ git init

2.リポジトリの中身を作る
今回は以下の様な階層を作ってみました。(詳細なコマンドは省略します)

A/ A.txt
     B/ B.txt
          D/ D.txt
     C/ C.txt

Aディレクトリのあるところに、".git"があります。各ディレクトリにあるテキストファイルには以下の様なテキストが入っています。(注:赤字の部分を別branchからコピーしてきます。ちなみに、B/とC/は同じA/以下の階層にいます。)

A.txtサンプルのテキスト
master branchのファイル

最初にファイル名を入れ、後はbranch名を入れてあります。(もちろん、この後commitしておきましょう)

3.develop branchの作成

$ git checkout -b develop

これで全く同じ内容でdevelop branchが作成され、develop branchに移動しました。

4.develop branch内のファイルの変更
次に、後にmaster brachの特定の部分(Bディレクトリ以下)にこのdevelop branchの内容をコピーするので、それがわかるようにファイルの中身を変更します。具体的には、以下の様にします。(これを、A, B, C, Dの4個のtxtファイルに行います)

A.txtサンプルのテキスト
develop branchのファイル

5.master branchへの移動、develop branchの一部をコピー

$ git checkout master
$ git checkout develop /home/hoge/git/repo/A/B

2回めのcheckoutはbranchを移動しません。単にdevelop branchのBディレクトリ以下をmaster branchにコピーしてくるだけです。これにより、B.txtと配下にいるD.txtがコピーされます。git statusをしてみると、この2つのファイルがmodifiedだといってきて、各ファイルの内容は以下の様になっています。

B.txtサンプルのテキスト
develop branchのファイル


これで自分のメインの開発はdevelop branchで行い、結合試験の必要に応じてmaster branchにコピーすることができます。


雑談:
今回、gitのことを色々調べていて思ったのが、こういうリポジトリ管理ではリポジトリ間でも「部分的な」コピーはどうやっても行えないということです。よく考えてみると、一つのリポジトリは一つの目的を持って作っているのであり、その一部だけを(履歴つきで)持ってくるのはかなり危ないことだと気づきました。そもそもその「履歴」(ログ)は別のリポジトリ(環境)で開発中のことが記録されているので、それを別のリポジトリで見ても何の意味もないか、逆に勘違いの元になる可能性があります。
同じように、一つのリポジトリ内でも、ファイルの移動を行うだけで「履歴」が消えてしまいますが、これはファイルの位置が変わるということは、当該ファイルの(開発)目的が変わる場合がほとんどで
、昔の履歴は害になることが多いはずです。
本来は、そんなことのないようにリポジトリを設計する段階できちんと決めておくべき(将来の可能性・拡張性を考えて)なのですが、世の中万能の人間ばかりではないので、filter-branch等駆使して、強引にログを書き換えてしまう参考例がいくつかありました。
ただ、最初から別リポジトリで開発を進め、途中から一つのリポジトリ管理下に置くようにすることは認められているようです。
後、調べている最中に"git-new-workdir"というツールの紹介がありました。このコマンドを使ってbranch間のコピー(共有?)を設定すると、どちらのbranchで操作を行っても、相手のbranchに反映される上に、履歴もつくのだとか。一瞬これこそ求めていたものだと思いましたが、よく考えたらこんなの使いはじめると「多用」しそうで危ないツールだと思いました。

2015年11月8日日曜日

pythonの超軽量webフレームワーク Bottle:Rapiroを制御する

さて本題ですが、webでRapiroを制御できるようにします。元々、これがしたくてpythonで動く簡単なフレームワークがないか探していました。

とりあえず、作ったweb画面を以下に示します。

何のひねりもありませんが、前進、後退、右旋回、左旋回と停止を指示できるようにします。Rapiroを制御するPythonプログラムではRapiroの運動制御を行っているArudinoに、制御用コンピュータとして搭載してあるRaspberry Piからシリアルで各コマンドを送るだけです。そのコマンドを、上記ページのボタンを押したら、送ってやるようにしてやればいいだけです。

Raspberry Piに以下の様なファイル(ディレクトリ構成)を作ります。

rapiro_study/
    - bottle.py
    - index.py
    views/
        - title.tpl

bottle.pyは、フレームワーク本体です。本来ならpythonのパッケージライブラリに入れるべきなんでしょうが、1ファイルと簡単な構成なのでわかりやすいようにここに一緒に置いています。index.pyがwebを制御する本体のプログラムです。(といっても、これだけです)views/以下に、htmlを置いておきます。(このディレクトリ名は固定のようです)今回は一つしか画面を用意していないので、一つしかありません。(title.tpl)これは拡張子が"tpl"ですが、内容は全く"html"です。

title.tpl
<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="UTF-8">
  <title>RAPIRO</title>
 </head>
 <body>
  <h1>RAPIRO Control page</h1>

  <form name="frm" method="get" action="stop">
  <input type="button" onclick="document.frm.submit();" value="停止" style="font-size: 400%; width:200px; ">
  </form>


  <form name="frmF" method="post" action="forward">
  <input type="button" onclick="document.frmF.submit();" value="前進" style="font-size: 100%; width:100px; height:100px; position: absolute; left: 50%; top: 40%;">
  </form>

  <form name="frmB" method="post" action="back">
  <input type="button" onclick="document.frmB.submit();" value="後退" style="font-size: 100%; width:100px; height:100px; position: absolute; left: 50%; top: 60%">
  </form>

  <form name="frmR" method="post" action="right">
  <input type="button" onclick="document.frmR.submit();" value="右旋回" style="font-size: 100%; width:100px; height:100px; position: absolute; left: 70%; top: 50%">
  </form>

  <form name="frmL" method="post" action="left">
  <input type="button" onclick="document.frmL.submit();" value="左旋回" style="font-size: 100%; width:100px; height:100px; position: absolute; left: 30%; top: 50%">
  </form>
 </body> 
</html> 

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

from bottle import route, run, template, request

'''
__debug__を追加。(通常実行時は、__debug__ = 1)
Macでデバッグしたい時は、$ python -O rapiro3.pyで最適化をかけて実行する。
'''

if __debug__:
 import serial
 com = serial.Serial('/dev/ttyAMA0', 57600, timeout=10)

# 出力を一カ所にまとめる。(デバッグ時には標準出力にだすようにする)
def out(comStr):
 if __debug__:
  com.write(comStr)
 else:
  print comStr

# localhost:8000
@route('/')
def title():
    # views/title.tplを呼ぶ
    return template('title')


# localhost:8000/show
@route('/stop', method='GET')
def stop():
    # GETパラメータの取得(username, men)
    command = request.forms.submit

    print("in stop", command)

    out('#M0') # 停止(初期姿勢)

    # views/title.tplを呼ぶ
    return template('title')

# localhost:8000/forward
@route('/forward', method='POST')
def forward():
    print("in forward")
    out('#M1') # 前進

    # views/title.tplを呼ぶ
    return template('title')

# localhost:8000/back
@route('/back', method='POST')
def back():
    print("in back")
    out('#M2') # 後退

    # views/title.tplを呼ぶ
    return template('title')

# localhost:8000/right
@route('/right', method='POST')
def right():
    print("in right")
    out('#M4') # 右回り

    # views/title.tplを呼ぶ
    return template('title')

# localhost:8000/left
@route('/left', method='POST')
def left():
    print("in left")
    out('#M3') # 左回り

    # views/title.tplを呼ぶ
    return template('title')

# ビルドインサーバの実行
run(host='rapiropi.local', port=8000, debug=True, reloader=True)

これだけです。実行するときは、Rapiroのコンピュータ(rapiropiです)にログインし、以下のコマンドを実行します。

$ python index.py

その後、PCで以下のURLをブラウザで表示します。

http://rapiropi.local:8000/

URL名の最後が".local"とちょっと普通と違いますが、家庭内のPCを特にDNSを作らなくてもURLでアクセスできるようにパッケージを入れてあるからです。Webのボタンを押したら、本来なら別のページに飛ぶためのhtmlファイルを指定するところなんですが、今回は単にpythonに制御用の指示を出したいだけなので、単純に文字列を送信して、index.pyではそれを受けとって対応するシリアルコマンドを送ったら、また一つだけのホームページを表示するようにしています。ホームページの方は文字の大きさや何かを指定するために、CSSを使わず個別に指定しています。大したページでもなかったので、CSSを作るのが面倒くさかっただけです。

実際に動かしてみたところ、「ちょっと反応が鈍いかな?」という感じですがちゃんと動いてくれました。
制御用にGETとPOSTの両方を使っていますが、単に勉強用に両方を使ってみただけです。コマンドと関係はありません。(特に送信時に個別のデータはつけてませんし)JavaScriptの練習の時にはよくPOSTで送信していましたが、いざhtmlの定義だけでやるとき、最初は"submit"ボタンしか送信する方法が思いつかず悩みました。調べていたら、ボタンにformをつけて、そこで一つだけJavaScriptを使う方法(onclick="document.frm.submit();")が簡単なので、それを多用しています。実は、中々この方法がわからず、最後はJavaScriptを各ボタン毎に書かないといけないだろうかと思いながら、でもこれはhtmlじゃなくtplのbottle用のファイルだから動くんだろうかと悩んでいました。
結局、bottleを使いながらJavaScriptも使えるようですがちょっと特別なお作法があるようです。今回は処理的なところはPythonでやりたかったので、色々調べてみました。

2015年9月23日水曜日

pythonの超軽量webフレームワーク Bottle

pythonでおもちゃを動かすプログラムを作っていて、それをwebからコントロールしたくなりました。 何か楽な手段はないかと探したら、pythonによる超軽量なwebフレームワーク”Bottle”があることを知りました。特徴は、bottle.pyというファイル一つ使うだけでいいこと。

1.bottleのインストール

インストールというほどのこともありません。以下のコマンドでbottle.pyをDLしてくるだけです。

wget http://bottlepy.org/bottle.py

ただこのコマンドを実行してみたところ、githubに飛ばされて、そこからDLしてきました。


2.最初のサンプル

bottle.pyの中に各種モジュールが入っているので、必要なものをimportしたpythonプログラムを書いてやります。超シンプルなものを以下に示します。(hello_world.pyで作成)

from bottle import route, run

@route('/hello')
def hello():
    return "Hello World!"

run(host='localhost', port=8080, debug=True, reloader=True)

これで、以下を実行します。(bottle.pyは同じ階層に置いておきます)
 $ python hello_world.py 

次にブラウザで、http://localhost:8080/hello にアクセスすると、ブラウザに”Hello World!”の文字が表示されます。 最初に文字コードを指定してやれば、日本語ももちろんいけます。

 # -*- coding:utf-8 -*-

さて、次に考えないといけないのは、ページ上に入力欄やボタン、リンクに飛ばすことができるよう、htmlを別途用意して、それを表示させるにはどうしたらいいか?どうもテンプレート(.tpl)ファイルを用意してやればいいようです。そちらについては、また今度結果をまとめようと思います。