OmniAICreator/Qiita-1.07M huggingface dataset:
小一時間でゲームをつくる の1章をReact + Typescriptで書いてみたメモ

## 概要
[小一時間でゲームをつくる ──7つの定番ゲームのプログラミングを体験](https://gihyo.jp/book/2022/978-4-297-12745-9)を買ったので写経してみる。
ただ写経ではつまらないので、React + Typescriptで書いてみた。
ここでは差分についてメモを残す。

[できたもの](https://d3snr6xc5uvnuy.cloudfront.net/cartagraph-1hour-games/)
[ソースコード](https://github.com/hibohiboo/1hour_games/blob/release/chapter1_refactor_for_smartphone/client/src/pages/Top/index.tsx)

## レトロゲーム風フォント

[8×8 ドット日本語フォント「美咲フォント」](https://littlelimit.net/misaki.htm)の代わりに、google fonts の [DotGothic16](https://fonts.google.com/specimen/DotGothic16)を使用。

## コンソール
コンソールの代わりにdev要素にテキストを配置して実装。

### 文字入力
キーボードイベントとして取得。

```src/hooks/useReactHook.ts
import { useCallback, useEffect } from 'react'
export const useKeyDown = (handler: (key: string) => void) => {
  const handleKeyDown = useCallback(
    (event: KeyboardEvent) => {
      handler(event.key)
    },
    [handler],
  )

  useEffect(() => {
    document.addEventListener('keydown', handleKeyDown)
    return () => {
      document.removeEventListener('keydown', handleKeyDown)
    }
  }, [handleKeyDown])
}
```

## ゲームループ
[ジェネレータ関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Generator)を使用。

```ts
function* battleLoop(characters: Character[]) {
  const [player, monster] = characters
  player.target = 1
  monster.target = 0

  while (true) {
    let commandSelecting = true
    while (commandSelecting) {
      commandSelecting = yield {
        message: `${selectCommandMessage(player.command, commandNames).join(
          '\n',
        )}`,
        player,
      }
    }
    for (const c of characters) {
      switch (c.command) {
        case commands.COMMAND_FIGHT: {
          yield { message: `${c.name} の攻撃！`, player }
          const damage = Math.floor(1 + Math.random() * c.attack)
          const target = characters[c.target]
          target.hp = target.hp - damage < 0 ? 0 : target.hp - damage
          yield {
            message: `${target.name} に${damage}のダメージ！`,
            player,
          }
          if (target.hp === 0) {
            return {
              message:
                player.name === 'ゆうしゃ'
                  ? 'あなたは しにました'
                  : `${target.name} をたおした！`,
              player,
            }
          }
          break
        }

      }
    }
  }
}
```

hooksから呼び出す。 ` const [gen] = useState(battleLoop(characters))`

```ts
const useHooks = (characters: Character[]) => {
  const [player, monster] = characters

  const [gen] = useState(battleLoop(characters))
  const [state, setState] = useState({
    message: `${monster.name} があらわれた！`,
    player,
  })
  const selectCommand = (key: string) => {
    switch (key) {
      case 'Enter': {
        const nextState = gen.next(false).value
        if (nextState) setState(nextState)
        return
      }
    }
  }

  useKeyDown(selectCommand)

  return { state, selectCommand }
}
```



## 参考

[サポートページ：小一時間でゲームをつくる ──7つの定番ゲームのプログラミングを体験](https://gihyo.jp/book/2022/978-4-297-12745-9/support)
【Java】オーバーロード

## はじめに


オーバーロードについての復習。  
細かいところは把握できていなかったので備忘録として残しておく。

## オーバーロートとは


メソッドの多重定義。同名のメソッドを複数宣言できる機能のこと。

## オーバーロードの条件


引数が異なること。つまり、引数の数や型順番が異なること。  
（Swiftは戻り値の違いでもできたような…。このあたりは多少言語でことなるよう。）

## サンプルコード


```java: Sample.java
public class Sample {

    public void sample(double a, int b) {
        //処理
    }
    
    //①引数の型が違うパターン
    public void sample(double a, double b) { }
    
    //②引数の順番が違うパターン
    public void sample(int a, double b) { }
    
    //③引数の数が違うパターン
    public void sample(double a, int b, int c) { }
}
```


上記は、問題なくコンパイルできます。

## さいごに


内容は簡単かと思いますが、誰かの役に立てば幸いです。

## 参考書籍

https://book.impress.co.jp/books/1118101186
ネットワーク関連設定・コマンド、iw、iwconfig、arpコマンド等

●ネットワーク関連設定

・/etc/sysconfig/network　RedHat系の全体・（ホスト名）設定
・/etc/sysconfig/network-scripts/ifcfg-インターフェイス名[0−9]　RedHat系のデバイス別設定
・/etc/network/interfaces　Debian系の全体・デバイス別設定
・/etc/networks ネットワーク名とネットワークアドレス対応の設定

●iwlist インタフェース scan[ning]
使用可能なアクセスポイントを表示するコマンド

●無線 LAN のリンク品質や信号強度は iwconfig、iwlistコマンドなどで確認できる

●ifconfig コマンド
ネットワークインタフェースに関する操作を行うコマンド

ifconfig インタフェース名 操作内容
操作内容
・指定なし　現在状態を表示
・up/down 有効化/無効化
・IPv4アドレス　IPv4アドレスを割り当て
・netmask 続けてネットマスクを指定
・inet6 add IPv6アドレス[/プレフィックス長]　IPv6アドレスを追加
・inet6 del IPv6アドレス[/プレフィックス長]　IPv6アド絵ｒ巣を削除

●ipコマンド
ifconfigを置き換えるコマンドとしてipコマンドがあります。

ip [オプション] オブジェクト コマンド

ipコマンドは非常に広範囲を対象としていて、ifconfigがネットワークインターフェース操作を主としていたのに対し、ifconfigと同様の範囲だけでなく、routeやarpといったコマンドの範囲も関係しています。

「-4（IPv4を指定）」「-6（IPv6を指定）」
※これらのオプションは、指定したアドレスがIPv4、IPv6のどちらであるか明確であれば省略が可能

●iwconfigコマンド
無線 LAN インタフェースに関連した設定をする

iwconfig インタフェース名 操作内容
操作内容
・指定なし　現在状態を表示
・essid 続けてESSIDを指定する
・key  続けｔWEPキーを指定する

●iwコマンド
無線関連の情報取得・設定を行うiwconfigを置き換えるコマンドとしてiwコマンドがあります。

iw オブジェクト コマンド

■オブジェクト
・dev インターフェイス名
インターフェイス名を引数に取り、インターフェイスに関する情報の表示や設定を行う

▲主要なコマンド
・link 無線の接続状況を表示
・scan 接続可能な無線APをスキャン
・connect/disconnect ESSIDを指定して接続/切断(WEPは「key0:~」でキーを指定)
・station dump 統計情報を確認

■オブジェクト
phy デバイス名
phy#デバイス番号　
デバイス名を引数にとりデバイスに関する情報の表示や設定を行う

▲主要なコマンド
・interface add/del インターフェイスを追加/削除
・info デバイスの使用可能な情報等を表ｚ

●arpコマンド
同じネットワーク内のIP アドレスと MAC アドレスの対応関係は、ARP キャッシュというテーブルとしてシステム内に保持されている。ARP キャッシュに関する操作を行うコマンドは arp 。

arp [オプション]

主要なオプション
・-i　続けて表示対象のインターフェイスを指定
・-a 続けて表示対象のホスト名を指定
・-d　続けて削除対象のホスト名を指定
・-n　逆引き（IP アドレスからホスト名を調べる）ではなくIPアドレスのまま表示
・-s 続けてIPとMACアドレスの対応を指定しキャッシュに追加
・-f 続けてファイルを指定し、その内容をキャッシュに追加

※-a や -d オプションの値は、ホスト名と IP アドレス のどちらでも指定可能

※-s オプションはコマンドの引数に対応を直接記述するのに対して、-f オプションではあらかじめファイルに対応関係を記述しておいて、そのファイルを読み込ませることで追加を行う、という違いがある

※-f オプションは続けてファイルを指定すると、そのファイルに書かれている IP アドレスと MAC アドレスの対応を新たに現在の ARP キャッシュテーブルに追加しますが、ファイルの指定を省略すると、デフォルトで /etc/ethers というファイルが指定されたものとして扱われます。
つまり、この /etc/ethers に対応を書き込んである場合には、-f オプションはファイル名の指定なしに単体で利用できることになります
Flutterで何を作成しようか悩み、模索中....

Flutterの環境構築はできたものの、何を作っていこうかと思い悩み中。。。

筆者のノートPCがWindowsのためiOS開発はできないのでAndroidアプリ開発のみとなる。。
（探せばWindowsでiOS開発できるかもだが、今軽く探した段階では可能とするアプリあったがゆくゆくサービス終了となるので付加かと。）

最近将棋にﾊﾏっているのでAIによる将棋指導アプリ作ろうかと思ったがアレは
ゴリゴリ機械学習やら深層学習?の知識必要そうなので、IT初心者(下手したら初心者かすら..)の筆者にはまだ早いと思い切り捨て。

まだ簡単そうで、学生の頃暇つぶしでお世話になったチャットアプリを作っていこうかと
思案中。続く。。。
【Rust】動的ディスパッチでインスタンスごとに異なる処理を呼び分ける

同一のインターフェイスを持つオブジェクトをインスタンス化し、そのインスタンスごとに異なる処理を呼び分けたいケースを考えます。

例えば、次のような動物（Animal）のトレイトがあるとします。
```rust
trait Animal {
    fn run(&self);
}
```

次に、このトレイトに基づいて、ウサギ（Rabbit）が定義されているとします。
```rust
struct Rabbit {
    speed: u8,
}
impl Rabbit {
    fn new() -> Self {
        Self { speed: 100 }
    }
}
impl Animal for Rabbit {
    fn run(&self) {
        println!("{} km/h", self.speed);
    }
}
```

同様に、カメ（Turtle）も定義されているとします。
```rust
struct Turtle {
    speed: u8,
}
impl Turtle {
    fn new() -> Self {
        Self { speed: 1 }
    }
}
impl Animal for Turtle {
    fn run(&self) {
        println!("{} km/h", self.speed);
    }
}
```

そして、ウサギまたはカメのインスタンスを```Vec```に格納し、そのインスタンスに応じて```run```を呼び分けることにより、「100 km/h」または「1 km/h」を出力させたいとします。

このとき「```Animal```は、```Rabbit```と```Turtle```を抽象化したものだから」という理由で次のように書いたとします。

```rust
const NUM_ANIMALS: usize = 2;

fn main() {
    let idx: [u8; NUM_ANIMALS] = [1, 2];
    let mut animals: Vec<Animal> = Vec::new();  // ← 抽象なんだからいけるよね？

    for i in 0..NUM_ANIMALS {
        match idx[i] {
            1 => animals.push(Rabbit::new()),  // ← これでいけるよね？
            2 => animals.push(Turtle::new()),  // ← これでいけるよね？
            _ => panic!("Specify correct animal number."),
        }
    }

    for i in 0..NUM_ANIMALS {
        animals[i].name();
    }
}
```

……残念ながら、これをやってしまうと、ヒグマ並みの攻撃力を持つ Rust コンパイラに激詰めされます。お前は何をやっとるねんと。型にこだわる Rust をナメとんのかと。**ロケットに括り付けて月まで飛ばすぞ！！**

ものすごい剣幕で怒られるのですが、どうしてよいかさっぱり分かりません。
そこで、その謎を探るべく我々はアマゾンの奥地……には向かわず、某スーパーエンジニアにお伺いを立てました。どうすりゃええねんと。

すると「トレイトは型ではないのでこうは書けない」と言いながら、光の速さで次のように修正してくれました。

そう。[公式サイトにも類似例が載っている](https://doc.rust-lang.org/rust-by-example/trait/dyn.html)のですが、正解は```Box```を使います。

```rust
const NUM_ANIMALS: usize = 2;

fn main() {
    let idx: [u8; NUM_ANIMALS] = [1, 2];
    let mut animals: Vec<Box<dyn Animal>> = Vec::new();  // ← こう！

    for i in 0..NUM_ANIMALS {
        match idx[i] {
            1 => animals.push(Box::new(Rabbit::new())),  // こう！
            2 => animals.push(Box::new(Turtle::new())),  // こう！
            _ => panic!("Specify correct animal number."),
        }
    }

    for i in 0..NUM_ANIMALS {
        animals[i].name();
    }
}
```

なぜ前者は激詰めされるのに、後者はうまく動くのか？
その謎を探るべく我々はアマゾンの奥地……には向かわず（しつこい）、某スーパーエンジニアにお伺いを立てました。なんでやねんと。

……で、いろいろと説明を聞き、その場では「なるほど〜！」と膝を打って理解した気分になっていたのですが、Rust を勉強し始めて１週間の私には、他人に説明できるほど理解が及びませんでした。

ここで私がテキトーなことを書いて誤ったことを流布するのは本意ではないので、神の降臨を待ちたいと思います。誰か詳しく教えてください！

とりあえず、動いてよかったです。
現場からは以上です。
MySQLクライアントインストール

# 【MySQLクライアントインストール】

Bastionからの疎通確認時等のために備忘録として残す。

## MySQLクライアントインストール

```
$ sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
$ yum repolist all | grep mysql
$ sudo yum-config-manager --disable mysql-connectors-community
$ sudo yum-config-manager --disable mysql80-community
$ sudo yum-config-manager --disable mysql-tools-community
$ sudo yum-config-manager --enable mysql56-community
$ yum repolist all | grep mysql
$ sudo yum install mysql-community-client
```

## その他

```
$ mysql -h xxxxx.ap-northeast-1.rds.amazonaws.com -u xxxxx -p
```
WSL+homebrew+fish環境構築まとめ

自分用のメモとして残しておきます．

## 構築の目標
- Homebrewのinstall失敗を防ぐために，resolv.confの作成
- Homebrewのインストール
- fishのインストール
- StarShipのインストールと適用
※WSLでUbuntuを使えるようにするところまでは省略します．

## Homebrewのinstall失敗を防ぐ
自分の環境では，特に設定しないままHomebrewを使うと`brew install`が成功しないことが多々あった．
それを防ぐための設定を最初に行う．
エディタはvimで進めていく．
### /etc/wsl.confというファイルを作る
```
sudo vim /etc/wsl.conf
```
ファイルが開けたら，以下を記入する．
これを記載することで，後述のDNSサーバー指定用ファイル`/etc/resolv.conf`が再生成されなくなる．
```/etc/wsl.conf
[network]
generateResolvConf = false
```
### WSLを再起動する
自分の環境では，この手順をふまないと，再起動したときに`/etc/resolv.conf`が消えた．

### DNS設定用ファイル`/etc/resolv.conf`を作る．
```
sudo vim /etc/resolv.conf
```
下記を記載する.
8.8.8.8はGoogleのDNSサーバーです．
```/etc/resolv.conf
nameserver 8.8.8.8
```

## Homebrewのインストール

### 事前準備
ひとまずこれ
```
sudo apt update && sudo apt upgrade -y
```
## 準備
homebrewを入れる前にこれをしておく
```
sudo apt-get install build-essential procps curl file git
```

### インストール
[Homebrew公式](https://brew.sh/index_ja)に則ってインストールする．
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

### bashにパスを通す
[公式のドキュメント](https://docs.brew.sh/Homebrew-on-Linux)に則ってパスを通す．
これをやったあと一度WSLを起動し直す．
```
test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)"
test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
test -r ~/.bash_profile && echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.bash_profile
echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.profile
```

### Homebrewがインストールできているか確認する．
何でもいいから`brew`を使ってみる．
自分は`brew doctor`使いがち．
```
brew doctor
```

## fishのインストール
### 先程導入したHomeberwを使ってfish shell をインストールする．
下記のコマンドでインストールできる．
```
brew install fish
```

### デフォルトのシェルをfishにする．
#### 1. fishの場所を探す．
```
which fish
```
これを入力すると，fishの場所が返ってくる．私の場合は`/home/linuxbrew/.linuxbrew/bin/fish`だった．

#### 2. Ubuntuに有効なシェルであることを伝えるために`etc/shells`にfishの場所を書き込む．
```
sudo sh -c "echo /home/linuxbrew/.linuxbrew/bin/fish >> /etc/shells"
```

#### 3. デフォルトのシェルとしてfishを登録する．
```
chsh -s /home/linuxbrew/.linuxbrew/bin/fish
```

#### 4. wslを起動し直して，シェルが変わっていることを確認する．
見た目でわかるが，一応`echo $SHELL`で現在使っているシェルが確認できる．

### fishでbrewのパスを通す
fishの設定ファイル`~/.config/fish/config.fish`にbrewを書き込む
```
echo 'eval (/home/linuxbrew/.linuxbrew/bin/brew shellenv)' >> ~/.config/fish/config.fish
```

## StarShipのインストールと適用
ほとんど[StarShip公式](https://starship.rs/ja-jp/guide/)の説明どおりに導入すればOK
NerdFontじゃないと表示がおかしくなるので，その辺は確認しておく．

### インストール
インストールはbrewを使う．
```
brew install starship
```

### パスを通す．
starshipを起動できるように下記のコマンドで`~/.config/fish/config.fish`に追加する．
```
echo starship init fish | source >> ~/.config/fish/config.fish
```

### starshipの設定ファイルを作る．
見た目とかはここをいじって整える．
```
mkdir -p ~/.config && touch ~/.config/starship.toml
```
以上！！

## 参考リスト
[1] keisukesan，WSL2 で Homebrew 使おうとしたけど 、ことごとく install 失敗するんだが，Qiita，https://qiita.com/keisukesan/items/7ec851b1ad3032de3925
[2] Homebrew, https://brew.sh/index_ja
[3] N04h, Zenn, https://zenn.dev/n04h/scraps/8cb5cb935fda10
[4] StarShip https://starship.rs/ja-jp/
pdf.jsを使って日本語ファイルを表示する

CDNのpdf.jsで日本語を含むPDFファイルを表示させるのに苦戦したのでメモ．
Prebuildのzipを展開して設置する場合も多分ほぼ同じ．

検索すると `viewer.html` を使うやり方はある程度出てくるけれど，`pdf.js` 自体を読み込んでスクリプトを書く場合の情報は見つけづらい印象．

使用バージョン: pdf.js 2.16.105


# 公式のExample

* [Examples](https://mozilla.github.io/pdf.js/examples/)
  最低限．これだけだとCMAPの設定がないので日本語等は表示されない
* [GitHubリポジトリのexamples](https://github.com/mozilla/pdf.js/tree/master/examples)
  色々ある? (あまり見てない)


# 基本設定

コンソールに `Deprecated API usage: No "GlobalWorkerOptions.workerSrc" specified.` と表示されるときは

```javascript
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@2.16.105/build/pdf.worker.js';
```

と書けばよい．(公式の例にもこの記述がある)

* 参考: [pdfjs-2.13.216-dist.zip : pdf.jsの利用での変更箇所 – Web Service Development](https://wsdlab.com/?p=1572)
  この記事で使われている `PDFJS` は最近のバージョンで非推奨になったらしい

# 日本語表示

コンソールに
```Warning: loadFont - translateFont failed: "UnknownErrorException: CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.".```
```Warning: Error during font loading: CMapReaderFactory not initialized, see the `useWorkerFetch` parameter.```
と表示されて日本語が描画されないときは

```javascript
const loadingTask = pdfjsLib.getDocument({
    url: 'sample.pdf',
    cMapUrl: "https://unpkg.com/pdfjs-dist@2.16.105/cmaps/",
    cMapPacked: true,
});
```
のように cMap を明示的に指定する．

* 参考: [pdf2png example cannot render Japanese font · Issue #11900 · mozilla/pdf.js · GitHub](https://github.com/mozilla/pdf.js/issues/11900)
* 参考: [[備忘録] pdf.jsで日本語が読み込めない場合はcMapを設定する必要があった - Qiita](https://qiita.com/harusann2/items/f2a7996d2777c2babb7f)
* 参考: [Pdf.jsで"The cMap url must be specified"のエラーが出たときの解決法 - Qiita](https://qiita.com/daikiichikawa/items/bef07dcfa77c11e62eb4)


# その他参考記事

* [pdf.jsを使いブラウザで見られるPDFスライド表示ツールを作った](https://efcl.info/2014/10/07/pdf-presentation/)
やや古く2014年の記事．テキスト選択関係の話がある
* [PDFJS のドキュメントが少なすぎる](http://var.blog.jp/archives/69268808.html)
EC2にNodeをインストールした際にバージョン違い

EC２にnode.jsをインストールしていたのですが
アセットファイルをコンパイルしようとした際にこのようなエラーが発生しました。
```terminal:ターミナル
$ rails assets:precompile RAILS_ENV=production
yarn install v1.22.19
[1/5] Validating package.json...
error furima_38077@0.1.0: The engine "node" is incompatible with this module. Expected version "14.19.3". Got "14.20.1"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
```
とバージョンが違うと出てきました
```terminal:ターミナル
$ sudo curl -sL https://rpm.nodesource.com/setup_14.x | sudo bash -
$ sudo yum -y install nodejs
```
でインストールしたのですがバージョンの下げ方が分からず、調べてみた所
ec2にノードバージョンマネージャー (nvm)を導入すれば良いと記事が見つかり実践しました。

# 手順
### まずターミナル内でEC2にアクセス

### ノードバージョンマネージャー (nvm)をインストール
```terminal:ターミナル
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
```

### nvm を有効にする
```terminal:ターミナル
. ~/.nvm/nvm.sh
```

### nvm を使用して Node.js のバージョンを指定してインストール
```terminal:ターミナル
nvm install 14.19.3
```
```terminal:ターミナル
nvm use 14.19.3
```

### nodeバージョン確認
```terminal:ターミナル
$ node -v
v14.19.3
```

もっとスマートにバージョンを変える方法があるのかも知れないですが、この方法で進める事が出来ました。

# 参考にさせて頂いたサイト
[EC2にnode.jsをインストール](https://qiita.com/youyonghua/items/70ad3a81b07f903760ee)
[AWS EC2に新しいバージョンのNode.jsをインストールする](https://qiita.com/masarufuruya/items/34f7617de45f2d7ca3d3)
凡人でも入緑できました!(初投稿)


## プロフィール

- 理系大学生
- pythonを初めて約1年
- 凡人です(緑になるのに50回以上参加しているので…)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883582/524cbdab-cc51-a169-10dd-776c7aed9dad.png" width=600>

## 使用言語

- 機械学習や深層学習にも興味があり、いずれkaggle等にも挑戦したいと考えていたためpythonを選択しました。
- 処理速度は灰~緑diff程度では気にすることはほとんどないと思います。
- python or pypy　みたいな知識を知っておく必要があるのが少し厄介でした

## 緑色の個人的なレベル感

- 最近のインフレにより、昔の問題と比べると同じdiffの場合の難易度は上がっているとは思います。
- chokudaiさんの記事に書いてあることは今でも的を得ていると思っています。

## 入茶した時の知識

- データ構造(連想配列,Heap,deque)
- 全探索(計算量を工夫する全探索,bit全探索,順列全探索)
- 累積和
- いもす法
- 尺取法
- DPの基本的な問題
- 2分探索(基本的なもの)
- 貪欲法
- ソート
- グラフの基本問題
- 数学の基本的知識

## 入緑した時の知識(+α)

- グラフアルゴリズム(bfs,dfs,dijkstra)
- データ構造(unionfind,順序付き集合)
- 多次元の動的計画法
- 2分探索(応用)
- ダブリング

正直、他にも最大流問題やセグメントツリー,最小共通祖先などのアルゴリズムにも手を出してはいますが、本番で使えるレベル(考察を踏まえて)ではないです。

また、知っている≠使えるなので、自分は習得するまでには4,5問は解かないと身につきませんでした。
実際、知識力+考察力+実装力の3つが揃って初めて問題が解けると考えているので、どれか一つでも欠けているとなかなか本番でACできなかったりします。

## 個人的アルゴリズム重要度ランキング

1. 2分探索(応用範囲がとても広く、頻出であるため)
2. 累積和(茶色diffでよく見る)
3. DP(基本的なdpは最近は茶diffなので...)

## なぜ,入緑するのに半年も停滞してしまったのか

- 正直4月にレートが759になったとき、緑はすぐいけるだろうと油断していました。
(今覚えば、過去の問題と類似してたラッキー問題やたまたま早解きが成功した上振れでした)
- 学業で忙しい(というの言い訳にしていた)ため、精進を全く行っておらず、週1回コンテスト参加のみを行なっていた
- 実装力不足(体系的にアルゴリズムの勉強をしたときに本番で使いこなせる気持ちになっていた)
- ミスがとても多い(色んな種類のミスをしてしまいます)

## 問題を解く上で心がけていること

- アルゴリズムベースで考えない
新しいアルゴリズムを勉強すると、使える手札が増える一方で、問題の考察を疎かにしてしまうことがあったため。
- 20分考えてわからなかったら次の問題に飛ぶ(悩みすぎるとダメな思考回路になってしまうことがあるため)

## レートを上げるためにやったこと

- 過去問精進
    - 正直これが1番大事だけど個人的には辛い作業
    - 本番の緊張感が好きなので、なかなかモチベが保てない
- 鉄則本
    - 6割ぐらいのページと問題を解いた
    - 体系的に競技プログラミングに関する知識を習得することができるので、レート400ぐらいの人に1番おすすめ(灰coderだと少しコードを理解するのに時間がかかると思うので、鹿本を勧めます)
- PAST試験
    - 2回受けましたが、両方ともあと一問というところが解けずギリギリ初級
    - 本番と同じような緊張感が味わえる(お金払っているので)ため、お金に余裕のある人にはおすすめ
    
- 知識を体系的にまとめる
    - 長期休みにipynb形式でチートシート的なものを作っていた
    - 昔解いた問題の振り返りが出来たり、理解していたつもりのアルゴリズムを再履修する機会になりました
- 問題分類
    - 解いた問題をグラフ問題やDP,データ構造などのフォルダに振り分けてます
    - コンテスト中も今まで解いた問題から、コードを引っ張ってくることが多いです
- 精錬100問、典型90問
    - 精錬の方は3割程度、典型90は~星4,5のうち理解出来たものを解説AC含めて7割程度埋めました
    - 鉄則本→典型90のステップで勉強していくと、かなり力がつきそうです。

## モチベ維持のTIPS

- 競プロ友達を作る(twitterはスゴい人が多いのでただ眺めるだけになっています(悲しい))
- レートで一喜一憂(賛否ありますが、レートが上がるとモチベは確実に上がりますね)
- AC数を積み重ねる(精進グラフがレートより低い場合は、全体的に演習量がたりないと考えていいと思います)
- ライバルとレートを競う
- 一旦競プロから離れる(楽しむことが1番です)
- 競技プログラミングに参加している時点でスゴい!!!

## 精進の仕方について
- 自分よりも低いdiffの問題だけを解くのはあまりおすすめしません。(解くスピードは多少上がるかもしれませんが、長期的にみると、自分より一色高い難易度の問題を解けないといつまで経ってもレートが上がらないから)
- 個人的なおすすめは、自分のレート+半色の問題を解きつづけること
- 考察をガンガンプログラムの中に書き込む(これは精進のときは必ずやっています。)
- 20分考えて全くアイデアが浮かばなかったら解説を少し見ます。方針は合っているけど実装がうまくいかない場合は、出来る限り自分で解くようにしてます。

## これから

- しばらくはunratedでコンテストに参加しようと思います(入水できるレベルの考察力が全然足りないから。あとレート下がるの怖い...:(
- 他にも,kaggleやヒューリスティックコンペ,ゲームAIなど興味があることがたくさんあり、そっちの方にも時間を割いていきたい
- 毎日1問は緑・水diffをACして鈍らないようにしたいです
- 過去問精進800AC超えたあたりで再びrated

をしていきたいです。

(記事というよりメモ書きみたいになってしまいました…。いいねしてくれると嬉しいです)
４０代おっさんPythonを勉強する（入力、出力編）

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## 出力と入力

### print()関数

- 変数や出力などを確認するのによく使う
- Pythonの特徴：複数の変数を一行で値を代入できる
- formatを使って、変数の値を文字列に代入する。引数の順序を指定して変数の代入場所を決める。

```python
a, b = 3, 5
print('{1} + {0} = {2}'.format(a, b, a + b)) #　{}の中がformatの順番を表す
```

## input()関数

- ユーザーから入力を求めたい時はinpnt()をいう関数を使う
- 変数 = input('文字列')のところで、入力ができるようになる
- 入力文を入れてEnterを押すと、入力文が変数に代入される
- Python3から全ての入力は文字列として返される

```python
name = input("あなたは誰が好きですか？")
print("私も{}がすきです".format(name))
type(name)
```

- 文字列だから、計算式で計算ができない
- int()関数、float()関数などを使って型を変更できる

```python
age = input('あなたの歳は？')
type(age) #　整数を入れてもstr
age = int(age)
type(age) #　型変換されてint型に
```

＊変更できない文字列はエラーになる

## 参考

<https://www.kitakyu-u.ac.jp/news/2022/08/003215.html>
Julia でルンゲ・クッタ法を実装してみる

Julia でルンゲ・クッタ法を実装してみた。

https://qiita.com/arcadia13/items/92a8d7fcdd79bc12f2d6

多くのプログラミング言語では，関数も関数の引数になり，関数内で直接引用できる。
`feval(func, t(k), Y(:,k))` は単純に `func(t(k), Y(:,k))` のように書ける。

```julia
## ルンゲ・クッタ法
function ClassicalRungeKutta(func, t, Y0)
  # func:微分方程式の関数ハンドル
  # t：積分範囲（hで分割済み）
  # Y0：初期値
  nrow = length(Y0)
  ncol = length(t)
  Y = zeros(nrow, ncol)
  Y[:, 1] = Y0 # 初期値の代入
  h = t[2] - t[1] # 刻み幅
  for k = 1:ncol-1
      k1 = func(t[k], Y[:, k])
      k2 = func(t[k] + h/2, Y[:, k] + h*k1/2)
      k3 = func(t[k] + h/2, Y[:, k] + h*k2/2)
      k4 = func(t[k] +h, Y[:, k] + h*k3)
      Y[:, k+1] = Y[:, k] + h*(k1 + 2*k2 + 2*k3 + k4)/6
  end
  Y
end

## 斜方投射（鉛直上向き）の運動方程式
function MotionEquation(t, Y)
    g = 9.8
    nrow = length(Y)
    Ydot = zeros(nrow, 1)
    Ydot[1, 1] = Y[2]
    Ydot[2, 1] = -g
    Ydot
end

# 質点の斜方投射

##　物理パラメータと運動方程式の初期条件

x0 = 0; y0 = 0 # 原点
g = 9.8 # 重力加速度
theta = (45/180)*pi # 45度の方向へ投げる
v0 = 10 # 初速度 m/s

# 運動方程式の初期条件
Y0 = [y0 v0*sin(theta)]

# シミュレーション時間
h = 10^-4 #刻み幅
t = 0:h:5

## 　運動方程式を解いてボールの軌跡を描画

x = @. x0 + v0*cos(theta)*t;
y = ClassicalRungeKutta(MotionEquation, t, Y0) # 近似解
yTrue = @. y0 + v0*sin(theta)*t - (g*t.^2)/2; # 真の解

using Plots
gr(fontfamily="IPAMincho", foreground_color_legend = nothing)
plot(x, y[1, :], xlims=(0, 10.1), ylims=(0, 3), label="真の解")
plot!(x, yTrue, label="近似解", title="斜方投射", xlabel="x[m]", ylabel="y[m]")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/b9dd22e2-a987-ac48-1fa0-bcdc69132929.png)
M1 Macでmackerel-plugin-dockerを使う

mackerel-agentのインストールは以下の記事にもあるように `/usr/local` を `/opt/homebrew` に読み替えて進めていく。

https://mackerel.io/ja/docs/entry/howto/install-agent/mac

![スクリーンショット 2022-10-07 22.29.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/f16112ff-d037-1c92-993b-3785674b9652.png)

Dockerのモニタリングは、以下の記事を参考に

https://mackerel.io/ja/docs/entry/advanced/docker

```zsh
docker run -h `hostname` \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /var/lib/mackerel-agent/:/var/lib/mackerel-agent/ \
  -e 'apikey=<APIKEY>' \
  -e 'enable_docker_plugin=1' \
  -e 'auto_retirement=0' \
  -e 'opts=-v' \
  --name mackerel-agent \
  -d \
  mackerel/mackerel-agent
```

としても動かない。

mackerel-agentの場所を調べると

```zsh
$ which mackerel-agent
/opt/homebrew/bin/mackerel-agent
```

なので、マウントポイントを変える。

```zsh
$ docker run -h `hostname` \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /opt/homebrew/bin/mackerel-agent/:/var/lib/mackerel-agent/ \
  -e 'apikey=<APIKEY>' \
  -e 'enable_docker_plugin=1' \
  -e 'auto_retirement=0' \
  -e 'opts=-v' \
  --name mackerel-agent \
  -d \
  mackerel/mackerel-agent
386bace64d36811d699c86aaa5f286f0337d36378cc50673840449d3f4fa5182
docker: Error response from daemon: Mounts denied: 
The path /opt/homebrew/bin/mackerel-agent is not shared from the host and is not known to Docker.
You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing.
See https://docs.docker.com/desktop/mac for more info.
```

怒られるので File sharingに `/opt/homebrew/bin/mackerel-agent`を追加する

![スクリーンショット 2022-10-07 22.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/d2527cf0-7e62-599b-44c1-c5abe9d2031d.png)

完成

![スクリーンショット 2022-10-07 22.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/de0bc794-e6e1-8ad5-be35-0415f3942344.png)
![スクリーンショット 2022-10-07 22.33.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402245/83ebea39-4dcc-3116-cc9f-d20fab96a412.png)
login実装中は他の関連ページ入れないようにする方法、sessionを持たせる

login実装中は他の関連ページ入れないようにする方法について学習したので、共有します。

通常、login機能を実装しただけでは関連ページをlocalhost/~で

入力すると関連ページを開くことができます。

これを見れないようにする方法は、リダイレクト機能を使うことによって関連ページを入力すると

loginページに戻るように設定する方法を共有します。

①sessionにidを持たせる
```php

    if( password_verify($login_pw ,$user["login_pw"])){  
   //password_verify指定したハッシュがパスワードにマッチするかどうかを調べます。
        //Login成功したら、session_id,name,age,mailを持たせてreg_list.phpへ
        $_SESSION["chk_ssid"]  = session_id();  //自分のsession.ID
        $_SESSION["id"]   = $user['id'];  // idを持たせる
        $_SESSION["name"]   = $user['name'];  //nameを持たせる
        $_SESSION["age"]   = $user['age'];  // ageを持たせる
        $_SESSION["mail"]   = $user['mail'];  //mailを持たせる

        redirect("reg_list.php");
     }else{
        echo  "login情報が違っています。";
     }
     exit();

```

loginページで「　＄_session["id"]   = $user['id'];　」
を持たせることによって他のページでも「id」の他に「name」、「age」、「mail」を
＄sessionがある場所に限り使用可能である。


〜〜〜〜〜※その他※〜〜〜〜〜〜
　session start();　　を持たせることによって
　session start();　　を持っている〜.phpの場所はページ内のどこでも
「id」「name」「age」「mail」を使うことができる。



②関連ページに$sessionがない場合は「login.php」へ戻るようにすると
```php

  if(!isset($_SESSION['id'])){
    header("Location:./login.php");
    exit(); 
  }

```

sessionのidを持っていない場合は、「 login.php 」のページに戻すと

関連ページの「　<?php　」のすぐ上に記述することによってうまく書くことができます。
４０代おっさんPythonを勉強する②

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## 基本の演算

### 数値演算

- 演算子(加算 +,減算 -,乗算 *,除算 /,余剰 %,指数 **)
- Python3から // で整数を返す

- 演算子(+=, -=, *=, /=)

```python
# 下記は等しい
a = a + 1
a += 1

b = b * 5
b *= 5
```

### 文字列演算

- 文字列の連結、繰り返す

```python
a = '利樹'
b = '大好き'
c = a + b
print(c)
d = c * 3
print(d) 
```

- シングルクォートがダブルクォートで文字列を囲んで作っても良い
- シングルクォートで文字列を作る時に、ダブルクォートを入れても、逆でもできる
- ３つのクォートで改行ができる

```python
texts = '''
利樹は大好きなんだよな～
だって利樹なんだもん
'''
print(texts)
```

- 文字列に特別な文字を入れる時、エスケープ文字のバックスラッシュを使う（\）
- コメントは#を使う（#は行末まで）
- 複数行は、'''(シングルクォーテーション3つ）あるいは"""（ダブルクォーテーション3つ）で囲まれた部分がコメントアウトされます。

## 参考

<https://www.kitakyu-u.ac.jp/news/2022/08/003215.html>
Yolov5でSemanticSegmentationができるって知ってた？

# しかもめっちゃかんたんに使えます

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/bf1d6f8c-1455-fd28-49f4-1900ff92345b.jpeg width=400>


https://github.com/ultralytics/yolov5

リポジトリをクローンして、必要なライブラリをインストール。

```shell
git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip install -r requirements.txt
```

入力パスを指定して実行。
画像や動画、Webカメラで使えます。

```shell
python segment/predict.py --source "Cat.mp4"
```

![Oct-07-2022 15-51-41.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/9c917965-c2cb-8806-0d57-8e935d188c83.gif)

動画でもできるのがすごいですよね。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

機械学習、ARアプリ（Web/iOS）を作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
【Swift】上がりながら消えていくアニメーションを実装する

# はじめに
いま作ってるアプリで「上がりながら消えていくアニメーション」を実装したので方法を共有します。

# イメージ
![Simulator Screen Recording - iPhone 12 - 2022-10-07 at 20.59.10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/99e8bde8-c51a-2295-c299-17a74f92a234.gif)

# 実装
※関係ないところは省いてます
`RxGesture`の`panGesture`で指が離れた位置を取得します。
指が離れた位置にラベルを配置します。
`UIView.animate`でラベルにアニメーションを追加します。

```swift
view.rx
    .panGesture()
    .when(.ended)
    .subscribe(onNext: { position in
        self.makeCountUpLabel(position: position)
    })
    .disposed(by: disposeBag)

private func makeCountUpLabel(position: UIPanGestureRecognizer) {
    let label = UILabel(
        frame: CGRect(
            x: position.location(in: self.view).x,
            y: position.location(in: self.view).y,
            width: 50,
            height: 50
        )
    )
    label.textColor = .black
    label.text = "+1"

    self.view.addSubview(label)

    label.isHidden = true

    label.alpha = 1.0

    UIView.animate(withDuration: 2.0, delay: 0.0, options: [.curveEaseIn], animations: {
        label.isHidden = false
        label.center.y -= 100.0
        label.alpha = 0.0
    }) { _ in
        label.removeFromSuperview()
    }
}
```

# おわり
UIViewのアニメーションを初めて触りました。
SwiftUIでのアニメーションよりできることの幅が広くて便利です
CloudFormation RainをWindowsにインストールする

ClooudFormationが捗るツールRainだけど、Windowsへのインストール手順は以下の3ステップ。

1. [Releasesページ](https://github.com/aws-cloudformation/rain/releases)の最新版の「Assets」から `rain-vX.X.X_windows-i386.zip` をダウンロードする。
2. zipファイルを展開する。
3. zipファイルから出てきた `rain.exe` をパスの通ったディレクトリに置く（もしくは適当なディレクトリに置き[パスを通す](https://atmarkit.itmedia.co.jp/ait/articles/1805/11/news035.html)。

これで `rain --version` として実行可能なこととバージョンを確かめたり、 `rain build` する分には十分なはず。

**余談1**

 `rain deploy` とかしたい時はAWS CLIで[構成設定の設定](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html#cli-configure-files-methods)とか必要。複数AWSアカウントを使ってたりロール使ってたりMFA必要だったりすると[名前付きプロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-profiles.html)作ったりプロファイル手書きで修正したり `rain info --profile` したりまで踏み込む必要がある。でもこの辺は主にAWS CLIの話なので、キーワードだけばらまいて以下割愛。

**余談2**


Rainの公式ページに「Windowsへのインストール」みたいな分かりやすい書き方去れてなかったり、ググっても出てくるのが以下だったりして…

* [WindowsでCloudFormation Rainを動くようにしてみた | DevelopersIO](https://dev.classmethod.jp/articles/try-cloudformation-rain-on-windows/)
* [RainのaliasをPowerShellとWSLで設定する - Qiita](https://qiita.com/handy-dd18/items/ce1ff79b2c7868309c16)

…読んでいくと「WSL使ってコンテナ上で実行するのがいいのね？」みたいに思って遠回りしそうだった…というか久しぶりにRainインストールしようとして手順忘れてて遠回りしようとした僕がいるので、別の誰か（往々にして将来の僕）が同じ轍を踏まないようにメモを残しておくことにした。むしろ一本目の「[インストール](https://dev.classmethod.jp/articles/try-cloudformation-rain-on-windows/#toc-7)の項だけ読めばこのメモの手順になるのだけど。

# 参考

* [Getting started - Readme.md - aws-cloudformation/rain](https://github.com/aws-cloudformation/rain#getting-started)
外部キー制約があるDBテーブル内のデータを削除する手順

はじめに
--
開発中に既にデータが入っているDBテーブルに外部キーを追加したかったのですが、「既にデータがあると外部キーを持っていない過去のデータが存在してしまうことになるから追加できないよ！」とエラーを返してしまいました。

じゃあDBテーブル内のデータを削除しよう!とMySQLに入ってコマンドを叩いたところ「外部キーを持ってるデータはtruncateできないよ！」とまたもエラーが返ってきました。(削除しようとしているテーブルにも既に外部キーが存在しています)

~~~
mysql> truncate table quizzes;

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (`~`.`~`, CONSTRAINT `~`)
~~~

外部キーが存在するDBテーブルのデータを削除する方法を毎回調べるのも無駄なので備忘録としてまとめます。

外部キー制約を一時的に解除する
--
外部キー制約をもつDBテーブルのデータを削除するためには、コマンドを叩いて一時的に外部キー制約を解除する必要があります。
下記のコマンドで、外部キー制約を解除したり再び適用させることができます。
(解除コマンドを叩くと全テーブルの外部キー制約が解除されるみたいです。)

~~~bash
#外部キー制約を解除
mysql> set foreign_key_checks = 0;
#外部キー制約を再び適用
mysql> set foreign_key_checks = 0;
~~~

テーブル内のデータを削除する手順が下記になります。

~~~bash
#外部キー制約で削除が失敗
mysql> truncate table quizzes;

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (`~`.`~`, CONSTRAINT `~`)

#外部キー制約を解除
mysql> set foreign_key_checks = 0;
Query OK, 0 rows affected (0.00 sec)

#削除成功
mysql> truncate table quizzes;
Query OK, 0 rows affected (0.09 sec)

#しっかり空になってる
mysql> select * from quizzes\G
Empty set (0.00 sec)

#忘れずに外部キー制約を再び適用
mysql> set foreign_key_checks = 1;
Query OK, 0 rows affected (0.00 sec)
~~~

終わりに
--
無事にデータを削除してカラムを追加することができました。
コマンドは実際に触らないと慣れないなぁと思いました。
怖がらずに新しいコマンドを使っていこうと思います。


参考
--
https://www.miracleave.co.jp/contents/97/mysql-delete-forginkey/

https://dev.mysql.com/doc/refman/5.6/ja/create-table-foreign-keys.html
iPadのSwift Playgroundを使ってカメラメモアプリを作成する

NCMBのSwift SDKが1.3.0にバージョンアップし、iPadのSwift Playgroundsに完全対応しました。ということで、[Swift SDKを使ってカメラメモアプリを作る（その1：画面の仕様とSwift SDKの導入） - Qiita](https://qiita.com/goofmint/items/937823dda1c83cf711d5)の手順を実際に試してみました。

## SDKのインストール

iPadのSwift Playgroundsアプリを立ち上げて、新しいアプリを作ります。

![BCC95850-22CF-4445-87CE-62A3C694F61B_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/ca4b56a2-8d09-014b-cd1c-9b31191b5cf5.jpeg)


新しいアプリを立ち上げたら、Swiftパッケージをタップします。

![2CAF179C-C120-4E03-B5B1-46BF59107BE4_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/58b42a42-6726-9ccf-0964-d3c168f63cac.jpeg)


URLには `https://github.com/NIFCLOUD-mbaas/ncmb_swift` と入力してエンターキーを押します。そうするとバージョン情報（執筆時点で1.3.0）が出ますので、そのまま `プロジェクトに追加` を選択します。

![635CF19B-A310-403B-9ED0-16ED9A7E916D_1_102_o.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/8e9ed660-dda7-1f4c-7261-270e893cf00d.jpeg)


これでパッケージの追加が完了です。

## SDKの初期化

SDKの初期化はMyAppを開きます。そして、NCMBのインポートと `init` 関数を追加します。 `init` 関数の内容は以下の通りです。アプリケーションキー、クライアントキーはお持ちのものを指定してください。

```swift
import SwiftUI
import NCMB

@main
struct MyApp: App {
    init() {
        NCMB.initialize(applicationKey: "YOUR_APPLICATION_KEY", clientKey: "YOUR_CLIENT_KEY")
    }
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

これでNCMBの利用準備が完了します。

## 実装してみて

Playgroundsアプリには実行ボタンがあるのですが、この実行ボタンを押すとアプリがビルドされた上で別アプリとして開きます。コードが見られないので、若干不便です。

そこで、一番右上にあるプレビューボタンを押します。このプレビューボタンで表示された中でもNCMBの動作確認は可能ですし、コードを見られるので便利です。しかもラベルなどはリアルタイムに編集が反映されます。

![7184BA37-AC7E-48AC-AE0F-5975F1037D68_1_102_o.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/fb256cd4-f4de-3d08-df2f-52a5a762b02a.jpeg)

画面サイズは縦長でiPhoneアプリ向けになりますが、これで十分開発を進められるでしょう。

## まとめ

Swift Playgroundsを使えば、PCはWindowsを使っているという方でもiOSアプリ開発をはじめられます。さらにSwiftパッケージを使えばNCMBを手軽に使い始められます。

ぜひぜひお試しください！
import export チートシート

# 変数
```tsx
export const name = "Mike";
export const age = 23;
```
または
```tsx
const name = "Mike";
const age = 23;

export { name, age };
```

```tsx
import { name, age } from "./sample1";
console.log(name, age);
//Mike 23
```

# as 
変数名を変更できる
```tsx
const name = "Mike";
const age = 23;

export { name as mike, age };
```

```tsx
import { mike, age } from "./sample1";
console.log(mike, age);
//Mike 23
```
または

```tsx
const name = "Mike";
const age = 23;
export { name, age };
```
```tsx
import { name as mike, age } from "./sample1";
console.log(mike, age);
```

# 関数

```tsx
export const sayHello = () => {
  return "hello";
};
```
```tsx
import { sayHello } from "./sample1";
console.log(sayHello());
```

# defaultエクスポート
```tsx
export default "default";
```
```tsx
import aaa from "./sample1";
console.log(aaa);
//default
```
なんという変数名を付けるかは、import側で決めることができる。

## 両方ある場合

```tsx
export const sayHello = () => {
  return "hello";
};

export default "default";
```
```tsx
import aaa, { sayHello } from "./sample1";
console.log(sayHello());
console.log(aaa);
//hello
//default
```

これはReactとuseStateをimportするときによく見る。

## defaultの正体

defaultエクスポートは、暗黙のうちに変数を用意して、defaultという名前でexportする機能。

つまり
```tsx
const age 23;

export default {ages default}
```
```tsx
import {default as old} from "./sample1";
//oldが使用できる
```

みたいなことが行われている。

# 型
```tsx
type animal = {
  name: string;
  age: number;
};

const dog: animal = {
  name: "dog",
  age: 3,
};

export { animal, dog };
```
```tsx
import { animal, dog } from "./sample1";
const myDog: animal = { ...dog };
```

型もexport/importできる。

# type export

```tsx
type animal = {
  name: string;
  age: number;
};

const dog: animal = {
  name: "dog",
  age: 3,
};

export type { animal, dog };
```
```tsx
import { animal, dog } from "./sample1";

// error
const myDog1: animal = { ...dog };

const myDog2: typeof dog = {
  name: "dog",
  age: 3,
};
```

type export を使用すると、値として使用できなくなる。
type of とともに型として、使用できる。

# type import

```tsx
type animal = {
  name: string;
  age: number;
};

const dog: animal = {
  name: "dog",
  age: 3,
};

export { animal, dog };
```
```tsx
import type { animal, dog } from "./sample1";

// error
const myDog1: animal = { ...dog };

const myDog2: typeof dog = {
  name: "dog",
  age: 3,
};
```

次のようにもかける

```tsx
import type { animal } from "./sample1"
import { dog } from "./sample1"
```

```tsx
import  { dog, type animal } from "./sample1"
```

# * アスタリスク
一括インポート

```tsx
const name = "Mike";
const age = 23;

export { name, age };
```

```tsx
import * as xxx from "./sample1";
const age = xxx.age;
const name = xxx.name;
console.log(age, name);
//23 Mike
```


これはReactでよく見る。

```tsx
import * as React from "react";
const [value,setValue] = React.useState()
```
protobufのbuilder.pyが見つからなかった

# 動作確認環境
macOS Monterey (12.2)
MacBook Air(M1、2020)
チップ: Apple M1
Python: 3.9.13
conda version: 4.14.0
protobuf: 3.19.4
mediapipe-silicon: 0.8.11

# はじめに
M1macbookでmediapipeを入れて動かそうとしたところ、以下のエラー。

```
import mediapipe as mp
  File "~/miniforge3/envs/grad/lib/python3.9/site-packages/mediapipe/__init__.py", line 17, in <module>
    import mediapipe.python.solutions as solutions
  File "~/miniforge3/envs/grad/lib/python3.9/site-packages/mediapipe/python/solutions/__init__.py", line 17, in <module>
    import mediapipe.python.solutions.drawing_styles
  File "~/miniforge3/envs/grad/lib/python3.9/site-packages/mediapipe/python/solutions/drawing_styles.py", line 20, in <module>
    from mediapipe.python.solutions.drawing_utils import DrawingSpec
  File "~/miniforge3/envs/grad/lib/python3.9/site-packages/mediapipe/python/solutions/drawing_utils.py", line 25, in <module>
    from mediapipe.framework.formats import detection_pb2
  File "~/miniforge3/envs/grad/lib/python3.9/site-packages/mediapipe/framework/formats/detection_pb2.py", line 5, in <module>
    from google.protobuf.internal import builder as _builder
ImportError: cannot import name 'builder' from 'google.protobuf.internal' (~/miniforge3/envs/grad/lib/python3.9/site-packages/google/protobuf/internal/__init__.py)
```

protobuf.internal内にbuilder.pyが無いらしい。

# 対処
最新のバージョンのprotobufから、mediapipeが要求するバージョンのprotobufにbuilder.pyをコピーした。

1. <a>https://pypi.org/project/protobuf/#history</a>より最新のprotobufのバージョンを確認
2. `$python3 -m pip install protobuf==3.20.3`
3. `$python3 -m pip show protobuf | grep Location`
4. `$cp [3で出てきたパス]/google/protobuf/internal/builder.py ./builder.py`
5. `$python3 -m pip install protobuf==3.19.4`
6. `$python3 -m pip show protobuf | grep Location`
7. `$mv　./builder.py　[6で出てきたパス]/google/protobuf/internal/builder.py`

(2022年10月時点では最新の4.xxがあるが、3系と4系で記述が変わってしまう可能性を考慮して3.xxでの最新にした)


# おわりに
protobufはtensorboardやらtensorflow-macosの依存ライブラリとして指定されているのに、importするファイルが無いエラーが出ちゃうんだと驚いた。
こういう対処法はゴリ押し感が否めないけど動いてよかった。
多対多(グループとユーザー)のRspecで躓いた箇所の備忘録

# 概要
ポートフォリオ作成で、多対多のモデルが絡むRspecを書いていたときに躓きました。その時の解決策を備忘録として書き留めています。

こちらの記事を参考にさせていただきました。

https://t1gerk1ngd0m.hatenablog.com/entry/2019/08/24/233047


#### 開発環境
- OS：Amazon Linux2
- Rails 6.1.6.1

# 背景
マイページで、「自分が参加しているグループの一覧が表示される」というテストを書く際、「グループに所属しているユーザーの数」という記述をする必要がありました。グループとユーザーは、下記に示すように多対多となっており、中間テーブルを考慮した記述をする必要がありました。
![pf_ER-ページ5 drawio](https://user-images.githubusercontent.com/106591130/194531248-e551cb72-2529-41b8-854f-8313544918dd.png)

# 解決策
まずは、group_spec.rbのテスト部分に、Userモデルとのアソシエーションを記述します。
```ruby:spec/models/group_spec.rb
  #省略
  describe 'アソシエーションのテスト' do
    context 'Userモデルとの関係' do
      it '1:Nとなっている' do
        expect(Group.reflect_on_association(:users).macro).to eq :has_many
      end
    end
  end
  #省略
```

同様に、user_spec.rbのテスト部分にも、Groupモデルとのアソシエーションを記述します。
```ruby:spec/models/user_spec.rb
  #省略
  describe 'アソシエーションのテスト' do
    context 'Groupモデルとの関係' do
      it '1:Nとなっている' do
        expect(User.reflect_on_association(:groups).macro).to eq :has_many
      end
    end
  end
  #省略
```

続いて、userのファクトリを作成します(多対多のテストでは、ここが重要みたいです。)
```ruby:spec/factories/user.rb
  #省略
    trait :user_with_groups do
      #userが作られるとき、自動的にuser.groups(userに紐づいたgroups、すなわちgroup_user)を作るということ
      after(:build) do |user|
        user.groups << build(:group)
      end
    end
  #省略
```
上記の記述をすることで、テスト実行中にuserが作成されたとき、そのuserに紐づいたgroupも自動的に作成することができるようになるようです!

準備が整ったので、コントローラのテストコードの方を書いていきます!
```ruby:spec/system/after_login_spec.rb  
describe 'ユーザーログイン後のテスト' do
  #省略
  #:user_with_groupsは、先ほどfactories/user.rbに記述。ここで記述することで、userが作成された際、userに紐づいたgroup(id: 1)が作成される。
  let(:user) { create(:user, :user_with_groups) } 
  let!(:other_user) { create(:user) }
  #ここで、Group.firstとしているのは、今回のテストで使用するのは、先ほど:user_with_groupsで作成されたuserに紐づいたgroupであるため。
  let!(:group) { Group.first }
  #省略

  before do
    visit new_user_session_path
    fill_in 'user[email]', with: user.email
    fill_in 'user[password]', with: user.password
    click_button 'Log in'
  end
  #省略
  describe '自分のマイページのテスト' do
    before do
      visit user_path(user)
    end

    #省略

    context 'サイドバーの確認' do
      #省略
      it '自分が参加中のグループ一覧が表示される' do
        #「id=1のgroup.nameを押した遷移先がグループの詳細ページである」
        expect(page).to have_link group.name, href: group_path(group)
        #今回通したかったテスト。「id=1のgroupに紐づいたusersの数が表示される」
        expect(page).to have_content group.users.count
      end
      #省略
    end
  end
#省略
```

```ruby:
  expect(page).to have_content group.users.count
```
こちらの`group.users`は、アソシエーションで中間テーブルのgroup_usersテーブルを介した記述なので、上記のuserのファクトリに記述を行い、group_userも作成する必要があるということなのですね。

# 終わりに
これで無事にRspecが通りました!今後Rspecがスラスラ書けるように学習していきます!今は主にRubyとrailsを学習しているので、他に学んだことも投稿させていただきます!
Sketchfabへのアップロード形式の比較

# 概要
Widarで出力できる形式
- .OBJ
- .FBX
- .GLTF
- .USDZ
- .STL
- .PLY

で、Sketchfabに3Dオブジェクトをアップロードした時の見え方の比較をしてみました。`.XYZ`はSketchfabにアップロードできないので、今回は対象外です。

# 結論
`.OBJ`か`.GLTF`でSketchfabにアップロードすると良かったです。

# 目次
[.OBJで出力し、Sketchfabにアップロードした場合](#objで出力しsketchfabにアップロードした場合)
[.FBXで出力し、Sketchfabにアップロードした場合](#fbxで出力しsketchfabにアップロードした場合)
[.GLTFで出力し、Sketchfabにアップロードした場合](#gltfで出力しsketchfabにアップロードした場合)
[.USDZで出力し、Sketchfabにアップロードした場合](#usdzで出力しsketchfabにアップロードした場合)
[.STLで出力し、Sketchfabにアップロードした場合](#stlで出力しsketchfabにアップロードした場合)
[.PLYで出力し、Sketchfabにアップロードした場合](#plyで出力しsketchfabにアップロードした場合)

# 動作環境と出力するオブジェクト
- Sketchfab(2022/10/6)
- Widar(バージョン3.4.1)
- iPhone11
- [出力する3Dオブジェクト](https://service.widar.io/web-viewer/375daffc-d492-48cb-b470-e73a7d6e908e/)

# .OBJで出力し、Sketchfabにアップロードした場合

<a href="https://sketchfab.com/3d-models/yasai-itame-obj-85037c2a93f54f6399586ce375b03e68"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/17b80e58-0394-9048-dfb7-3214b780b75a.png"></a>

特に変なところはなく、Widarでの見た目とほぼ一緒です。

Sketchfabにアップロードする時には、テクスチャファイルとMTLファイルとOBJファイルをzipに圧縮してからアップロードしました。

![スクリーンショット 2022-10-06 19.52.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/4ed14a79-133d-d2b8-852a-2ff6ee7a91be.png)

![YasaiItame.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/96535759-f9e1-fd26-2b5c-41962b8b217a.gif)

# .FBXで出力し、Sketchfabにアップロードした場合

<a href="https://skfb.ly/oyMxO"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/ee15fea8-1f89-7376-ceb8-d876b39af1f9.png
"></a>

謎の線が表示されます。

# .GLTFで出力し、Sketchfabにアップロードした場合

<a href="https://skfb.ly/oyMBG"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/11669a49-8fa5-ef85-df6a-fe3151749311.png"></a>

こちらも特に変なところはなく、Widarでの見た目とほぼ一緒です。

# .USDZで出力し、Sketchfabにアップロードした場合

<a href="https://skfb.ly/oyMBI"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/28f559f9-467c-f19d-f08f-2bf0c298a62e.png"></a>

何故か発光しています。

# .STLで出力し、Sketchfabにアップロードした場合

<a href="https://skfb.ly/oyMBL"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/b13038d6-08b4-a61a-47a1-852a5104e121.png"></a>

色が白色になり、なぜか初期の角度がおかしくなっています。

そもそも`.STL`は小さな三角形（ポリゴン）を大量に用いて3次元の形状を表現する、3DCADソフトにおけるファイルフォーマットの一つなので、今回のような小さなオブジェクトには向いていないでしょう。([参考元](https://www.jampt.jp/column/1441/))

# .PLYで出力し、Sketchfabにアップロードした場合

<a href="https://skfb.ly/oyMBK"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/1e10e753-987b-e1c3-6510-66f10f8c53a5.png"></a>

こちらも、色の情報はなくなり、初期の角度がおかしくなっています。

`.PLY`は小さな点を大量に用いて3次元の形状を表現する、3D点群用のファイルフォーマットなので`.STL`と同様に今回のような小さなオブジェクトには使わない方が良いでしょう。

# 今後の課題
`FBX`や`USDZ`で表示がおかしくなる原因が分からなかったので、原因解明を急ぎたいところです。
SORACOM Harvest Filesからのファイル一括ダウンロード

## はじめに

SORACOM Harvest Filesからファイルをまとめてダウンロードする方法の解説です。
基本的には[ソラコム公式ブログ](https://blog.soracom.com/ja-jp/2021/07/15/soracom-harvest-files-api-downloads/)をご確認頂ければ問題ありませんが、初心者が躓きそうな点を補足説明します。
尚、本記事は[別記事](https://qiita.com/ogatoshi/items/deaf7799f9ae98b581af)で紹介しているKC4-C-100Aを使って連続撮影した静止画から動画を作成する際の補足手順です。その為、[KC4-C-100A](https://www.kyocera.co.jp/prdct/telecom/office/iot/products/kc4-c-100a.html?qiita)のツールが対応しているWindows®を前提とした内容になっています。


## 手順

「[Soracom Harvest Files Tools](https://github.com/soracom-labs/soracom-harvest-files-tools)」の「README.md」に記載された手順で進めて下さい。下記補足説明です。

### APIキーとAPIトークンの発行
:::note warn
認証する際は記載されている注意点をよくご確認ください。
:::

「[SORACOM API リファレンス](https://users.soracom.io/ja-jp/tools/api/reference/)」にアクセスし、「注意点を理解して認証する」をクリックしてください。

「SORACOMアカウントのメールアドレスとパスワードを使用する」のタブを選択し、SORACOMコンソールにログインする際のメールアドレスとパスワードを入力し、「認証」をクリックしてください。



### スクリプトの更新
ダウンロードし任意のディレクトリに配置したスクリプト「soracom_harvest_files_downloader.py」に、先ほど発行したAPIキーとAPIトークンを入力します。

| 更新行 | 削除 | 追加 |
|:-:|:-:|:-:|
| 20行目<br>30行目 | token["apiKey"] | 先ほど発行したAPIキーの前後を`"`で挟んで入力<br>APIキーは「api-」から始まる40字程度の文字列 |
| 21行目<br>31行目 | token["token"] | 先ほど発行したAPIトークンの前後を`"`で挟んで入力<br>APIトークンは2000字程度の文字列 |

### スクリプトの実行
以下の置換えを行ったコマンドでスクリプトを実行してください。
コマンドを実行するパソコンには、事前にPythonとRequestsモジュールのインストールが必要です。
※公式サイトでは冒頭が「python3」となっていますが、Widowsでは「python」の後の「3」は不要なため削除しています
※[公式サイト](https://github.com/soracom-labs/soracom-harvest-files-tools#parameter)を参照し、`--base_path`など必要なパラメータ設定を行ってください。

```
python soracom_harvest_files_downloader.py --auth_key_id [AUTH_KEY_ID] --auth_key [AUTH_KEY_SECRET] --base_path "/"
```

| 削除 | 追加 |
|:-:|:-:|
| AUTH_KEY_ID | SORACOMコンソールにログインする際のメールアドレス |
| AUTH_KEY_SECRET | SORACOMコンソールにログインする際のパスワード |

※`AUTH_KEY_ID`、`AUTH_KEY_SECRET`共に前後の`[]`は残して置換えを行ってください。

## 注記
- 商標
    - Windows®は米国Microsoft Corporationの米国およびその他の国における登録商標または商標です。Microsoft® Windows® の正式名称は、Microsoft® Windows® Operating Systemです。
    - ソラコム、SORACOM、又はソラコムの商品・サービス名称等は、株式会社ソラコムまたはその関連会社の商標または登録商標です。
    - その他本文中に記載されている会社名および商品名は、各社の商標または登録商標です。
Excelで必要な列のみ抽出するスピル関数を作ってみた

# はじめに
Filter関数を使っていて、便利だなと思ったのですが、必要な列だけを抽出することができず、いろいろ調べてみましたができないようなので、自作のスピル関数を作ってみました。

# 前提
スピルが利用できるバージョンのExcelであること

# スピルとは
数式を入力したセルから結果があふれて隣接したセルにも出力される機能です。

スピルを利用した関数には以下のようなものがあります。
- SORT関数
- SORTBY関数
- FILTER関数
- UNIQUE関数
- RANDARRAY関数
- SEQUENCE関数
- XLOOKUP関数

# 仕様

関数名: extractCols
第１引数：配列（列を絞り込みたい範囲を表すもの）
第２引数以降：第１引数で指定した配列から抽出したいカラム番号。1～の数値を指定

# 実装
実装コードは以下の通り「WorksheetFunction.Transpose」を使って、行列を入れ替え
そして必要な行のみに絞り、最後に再度行列を入れ替えて、応答するというもの

```vb
Option Explicit

Function extractCols(ByVal vArray As Variant, ParamArray cols() As Variant) As Variant
    
    Dim dummyArray As Variant
    Dim resutlArray() As Variant
    Dim count As String
    Dim col As Variant
    
    ' 配列の行列を入れ替える
    dummyArray = WorksheetFunction.Transpose(vArray)
    
    count = 0
    ' 行列入れ替えたので、指定した行のみを、新しい配列に追加
    For Each col In cols
        ReDim Preserve resutlArray(count)
        resutlArray(count) = WorksheetFunction.Index(dummyArray, CInt(col))
        count = count + 1
    Next
    
    ' 配列の行列を入れ替え、結果に設定
    extractCols = WorksheetFunction.Transpose(resutlArray)

End Function
```

# 結果
想定している通りの結果となりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132118/73ba5d3a-13e7-4ab2-10c9-dd368d07512e.png)

Filter関数の結果を第１引数に入れることもできます。ある表から
一定の条件で抽出したのち列を絞りたいというときに使うことができます。

# おわりに
スピルを調べる中で、独自関数を作る場合の可変長パラメータなど
今までやったことなかった要素もあって、なかなか勉強になりました。
roscoreを複数立ち上げる


1つのPCに複数のrosアプリケーションを立ち上げたいとき、それぞれのアプリケーションの命名などを意識してシステム開発をするのが面倒だなと思い`roscore`を複数立ち上げる方法を調べました.

使用環境は`ubuntu20.04` `ros noetic`です.

方法としては,`ROS_MASTER_URI`と`roscore`の`-p`オプションをのポート番号を一致させることで実現できます.

では実際に行っていきます.

まず1つ目の`roscore`をたちあげます.ターミナルを開いて以下コマンドを実行していきます(`11311`番ポートに立ち上げ)

```bash:roscore1
export ROS_MASTER_URI=http://127.0.0.1:11311
roscore -p 11311
```

次に2つ目のターミナルを開き以下のように実行します(`11312`番ポートに立ち上げ)


```bash:roscore2
export ROS_MASTER_URI=http://127.0.0.1:11312
roscore -p 11312
```

結果以下のように`roscore`を2つ立ち上げることができました.

![Screenshot from 2022-10-07 19-43-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/5918d00b-6636-93a5-ed0f-749c9704265c.png)

プログラム実行前に`export ROS_MASTER_URI=http://127.0.0.1:11312`のように立ち上げたいポート番号の指定は必要になると思います.アプリケーション間のつながりを疎にしたい場合に活用できそうです.

# reference

- How to run multiple roscore/master in a single machine?
https://answers.ros.org/question/57539/how-to-run-multiple-roscoremaster-in-a-single-machine/
LocalDateTime とフォーマッターの初歩！

Java研修を3日行なった中で筆者が一番苦労したのが、
LocalDateTimeとDateTimeFormatterでした！

なのでまとめてみました

<h2>時間の設定</h2>

```Java
LocalDateTime ldt=LocalDateTime.of(2022,10,7,19,33);
// 年・月・日・時・分の並び
```

<h2>フォーマットの作り方</h2>

``` Java
DateTimeFormatter dtf=
        DateTimeFormatter.ofpattern("uuuu年MM月(E)HH：mm",Locale JAPAN);
```
【Git】マージ済みのローカルブランチを削除する方法

## マージ済みローカルブランチを削除

以下のコマンドを実行することでマージ済みのローカルブランチを削除できます。

```
git branch --merged | grep -Ev '^\*|main|develop' | xargs git branch -d
```

* `git branch --merged`
マージ済みブランチの一覧を取得する。

* `grep -Ev '^\*|main|develop'`
一覧の内、先頭に`*`または`main`または`develop`を含まないものを取得する。
`egrep -v '^\*|main|develop'`でも可。

* `xargs git branch -d`
前のコマンドで取得したブランチを引数として`git branch -d`を実行してブランチを削除する。

## 不要なリモート追跡ブランチを削除

また以下のコマンドを実行することで不要になった[リモート追跡ブランチ](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81)を削除できます。

```
git remote prune origin
```
Java 研修3日目エンジニアがソースを書くとき頻繁に間違えたところ

自分は１０/３に入社し、１０/5からフルタイムでのJava研修を受けています。
そんな自分が練習の中で間違えたとこを記事にしています。

<h2>エスケープシーケンスの記入漏れ</h2>

```Java
System.out.println(""");              "
//　ダブルクオーテーションを文字列で記入できない！！

//正答
System.out.println("\"");
//¥の場合あり！

```

<h2>=の右と左を間違える</h2>

```Java
public void setName(String name) {
			name=this.name;
		}
//代入される値と代入する値の順序が逆になってしまう

//正答
public void setName(String name) {
			this.name=name;　//代入される＝代入する
		}
```

<h2>コンストラクタに戻り値をつけてしまう</h2>

```Java:Cat.java
void Cat(){〜〜〜処理〜〜〜}

//正答
Cat（）{〜〜〜処理〜〜〜}
```

<h2>メソッドに引数があった場合に引数を入れ忘れる</h2>


上記のようなかなり初歩的なミスを多くしてました。
他にもString型のデータを＝＝で判定しそうになったり
getterとsetterの名前を逆逆にしてしまうなど！
あげたらキリがないですが、初心者が間違えそうな部分を記事にしました。