UdemyでPythonを勉強した結果を残すブログ。

40歳でプログラミング始めて転職までいけるのかを実録してみます。

DAY23 Turtleモジュールをもっと応用して障害物よけゲームを作る

今回はTurtleモジュールを使ってもう1個ゲームを作る講座。

今回は障害物よけゲームです。

Udemyの講座では長方形が動くようにしていますが、

自分のは復習と応用も兼ねてshapeをタートルにしてクリアするたびに難易度があがる設定を追加しています。

クラッチから書けたので、コーディング自体は荒削りだと思います。

 

クラッチからってなんだよって始めたとき思ってたけど

「最初から」ということなんですね。

フルスクラッチでというのはネットからのコピペもなしでということ…すごいわ

 

こんな感じのゲームイメージ

白い亀がタートルから通り過ぎるタートルを避けて上まで通り抜けるというゲーム。

f:id:GO-py:20220409093531p:plain

 

流れとしてはこんな感じ

  • プレイヤーのタートルを作り、下からスタートする。
    上のみ動ける仕様にする。
  • 敵のクラスを作る。色はランダムにし、動くスピードもランダムにする。
    右端でy軸はランダムに設置していく。
  • 上に行ったらゴール・次のレベルを表示し、下に戻る。

 

それでは始めます。

 

プレイヤーのクラスを作る

tim.py 

これは今までの流れからすると難しいことはしていないので

全部のコードを。

 

from turtle import Turtle
import random
START_POSITION = (0, -280)

class Tim(Turtle):

def __init__(self):
super(Tim, self).__init__()
self.shape("turtle")
self.color("white")
self.penup()
self.setheading(90)
self.start()
self.goto(START_POSITION)

def start(self):
self.goto(random.randint(-200, 200), -280)

def move(self):
new_y = self.ycor() + 20
self.goto(self.xcor(), new_y)

udemyの講座だと常にx軸は真ん中からのスタートにしたけど

今回はゴールするたびにx軸も-200から200の間の何処かからのスタートに。

 

 

次に、横切るタートルのクラスを作成

enemies.py

main.pyでたくさんのタートルを作るため、このクラスの初期値では

作るたびにタートルの色とはじまる位置を変更する機能をいれます。

右から左にいくので、頭の位置は左向きに。

 

from turtle import Turtle
import random


class Enemies(Turtle):
def __init__(self):
super(Enemies, self).__init__()
self.shape("turtle")
self.penup()
col_r = random.randint(100, 255)
col_g = random.randint(100, 255)
col_b = random.randint(100, 255)
random_y = random.randint(-250, 250)
self.color(col_r, col_g, col_b)
self.setheading(180)
self.goto(300, random_y)

 

ランダムなスピードで歩く機能を追加します。

スピードは毎回違うように設定します。

 


def move(self):
new_x = self.xcor() - random.randint(4, 20)
self.goto(new_x, self.ycor())

 

これで横切るタートルの設定はおしまい。

 

 

メッセージ表示部分のクラスを作成

msg.py

  • 左上に現在のレベル表示
  • 上に着いたらゴール!次のレベルを表示
  • 敵に当たったらゲームオーバー

の3つを表示する機能を作ります。

 

from turtle import Turtle
import time

class Msg(Turtle):
def __init__(self):
super(Msg, self).__init__()
self.color("white")
self.penup()
self.ht()
self.level_num = 1
self.display_level()

初期値はこんな感じ。

display_levelは左上にgoto()して、writeでlevel_numの変数を呼び出して表示します。

 


def display_level(self):
self.clear()
self.goto(-280, 260)
self.write(f"Level {self.level_num}", font=("Futura", 20, "bold"), align="left")

 

ゴールしたときの表示はこんな感じ

レベル表示で書く位置が左上に行ってるので、最初にgoto(0, 0)にしてから書く。

ここでimportしたtimeを使います。Goal!と2秒表示、その後次のレベルを2秒表示。

 


def goal(self):
self.goto(0, 0)
self.clear()
self.write("Goal!!", font=("Futura", 40, "bold"), align="center")
time.sleep(2)
self.clear()
self.level_num += 1
self.write(f"Level {self.level_num}", font=("Futura", 40, "bold"), align="center")
time.sleep(2)
self.clear()

 

負けたらゲームオーバーのテキストを真ん中に表示します。


def game_over(self):
self.goto(0, 0)
self.write("Game Over.", font=("Futura", 20, "bold"), align="center")

 

これでクラスファイルの作成は終わり。

 

 

main.pyでオブジェクトをまとめてゲームにしていく

仕上げていきます。

今まで作ったものは全てインポートして、こちらもscreen, timeなどもインポートしていきます。

 

from turtle import Screen
from tim import Tim
from msg import Msg
from enemies import Enemies
import random
import time

tim = Tim()
msg = Msg()
screen = Screen()
screen.colormode(255)
screen.setup(600, 600)
screen.bgcolor("black")
screen.tracer(0)

enemies_list = []

screen.listen()
screen.onkey(tim.move, "Up")

 

enemies_list のリストは、スネークゲームの時と同じように

敵のタートルを1つずつリストに格納していってそれぞれが独立したランダムな動きをするために設定しています。

 

screen.listen()とonkey()のセットで、上のキーを押すたびに上にあがる機能に。

 


difficulty = [0,1,0]

game_on = True
while game_on:
screen.update()
    time.sleep(0.1)
for i in range(random.choice(difficulty)):
enemies = Enemies()
enemies_list.append(enemies)

for enemie in enemies_list:
enemie.move()
if enemie.xcor() <= -330:
enemies_list.remove(enemie)

if tim.distance(enemie) <= 20:
msg.game_over()
game_on = False

difficultyのリストは敵のタートルを出現するときに何人追加するかをランダムで決めるためのリストです。

whileで動かすたびに敵を作ってたら大渋滞になるので(試しにこのリストを1,1とかにしてみてください)

作らない時もあるようにしています。

 

で作ったらenemies_listに格納していって、次のforでそれぞれを動かしていきます。

xcor() <= -330の部分のifは、敵のタートルが左端にいってもそのままにしとくと

オブジェクトはずっとたまっていくので、リストがどんどん増えていきます。

超上級者がいた場合もしかしたら動きがもっさりする可能性もあるので、

敵のタートルが左端へ消えたらリストから削除するようにremoveを入れています。

 

また最後に敵タートルにぶつかったときに

ゲームオーバーの文字を表示すると同時にgame_on = Falseにして動きをストップしています。

 

time.sleepはゲームスピードを調整しています。

