へたっぴpythonista

ド素人pythonistaとして、日々の学習成果や気づいたことについて書きます。

Magic Mirror with Monitorがカッコいい!

 ちょっと前にlifehackerで見つけたこのページ

 マジックミラーの後ろにタブレットを仕込んで、天気予報やtoDoリストを表示させてるだけのシンプルなDIY作品ですが実にカッコいい。私はこれに一目ぼれしてしまいました。自分もこんなクールなインテリアを作ってみたい!
 
 早速"Magic Mirror with computer"で検索して情報収集を開始すると、更にイカしたDIY作品を紹介しているサイトを見つけました。Magic Mirror: Part I - The Idea & The Mirror
 Michael氏は24インチモニターの表面にマジックミラーを重ねることで鏡全体を表示領域にしています。これならタブレットよりも自由に情報を配置することができて便利そうです。今回はこれを参考にしてDIYに挑戦します。

 といってもHTML+CSSの知識がほとんど無い状態からのスタートなので結構時間がかかるかもですけどね(笑)
 
 取りあえずモニターとraspberry Piは購入済みなのでできるところからコツコツ進めたいと思います。

サーバー起動しました!

どうやらポート番号8000が問題だったようです。

コマンドプロンプトで netstat -naoと入力するとアクティブなポートの一覧が表示されます。
f:id:ruriohead:20131223141613p:plain
一番下にローカルアドレス0.0.0.0:8000、つまり8000番のポートがあり、そのPIDを確認すると4です。この後「タスクマネージャー」⇒「表示」⇒「列の選択」⇒「PID」を選択して、該当するPIDを持つプロセス、或いはサービスを探してみると、なんとPID「4」はシステムが占有にしているのでした。これでは停止するわけにはいかないですね。

悩み続けているうちにふと、そもそもポート番号とはなんぞやと思いウィキペディアで調べてみると、ポート番号の種類の項目に1024~49151番は登録済みポートであると書かれていました。なるほど、僕はいままで登録済みのポートに無理やり介入しようとしていたのか。

ここでHTTPで一般に使用されるポートが80であることも判明したので試したところ、無事サーバーの起動を確認できました。


みんなのpythonでもpythonドキュメントでもPORT=8000と書いてあったので、それを鵜のみにしてしまったのが失敗でした。自分初心者なもので、お恥ずかしい限りです。

http.serverが起動しない・・・

みんなのpythonを参考にウェブサーバーを作ろうとしたらわけがわからなくなりました。

とりあえずSimpleHTTPServerモジュールなるものが3.系ではhttp.serverに変更されていることは分かりました。
2.系では

import SimpleHTTPServer

だったけど、3.系では

import http.server

になるわけですね。

問題はその先。

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    http.server.test()
  File "C:\Python\lib\http\server.py", line 1188, in test
    httpd = ServerClass(server_address, HandlerClass)
  File "C:\Python\lib\socketserver.py", line 430, in __init__
    self.server_bind()
  File "C:\Python\lib\http\server.py", line 135, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "C:\Python\lib\socketserver.py", line 441, in server_bind
    self.socket.bind(self.server_address)
OSError: [WinError 10013] アクセス許可で禁じられた方法でソケットにアクセスしようとしました。

こんなエラーが返されて先に進めないのです。なんじゃこりゃ。調べてみてもポートの占有、ファイアウォール等が原因らしいということが分かっただけで解決には至らず、お手上げ状態です。残念。

はてなブログの記法って

先ほど紹介したはてな記法で今までのソースコードを書きなおそうかと思ったんですが、どうも記法って記事ごとに変更できるものらしく、今までの記事は色づけできない模様です。まぁ記事をコピペして一から書き直せばできなくはないですが、さすがに手間がかかりすぎですしねぇ・・・こんなことならもっと早く知っておくべきだったorz

ソースコードの色づけ

前回更新が9月半ばだから、もう2か月ほど放置していたことになりますね。受験勉強しなくちゃいけないからプログラミングがおざなり状態だったせいです。でも、いい加減受験勉強も飽きたので、ちょっとずつプログラミングの勉強も再開しようかな。

