pythonで家計簿 その2

jsonで保存,表示させるところまで。
色々とオプションも動くようにしたけどまだ中途半端。
保存フォーマットの仕様を変更したので、
以前のファイルを新フォーマットに更新するhadbrf.pyも用意。

hadb.py

#Household Accounts Database
import json
import datetime
import locale

#データ格納ファイル
datafile = 'sample.json'

#初期辞書
initialdic = {'0': {'date':{'year':"0",'month':"0",'day':"0"},'item':{'kind':"0",'place':"0",'amount':"0"},'record':{'year':"0",'month':"0",'day':"0"}}}

#日付データ
thisdate = datetime.date.today()
thisyear,thismonth,thisday = str(thisdate).split('-')

#データ読み込み
def fileinput(filename,encoding):
    with open(filename,'r',encoding=encoding) as file:
        return(json.load(file))

#データ上書き
def fileoutput(filename,encoding,data):
    with open(filename,'w',encoding=encoding) as file:
        json.dump(data,file,sort_keys = True, indent = 4)

#年月日補完
def DatetimeCompletion(data):
    revdata = data[::-1]
    if len(revdata) == 3:
        revdata.append(thisday)
    if len(revdata) == 4:
        revdata.append(thismonth)
    if len(revdata) == 5:
        revdata.append(thisyear)
    completedata = revdata[::-1]
    return(completedata)

#総計
def TotalAmount():
    HADB = fileinput(datafile,'utf-8')
    index = [str(itr) for itr in range(len(HADB))]
    AllAmount = [int(HADB[itr]['item']['amount']) for itr in index]
    return(sum(AllAmount))

#データ抽出表示
def SearchDictionary():
    print("\nEnter: query\n")
    query = input()
    LineBreak()
    HADB = fileinput(datafile,'utf-8')
    index = [str(itr) for itr in range(len(HADB))]
    for itr in index:
        print(HADB[itr]['item'][query])

#データ変更
def ChangeDictionary():
    print("\nEnter: query origin replace")
    query,origin,replace = input().split()
    HADB = fileinput(datafile,'utf-8')
    index = [str(itr) for itr in range(len(HADB))]
    for itr in index:
        if HADB[itr]['item'][query] == origin:
            HADB[itr]['item'][query] = replace

    fileoutput(datafile,'utf-8',HADB)
    print("\ndata changed.")

#データ追加
def UpdateDictionary():
    #データ振り分け(年,月,日,種別,店名,金額)
    year,month,day,kind,place,amount = DatetimeCompletion(input().split())
    #日付,項目,記録日
    date = {'year':year,'month':month,'day':day}
    item = {'kind':kind,'place':place,'amount':amount}
    record = {'year':thisyear,'month':thismonth,'day':thisday}
    #追加する辞書
    newdata = {'date':date,'item':item,'record':record}
    #家計簿データベースに新しいデータを追加
    HADB = fileinput(datafile,'utf-8')
    numbering = str(len(HADB))
    HADB[numbering] = newdata
    #json形式で保存
    fileoutput(datafile,'utf-8',HADB)
    print("\ndata appended.")

#改行
def LineBreak():
    print("")

#実行文
while True:
    print("\nEnter: year month day kind place amount")
    print("Option: exit clear view search change\n")
    stdin = input() #標準入力
    if stdin == "exit": #終了
        LineBreak()
        break
    elif stdin == "clear": #データ初期化
        fileoutput(datafile,'utf-8',initialdic)
    elif stdin == "view": #データ一覧表示
        print(json.dumps(fileinput(datafile,'utf-8'),sort_keys = True, indent = 4))
        LineBreak()
        print("total amount =",TotalAmount())
    elif stdin == "search": #データ抽出表示
        SearchDictionary()
    elif stdin == "change": #データ変更
        ChangeDictionary()
    elif stdin == "sum": #総和を求める
        LineBreak()
        print(TotalAmount())
    else: #データ追加
        UpdateDictionary(stdin)
続きを読む

mecab-pythonがどうしても入らない話

