Diagonal M

データサイエンス系長期インターンで学んだことなど

【Python】オブジェクト指向プログラミング vol.5 ~関数の追加~

Pythonオブジェクト指向の勉強の続きです。

関数をクラスに追加する

Playerクラスに能力値の平均値を算出する関数を作ってみます。能力値の平均値を戻り値にする関数をability_avgとしてPlayerクラスに追加します。

class Player:
    def __init__(self, name, team, position, attack, special, heart, technique, defense):
        self.name = name
        self.team = team
        self.position = position
        self.attack = attack
        self.special = special
        self.heart = heart
        self.technique = technique
        self.defense = defense
    
    def ability_avg(self):
        return (self.attack+self.special+self.heart+self.technique+self.defense) / 5
        

c = Player('クリステファン・ローディ', 'R・マドリード', 'FW', 409, 391, 310, 395, 193)

ability = c.ability_avg()
print('能力値の平均:{}'.format(ability))

このようにPythonではオブジェクトに属する関数を定義するとき、第一引数にselfというキーワードを書くことになっています。

上のコードを実行すると以下の結果が出力されます。

能力値の平均:339.6

selfはオブジェクト生成時に自動的に引数に入ってくるので引数として渡す必要はありません。

次回は簡単に継承とオーバーライドについて簡単にまとめます。

【Python】オブジェクト指向プログラミング vol.4 ~コンストラクタ~

Pythonオブジェクト指向の勉強の続きです。

コンストラク

__init__は、「インスタンスが作成されるタイミングで呼びだされる特殊なメソッド」です。

一般的にそのような処理をするメソッドは「コンストラクタ」と呼ばれています。コンストラクトは「構築する」という意味です。試しに__init__内にprint文を加えてインスタンスを作成し、コンストラクタの挙動を見てみます。

class Player:
    def __init__(self):
        print('Diagonal-M')
        self.name = name
        self.team = team
        self.position = position
        self.attack = attack
        self.special = special
        self.heart = heart
        self.technique = technique
        self.defense = defense
c = Player()

このプログラムを実行すると、インスタンスを作成した際に__init__内にあるprint文が呼び出されます。以下が実行結果です

Diagonal-M

このコンストラクタにも通常のメソッドと同じようにコンストラクタも引数を複数与えることができます。このコンストラクタの引数はクラスをインスタンス化する際に利用されます。実際にコンストラクタの引数の利用例を上記コードを改良して__init__に引数を与えてみます。

class Player:
    def __init__(self, name, team, position, attack, special, heart, technique, defense):
        print('Diagonal-M')
        self.name = name
        self.team = team
        self.position = position
        self.attack = attack
        self.special = special
        self.heart = heart
        self.technique = technique
        self.defense = defense

c = Player('クリステファン・ローディ', 'R・マドリード', 'FW', 409, 391, 310, 395, 193)

print('選手名:{}'.format(c.name))
print('所属チーム:{}'.format(c.team))
print('守備力:{}'.format(c.defense))

このコードを実行すると以下のようになります。

Diagonal-M
選手名:クリステファン・ローディ
所属チーム:R・マドリード
守備力:193

コンストラクタで定義した引数に対応した形で、インスタンス化が行われていることがわかります。具体的にはdef __init__(self, name, team, position, attack, special, heart, technique, defense)Player('クリステファン・ローディ', 'R・マドリード', 'FW', 409, 391, 310, 395, 193)が対応しているかたちになっています。

そしてコンストラクタ内では、与えられた引数をインスタンスのデータの初期化に利用しています。コンストラクタの引数を使うと「インスタンスの初期化を実施する」という保証を与えることができます。

次回はクラスに関数の追加する方法をまとめます。

【Python】オブジェクト指向プログラミング vol.3 ~クラスの定義方法~

Pythonオブジェクト指向の勉強の続きです。

前回のまとめ

  • クラスとは管理対象となる情報と振る舞いを定義したテンプレートのこと
  • インスタンスは、クラスの情報をすべて受け継いで生成されたオブジェクトのこと

