はじめに
健康診断でメタボの仲間入りとなってしまい、ダイエットを決意しました。
手元にあるipadで、毎日の体重等を記録してグラフ化できたらモチベーションも
上がるかも。
環境
ipad + pythonista3
要件
・朝と夜の体重・血圧や脈拍・体温も記録する。
・歩数や体脂肪も記録する。
・その日の行動メモも記録できたら、後日の分析に役に立つかも。
・毎日のデータをグラフ化する。
・長く続いた時にデータを活用できるように、CSVでデータを書き出したい。
Ui
コード
メインスクリプト
試行錯誤した経緯で、注釈がかなり多く入っています。
色々調べたコードの注釈が少なくて、流れを調べるのに苦労したので
同じように コード調べながら書いている人が注釈みて理解する助けに
なればいいな共います。
こんな注釈無くても理解できる方には、注釈だらけの汚いコードになって
しまっています。ごめんなさい。
あと、注釈は自分用メモも兼ねています。
healthmemo.py
#! python3
#coding: utf-8
# 体重等を測ったら、簡単にメモしてcsv保存
# 体重・日時・血圧・脈・体脂肪率・体温・歩数を記録する。
'''
開発履歴
20201029 Ver001 健康支援研修から体重等を記録し易くするメモアプリを作る事にした
20201031 Ver002 データ構造などをpcで作成し、ipadでui作成。ベータ版
20201114 Ver003 体重のグラフ表示を追加。グラフ化すると入力が面白くなる!!
20201117 Ver004 起動時loadとsaveのバックアップ作成。上書きでデータ消えた(T_T)
20201125 Ver004 グラフに歩数・体温・血圧を追加。バージョン変更無。
★日付と朝と夜=午前午後から自動判別。csvに記録→グーグルスプレッドシートに追記+メールでバックアップを自動送信。
★→自動追記とメール送信はしない。csvを共有してコピーするとした。
★小数点は入力しない。3桁の数で入力して、自動変換。←変換しない。小数点入力無しにする。
★メモの字数を自動カウント+警告を出すようにする。(200文字制限?) 、
★縦横の両方で使えるようにする。キーボードに注意。できれば縦メイン。→iPad横のみ用とした。iphoneでは小さすぎた。
★保存ボタン(メールの自動送信も含む)は、必要かも。
★csvも日毎に1ファイル作って、pcでcsvを合成するファイル統合ソフト作った方がいいかな?
→そうすると、iPad上でのcsvは1次元配列でもできるかもしれない。→csv一つに毎日のデータ追記にした。2次元配列。
'''
import ui
import datetime
import sys
import io #gazou hennkou
import csv
import os #file sousa
# import pandas 不可!pythonista3は、pandas使用不能。numpyとバージョン合わないらしい。csvで読むことにした。
import matplotlib.pyplot as plt
from PIL import Image
#global変数 一覧
nitiji_now = datetime.datetime.now() # 現在日時の取得
nitiji_on = nitiji_now.strftime('%Y/%m/%d_%H:%M:%S')
# datetime関数から日時を取り出して、表示する文字の変数に代入
nitiji_kyou = str(nitiji_now.strftime('%Y/%m/%d'))
#kyoufile = str('healthmemodata') + nitiji_now.strftime('%Y%m%d') + str('.csv')
filename = str('healthmemodata.csv')
graphname = str('healthmemograph.png')
healthlist = [['年月日','体重朝','体重夜','血圧上朝','血圧下朝','脈拍朝','血圧上夜','血圧下夜','脈拍夜','体脂肪','歩数','メモ','体温朝','体温夜']]
nitiji_asaban = 'AM'
taijyuuAM = '001'
taijyuuPM = '002'
ketuatuueAM = '003'
ketuatuuePM = '006'
ketuatusitaAM = '004'
ketuatusitaPM = '007'
myakuhakuAM = '005'
myakuhakuPM = '008'
taionAM = '012'
taionPM = '013'
taisibou = '009'
hosuu = '0010'
memo = 'memo011'
listnosaigonohi = False
###########
# グラフ作成と表示
def graphsakusei(): # グラフ画像作成
xmin=0
xmax=100
dx=1
ymax=730
ymin=670
dy=25
if os.path.exists(graphname):# グラフ画像あれば、消す。無ければそのまま作成。
os.remove(graphname)
else:
pass
x0 = [x[0] for x in healthlist]#0列目を抽出
del x0[0]
x = range(len(x0))
y = [y[1] for y in healthlist]
y1 = [y1[2] for y1 in healthlist]
del y[0]
del y1[0]
plt.figure() #matplotでグラフ描く毎に最初に宣言しないと重ね書きされる。pythonista3の癖。
# 体重以外の項目を換算して表示
y2b = [y2b[10] for y2b in healthlist]#歩数
y2 = other_y(y2b)
print(y2b)
print(y2)
plt.plot(x,y2,linestyle='dashed',marker='o',color='g',label='Hosuu')#緑
y3b = [y3b[9] for y3b in healthlist]#体脂肪
y3 = other_y(y3b)
print(y3b)
print(y3)
plt.plot(x,y3,linestyle='dashed',marker='o',color='orchid',label='Tisibou')#紫
y4b = [y4b[12] for y4b in healthlist]#体温am
y4 = other_y(y4b)
plt.plot(x,y4,linestyle='dashed',marker='o',color='hotpink',label='TaionAM')#ピンク
y5b = [y5b[3] for y5b in healthlist]#血圧上am
y5 = other_y(y5b)
plt.plot(x,y5,linestyle='dashed',marker='o',color='y',label='KetuatuUeAM')#黄色
y6b = [y6b[4] for y6b in healthlist]#血圧下am
y6 = other_y(y6b)
plt.plot(x,y6,linestyle='dashed',marker='o',color='gold',label='KetuatuSitaAM')#黄色
'''
y7b = [y7b[11] for y7b in healthlist]#memoの▲の日
y7 = other_y(y7b)
plt.plot(x,y7,linestyle='dashed',marker='o',color='goldenrod',label='Memo')#茶色
'''
#plt.figure() #matplotでグラフ描く毎に宣言しないと重ね書きされる。最初に宣言pythonista3の癖。
plt.grid()#グリッドの表示
plt.plot(x,y,marker='o',color='red',label='AMkg')#グラフにデータインプット
plt.plot(x,y1,marker='v',color='blue',label='PMkg')
#plt.plot(x,y2,linestyle='dashed',marker='o',color='g',label='Hosuu')
plt.ylim(ymin,ymax) #グラフの表示範囲を指示
plt.title('taijyuu kg')
plt.xlabel('date')
plt.ylabel('kg')
#plt.xlim([xmin,xmax])
plt.legend(bbox_to_anchor=(1.01,1),loc='upper left',borderaxespad=0,fontsize=18)# 凡例の表示。
plt.subplots_adjust(right=0.8) # 右側の余白を追加して凡例を切れない様にする(グラフを左から80%以内に表示)
plt.show() #グラフ表示
plt.savefig(graphname)#PNGでカレントに保存される
pil_img = Image.open(graphname)#pilに画像読み込み
imgg = pil2ui(pil_img)
return imgg
# 体重以外の項目を675-725の50の範囲内に換算した値のリストを返す
def other_y(inputlist): #
yyb = inputlist
#其の他データを体重に合わせて表示(670-730→675−725の50で最大値最小値に換算して表示
#yyb = [yyb[10] for yyb in healthlist]#歩数
del yyb[0]#インデックスの先頭行を削除
yyb = [float(x) for x in yyb]# リスト全体をstrからfloatに変換
yymin2 = min2(yyb) #2番目に小さい値(自作関数)
yyd=(float(max(yyb))-yymin2)/50
# [0 if c<15 else c for c in yyb] #空白値が12までなので、15以下を0に置換
yyout = [((i-yymin2)/yyd)+675 if i>15 else 0 for i in yyb] #yybのリストを順に15超は(i-yymin2)*yyd.15未満は0に置換
print('yyb;',yyb,'yymin2;',yymin2,'yyd;',yyd,'yyout;',yyout)
return yyout
# 2番目に小さい値を返す
def min2(inputlist): #
m1,m2=float('inf'),float('inf') # float('inf')は、無限大を示す
for x in inputlist:
#print(x)
x = float(x) #引数がstrだとエラーになるのでfloatに変換。しかし、数字以外だとやっぱりエラー(^^)b
if x == m1:#最小値が複数ある場合の除去用に必要な条件分岐
pass
elif x < m1:
m1,m2=x,m1
elif x < m2:
m2 = x
return m2
# pil <=> ui pilとios(ui)の使う画像データは異なるので 変換が必要。今回はpil→uiに変換してる。imgIn=pil
def pil2ui(imgIn):#from PIL import Image が必要
with io.BytesIO() as bIO: # pilの画像データをiosのuiで使える画像データに変換する。import io必要
imgIn.save(bIO, 'PNG')
imgOut = ui.Image.from_data(bIO.getvalue())
del bIO
return imgOut
###########
# メイン処理
def readdata(): # データファイルの読み込みリスト変数に代入 不使用
global healthlist # グローバル変数でないと各関数で読めない。ここで変更するのでglobal宣言必要
if os.path.exists(filename):
healthlist =[]
faile1 = open(filename,"r",encoding='utf-8') # ファイルを読み込む=r属性でオープンする。
healthlist = list(csv.reader(faile1)) # すべて読み込んでcsvオブジェクト→リストデータにする。
#for n in range(len(memocamdata)): # 一行づつ全部表示。rangeで数のカウント lenで要素数
# memocamdata[n] = memocamdata[n].strip("\n") # stripで指定文字消去。要素1づつに入てる、改行を消す
faile1.close() # ファイルをクローズする。メモリ節約
else:
healthlist = ['not data file']
return healthlist
def writedata(healthlist): # グローバル変数のリストをデータファイルに書込み
with open(filename,'w', newline='',encoding='utf-8') as f:# テキストファイルを作成。winはnweline='' を入れると安全?
writer = csv.writer(f) # 二次元配列を一気に書込み
writer.writerows(healthlist) # 二次元配列を一気に書込み
def listgousei():#入力数値を二次元配列の最後列に追加。
global healthlist # グローバル変数でないと各関数で読めない。ここで変更するのでglobal宣言必要
healthlist0 = [nitiji_kyou,taijyuuAM,taijyuuPM,ketuatuueAM,ketuatusitaAM,myakuhakuAM,ketuatuuePM,ketuatusitaPM,myakuhakuPM,taisibou,hosuu,memo,taionAM,taionPM]
healthlist.append(healthlist0)
return healthlist
def tail_csv(list0,n):#csvの最後からn行目までをリストで返す。文字列のまま。
#with open(file0) as f: #def ni file0 wo hikisuu de ireru
#reader = csv.reader(f)#ファイルをCSVリーダーに変換
#next(reader)#ヘッダーを捨てる
#rows = [row for row in reader]#全部行読んでリスト化
#tail = [list(map(float,row)) for row in rows[-n:]]#文字列なのでmap()でfloatに変換して、最後n行目まで抜き出す。(全部数字の場合のみ)
tail = [list0[-n:]]
return tail
def dateck(sender):#リストの最下行が、今日か判別して代入
#tail = [] #1次元配列を宣言
global healthlist,taijyuuAM,taijyuuPM,ketuatuueAM,ketuatusitaAM,myakuhakuAM,ketuatuuePM,ketuatusitaPM,myakuhakuPM,taisibou,hosuu,memo,taionAM,taionPM,listnosaigonohi # グローバル変数でないと各関数で読めない。ここで変更するのでglobal宣言必要
tail = healthlist[-1:] # リストの最後行を抽出
if tail[0][0] == nitiji_kyou:
listnosaigonohi = True
taijyuuAM = tail[0][1]
taijyuuPM = tail[0][2]
ketuatuueAM = tail[0][3]
ketuatusitaAM = tail[0][4]
myakuhakuAM = tail[0][5]
ketuatuuePM = tail[0][6]
ketuatusitaPM = tail[0][7]
myakuhakuPM = tail[0][8]
taisibou = tail[0][9]
hosuu =tail[0][10]
memo = tail[0][11]
taionAM = tail[0][12]
taionPM = tail[0][13]
g_name = str('体重AM; ') + str(float(taijyuuAM)/10) + str('kg') # 後ろに言葉を足す。
sender.superview['ttaijyuuAM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('体重PM; ') + str(float(taijyuuPM)/10) + str('kg') # 後ろに言葉を足す。
sender.superview['ttaijyuuPM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('血圧上AM; ') + ketuatuueAM + str('mmHg(135)') # 後ろに言葉を足す。
sender.superview['tketuatuueAM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('血圧下AM; ') + ketuatusitaAM + str('mmHg(85)') # 後ろに言葉を足す。
sender.superview['tketuatusitaAM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('脈拍AM; ') + myakuhakuAM + str('回/分(60-90)') # 後ろに言葉を足す。
sender.superview['tmyakuhakuAM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('血圧上PM; ') + ketuatuuePM + str('mmHg(135)') # 後ろに言葉を足す。
sender.superview['tketuatuuePM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('血圧下PM; ') + ketuatusitaPM + str('mmHg(85)') # 後ろに言葉を足す。
sender.superview['tketuatusitaPM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('脈拍PM; ') + myakuhakuPM + str('回/分(60−90)') # 後ろに言葉を足す。
sender.superview['tmyakuhakuPM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('体脂肪率; ') + str(float(taisibou)/10) + str('%(10−19)') # 後ろに言葉を足す。
sender.superview['ttaisibou'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('歩数; ') + hosuu + str('歩(1万)') # 後ろに言葉を足す。
sender.superview['thosuu'].title = g_name # テキストビューに反映する。左右重要。
g_name = memo # 後ろに言葉を足す。
sender.superview['tmemo'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('体温AM; ') + str(float(taionAM)/10) + str('度') # 後ろに言葉を足す。
sender.superview['ttaionAM'].title = g_name # テキストビューに反映する。左右重要。
g_name = str('体温PM; ') + str(float(taionPM)/10) + str('度') # 後ろに言葉を足す。
sender.superview['ttaionPM'].title = g_name # テキストビューに反映する。左右重要。
else:
pass
return
###########
# load save create ボタン
def loadinput(sender):
global healthlist,taijyuuAM,taijyuuPM,ketuatuueAM,ketuatusitaAM,myakuhakuAM,ketuatuuePM,ketuatusitaPM,myakuhakuPM,taisibou,hosuu,memo,taionAM,taionPM # グローバル
if os.path.exists(filename):
readdata()
dateck(sender)
else:
sender.superview['lasttext'].title = str('データファイルがありません。データを作成しました。') # テキストビューに反映する。左右重要。
createinput(sender)
img = graphsakusei()
sender.superview['graphview'].image = img
sender.superview['txtcsv'].text = str(healthlist)
def saveinput(sender):
global healthlist
backfilename = filename[:-4] + '_bk.csv'
if os.path.exists(backfilename):#バックアップがあるか確認して、有れば消す
os.remove(backfilename)
else:
pass
if os.path.exists(filename):
os.rename(filename,backfilename)#バックアップファイルにリネーム
if listnosaigonohi:
#print(backfilename)
healthlist.pop(-1) #pop;リストの最後の要素を取得するメソッドだけど、結果として最後の要素を抜く
#print(healthlist)
listgousei()
#print(healthlist)
writedata(healthlist)
sender.superview['lasttext'].title = str('healthlistdata保存完了') # テキストビューに反映
else:
listgousei()
writedata(healthlist)
sender.superview['lasttext'].title = str('healthlistdata保存完了') # テキストビューに反映
else:
sender.superview['lasttext'].title = str('データファイルがありません。') # テキストビューに反映する。左右重要。
def createinput(sender):
if os.path.exists(filename):
sender.superview['lasttext'].title = str('データファイルが既に有ります。') # テキストビューに反映する。左右重要。
else:
#listgousei()
writedata(healthlist)
sender.superview['lasttext'].title = str('healthlistdata新規作成完了') # テキストビューに反映
def deleteinput(sender):
if os.path.exists(filename):
os.remove(filename)
sender.superview['lasttext'].title = str('healthlistdata削除完了') # テキストビューに反映
else:
sender.superview['lasttext'].title = str('データファイルがありません。') # テキストビューに反映する。左右重要。
###########
# 体重等の入力ボタン
def taijyuuAMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('体重AM; ') + str(float(f_name)/10) + str('kg') # 後ろに言葉を足す。
sender.superview['ttaijyuuAM'].title = g_name # テキストビューに反映する。左右重要。
global taijyuuAM
taijyuuAM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def taijyuuPMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('体重PM; ') + str(float(f_name)/10) + str('kg') # 後ろに言葉を足す。
sender.superview['ttaijyuuPM'].title = g_name # テキストビューに反映する。左右重要。
global taijyuuPM
taijyuuPM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def ketuatuueAMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('血圧上AM; ') + f_name + str('mmHg(135)') # 後ろに言葉を足す。
sender.superview['tketuatuueAM'].title = g_name # テキストビューに反映する。左右重要。
global ketuatuueAM
ketuatuueAM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def ketuatusitaAMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('血圧下AM; ') + f_name + str('mmHg(85)') # 後ろに言葉を足す。
sender.superview['tketuatusitaAM'].title = g_name # テキストビューに反映する。左右重要。
global ketuatusitaAM
ketuatusitaAM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def myakuhakuAMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('脈拍AM; ') + f_name + str('回/分(60-90)') # 後ろに言葉を足す。
sender.superview['tmyakuhakuAM'].title = g_name # テキストビューに反映する。左右重要。
global myakuhakuAM
myakuhakuAM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def ketuatuuePMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('血圧上PM; ') + f_name + str('mmHg(135)') # 後ろに言葉を足す。
sender.superview['tketuatuuePM'].title = g_name # テキストビューに反映する。左右重要。
global ketuatuuePM
ketuatuuePM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def ketuatusitaPMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('血圧下PM; ') + f_name + str('mmHg(85)') # 後ろに言葉を足す。
sender.superview['tketuatusitaPM'].title = g_name # テキストビューに反映する。左右重要。
global ketuatusitaPM
ketuatusitaPM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def myakuhakuPMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('脈拍PM; ') + f_name + str('回/分(60−90)') # 後ろに言葉を足す。
sender.superview['tmyakuhakuPM'].title = g_name # テキストビューに反映する。左右重要。
global myakuhakuPM
myakuhakuPM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def taisibouinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('体脂肪率; ') + str(float(f_name)/10) + str('%(10−19)') # 後ろに言葉を足す。
sender.superview['ttaisibou'].title = g_name # テキストビューに反映する。左右重要。
global taisibou
taisibou = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def hosuuinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('歩数; ') + f_name + str('歩(1万)') # 後ろに言葉を足す。
sender.superview['thosuu'].title = g_name # テキストビューに反映する。左右重要。
global hosuu
hosuu = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def memoinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name # 後ろに言葉を足す。
sender.superview['tmemo'].title = g_name # テキストビューに反映する。左右重要。
global memo
memo = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def taionAMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('体温AM; ') + str(float(f_name)/10) + str('度') # 後ろに言葉を足す。
sender.superview['ttaionAM'].title = g_name # テキストビューに反映する。左右重要。
global taionAM
taionAM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def taionPMinput(sender): # 数値を入れて標準するボタン
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = str('体温PM; ') + str(float(f_name)/10) + str('度') # 後ろに言葉を足す。
sender.superview['ttaionPM'].title = g_name # テキストビューに反映する。左右重要。
global taionPM
taionPM = f_name
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
###########
# 数字入力ボタン
def b01_click(sender):
text00 = "1"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b02_click(sender):
text00 = "2"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b03_click(sender):
text00 = "3"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b04_click(sender):
text00 = "4"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b05_click(sender):
text00 = "5"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b06_click(sender):
text00 = "6"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b07_click(sender):
text00 = "7"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b08_click(sender):
text00 = "8"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b09_click(sender):
text00 = "9"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b0_click(sender):
text00 = "0"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def b00_click(sender):
text00 = "00"
f_name = sender.superview['text1'].text # textfieldのnameが['']
g_name = f_name + text00 # 後ろに言葉を足す。
sender.superview['text1'].text = g_name # テキストビューに反映する。左右重要。
def bclear_click(sender):
f_name = sender.superview['text1'].text # textfieldのnameが['']
sender.superview['text1'].text = str("") # テキストビューに反映する。左右重要。
def bmemoread_click(sender):
sender.superview['text1'].text = memo # テキストビューに反映する。左右重要。
###########
#
if os.path.exists(filename):
readdata()
tail = healthlist[-1:] # リストの最後行を抽出
if tail[0][0] == nitiji_kyou:
listnosaigonohi = True
taijyuuAM = tail[0][1]
taijyuuPM = tail[0][2]
ketuatuueAM = tail[0][3]
ketuatusitaAM = tail[0][4]
myakuhakuAM = tail[0][5]
ketuatuuePM = tail[0][6]
ketuatusitaPM = tail[0][7]
myakuhakuPM = tail[0][8]
taisibou = tail[0][9]
hosuu =tail[0][10]
memo = tail[0][11]
taionAM = tail[0][12]
taionPM = tail[0][13]
else:
writedata(healthlist)
v = ui.load_view()
v.present('fullscreen')
uiで生成されたコードをそのままアップしただけです。
healthmemo.pyui
[
{
"nodes" : [
{
"nodes" : [
],
"frame" : "{{32, 52}, {572, 41}}",
"class" : "TextField",
"attributes" : {
"action" : "",
"font_size" : 20,
"frame" : "{{254, 368}, {200, 32}}",
"spellchecking_type" : "default",
"class" : "TextField",
"uuid" : "6F710D34-0CD5-4805-9A21-C94951CFA56D",
"alignment" : "left",
"text" : "",
"autocorrection_type" : "default",
"name" : "text1",
"font_name" : "<System>"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{436, 150}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b01_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "1",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b01",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{436, 310}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b03_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "3",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b03",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{524, 230}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b07_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "7",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b07",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{436, 390}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b04_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "4",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b04",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{524, 550}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b00_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "00",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b00",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{436, 470}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b05_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "5",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b05",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{436, 230}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b02_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "2",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b02",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 470}, {94, 72}}",
"class" : "Button",
"attributes" : {
"action" : "loadinput",
"image_name" : "iob:ios7_cloud_download_outline_32",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "load",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(0.266667,1.000000,0.266667,1.000000)",
"class" : "Button",
"name" : "bload",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{524, 310}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b08_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "8",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b08",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{524, 470}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b0_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "0",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b0",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{524, 390}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b09_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "9",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b09",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 150}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "taijyuuAMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "体重AM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "ttaijyuuAM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 190}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "taijyuuPMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "体重PM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "ttaijyuuPM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 230}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "ketuatuueAMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "血圧上AM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tketuatuueAM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 12}, {572, 32}}",
"class" : "Button",
"attributes" : {
"action" : "",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "日付・・・",
"uuid" : "61026267-1FAC-45B5-9261-F7077490FA9E",
"font_bold" : true,
"class" : "Button",
"name" : "lasttext",
"font_size" : 20
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 270}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "ketuatusitaAMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "血圧下AM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tketuatusitaAM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 350}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "ketuatuuePMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "血圧上PM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tketuatuuePM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 310}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "myakuhakuAMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "脈拍AM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tmyakuhakuAM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 390}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "ketuatusitaPMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "血圧下PM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tketuatusitaPM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{32, 430}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "myakuhakuPMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "脈拍PM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tmyakuhakuPM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 190}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "hosuuinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "歩数",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "thosuu",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 230}, {194, 72}}",
"class" : "Button",
"attributes" : {
"action" : "memoinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "memo",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "tmemo",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 150}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "taisibouinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "体脂肪 %",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "ttaisibou",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 390}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "taionAMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "体温AM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "ttaionAM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 430}, {194, 32}}",
"class" : "Button",
"attributes" : {
"action" : "taionPMinput",
"frame" : "{{344, 496}, {80, 32}}",
"title" : "体温PM",
"uuid" : "A187D39B-77D9-4CD0-B4B9-AD98BD2B7460",
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"class" : "Button",
"background_color" : "RGBA(0.771226,0.771226,0.771226,1.000000)",
"name" : "ttaionPM",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{524, 150}, {80, 72}}",
"class" : "Button",
"attributes" : {
"action" : "b06_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "6",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "b06",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 470}, {90, 72}}",
"class" : "Button",
"attributes" : {
"action" : "createinput",
"font_size" : 15,
"frame" : "{{472, 284}, {80, 32}}",
"title" : "create",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(0.266667,1.000000,0.266667,1.000000)",
"class" : "Button",
"name" : "bcreate",
"image_name" : "iob:leaf_32"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{134, 470}, {92, 72}}",
"class" : "Button",
"attributes" : {
"action" : "saveinput",
"font_size" : 15,
"frame" : "{{472, 284}, {80, 32}}",
"title" : "save",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(0.266667,1.000000,0.266667,1.000000)",
"class" : "Button",
"name" : "bsave",
"image_name" : "iob:ios7_cloud_upload_outline_32"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{332, 470}, {96, 72}}",
"class" : "Button",
"attributes" : {
"action" : "deleteinput",
"image_name" : "iob:ios7_trash_32",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "delete",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(0.266667,1.000000,0.266667,1.000000)",
"class" : "Button",
"font_size" : 15,
"name" : "bdelete"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{332, 550}, {184, 72}}",
"class" : "Button",
"attributes" : {
"action" : "bclear_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "clear",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "bclear",
"font_size" : 50
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{234, 310}, {194, 72}}",
"class" : "Button",
"attributes" : {
"action" : "bmemoread_click",
"frame" : "{{472, 284}, {80, 32}}",
"title" : "memoread",
"uuid" : "A94A4D9E-3A5F-4687-8759-C78625266BD8",
"background_color" : "RGBA(1.000000,0.844444,0.533333,1.000000)",
"class" : "Button",
"name" : "bmemoread",
"font_size" : 15
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{640, 150}, {346, 312}}",
"class" : "ImageView",
"attributes" : {
"alpha" : 1,
"border_width" : 1,
"frame" : "{{462, 334}, {100, 100}}",
"border_color" : "RGBA(1.000000,0.533333,0.300000,1.000000)",
"class" : "ImageView",
"uuid" : "2D875A02-DC26-4EEE-A03C-1CD264CACCBE",
"corner_radius" : 0,
"background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"name" : "graphview",
"image_name" : "iob:arrow_graph_down_right_256"
},
"selected" : false
},
{
"nodes" : [
],
"frame" : "{{640, 470}, {346, 286}}",
"class" : "TextView",
"attributes" : {
"uuid" : "DC7E0A0D-573D-487E-9D7D-527DD4E5EBF6",
"font_size" : 10,
"background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)",
"frame" : "{{412, 284}, {200, 200}}",
"editable" : true,
"alignment" : "left",
"autocorrection_type" : "default",
"text" : "",
"font_name" : "<System>",
"spellchecking_type" : "default",
"class" : "TextView",
"name" : "txtcsv",
"flex" : "WH"
},
"selected" : false
}
],
"frame" : "{{0, 0}, {1024, 768}}",
"class" : "View",
"attributes" : {
"name" : "",
"enabled" : true,
"border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)",
"background_color" : "RGBA(0.833333,1.000000,1.000000,1.000000)",
"tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)",
"flex" : ""
},
"selected" : false
}
]
最後に、
pythonisutaで 写真に手書きスケッチとかできるツールのスクリプトは
いくつか見つかったのですが、zoom機能の付いたスクリプトって なぜか在りませんでした。
こちらも作ってみたので またアップしてみます。