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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

328閲覧

Pythonで「入門書」と「アプリケーション製作」の橋渡し

totoki359

総合スコア14

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/09/25 11:26

Pythonの入門書を終え、いくつかネット上に転がっている練習問題みたいなものも解いてみて、とりあえずPythonの文法はだいたい分かった、みたいな状態です。

よって次にとりあえずそれなりの実用性を持つ小さなアプリケーションを作成してみました。(内容は後述)
しかし、コードを書いている途中で、「他の人はこんなに関数だらけのソースコードになるのか?」とか「ファイルは分割する必要があるのか?」とか、短いコードばかり書いていて、それなりの長さのコードを書いたことがない故の迷いがめちゃめちゃ生じました。

今回伺いたいのは主に2つです。
1.入門書の次にすぐ何か制作するというのは早すぎなのでしょうか?何か橋渡し的な本だったりがあるのでしょうか?

2.私の書いたソースコードで何か普通はやらないこと、おかしいことがあれば教えていただきたいです。

今回作成したのは複数の画像データについて、それぞれ形を整えて、中心にそれぞれの画像が寄せ集められたような一枚の画像を出力するというものです。
・imageという名前のディレクトリ内の画像データを読み込み、上下左右の白い余白を切り取る
・なるべく中心に画像が集まるように配置を決定する
・一枚の画像として出力
というような手順です。

他人に読まれることを想定していないわけのわからないコードなので、ソースコードの具体的な内容ではなく、もっと漠然とした、一般的な部分についておかしいところを指摘いただけるとありがたいです。
おそらくあらゆる点で稚拙なコードでお恥ずかしいのですが、回答いただけるとありがたいです、よろしくおねがいします。

該当のソースコード

Python

1 2from PIL import Image, ImageChops 3import math 4import os 5import random 6T = 1 7 8img_st = [] 9corner = [] 10 11def trim(im): 12 bg = Image.new(im.mode, im.size, '#ffffff') 13 diff = ImageChops.difference(im, bg) 14 bbox = diff.getbbox() 15 if bbox: 16 return im.crop(bbox) 17 18def converse(crd, size): 19 w = size[0]/2 20 h = size[1]/2 21 return ((crd[0]-w,crd[1]+h),\ 22 (crd[0]+w,crd[1]+h),\ 23 (crd[0]+w,crd[1]-h),\ 24 (crd[0]-w,crd[1]-h)) 25 26#中心の座標とサイズを追加 27def update(crd, size): 28 img_st.append(tuple((crd, size))) 29 corner.extend(converse(crd,size)) 30 31#2つの長方形が重なるときTrueを返す 32def is_overlapped(rct1, rct2): 33 dist_center = tuple(abs(x-y) for x,y in zip(rct1[0],rct2[0])) 34 total_len = tuple(x/2+y/2 for x,y in zip(rct1[1],rct2[1])) 35 return all(tuple(x<y for x,y in zip(dist_center, total_len))) 36 37def is_vacant(rct): 38 return all(tuple(not is_overlapped(st, rct) for st in img_st)) 39 40def evaluate_dist(crd): 41 return math.sqrt(T*pow(crd[0], 2) + pow(crd[1], 2)) 42 43#画像を置く座標を一つに決定 44def decide_center(crd, size): 45 center_list = converse(crd, size) 46 crd_list = [c for c in center_list if is_vacant((c,size)) ] 47 if crd_list == []: 48 return tuple() 49 else: 50 crd_list.sort(key = evaluate_dist) 51 return crd_list[0] 52 53def decide_location(size): 54 for c in corner: 55 t = decide_center(c,size) 56 if t==tuple(): 57 continue 58 else: 59 return t 60 61def export(): 62 x1 = max(corner, key = lambda x: x[0])[0] 63 x2 = min(corner, key = lambda x: x[0])[0] 64 y1 = max(corner, key = lambda x: x[1])[1] 65 y2 = min(corner, key = lambda x: x[1])[1] 66 canvas = Image.new('RGB', (int(x1-x2), int(y1-y2)), (255, 255, 255)) 67 68 for i in range(len(im_list)): 69 canvas.paste(im_list[i], [(int(img[0][0]-x2-img[1][0]/2),int(-img[0][1]+y1-img[1][1]/2)) for img in img_st][i]) 70 canvas.save('c.jpg', 'JPEG', quality=100, optimize=True) 71 72im_name = os.listdir('image') 73im_list = [trim(im) for im in [Image.open('image/'+s) for s in im_name]] 74im_list.sort(reverse=True, key = lambda x:x.size[0]*x.size[1]) 75 76for im in im_list: 77 if img_st == []: 78 update((0,0), im.size) 79 80 else: 81 crd = decide_location(im.size) 82 update(crd,im.size) 83 corner.sort(key = evaluate_dist) 84 85export()

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

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

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

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

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

guest

回答1

0

ベストアンサー

関数だらけ、というのは気にしなくていいです。
むしろ、メインルーチンには処理は書かなくて、全て関数の組み合わせだけで記述する、という勢いでいいです
#って、処理なしでは書けませんが

で、関数にする処理ですが、これはなにをしている関数か、というのを口で説明できるなら関数にしてしまいましょう。
短くてもOKOK、というよりダラダラ長いだけの関数は害悪です

投稿2018/09/25 11:34

y_waiwai

総合スコア87774

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

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

totoki359

2018/09/25 12:23

>これはなにをしている関数か、というのを口で説明できるなら関数にしてしまいましょう だいぶ頭の中がスッキリしました。 ありがとうございます!
y_waiwai

2018/09/25 13:07

プログラミング全般に言えることですが、「なにかやりたいこと」をいかにうまく分解できるか、がキモになります。 関数としては、あれとこれとそれと、、と画面をスクロールしなければ全容が見えないってのは長すぎで、 「あれ」と、「これ」と、「それ」と機能が明確でひと目で見れるような関数にすれば作り込みもやさしくバグも潰しやすくなります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問