質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

361閲覧

クラスを分けたいです。 python3

------.

総合スコア13

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/11/06 06:39

閲覧ありがとうございます。
入力したデータをもとに、ベースデータと加工データを作りたいと思っています。
このほかにも追加で入力したいデータがあり、Dataクラスを、BaseクラスとKakouクラスに分けたいです。
いろいろ試しましたが、引数の数が違うエラーが出たり、データが空になってしまったりして、私の力ではうまくできませんでした。
どうかご知恵を貸していただけたら幸いです。

また、まだまだ未熟なため、プログラムでこう記述したほうが良いという部分がありましたら、ご指摘いただけましたら幸いです。

よろしくお願いします。

main.py

python3

1from datainput import Data 2data_ins = Data() 3 4datalist = ['モデル1を入力', 'モデル2を入力','幅の数値を入力', 5 '奥行の数値を入力','高さの数値を入力','上部の数値を入力', 6 '左側の数値を入力','右側の数値を入力','下部の数値を入力',] 7 8def for_int(): 9 data = input() 10 if data: 11 data = int(data) 12 return data 13 else: 14 data = 0 15 return data 16 17 18def main(): 19 print('作るデータの数を教えてください。') 20 num_1 = int(input()) 21 for i in range(num_1): 22 print('データ',i+1,'を入力') 23 input_data = [] 24 input_data.append(i+1) 25 for j in datalist: 26 print(j) 27 k = for_int() 28 input_data.append(k) 29 data_ins.assign(input_data[0], input_data[1], input_data[2], 30 input_data[3], input_data[4], input_data[5], 31 input_data[6], input_data[7], input_data[8], 32 input_data[9], ) 33 data_ins.add_data() 34 data_ins.add_base() 35 data_ins.add_kakou() 36 data_ins.show_all() 37 data_ins.show_all2() 38 data_ins.show_all3() 39 40if __name__ == "__main__": 41 main()

datainput.py

python3

1class Data: 2 3 def __init__(self): 4 5 self.all_data = [] 6 self.base_items = [] 7 self.kakou_list = [] 8 9 10 11 def assign(self, data_number, data_model, data_model2, 12 data_width, data_depth, data_height, 13 top_t, left_t,right_t, 14 bottom_t,): 15 self.data_number = data_number 16 self.data_model = data_model 17 self.data_model2 = data_model2 18 self.data_width = data_width 19 self.data_depth = data_depth 20 self.data_height = data_height 21 self.top_t = top_t 22 self.left_t = left_t 23 self.right_t = right_t 24 self.bottom_t = bottom_t 25 26 27 def add_data(self): 28 self.all_data.append({'data_number' : self.data_number, 29 'data_model':self.data_model, 30 'data_model2': self.data_model2, 31 'data_width' : self.data_width, 32 'data_depth' : self.data_depth, 33 'data_height' : self.data_height, 34 'top_t': self.top_t, 35 'left_t' : self.left_t, 36 'right_t': self.right_t, 37 'bottom_t,': self.bottom_t, 38 }) 39 40 def show_all(self): 41 for i in self.all_data: 42 print(i) 43 44 45 46 def hantei_1(self): 47 if self.data_model == 1 or self.data_model ==3 or self.data_model == 5: 48 return 1 49 elif self.data_model == 2 or self.data_model ==4: 50 return 0 51 else: 52 return None 53 54 def hantei_2(self): 55 if self.data_model2== 1 or self.data_model2 == 2 : 56 return 0 57 elif self.data_model2 == 5 or self.data_model2 ==6: 58 return 1 59 elif self.data_model2 == 4 or self.data_model2 ==8 : 60 return 2 61 elif self.data_model2 == 3 or self.data_model2 ==7 : 62 return 3 63 else: 64 return 0 65 66 67 def add_base(self): 68 #黄色の部分の数値 69 self.base_items.append({'データ番号' : self.data_number, 70 'モデル1の判定' : self.hantei_1(), 71 'モデル2の判定': self.hantei_2(), 72 '幅' : self.data_width, 73 '深さ' : self.data_depth, 74 '高さ' : self.data_height, 75 '上部':self.top_t, 76 '左側':self.left_t, 77 '右側':self.right_t, 78 '下部':self.bottom_t, }) 79 80 def show_all2(self): 81 for i in self.base_items: 82 print(i) 83 84 85 def top_1(self): 86 if self.hantei_1() == 1: 87 return self.data_width 88 elif self.hantei_1() == 0: 89 return self.data_width - self.left_t - self.right_t 90 else: 91 return 'error' 92 93 94 95 96 def bottom_1(self): 97 if self.data_model == 1 or self.data_model == 2: 98 return self.data_width - self.left_t - self.right_t 99 elif self.data_model == 3 or self.data_model ==4: 100 return self.data_width 101 elif self.data_model == 5 or self.data_model == 7: 102 return self.data_width - self.left_t 103 elif self.data_model == 6 or self.data_model == 8: 104 return self.data_width -self.right_t 105 else: 106 return 0 107 108 def add_kakou(self): 109 self.kakou_list.append({'データ番号' : self.data_number, 110 '上部加工長さ':self.top_1(), 111 '右側加工長さ':5, 112 '左側加工長さ':3, 113 '下部加工長さ':self.bottom_1(), 114 }) 115 116 def show_all3(self): 117 for i in self.kakou_list: 118 print(i)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2018/11/06 06:51 編集

もしサイトや書籍等を参考にしているのであれば、何を参考にしたのか書いてください。そして勉強が目的であれば、はっきり言ってあまり良い題材とは思えないのですが・・・
------.