研究で使用しなきゃいけないんだけど、どうしても入らない
gcc-4.2がエラー吐いてるからgcc入れ直したりしたけど無意味
MacがダメならUbuntuでと試してもダメ
ということで困っている。解決策模索中。

(2016-06-16追記)
macでpip install時にgccエラーが表示される場合 | かねしろぐ - 兼城駿一郎(@pinkroot )のライフログ
上の記事に辿り着いて解決しました。
command line toolsがインストールされていないのが原因でした。
「恐るべきことに、以前インストールしたはずなのにインストーラーが立ち上がりました。」
がそのまんま当てはまったパターン。

以下長文のエラーコード

続きを読む

pythonで家計簿を付ける その1

家計簿を付ける習慣がない、でもpythonを書く習慣はある。
だからpythonで家計簿を付けよう。

とりあえず記録するところまで書き終えた。

hab.py

import json
import datetime
import locale

#データ格納先ファイル
datafile = "sample.json"

#日付情報
thisdate = datetime.date.today()
thisyear,thismonth,thisday = str(thisdate).split('-')

# データ読み込み
def fileinput(filename,encoding):
    with open(filename,'r',encoding=encoding) as file:
        return(json.load(file))

#データ上書き
def fileoutput(filename,encoding,data):
    with open(filename,'w',encoding=encoding) as file:
        json.dump(data,file)

#データ書き込み
def filewrite(filename,encoding,data):
    with open(filename,'a',encoding=encoding) as file:
        json.dump(data,file)

#年月日補完
def DatetimeCompletion(data):
    revdata = data[::-1]
    if len(revdata) == 3:
        revdata.append(thisday)
    if len(revdata) == 4:
        revdata.append(thismonth)
    if len(revdata) == 5:
        revdata.append(thisyear)
    completedata = revdata[::-1]
    return(completedata)

print("Enter: year month day kind place amount")
while True:
    inputdata = input()
    if inputdata == "exit": #終了
        break
    elif inputdata == "clear": #データ全削除
        fileoutput(datafile,'utf-8',{})
    elif inputdata == "view": #情報一覧表示
        data = fileinput(datafile,'utf-8')
        print(data)
    else:
        newdata = inputdata.split() #標準入力
        completedata = DatetimeCompletion(newdata) #年月日補完
        year,month,day,kind,place,amount = completedata #データ振り分け
        dicdata = {'year':year,'month':day,'day':day,'kind':kind,'place':place,'amount':amount} #辞書にする
        appenddata = {'year':thisyear,'month':thismonth,'day':thisday,'data':dicdata} #記録年月日を付ける
        data = fileinput(datafile,'utf-8') #元データ(辞書)を読み込む
        data[str(len(data)+1)] = appenddata #元データ(辞書)に新しいデータを追加
        fileoutput(datafile,'utf-8',data) #json形式で保存

以下のように、"年 月 日 店名 種別 金額" と入力すると
{ナンバリング{記録年月日{入力データ}}}の辞書の形で追加されていく方式。
年月日はそれぞれ省略すると記録した日の情報が適用される。
"view"を入力で一覧を出力、"clear"でデータ全削除、"exit"で終了。

$ python3 hab.py
Enter: year month day kind place amount
5 food すき家 610
view
{'1': {'day': '07', 'year': '2016', 'month': '06', 'data': {'year': '2016', 'kind': 'food', 'amount': '610', 'place': 'すき家', 'day': '5', 'month': '5'}}}
6 food ローソン 916
2 14 food ローソン 1790
view
{'1': {'day': '07', 'year': '2016', 'month': '06', 'data': {'year': '2016', 'kind': 'food', 'amount': '610', 'place': 'すき家', 'day': '5', 'month': '5'}}, '2': {'day': '07', 'month': '06', 'year': '2016', 'data': {'year': '2016', 'kind': 'food', 'amount': '916', 'place': 'ローソン', 'day': '6', 'month': '6'}}, '3': {'day': '07', 'year': '2016', 'month': '06', 'data': {'year': '2016', 'kind': 'food', 'amount': '1790', 'place': 'ローソン', 'day': '14', 'month': '14'}}}
exit
$ 

表示や演算の部分の実装はまだこれから。
pandas使って綺麗に表示できると良さげかな。