クラスの定義方法

前回のテンプレートに該当するものがクラスです。クラスの定義方法は以下のとおりです。

classキーワードを使い、その右にクラス名を記述し、右にコロン(:)をつけます。慣例として最初の文字は大文字にします。

class Player:
    def __init__(self):
        self.name = name
        self.team = team
        self.position = position
        self.attack = attack
        self.special = special
        self.heart = heart
        self.technique = technique
        self.defense = defense

c = Player()
c.name = 'クリステファン・ローディ'
c.team = 'R・マドリード'
c.position = 'FW'
c.attack= 409
c.special = 391
c.heart = 310
c.technique = 395
c.defense = 193

print('ポジション:',c.position)
print('所属チーム:{}, 名前:{}'.format(c.team, c.name))

変数をPlayerクラスに8個作りました。

このテンプレートをもとにPlayer型のオブジェクトを作ります。クラスからオブジェクトを作る構文は、「クラス名()」です。

Player()がクラスからオブジェクトを作る構文になります。こうすることで、同じテンプレートから異なるPlayer型オブジェクトを作成できます。

上のコードを実行すると以下のような結果が返ってきます。

ポジション: FW
所属チーム:R・マドリード, 名前:クリステファン・ローディ

オブジェクトの変数にアクセスするには、ドット(.)を使います。c.namec.defenceのように書けます。

今回クラスにデータを持たせる際にdef __init__内に定義しました。上のコードではdef __init__がなくても同じ結果を返してくれます。

次回__init__(コンストラクタ)についてまとめます。

【Python】オブジェクト指向プログラミング vol.2 ~オブジェクトでの表現~

Pythonオブジェクト指向の勉強の続きです

プログラムにおけるオブジェクトの表現

オブジェクトは自分に所属する関数を保持できます。

以下のコードを見てください。

f = open('diagonal_m.txt', 'w')
f.write('diagonal')
f.close()

これはdiagonal_mというテキストファイルを開きdiagonalという文字列を書き込むコードdす。1行目でopenという関数を実行することでファイルオブジェクトが戻り値として返ります。ファイルオブジェクトに対してドットを使うことで、そのオブジェクトが保有している関数を呼び出すことができています。

別の例で、文字列を例に挙げます。文字列もオブジェクトですので文字列オブジェクトが保有する関数を利用することができます。

str = 'Daiagonal_M'
str.lower()
# daiagonal_m
str.upper()
# DAIAGONAL_M

lower()は文字列をすべて小文字に変換する関数で、upper()は小文字を大文字に変換する関数です。文字列としての型と、'Diagonal_M'という値を持ちながら、かつ関数を保有できます。

オブジェクトでの表現

プログラミングにおいては「成果物と構成要素に分解して、その要素がどんな情報を持つ必要ががあり、どのような動作を行えば良いのか」を考えなければなりません。つまりその構成要素をオブジェクトとして抽出し、必要な情報と動作を規定していくことになります。

例として「サッカーゲームの選手」をオブジェクトを用いて表現してみます。

サッカー選手の持つ属性として考えられるのは、例えば以下のようなものがあります。

  • 名前
  • 所属チーム
  • ポジション
  • 攻撃
  • 特殊
  • 技術
  • 守備

f:id:diagonal-m:20190717151102p:plain
ポケサカ

この内容をPythonで表現すると以下のようになります。playerというオブジェクトが仮に存在するとします。

player.name = 'クリステファン・ローディ'
player.team = 'R・マドリード'
player.position = 'FW'
player.attack = 409
player.special = 391
player.heart = 310
player.technique = 395
player.defense = 193

このようにキャラクターがもつ普遍的な属性を定義しておいて、適切なデータを代入しています。上のコードのテンプレートに該当するものをプログラミング用語でクラスといい、クラスのテンプレートから作られたオブジェクトのことをインスタンスといいます。