2018/11/06 06:59

サイトや本は以前に読みましたが、自分でコードを書きました。自分が作りたいものがあって、それを作るために必要なデータを取得するためにこのコードを書いているので、勉強として多少不適切であっても、この件についての回答をご教授頂けると幸いです。
guest

回答1

0

ベストアンサー

とりあえず、つい最近よく似たコード構成の質問を見たので、参考に貼っておきます。

Python 3.x - inputで空白か数値のどちらかを入力したいのと、classで作った辞書データの修正がしたいです。|teratail

もしよろしければ、一体なんという本を参考にしたのか、後学のためにご教授ください。


ツッコミどころはたくさんあります。

データの数だけ変数を作るのは正気の沙汰ではありません。

python

1 data_ins.assign(input_data[0], input_data[1], input_data[2], 2 input_data[3], input_data[5], input_data[4], 3 input_data[6], input_data[7], input_data[8], 4 input_data[9], )

とりあえず、愉快ではないのは確かです。

アンパック機能を使えばこんな感じで書けたりします。

python

1 data_ins.assign(*input_data)

こうなると、受け取る側の冗長さが気になります。

python

1 def assign(self, data_number, data_model, data_model2, 2 data_width, data_depth, data_height, 3 top_t, left_t,right_t, 4 bottom_t,): 5 self.data_number = data_number 6 self.data_model = data_model 7 self.data_model2 = data_model2 8 self.data_width = data_width 9 self.data_depth = data_depth 10 self.data_height = data_height 11 self.top_t = top_t 12 self.left_t = left_t 13 self.right_t = right_t 14 self.bottom_t = bottom_t 15 16 17 def add_data(self): 18 self.all_data.append({'data_number' : self.data_number, 19 'data_model':self.data_model, 20 'data_model2': self.data_model2, 21 'data_width' : self.data_width, 22 'data_depth' : self.data_depth, 23 'data_height' : self.data_height, 24 'top_t': self.top_t, 25 'left_t' : self.left_t, 26 'right_t': self.right_t, 27 'bottom_t,': self.bottom_t, # ミスってるし・・・ 28 })

とりあえずクラス変数keysでも作ってみたらどうですか。

python

1class Data: 2 keys = ['data_number', 'data_model', 'data_model2', 'data_width', 'data_depth', 'data_height', 'top_t', 'left_t', 'right_t', 'bottom_t']

ちゃんと動くかは確認していませんが、以下のような方針で元のコードと同じことができます。

python

1 def assign_and_add_data(self, *args): 2 self.all_data.append(dict(zip(Data.keys, args)))

タイピング量は1/10以下になり、たぶん保守管理もしやすくなったでしょう。

ところで、最初のコードはオリジナルから2箇所書き換えたんですが、気づきましたか? 私がいきなり見せられたら見落とす自信があります。見落とすということは、凡ミスがあっても、バグが埋もれていても、気づけないということです。こういうコードは困ったコードです。


DataクラスをBaseクラスとKakouクラスに分ける場合、文字通り解釈するのであればクラスを継承することになります。

python

1class Base(Data): 2 ... # 変更点についてはメソッドをオーバーライド 3 4class Kakou(Data): 5 ... # 変更点についてはメソッドをオーバーライド 6

ただ、元のDataクラスが汎用性の高い作りにはなっていないので、show_all()は使い回せると思いますが、他はすべて書き直すことになると思います。何のために継承しているのかよくわからない事態になりそうです。

ちょっと判断に迷いますが、できれば入力処理には汎用性をもたせて流用したいところですね。内部の判定などのロジックは変わると思うので、そういった部分だけ書き換えれば済むようにします。当然、それを前提にしたデータ構造にする必要があるでしょう。

なお、質問文のコードでやっているのは「クラスを分ける」といった行為ではなく、「一つのクラスになんでも書いてしまう」という行為です。これを俗に神クラスと言ったりします。典型的なアンチパターン(不適当とされるコードのパターン)の一つです。


こんな感じで改善していくことはできると思いますが、どこまでやっても、車輪の再発明にしかなりません。

データを入れて管理したいのなら、データベースを使うとか、pandasを使うといった優れた方法があるからです。

「作りたいものがある」ならむしろそちらを先に覚えることをおすすめします。

投稿2018/11/06 07:38

編集2018/11/06 08:54
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

------.

2018/11/06 08:38

ご回答ありがとうございます。 私が勉強に使いましたのは、一般的な本(オライリージャパンの本や独学プログラマー、paizaやteratail、pyQなど)です。 恥ずかしながら、ご回答いただいたやり方は、知識としては知っておりました。 ですが、エラーが出てしまい、別の方法をとることにしました。 (*input_dataがなぜエラーになったのかはわかりませんが、リストは入れられません、みたいなエラーでした。key変数は、式の作り方が悪く、思うような答えが出せませんでした。) その結果、この部分について別のやり方を手当たり次第に試して、このような式になりました。 ですから、これらの本が悪書というわけではなく、単に私の理解力の問題であると思います。 クラスだと、継承になってしまうのですね。 確かに、一つのクラスになんでも書いてしまうのは、よくないですね。 色々と、とても勉強になりました。 ご長文での回答を感謝いたします。 pandasなど本腰をいれて勉強してみようと思います。
------.

2018/11/06 08:54

それから、修正いただいた個所はわかりませんでした。 spyderでもエラーが出ていなかったので、そのような作り方はよくないですし気を付けようと思います
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問