1
2

More than 3 years have passed since last update.

Python初心者(中学生)のコードをガチでリファクタしてみた

Last updated at Posted at 2019-11-13

中学生の書いたPythonプログラム。はじめてにしてはよくできてました。
最初は、どんな書き方でも動けばよい。だと思います。

でも難しいプログラムを作れるようになるためには、頭の中を整理して、分かりやすくプログラムにする事も大切です。このプログラムを例題に、書き直してみました。

オリジナルプログラム

きれいな図形描けましたねぇ。
カラフルな色合いの出し方を工夫していて素晴らしいです。
if文の条件分けや、計算式よく考えて作りましたね。

number = int(input("いくつの円を書きますか?"))
R = 1.0
G = 0.0
B = 0.0
color = 0
from turtle import *
delay(5)
shape("turtle")
for i in range(number):
    color = int(360/number*i)
    if color <= 60:
        R = 1.0
        G = color/60
        B = 0.0
    elif color <= 120:
        R = 2.0-color/60
        G = 1.0
        B = 0.0
    elif color <= 180:
        R = 0.0
        G = 1.0
        B = color/60-2.0
    elif color <= 240:
        R = 0.0
        G = 4.0-color/60
        B = 1.0
    elif color <= 300:
        R = color/60-4.0
        G = 0.0
        B = 1.0
    elif color <= 360:
        R = 1.0
        G = 0.0
        B = 6.0-color/60

    pencolor(R,G,B)
    circle(100)
    left(360/number)
done()

実行結果
lessen_turtle.png

料理開始

importは最初に移動
RGB値を求める部分は関数化
if文の中の数式の規則性が見えてこない。試行錯誤して作ったんだろう。同じ結果になる規則性のある式に変更。
if文の条件式に = が入ってるけど、=を除いても結果は変わらない。colorの
範囲が0~359であることを考えると= つけない方が本質に合ってそう。

import turtle

def color2rgb(color):
    if color < 60:
        R = 1.0
        G = color/60
        B = 0.0
    elif color < 120:
        R = 1.0-(color-60)/60
        G = 1.0
        B = 0.0
    elif color < 180:
        R = 0.0
        G = 1.0
        B = (color-120)/60
    elif color < 240:
        R = 0.0
        G = 1.0-(color-180)/60
        B = 1.0
    elif color < 300:
        R = (color-240)/60
        G = 0.0
        B = 1.0
    elif color < 360:
        R = 1.0
        G = 0.0
        B = 1.0-(color-300)/60
    return(R, G, B)

def draw(number):
    turtle.delay(5)
    turtle.shape("turtle")
    for i in range(number):
        color = int(360 / number * i)
        turtle.pencolor(color2rgb(color))
        turtle.circle(100)
        turtle.left(360 / number)
    turtle.done()

number = int(input("いくつの円を書きますか?"))
draw(number)

さらに

color2rgb()は、よく見るとR,G,Bの値は位相が120ずれた同じ形。
if文をやめてテーブル化もできる。
でもテーブル化するとちょっと可読性が下がりそう。これくらいにしておこうか。

import turtle

def color2r(color):
    color = color % 360
    if color < 60:
        R = 1.0
    elif color < 120:
        R = 1.0-(color-60)/60
    elif color < 180:
        R = 0.0
    elif color < 240:
        R = 0.0
    elif color < 300:
        R = (color-240)/60
    elif color < 360:
        R = 1.0
    return R

def color2rgb(color):
    return color2r(color), color2r(color-120), color2r(color-240)

def draw(number):
    turtle.delay(5)
    turtle.shape("turtle")
    for i in range(number):
        color = int(360 / number * i)
        turtle.pencolor(color2rgb(color))
        turtle.circle(100)
        turtle.left(360 / number)
    turtle.done()

number = int(input("いくつの円を書きますか?"))
draw(number)

番外編

頂いたコメントみていて、イメージが膨らんだので、関数テーブル版作ってみました。読みやすいかはわかりませんが、私好み。

import turtle

convert_func_table = [lambda x: 1.0, lambda x:1.0-x/60, lambda x:0, lambda x:0, lambda x:x/60, lambda x:1.0]

def convert(i,fine):
    return convert_func_table[i%6](fine)

def color2rgb(color):
    i, fine = divmod(color, 60)
    return (
        convert(i, fine),
        convert(i+4, fine),
        convert(i+2, fine),
    )

def draw(number):
    turtle.delay(5)
    turtle.shape("turtle")
    for i in range(number):
        color = int(360/number*i)
        turtle.pencolor(color2rgb(color))
        turtle.circle(100)
        turtle.left(360/number)
    turtle.done()

number = int(input("いくつの円を書きますか?"))
draw(number)

K君、プログラム提供してくれてありがとう。

1
2
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2