Pythonで循環リストっぽいものをやってみる
はじめに
しばらく放置していたので、小ネタを書いてみます。
ちょっとした状態管理を書くときなどに、循環リストが使いたくなる時があります。
起動 → 実行中 → 停止 → 起動みたいに繰り返される状態を表したいなど
使う機会があり、ちょっと書いてみたので公開します。
リストと言いつつ、ジェネレータを使って実装しているため、追加などができませんので悪しからず。
やってみる
def circular_list(list): # listの長さは1以上 index = 0 while True: yield list[index] index = (index + 1) % len(list)
使ってみる
試しのテストを書いてみます。
import unittest class Test(unittest.TestCase): def test_circular_list(self): list = circular_list(['foo', 'bar', 'baz']) self.assertEquals(list.__next__(), 'foo') self.assertEquals(list.__next__(), 'bar') self.assertEquals(list.__next__(), 'baz') self.assertEquals(list.__next__(), 'foo') self.assertEquals(list.__next__(), 'bar') self.assertEquals(list.__next__(), 'baz') if __name__ == '__main__': unittest.main()
WebSocketを死活監視に使ってみた
はじめに
Websocketを使って、キープアライブのようなこと*1をやってみました。
やってみたキッカケは、お仕事でTomcatのWebSocket Sevletを作った際にAPIを見ていたら
接続が切れた時にイベントが拾えるようで、キープアライブに使えるのでは?と思ったからです。
やってみたら、案外ちゃんと使えたので内容を公開します。
ちなみに、WebSocketの実装にはTomcatのWebSocket Servletを使用します。
WebSocket Servletについては、色々解説しているサイトがあるので、ここでは説明を省きます。
環境
ライブラリ
- Java-WebSocket v1.2.0
仕組みについて
ざっくりと流れはこんな感じ
- クライアントがサーバにWebSocketで接続する
- 接続後に、クライアントからサーバにメッセージを送る
- この時に、クライアントを識別する情報を渡してあげると、クライアントが識別できます
- サーバは、クライアントからのメッセージを受けて、クライアントに応答を返す
- クライアントは、サーバからのメッセージを受けて、サーバに応答を返す
- 正常時は、上のサーバとクライアントのやり取りが繰り返される
- (クライアントが切れた時)サーバ側のonCloseが呼ばれる
- ここで、切れた時に行いたい処理を呼び出す
ソース
サーバ側
以下のライブラリにパスを通す
import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @WebServlet(name = "KeepAliveServlet", urlPatterns = { "/KeepAliveServlet" }) public class KeepAliveServlet extends WebSocketServlet { private static final long serialVersionUID = -1L; private static final Log log = LogFactory.getLog(KeepAliveServlet.class); private static Set<MessageInbound> messages = new HashSet<MessageInbound>(); @Override protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest arg1) { log.info("called createWebSocketInbound."); return new KeepAliveInbound(); } private class KeepAliveInbound extends MessageInbound { private WsOutbound outbound; private String clientId; @Override public void onOpen(WsOutbound outbound) { log.info("onOpen."); this.outbound = outbound; messages.add(this); } @Override public void onClose(int status) { log.info("onClose."); if (clientId != null) { log.info(String.format("クライアントID[%s]が切れた", clientId)); } messages.remove(this); } @Override public void onTextMessage(CharBuffer cb) throws IOException { if (clientId == null) { clientId = cb.toString(); } log.info("onTextMessage. " + cb); // すぐにメッセージを返すと通信量が多すぎるので、間隔を設ける try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } outbound.writeTextMessage(CharBuffer.wrap("echo from server.")); } @Override public void onBinaryMessage(ByteBuffer bb) throws IOException { } @Override public int getReadTimeout() { // 初期状態だとクライアントと通信が切れても待ち続けるので、時間を指定しています。 return 10000; } } }
クライアント側
以下のライブラリにパスを通す
- java_websocket.jar
import java.net.URI; import java.net.URISyntaxException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.java_websocket.client.WebSocketClient; import org.java_websocket.drafts.Draft_17; import org.java_websocket.handshake.ServerHandshake; public class KeepAliveClient extends WebSocketClient { private static final Log log = LogFactory.getLog(KeepAliveClient.class); private static final String CLIENT_ID = "123"; private KeepAliveClient(URI serverURI) { super(serverURI, new Draft_17()); } @Override public void onClose(int arg0, String arg1, boolean arg2) { // サーバ側と接続が切れた時に呼ばれる log.info("onClose."); } @Override public void onError(Exception arg0) { log.error("onError. " + arg0.toString()); } @Override public void onMessage(String arg0) { log.info(arg0); this.send("echo from client."); } @Override public void onOpen(ServerHandshake arg0) { log.info("onOpen called. " + arg0.getHttpStatus()); this.send(CLIENT_ID); } public static KeepAliveClient getInstance() { URI uri; try { // 環境に合わせて接続先を変更 uri = new URI("ws://localhost:8080/TomcatProject/KeepAliveServlet"); } catch (URISyntaxException e) { throw new RuntimeException(e); } KeepAliveClient client = new KeepAliveClient(uri); return client; } }
実行用のメインクラス
public class Main { public static void main(String[] args) { KeepAliveClient client = KeepAliveClient.getInstance(); client.connect(); } }
動かしてみる
まず、Mainクラスを適当に実行 クライアント側のログはこんな感じ
KeepAliveClient onOpen 情報: onOpen called. KeepAliveClient onMessage 情報: echo from server. KeepAliveClient onMessage 情報: echo from server. KeepAliveClient onMessage 情報: echo from server.
サーバ側のログはこんな感じ
sample.KeepAliveServlet createWebSocketInbound 情報: called createWebSocketInbound. KeepAliveServlet onOpen 情報: onOpen. KeepAliveServlet onTextMessage 情報: onTextMessage. 123 KeepAliveServlet onTextMessage 情報: onTextMessage. echo from client. KeepAliveServlet onTextMessage 情報: onTextMessage. echo from client.
ここで、クライアント側の接続を切る(LANを切るとか) そうすると、しばらくしてサーバ側にクライアントが切れたとログが出る
KeepAliveServlet onClose 情報: クライアント[123]が切れた
このような感じで、クライアント側の死活を監視することができる
終わりに
WebSocketのちょっと変わった使い方を紹介してみました。
あまりミッション・クリティカルな用途には向きませんが
比較的簡単に、キープアライブ的なことができるのでお試しあれ!*2
VirtualBoxでCentOS6.4が起動しない時には
結論
この通りやればOK
説明は英語ですが、分からなくてもOK。画面に出る指示通りにやれば大丈夫です。
なんでこうなった
どうやら、Guest Additions入れたCentOSのバージョンを6.4に上げると起こるものらしい。
辿った道
- ちょっと調べたいことがあってVirtualBoxのCentOSを起動しようとしたら起動しなかった。
- VirtualBoxのバージョンを最近あげていたのでそれが原因かと思って、バージョンを戻してもダメ。
- 諦めて、OSを再インストールしたら一旦は起動したもののyum updateをしたらまた起動しなくなった。
- 困り果てて、ぐぐってみたら上の動画がヒット(゚∀゚)
- 誰か他の人も同じ問題にハマるかもしれないので、記事を書く
- この記事よりも動画が先に見つかると思うけど・・。
一年に素数は何個ある??
初めに
きっかけは、今日見たツイート
- 数人が似たツイートしていて、誰が最初にツイートしたのか分からなかったので文章のみコピってます
一般人「3月9日だー!卒業シーズンだしレミオロメンだねー」 ボカロ厨「ミクの日!」 バンギャ「SuGの日!」 ガンダム「ザクの日」 東工大生「そ、素数…」 _人人人人人人人_ > 突然の素数 <  ̄Y^Y^Y^Y^Y^Y ̄
これを見た時、3月9日が素数って言うのがよく分からなかった。
3 + 9が素数?
それはない・・
月と日をくっつけた数 → 39が素数?
それっぽいけど、違う
そんなことを考えていると別の疑問が湧いた
あ、でも月と日をくっつけた数が、素数って一年に何個あるんだろう??
調べてみた
まずは、条件を考える
- 範囲は、2012年の1年間(1月1日から12月31日)
- 閏年だったので・・
- 月と日のくっつけ方は、3月9日が39になるようにくっ付ける
- 日の頭が0になる時は、0をとるようにする(3月9日 ≠ 309)
- 最初に思いついたのが、この形式だったので・・
- 日の頭が0になる時は、0をとるようにする(3月9日 ≠ 309)
次に、調べる用のコードを書く
def is_prime(number): if number % 2 == 0 or number % 3 == 0: return False for x in range(5, int(number ** 0.5) + 1): if number % x == 0: return False return True import time from datetime import date A_DAY = date.resolution prime_numbers = [ ] other_numbers = [ ] day = date(2012, 1, 1) while day <= date(2012, 12, 31): # 日付の先頭から0を削る 例: 1/1 → 11 _day = int(str(day.month) + str(day.day)) if is_prime(_day): prime_numbers.append(_day) else: other_numbers.append(_day) day += A_DAY assert len(prime_numbers) + len(other_numbers) == 366 print (prime_numbers) print ('size = %s' % len(prime_numbers))
実行してみる
今回の条件では、一年に素数は67個ある!
- これ見た時、思ったより多いなって思いました
最後に
酔った勢いで書いた
反省している
読み返すとコードがごちゃごちゃしてるので、次はもっとスッキリしたコードを書くように頑張ろう
でも、結構楽しめたのでよかった
Tomcat7にEclipseからアプリケーションをデプロイする方法
前置き
Tomcat7に対して、EclipseからAntを使ってデプロイしようとした際に、色々苦戦したのでやり方を記録に残します。
やることはそれほど多くありませんが、Tomcat6とは違いがあるので、これからTomcat7を使う方は参考にどうぞ。
環境
手順
Tomcatの設定
- デプロイに使うTomcatユーザのロールに"manager- script"を追加します。
<tomcat-users> <user name="admin" password="tomcat" roles="manager-gui,manager-script"/> </tomcat-users>
- antが使用する4つのjarを取得
Eclipseの設定
Eclipseを使用せずに、Antのみで行いたい場合は、参考のページを見てください
- Antが使用するjarを追加
Build.xmlの編集
- 以下の内容をBuild.xmlに追加
- プロパティ値は、環境に合わせて書き換える
<!-- プロパティ値 --> <property name="manager.url" value="http://192.168.0.2:8080/manager/text"/> <property name="manager.username" value="admin"/> <property name="manager.password" value="tomcat"/> <property name="manager.context.path" value="/TomcatProject"/> <property name="manager.war.file" value="file:./dist/TomcatProject.war"/> <property name="manager.update" value="true"/> <target name="manager.deploy.war" depends="context.status" if="context.deployable"> <deploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${manager.context.path}" update="${manager.update}" war="${manager.war.file}"/> </target> <target name="manager.undeploy.war" description="context.status" if="context.undeployable"> <undeploy url="${manager.url}" username="${manager.username}" password="${manager.password}" path="${manager.context.path}" /> </target> <target name="context.status"> <property name="running" value="${manager.context.path}:running"/> <property name="stopped" value="${manager.context.path}:stopped"/> <list url="${manager.url}" outputproperty="ctx.status" username="${manager.username}" password="${manager.password}"> </list> <condition property="context.running"> <contains string="${ctx.status}" substring="${running}"/> </condition> <condition property="context.stopped"> <contains string="${ctx.status}" substring="${stopped}"/> </condition> <condition property="context.notInstalled"> <and> <isfalse value="${context.running}"/> <isfalse value="${context.stopped}"/> </and> </condition> <condition property="context.deployable"> <or> <istrue value="${context.notInstalled}"/> <and> <istrue value="${context.running}"/> <istrue value="${manager.update}"/> </and> <and> <istrue value="${context.stopped}"/> <istrue value="${manager.update}"/> </and> </or> </condition> <condition property="context.undeployable"> <or> <istrue value="${context.running}"/> <istrue value="${context.stopped}"/> </or> </condition> </target>
- プロパティ値について
- manager.url
- デプロイ先のサーバを示すURL
- http://
<hostname>
:<port>
/manager/text
- http://
- デプロイ先のサーバを示すURL
- manager.username
- デプロイに使用するtomcatのユーザ名
- manager.password
- デプロイに使用するtomcatのパスワード
- manager.context.path
- デプロイするアプリケーションのコンテキストパス
- /<任意のコンテキストパス>
- /を忘れずにつける
- /<任意のコンテキストパス>
- デプロイするアプリケーションのコンテキストパス
- manager.war.file
- warへのパス
- manager.update
- すでにデプロイされている場合に、更新するか
- 更新する場合: true, 更新しない場合: false
- すでにデプロイされている場合に、更新するか
- manager.url
デプロイ
- プロジェクトエクスプローラ上で、Build.xmlを右クリック
- Run As → Ant Build を選択
- manager.deploy.warを選択し、Runを押下
アンデプロイ
- プロジェクトエクスプローラ上で、Build.xmlを右クリック
- Run As → Ant Build を選択
- manager.undeploy.warを選択し、Runを押下
以上、思ったより長かった
参考
Mountain Lionを使い始めて、選んだアプリたちを紹介
MacBook Air(11.6)を使い始めて、1ヶ月が経ちました。
# 普段は、Windowsをメインで使ってます。
使い始めた感想は、一言で言って快適!
OSの操作は自然で、ほとんど考えずに使えました。
また、Bashや各種コマンドが最初から使えるのが便利。
ただ、困ったことが1つがあります。
Windowsで使い慣ればアプリケーションの幾つかが使えないこと。
そんな中で、選んだアプリケーションを一ヶ月の記念に書きます。
これから、使う人に少しでも参考になればいいな~と
コンセプト
なるべく使い慣れたアプリと同じ感じのものを選んでます。
また、情報が豊富な定番の中から選んだつもりです。
それと、Macの主な使い方がお布団でネットを見るのとコードを書くことなので
そっち方面にアプリケーションが偏っています^^;
アプリケーション
分類 | Winアプリ | Macアプリ | コメント |
ブラウザ | Firefox | Firefox | マウス操作系のアドオンが気に入ってるけど、マウス使っていないので、Chromeにしようか検討中 |
Saezuri | 夜フクロウ | Macアプリの中で一番使って見たかった。とっても素敵。 | |
メモ | Evernote | Evernote | 同じだけど、UIが違う(バージョンの違い?)。 |
日本語入力 | Google日本語入力 | Google日本語入力 | 悩まなくて済んだ。Googleさまさま。 |
圧縮解凍 | Lhaz | Stuffit Expander | 定番っぽい? |
ストレージ | Dropbox | Dropbox | |
クリップボード拡張 | Clibor | ClipMenu | 使いやすい |
画像閲覧 | MassiGra | (なし) | 標準のものを使ってる |
動画再生 | MPC | VLC, QuickTime | たまに動画を見るときに |
音楽再生 | foobar2000 | iTunes | バージョン11がシンプルで使いやすいと思う |
ウィルス対策 | Microsoft Security Essentials | ClamXav | たまーにスキャンしてる |
2画面ファイラー | あふ | (なし) | 代わりが見つからないので、Finder使う |
キーカスタマイズ | keyhac | (なし) | OSの使い勝手がいいので、いらないかも |
エディタ | Vim(KaoriYa) | MacVim | ド安定 |
エディタ | EmEditor | CotEditor | さっと使う用 |
ランチャー | fenrir | Alfred | 一番迷った。Alfredは高機能だけど、fenrirを フォルダ移動用に使ってたので、ちょっと違う |
SCM | Mercurial | Mercurial | Macと使うと、日本語ファイル名の問題が・・・。 Gitもいいな |
SCM(GUI) | TortoiseHg | SourceTree | インストールが簡単なので、使って見てる |
マージツール | WinMerge | p4merge | なかなか変わりが見つからなかったけど、これに落ち着いた |
grep | Devas | (なし) | GUIでサクッと置換できるものを探し中 |
シェル | bash(Cygwin) | bash | 最初から使えるのが嬉しい |
SCP | WinSCP | (なし) | 探し中 |
パッケージ管理 | (なし) | Homebrew | あると楽。MacPortsと迷う |
あとがき
さっと書いたので、忘れてるものもある気がします。
まだまだ慣れていないので、いい情報があったら教えていただけると嬉しいです。
のんびりしてたら、今年もあと少しになりました。
それでも、まだ時間があるので、楽しく過ごせるといいと思います。
# 自分は、今年やるやる詐欺をしていたScalaを楽しみます
では、メリークリスマス and いいお年を!
TortoiseHgをコマンドラインから使う
快適なMercurialライフのために、役立つかもしれない情報をお送りします。
前置き
TortoiseHgは、使い勝手の良いMercurialのGUIクライアントです。
そんなTortoiseHgは、コマンドラインから(も)使用できます*1。
コマンドラインなら、CUIを使ったほうがいいのではとおもわれるかもしれません。
しかし、これが意外と便利なのです。
たとえば、普段はCUIを使っていても、次のようなことはGUIのほうが使いやすことがあります。
- ログを追いながら、変更内容を確認する
- リビジョンとの差分を確認する
環境
- Windows 7(64bit)
- TortoiseHg 2.6
使い方
1. TortoiseHgをインストール
2. TortoiseHg(thg.exe)にパスを通す
- デフォルトでは、C:\Program Files\TortoiseHg
3. ログを確認する
> thg log
- 画像は、TortoiseHg履歴を使用しています
3. 差分を確認する
> thg vdiff -r <rev>
4. その他のコマンドを知る
> thg help
コマンド体系は、Mercurialと近いです。
おまけ
TortoiseHgは、Windows shellと統合されています。
しかしこれは便利な半面、いくつか問題があります。
- 動作が重くなったり、右クリックのメニューがごちゃごちゃしたりとか
インストール時のオプションを変更することで、shellとの統合をやめることができます。
手順
- インストーラを起動し、Custom Setupまで進める
- Shell Extension x64(84)を選択しクリック
- Entrie feature will be unavailableを選択
*1:マニュアルにも書かれており、知っている方も多いと思います