技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

行列操作周りのメモ

ニューラルネットワーク周りが行列だらけなので。
そして僕は数式では理解できず、コードで理解する人なのでメモ(汗

スカラー

といっても、基本的には単独の値を意味する

a = 1
b = 1.5
c = 1.2e5

ベクトル(一次テンソル)

スカラを直線状に並べたもの≒一次元配列

f:id:white-azalea:20210209235234p:plain

import numpy as np

a = np.array([1, 2, 3])
b = np.array([-1.1, 1.8e2, 3.14])

行列(二次テンソル

つってもこれも有名すぎるでしょう。

f:id:white-azalea:20210209235313p:plain

c = np.array([
    [1, 2, 3],
    [4, 5, 6]
])

多次元テンソル

複数次元のテンソルのことです

d = np.array([
    [
        [1, 2, 3],
        [4, 5, 6]
    ],
    [
        [7, 8, 9],
        [10, 11, 12]
    ]
])

テンソルの次元変更を reshape

ソース

simple = np.array([i for i in range(24)])
reshaped = simple.reshape(4, 6)
print(reshaped)
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]]
続きを読む

全幅探索アルゴリズム

お題はこれ

相変わらず問題だけ読んで、答えの処理を見ずに書いてみた系。

# 9=壁, 1=goal, 0=道
maze = [
    [0, 0, 0, 9, 9, 0, 9],
    [0, 9, 9, 0, 0, 0, 0],
    [0, 0, 0, 0, 9, 9, 9],
    [9, 0, 9, 0, 9, 0, 1],
    [0, 0, 9, 0, 0, 0, 9],
    [0, 9, 0, 0, 9, 0, 0]
]

で、自分が真っ先に考えたのが再起で全幅探索すること。
こんなのに、機械学習まで持って行っても仕方ないので(汗

現在の位置から、→↓←↑ の順番に見て、移動できるなら移動する。行き止まりに入ったら戻る…を繰り返します。

続きを読む

Python3 でマルバツゲームを自分ならどう書くだろう?

お題

一番最初の課題:三目並べ(マルバツゲームとも TicTacToe ともいう)の実装。

自分ならどう解くか?

ということで実装してみた。
自分なりに教科書を見ずに課題を解くなら何に気をつけるだろうか?

  • ベタ書きを避ける(定数を使う)
  • 入出力とロジックは分離する(テストしやすくする+移植しやすくする)

と先ずは考える。
ということで、書いたのがこんな感じ。

バージョンは Python 3.8.3 anaconda を利用。

続きを読む

ADコンバータ MCP3208 で可変抵抗の値を読み取ってみる

やったこと

可変抵抗を操作したときの抵抗の値をリアルタイムに読み取る。

使ったもの

回路

f:id:white-azalea:20210126204747p:plain

作りはこんな感じ

f:id:white-azalea:20210126210741p:plain

コード

# -*- cofing: utf-8 -*-

import RPi.GPIO as GPIO
from time import sleep

def readadc(adcnum, clockpin, mosipin, misopin, cspin):
        # MCP3208 から SPI 通信で 12 ビットのデジタル値を取得する。
        # 0-7 の 8 チャンネルが利用可能。
    if adcnum > 7 or adcnum < 0:
        return -1
    
        # 各ピンに初期電圧状態設定
    GPIO.output(cspin, GPIO.HIGH)
    GPIO.output(clockpin, GPIO.LOW)
    GPIO.output(cspin, GPIO.LOW)
    
        # 読み取り準備
    commandout = adcnum # 今回 0 なので 0b 0000 0000 0000 開始
    commandout |= 0x18 # スタートビット + シングルエンドビット  (0b 0000 0001 1000)
    commandout <<= 3   # LSB から 8 ビット目を送信するよう指定 (0b 0000 1100 0000)

    # クロックピンの電圧上げ下げをキーに、
        # 0b 0000 1100 0000 から 1100 部分を順に送信
    for i in range(5):
        if commandout & 0x80:
            GPIO.output(mosipin, GPIO.HIGH)
        else:
            GPIO.output(mosipin, GPIO.LOW)
        commandout <<= 1
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)

    # clock ピンを区切りに使用して、13 ビット読み取り (nullbit + 12bit data)
        # misopin の状態を利用して読み取り
    adcount = 0
    for i in range(13):
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
        adcount <<= 1
        if i > 0 and GPIO.input(misopin) == GPIO.HIGH:
            adcount |= 0x1
    GPIO.output(cspin, GPIO.HIGH)

        # 読み取った結果を応答
    return adcount

# ここからメインの流れ
GPIO.setmode(GPIO.BCM)

# 使うピンの定義
SPISCLK=11  # 数字は GPIO 番号レイアウトはここ参照 [https://white-azalea.hatenablog.jp/entry/2021/01/06/212250:title]
SPIMOSI = 10
SPIMISO = 9
SPICS = 8

# ピンをセットアップ
GPIO.setup(SPISCLK, GPIO.OUT)
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICS, GPIO.OUT)

try:
    while True:
        inputVal0 = readadc(0, SPISCLK, SPIMOSI, SPIMISO, SPICS)
        print(inputVal0)
        sleep(0.2)
except KeyboardInterrupt:
    pass
    
GPIO.cleanup()

実行結果

抵抗スイッチを左に回すと f:id:white-azalea:20210126212336p:plain

右に回すと f:id:white-azalea:20210126212419p:plain

ほっほーい

ラズパイで音楽を鳴らせ

環境