ここをいじることで難易度がより調整できます。

 


if tim.ycor() >= 300:
msg.goal()
for enemie in enemies_list:
enemie.goto(-320, enemie.ycor())
if len(difficulty) <= 8:
difficulty.append(1)
else:
difficulty.append(random.randint(1,2))
tim.start()
msg.display_level()

screen.exitonclick()

 

仕上げに、プレイヤーが上に行ったときの表示を設定していきます。

難易度の調整もゴールに行ったときにしていて、

difficultyのリスト数が8以下ならリストに1を追加していって敵タートルの出現確率を上げるようにしています。

さらにLEVEL 6以降は出現数を2にしたりもして難易度を上げるようにしています。

 

最後にscreen.exitonclick()で締め。

 

 

今回は復習ということでとりあえず自分で作れるなら作ってみよう、

どうせ作れなさそうだしあとで動かないところお手本ソースコピーして勉強しよう

くらいに思ってたら全部作れたので嬉しい。笑

 

 

今回の全てのコードはGitに上げています。

実務だとGitもいるだろうし今回からはGitでアップロードするようにします。

 

github.com

DAY22 Turtleモジュールを使ってピンポンゲームを作る

Angela Yu先生による22日目の講座実践。

今回はTurtleモジュールをさらに応用してレトロゲームのピンポンゲームを作ります。

 

 

f:id:GO-py:20220407121049p:plain

pong game

 

両端にバーがあって、キーボードで動かして、

ボールを跳ね返していき、はねかえせずにバーを通り過ぎてしまったら負け。

ゲーセンのホッケーみたいな感じですね。

 

それでは始めます。

流れとしては

  • スクリーンを用意して、上部にスコアを表示。また負けたらメッセージを表示
  • 両端にバーを表示。キーボードで動かせるようにする
  • 常に動くボールを用意。上下とバーに当たったら跳ね返るようにする。

 

それぞれのクラスの定義とスクリーンの基本表示

 

main.py

from turtle import Screen
from bar import Bar
from scoreboard import ScoreBoard
from ball import Ball
import time

screen = Screen()
screen.bgcolor("black")
screen.setup(800, 600)
screen.title("PONG")

screen.tracer(0)

ball = Ball()
score_board = ScoreBoard()

ざっくりとここまで。

from …のbar,scoreboard, ball部分とそれぞれの定義は

後でそれぞれを書いていくので今書いても、書かなくても。

 

前回と同じくscreenでスクリーンを定義して、setupでサイズを設定。

背景を黒に、ウィンドウのタイトルをPONGにしています。

 

またアニメーションをスムーズにするためのscreen.tracer(0)も記載。

後でscreen.update()も書きます。

 


screen.listen()
screen.onkey(bar_r.go_up, "[")
screen.onkey(bar_r.go_down, "]")
screen.onkey(bar_l.go_up, "q")
screen.onkey(bar_l.go_down, "a")

キーボード入力で動くようにするのはscreen.listen()からの.onkey設定で。

これもとりあえず右のバーは[ ]を押すことで上下へ動くように、

左のバーはq a で動くように設定。

 


game_on = True
while game_on:

screen.update()

screen.exitonclick()

 

とりあえずゲームが進む基本的なところまで。

 

 

両端にバーを表示する

次にbarのクラスをコーディングしていきます。

bar.py

 

from turtle import Turtle

class Bar(Turtle):
def __init__(self,x, y):
super(Bar, self).__init__()
self.shape("square")
self.color("white")
self.penup()
self.shapesize(5, 1)
self.goto(x,y)

turtleをインポートして機能を継承できるようにBar()の中にTurtleを入れる。

super().__init__()を結構忘れてしまうのでセットで覚えておいた方がいい。

以下部分は前回もやったけどshapesize(5,1)部分はやってないので説明すると

そのshapeの縦横比率を設定できる。

 

main.pyにもbarを定義する。

main.pyに書くよ
bar_l = Bar(-360, 40)
bar_r = Bar(350, 40)

 

スネークゲームのときは1つ1つが前を追うように動いてたので設定しなかったけど

今回のバーの場合は上下しか動かないのでfor . in で1こずつ作る必要がない。

shapesize()で設定するだけで縦がブロック5個分の長さを持つバーが出来上がる。

 

上下に動くファンクションを作る

バーのy座標を取得して、それより20上、または下にいくようにする。

今回のdef のなまえはmain.pyに書いたscreen.onkeyの最初の関数と同じもので。


def go_up(self):
new_y = self.ycor() + 20
self.goto(self.xcor(), new_y)

def go_down(self):
new_y = self.ycor() - 20
self.goto(self.xcor(), new_y)

 

これでbar.pyは終わり。

 

 

ball.pyでボールクラスを作る

ball.py

まずは初期値を設定する。ボールの大きさ、色などに加えて

常に動く数値も設定する。

 

from turtle import Turtle

class Ball(Turtle):
def __init__(self):
super(Ball, self).__init__()
self.shape("circle")
self.color("yellow")
self.shapesize(1)
self.penup()
self.x_move = 10
self.y_move = 10

 

次に常に動く機能を実装する

現在のxとyの位置を取得して、上に設定したx_moveとy_move分動くように。


def move(self):
new_x = self.xcor() + self.x_move
new_y = self.ycor() + self.y_move
self.goto(new_x, new_y)

 

当たったら跳ね返る機能を実装する

ycor()でスクリーンサイズからはみ出たら、y_move に -1をかけて逆にいくようにする。

上に行ったら 10 x -1 で-10で下にいくように。

 


def bounce_y(self):
self.y_move *= -1

同じ要領でバーに当たったら跳ね返る機能も実装。


def bounce_x(self):
self.x_move *= -1

 

最後に、どちらかが勝った時はボールが真ん中に戻るようにする機能も実装。


def ball_reset(self):
self.goto(0, 0)
self.ball_speed = 0.1
self.bounce_x()

 

これで終わり。

 

スコア・メッセージを表示するクラスの定義

最後のクラスでスコアボードを実装。

from turtle import Turtle
import time

class ScoreBoard(Turtle):
def __init__(self):
super(ScoreBoard, self).__init__()
self.penup()
self.ht()
self.color("white")
self.l_score = 0
self.r_score = 0
self.write_score()

def write_score(self):
self.clear()
self.goto(-100, 260)
self.write(self.l_score, align="center", font=("Futura", 30, "italic"))
self.goto(100, 260)
self.write(self.r_score, align="center", font=("Futura", 30, "italic"))

 

初期値は0点にして、init ではなく別でスコアを書く機能を実装しています。