まとめ

  • クラスとは管理対象となる情報と振る舞いを定義したテンプレートのこと
  • インスタンスは、クラスの情報をすべて受け継いで生成されたオブジェクトのこと
  • インスタンスにどのようなデータを持たせるかはクラスで定義する

次回はクラスの定義方法についてまとめます。

【Python】オブジェクト指向プログラミング vol.1 ~オブジェクトとは~

オブジェクト指向への理解が浅くインターン先で理解しきれないPythonのコードがあったので勉強したことを複数記事に渡ってまとめていきます

オブジェクトとは

Pythonの公式ドキュメントでは以下のように記載されています

pythonにおけるオブジェクト(object)とは、データを抽象的に表したものです

Pythonプログラムにおけるデータはすべて、オブジェクトまたはオブジェクト間の関係として表されます。

オブジェクトはアイデンティティ値(identity)、型(type)、そして値(value)を持ちます。

まったく意味がわからないので一つずつ分けて考えます。

オブジェクトには大きく分けて2つの性質があります。

アイデンティティ、型、値とは

オブジェクトにおけるアイデンティティとはPythonで使われるオブジェクトはID番号を持っているという意味です。以下のコードを実行すると

hello = 'hello world'
id(hello)
# 2448634654512

このように数字の羅列が表示されます(コメントアウト部分を出力とします)。id関数を使うことでそのオブジェクトのIDが割り振られていることがわかります。

オブジェクトの値は変数に代入されたデータのことです。上の場合はhello worldが値になります。

オブジェクトの型は整数型や文字列やリスト型といったもので、オブジェクトがどんな型を持っているか確認する関数にtypeというものがあります

type(hello)
# <class 'str'>

strというクラスのオブジェクトだと表示がされます。

蛇足ですがオブジェクト指向とは概念であるということをよく聞き余計に混乱させられます。

例えば上のリストは型のひとつであり、内部に複数のデータをリスト形式で持ちます。例えば以下はすべてリスト型にデータです。

[]
[1, 2, 3]
['hello', 'world']
[1, 'python', 3]

リストは "" であり、上記はそのデータです。リストは "概念" で「1, 2, 3という数字が格納されたリストのデータ」は具体的なモノです。オブジェクト指向におけるこの「概念のレベルでのデータが」クラスであり、その具体的なモノがオブジェクトと呼ばれます。

クラスとオブジェクトの関係を以下にまとめます。

クラス オブジェクト
整数型 1, 2, 3
文字列型 'hello', 'world'
リスト [], ['hello', 'python']

この表だけですとオブジェクトととは「具体的なデータ」のように思えますが、そうではありません。データに加えて処理も含んでいます。このことを覚えておいてください。次回はプログラムにおけるオブジェクトの表現についてまとめます。

【Git】Git操作手順カンニングシート

データサイエンス系のインターン先でGitを使っていろいろ管理するらしく。Gitでの操作手順を自分なりにまとめます。

Gitとは

誰がいつどのファイルの何を変更したかを管理してくれる。バージョン管理システムのこと。
いつ、誰が、どのファイルのどの箇所を、どういった目的で作成、変更、削除したかという履歴を残し、共有することができる。
過去の状態を確認したり、その時点に復元したりすることもできるため、誤って削除してしまったファイルも復元することが可能になります。

基本的な用語

  • リポジトリ : ファイルの変更、追加、修正を管理する場所 。一般に1個のディレクトリ。
  • リモートリポジトリ : みんなで共有するリポジトリ
  • ローカルリポジトリ : 自分一人のリポジトリ
  • コミット(commit) : 変更の履歴を記録する
  • ブランチ : リポジトリで行う開発の経路
  • ステージングブランチ : 開発の元となるブランチ、このブランチから各々ブランチを切って作業を進める
  • マージ : ブランチをひとつにまとめる
  • クローン : リモートリポジトリの内容をダウンロード
  • プッシュ : ローカルリポジトリの変更履歴をリモートリポジトリへアップロードする
  • プル : リモートリポジトリからローカルリポジトリへ変更履歴を取得する

