OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoder Beginner Contest 107

## [A - Train](https://atcoder.jp/contests/abc107/tasks/abc107_a)

O(1)
法則は、

```txt
後ろから何両目 = N - i + 1
```

です。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repx(i,x,n) for(int i=x; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N, i;
    cin >> N >> i;
    cout << N - i + 1 << endl;
    return 0;
} 
```

## [B - Grid Compression](https://atcoder.jp/contests/abc107/tasks/abc107_b)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define repx(i,x,n) for(int i=x; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main(){
    int H, W;
    cin >> H >> W;
    vector<string> a(H);
    for(auto &s:a) cin >> s;

    int h_cnt = H;
    int w_cnt = W;

    for(int i=0; i<H; i++){
        for(int j=0; j<h_cnt; j++){
           int cnt=0;
            for(int x=0; x<W; x++){
                if(a[j][x] == '.'){
                    cnt++;
                }
            }  
            if(W == cnt){
                if(j<H-1) swap(a[j+1], a[j]);
                if(j == h_cnt-1) h_cnt--;
            }               
        }
    }

    for(int i=0; i<W; i++){
        for(int j=0; j<w_cnt; j++){
            int cnt=0;
            for(int y=0; y<H; y++){
                if(a[y][j] == '.') cnt++;
            }

            if(H == cnt){
                if(j<W-1){
                    for(int y=0; y<H; y++){
                        swap(a[y][j+1], a[y][j]);
                    }
                }
                if(j == w_cnt-1) w_cnt--;
            }             
        }
    }

    for(int i=0; i<h_cnt; i++){
        for(int j=0; j<w_cnt; j++){
            if(j != w_cnt-1) cout << a[i][j];
            else cout << a[i][j] << endl;
        }  
    }

    return 0;
} 
```
Gitのコミットメッセージ内容からCircleCIで実行する処理を分岐する(自動テストスキップなど)

## やりたいこと
テストコードに関連のない修正のコミットで自動テストが動き、
早くマージしたいのにできない!!という悩みをなんとかした。

## コード

```config.yml
      - run:
          command: |
            commitMessage=$(git log -n 1 --oneline --pretty=format:"%s")
            echo "${commitMessage}"
            if [[ $commitMessage =~ --hoge ]]; then
              echo "--hogeのオプションあり"
            else
              echo "--hogeのオプションなし"
            fi
```

コミットメッセージで条件分岐してます。
コミットメッセージに[--hoge]がある場合、ない場合で、echoの処理を差し替えてあげれば完成です。
CDKでWordPressを構築する手順書を公開します

CDK v2の凄さとMkDocsの凄さに感動して、CDKでWordPressを構築する手順書を作成しました。

https://moritalous.github.io/wordpress-cdk/


この構成をほぼCDKで手順を追いながら構築します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/ee17da34-ba56-bcca-bbac-fd4416831f78.png)

私なりに感じたCDKの凄さです。

* マネジメントコンソールを触らなくても環境構築ができる
* やり直しが何度も効くし、うまくいった状態まで巻き戻せる  
    実際、この手順書を完成させるまでに30回ぐらいは環境をすべて消して一から構築してを繰り返したと思います。
* リソースの消し忘れがない
* IDEの補完が効く  
  CloudFormationのJSONやYAMLを書くのが嫌でも、CDKなら楽しみながら環境構築ができました。
* 学習成果をアウトプットできる

最後の**学習成果をアウトプットできる**が一番の発見でした。

WordPressの環境をマネジメントコンソールで作ってみるだけだと、なんとなくわかった気がしますが、アウトプットにはつながらないので、しばらくすると忘れてしまうと思います。しかし、CDKの場合は、**ソースコードが残る**ので、以前どうやって作ったか、作成するリソースはどんなもの必要なのかなどが後で見返してもわかります。今回は、MkDocsを使ってドキュメント化することも体験したかったので手順書化しましたが、CDKのソースだけでも十分資産になっただろうなと感じました。


実際に試していただけた方は、感想をいただけると嬉しいです。
JavaのメソッドとJavaDocの結びつきを考える

いつもの業務中にメソッド名プラス数字というメソッドが乱発されていた。
ただ、これって改善したほうがいいのかと悩んだということに関して記事にさせていただく。

# 問題のコード
問題のコードと似た状態のコードを参考に記載させていただく。
```
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        DoSomething1();
        DoSomething2();
        DoSomething(1); 
        DoSomething(2);
    }

    /**
     * DoSomething1の説明
     * 
     */
    public static void DoSomething1(){
        //do somthing1
    }
    
    /**
     * DoSomething2の説明
     * 
     */
    public static void DoSomething2(){
        // dosomthing2
    }
    
    
    /**
     * DoSomethingの説明
     * 
     */
    public static void DoSomething(int i){
        switch(i){
            case 1:
                //doSomthing 1
                break;
            case 2:
                //doSomthing 2
                break;
            
        }
    }
}
```
自分としてはDoSomethingメソッドのほうでうまく処理を一つにして、変数名とかをうまいことDoSomethingのJavaDoc内へ記載すればいいかなって考えたんですが、案外見にくくなる可能性があるかなと思って。

# 一つのメソッドにまとめて引数として処理する方法の問題点
一番の問題点は、JavaDocの説明書きが長くなってしまうことであると思われる。
みんながみんな縦置きモニタなどという変態ツールを持っているわけではないので、
縦長の文章を永遠と読まされると結構うんざりしてしまう。
なので、JavaDocの文章はなるべく簡略するという点では、メソッドと引数でなんとか処理を考えるのではなく、
案外連番のメソッドなんていう冗長性の高そうなメソッドを作るのもありなのかなと思う次第である。

# 自分としての提案
連番は辞めて意味のある英語を使いませんか。
自分のプロジェクトローマ字変数、ローマ字メソッド名乱発の上、
詳細設計書とかは充実している割にそれをちゃんとみないと
JavaDocとかもちゃんと書かれていないので、結構ソースだけを見ていると
全然仕様がわからないんですが。
ソースと別に詳細設計書とかをエクセルで開くのも結構面倒ですし。
デュアルモニターとかを使うにしても視点移動が多くなり疲れるんですが。
Cloud Workflows で YYYYMMDD 形式の文字列を得る

## Background
Google Cloud Platform (GCP) のサービスの一つ Cloud Workflows を利用する機会がありました。その際、ワークフロー内の特定のステップにおいて、引数に `YYYYMMDD` 形式の文字列が必要となったので、 標準ライブラリを利用したスタンドアローンな実装の一例をこちらに（備忘録として）記録しておきます。

## TL;DR