勝ったときにスコアを書き換えるので流用するためです。

書くときは毎回文字をクリアしてから指定の場所にいって、書いて、いって、書いて。

 

どちらかが勝ったときに点数を加算し、メッセージを書いて少しポーズする

最後にどちらかが勝ったときにポイントを追加する。

udemyにはなかったけど左の勝ち!みたいなメッセージ欲しいなと思って

昨日追加。

右と左で処理を分けたいので、アーギュメントがrightかleftで動作を変えるようにする。

 


def get_point(self, player):
self.goto(0, 0)
if player == "left":
self.l_score += 1
self.write("Left Player WIN!", align="center", font=("Futura", 45, "italic"))
elif player == "right":
self.r_score += 1
self.write("Right Player WIN!", align="center", font=("Futura", 45, "italic"))
time.sleep(3)
self.write_score()

 

 

再度main.pyにて動作を実装していく

再度main.pyに戻って、whileの内側に作った機能を盛り込んでいきます。

 

  • ボールが動き続ける
  • ボールが上か下の端にいったら跳ね返る
  • バーにあたったら跳ね返る
  • ボールが右端、または左端にいったら勝利者にポイントとメッセージが表示

これをそのままコーディングしていきます。

 


game_on = True
while game_on:
ball.move()

if ball.ycor() >= 280 or ball.ycor() <= -280:
ball.bounce_y()

if ball.xcor() >= 400:
score_board.get_point("left")
ball.ball_reset()

if ball.xcor() <= -400:
score_board.get_point("right")
ball.ball_reset()

if bar_l.distance(ball) < 30 and ball.xcor() <= -340 or bar_r.distance(ball) < 30 and ball.xcor() >= 310:
ball.bounce_x()
screen.update()

screen.exitonclick()

 

これでほぼ完成!

 

 

長く続くほどにボールスピードの上がる機能を実装

同じスピードだと上手くなるごとに延々と続けれる可能性が出てくるので、

ボールのスピードを上げていくようにします。

 

まずball.pyの__init__部分にball_speedを定義。


class Ball(Turtle):
def __init__(self):
super(Ball, self).__init__()
self.shape("circle")
self.color("yellow")
self.shapesize(1)
self.penup()
self.x_move = 10
self.y_move = 10
self.ball_speed = 0.1

 

跳ね返るごとに少しずつ早くしていきます。

ただ、どちらかが負けたときにはボールスピードを初期値に戻します。

 


def bounce_x(self):
self.x_move *= -1
self.ball_speed *= 0.9

def ball_reset(self):
self.goto(0, 0)
self.ball_speed = 0.1
self.bounce_x()

 

この設定を実装するように、main.pyで設定。

 


game_on = True
while game_on:
time.sleep(ball.ball_speed)
ball.move()

 

これで完成!

 

 

全てのコードは

main.py

from turtle import Screen
from bar import Bar
from scoreboard import ScoreBoard
from ball import Ball
import time

screen = Screen()
screen.bgcolor("black")
screen.setup(800, 600)
screen.title("PONG")

screen.tracer(0)

ball = Ball()
score_board = ScoreBoard()

bar_l = Bar(-360, 40)
bar_r = Bar(350, 40)

screen.listen()
screen.onkey(bar_r.go_up, "[")
screen.onkey(bar_r.go_down, "]")
screen.onkey(bar_l.go_up, "q")
screen.onkey(bar_l.go_down, "a")

game_on = True
while game_on:
time.sleep(ball.ball_speed)
ball.move()

if ball.ycor() >= 280 or ball.ycor() <= -280:
ball.bounce_y()

if ball.xcor() >= 400:
score_board.get_point("left")
ball.ball_reset()

if ball.xcor() <= -400:
score_board.get_point("right")
ball.ball_reset()

if bar_l.distance(ball) < 30 and ball.xcor() <= -340 or bar_r.distance(ball) < 30 and ball.xcor() >= 310:
ball.bounce_x()
screen.update()

screen.exitonclick()


ball.py

from turtle import Turtle


class Ball(Turtle):
def __init__(self):
super(Ball, self).__init__()
self.shape("circle")
self.color("yellow")
self.shapesize(1)
self.penup()
self.x_move = 10
self.y_move = 10
self.ball_speed = 0.1

def move(self):
new_x = self.xcor() + self.x_move
new_y = self.ycor() + self.y_move
self.goto(new_x, new_y)

def bounce_y(self):
self.y_move *= -1

def bounce_x(self):
self.x_move *= -1
self.ball_speed *= 0.9

def ball_reset(self):
self.goto(0, 0)
self.ball_speed = 0.1
self.bounce_x()

bar.py

from turtle import Turtle


class Bar(Turtle):
def __init__(self,x, y):
super(Bar, self).__init__()
self.shape("square")
self.color("grey")
self.penup()
self.shapesize(4, 1)
self.goto(x,y)

def go_up(self):
new_y = self.ycor() + 20
self.goto(self.xcor(), new_y)

def go_down(self):
new_y = self.ycor() - 20
self.goto(self.xcor(), new_y)

scoreboard.py

from turtle import Turtle
import time


class ScoreBoard(Turtle):
def __init__(self):
super(ScoreBoard, self).__init__()
self.penup()
self.ht()
self.color("white")
self.l_score = 0
self.r_score = 0
self.write_score()

def write_score(self):
self.clear()
self.goto(-100, 260)
self.write(self.l_score, align="center", font=("Futura", 30, "italic"))
self.goto(100, 260)
self.write(self.r_score, align="center", font=("Futura", 30, "italic"))

def get_point(self, player):
self.goto(0, 0)
if player == "left":
self.l_score += 1
self.write("Left Player WIN!", align="center", font=("Futura", 45, "italic"))
elif player == "right":
self.r_score += 1
self.write("Right Player WIN!", align="center", font=("Futura", 45, "italic"))
time.sleep(3)
self.write_score()


 

 

 

 

 

DAY20-21 タートルモジュールを使ってスネークゲームを作る

f:id:GO-py:20220403114146p:plain

snake game


DAY 19 20の二日間ではタートルモジュールを使って

レトロゲームのスネークゲームを作ります。

 

スネークを上下左右に操って、丸い餌を食べることで

体がとスコアが1つずつ増えていってどれだけスコアを上げられるかというゲームです。

 

ざっくりした流れは

  • 餌を食べるスネークを作る
  • ランダムに現れる餌を作成する
  • スネークが餌を食べたら増えるスコアを作成する
  • 四方の壁か自分の体に先頭が当たったらGameOver

こんな感じ。

 

