pythonでirisのデータセットを使う
pythonでもirisのデータセットを使える
mecobalamin.hatenablog.com
こちらのサイトで紹介されている
Sklearnを使ってみる1 - ぴろの狂人日記
iris以外のデータセットも使える
scikit-learnのサンプルデータセットの一覧と使い方 | note.nkmk.me
今回はirisのデータセットの内容を確認し
統計処理を行ってグラフを作成する
まずデータセットを確認してみた
irisのデータセットはscikit-learnに含まれている
そこでscikit-learnのdatasetsをインポートする
from sklearn import datasets
irisのデータセットを読み込む
iris = datasets.load_iris()
データセットの型はsklearn.utils.Bunchで
辞書の書式でデータが記録されている
print(type(iris)) print(iris.keys()) print(iris.values())
結果がこちら
<class 'sklearn.utils.Bunch'> dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename']) dict_values([array([[5.1, 3.5, 1.4, 0.2], [4.9, 3. , 1.4, 0.2], ~~~省略~~~ 'petal length (cm)', 'petal width (cm)'], 'D:\\Python\\Python37-32\\lib\\site-packages\\sklearn\\datasets\\data\\iris.csv'])
データセットについての説明もある
print(iris.DESCR)
データの統計値もある
============== ==== ==== ======= ===== ==================== Min Max Mean SD Class Correlation ============== ==== ==== ======= ===== ==================== sepal length: 4.3 7.9 5.84 0.83 0.7826 sepal width: 2.0 4.4 3.05 0.43 -0.4194 petal length: 1.0 6.9 3.76 1.76 0.9490 (high!) petal width: 0.1 2.5 1.20 0.76 0.9565 (high!) ============== ==== ==== ======= ===== ====================
irisのデータセットをpandasのデータフレームに変換する
その時dataのカラム名をfeature_namesを当てる
またtargetをirisの種名に変えてdataのカラムに追加する
df = pd.DataFrame(iris.data, columns = iris.feature_names) df['target'] = iris.target_names[iris.target] print(df.head())
出力結果はこんな感じ
(見辛いのではてな記法で表組みした)
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | target | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
~~~以下略~~~
統計値を確認
print(df.mean())
当然だけどiris.DESCRで表示される結果と同じになる
繰り上がりがちょっと変な気がする
sepal length (cm) 5.843333 sepal width (cm) 3.057333 petal length (cm) 3.758000 petal width (cm) 1.199333 dtype: float64
統計値をまとめて出すこともできる
print({}.format(df.describe().T))
比較しやすいように行と列を入れ替えてある
count mean std min 25% 50% 75% max sepal length (cm) 150.0 5.843333 0.828066 4.3 5.1 5.80 6.4 7.9 sepal width (cm) 150.0 3.057333 0.435866 2.0 2.8 3.00 3.3 4.4 petal length (cm) 150.0 3.758000 1.765298 1.0 1.6 4.35 5.1 6.9 petal width (cm) 150.0 1.199333 0.762238 0.1 0.3 1.30 1.8 2.5
pandasのgoupbyで種ごとの統計値を計算する
df_grouped = df.groupby(['target']) print(df_grouped.mean())
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target setosa 5.006 3.428 1.462 0.246 versicolor 5.936 2.770 4.260 1.326 virginica 6.588 2.974 5.552 2.026
結果を棒グラフとヒートマップにして
画像として保存する
current_dpi = mpl.rcParams['figure.dpi'] print(current_dpi) path = os.getcwd() path = os.chdir(os.path.dirname(os.path.abspath(__file__))) path = os.getcwd() plt.figure() df_grouped.mean().T.plot(kind = 'bar', yerr = df_grouped.std().T, rot = 0) plt.savefig(path + '\\' + 'bar_graph_mean.png', dpi = current_dpi * 1.5) plt.close() plt.figure() plt.figure(figsize=(8, 6)) sns.heatmap(df_grouped.mean().T, square = True, cmap = 'plasma') plt.savefig(path + '\\' + 'heatmap_mean.png', dpi = current_dpi * 1.5) plt.close()
グラフは以下の通り
ヒートマップのカラーマップは以下のサイトを参考にした
https://matplotlib.org/tutorials/colors/colormaps.html#grayscale-conversion
実際のコードはこんな感じ
import os from pandas import Series, DataFrame import pandas as pd from sklearn import datasets import matplotlib as mpl import matplotlib.pyplot as plt import seaborn as sns pd.set_option('display.max_columns', 10) iris = datasets.load_iris() print(type(iris)) print(iris.keys()) print(iris.DESCR) df = pd.DataFrame(iris.data, columns = iris.feature_names) df['target'] = iris.target_names[iris.target] print(df.head()) print(df.columns) df_grouped = df.groupby(['target']) df_mean = df_grouped.mean() print(df_mean) current_dpi = mpl.rcParams['figure.dpi'] print(current_dpi) path = os.getcwd() path = os.chdir(os.path.dirname(os.path.abspath(__file__))) path = os.getcwd() plt.figure() df_grouped.mean().T.plot(kind = 'bar', yerr = df_grouped.std().T, rot = 0) plt.savefig(path + '\\' + 'bar_graph_mean.png', dpi = current_dpi * 1.5) plt.close() plt.figure(figsize=(8, 6)) sns.heatmap(df_grouped.mean().T, square = True, cmap = 'plasma') plt.savefig(path + '\\' + 'heatmap_mean.png', dpi = current_dpi * 1.5) plt.close()
pandasでgroupbyを使う
pythonのpandasで表の集計をしている
groupbyが便利だったのでメモ
groupbyについて参考にした
Pandasのgroupbyを使った要素をグループ化して処理をする方法 - DeepAge
例えばirisのデータで種毎に平均値を計算してみる
pythonでもirisのデータが使えた
【python】iris(アヤメ)のデータセットをpandasとseabornを使って可視化する
ライブラリscikit-learnに含まれている
irisのカラムは5つ
[5 rows x 5 columns] Index(['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)', 'target'], dtype='object')
targetが種の名前
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \ 0 5.1 3.5 1.4 0.2 1 4.9 3.0 1.4 0.2 2 4.7 3.2 1.3 0.2 3 4.6 3.1 1.5 0.2 4 5.0 3.6 1.4 0.2 target 0 setosa 1 setosa 2 setosa 3 setosa 4 setosa
groupbyでtargetを指定するとtargetで各行がまとめられて
mean()で平均値を計算してくれる
df.groupby(['target']).mean()
df.groupby(['target'])の出力は以下の通りで数値を確認できない
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x07FE0310>
dict(list(df.groupby(['target'])))とすると表示できる
実際に使用したコードはこれ
import pandas as pd from sklearn import datasets pd.set_option('display.max_columns', 5) iris = datasets.load_iris() df = pd.DataFrame(iris.data, columns=iris.feature_names) df['target'] = iris.target_names[iris.target] print(df.head()) print(df.columns) print(df.groupby(['target']).mean())
計算結果
sepal length (cm) sepal width (cm) petal length (cm) \ target setosa 5.006 3.428 1.462 versicolor 5.936 2.770 4.260 virginica 6.588 2.974 5.552 petal width (cm) target setosa 0.246 versicolor 1.326 virginica 2.026 [Finished in 1.624s]
列が省略されないようにするにはset_optionで指定する
Pandas DataFrameの表示を省略したくない時. Jupyter… | by takkii | Music and Technology | Medium
Atomで出力している
結果が折り返されるのが修正できない。。。
Pythonista3でTableviewを使う
Pythonisata3でui.tableviewを使うときにハマったのでメモ
.pyuiファイルにTextFieldを配置したとき
TextFieldの中身はsuperviewで読み出せる
例えばTextFieldの名前をtextfield1とするとき
以下のように書く
def on_textfield(sender): a = sender.superview['textfield1']
これがTableViewの場合だとsuperviewの前にtableviewを挟まないといけない
例えばTableViewの名前がtableview1とするとき
このように書く
def on_tableview(sender): b = sender.tableview.superview['tableview'1]
これでTableViewの読み書きできる
こんな感じで任意のリストを
TableViewに加えることができる
list = ui.ListDataSource([{'title':'dog'}, {'title':'cat'}, {'title':'bird'}]) tableview.data_source.items = [] for i in list.items: tableview.data_source.items.append(i) tableview.reload_data()
関数の引数であるsenderは
.pyui上のどのパーツをタップしたかで
内容が異なっている
for key in sender.__dict__.keys(): print(key)
で内容を確認できて
_pyuiが含まれていると
superviewを使えるっぽい
以下が確認した内容で
TableViewではsender.tablevewに_pyuiが含まれる
---sender@TextField--- <class '_ui.TextField'> _pyui None ---sender@TableView--- <class 'ui.ListDataSource'> tableview reload_disabled delete_enabled move_enabled action edit_action accessory_action tapped_accessory_row selected_row _items text_color highlight_color font number_of_lines None ---sender.tableview@TableView--- <class '_ui.TableView'> _pyui None
WSLとJupyter-notebookでCNN、その2、CNNを試す
前回の続き
mecobalamin.hatenablog.com
環境ができたので手持ちのデータセットを試してみる
こちらのサイトを参考にコードを作成した
kerasでCNN 自分で拾った画像でやってみる - Qiita
主な変更点は以下の3点
- 画像の読み込み
- mnist_cnn.pyのモデルを使用
- label、predict、画像ファイル名を保存する
こちらの環境ではlist_picturesが動かなかったので
ファイルを読み込む関数Image_Listを定義した
globは引数で指定したパスのファイル名を再帰的に取得する
ファイル名だけ取得したいのでrelpathで処理している
モデルはmnist_cnn.pyのと同じモデルを使ってみた
画像の分類は手動で行って
negativeとpositiveのディレクトリに保存してある
それぞれの画像がどのように分類されているかを知りたかったので
画像のファイル名とそれぞれがどのようにpredictされているかを
csvファイルに保存した
fit()で出力されるlistのindexも
バージョン違いのせいか"accu"ではエラーが出るので
"accuracy"に修正してある
実際のコードは以下の通り
# ライブラリのインポート import keras from keras.utils import np_utils from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation, Flatten from keras.preprocessing.image import array_to_img, img_to_array, load_img from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt import pandas as pd import numpy as np from glob import glob from os.path import relpath # ファイル名の取得 def Image_List(Path_Images, Ext): List_Images = glob(Path_Images + "/*." + Ext) List_Names = [] for i in List_Images: List_Names.append(relpath(i, Path_Images)) return List_Names # 画像の拡張子 Ext_Type = "png" # 画像のパス Path_Negative = '/path/to/negative/' Path_Positive = '/path/to/positive/' X = [] Y = [] # ネガティブ画像の読み込み Image_Negative = Image_List(Path_Negative, Ext_Type) for picture in Image_Negative: img = img_to_array(load_img(Path_Negative + picture, color_mode = "grayscale", target_size=(256, 256))) X.append(img) Y.append(0) # ポジティブ画像の読み込み Image_Positive = Image_List(Path_Positive, Ext_Type) for picture in Image_Positive: img = img_to_array(load_img(Path_Positive + picture, color_mode = "grayscale", target_size=(256, 256))) X.append(img) Y.append(1) # arrayに変換 # Zはファイル名のリスト X = np.asarray(X) Y = np.asarray(Y) Z = pd.DataFrame(Image_Negative + Image_Positive) # 画素値を規格化 X = X.astype('float32') X = X / 255.0 # one-hot表現に変換 Y = np_utils.to_categorical(Y, 2) # 学習用データとテストデータに分割 # ファイル名のリストも分割 X_train, X_test, y_train, y_test, indices_train, indices_test = train_test_split(X, Y, Z, test_size=0.33, random_state=111) # モデルの構築 model = Sequential() model.add(Conv2D(20, kernel_size=(3, 3), activation='relu', input_shape=X_train.shape[1:])) model.add(Conv2D(40, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(2)) # クラスは2個 model.add(Activation('softmax')) # コンパイル model.compile(loss='categorical_crossentropy', optimizer='SGD', metrics=['accuracy']) # 実行 # 出力有り(verbose=1)。 history = model.fit(X_train, y_train, batch_size=300, epochs=4[f:id:mecobalamin:20200608101008p:plain]0, validation_data = (X_test, y_test), verbose = 1) plt.plot(history.history['accuracy']) plt.plot(history.history['val_accuracy']) plt.title('model accuracy') plt.xlabel('epoch') plt.ylabel('accuracy') plt.legend(['acc', 'val_acc'], loc='lower right') plt.show() # テストデータに適用 predict_classes = model.predict_classes(X_test) # マージ。yのデータは元に戻す mg_df = pd.DataFrame({'predict': predict_classes, 'class': np.argmax(y_test, axis=1)}) # confusion matrix pd.crosstab(mg_df['class'], mg_df['predict']) # 結果の保存 # テストに使った画像ファイルのリストも保存 df_h = pd.concat([pd.DataFrame(y_test), indices_test], axis = 1) pd.DataFrame(y_test).to_csv("/path/to/y_test.csv") indices_test.to_csv("/path/to/indices_test.csv") pd.DataFrame(predict_classes).to_csv("/path/to/predict_test.csv")
jupyter-notebookの複数のcellをまとめたが
gistを使うとそのまま貼り付けられるらしい
計算結果は以下の通り
Core i5-7200UのノートPCで
大体6時間ぐらいかかった
Train on 3287 samples, validate on 1619 samples Epoch 1/40 3287/3287 [==============================] - 522s 159ms/step - loss: 0.6425 - accuracy: 0.5117 - val_loss: 0.5973 - val_accuracy: 0.5374 Epoch 2/40 3287/3287 [==============================] - 494s 150ms/step - loss: 0.5793 - accuracy: 0.6693 - val_loss: 0.5340 - val_accuracy: 0.7739 Epoch 3/40 3287/3287 [==============================] - 493s 150ms/step - loss: 0.5429 - accuracy: 0.7478 - val_loss: 0.5146 - val_accuracy: 0.7573 ~~~ 省略 ~~~ Epoch 38/40 3287/3287 [==============================] - 501s 152ms/step - loss: 0.4346 - accuracy: 0.8059 - val_loss: 0.4734 - val_accuracy: 0.7900 Epoch 39/40 3287/3287 [==============================] - 493s 150ms/step - loss: 0.4001 - accuracy: 0.8190 - val_loss: 0.5238 - val_accuracy: 0.7622 Epoch 40/40 3287/3287 [==============================] - 497s 151ms/step - loss: 0.4388 - accuracy: 0.8026 - val_loss: 0.4895 - val_accuracy: 0.7857
Epochが増えると学習データに対するAccuracyは増えているが
テストデータに対するAccuracyはあまり増えていない
Jupyter Notebookをはてなブログに貼り付ける方法 - akatak’s blog
画像の分類は以下の通り
classは学習時に使った画像のラベルで
0はnegative、1はpositiveを表す
predictはcnnで分類された画像で
0/1はやはりnegative/positiveを表す
predict | |||
---|---|---|---|
0 | 1 | ||
class | 0 | 652 | 104 |
1 | 243 | 620 |
10%-30%程度間違っている
グラフにしてないけれど損失関数も
mnistのデータを使ったときほど減っていない
使ったモデルが合っていないのか
教師データの分類が不十分なのか
そもそもデータの数が足りないのか
分類できた画像を確認したら
見た目にも分類が不十分に感じる
この画像がネガティブに分類?みたいな
計算はできたけど
ここからの修正はどうしたらいいだろうか
WSLとJupyter-notebookでCNN、その1、環境構築
画像の分類をしたくてDeep Learningについて勉強している
ネットで調べながらこの本を何度も読み直している
ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
(Amazonのサイトに飛びます)
CourseraのMachine Learningの講義もおすすめ
mecobalamin.hatenablog.com
試してみたいデータもあるのでどこか
似たようなことをやっている人がないか探してみたら
Kerasの開発者がCNNを使ってMNISTの画像認識を行っていた
https://github.com/keras-team/keras/tree/master/examples
いくつもファイルがあるがこの中からmnist_cnn.pyを利用した
mnist_cnn.pyについてはググるといくつも情報が出てくる
https://pondad.net/deep-learning/2016/12/25/keras-mnist.html
【AI初心者向け】mnist_cnn.pyを1行ずつ解説していく(KerasでMNISTを学習させる) - Qiita
手持ちの画像データを使いたいので
画像を読み込ませるために以下のサイトを参考にした
kerasでCNN 自分で拾った画像でやってみる - Qiita
Google Colaboratory で Keras 自作データセットを読み込み - Qiita
sklearn の train_test_split でデータの順番の情報を保持しておく - Qiita
実際に行ったのは
- mnist_cnn.pyを動かす環境の構築と実行
- 手持ち画像を読み込ませるコードの実行
今回はmnist_cnn.pyを動かす環境の構築
実行環境はWSLに作った
WSLを利用したのはPower Shellには
tensorflowをインストールできなかったためだ
まずはkeras/tensorflowをインストールする仮想環境を用意する
以下の過去記事を参考にした
mecobalamin.hatenablog.com
condaのコマンドを使ってtfという仮想環境を作る
conda create -n tf python=3.7 anaconda
環境の切り替えは
conda activate tf
と
conda deactivate
で行う
この環境にkerasとtensorflowをWSLにインストールした
keras/tensorflowの関係がいまいちよくわかっていないけど
tensorflowはバックエンドで実際の作業をするライブラリで
kerasはtensorflowを効率よく使うためのライブラリという認識
インストールは以下の通り
pip install --upgrade tensorflow
conda install keras
しようがないとはいえpipとcondaを混ぜて使ってしまったのが若干気になる
condaとpip:混ぜるな危険 - onoz000’s blog
仮想環境下にインストールしているので
やり直しをしやすいと思う
pythonコードの実行環境としてJupyterもインストール
pip install Jupyter
jupyter-notebookを使えるようになる
jupyter-notebookはデータサイエンス・機械学習の分野で
よく使われているらしい
セル毎にコードを実行できるので
修正箇所だけ実行とかできて便利
インストール後にjupyter-notebookを起動すると
jupyter-notebook
以下の表示が出るのでURLを
windowsのbrowserにコピペすると
jupyter-notebookを利用できる
To access the notebook, open this file in a browser: file:///home/hogehoge/.local/share/jupyter/runtime/nbserver-hogehoge-fugafuga.html Or copy and paste one of these URLs: http://localhost:8888/?token=hogehogefugafuga or http://127.0.0.1:8888/?token=hogehogefugafuga
実際にはtokenにアルファベットと数字の文字列が入っている
jupyter-notebookで新規にnotebookを作って
mnist_cnn.pyの中身をコピペするとこんな感じ
実行結果は以下の通り
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz 11493376/11490434 [==============================] - 5s 0us/step x_train shape: (60000, 28, 28, 1) 60000 train samples 10000 test samples Train on 60000 samples, validate on 10000 samples Epoch 1/12 60000/60000 [==============================] - 138s 2ms/step - loss: 0.2544 - accuracy: 0.9218 - val_loss: 0.0638 - val_accuracy: 0.9800 Epoch 2/12 60000/60000 [==============================] - 133s 2ms/step - loss: 0.0873 - accuracy: 0.9743 - val_loss: 0.0448 - val_accuracy: 0.9861 Epoch 3/12 60000/60000 [==============================] - 134s 2ms/step - loss: 0.0651 - accuracy: 0.9802 - val_loss: 0.0327 - val_accuracy: 0.9894 Epoch 4/12 60000/60000 [==============================] - 139s 2ms/step - loss: 0.0539 - accuracy: 0.9836 - val_loss: 0.0291 - val_accuracy: 0.9901 Epoch 5/12 60000/60000 [==============================] - 130s 2ms/step - loss: 0.0445 - accuracy: 0.9866 - val_loss: 0.0301 - val_accuracy: 0.9900 Epoch 6/12 60000/60000 [==============================] - 131s 2ms/step - loss: 0.0407 - accuracy: 0.9874 - val_loss: 0.0292 - val_accuracy: 0.9900 Epoch 7/12 60000/60000 [==============================] - 123s 2ms/step - loss: 0.0368 - accuracy: 0.9891 - val_loss: 0.0254 - val_accuracy: 0.9907 Epoch 8/12 60000/60000 [==============================] - 74s 1ms/step - loss: 0.0326 - accuracy: 0.9899 - val_loss: 0.0300 - val_accuracy: 0.9908 Epoch 9/12 60000/60000 [==============================] - 77s 1ms/step - loss: 0.0310 - accuracy: 0.9905 - val_loss: 0.0243 - val_accuracy: 0.9921 Epoch 10/12 60000/60000 [==============================] - 76s 1ms/step - loss: 0.0272 - accuracy: 0.9919 - val_loss: 0.0268 - val_accuracy: 0.9921 Epoch 11/12 60000/60000 [==============================] - 76s 1ms/step - loss: 0.0264 - accuracy: 0.9916 - val_loss: 0.0268 - val_accuracy: 0.9917 Epoch 12/12 60000/60000 [==============================] - 77s 1ms/step - loss: 0.0261 - accuracy: 0.9920 - val_loss: 0.0247 - val_accuracy: 0.9922 Test loss: 0.024740188298751492 Test accuracy: 0.9922000169754028
mnist_cnn.pyには
Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
とある
test accuracyは0.9920で大体あっているようだ
また今回使用した
Intel Core i5 7200U、GPUなしのnotebook PCでは
74-139s/Epochなので1/5 - 1/9 程度の計算速度か
値段の差を考えるとまあ順当
NVIDIA GRID k520 8 GB gddr5 PCIe gen3 x16クラウドゲームケプラーGPUグラフィックス900 – 12055 – 0020 – 000
とりあえず環境ができたので
次は手持ちのデータで試してみる
Pythonで数値のみの入力
以前、選択肢を数字で選ばせる
pythonのスクリプトの記事を書いた
mecobalamin.hatenablog.com
該当する部分は以下のコード
print('計算の種類を選んで数字を入力してね') print('1: 少数のたし算・ひき算') print('2: 大きな数のかけ算') print('3: あまりのあるわり算') print('4: 分数のたし算・ひき算') while True: eq_type = input('数値を入力 (1 - 4): ') if eq_type > '0' and eq_type < '5': break
動いていたから気にしていなかったが
入力は文字なのに大小の比較ができている
なぜだ?
文字列にも等号記号が使えることは知っていたが
調べてみると比較演算子も使えた
Pythonで文字列を比較(完全一致、部分一致、大小関係など) | note.nkmk.me
比較演算子の使い方 | Python入門
unicodeのコードポイントを比較しているそうだ
pythonではord()でコードポイントを取得できる
>>> ord('0') 48 >>> ord('1') 49 >>> ord('2') 50 >>> ord('9') 57
数字の0から9には
48から57が割り当てられている
なので過去記事で使ったコードでも
問題なく動いたようだ
本来ならint()で数値にして
大小比較するのが筋かも
ただし数値以外の文字・記号を
int()の引数にした場合はエラーになるので
try/except文を使って
エラーを弾きつつ
数値の入力を受け付けるように書き直した
try/excptの使い方は以下のサイトを参考にさせてもらった
Pythonの例外処理(try, except, else, finally) | note.nkmk.me
書き直したコードはこんな感じ
確認のためprint()を追加している
while True: eq_type = input('数値を入力 (1 - 4): ') try: int(eq_type) except ValueError as e: print('1から4までの数字を入力してね') else: if int(eq_type) >= 1 and int(eq_type) <= 4: break else: print('1から4までの数字を入力してね') print(eq_type)
もっと簡潔にかけそうな気がする
あと全角・半角の区別はしていない
出力は半角になる
そのうち区別できるようにしたい
Pythonista3でpythonプログラミング
pythonプログラミングに利用している
iOSアプリのPythonista3
mecobalamin.hatenablog.com
mecobalamin.hatenablog.com
割と色々できて便利
まずはpythonistaについて
iOS上で動作する革命的ものづくり環境「Pythonista 3」の魅力をとくと語る
iOS上で動作する革命的ものづくり環境「Pythonista 3」の魅力をとくと語る
iPad ProでPythonプログラム
iPad ProでPythonプログラム - Qiita
Deep Learningの勉強にも使っていたり
「ゼロから作るDeep Learning」をiPhoneのPythonistaだけで学ぶ(2)
「ゼロから作るDeep Learning」をiPhoneのPythonistaだけで学ぶ(2) - blog.tmp.tokyo
iPadで「ゼロから作るDeep Learning」を勉強するために必要なこと
poipoides.hatenablog.com
自分でも試してみたけどコードに変更が必要で
上記のリンク先の方が変更したコードを載せてくれている
3章か4章ぐらいまではpythonistaで動くことを確認した
その先は結局PCのpythonで。
今までやったのは
コンソールに結果を表示する
プログラミング
希望する機能を実装できていたけど
せっかくiPadを使っているのだから
タッチ操作できるプログラミングをしてみたい
pythonistaにはいくつもサンプルコードが入っていて
そのいくつかはタッチ操作のゲームだったりする
実際ゲームを作っている人達もいる
Pythonistaで作るポーカー作成講座(全5回)
Pythonistaで作るポーカー作成講座(全5回) | みやびのどっとぴーわい
Pythonista+sceneでトランプをランダムに表示する
Pythonista+sceneでトランプをランダムに表示する - Qiita
公式でXcodeに変換するコードを公開しているので
その気になればiOSアプリも作れそう
python2に対応
github.com
で、試しに作ってみた
作ったのは例えば何かカードゲームをして
得点を記録するプログラム
一度コンソールに表示するバージョンは書いていて
こんな感じ
それをこのように表示したい
プレイヤーは3人で
ポイントを入力してsubmitを押すと
totalに加算される
そしてroundが一つ進む
コードはpythonプログラムのui.pyと
ボタン等を配置したui.pyuiの2つで一セット
実際のコードはこの記事の最後に載せるとして
ui.pyの説明を書く
import ui import console
pythonistaにはsceneというライブラリもあるが
今回使用したのはui
consoleもpythonistaのライブラリで
コンソールを操作するのに使う
v = ui.load_view() v['num1'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num2'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num3'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v.present('fullscreen')
ui.load_view()でui.pyuiをロードしている
v['num1'].keyboard_typeは
num1に入力するときのキーボードの種類を設定する
num1は得点の入力なので数値のみ
なので最初から数字入力になっている
キーボードが表示されるようにしている
present('fullsucreen')で
フルスクリーン表示でコードを実行する
よくわかっていないんだけど
このときプログラムは×印をタップして停止させるまで
入力待ちになっているっぽい
関数を実行するにはui.pyに書かれた関数を
ui.pyuiのボタンに紐付けしておく
ボタンをタップすると
紐付けされた関数on_buttonが実行される
def on_button(sender):
引数のsenderには画面上の情報が入っているようで
superview[]とボタンやtextfieldの名前を使って値を取り出す
text_label1 = sender.superview['label1'] Num_1 = sender.superview['num1']
label1やnum1はtextfieldの名前であり
ui.pyuiで編集できる
print文はconsol画面に表示されるため
プログラムを停止するまで表示を見られない
書いただけなので読みやすく修正したいけど
とりあえずここまででやりたいことは実装できた
ui.pyuiも見やすいデザインにしたい
まだ読んでいないけどpytonista3を使った
プログラミング教本らしいのでメモ
PythonではじめるiOSプログラミング 〜iOS+Pythonで数値処理からGUI、ゲーム、iOS機能拡張まで〜
実際のコードは以下の通り
ui.py
import ui import console def on_button(sender): text_label1 = sender.superview['label1'] Num_1 = sender.superview['num1'] Re_1 = sum_score(text_label1.text, Num_1.text) text_label1.text = str(Re_1) Num_1.text = '' text_label2 = sender.superview['label2'] Num_2 = sender.superview['num2'] Re_2 = sum_score(text_label2.text, Num_2.text) text_label2.text = str(Re_2) Num_2.text = '' text_label3 = sender.superview['label3'] Num_3 = sender.superview['num3'] Re_3 = sum_score(text_label3.text, Num_3.text) text_label3.text = str(Re_3) Num_3.text = '' num_round = sender.superview['num_round'] num_round.text = str(int(num_round.text) + 1) #print(Num_3.text_color) print('round' + str(int(num_round.text) - 1), Re_1, Re_2, Re_3) def sum_score(m, n): r = 0 if m == '': r = int(n) elif n == '': r = int(m) else: r = int(m) + int(n) return r if __name__ == '__main__': console.clear() console.set_font('Menlo',20) v = ui.load_view() v['num1'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num2'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v['num3'].keyboard_type = ui.KEYBOARD_NUMBER_PAD v.present('fullscreen')
ボタンや数字の入力場所の配置はこんな感じ
赤でマークしたactionにon_button関数を登録した
submitのボタンを押すと
on_button関数が実行される
ui.pyuiはテキストファイルなのでエディタで中身が読める
よくわからないけどファイルの形式はJSON?っぽく見える
ui.pyui
[ { "nodes" : [ { "nodes" : [ ], "frame" : "{{119, 54}, {77, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "custom_attributes" : "", "action" : "", "alignment" : "right", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "num1", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 54}, {95, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "left", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "usr1", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 105}, {95, 43}}", "class" : "TextField", "attributes" : { "flex" : "WHLRTB", "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "left", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "usr2", "font_size" : 17 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 156}, {95, 43}}", "class" : "TextField", "attributes" : { "flex" : "WHLRTB", "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "left", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "usr3", "font_size" : 17 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{119, 105}, {77, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "right", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "num2", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{119, 156}, {77, 43}}", "class" : "TextField", "attributes" : { "uuid" : "EB343BBB-5CFB-4AE7-8BCC-41EE1ACDE42E", "font_size" : 17, "frame" : "{{60, 224}, {200, 32}}", "action" : "", "alignment" : "right", "autocorrection_type" : "default", "text" : "", "font_name" : "<System>", "spellchecking_type" : "default", "class" : "TextField", "name" : "num3", "flex" : "WHLRTB" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 54}, {97, 43}}", "class" : "Label", "attributes" : { "uuid" : "F3870D2E-9FCF-4C83-B5AF-C393166D3D4E", "flex" : "WHLRTB", "corner_radius" : 0, "frame" : "{{85, 224}, {150, 32}}", "number_of_lines" : 0, "border_width" : 1, "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "alignment" : "center", "text" : "0", "font_name" : "<System>", "class" : "Label", "name" : "label1", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 105}, {97, 43}}", "class" : "Label", "attributes" : { "uuid" : "F3870D2E-9FCF-4C83-B5AF-C393166D3D4E", "flex" : "WHLRTB", "corner_radius" : 0, "frame" : "{{85, 224}, {150, 32}}", "number_of_lines" : 0, "border_width" : 1, "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "alignment" : "center", "text" : "0", "font_name" : "<System>", "class" : "Label", "name" : "label2", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 156}, {97, 43}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "uuid" : "F3870D2E-9FCF-4C83-B5AF-C393166D3D4E", "corner_radius" : 0, "frame" : "{{85, 224}, {150, 32}}", "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "border_width" : 1, "alignment" : "center", "text" : "0", "font_name" : "<System>", "class" : "Label", "name" : "label3", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{95, 207}, {142, 41}}", "class" : "Button", "attributes" : { "action" : "on_button", "flex" : "WHLRTB", "border_width" : 1, "frame" : "{{120, 224}, {80, 32}}", "title" : "submit", "uuid" : "BD6B3517-3570-46B3-B6E4-E967C932197B", "class" : "Button", "corner_radius" : 0, "name" : "button1", "font_size" : 15 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{174, 6}, {73, 19}}", "class" : "Label", "attributes" : { "font_size" : 18, "flex" : "WHLRTB", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "AC87D8D9-39BC-4DA0-90E3-861257E72023", "class" : "Label", "alignment" : "left", "text" : "1", "custom_attributes" : "", "name" : "num_round", "font_name" : "<System>" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 6}, {150, 19}}", "class" : "Label", "attributes" : { "name" : "Round_title", "flex" : "WHLRTB", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "right", "text" : "Round", "font_size" : 18, "font_name" : "<System>" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{16, 33}, {95, 20}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "font_name" : "<System>", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "center", "text" : "User name", "name" : "", "font_size" : 18 }, "selected" : false }, { "nodes" : [ ], "frame" : "{{119, 33}, {77, 20}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "font_size" : 18, "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "center", "text" : "point", "name" : "", "font_name" : "<System>" }, "selected" : false }, { "nodes" : [ ], "frame" : "{{204, 33}, {97, 20}}", "class" : "Label", "attributes" : { "flex" : "WHLRTB", "font_name" : "<System>", "frame" : "{{85, 224}, {150, 32}}", "uuid" : "7CBBD8E2-1DAE-471D-B7D6-2EAA890A3C7F", "class" : "Label", "alignment" : "center", "text" : "total", "font_size" : 18, "name" : "" }, "selected" : false } ], "frame" : "{{0, 0}, {320, 480}}", "class" : "View", "attributes" : { "tint_color" : "RGBA(0.000000,0.478000,1.000000,1.000000)", "enabled" : true, "border_color" : "RGBA(0.000000,0.000000,0.000000,1.000000)", "background_color" : "RGBA(1.000000,1.000000,1.000000,1.000000)", "name" : "", "flex" : "" }, "selected" : false } ]