from adglobal import N, P, A, T, M, j import adglobal as g import os import adsub class person: # personクラス def __init__(self, q): # コンストラクタ self.p = q def show(self, k): # class personの表示メソッド s = self.p str1 = "{0}: 氏名:{1} 住所:〒{2} {3} 電話:{4} mail:{5}".format(k, s[0], s[1], s[2], s[3], s[4]) print(str1) def csvline(self): # class perosnのファイル書き込み用メソッド s = self.p str1 = "%s,%s,%s,%s,%s\n" % (s[0], s[1], s[2], s[3], s[4]) return str1 # 文字列str1を返す。 def fetch(self): # class personの要素を編集しやすい辞書式にするメソッド s = self.p d = {N: s[0], P: s[1], A: s[2], T: s[3], M: s[4]} return d def fix(self, d): # 辞書式になっているデータをperson classに格納して戻す s = self.p for i, a in enumerate(j): if len(d[a]) > 0: # 長さが0になっている項目は格納しない s[i] = d[a] return s def check(self): # データの有効性をチェックする s = self.p for i, e in enumerate(j): data = adsub.zhconv(s[i]) # 郵便番号、電話番号も全角で入力されてしまうので、半角に変換する。 if not adsub.check_func[i](data): # 有効性を確認鶴関数は関数のリストに入っている。 return False return True class book: # 住所録クラス def __init__(self, book_name): # コンストラクタ self.name = book_name # 住所録の名前 self.book_path = g.ad_path + "\\" + book_name + ".csv" # 住所録名からパス名を作る。 self.a = [] # personクラスのインスタンスを格納するリスト。最初は空 def writeab(self): # 住所録をファイルに書き込むメソッド fd1 = open(self.book_path, mode='w') for d in self.a: fd1.write(d.csvline()) fd1.close() def readab(self): # 住所録ファイルを読み込むメソッド rcnt = 0 # rcnt:レコード数 self.a = [] # 住所録データをクリアする。 if os.path.exists(self.book_path): # 住所録パスが存在するか? fd1 = open(self.book_path, mode='r') # 住所録ファイルをopenしてファイル・オブジェクトを作る。 for str1 in fd1: a1 = list(str1) # 一旦、ファイルから読み込んだ文字列 str1 = "".join(a1[:-1]) # str1の末尾の\nを削除する。 ncomma = str1.count(',') if ncomma == 4: # 5項目あるので、文字列の中に','は4個のはず。 a = str1.split(',') # ','で文字列を5個の項目に分離する。 d = person(a) # 5個の文字列からpersonクラスのインスタンスを作る。 self.a.append(d) # personインスタンスをリストに付加(壊れたデータでも一応読み込む) rcnt += 1 # レコード数を+1 if not d.check(): # 不適切なデータはエラーを出す。 print("%d'th record is illegal" % rcnt) else: # ','が4個でないレコードはファイルが壊れているので、そこで読み込み中止。 print("{0} is broken".format(self.name)) rcnt = -1 # このとき、プログラムは強制終了してしまう。 break fd1.close() # フィアルを閉じる else: rcnt = 0 if rcnt == 0: self.a = [] # レコード数が0のときは、データなしとして、プログラムを始める。 return rcnt # レコード数を返す。-1を返すときは、読み込み失敗。 def show(self, ra): # リストra[]に入っている番号のデータを表示する。 da = self.a # da:データのリスト size = len(da) if size > 0: # n:項目数の確認 n = len(da[0].p) else: n = 5 # デフォルトの項目数は5 if size < 11: # wdt:項目番号の表示幅 wdt = 1 elif size < 101: wdt = 2 elif size < 1001: wdt = 3 elif size < 10001: wdt = 4 elif size < 100001: wdt = 5 elif size < 1000001: wdt = 6 else: # こんなことはない wdt = 7 w = [wdt, len(N), len(P), len(A), len(T), len(M)] # 各項目幅の初期値 if not ra: # raが空のときは住所録全体を表示する。 ra = list(range(size)) # book全体の項目番号が入る。 for i in ra: # raに入っているものの中から最大幅を求める。 q = da[i] # 住所録内の各個人データ for k in range(n): # 各項目について調べる。 w1 = adsub.len2(q.p[k]) # len2は全角半角を考慮した長さ if w1 > w[k+1]: # nameの幅がw[1]なので注意 w[k+1] = w1 # 表示されるものの中での最大幅を求める。 align = ["r", "l", "l", "l", "l", "l"] # 左寄せか右寄せか d = [" ", N, P, A, T, M] # 項目名行 print(adsub.makestr(len(w), align, w, d, ' ')) # Python標準機能ではうまく行かない。書式文字列f1も無意味。 # print(f1.format(i, pa[0], pa[1], pa[2], pa[3], pa[4])) # データの表示 for k in ra: pa = da[k].p d = [str(k), pa[0], pa[1], pa[2], pa[3], pa[4]] # Python標準機能ではうまく行かない # print(f1.format(k, pa[0], pa[1], pa[2], pa[3], pa[4])) # データの表示 print(adsub.makestr(len(w), align, w, d, ' '))