Pythonメモ

#Python画像投稿
https://nktmemo.wordpress.com/2014/01/05/画像のurlを受け取りbase64テキストに変換する（python）/

#新しいデータ型を作成するには、classを使う

[例:何の機能も持たない、名前だけのDice型]

```
>>> class Dice:
...     pass
...
```

※「pass」は、:(コロン)の後の何か書かなければならないブロックに、
　何もしないことを指示するためのキーワード。

[インスタンスを呼び出す]

```
>>> sai = Dice()
```

エラーが起きなければ、新しいDice型が用意され、変数saiに割り当てられたことになる。


#「新しいデータ型」とは、
  アトリビュート(属性)によって性質を決め、
  メソッドによって機能を作り込んでいく。

例)サイコロ
・性質:6つの面とそこに刻印された数字
・ころがして数字をひとつ決められる

[データ型]
・よりシンプルなデータ属性(アトリビュート)と関数(メソッド)の集まり。
「アトリビュート」と、
「メソッド」
がどのようにあるのか、
を決める仕組み(設計図)が、クラスという概念です。

```
クラスはデータ型の設計図
新しいデータ型はclassキーワードで作る
```

Dice型にサイコロの面の数を表現するデータ属性を追加する。

```
>>> class Dice:
...     face_num = 6
...
>>> 
```

#インスタンスを呼び出す
```
>>> sai = Dice()
>>> sai.face_num

6
```

Dice型に新しいデータ属性であるface_numが追加され、
6が格納されていることが分かる。


#メソッドと関数の違いを考える

[1から6までの数字をランダムに返す関数]

```
>>> import random
>>>
>>> def shoot():
...     return random.randint(1,6)
...
```

クラスの中にこの関数をそのまま入れても、メソッドとして機能しない。

ではどうするか

#メソッドを定義するルール

- メソッドには最初の引数として「self」が必要

・引数を1つ書かなければいけない「self」
　※機能には引数が不要な場合にも必要 (例:shoot()の場合も)

```sample.py
モジュールとしてまとめる

>>> import random
>>>
>>> class Dice:
...     face_num = 6
...     def shoot(self):
...             return random.randint(1,6)
... 

>>> sai = Dice()
>>> sai.shoot()
5
```

face_num = 6を使っていない
例えば、


※エラー

```err.py
>>> import random
>>>
>>> class Dice:
...     face_num = 6
...     def shoot(self):
...             return random.randint(1,face_num)
... 
```

これはエラーになる。
face_num = 6
メソッドの内部からは外の変数を見ることはできない。
関数の内部で使うデータは引数で渡すのが決まり

face_numは、Dice型が自分で持っているデータ属性ですので、
わざわざメソッドに引数として渡すのは面倒。
データ属性が増えると、メソッドの引数が増えて大変になる。


インスタンスを用意するとき、ユーザーがどのような変数名を割り当てるかは分からない。どのような名前でDice型のインスタンスが作られても良いように、メソッドの第一引数でインスタンスを「self」と呼ぶことが決められている。

#自分自身をselfで参照することに決めておく

```sample.py
>>> class Dice:
...     face_num = 6
...     def shoot(self):
...             return random.randint(1,self.face_num)
...
```

```
関数を作ったときは関数の外の変数が見えたのに、なぜここではすぐ隣にあるface_numが見えないのか。

変数は定義した場所によってどの範囲から参照できるかが決まっている。
スコープ。
```

#スコープの種類

・ビルトインスコープ (組み込み関数が所属しているスコープ どこからでも自由に参照できる)
・モジュールスコープ (新しいモジュールを作ったとき)
・ローカルスコープ (関数やメソッドを作ったとき)

今いる場所から見えるのは、
「ビルトインスコープ」と自分が所属している「モジュールスコープ」だけ。

```
import random

random.randint(1,10)
```

このようにrandomという名前をつければ参照できる仕組みになっている。
「名前空間」という。



```sample.py

#! /usr/bin/python
#-*- coding:utf-8 -*-

import dice

sai = dice.Dice()
count = sai.shoot()
print(count)
```

```sample.py

import random

class Dice:
        face_num = 6
        def shoot(self):
            return random.randint(1,self.face_num)
```


#初期化メソッドの正体

組み込みデータ型以外のデータ型を持ったインスタンスを用意するときは、初期化メソッドを呼び出す必要がありました。作成したDice型も組み込みデータ型ではないので次のように書いた。


sai = dice. Dice()

このようにいつもしている。
これは、引数のない初期化メソッドを呼び出している。
classを使って「新しいデータ型」を作ると、Pythonが引数のない初期化メソッドを自動的に用意する。
この初期化メソッドの動きを変更したいときはどうすれば良いのか。


初期化メソッドの本当の名前
__init__


[完成]

```dice.py
import random

class Dice:
        face_num = 6
        def __init__(self):
            print("Hello")

        def shoot(self):
             return random.randint(1,self.face_num)
```

```sample.py

#! /usr/bin/python
#-*- coding:utf-8 -*-

import dice

sai = dice.Dice()
count = sai.shoot()
print(count)

Hello
2
```

#Dice型を改造する