それでは始めます。

 

初めにスネークから。

Turtleのshapeをsquareにして最初は3つに並べれば

体ができる。

ただ、餌を食べれば増えていくので初めにおきたい場所だけ設定しておいて、その後は最後尾に増えるようなコーディングにしたい。

 

snake.py

from turtle import Turtle
STARTING_POSITIONS = [(0, 0), (-20, 0), (-40, 0)]

class Snake:
def __init__(self):
self.snake_body = []
for i in STARTING_POSITIONS:
self.add_body(i)
self.head = self.snake_body[0]


def add_body(self, position):
new_body = Turtle("square")
new_body.color("white")
new_body.penup()
new_body.goto(position)
self.snake_body.append(new_body)

 

初期値でsnake_bodyというリストを作り、

add_bodyで四角をSTARTING_POSITIONにある3つの位置に置く。

 

4つ目以降は一番最後に置くようにする。


def increase_snake(self):
self.add_body(self.snake_body[-1].position())

def move(self):
for seg_num in range(len(self.snake_body)-1, 0, -1):
new_x = self.snake_body[seg_num - 1].xcor()
new_y = self.snake_body[seg_num - 1].ycor()
self.snake_body[seg_num].goto(new_x, new_y)
self.head.forward(20)

 

moveのrangeの内容はスネークの最後から順次20ずつ進むようにしているのは、アニメーションと体が増えるときに違和感のないようにしている。

 

というのも、最初に頭から移動すると、

1■■■

2■■ ■

3■ ■■

4 ■■■

と言う感じになって体1つ分隙間ができてしまう。

逆からやると、

1■■■

2 ■■ (左から2つ目が重なる)

3 ■■ (左から3つ目が重なる)

4 ■■■

と言う感じで体が離れずに進むことができる。

 

また、体が一つ増える分に関しては

snake_bodyの一番最後の場所を取得してから進み、

最後にその場所に四角を増やす、という仕組み。

同じような流れで言うと、

1■■■

2 ■■ (左から2つ目が重なる)

3 ■■ (左から3つ目が重なる)

4 ■■■

5■■■■(最後のpositionに新しい体を追加する)

6 ■■■(同じように進む)

 

最後に、上下左右に向きを変えるようための動作

 

UP = 90
DOWN = 270
RIGHT = 0
LEFT = 180

def up(self):
if self.head.heading() != DOWN:
self.head.setheading(UP)

def down(self):
if self.head.heading() != UP:
self.head.setheading(DOWN)


def left(self):
if self.head.heading() != RIGHT:
self.head.setheading(LEFT)


def right(self):
if self.head.heading() != LEFT:
self.head.setheading(RIGHT)

 

これでsnake.pyは終わり。

 

 

次に、food.pyとしてエサのクラスを作成する

food.py

これはシンプルに、エサの形状と

ランダムに表示される設定を作成する。

 

from turtle import Turtle
import random

class Food(Turtle):
def __init__(self):
super().__init__()
self.shape("circle")
self.color("yellow")
self.shapesize(0.3)
self.penup()
self.refresh()

def refresh(self):
random_x = random.randint(-280, 280)
random_y = random.randint(-280, 280)
self.goto(random_x, random_y)

 

food = Turtle()をつけなくてもclassのかっこにimportをいれて、

__init__下部分にsuper().__init__()

を入れることでTurtle()と同じことができるようになる。

 

次にスコアを表示

score_board.py

 

from turtle import Turtle

class ScoreBoard(Turtle):
def __init__(self):
super(ScoreBoard, self).__init__()
self.score = 0
self.penup()
self.ht()
self.goto(0, 270)
self.color("white")
self.get_score()

def get_score(self):
self.write(f"Score : {self.score}", font=("Sans", 20, "bold"), align="center")

def game_over(self):
self.goto(0, 0)
self.write("Game Over.", font=("Sans", 20, "bold"), align="center")

def increase_score(self):
self.clear()
self.score += 1
self.get_score()

 

スコアでは文字を取り扱うパーツにする。

スコアを初期値は0にして、get_scoreで表示をする。

 

スクリーンに文字を入れるには.writeメソッドを使う。