やったこと

といってもこれだけ

$ sudo apt install mplayer

そして適当に mp3 ダウンロードしたら

フリーのBGMと動画やゲーム用音楽素材[Wave,MP3]

$ mplayer menuettm.mp3

と指定してやるだけ。
出力は HDMI のディスプレイか、本体のイヤホンジャックで、変える場合は

f:id:white-azalea:20210120184748p:plain

ここからやれます。

コマンドで使えるということは、プログラムから呼べるってことで…

Docker + CakePHP4.2 + VSCode でデバッグサーバに接続する

日中そういうことにドハマリしたので、日々の勉強がてらやってみて成功したのでメモしてみる。

ということで、上記バージョン以外ではどうかは保証外。

ディレクトリ構成

f:id:white-azalea:20210118194952p:plain

ということでこの状態からガンガン行こうか

xdebug の設定(php.ini

php.ini にこんな感じでケツに追記した。
元となるファイルは、PHP の Docker コンテナ起動してから「/usr/local/etc/php/php.ini-develop」をコピって来ればいいでしょう。

[xdebug]
xdebug.idekey      = "PHPVSCode"
xdebug.client_host = 'host.docker.internal'
xdebug.client_port = 9003
xdebug.mode          = "debug"
xdebug.output_dir         = "/root/codes/trace_logs"
xdebug.remote_handler     = "dbgp"
xdebug.start_with_request = yes
xdebug.log_level          = 10

デバッグ設定はすごく癖が強くて、Java ならデバッグサーバが立ち上がってそこに IDE が接続詞に行きますが、PHPデバッグサーバが指定のクライアントにデバッグ接続しに行くという流れがあるようです。
それを知らないとガチでハマります。

今回は Docker 内の PHP からホストマシンの 9003 ポートへ接続しに行きます。

Dockerfile

こっちはこんな感じ

FROM php:7-fpm-buster

RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y unzip curl wget git gcc libicu-dev

RUN docker-php-ext-install intl pdo pdo_mysql

RUN pecl install xdebug && docker-php-ext-enable xdebug

COPY --from=composer /usr/bin/composer /usr/bin/composer

ADD ./php.ini /usr/local/etc/php/

WORKDIR /root/codes

CMD cms/bin/cake server -H 0.0.0.0 -p 80
EXPOSE 80

最後の2行は、CakePHP のインストール後に入力しませう。

docker-compose.yml 設定

docker-compose.yml も一応晒します。

version: '3.7'
services:
  host:
    restart: always
    build: ./data/main
    environment: 
      TZ: 'Asia/Tokyo'
    volumes:
      - './sources:/root/codes'
    ports:
      - "8765:80"
    tty: true
    stdin_open: true
続きを読む

CakePHP4.2 で Http get する

記事の本質は、「オープンソースならコードよんじゃえ♪」でオナシャス!

といっても、それだけ言えば公式ドキュメント見れば即終了する。

book.cakephp.org

use Cake\Http\Client;

$http = new Client();
$response = $http->get('http://example.com/search', ['q' => 'widget']);

わかりやすっ

// 文字列としてレスポンス全体を読み込み
$response->getStringBody();

// レスポンスボディーを含む Psr\Http\Message\StreamInterface を取得
$stream = $response->getBody();

// 何らかの XML を取得
$http = new Client();
$response = $http->get('http://example.com/test.xml');
$xml = $response->getXml();

// 何らかの JSON を取得
$http = new Client();
$response = $http->get('http://example.com/test.json');
$json = $response->getJson();

// 連想配列として全てのヘッダーを取得
$response->getHeaders();

// 配列として単一のヘッダーを取得
$response->getHeader('content-type');

// 文字列としてヘッダーを取得
$response->getHeaderLine('content-type');

// レスポンスのエンコーディングを取得
$response->getEncoding();

// 全てのヘッダーの key=>value の配列を取得
$response->headers;

でもそんなのはドキュメントの焼き直しでしかなくて、では URL パラメータに 'hoge' => 'fuga&test=value' と意地悪したらどういったクエリが出るのでしょうか?
としたときに、公式ドキュメントになかったら自分は何を見るか?

コード読めばいいじゃない

ビバ!オープンソースぅ!

ってことで github 調べてみる

github.com

そして該当ライブラリは Http/Client.php ということで get を探しませう。

cakephp/Client.php at 4.2.2 · cakephp/cakephp · GitHub

    public function get(string $url, $data = [], array $options = []): Response
    {
        $options = $this->_mergeOptions($options);
        $body = null;
        if (is_array($data) && isset($data['_content'])) {
            $body = $data['_content'];
            unset($data['_content']);
        }
        $url = $this->buildUrl($url, $data, $options);

        return $this->_doRequest(
            Request::METHOD_GET,
            $url,
            $body,
            $options
        );
    }

$data が URL パラメータなので、ビルドしてるのは buildUrl

    public function buildUrl(string $url, $query = [], array $options = []): string
    {
        if (empty($options) && empty($query)) {
            return $url;
        }
        if ($query) {
            $q = strpos($url, '?') === false ? '?' : '&';
            $url .= $q;
            $url .= is_string($query) ? $query : http_build_query($query);
        }

第二パラメータは文字列でもいいのか、文字列を入れるとそのままリクエストするのね…

http_build_query は標準 API のようだ。

PHP: http_build_query - Manual

文字コードエンコーディングはしないのかYO!
やるなら事前にエンコードしてから渡しておく必要がありそうだということまで分かった。