Dice型で多様な形のサイコロを実現できるように、初期化メソッドを呼び出したとき、
引数で４、６、８、１２、２０
のどれかの整数を指定して、
サイコロの形を決められるようにする。


```dice2.py

import random

class Dice:
    def __init__(self,val):
        self.face_num = val

    def shoot(self):
         return random.randint(1,self.face_num)
```

```test10.py

import dice2

sai = dice2.Dice(4)
count = sai.shoot()
print(count)
```

引数を与えられない場合、エラーが出てしまう

dice2.pyに、引数valのデフォルト値を設定する

```
import random

class Dice:
    def __init__(self,val=6):
        self.face_num = val

    def shoot(self):
         return random.randint(1,self.face_num)
```

#発展

正四面体は5種類しかないのに、今のDice型は初期化メソッドの引数に
どんな値でも指定されてしまう。
そこで、
初期化メソッドで引数をチェックして、あり得ない場合をエラーを出す。

引数が指定の数字かどうかはinというキーワードとリストを使って判定を行う。

```
>>> 4 in [4,6,8,12,20]
True

>>> 7 in [4,6,8,12,20]
False

>>> 7 not in [4,6,8,12,20]
True
```

```dice3.py
#coding:UTF-8

import random

class Dice:
    def __init__(self,val=6):
        if val not in [4,6,8,12,20]:
            raise Exception("そんな多面体はありません。")
            self.face_num = val

    def shoot(self):
        return random.randint(1,self.face_num)
```


```test10.py

import dice3

sai = dice3.Dice(99)
count = sai.shoot()
print(count)
```

```dice3.py

#! /usr/bin/python
#-*- coding:utf-8 -*-

import random

class Dice:
    def __init__(self,val=6):
        if val not in [4,6,8,12,20]:
            #raise Exception("そんな多面体はありません")
            print("そんな多面体はありません")
        self.face_num = val

    def shoot(self):
        return random.randint(1,self.face_num)
```

```
-*- coding:utf-8 -*-

import dice3

num = input("4,6,8,12,20のどれで勝負しますか？:")
my_dice = dice3.Dice(num)
cpu_dice = dice3.Dice(num)

my_pip = my_dice.shoot()
cpu_pip = cpu_dice.shoot()
```

#数字はstr関数を使って文字列に変換

```
print("CPU:"+ str(cpu_pip) + "あなた"+ str(my_pip))

if my_pip > cpu_pip:
    print("おめでとうございます。あなたの勝ちです")
elif my_pip < cpu_pip:
    print("残念!あなたの負けです")
else:
    print("引き分けです")
```

#まとめ
・データ型はデータ属性とメソッドからできている
・新しいデータ型を作るには設計図となるクラスを作る
・クラスはデータ属性(アトリビュート)とメソッドをまとめる
・メソッドは関数と同じようにdefキーワードを使ってクラスに追加する
・メソッドには1つめの引数として必ず「self」が必要
・初期化メソッドの実体は、__init__という名前のメソッド



##Djangoとは

Pythonで実装されたwebアプリケーションフレームワーク。
MVC(Model-view-Controll)アーキテクチャーを継承するフレームワーク。

Djangoはコード量を削減し、データベース主体の複雑なWebサイトの構築を簡単にする。

https://django-docs-ja.readthedocs.org/


#インストール

```
pip install django
```

##プロジェクト
・プロジェクトとは、Djangoインスタンスの全設定を持ったPythonパッケージ。
・1つのWebサイトを1つのプロジェクトとして作る。
・プロジェクト内には、プロジェクト固有のアプリケーションを新規に作成して配置する
・Webサイトごとの設定(データベース設定、Djangoのオプション設定、アプリケーションごとの設定など)を持つ。


#django-adminコマンド

「startproject」を実行することでプロジェクトのディレクトリ(myprj)と、
初期ファイルが作られる

```
django-admin startproject myprj

```

```
・myprj/
　   ・manage.py
     ・myprj
         ・__init__.py
         ・settings.py
         ・urls.py
　　　　　 ・wsgi.py
```

#アプリケーション

中身はただのPythonパッケージ。
PYTHONが通っている場所ならどこに置いてあっても構わない。       

pollsディレクトリと初期ファイルを作成する場合

```
cd myprj
python manage.py startapp polls
```

#モデル
DjangoはO/Rマッパーを提供している。
Pythonコードでデータベースレイアウトを記述できる。

各モデルは、django.db.models.Modelクラスを継承したPythonのクラスでデータベースの1テーブルに対応する。


#URLディスパッチャ
・正規表現で書かれたURLのパターン
・Pythonの関数のマッピングを定義した「URLconf」モジュールに記述する。
(アプリケーションごとに分割できる)
(URLに名前をつけて定義することでコードやテンプレートからその名前でURLを参照できる。)

#ビュー
HTTPレスポンスを返す関数
・要求されたページのHttpResponseオブジェクト
・Http404のような例外

典型的なビュー関数は、
1)リクエストパラメータからデータを取得
2)テンプレートを読み込む
3)取得データを使ってテンプレートをレンダリングして返す

http://django-docs-ja.readthedocs.org/en/latest/contents.html