SublimeText 2 to 3

なんとなく使いやすいなって理由で使っていたSublime Text 2ですが、
使いこなそうと思ってまずは3にバージョンを上げました。

そして以下の記事を参考にカスタマイズをするなど。
テーマはFlatlandにしました。

Sublime Text 3 の初期設定 - Qiita
[tips][Sublime Text] Sublime Text 3をインストールしたらまずやること
より見やすく、使いやすくなるsublime textテーマ8つ | 株式会社LIG

SublimeText内でコンソール開いてpythonインタプリタを使えることも知る。

Webサイト作成のための準備の記録 その2

以前のサーバーのセットアップでは、
Ubuntu14.04 LTS に Python, Django, Apache, mod_wsgi を入れましたが、
Webサイト作成のための準備の記録 - GraffitiNote

NginxやuWSGIが良いという記事を散見したのでそちらを利用してみる。

環境構築の際に参考にしたのはこちら。
Ubuntu 14 でLAMP(Nginx+MariaDB(MySQL)+PHP)インストールからWordPressを動かすまで(Nginx編) | レンタルサーバー・自宅サーバー設定・構築のヒント

記事通りに進めていくと何故かエラーが出たりしますが、
(何度か手順を逆戻りをしたりはしたものの)
今回は記事通りに上手く環境構築が出来ました。

ということで、
Ubuntu14.04 LTS + Python + Django + Nginx + uWSGI
で新しいWebサイトは作成していきます。

現在はphpinfoを表示させている状態。
phpinfo()

今後の予定としては、人狼サイトを作るので、
とりあえず原型となる掲示板サイトを作成。
その後デザインや掲示板の仕様変更を行い、
コマンドや時間制限による切り替えを実装。
肝となるAIの実装はまだ保留。

「絶対普通の脳ミソじゃない」に対するアルゴリズム屋の考察


www.youtube.com

最近こんな動画が話題だそうです。

一般的な視点としては、
1.カスケード(ジャグリング)を行う
2.ルービックキューブを揃える
以上2点を同時に行っているということになると思います。

しかし、動画を見てみると、3つのキューブが全て
同じタイミング(21回目の操作)で揃っていることが分かります。
このことから、規定の動作を3つのキューブに適用しているのではないか?
ということが予想されます。
また、規定の動作を共通の解法としている場合、
元のキューブの状態が(グラフ理論的に)同型であると考えられます。

左手手前のキューブの状態は殆ど確認することができませんが、
左手外側のキューブと右手のキューブの2面が
同型であることは容易に確認できます。
f:id:sweetsoundstory:20160323002221p:plain
f:id:sweetsoundstory:20160323002233p:plain

また、ルービックキューブは、ある一面に着目した場合、
縦に回すことを考えると左右側面と中央の3パターンに分けられます。
カスケード中に中央を回すのは難易度が高すぎるので、
側面を回し続けていることが推測されます。

以上の考察より、動画投稿主が実行していると考えられるアルゴリズムは、
1. 左(または右)側面を回す
2. 1を回転軸をx軸⇢y軸(⇢z軸)の繰り返しで変更しながら21回転分行う
3. 1と2を3つのキューブに適用する
4. 3つのキューブに対してカスケードしながら操作を逆戻りしていく

ちゃんと画像(映像)解析してやればきちんと検証できると思いますが、
そこまでする余力が今のところないので考察のみで今回は終わります。

汎用ビルドスクリプト

恐らく将来的に新しい言語を習得する時に使うであろうということでメモ。

C++の勉強をしていた時、ひたすらサンプルプログラムを走らせてるうちに、
いちいちコンパイル⇢実行の手順を踏むのが面倒くさい!!!
ということで書いた、コンパイルと実行をまとめてやってくれるだけの
ビルドスクリプトです。特にすごい機能はありません。
気が向いたら機能もりもりに更新します。

仕様としては、スクリプト言語はそのまま実行、
コンパイラ言語は実行ファイル(.exe)を生成して実行、
既に生成済の xxx.exe は xxx を宣言することで実行できます。
コンパイルや実行文は赤文字で、実行結果は青文字で表示されます。
現状、CとC++pythonが動きます。
引数やpython2,3系の使い分けには対応してないです。


