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

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

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

# オリジナルプログラム

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

```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/b8c51563-0d9d-bdb9-4886-10cf3b080809.png)

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


```python
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文をやめてテーブル化もできる。
でもテーブル化するとちょっと可読性が下がりそう。これくらいにしておこうか。

```python
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)
```

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

```Python
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君、プログラム提供してくれてありがとう。