.write("表示したい文字", font=("フォント". 文字の大きさ,"太字とかイタリックとか", align="centerとか")

 

で文字の装飾も可能。

 

 

main.pyでゲームをまとめていく

それぞれのクラスが設定できたので、まとめる。

 

まずはそれぞれを呼び出して、ウィンドウの設定をしていく。

 

from turtle import Turtle, Screen
from snake import Snake
from food import Food
from score_board import ScoreBoard
import random
import time

screen = Screen()
screen.setup(600, 600)
screen.bgcolor("black")
screen.title("Snake Game")
screen.tracer(0)

snake = Snake()
food = Food()
score = ScoreBoard()

 

.tracerについては後述。

前回のタートルゲームでやったキーを押すことでウィンドウ内にアクションができる機能 listen()とonkey()を入力して上下左右に向きを変えられるようにする。

 


screen.listen()
screen.onkey(snake.up, "Up")
screen.onkey(snake.down, "Down")
screen.onkey(snake.left, "Left")
screen.onkey(snake.right, "Right")

 

ゲーム開始部分に。

ゲームが終わるまではずっとスネークが動かせるようにする。

スネークが四方にはみ出たらゲームオーバー。

また、スネークが自分の体にあたってもゲームオーバー。

スネークがエサを食べたら体が伸びてスコアもアップする。

この3つを盛り込めば完成。


start_game = True
while start_game:
screen.update()
time.sleep(0.5)
snake.move()
if snake.head.distance(food) < 20:
food.refresh()
score.increase_score()
snake.increase_snake()

if snake.head.xcor() >= 300 or snake.head.xcor() <= -300 or \
snake.head.ycor() >= 300 or snake.head.ycor() <= -300:
score.game_over()
start_game = False

for snake_body in snake.snake_body:
if snake_body == snake.head:
pass
elif snake.head.distance(snake_body) < 10:
score.game_over()
start_game = False

screen.exitonclick()

 

エサを食べるというのはどう言う判定をするか、というのは

スネークの頭とエサの距離が20以下になったら、と判定する。

(スネークの体1つが20なので)

それができるのがdistance関数。1つ目のifがそのコード。

 

2つ目のコードは四方の壁からスネークがはみ出たらゲームオーバーになるコード。

壁からはみ出るのを判定するのは、

スネークの頭をxcor()、ycor()で場所を取得して、

ウィンドウサイズより大きい、または少ないを判定している。

 

for部分では頭が体に追突したらゲームオーバーになるコード。

snake_body == snake.headの場合はpassとしているが、

これをしないとsnake.headの距離は0なのですぐゲームオーバーになってしまうため。

 

先ほどの.tracer()と今回の.update()について

これがないとgoto()や向きを変更するときに律儀にくるっと回転するアニメーションまで出てきてしまうので、

time.sleepと合わせて使用する。

伝え方が難しいので、コードをない場合とある場合で試してみるといいかも。

 

 

これで完成。

 

それぞれのファイルまとめ

main.py

from turtle import Turtle, Screen
from snake import Snake
from food import Food
from score_board import ScoreBoard
import random
import time

screen = Screen()
screen.setup(600, 600)
screen.bgcolor("black")
screen.title("Snake Game")
screen.tracer(0)

snake = Snake()
food = Food()
score = ScoreBoard()

screen.listen()
screen.onkey(snake.up, "Up")
screen.onkey(snake.down, "Down")
screen.onkey(snake.left, "Left")
screen.onkey(snake.right, "Right")

def count_num(num):
count_nums = Turtle()
count_nums.ht()
count_nums.color("white")
count_nums.penup()
count_nums.goto(0, 20)
for i in range(1,num):
count_nums.clear()
count_nums.write(num - i, font=("Sans", 20, "bold"), align="center")
time.sleep(1)
count_nums.clear()

count_num(4)

start_game = True
while start_game:
screen.update()
time.sleep(0.1)
snake.move()
if snake.head.distance(food) < 20:
food.refresh()
score.increase_score()
snake.increase_snake()

if snake.head.xcor() >= 300 or snake.head.xcor() <= -300 or \
snake.head.ycor() >= 300 or snake.head.ycor() <= -300:
score.game_over()
start_game = False

for snake_body in snake.snake_body:
if snake_body == snake.head:
pass
elif snake.head.distance(snake_body) < 10:
score.game_over()
start_game = False

screen.exitonclick()

 

 

snake.py

from turtle import Turtle
STARTING_POSITIONS = [(0, 0), (-20, 0), (-40, 0)]
UP = 90
DOWN = 270
RIGHT = 0
LEFT = 180

class Snake:
def __init__(self):
self.snake_body = []
for i in STARTING_POSITIONS:
self.add_body(i)
self.head = self.snake_body[0]

def add_body(self, position):
new_body = Turtle("square")
new_body.color("white")
new_body.penup()
new_body.goto(position)
self.snake_body.append(new_body)

def increase_snake(self):
self.add_body(self.snake_body[-1].position())

def move(self):
for seg_num in range(len(self.snake_body)-1, 0, -1):
new_x = self.snake_body[seg_num - 1].xcor()
new_y = self.snake_body[seg_num - 1].ycor()
self.snake_body[seg_num].goto(new_x, new_y)
self.head.forward(20)



def up(self):
if self.head.heading() != DOWN:
self.head.setheading(UP)

def down(self):
if self.head.heading() != UP:
self.head.setheading(DOWN)


def left(self):
if self.head.heading() != RIGHT:
self.head.setheading(LEFT)


def right(self):
if self.head.heading() != LEFT:
self.head.setheading(RIGHT)

 

score_board.py

from turtle import Turtle

class ScoreBoard(Turtle):
def __init__(self):
super(ScoreBoard, self).__init__()
self.score = 0
self.penup()
self.ht()
self.goto(0, 270)
self.color("white")
self.get_score()

def get_score(self):
self.write(f"Score : {self.score}", font=("Sans", 20, "bold"), align="center")

def game_over(self):
self.goto(0, 0)
self.write("Game Over.", font=("Sans", 20, "bold"), align="center")

def increase_score(self):
self.clear()
self.score += 1
self.get_score()

 

food.py

from turtle import Turtle
import random

class Food(Turtle):
def __init__(self):
super().__init__()
self.shape("circle")
self.color("yellow")
self.shapesize(0.3)
self.penup()
self.refresh()

def refresh(self):
random_x = random.randint(-280, 280)
random_y = random.randint(-280, 280)
self.goto(random_x, random_y)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DAY19 python - Turtleモジュールを使って簡単なレースゲームを作る

DAY18で学習したTurtleオブジェクトをさらに応用して、

今回はタートルレースゲームを作成します。

 

 

 

今回の流れとしては

  • ウィンドウサイズを設定する
  • 複数のタートルをスタートラインに立たせる
  • どのタートルが勝つか予想をinputに入力する
  • レーススタート!
  • ウィンドウ右端にいったタートルが勝ち
  • もう一回するか聞く
  • 上のすべてをdefで囲んでリピートできるようにする

 

こんな感じです。

 

では始めます。

 

まずはモジュールをインポート。

タートルがfoward()で進む数をランダムで指定したいので、randomも。

 

from turtle import Turtle, Screen
import random

 

ウィンドウサイズの調整

次にウィンドウサイズの調整。

screen.setup(x, y)でできる。

また、タートルの区別をするために1体ずつ違う色にしたいので、

色のリストを追加してそこから1つずつ色をとってくる動作にする。

 

screen = Screen()
screen.setup(500, 500)
color_list = ["orange", "red", "purple", "blue", "black", "green", "pink"]

 

次にゲーム部分をファンクションで作っていく。

ウィンドウサイズが500ピクセルの正方形で、タートルのサイズも考えて

最初のタートルの位置は-230, -90くらいにしておく。

そこから30ずつ上に7体くらい作ってみよう。

 

それをコーディングしていくとこんな感じになった。


def game_start():
x = -230
y = -90
all_turtles = []

for i in range(7):
tim = Turtle()
tim.ht()
tim.color(color_list[i])
tim.shape("turtle")
tim.penup()
tim.goto(x, y)
tim.st()
y += 30
all_turtles.append(tim)

 

forでタートルを定義し、初期設定を終えた後に左端に行くようなコードです。

それをall_turtlesというリストに追加してそれぞれが判別できるように入れています。

 

ここで、「どの色のタートルが勝つ?色をタイプして!」という入力ウィンドウを出す。

これはscreen.textinput(title="", prompt="")でできる。

 


user_bet = screen.textinput(title="Make Your Bet", prompt="Which turtle will win the race? Enter a color : ")
print(user_bet)

一応自分が入力した文字がわかるようにprintで記録しておく。

 

そして、これが入力されたらレースが始まるようにする。


if user_bet:
is_race_start = Tru
while is_race_start:

 

それぞれのタートルを動かすには、1体ずつforward(ランダムな数)で進ませるという方法でいく。for in ですね。

 


for turtle in all_turtles:
turtle.forward(random.randint(5,20))

最小で5、最大20進むランダムな数値で進むようにしています。

この辺の数値は任意で変えたらまた逆転ゴールとかあって楽しいかも笑

 

最終的に右端にいったらwhileはFalseにして止めるのと同時に

勝った亀の色を取得する。

右端も考慮して220にする。

横軸の数値を取得するには、xcor()でわかる。

 

if turtle.xcor() >= 220:
is_race_start = False
win_color = turtle.pencolor()

 

賭けに勝った場合と負けた場合で表示を変えたいので、

ifで入れ子にする。

 

if user_bet == win_color:
restart = screen.textinput(title="You Win!", prompt="Do you wanna again? y / n")
if restart == "y":
screen.clear()
game_start()
else:
return False
else:
restart = screen.textinput(title=f"You Lose! {win_color} Win!", prompt="Do you wanna again? y / n")
if restart == "y":
screen.clear()
game_start()
else:
return False

 

もう一回やるかの確認でy以外をタイプした場合はゲーム終了として、

return Falseを追加しました。

また、ただ単にgame_start()で繰り返すとゴールしたタートルたちが右端に残ってしまうので、

screen.clear()でいったんウィンドウをクリアしてからゲームをスタートしてます。

 

最終コードはこちら。

 

from turtle import Turtle, Screen
import random

screen = Screen()
screen.setup(500, 500)
color_list = ["orange", "red", "purple", "blue", "black", "green", "pink"]

def game_start():
x = -230
y = -90
all_turtles = []

for i in range(7):
tim = Turtle()
tim.ht()
tim.color(color_list[i])
tim.shape("turtle")
tim.penup()
tim.goto(x, y)
tim.st()
y += 30
all_turtles.append(tim)

user_bet = screen.textinput(title="Make Your Bet", prompt="Which turtle will win the race? Enter a color : ")
print(user_bet)

if user_bet:
is_race_start = True

while is_race_start:
for turtle in all_turtles:
turtle.forward(random.randint(5,30))
if turtle.xcor() >= 220:
is_race_start = False
win_color = turtle.pencolor()
if user_bet == win_color:
restart = screen.textinput(title="You Win!", prompt="Do you wanna again? y / n")
if restart == "y":
screen.clear()
game_start()
else:
return False
else:
restart = screen.textinput(title=f"You Lose! {win_color} Win!", prompt="Do you wanna again? y / n")
if restart == "y":
screen.clear()
game_start()
else:
return False


game_start()
screen.exitonclick()

 

 

Turtleでも色々楽しめますね!

 

 

 

 

 

 

DAY18 python - Turtleモジュールを使ってダミアンハースト的なアート画像を作る

今回は今までと打って変わって新しいモジュールを使って

アートな画像を作る講座。

 

アートを知っている人くらいしか知らないマニアックだけど

アート界では巨匠な人 ダミアンハーストの画像を作ります。

 

こんな感じのドット並べてるだけの絵なんだけど、これがすごいらしい笑

 

www.gettyimages.co.jp

 

Turtleモジュールはインポートして使う。

プログラミング入門用に使えるモジュールで亀を動かすこととか絵を描くこともできるし、アイデアによってはゲームとかも作れる。

 

ドキュメントはこちら

docs.python.org

 

ざっくりと簡単な機能を言うと

  • from turtle import Turtle, Screen で機能を呼び出す
  • 前に進むはforward(i) でiには数字を入れるとその分前にすすむ。
  • 曲がりたいときはright(i)かleft(i)でiに数値を入れるとその角度分曲がる。
  • 基本的に動くとその跡は線となるのだけど、penup()で線は消せる。pendown()で再度線が描かれる。

これだけあれば四角形とか簡単な図形はかけたりタートルを動かせる。

 

 

今回はタートルはいらなくて色の着いたドットだけを書いていく。

 

流れとしてはこんな感じ

  • ダミアンハーストの色味をcolorgram.pyを使って色を取得する
  • その色をランダムに選んで左下から等間隔に右に塗っていく
  • 10点塗り終わったら左端に戻って、50ピクセル上に上がってから同じことを繰り返す
  • 10回繰り返したら完成

 

spotpainting

 

ではやっていきます。

 

colorgram.pyで使われている色を取得する

pypi.org

 

import colorgram

まずcolorgramをインポート。

多分システムにないと思うのでpycharmでインストールするか、

ターミナルでドキュメントに書いてある通り

pip install colorgram.py

 

でインストールしてからimportする。


colors = colorgram.extract('image.jpg', 30)

このコードで、image.jpgにある色を30色取得してくれる。

colorsはリストの中に30色分のcolors.rgbのオブジェクトで取得された色がある。

このままだと色が呼び出せないので、.rgbメソッドでrgbデータを取得する。

 

rgb_colors = []
for color in colors:
rgb_colors.append(color.rgb)

 

rgb_colorsのリストの中にcolor.rgbで吐き出されたrgbデータを追加していく。

 

Turtle, Screenのインポート

from turtle import Turtle, Screen

次にタートルモジュールとウィンドウの調整ができるScreenをインポートする。

 

tim = Turtle()
screen = Screen()
screen.colormode(255)

screenはタートルを動かすウィンドウの設定のことで、

colormode(255)にすることでrgbの設定が使えるようになる。

 

これだけだと絵を描き終わったらすぐウィンドウが閉じてしまうので、

一番最後に


screen.exitonclick()

を書いておく。これは自動的に閉じるんじゃなくて、

描画が終わった後にクリックをしたら閉じるメソッド。

 

スクリーン・タートルの初期値を設定する

tim.speed(0)
tim.ht()
tim.penup()

x = -250
y = -250
tim.setpos(x, y)

 

タートルはデフォルトだと矢印が出るので、消したい。

消すメソッドはht()、もしくはhideturtle()で消える。

最初に動くのを見たい場合は書かないで動かしてもいいかも。

penup()は文字通りペンが浮いている状態なので、タートルを動かしても線は出ない状態。

 

setpos(x,y)ではタートルをどの部分に置くかを設定できる。

キャンバスの真ん中が0,0としているので、左と下に-250ずつ移動している状態。

 

横に10回を上に10回繰り返して100個のドットを作る

 


for i in range(10):
tim.setpos(x, y)
for i in range(10):
tim.pendown()
tim.pencolor(random.choice(rgb_colors))
tim.pensize(25)
tim.forward(1)
tim.penup()
tim.forward(50)
y += 50

screen.exitonclick()

 

for分を横10個を繰り返す分と、

これを10回繰り返す分と入れ子にして描画するようにしています。

最初にポジションをセットして、pendown()で描画開始。

.pencolor()でドットの色を先ほどリストに入れた色からランダムで選んで指定。

.pensize()でドットの大きさを指定しています。

.forward(1)で1ピクセルだけ移動しているので実質点を描画。

終わったらpenup()で再び線をひかないようにしてから右に50進んでいます。

これを10回繰り返すと10個のランダムに色付けされた点ができます。

10回くらい返した後に、yを50プラスすることで11個目のドットが

左端で50上に行ったところからスタートするようになり、また10このドットを描画…という流れ。

 

 

これであっというまにアート作品のできあがり。

 

全体のコードはこちら。

 

from turtle import Turtle, Screen
import random
import colorgram

rgb_colors = []
colors = colorgram.extract('hirst-painting-start/image.jpg', 50)
for color in colors:
rgb_colors.append(color.rgb)

tim = Turtle()
screen = Screen()
screen.colormode(255)
tim.ht()
tim.penup()

x = -250
y = -250
tim.setpos(x, y)

for i in range(10):
tim.setpos(x, y)
for i in range(10):
tim.pendown()
tim.pencolor(random.choice(rgb_colors))
tim.pensize(25)
tim.forward(1)
tim.penup()
tim.forward(50)
y += 50

screen.exitonclick()

 

 

 

DAY17 クラスの初期化してクイズアプリを作る

DAY16 のclassはメソッドを格納して1つのコーヒーメーカーだけでなく

他のコーヒーメーカーでも使えるように基本的な機能を格納する記述を勉強したけど、

 

今回は呼び出したら機能を使えるだけでなく、

元々のデフォルト設定ができるようなコーディングを勉強する。

 

流れとしては、

 

  1. クイズをネットからゲットする
  2. クイズデータとしてpyにリストとして保存する
  3. クイズマシーンをクラスとして用意し、そこにクイズデータを入れてクイズを出してもらう
  4. クイズが尽きるまで繰り返し、終わったら何ポイントか教えてもらう

こんな感じ。

 

main.pyでいうと、

#用意するのは main.py, quiz_brain.py, quiz_model, questionsの4つ

#import quiz_data

#append list to quiz_list

#app quiz_machine!

#if quiz number = 0, finish

#print your point!

 

こんな感じ。

 

では始めます。

 

questions.pyから。

 

trivia databaseから質問をjsonでコピペする。

opentdb.com

 

ページに行ったら右上のAPIをクリック

今回は10問のクイズアプリを作るので、

Number of Questions : 10

Select Category : 好きなの

Select Difficulty : 好きなの

Select Type : 今回は2択クイズにするので True  False

Select Encoding : Default Encoding

 

でGenerate APIをクリック

すると、APIアドレスが出てくるのでコピペでジャンプする。例:

https://opentdb.com/api.php?amount=10&category=11&difficulty=easy&type=boolean#

JSON format でコピー。

 

今回作るmain.pyと同じフォルダ内にquestions.pyとかの名前で保存する。

(今後はAPIで取得すると毎回違うクイズが自動で出てきたりもできる)

 

一番最初にquestion_data = [をつけて、一番最後に]をつけてリスト化する。

 

クイズデータはこんな感じ

questions_data = [
{
"response_code": 0,
"results": [
{
"category": "Entertainment: Film",
"type": "boolean",
"difficulty": "easy",
"question": "Han Solo&#039;s co-pilot and best friend, &quot;Chewbacca&quot;, is an Ewok.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
},
クイズが続く...
]

 

 

quiz_machine.py詳細

 

これでクイズデータができたので、次はクイズマシーンをクラスで作る。

別のファイル quiz_machine.pyを作成。

 

作る内容はこちら

  1. スコア・クイズ数・クイズデータの初期化
  2. クイズが最後かどうかを確認する機能
  3. クイズを出す機能
  4. 答えが合ってるかどうかをチェックする機能

 

初期化

クイズマシーンでクイズを出すときはスコア・クイズ数・取り込むクイズデータを初期化したいので、最初にコーディングしていく。

 

初期化するときはいままでの def function()... ではなく、

def __init__ (self, args):  でコーディングする。

selfというのはそのクラス自身ということで必ずいる。

argsは適当に今回つけただけでここには他のファイルから出力されたデータを受け取ることができる。

今回の場合はクイズデータを取り込むので、argsの部分はq_dataなどにする。

 

class QuizMachine:
def __init__(self, q_data):
self.q_num = 0
self.score = 0
self.q_data = q_data

 

これでまずクイズマシーンを始めるたびにクイズ数・スコア・取り込むデータが初期化される。

クラスの中で使う機能は全て最初にself.を入れる。

(ちょっとしつこいけど)

 

次にクイズが最後かどうかを確認する機能。

クイズナンバーが最後のクイズ数より大きくなったらfalseを返す。

クイズを出すごとにq_numが増えていく想定にしているので、

それが取り込むクイズデータの数より大きかったらfalseに。

    def continue_q(self):
return self.q_num < len(self.q_data)

このコーディングではfalseは書いてないのは、

これだけですでにbooleanを吐き出すようになっているから。

 

クイズを出す機能

クイズを出すにはこの機能がいる。

  • 今何問目かを取得する
  • その数字にあてられた質問を出して、答えてもらう
  • 回答者と質問の答えを出力して、チェックする機能に渡す

 

これをコーディングすると、


def next_q(self):
current_q = self.q_data[self.q_num] #今の質問ナンバーを取得
self.q_num += 1 #1つ増やす
user_a = input(f"{self.q_num} : {current_q.text} \n T / F ? : ")
self.check_a(user_a, current_q.answer) #check_answerで合ってるかチェック

 

となる。

 

最後に、チェック機能であってるか確認する

next_qの中に書いたcheck_aを書いていく。

これはシンプルにif であってたらスコアアップする感じ。

このコードにある[:1]というのはデータをスライスしていて、

最初の1文字だけを取得しています。

回答者もめんどくさいので trueとかfalseとか毎回書くのめんどくさいし笑

打ち間違いもあるかもと思ってとりあえず.lower()で小文字にして1文字だけを見ています。

問題にもTかFかにしています。

 


def check_a(self, user_a, correct_a):
if user_a[:1].lower() == correct_a[:1].lower():
self.score += 1
print("Got it!")
else:
print("It's wrong...")
print(f"Now your score is {self.score} / {self.q_num}.")

 

これでquizmachineクラスは完成。

 

もう1つquestion_modelがあるが、途中で書くとして最後の仕上げに。

 

main.pyでクイズアプリをまとめる

 

終盤になってきました。

main.pyで作ったファイルをインポートしていきます。

import html
from questions import questions_data
from quiz_machine import QuizMachine
from question_model import QuestionModel

 

最初に import htmlをいれているのは、後で説明します。

次に、questions_data のデータ指定のコードを少し短くしたいので、

ショートカットの変数を作ります。

 


#import quiz_data
q_list = questions_data[0]["results"]

 

questions_dataのjsonデータから必要なものだけ(クイズと正解)を辞書型リストとして作っていきます。

 


#import quiz_data
q_list = questions_data[0]["results"]

#append list to quiz_list

quiz_data_to_list = []
for quiz in q_list:
q_text = quiz["question"]
q_text = html.unescape(q_text)
q_a = quiz["correct_answer"]
new_q = QuestionModel(q_text,q_a)
quiz_data_to_list.append(new_q)

 

ここでQuestionModel()がでてきました。

これは取得したデータを辞書型リストにするためにはオブジェクトとして登録しなくてはいけないのですが、

それをクラスとして別ファイルにしてコーディングしています。

 

question_model.py

class QuestionModel:
def __init__(self, q, a):
self.text = q
self.answer = a

 

展開するときにはこれは合った方がいいのかもしれないけど、

ここだけであれば

 

new_q = {q_text, q_a}

にしても問題なし。

ただこの場合はnext_q()のuser_a以下をこちらに変更する必要がある。

keysとvaluesで呼び出す必要がある。


user_a = input(f"{self.q_num} : {list(current_q.keys())[0]} \n T or F ? : ")
self.check_a(user_a, list(current_q.values())[0]) #check_answerで合ってるかチェック

 

脱線しましたが、jsonを辞書型リストに保存して、

次はクイズマシーンをここで呼び出します。

先ほどappendしてクイズデータをリストにしたquiz_data_to_listを中に入れます。

 


#app quiz_machine!

quiz = QuizMachine(quiz_data_to_list)

 

 

クイズが終わるまで次の問題を出し続けるクイズマシーンの機能を

呼び出します。


#if quiz number = 0, finish

while quiz.continue_q():
quiz.next_q()

 

クラスのオブジェクトの中からメソッドのみを呼び出す場合は

呼び出したクラス変数にドットをつけてメソッドを書けば起動してくれます。

これは同じく初期値なども呼び出せます。

 

最後にクラスの初期値であるスコアとクイズ数を呼び出します。

初期値といったもののクイズが終わった後なので、

スコアとクイズ数は変わっています。

 


print("Finish Quiz!")
print(f"Your final score is {quiz.score}/ {quiz.q_num}")

 

これで完成!

 

最終コードはこちら。

 

main.py

import html
from questions import questions_data
from quiz_machine import QuizMachine
from question_model import QuestionModel

#import quiz_data
q_list = questions_data[0]["results"]

#append list to quiz_list

quiz_data_to_list = []
for quiz in q_list:
q_text = quiz["question"]
q_text = html.unescape(q_text)
q_a = quiz["correct_answer"]
# new_q = QuestionModel(q_text,q_a)
new_q = {q_text:q_a}
quiz_data_to_list.append(new_q)

# print(quiz_data_to_list)

#app quiz_machine!

quiz = QuizMachine(quiz_data_to_list)

#if quiz number = 0, finish

while quiz.continue_q():
quiz.next_q()

print("Finish Quiz!")
print(f"Your final score is {quiz.score}/ {quiz.q_num}")


#print your point!

 

questions.py

questions_data = [
{
"response_code": 0,
"results": [
{
"category": "Entertainment: Film",
"type": "boolean",
"difficulty": "easy",
"question": "Han Solo&#039;s co-pilot and best friend, &quot;Chewbacca&quot;, is an Ewok.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
},....

]

 

quiz_machine.py

class QuizMachine:
def __init__(self, q_data):
self.q_num = 0
self.score = 0
self.q_data = q_data

def continue_q(self):
return self.q_num < len(self.q_data)

def next_q(self):
current_q = self.q_data[self.q_num] #今の質問ナンバーを取得
self.q_num += 1 #1つ増やす
# user_a = input(f"{self.q_num} : {current_q.text} \n T or F ? : ")
# self.check_a(user_a, current_q.answer) #check_answerで合ってるかチェック

user_a = input(f"{self.q_num} : {list(current_q.keys())[0]} \n T or F ? : ")
self.check_a(user_a, list(current_q.values())[0]) # check_answerで合ってるかチェック

def check_a(self, user_a, correct_a):
if user_a[:1].lower() == correct_a[:1].lower():
self.score += 1
print("Got it!")
else:
print("It's wrong...")
print(f"A : {correct_a}")
print(f"Now your score is {self.score} / {self.q_num}.")

question_model.py

 

class QuestionModel:
def __init__(self, q, a):
self.text = q
self.answer = a

 

 

 

 

 

 

python - google colab のより複雑なデータの扱い方まとめ

前回、前々回に引き続きgoogle colabでデータを扱う時の流れ。

  • htmlタグが+テキストのボタンを使うと使用可能。
  • .groupby(”見出し名”)に.count()でそのデータの見出し名が同じものを集計することができる。 例:df.groupby("color").count()
  • df.見出し名.value_counts()だと見出し名にある重複データを集計できる。
  • df[:10]などコロン+数字で10個目まで表示などスライスができる。
  • rename(columns = {"変更前見出し", "変更後見出し"}, inplace = True)で読み込んだcsvの見出しが変更できる。indexも可能。
  • groupby("インデックスにしたい見出し名")に.agg(計算したい方法)を追加することで簡単に集計ができる。.agg("特定の見出し", 計算したい方法)で特定の列のみ計算して表示することができる。
    df.groupby("year").agg({"item" : pd.Series.nunique})
  • チャートで例えば左側に0-10000km、右側に0-100個など2種類の単位を1つのチャートでに入れて表示することもできる。

    ax1 = plt.gca() 
    ax2 = ax1.twinx() この2行で左右に単位が表示されるようになる

    ax1.set_xlabel("下の単位の見出し")
    ax1.set_ylabel("左部分の単位見出し", color="green") 色も変えられる
    ax2.set_ylabel("右部分の単位見出し", color="blue")

    ax1.plot(左単位のindex, 左単位のデータ, color="g") 線の色も変えられる
    ax2.plot(右単位のindex, 右単位のデータ)

  • .merge("結合したいテーブル1", "結合したいテーブル2", on="紐づける見出し")
    で2つの表をマージすることができる。