pythonistaでダイエット・体温メモツールを作ってみた

# はじめに
健康診断でメタボの仲間入りとなってしまい、ダイエットを決意しました。
手元にあるipadで、毎日の体重等を記録してグラフ化できたらモチベーションも
上がるかも。


# 環境
ipad + pythonista3

# 要件
・朝と夜の体重・血圧や脈拍・体温も記録する。
・歩数や体脂肪も記録する。
・その日の行動メモも記録できたら、後日の分析に役に立つかも。
・毎日のデータをグラフ化する。
・長く続いた時にデータを活用できるように、CSVでデータを書き出したい。

# Ui
![Downloads20210115_02healthmemo[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017925/aca7c1c4-61b9-f89f-cd73-880556c8b571.png)

グラフはコンソールに画像として表示されています。
![Downloads20210115_03healthmemo[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017925/d7165e34-159e-42dc-5ef0-75a519589214.png)

# コード
メインスクリプト
　試行錯誤した経緯で、注釈がかなり多く入っています。
色々調べたコードの注釈が少なくて、流れを調べるのに苦労したので
同じように　コード調べながら書いている人が注釈みて理解する助けに
なればいいな共います。
こんな注釈無くても理解できる方には、注釈だらけの汚いコードになって
しまっています。ごめんなさい。
あと、注釈は自分用メモも兼ねています。


```php:healthmemo.py
#! python3
#coding: utf-8

# 体重等を測ったら、簡単にメモしてcsv保存
# 体重・日時・血圧・脈・体脂肪率・体温・歩数を記録する。

'''

開発履歴
20201029 Ver001 健康支援研修から体重等を記録し易くするメモアプリを作る事にした
20201031 Ver002 データ構造などをｐｃで作成し、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]#０列目を抽出
	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') # ファイルを読み込む＝ｒ属性でオープンする。
		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):#ｃｓｖの最後からｎ行目までをリストで返す。文字列のまま。
	#with open(file0) as f: #def ni file0 wo hikisuu de ireru
	#reader = csv.reader(f)#ファイルをＣＳＶリーダーに変換
	#next(reader)#ヘッダーを捨てる
	#rows = [row for row in reader]#全部行読んでリスト化
	#tail = [list(map(float,row)) for row in rows[-n:]]#文字列なのでmap()でfloatに変換して、最後ｎ行目まで抜き出す。（全部数字の場合のみ）
	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で生成されたコードをそのままアップしただけです。

```php: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機能の付いたスクリプトって　なぜか在りませんでした。
こちらも作ってみたので　またアップしてみます。