run.sh

#! /bin/sh

tput setaf 1 #red
if [ $# -lt 1 ]
then
    echo " "
    echo ">>./run filename"
    echo " "
    tput setaf 0 #black
    exit 1
fi

echo " "
case $1 in
    *.c)
        name=${1/\.c/}
        echo "gcc $name.c -o $name.exe"
        gcc $1 -o $name.exe
        ;;
    *.cpp)
        name=${1/\.cpp/}
        echo "g++ $name.cpp -o $name.exe"
        g++ $1 -o $name.exe
        ;;
    *.py)
        echo "python $1"
        echo " "
        tput setaf 4 #blue
        python $1
        echo " "
        tput setaf 0 #black
        exit 1
        ;;
    *.*)
        echo "not support."
        echo " "
        tput setaf 0 #black
        exit 1
        ;;
    *)
        echo "./$1.exe"
        echo " "
        tput setaf 4 #blue
        ./$1.exe
        echo " "
        tput setaf 0 #black
        exit 1
        ;;
esac
echo "$1 ===COMPILE===> $name.exe "

echo "./$name.exe"
echo " "
tput setaf 4 #blue
./$name.exe
echo " "
tput setaf 0 #black


さて、ここで実行するC++のコードを用意します。
有名なa^=b^=a^=bというエレガントなコードでswapを行うプログラムです。

swap.cpp

#include <iostream>
using namespace std;

int main(){
  int a = 1,b = 2;
  cout << "a = " << a << ", b = " << b << endl;
  a^=b^=a^=b; cout << "swapped." << endl;
  cout << "a = " << a << ", b = " << b << endl;
}


上記のコードをビルドスクリプトを使用して実行した結果が
以下のようになります。

$ ./run swap.cpp
 
g++ swap.cpp -o swap.exe
swap.cpp ===COMPILE===> swap.exe 
./swap.exe
 
a = 1, b = 2
swapped.
a = 2, b = 1


ここでは全て黒文字で表示されていますが、
実際には上から順に黒文字、赤文字、青文字で表示されます。

pythonの演算子オーバーロードはIQ150を超える

算数の問題だ!┗(^o^;)┓足し算かな????wwWwwWWw┏(;^o^)┛足し算じゃないな?????wWWWwww(´・`;) こ… これ…これは……演算子オーバーロードだあああああ┗(^o^)┛WwwwWW┏(^o^)┓ドコドコドコwwwwwwwwwww

IQ150もあるわけねーだろ


というわけでこの問題を演算子オーバーロードを使って解いてくれる
python3のソースコードです。(解法の説明は要らないと思われる)

overload.py

class N(int):
  def __init__(self,value):
    self.value = value
  def __add__(self,other):
    n1,n2 = self.value,other.value
    if n1 < n2: n1,n2 = n2,n1 #念の為
    return str(n1 - n2) + str(n1 + n2)

#a+bのフォーマットで標準入力
while True:
  a,b = map(int,input().split("+")) #標準入力から数値受け取り
  a,b = N(a),N(b) #わざわざ変換する
  answer = a + b #演算子オーバーロードだ!!!(これがやりたかっただけ)
  print("=" + str(answer))


実行結果
(標準入力時に改行しない方法を知ってる方がいたら教えてください)

$ python3 overload.py
6+4
=210
9+2
=711
8+5
=313
5+2
=37
7+6
=113

Webサイト作成のための準備の記録

まずはConoHaでサーバー(VPS&SSD)を借りる

サーバーにUbuntu14.04をブチ込む

adduser
passwd
apt-get update
apt-get upgrade
apt-get install openssh-server
ifconfig
apt-get install build-essential

PYTHONでWEB開発: Django実践チュートリアル(サーバー編)DjangoをUbuntu,Apache, mod_wsgiで動かしてみる

に従ってUbuntuを構築していく

途中でエラーがでたので

Apache2 on ubuntu で a2ensite すると does not exist と言われるときの対処法 - Qiita

を参考に対処

名前.comでドメインを借りてDNSレコードを設定する