ということで復帰第一回めはソースコードの色づけです。
今まではコードをEcllipseからのコピーアンドペーストでごまかしていましたが、調べてみるとはてなブログにはソースコードに色をつけるための専用記法、その名もズバリ「はてな記法」が存在するそうで。そんな便利機能に今までぜんぜん気づかなかったなんて・・・

詳しくはこちら。まぁ公式のヘルプページですが。
まず始めにブログの設定画面のEditing_modeではてな記法モードを選択します。この記法ではHTMLタグは無効になるのでご注意を。f:id:ruriohead:20131128205826p:plain
設定が完了したらあとはソースコードを「>|言語|」と「||<」で挟むだけでOKです。ただし「>||」、「||<」は必ず行頭に来るようにします。

例えば
>|python|
 print('Hello_world')
|| <
と書けば

print('Hello_world')

と表示されます。簡単ですね(何故今まで使わなかったんだ・・・)

" ".join(iterable)はrosalindに必須か

rosalindを解いていると、たまに解答の形式としてカンマを用いずに空白で要素を区切ることが要求されます。つまり「A,B,C,D」ではなく「A B C D」としなくてはならないのです。カンマが入っていようものなら答えが正しくても不正解扱いです。

 

そこで[A,B,C,D]を"A B C D"に変換する手段となる" ".join(iterable)が必要になってきます。

str.join(iterable)はiterable内の文字列をstrで連結する関数です。strにはなんでも指定できるのでstr=" "とすれば要素を空白で連結(連結になってないけど)することが可能になるわけです。

 

注意:

join()は文字列のメソッドであるため、数値には使えません。使うならmap()を用いてiterable内の要素を全てstrにする必要があります。

 例 L=["A","B","C","D"]

            print(" ".join(L)) ⇒ A B C D

 

            L=[1,2,3,4]

            print(" ".join(L))    ⇒TypeError: sequence item 0: expected str instance, int found

   L=[1,2,3,4]

            L=map(str,L)

            print(" ".join(L))    ⇒1 2 3 4

 

文字列からリストへの変換list(str)に比べるとやや煩雑ですが、覚えておいて損はないはずです。こういう手間は出題者側が省くべきではないかなどとは言ってはいけません。

ProjectEuler22をpythonで解く

最近Rosalindばかり解いていて放置気味のEuler。パッと見て解けそうだったので久々に挑戦しました。

Problem22

Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score.

For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 53 = 49714.

What is the total of all the name scores in the file?

 

訳(PukiWiki様より)

5000個以上の名前が書かれている46Kのテキストファイル names.txt を用いる. まずアルファベット順にソートせよ.
のち, 各名前についてアルファベットに値を割り振り, リスト中の出現順の数と掛け合わせることで, 名前のスコアを計算する.
たとえば, リストがアルファベット順にソートされているとすると, COLINはリストの938番目にある. またCOLINは 3 + 15 + 12 + 9 + 14 = 53 という値を持つ. よってCOLINは 938 × 53 = 49714 というスコアを持つ.
ファイル中の全名前のスコアの合計を求めよ.

解答

names=sorted(open("C:/python33/names.txt").read().replace('"','').split(","))
s=0
for i in range(len(names)):

     a=0

     for j in range(len(names[i])):
           a +=int(ord(names[i][j]))-64
     s +=a*(i+1)
print(s)

ポイントは2つ

①テキストファイルをアルファベット順にソートされたリストに変換する。

  まずread()でテキストファイルを一つの文字列にまとめ、replace()で文字列から不要なダブルクォーテーションを取り除き、split()でカンマごとに区切ったリストに変換します。後はsorted()でリストをアルファベット順にソートします。(list.sort()はもう使われていないのでエラーになります)

②各文字を数値に変換する。

  ord()を使います。愚直にアルファベットと数値の対応表を作らない点で進歩したを感じました(笑)

  ord()は因数に指定した文字に対応するASCⅡコードを返す関数です。ord("A")=65なのでord(w)-64 (wはA~Z)は1~26に対応することになります。

  他にもord()を使ってアルファベット・数値対応表を先に作っちゃうという手もありますね。ord()便利です。

 

さて、以上を実行すれば答え871198282が得られます。