操作手順

1.ソースのクローン(既存のリポジトリのコピーの取得)

git clone `url project_dir_name`

カレントディレクトリにリモートリポジトリで管理されているディレクトリが複製される

2.ディレクトリに移動し、アカウント名とメールアドレスを設定

cd project_dir_name
git config user.name "Diagonal-M"
git config user.email "diagonal-m@mail.com"

誰がコミットしたかがわかるようになる

3.ステージングブランチから作業用ブランチを作成してチェックアウト

git checkout -b dev

ブランチの作成とチェックアウトを同時に行う

4.作業用ブランチでファイルの追加や修正などを行う

git add .
git commit -m "コメント"

5.ステージングブランチを最新に更新する

git checkout staging
git pull

他のメンバーがすでにstagingブランチを進めているかもしれないので更新する

6. ステージングブランチをdevブランチにマージ

git checkout dev
git merge master

自分のブランチも更新する

7. devブランチをpush

git push

初めてpushするブランチの場合は下のようにする

git push --set-upstream origin dev

8. ステージングブランチにdevブランチをマージする

git checkout satging
git merge dev

9.stagingブランチをpushする

git push

よくつかうコマンドと使い方

コマンド 説明
git status Gitに関するカレントディレクトリの状態を表示
git log Gitリポジトリのログを表示
git add ファイルをステージングエリアに追加
git commit 変更をGitリポジトリにコミットする
git branch -v 詳細情報を付与した状態で、ブランチの一覧を表示する
git checkout <ブランチ> 作業ディレクトリを変更して、既存のブランチを反映させる
git checkout -b ブランチの作成とチェックアウトを同時にやる
git merge <ブランチ> ブランチをカレントブランチにマージする
git diff カレントディレクトリ内で追跡されているファイルと、リポジトリ内のファイルに変更があればそれをしめす
git diff --name-only 変更点を表示するときに、変更があったファイルのパスだけを表示してくれます。
git diff --word-diff 差分を文字レベルで表示する
git clone ソースの位置にあるGitリポジトリのクローンを、複製先ディレクトリに、ペアリポジトリとしてつくる
git pull 自分のリポジトリを、複製元と同期させる
git push 現在のブランチを、デフォルトのリモート追跡ブランチにプッシュする

【SQL】postgreSQLでFROOR関数を用いたヒストグラムを作成するための集計方法

postgreSQLでFROOR関数を用いたヒストグラムを作成するための集計方法を紹介します。

以下のようなテーブルを考えていきます。

member_id
character varying(2)
total_price
integer
1 1500
2 3200
3 1820
4 2680
5 1020
6 3800
7 4100
8 1660
9 4500
10 3260
11 2010
12 1960

member_idは会員番号、total_priceはある期間における購入金額の合計と考えてください。

階級幅は1000円とし、度数を集計して以下のようなヒストグラム作成を目指します。

f:id:diagonal-m:20190715145145p:plain
ヒストグラム

FROOR関数

FROOR(数値)とすると引数の数値データの小数点以下を切り捨てます。

total_priceの値を階級幅(1000)で割り、小数点を切り捨て、階級幅を再びかけることで千の位のみを求めることができます。

たとえばtotal_priceが1960の場合だと
1000で割ると1.96になり
小数点以下を切り捨て再び階級幅1000をかけ集計する。 このようにして階級ごとの度数を集計していく。

度数分布表作成のためのSQL

WITH sub1 AS
(
SELECT 
    fre_table.member_id
    , FLOOR(total_price / 1000) * 1000 AS total_price_by1000
FROM 
    fre_table AS fre_table
)
SELECT 
    total_price_by1000
    , COUNT(*) AS cnt
FROM 
    sub1
GROUP BY
    total_price_by1000
;

上クエリの結果

total_price by1000 cnt
1000 5
2000 2
3000 3
4000 2

以上のように簡単に度数分布表をつくることができます。