| # | 標準ライブラリ | 用途 | 実行後の例 |
|:-:|:-----------|:----|:------|
| 1 | [sys.now](https://cloud.google.com/workflows/docs/reference/stdlib/sys/now) | 現在時刻の UNIX 時間を取得する | `1651647916.8227115` |
| 2 | [time.format](https://cloud.google.com/workflows/docs/reference/stdlib/time/format) | UNIX 時間を日時の形式（ ISO 8601 ）に変換する | `2022-05-04T16:05:16.822711+09:00` |
| 3 | [text.substring](https://cloud.google.com/workflows/docs/reference/stdlib/text/substring) | 日付部分（ `YYYY-MM-DD` ）を取得する | `2022-05-04` |
| 4 | [text.replace_all](https://cloud.google.com/workflows/docs/reference/stdlib/text/replace_all) |  `-` を削除する | `20220504` |

## Example

```yaml
main:
    steps:
    - extractCurrentTimestamp:
        call: sys.now
        result: currentTimestamp

    - formatCurrentTimestamp:
        call: time.format
        args:
            seconds: ${currentTimestamp}
            timezone: 'Asia/Tokyo'
        result: currentDatetime

    - substrCurrentDatetime:
        call: text.substring
        args:
            source: ${currentDatetime}
            start: 0
            end: 10
        result: currentDate

    - removeHyphen:
        call: text.replace_all
        args:
            source: ${currentDate}  
            substr: '-'
            repl: ''
        result: result

    - showResult:
        call: sys.log
        args:
            data: ${result}
```

## Summary
Cloud Workflows をトリガーする際に `YYYYMMDD` 形式の文字列を引数として動的に引き渡すことが面倒な場合に、このような処理を記述することで簡単に実現することができます（そのようなケースがあれば、の話ですが...）。
キャリアアグリゲーション とは

## 勉強前イメージ

キャリアの集合・・・？

## 調査

### キャリアアグリゲーション とは

carrier aggregation と書き、略して CA とも言われます。
無線通信を高速化する手法の一つです。
複数の周波数帯の電波を同時に使用することで、通信速度や通信品質の向上を図るものでLTEから導入されています。

LTEは最大20MHz幅の連続した周波数帯域でデータ通信を利用していますが、
元々日本でのキャリアは複数の周波数帯に分かれており、また今まで使用していた3Gも並行して運用する必要がありました。
その為、LTEで必要になる連続した周波数帯域を安定して利用できないケースが有りました。

そこで考えられたのが `キャリアアグリゲーション` の技術になります。
複数の同じ帯域幅の周波数帯を同時に利用することで、通信速度を倍以上にできたり
片方の通信状況が良くないときでも、他の周波数帯を利用することで利用者側は安定した通信を使用することができます。

2CC CA(2波キャリアアグリゲーション)、3CC CA(3波キャリアアグリゲーション)、4CC CA(4波キャリアアグリゲーション)など種類があります。

## 勉強後イメージ

いくつかの周波数帯を同時にしようするってできるんやな

## 参考

- [キャリアアグリゲーション 【carrier aggregation】 2CC CA](https://e-words.jp/w/%E3%82%AD%E3%83%A3%E3%83%AA%E3%82%A2%E3%82%A2%E3%82%B0%E3%83%AA%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3.html)
- [キャリアアグリゲーションの意味と確認方法は？ドコモやソフトバンクはない？](https://simchange.jp/wimax-ca/)
gccコマンドのオプションの説明

gccコマンドのオプションの一部を説明をします。

```
gcc -Wall -ansi -g -o file file.c
```

とあった場合、

# gcc

gccコマンドの事。

# -Wall

バグが潜む可能性のある箇所に警告(Warning)を出してくれる。

# -ansi

ANSI規格にのっとったCプログラムをサポートする。

# -g

gdbを使用したデバッグが出来る。

# -o file

file で指定した名前でオブジェクト ファイルに名前をつける。

# file.c

C言語ソースファイル名。
Ruby初心者がGitHub上でよくやりがちな誤爆メンションとその解決策

## はじめに：誤爆メンションって何？
Rubyでは`@`で始まる変数がインスタンス変数になります。
これはRuby on Railsなどでも当然同じルールです。

```ruby
# @で始まる変数はインスタンス変数 
@foo = 1

# 何も付かない変数はローカル変数
foo = 1
```

一方、TwitterやGitHub、そしてこのQiitaなど、昨今のSNSでは`@`がユーザーへのメンションとしても使われています。
たとえば、以下の画像に見える`@jnchito`は、jnchitoというTwitterユーザーに対するメンションです。

![Screen Shot 2022-05-04 at 15.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/bff65b1b-67bb-c4f4-4427-2e349e2b1428.png)

この2点はわざわざ僕が説明しなくても「そんなこたぁ前からわかっとるわい！」と思われそうな話なのですが、TwitterやGitHubで何も考えずにRubyのコードをコピペすると、予期せずメンションが発生するので要注意です。

たとえばGitHubを例に挙げると、こんなイメージです。

![Screen Shot 2022-05-04 at 15.34.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/34380643-46c9-7ff8-0aab-9dccbd99414e.png)

こうすると「GitHub上に実在する [bookさん](https://github.com/book)」にメンションを送ることになってしまいます。

![Screen Shot 2022-05-04 at 15.37.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/8c1ffdac-444a-3a61-8e3b-b31071e25d91.png)

ですが、ここではもちろん `@book` さんにメンションを送る必要はありません。

SNS上で発生するこういった意図しないメンションのことを「誤爆メンション」と僕は呼んでいます。

## 解決策

Markdownでは単語をバッククオートで囲むとコードスパンになります。コードスパンにすればメンションは発生しません。

```markdown
ここは `@book = Book.new(book_params)` 以外の方法で `@book` をnewできませんか？
```

以下のように薄いグレーの背景になっていれば、コードスパンになっているので大丈夫です。

![Screen Shot 2022-05-04 at 15.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/eed43eb1-f66a-2fca-508a-d24c8f775d7a.png)

バッククオートを3つ重ねてコードブロックにするのも同じく有効です。

````markdown
ここは 

```ruby
@book = Book.new(book_params)
```

以外の方法で `@book` をnewできませんか？
````

![Screen Shot 2022-05-04 at 15.43.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/a3530e29-f83b-085e-a480-f409a6c7a0d1.png)

GitHubやQiitaなど、Markdown記法を採用しているサイトはこれで大丈夫ですが、TwitterはMarkdown記法ではないので、意図的に`@`のうしろにスペースを入れるぐらいしか対策はないと思います。

![Screen Shot 2022-05-04 at 16.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/717f31a3-b156-5aa5-0fbc-9278d811bdb9.png)

そうそう、上の例だと`Book.new`がURLと見なされているので、ここもドットの前にスペースを入れたりしてリンクにしない方がいいですね。（面倒くさいけど・・・）

![Screen Shot 2022-05-04 at 16.06.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/99370baa-cb2b-9b28-d410-5fb43c502218.png)


## まとめ（と情報募集）
というわけで、この記事では昨今のSNSで発生しやすい誤爆メンションと、その解決策を紹介しました。

Rubyのコードを交えながらコメントする際は、必ずインスタンス変数をバッククオートで囲むようにしましょう！・・・と言っても、プログラミング初心者だとなかなかこの問題に気付きにくいですよね〜。
今のところ「気を付ける」ぐらいしか対策が思いつかないんですが、もうちょっといい方法はないのかな〜と思ったりします :thinking: 

もし「気を付ける」以外の何かいい仕組みをご存じの方がいたら、コメント欄で教えてください！

https://twitter.com/jnchito/status/1515129179758788609

### 参考

QiitaとGitHubのMarkdown記法については、以下の公式ページが参考になります。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

[基本的な書き方とフォーマットの構文 \- GitHub Docs](https://docs.github.com/ja/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax)
GoogleHomeのアプリについて

ずるずると簡単なクイズをだすものを作った。　

* ssmlを使うのが少し癖があった
    * メディアファイルのurlのエスケープがないとわかりにくいエラーに陥る
* 変数っぽいことはできそう
    * sessionなどが使えるっぽい
* ロギングはconsole.logとかでいける(cloud functions) 
* ローカルでのバージョン管理もできそうだがやってない
* 画面上でできないこともcliでファイル反映だとある程度できる
* ユーザーごとの独自設定とかどこまでやれるのかよくわからないけど、今回はそこまで頑張らない
* リリースしたらcloud functionsとかの費用は個人にかからないっぽい記述をどこかで見たけど、よく確認にしてない
[図解]マークルツリーについて理解しよう！〜ブロックチェーンに絡めながらわかりやすく解説〜

# はじめに
今回は「**マークルツリー**」について解説していきます！

「**マークルツリー**」はブロックチェーンや仮想通貨にも関係してくるものです。

図解たっぷりで解説していくのでこの記事を読み終わる頃にはしっかり理解できます！

「**ブロックチェーンや仮想通貨に興味がある**」

「**マークルツリーって何？**」

「**アルゴリズムに興味がある**」

こんな人の役に立てば幸いです。

前置きは早々に早速みていきましょう！

https://chaldene.net/python-book

# マークルツリーとは？

まずは「マークルツリー」がどんなものなのかや関連用語について解説していきます。

## 概要

::: note
データが正しいか効率的に検証するデータ構造。
:::

「**マークルツリー**」を一言でいえばこのようになります。

複数のデータがあるとして、その全てのデータが正しいものかを検証するにはどのような方法があるでしょうか？

１つ１つ検証していけば良いのですが、それでは時間がかかりすぎてしまいます。

その際に用いられるのがこの「**マークルツリー**」です。

名前の通り下記のような二分木の「**ツリー**」構造になっています。

![ブログ-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/e58e0ad8-b28c-c6dc-c672-c038f1dcb8cd.png)


この図を基準として、「**マークルツリー**」に近づけていきましょう。

「**マークルツリー**」はデータの検証を行う役割を持つため、どちらかというと上記のように矢印が上から下にいくよりも、下から上にいくほうが正しいです。

![ブログ-1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/f6197c56-c0ee-5222-5e7d-f84972cf08d0.png)

このようにボトムアップで要素を足し合わせていき、最終的に１つの値になります。

この「**ツリー**」のAの部分を検証用の値として用いるのが「**マークルツリー**」です。

しかし、この図ではまだイメージが湧きづらいと思うので、さらに変更を加えます。

![ブログ-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/32fda849-5c70-4aa8-d4cb-359678bc6eb5.png)

これでイメージしやすくなったはずです！

各要素をどんどん足し合わせていって、最終的にABCDEFGHという値になっています。

これが「**マークルツリー**」というものです。

ちなみにこの値は本来全て「**ハッシュ化**」して「**ハッシュ値**」となります。

「**ハッシュ化**」についてわからない方は以下を参考にしてください。

https://chaldene.net/hash

説明のためにわかりやすいものにしています。

そのため実際はこんな感じになります。

![ブログ-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/a993d34d-8b12-680e-4294-7ae49f18ef12.png)

「**２つのハッシュ値を足し合わせたものをハッシュ化する**」ということを繰り返して、最終的に１つの値となります。

ちなみにハッシュ値は、どんな長さのデータを入力しても同じ長さの値を返します。

上の図でも全て同じサイズの「**ハッシュ値**」になっているのが確認できますね。

そのため、どんな大きなどんな大きなデータやどんなに多くのデータを入力しても、最終的に得られる値は決まった長さになります。

ここでもしかしたら以下のような疑問を持つ人がいるかもしれません。

::: note
データが奇数個の場合はどうするの？
:::

図を見てもらえればわかると思いますが、データが偶数個でないとツリー構造は作れません。

![ブログ-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/0729d9b5-8c79-2d93-3dc7-9b6ae531672f.png)

ではどうするかというと、末尾のデータを複製させます。

![ブログ-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/b0cd9922-75da-e0e1-4056-cda1604f7e1b.png)

このように末尾であるGを複製して足し合わせていきます。

最終的に出力される値はあくまで検証のための「ハッシュ値」なので、このように複製しても問題がないのです。

# 続き

これより先は以下の記事にまとめています。

https://chaldene.net/markle-tree

より詳しく**マークルツリー**について学ぶことができるので、興味がある方はぜひ！
（もちろん無料です！）
Raspberry Pi Pico / XIAO RP2040 ArduinoでI2Cを使う

# 自分への教訓

ボード定義をしっかり確認しなければ...

# Raspberry Pi Pico を Arduino で使う場合

デフォルトは
**SDA = GP4 = ボードの6ピン** 
**SCL = GP5 = ボードの7ピン** 

に接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/28d76fbd-0c62-fec7-02c7-cbf47e483d30.png)


```pinmode_arduino.h
// Wire
#define PIN_WIRE_SDA        (4u)
#define PIN_WIRE_SCL        (5u)
```

こちらのかたの記事ではGPIO6とGPIO7になっていたのですが，
- https://qiita.com/jamjam/items/0860b6b99a07bfd9dc3f

私が使った環境ではそこから変更になっていたようです。確認した場所は以下です。

`~/.platformio/packages/framework-arduino-mbed/variants/RASPBERRY_PI_PICO/pinmode_arduino.h`

`~/Library/Arduino15/packages/arduino/hardware/mbed_rp2040/3.0.1/variants/RASPBERRY_PI_PICO/pinmode_arduino.h`

I2Cで使うピンを変更できそうな記事も見かけたのですが，私の環境では動きませんでした... なぜだろう

もともと u8g2ライブラリーでSSD1306を使いたかったのですが，上記の接続に半日かけてやっと気づき，無事動くようになりました。

```main.cpp
#include <Arduino.h>
#include <U8x8lib.h>

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); 	      

void setup(void)
{
  u8x8.begin();  
}

void loop(void)
{
  u8x8.setCursor(0, 0);
  u8x8.setFont(u8x8_font_8x13B_1x2_f);
  u8x8.print("Hello World!\r\n");

  delay(2000);
  u8x8.clear();
}
```

# XIAO RP2040 で I2C を使う

もともとこちらの方の記事を参考に動かそうとしていたのですが，すっと動かずに苦戦しました...

- https://aloseed.com/it/xiao_rp2040/#toc16

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/ee8bee03-08b6-ba64-cede-c4c8371f81e2.png)

そもそも
**GPIO6 = SDA**
**GPIO7 = SCL**

として引き出されていて，Raspberry Pi Picoのデフォルトである GPIO4/GPIO5 は使えません。

```~/Library/Arduino15/packages/Seeeduino/hardware/rp2040/2.7.2/variants/Seeed_XIAO_RP2040/pins_arduino.h
// Wire
#define SDA        (6u)
#define SCL        (7u)
```

なので，GPIO6/GPIO7にI2Cを接続しつつ，XIAO RP2040 専用のボード定義を使います。

- https://wiki.seeedstudio.com/XIAO-RP2040-with-Arduino/

これを Arduino IDE でインストール，無事I2Cが扱えました。拡張ボードのSSD1306が動き出しました。

Platformioで作業したかったのですが，

- Raspberry Pi Picoとしてビルドすると，上記の通り，I2CはGPIO4/GPIO5を使うことになりますので，XIAO RP2040 ではうまく動きません。
- I2Cピン定義変更を試みたのですが，うまくいってません。
- XIAO RP2040のピン定義を自力で追加すればいいのかな? 気が向いたらやってみようかな...
- https://qiita.com/WhiteGrouse/items/10c36e382efd2872d267
Reactを基本からまとめてみた【27】【useEffect】

## useEffectとは

『useEffect』を使うと、『useEffect』に渡された関数はレンダーの結果が画面に反映された後に動作する。つまりuseEffectとは、「関数の実行タイミングをReactのレンダリング後まで遅らせるhook」の事。
副作用の処理（DOMの書き換え、変数代入、API通信などUI構築以外の処理）を関数コンポーネントで扱える。

## 副作用を実行、制御するためにuseEffectを利用する

```sample.js
useEffect(() => {
  /* 第1引数には実行させたい副作用関数を記述*/
  console.log('副作用関数が実行されました！')
},[依存する変数の配列]) 
// 第2引数には副作用関数の実行タイミングを制御する依存データを記述
```
第2引数を指定することにより、第1引数に渡された副作用関数の実行タイミングを制御することができる。Reactは第2引数の依存配列の中身の値を比較して、副作用関数をスキップするかどうかを判断する。

| 　　　　|説明|データ型
|:-----------|------------:|:------------:|
| 第1引数| 副作用関数（戻り値はクリーンアップ関数、または何も返さない）|関数
| 第2引数| 副作用関数の実行タイミングを制御する依存データが入る（省略可能）|配列

## useEffectでの外部からデータをfetchする方法

外部のサーバのやりとりにuseEffectを利用する場合は第2引数に[](配列)をつけるのを忘れないこと。配列をつけていない場合はコンポーネントの更新によりuseEffectが実行され、サーバへのFetchが継続して行われることになりサーバへの負荷をかけることになる。ネットワーク処理がブラウザ上では気づかない場合があるのでブラウザ上ではなにも発生していないのにすごい数のリクエストがサーバに送信されていることがある。

```sample.js
import React,{ useState, useEffect} from 'react';
import './App.css';

function App() {

  const [posts, setPosts] = useState([]);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts')
      .then(response => response.json())
      .then(data => {
        setPosts(data)
      },[])
  })

  return (
    <div className="App">
      <h1>Learn useEffect</h1>
      <div>
        {
          posts.map(post => (
            <div key={post.id}>{post.title}</div>
          ))
        }
      </div>
    </div>
  );
}
```

useStateを使ってstata変数postsを定義し、初期値を空の配列に設定する。マウント後にuseEffect内のfetchメソッドが実行され、JSONPLACEHOLDERのURLにアクセスを行いpostsデータ一覧を取得。取得したデータはsetPostでposts変数に挿入し、最後にmapメソッドで展開し、ブラウザに一覧を表示する。

## async, awaitを利用して外部から取得する場合

useEffectでasync, awaitを利用して外部リソースからデータを取得したい場合は下記のように記述することができる。

```sample.js

import React,{ useState, useEffect} from 'react';
import './App.css';

function App() {

  const [posts, setPosts] = useState([]);

  useEffect(() => {
    const fetchPost = async () => {
      const response = await fetch(
        'https://jsonplaceholder.typicode.com/posts'
      );
      const posts = await response.json();
      setPosts(posts);
    };
    fetchPost();
  })

  return (
    <div className="App">
      <h1>Learn useEffect</h1>
      <div>
        {
          posts.map(post => (
            <div key={post.id}>{post.title}</div>
          ))
        }
      </div>
    </div>
  );
}

export default App;
```




## 参考サイト
[初心者でも簡単にわかるReact useEffect, useLayoutEffectの使い方](https://reffect.co.jp/react/react-useeffect-understanding#useEffectfetch)
RealVNC Viewer Protocol error: bad rectangle size

(外部マシン)Debianのバージョンを11に上げたらScreen SharingにRealVNCで接続時にこういうエラーが出るようになった。

Protocol error: bad rectangle size 16191x16191

![Screenshot from 2022-05-04 13-28-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29692/a94c530d-e7d8-4b26-2666-944a1358bd0b.png)

どうも、Quality=Auto (デフォルト)だとこうなるらしい。
Qualityを固定すれば良い。[^1]

コマンドラインに--Quality=High[^2]を加えるか、$HOME/.vnc/config.d/vncviewer[^3]にQuality=Highと書けば良い。

[^1]: 帯域のことを考えるとAutoのほうが良い気もするのですが、やむを得ないところ。
[^2]: HighとMediumのどちらで固定すべきなのか、うーむ
[^3]: https://help.realvnc.com/hc/en-us/articles/360002253878-Configuring-VNC-Connect-Using-Parameters
Bootstrap modal表示後にSlick利用したいけど躓いたのでメモ

# 概要
Bootstrap4 modal内で画像を複数表示する際にカルーセルを採用しました。
ライブラリは過去に利用実績のあった、Slick.jsを使えば簡単に作成できる！と思い、取り組んだのですが、
色々躓いた箇所があったので、備忘録として記事を書いてみよう！となりました。（初めての記事です）


# 環境
bootstrap：4.0.0
slick.js：1.8.0


# 経緯
最初はなんの対処もせずにmodal上でカルーセルを表示させようとしていました。
しかし、それだとSlickの発火タイミングではModalは表示されていないので、
カルーセルを表示させる箇所のwidthを取得できずにSlick動きません状態でした。

## modalが表示されてから、Slick起動

[参考サイト1](https://qiita.com/mimoe/items/c4f4754815525b08041e)
同じような事象にぶつかっていた方がおりましたので、その記事を参考に下記コードで

```public/js/script.js
let slider = $('.product-img').slick({  //.product-imgはカルーセルで表示したい画像の上位クラス
  slidesToShow: 1, //スライド一枚だけ表示
  lazyLoad: 'progressive',　//ページが読み込まれた後に非表示の画像を読み込み
  dots: true　　　　　　　　　　　　　//カルーセルの下にドット表示
});
  $('.js-modal-open').on('click', function(){　 //.js-modal-openはモーダル表示する際に押下するクラス
  slider.css('opacity', 0);
  slider.animate({'z-index':1}, 100, function(){
    slider.slick('setPosition');
    slider.animate({'opacity':1});
  });
});
```
　
modal表示するボタンのコード
```index.blade.php
<li class="js-modal-open" data-toggle="modal" data-target=".modal-lg-product{{ $product->id }}">
  　<img data-lazy="{{ asset('product/'.$product->product_images->first()->path) }}">
</li>
```
このliを押下すると該当するmodalが表示される感じ

　
カルーセルで表示したい画像たち
```index.blade.php
<div class="product-img">
　　　@foreach ($product->product_images as $image)
 　　　 <img src="{{ asset('product/'.$image->path) }}">
　　　@endforeach
</div>
```

上記コードでは、表示はされるが下記問題が発生
・modalが表示されてから、数秒画像が表示されない
・複数画像がある場合は、ドットか矢印を押下し、カルーセルを動かさないと画像が表示されない

# 解決
```script.js
let slider = $('.product-img').slick({
  slidesToShow: 1,
  lazyLoad: 'progressive',
  dots: true
});
$('.js-modal-open').on('click', function () {
  setTimeout(function () {　　　　　　　　　//.js-modal-openを押下時165ミリ秒後にSlickが動作
    slider.css('opacity', 0);　　　//なくてもOK、表示をスムーズにするために入れてる
    slider.slick('setPosition');　　//slickのwidthを再計算
    slider.animate({ 'opacity': 1 });　　　//なくてもOK、表示をスムーズにするために入れてる
  }, 165);
});
```

165ミリ秒は色々試した結果、いい感じに表示されたのがこの値だったので設定した感じです。
環境ごとにこの値は変更する必要があると思いますが、僕の環境ではこの値がベストでした。
ゲーム開始ボタンがスペースキーに反応しないように設定

タイピングゲームを製作中。
スタートボタンを押して、キーを打つとゲームが開始するが

ボタンを押した後、スペースキーに反応してしまう為（スペースキーを押すたびに開始ボタンが押される挙動になってしまう）
こちらの問題を解消するための設定を施す。
![スクリーンショット 2022-05-04 15.22.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651730/36debf59-5105-ace5-7326-36065d8a43c1.png)

```ruby
        window.document.onkeydown = function(evt){
          if ((evt.which == 32)
          ){ evt.which = null;
          return false;}
         }
```

任意の場所に上記のように記述すると反応しなくなった！
且つ出題されたタイピングフレーズに対しては反応してくれたので、タイピングゲームとしての挙動にも問題なかった！

evt.which == 32
↑の３２の部分を変えるとその他のキーの無効化ができるらしい


参考記事
https://web-designer.cman.jp/javascript_ref/keyboard/keydisabled/
wordpress の管理画面に入力項目を追加する（theme拡張/add_meta_box)

wordpressの投稿画面に、添付画像の一覧を表示するBoxを追加してみます

add_meta_boxesに追加したアクション関数でadd_meta_box関数を呼び出すことで、情報出力欄を追加します

## 投稿編集画面に任意の文字列を表示する

出力イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42407/f3f30277-bbf5-8dc1-cbb1-ead117e044b8.png)



### 1. 文字列出力の関数を用意する

```php:function.php
function attached_image_list($post){
  //$postは編集対象の投稿の情報が取得されます
  echo "image_list:".$post->ID;
}
```

### 2. filter add_meta_boxに関数 'attached_image_list'を関連づける

```php:function.php
function oj_add_meta_box(){
  $html_id = "attach_image_list";
  $meta_box_title= "添付画像（ギャラリー画像）";
  $screen = null;
  $context = "normal";
  $priority= "high";

  add_meta_box($html_id,$meta_box_title,
    'attached_image_list',
    $screen,$context,$priority);

}

```

### 3. add_meta_boxesアクションに 2で定義した関数を追加

```php:function.php
add_action('add_meta_boxes','oj_add_meta_box');
```

## add_meta_box filterについて

https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/add_meta_box

$contextを"advanced"にすると入力欄が下の方に移動します

## おまけ、添付画像の一覧を出力する

wordpressにpsr-4対応のautoloaderを仕込んであるので、わざわざContollerクラスを実装しています（なので、wordpressぽくないかも）

```php:funciton.php
// 投稿画面のカテゴリーの配置調整
add_action('wp_terms_checklist_args', function ( $args, $post_id = null ) {
  $args['checked_ontop'] = false;
  return $args;
});

add_action('add_meta_boxes','oj_add_meta_box');

function oj_add_meta_box(){
  $html_id = "attach_image_list";
  $meta_box_title= "添付画像（ギャラリー画像）";
  $screen = null;
  $context = "normal";
  $priority= "high";
  add_meta_box($html_id,$meta_box_title,
    'attached_image_list',
    $screen,$context,$priority);
}

function attached_image_list($post){
  $gallery = new \controllers\PostGallery($post);
  $content = $gallery->get_attachment_list_for_admin_post();
  echo $content;
}
```

```php:src/controllers/PostGallery.php
<?php


namespace controllers;


class PostGallery
{

  private $post;
  /**
   * PostGallery constructor.
   */
  public function __construct($post)
  {
      $this->post = $post;
  }

  public function get_attachment_list_for_admin_post(){
    $list = $this->get_all_attached_files();
    $content = "\n";
    foreach ($list as $att_id => $attachment){
      $image_output = wp_get_attachment_link( $att_id, "thumbnail", true, false, false);
      $content .= "<li>".$attachment->post_title."$image_output</li>";
    }
    if (strlen($content)>0){
      $content = "<ul>".$content."</ul>";
    }
    return $content;
  }

  private function get_all_attached_files(){
    // from media.php
    $attachments = get_children(
      array(
        'post_parent'    => $this->post->ID,
        'post_status'    => 'inherit',
        'post_type'      => 'attachment',
        'post_mime_type' => 'image',
        'order'          => 'ASC',
        'orderby'        => 'menu_order ID',
      )
    );
    return $attachments;
  }
}
```
セッションとクッキーの違い

## 勉強前イメージ

ぱっとでないけど、
セッションってサーバ側でクッキーってクライアント側じゃなかったっけ？

## 調査

### セッション とは

webサイトにアクセスして、ログインを行いログアウトを行うまでのやり取りのことで
一つのwebサイトの中で複数のページにアクセスを行い、ログアウトしたとすると
複数のページを見た一連の流れを1セッションと考えます。
サーバ側に保存されるのでデータの改竄の可能性は低いです。

### クッキー とは

データをブラウザに保存する仕組みで、ユーザ情報などが保存されています。
ブラウザのメモリに保存されていてブラウザとwebサイトに固有のデータを保持するように設計されています。
クライアント側にデータを保存するので、データを改ざんされる可能性があります。

### セッションとクッキーの違い

- セッション : ユーザがログイン～ログアウトまでのやり取りで `サーバ側にデータが保存される`
- クッキー : ユーザ情報を保持する仕組みで `クライアント側にデータが保持される`

## 勉強後イメージ

確かに、クッキーはブラウザで見れて、セッションはサーバ側でデータ持ってるよね。

## 参考

- [(PHP) SESSIONとCookieの違い【使い方・使い所なども解説】](https://hara-chan.com/it/programming/session-cookie-difference/)
- [CookieとSessionを今度こそ完全に理解する【分かりやすく図解】](https://www.engilaboo.com/definitely-understand-cookie-session/)
Pythonで定周期実行

# Pythonで定周期で誤差を少なく処理したい（シンプルなのが好き）
定周期処理の仕方はいろいろある中で、できるだけ正確にシンプルな方法で機種依存なくできる方法を考える

# たどり着いた方法
実行開始時間をベースに経過時間を定周期間隔で割った余りをスリープすることにしました
(python3.3以降)
```python
import time

def TimeSpan(interval):
    BaseTime = time.perf_counter()

    while True:
        # 任意の処理

        now = time.perf_counter()
        ET = now - BaseTime
        rem = ET % interval
        time.sleep(interval - rem)

# 1秒周期
TimeSpan(1)

```

## ばらつき具合
1秒周期で1000回実行したときのばらつき
![Figure_processtime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2489321/6b9a869f-4720-d841-8a1c-354583ae316f.png)


# まとめ
Python3.3以降のtime.pref_counter()を使いました 3.3より前のバージョンのtime.time()より精度がいいらしいです
いずれにしろWindowsとUnix系で精度が違うのと、他のプロセスの影響も受けるため精度が必要な場合は注意が必要です

# 参考にした記事
[Pythonで定周期で実行する方法と検証](https://qiita.com/montblanc18/items/05715730d99d450fd0d3)
[Go] ポインタを完全に理解した

# はじめに
この記事は、エンジニア経験1年の大学生が実務や個人の学習で勉強になったこと、詰まったことをまとめています。間違っている箇所などがございましたら、指摘していただけると幸いです。

# 背景
今まで恥ずかしながらポインタという概念を理解できていませんでした。なので、今回Goを新たに学習するにあたって、ポインタにつまずいたので、記事にして理解を深めようと思いました。

※自分なりに整理した記事であり、参考にならないかもしれないのでご了承下さい。

# 環境
- Go 1.18.1

# ポインタとは？
ポインタとは値のメモリアドレスを指す。

[参照](https://go-tour-jp.appspot.com/moretypes/1)

```go
func main() {
	var n int = 1
	
	fmt.Println(n) // => 1
	fmt.Println(&n) // => 0xc0000bc008
}
```
Goでは変数に`&`を付けることで、その変数のメモリアドレスを取得できる。 なので、`0xc0000bc008`がメモリアドレスとなる。では、メモリアドレスとは何なのか。



# メモリアドレスとは？
コンピュータにはメモリと呼ばれる場所が存在し、変数はそのメモリに記録されており、その場所をアドレスと呼ぶ。その名の通り、メモリ内のアドレス(場所)である。メモリアドレスは`0xc0000bc008`となっている。

# ポインタ型変数とは？
```go
func main() {
	var n int = 1

	var p *int = &n

	fmt.Println(p) // => 0xc0000ba008
}
```

その名の通り、ポインタ(メモリアドレス)が代入された変数である。また、ポインタ型変数を定義するには`*(アスタリスク)`をつけて定義する。


# ポインタからアクセスする
```go
func main() {
	var n int = 1

	var p *int = &n

	fmt.Println(p)

	fmt.Println(*p) // => 1
	
}
```
ポインタ型変数に対して、`*変数名`でポインタが示す変数名の値を取得することができる。`*p`とすることで、変数`p`の値が取得できる。

# ポインタの書き換え
```go
func main() {
	name := "坂本勇人"
	var namePtr *string = &name

	*namePtr = "李承燁"
	
	fmt.Println(name)  // => 李承燁
}
```
ポインタ型変数を使用して、値を更新することもできる。更新するには`*変数名 = 更新する値`と記述する。また、ポインタの書き換えで値渡しと参照渡しの理解が必要になってくる。

### 値渡し
```go
func main() {
	var name string = "坂本勇人"

	favoriteBaseballPlayer(name)
	fmt.Println(name)  // => 坂本勇人
}

func favoriteBaseballPlayer(name string) {
	name = "菅野智之"
}
```

`favoriteBaseballPlayer(name)`で渡したのは`name`のコピーなので`name`自体の値は変わらない。つまり、値渡しをしているということである。

### 参照渡し
```go
func main() {
	var name string = "坂本勇人"
	
	favoriteBaseballPlayer(&name)
	fmt.Println(name)  // => 菅野智之
}

func favoriteBaseballPlayer(name *string) {
	*name = "菅野智之"
}
```
`favoriteBaseballPlayer(&name)`で変数nameのアドレスを渡している。なので、`name`自体の値が変わる。つまり、参照渡しをしているということである。


# まとめ
今回このように記事にすることでポインタについて整理することができ、理解が深まったと思います。Rubyではポインタを意識することは無かったので、とても勉強になりました。同じように今までポインタの概念を知らなかった人などに少しでも参考になれば幸いです。
Vertex AI Workbenchで日本語を含むグラフを描画

# サマリ
terminalを開き、以下のコマンドを実行してから、描画すると日本語を含むグラフも表示される。
```
sudo apt-get update
sudo apt-get install -y fonts-takao-gothic
echo "font.family : TakaoGothic" > ~/.config/matplotlib/matplotlibrc
```

# Vertex AI Workbenchで文字化け
Vertex AI Workbenchで日本語を含むグラフを描画しようとすると

```python
import matplotlib.pyplot as plt

plt.figure()
plt.title('タイトル')
```

下記のようWarningが出て日本語が豆腐となる。
```
/opt/conda/lib/python3.7/site-packages/IPython/core/events.py:89: UserWarning: Glyph 12479 (\N{KATAKANA LETTER TA}) missing from current font.
```

<img width="400" alt="日本語が文字化け" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/828e3856-7cc4-f1e6-ab05-e80d9a4739bb.png">

これはmatplotlibで描画するときに、日本語フォントがないときによく起きる事象だ。

# 日本語フォントをインストールして設定
きちんとグラフ内で日本語を表示するためにはフォントをインストールすればよい。

まずは `File > New > Terminal` でターミナルを開く。

<img width="400" alt="terminalを開く" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/7f4debbe-5f19-91b7-30ab-494b896d2dc0.png">


ターミナルを開いたら以下のコマンドで日本語フォントをインストールする。

```bash
sudo apt-get update
sudo apt-get install -y fonts-takao-gothic
```

インストールしたフォントをmatplotlibのフォントとして`~/.config/matplotlib/matplotlibrc` に設定する。

```bash
echo "font.family : TakaoGothic" > ~/.config/matplotlib/matplotlibrc
```

kernelをリスタートして再度描画してみると、以下のように日本語が表示されるようになります。
<img width="400" alt="日本語が表示される" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7058/2df4fb95-012e-c498-4a48-9a35ece00fce.png">
Pythonでつくる対話システム

## サポートサイト
https://github.com/dsbook/dsbook


# MeCabインストール
## 参考サイト
https://self-development.info/mecab%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%81%A6python%E3%81%A7%E4%BD%BF%E3%81%86%E3%80%90windows%E3%80%91/

## mecab-python3インストール

```
pip install mecab-python3
```

## PySIde2インストール

```
pip install PySIde2
```

## 気象庁 天気予報API

```
https://www.jma.go.jp/bosai/forecast/data/overview_forecast/130000.json
```

## 地域コード
https://anko.education/webapi/jma

## requestsインストール

```
pip install requests
```

## pipインストールライブリ確認

```
pip list
```

# ランダムアクセス タスク指向型対話システム 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596059/a1462f8b-8081-bf9a-958d-ec081ba0576e.png)

<img width="600" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596059/7db2384c-c214-a52d-dc0e-b4377c509efc.png">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596059/6fcf8886-26b3-3553-2801-626b0010c47d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596059/653f75a8-e248-92a3-9581-a56c777fb822.png)


## コマンド
### フレームの設定
```
request-weather,place=大阪,type=天気
```

### フレームの訂正

※place=東京が設定されている場合

```
correct-info,place=東京
```
### 全フレーム初期化
```
initialize
```
## SVMを用いた対話行為の推定

### scikit-learn(機械学習ライブラリ)インストール
```
pip install sklearn
```
### dill(データ保存)ライブラリインストール
```
pip install dill
```



labels:は対話行為の配列
sent:は発話を要素解析し分割したものをスペースで区切ったもの

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596059/ed998ffb-8ff4-b7b9-afe9-56a8d26ba369.png)

## tf-idf

https://atmarkit.itmedia.co.jp/ait/articles/2112/23/news028.html#:~:text=%E7%94%A8%E8%AA%9E%E3%80%8Ctf%2Didf%E3%80%8D%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6,%E3%81%AB%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82

## TfidfVectorizer

https://gotutiyan.hatenablog.com/entry/2020/09/10/181919
https://qiita.com/ground0state/items/155b77f4c07e1a509a14

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596059/efc97351-2c43-950f-a040-c44982889be6.png)
このシステムではスクリプトの実行が無効になっているため～「about_Execution_Policies」の解消

https://qiita.com/__Lily__/items/71c75566f067c19c18aa

以下のエラーメッセージの対処方法

```
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新しいクロスプラットフォームの PowerShell をお試しください https://aka.ms/pscore6

このシステムではスクリプトの実行が無効になっているため、ファイル C:\xxx\xxx\xxx\xxx\venv\Scripts\activate.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlin
k/?LinkID=135170) を参照してください。
    + CategoryInfo          : セキュリティ エラー: (: ) []、ParentContainsErrorRecordException
    + FullyQualifiedErrorId : UnauthorizedAccess

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330873/4224e817-e17a-008e-9f2d-1fe7a59a836a.png)
pythonでリストの要素をカンマ区切りで出力したい

pythonでリストの要素をカンマ区切りで出力したい場合がある。
例えば普通に`print`すると以下のように出力されるところを、

```
['player', 7, 2, 1]
```

以下のように出力したい場合

```
player,7,2,1
```

`print(*l, sep=',')`のようにすればOK

```
print(l)           # ['player', 7, 2, 1]
print(*l, sep=',') # player,7,2,1
```

以上です
要件定義・設計の流れをなんとなく理解しておくだけでも全然違う！

# 要件定義とは？
要件定義とは、発注者の要求を実現するために進め方をまとめたものです。
ここではしっかり発注者にヒアリングを行い、プロジェクトのゴールを定めるため、最終的に納品されるシステムのクオリティを左右する一番重要と言っても良い工程です。

# 主な流れ
## STEP1：ヒアリング
まずは解決したい課題と目標を明確にしながらヒアリングを行なっていきます。ここが具体的であるほどに設計や開発がスムーズになります。
また、システム構造に関わる機能要件だけでなく、セキュリティなどの非機能要件も確実に確認しておくようにしましょう。

- 機能要件
    - システムの機能に関する要件。
        - 例：案件一覧検索ができること、ログイン機能があること...etc
- 非機能要件
    - 可用性、性能、拡張性、運用・保守性、セキュリティなど機能以外の要件。
        - 例：応答は3秒以内、同時アクセスはユーザー数の15%を想定する...etc

ここで業務フロー図やデータフロー図など、簡単な図で分かりやすくしておくのも効果的です。

## STEP2：要求の細分化
ここから要求をヒアリングした後に、「実現可能か？」「コストは大丈夫か？」など問題点を深掘りして解決策を模索します。優先順位をつけたり代替案を考えたりして発注者と相談をしましょう。
5W2H(いつ？どこで？誰が？何を？なぜ？どうやって？いくらで？)を質問して明確にすることで問題が解決に向かいこともあるのでオススメです。

## STEP3：要件定義書の作成
では、ここまでヒアリングしてきた内容を定義書に落とし込みます。
具体的には以下のようなことを書いておけば問題ないかなと思います。

- システム概要や目的
- システム導入後の業務フロー
- 機能要件
- 非機能要件
- スケジュール
- 見積もり(予算)

IT知識が少ない人が見る可能性も高いので、分かりやすい言葉を使うよう意識しながら作成しましょう。

# 設計とは？
設計とは、要件定義で決定された要件を実現するための項目を設計することです。
具体的には、以下のような項目の設計を行います。

- システムが行う作業の範囲
- システム利用者が手動で行う作業の範囲
- システムに使用する機材、機器
- システムに使用するソフトウェア、アプリケーション
- 開発に使用する言語やフレームワーク

このように、システム方式設計では、開発するシステムのベースとなる内容を決定することが特徴です。
この工程での品質は後にかなり大きな影響を与えるので注意が必要です。

# 主な設計内容
## 1.ハードウェア・ソフトウェアの構成
システムを稼働させるためのハードウェア・ソフトウェアの構成・環境を決定する必要があります。
基本的には`「オンプレミス」「クラウド」「ハイブリッド」`の3種類からシステムを稼働させる環境を決めた後、詳細を突き詰めていきます。

## 2.ネットワークの構成
サーバーのネットワーク構成についても決定を行います。システムが安定して稼働できるように、適切なネットワーク構成・負荷分散・トラブルを想定した予備サーバーまで詳細に検討します。
システムを稼働させるハードウェアとネットワークは関連性が高いため、全体的な機能を考慮しつつセットで検討することが一般的です。
最近では、基本的にAWSで構築することが多いですかね(諸説あり)

## 3.開発言語の決定
設計では、どの開発言語を使用するかも決める必要があります。開発言語は複数ありますがそれぞれ特性が異なるため、開発するシステムに適した言語を多角的に分析したうえで選定を行うことが重要です。

開発言語は複数ありそれぞれに特徴がありますが、それを多角的に分析した上で選ぶようにしましょう。
具体的には、、
- 開発期間
- サポート
- 作業効率
- フレームワーク
- バージョン

などを検討しておきましょう。

## 4.外部システムとの連携方式の決定
外部システムとの連携が発生する場合の連携方法・連携方式についても決定を行います。
開発するシステムの規模が一定以上となると、システム単体で完結することが難しくなるため、外部システムとの連携を行う必要性がでてくるためです。

## 5.画面(UI)
ユーザーは画面（UI）を通じてソフトウェアを利用するので、
まず最初に 『画面の使いやすさ』 を考えると良いでしょう。

- 各画面で何ができるのか考える
- 表示する情報（文字、画像 など）とレイアウト構成を考える
- 画面遷移図にまとめる

ということをすればOKです。

## 6.機能設計
機能設計は 『実行する処理』『必要なデータ』 を定めます。

- 機能名と処理内容
- 処理に必要なデータ、データの取得元
    - 例：画面から入力、DBから取得...etc
- 処理したデータの受渡し先
    - 例：画面表示、DBへ保存...etc

ここまでやればパッと見ただけでどんなプログラムを実装すれば良いかがわかるようになります。

## 7.データ設計
ここでは文字通り、扱うデータを設計します。

- データの具体的な内容
    - 例：会員情報(名前、メールアドレス、パスワード)
- データベース設計
    - 例：会員マスタ(name、email、password)

データベース設計ではER図を用いることでより分かりやすくなります。

# 参考
[要件定義とは？進め方・必要スキル3つを簡単に解説【ITシステム開発に必須】](https://www.gaiax.co.jp/blog/requirement-definition/)

[要件定義の流れ｜失敗しないように進めるポイントと必要なスキル](https://www.yaz.co.jp/tec-blog/it-column/1345)

[システムの要件定義とは　基本の内容や進め方、必要な準備を簡単解説](https://smbiz.asahi.com/article/14495721#inner_link_002_1)

[システム方式設計とは？目的や書き方のコツ、注意するポイントについて解説](https://products.sint.co.jp/obdz/blog/system-method-design)

[]()
総当たり戦の結果表から、各playerの勝ち負けを集計したい（pythonで）

以下のような総当たり戦の結果表から、各playerの勝ち負けを集計したい場合がある。
（W:Win, L:Lose, D:draw）

```csv:test.csv
player1,-,L,L,W,L,L,L,W,L,W,W,
player2,W,-,W,W,L,L,L,W,L,L,W,
player3,W,L,-,W,L,L,W,L,L,W,W,
player4,L,L,L,-,W,W,L,L,L,L,W,
player5,W,W,W,L,-,D,L,L,L,W,W,
player6,W,W,W,L,D,-,L,L,W,L,W,
player7,W,W,L,W,W,W,-,L,L,L,W,
player8,L,L,W,W,W,W,W,-,D,W,W,
player9,W,W,W,W,W,L,W,D,-,W,W,
player10,L,W,L,W,L,W,W,L,L,-,W,
player11,L,L,L,L,L,L,L,L,L,L,-,
```

以下のような出力が期待値

```
Player,W,L,D
player9,8,1,1
player8,7,2,1
player7,6,4,0
player2,5,5,0
player3,5,5,0
player10,5,5,0
player5,5,4,1
player6,5,4,1
player1,4,6,0
player4,3,7,0
player11,0,10,0
```

これを処理するには以下のようなスクリプトを実行すればOK

```py:test.py
import sys

ll=[]
# 入力
for line in sys.stdin.readlines():
    A=list(map(str, line.split(',')))
    ll.append(A)

# count
l_out=[]
for l in ll:
    PLAYER=l[0]
    W_NUM=l[1:].count('W')
    L_NUM=l[1:].count('L')
    D_NUM=l[1:].count('D')
    l_out.append([PLAYER,W_NUM,L_NUM,D_NUM])

# sort
l_out.sort(key=lambda val: val[3], reverse=True)
l_out.sort(key=lambda val: val[2], reverse=True)
l_out.sort(key=lambda val: val[1], reverse=True)

print("Player,W,L,D")
for l in l_out:
    print(*l, sep=',')
```

実行結果

```sh
$ cat test.csv | python3 test.py 
Player,W,L,D
player9,8,1,1
player8,7,2,1
player7,6,4,0
player2,5,5,0
player3,5,5,0
player10,5,5,0
player5,5,4,1
player6,5,4,1
player1,4,6,0
player4,3,7,0
player11,0,10,0
```


markdownの表に変換したい場合は以下の通り

```sh
$ cat test.csv | python3 test.py | csvtomd
```

Player    |  W  |  L   |  D
----------|-----|------|---
player9   |  8  |  1   |  1
player8   |  7  |  2   |  1
player7   |  6  |  4   |  0
player2   |  5  |  5   |  0
player3   |  5  |  5   |  0
player10  |  5  |  5   |  0
player5   |  5  |  4   |  1
player6   |  5  |  4   |  1
player1   |  4  |  6   |  0
player4   |  3  |  7   |  0
player11  |  0  |  10  |  0

以上です

# 参考

https://teratail.com/questions/156316
ユーザーごとの学習時間の合計

# はじめに
この記事は筆者がスタディープラスのトレースをする際に、ユーザーの学習時間のランキングを表示するために書いたコードの備忘録になります。
# 実装
deviseの導入と基本となる投稿機能(記事内ではtweets)が完成している前提で進めます。

```ruby:users_controller
#以下を追記
    def index
        user = User.all
        @arr = []
        user.each do |t|
            t.sum_time = t.tweets.sum(:time)
            @arr.push(t)
        end
    end
```
pushメソッドは配列(@arr)の末尾に要素を一つ追加してくれるメソッドです

```ruby:app/views/users/index.html.erb
<h1>Users#index</h1>
<% @arr.each do |u| %>
    <%= u.email %>
    <%= u.sum_time %>
<% end %>

```

配列の中身を一つずつ表示していきます。この時点ではまだランキング順での並べ替えはできていません。
```ruby:users_controller.rb
#以下を追記
        @rank = @arr.sort do |a,b| 
            if !a[:sum_time]
                1
            elsif !b[:sum_time]
                -1
            else 
                b.sum_time <=> a.sum_time
            end
        end
```

この記述を加えることで@rankという変数の中にランキングが格納されます。

# おわりに
閲覧ありがとうございました。もっと短い書き方をご存じの方がいましたら教えていただければ恐縮です！
【備忘録】PythonのIterator, Generator



# はじめに
PythonのIteratorに関する備忘録です。

下記の記事を書くためものです。よかったら、こちらも見てみてください。

https://qiita.com/kotai2003/items/497795548cc4e3a78d91

# コード

```python
# generatorの定義、returnではなくyieldであることに注意
def generator():
    i = 0
    while True:
        i = i + 1
        yield  i

threshold = 100

for item in generator():
    print(item)
    if item > threshold:
        break

```

```python:結果

1
2
3
...
98
99
100
101

プロセスは終了コード 0 で終了しました
```

# 説明
PythonのGeneratorは特殊な繰り返し演算子です。 メモリを少なく使うことがメリットです。
yield文を用いて作った場合をGenerator関数、**小括弧**とlist内包表記を使う場合はGenerator表現と言います。

```python
Generator expression
(x*2 for x in range(256))

List comprehension
[x*2 for x in range(256)]
```
下記の動画の講義が分かりやすかったので、ご紹介いたします。

https://youtu.be/uUO4fBLl64U
pythonで終了条件が指定されていないテキスト情報を標準入力から入力する

pythonで終了条件が指定されていないテキスト情報を標準入力から入力する際の備忘録です

以下のような`csv`ファイルをpythonで処理したい。
ただし事前に何行あるか不明である、という場合は以下のように`sys.stdin.readlines()`で一度全ての入力を受け取ってから処理すると良い。

```csv:test.csv
player1,-,L,L,W,L,L,L,W,L,W,W,
player2,W,-,W,W,L,L,L,W,L,L,W,
player3,W,L,-,W,L,L,W,L,L,W,W,
player4,L,L,L,-,W,W,L,L,L,L,W,
player5,W,W,W,L,-,D,L,L,L,W,W,
player6,W,W,W,L,D,-,L,L,W,L,W,
player7,W,W,L,W,W,W,-,L,L,L,W,
player8,L,L,W,W,W,W,W,-,D,W,W,
player9,W,W,W,W,W,L,W,D,-,W,W,
player10,L,W,L,W,L,W,W,L,L,-,W,
player11,L,L,L,L,L,L,L,L,L,L,-,
```

`sys.stdin.readlines()`で一度全ての入力を受け取る。

```py:test.py
import sys

ll=[]
# 入力
for line in sys.stdin.readlines():
    A=list(map(str, line.split(',')))
    ll.append(A)

# 出力
for i in ll:
    print(i)
```

実行結果

```
$ cat test.csv | python3 test.py 
['player1', '-', 'L', 'L', 'W', 'L', 'L', 'L', 'W', 'L', 'W', 'W', '\n']
['player2', 'W', '-', 'W', 'W', 'L', 'L', 'L', 'W', 'L', 'L', 'W', '\n']
['player3', 'W', 'L', '-', 'W', 'L', 'L', 'W', 'L', 'L', 'W', 'W', '\n']
['player4', 'L', 'L', 'L', '-', 'W', 'W', 'L', 'L', 'L', 'L', 'W', '\n']
['player5', 'W', 'W', 'W', 'L', '-', 'D', 'L', 'L', 'L', 'W', 'W', '\n']
['player6', 'W', 'W', 'W', 'L', 'D', '-', 'L', 'L', 'W', 'L', 'W', '\n']
['player7', 'W', 'W', 'L', 'W', 'W', 'W', '-', 'L', 'L', 'L', 'W', '\n']
['player8', 'L', 'L', 'W', 'W', 'W', 'W', 'W', '-', 'D', 'W', 'W', '\n']
['player9', 'W', 'W', 'W', 'W', 'W', 'L', 'W', 'D', '-', 'W', 'W', '\n']
['player10', 'L', 'W', 'L', 'W', 'L', 'W', 'W', 'L', 'L', '-', 'W', '\n']
['player11', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', 'L', '-', '\n']
```

ただしあまりにも標準入力が多い場合はメモリ制約を受けそうであり別の方法を考えた方が良い場合もありそう。

# 参考
https://teratail.com/questions/123054
MPD管理下の曲をコマンドで操作する。（またはWEB操作、GoogleHomeで操作）

# はじめに
●MPD管理下の曲をコマンドで操作する。
WEB操作、GoogleHome操作は下記の記事を参考に修正してください。
[WSLのUbuntuでPC内の音楽データをGoogleHomeで操作する](https://qiita.com/kobbeko/items/04954bc47e407c07d9e7)
[WSLのUbuntu環境でPC内音楽データをWeb操作する（おまけでyoutube音楽とGooglehomeで伝言）](https://qiita.com/kobbeko/items/f4d47c817309bda1e56c)

# 環境
●WSLのUbuntu環境で構築しています。ラズパイでも問題ありません。
●mpd,mpc,mplayerをインストールする

# PC内音楽データを再生するプログラム(pc2play.js)
●単体で起動する方法
 $node pc2play.js 松田聖子＆赤いスイートピー（artist＆title）

``` javascript
    const exec   = require('child_process').exec;
    //値取得
    const value = process.argv[2];
    if (!value) return
    console.log(value)
    const value3 = value.split('＆');
    console.log(value3[0])
    console.log(value3[1])
    console.log(value3.length)
    // キーワードから検索し、音楽データのパスを取得する。
    play_pcmusic(value3);
    // 音楽ファイルのパスを取得し、再生する。
    function play_pcmusic(keyword) {
      if(keyword.length == 1) { //artistのみ
        // 取得したパス(htdocs/...)の先頭にMPDの音楽ライブラリのパス(/mnt/j/music)を追加
        command = 'mpc search artist "'  + keyword[0] + '" | sed -e "s/htdocs/\\/mnt\\/j\\/music\\/htdocs/">/mnt/j/music/htdocs/music/playlist';
      } else {                  //artist＆title
        command = 'mpc search artist "'  + keyword[0] + '" title "'  + keyword[1] + '" | sed -e "s/htdocs/\\/mnt\\/j\\/music\\/htdocs/">/mnt/j/music/htdocs/music/playlist';
      }
      console.log(command)
      var exec = require('child_process').exec;
      exec(command);

      function mplay(){
      command = 'mplayer -shuffle -playlist /mnt/j/music/htdocs/music/playlist';
      console.log(command)
      var exec = require('child_process').exec;
      exec(command);
      }
      setTimeout(mplay,3000);
    }
Opal::Builder を使ってコンパイルする際に source map も生成する

[cli_runners/compiler.rb](https://github.com/opal/opal/blob/v1.5.0/lib/opal/cli_runners/compiler.rb) を参考にしました。Opal のバージョンは v1.5.0 です。


```ruby
require "opal"

builder = Opal::Builder.new
builder.build("./sample.rb")
compiled_source = builder.to_s
compiled_source += "\n" + builder.source_map.to_data_uri_comment

File.write("sample.js", compiled_source)
```

ちなみに、 opal コマンドを使って `opal -c sample.rb` のようにコンパイルした場合はデフォルトで source map を生成してくれます（ `--no-source-map` オプションで無効化できる）。




# 参考

<!--
DxOpalのゲームをコンパクトにして公開する方法 - Qiita
-->
https://qiita.com/crane_house/items/2d0059c7d35542509397




<!--
■ メモ

`lib/cli.rb` というのがそれっぽいので、そこを起点として見ていくと、

opal コマンドの `-R` `--runner` で指定するランナーに対応するクラスが `cli_runners/` 以下にあり、
たとえば `-R compiler` と指定された場合は `cli_runners/compiler.rb` が使われる。

cli_options.rb を見ると以下のようになっていて、 `-c` or `--compile` は `--runner compiler` と同等。

```ruby
      on('-c', '--compile', 'Compile to JavaScript') do
        options[:runner] = :compiler
      end
```
-->
ワイのQiita記事の書き方　〜遡り法〜

# ワイ記法の記事、どんな流れで書いているか

↑これについてまとめて行きます。

# まずはテーマ決め

まずは記事のテーマを決めます。

- 何の技術について書くか
- 何のテクニックについて書くか

みたいな感じです。

私の場合、何か**気づき**を得たときに「このテーマについて書きたい！」となることが多いです。

## 「分かった！」瞬間が記事を書くチャンス

プログラミングの勉強（または実務でのプログラミング）をしていると、何かしら**気づき**の瞬間ってあると思います。
例えば・・・

### 勉強中ワイ
ワイ「Reactに〇〇っていう機能があるらしいけど」
ワイ「実際どんな時に役立つんやろ・・・」

### 数日後ワイ
ワイ「あ、もしかしたら今が〇〇の使いどき？」

### 理解ワイ

ワイ「お、〇〇機能を使ったら、コードがいい感じになった！」

**↑こんな時が「記事の書きどき」だと思います。**

# そこから遡っていく

> 「〇〇機能を使ったら、コードがいい感じになった！」

↑こう感じたら、その**直前の状態を思い出します**。

> 「〇〇機能を使えば、コードがいい感じになるのでは？」と気付いた状態

更に前の状態を、どんどん思い出して行きます。

> 〇〇機能を使ってないから、コードが微妙な感じになっている状態
↓
とりあえず、実装したい物に向かってコードを書き始めた状態
↓
「こんな物を実装しなきゃなぁ」と思っている状態

**理解のプロセス**を頑張って思い出しながら、**逆戻り**しながら、「無理解」に向かって階段を一段一段と降りていくイメージです。

# それを逆にして、一人称で書いていく

さっき「無理解」に向かって一段一段と降りていった階段を、今度は上っていく感じです。
それをワイ君に、一人称で語らせます。

ワイ「あー、こんな物を実装せなアカンなぁ」
ワイ「とりあえず、コードを書いて行こか」
ワイ「なんか、微妙なコードになったなぁ」
ワイ「もしや、〇〇機能を使えばええんか？」
ワイ「おっ！〇〇機能を使ったら、コードがいい感じになった！」

↑といった感じです。

一人称で書くことで、

- 筆者が「分からない」→「分かった！」に到達したプロセス

↑これを読者にも**追体験**してもらうことができます。

「分からない」状態から、階段を一段一段上って「分かった！」状態に辿り着いてもらう感じです。
そうすることで、脳にスッと入って来ます。
**・・・と勝手に思っています。**
知らんけど。

## 実際の体験でなくても良い

> 「Reactのこの機能は、こんな場面で便利だな」
> 「じゃあ、そこから**想像で**遡ってみよう」

↑という書き方も、よくやります。

> 「この機能のおかげで、こんな場面で問題が解決した！」
↓
「もしかしたら、この機能を使って解決できるかも？」
↓
「うーん、困りごと発生やで・・・」
↓
「とりあえずコード書いてみよう」
↓
「〇〇を作ろう」

「無理解への階段」を**想像で**降りていく感じです。
そして、それを逆に書くことで「理解への階段」を組み立てます。

## 最後に

記事の最後に「まとめ」という章を作って、そこに「今回の学びの要点」をまとめると良いと思います。
箇条書きとかで。
そうしないと、読み返す時にダルいので。

**以上です。**

**〜おしまい〜**

# おまけ
記事の冒頭に、アイスブレイクとして**面白パート**を入れるのも良いと思います。

最初に読者に笑ってもらって、良い気分になってもらう。
それから読み始めてもらう。

意外と大事だと思います。
「楽しみながら学べる」なんて最高ですもんね。

### ニーズもありそう
「仕事中に、合法的にオモロイもん読みたい」みたいなニーズ、ありそうですよね。
Qiitaなら仕事中に読んでても「プ、プログラミングの勉強でんがな！」って言い張れますし。
知らんけど。

### 記事の宣伝にも使える

その**面白パート**は、記事の宣伝にも使えます。
記事冒頭の**面白パート**をスクショして、Twitterに投稿します。

### 例
https://twitter.com/Yametaro1983/status/1520596030102077440?s=20&t=ll1Jt1oFGcu2xGOdYD28CQ

このツイートをすることで「何やこの記事、続き気になる・・・！」と思ってもらえて、公開後に読んでもらえる・・・かもしれません。

**〜おしまい〜**

# 新しい記事も読んでみてくださいやで

- [ワイ「なに！？普通のJavaScriptなのに型が書けるやと！？」](https://qiita.com/Yametaro/items/d86ae59e8b07aff1d4f5)
- [文章が下手なワイが、技術記事を書くときにやっていること](https://qiita.com/Yametaro/items/21b8772e6c0d1d77e176)
- [経営者目線を持ったエンジニアになるために](https://qiita.com/Yametaro/items/bfa11a001aa8982cd8f1)
AWS API Gateway で直接 DynamoDB に読み取り・書き込み・削除を行う

# 初めに

この記事では、以下のようなプライマリキーをもつテーブルを想定し、API Gateway の AWS 統合タイプを使用して DynamoDB の操作について書きます。

|パーティションキー|ソートキー|
|---|---|
|year|title|

# 読み取り

アクション：`Scan`

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html

マッピングテンプレート例

```json
{
    "TableName": "Movies"
}
```

# 書き込み

アクション：`PutItem`

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html

マッピングテンプレート例

```json
#set($inputRoot = $input.path('$'))
{
  "TableName": "Movies",
  "Item": {
    "title": {
      "S": "$inputRoot.title"
    },
    "year": {
      "N": "$inputRoot.year"
    },
    "genre": {
      "S": "$inputRoot.genre"
    },
    "director": {
      "S": "$inputRoot.director"
    },
    "star": {
      "S": "$inputRoot.star"
    },
    "place": {
      "S": "$inputRoot.place"
    }
  }
}
```

## 実行例

リクエスト body

```json
{
    "year": "999",
    "title": "myMovie",
    "genre": "myGenre",
    "director": "myDirector",
    "star": "myStar",
    "place": "myPlace"
}
```

変換後

```json
{
  "TableName": "Movies",
  "Item": {
    "title": {
      "S": "myMovie"
    },
    "year": {
      "N": "999"
    },
    "genre": {
      "S": "myGenre"
    },
    "director": {
      "S": "myDirector"
    },
    "star": {
      "S": "myStar"
    },
    "place": {
      "S": "myPlace"
    }
  }
}
```

# 削除

アクション：`DeleteItem`

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html

マッピングテンプレート例

```json
#set($inputRoot = $input.path('$'))
{
  "TableName": "Movies",
  "Key": {
    "title": {
      "S": "$inputRoot.title"
    },
    "year": {
      "N": "$inputRoot.year"
    }
  }
}
```

## 実行例

リクエスト body

```json
{
    "year": "999",
    "title": "myMovie"
}
```

変換後

```json
{
  "TableName": "Movies",
  "Key": {
    "title": {
      "S": "myMovie"
    },
    "year": {
      "N": "999"
    }
  }
}
```

# 参考記事

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html

https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html

https://blog.yuu26.com/api-gateway-dynamodb-json/
将棋AIの作成(AIのコードは非公開)

将棋AIを作成しました。

対戦の様子
![shogiAI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2615735/46ebad4d-3618-863d-369a-1ecce50c27dc.jpeg)

対戦の様子の動画も撮影したがQiitaには載せづらいので自分のはてなブログの記事のリンクを載せる。

https://kai-programming.hatenablog.com/entry/2022/05/04/135525

はてなブログの動画が見づらい人はTwitterの方の動画を見てください。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自作将棋AIとの対局<br>Twitterの動画の長さは短いのでそれに収まるように詰ます<br>AIは弱いですが<br>将棋指せる人が自分の作ったAIと対局<br>繰り返しますがAIは弱い<br>なんなら自分の棋力も低い <a href="https://t.co/HbmeCxTghf">pic.twitter.com/HbmeCxTghf</a></p>&mdash; Kai (@Kai_orange4) <a href="https://twitter.com/Kai_orange4/status/1518864636531011587?ref_src=twsrc%5Etfw">April 26, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>