OmniAICreator/Qiita-1.07M huggingface dataset:
3DのTPSシューティングゲームを作りたい人の日記3

#はじめに
前回の記事を読んだ方からすればかなりお久しぶりです。またまた更新が遅くなってしまいました・・・。
[前回の日記はこちら](https://qiita.com/midorinohito/items/0c9c82d5e79de1042a31)

この記事は私がUnityで3DのTPSシューティングゲームを作る過程を残しておくために書いています。

プログラムを組む過程で詰まったところで参考にしたもの等を書いていくので、同じようなことで詰まっている方の助けになればと思います。

#作りたいもの

**ステージ1が遊べるようになりましたー！！**

**特定のアイテム(荷物)を集めてゴール(依頼主の家)まで運ぶ(配達する)**というのを目的としたゲームになっています。
TPSのゲームですが、TPSが苦手な人でも遊べるようになっています。

#進歩
今回はスタート画面からゲームが終わってスタート画面に戻ることができるようになるまで作りました。デモ版という形で配布できるところまで来ました。
コード等は自分の苦戦した部分のみ説明します。

1. ミニマップの表示
1. アイテムのドロップ
1. プレイヤーの攻撃エフェクトの表示
1. 画面の遷移
1. 音量調整機能の追加
1. 遊び方の画面の追加
1. データのセーブとロード
1. SEとBGMの追加
![スクリーンショット 2021-03-01 142006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688227/6b904fbb-c821-63e0-ee9a-d8b36acbde44.png)

進歩動画↓

https://youtu.be/wkLJpbTj-9w

#データのセーブとロード
今回、セーブとロードが必要なデータをtext形式で保存しました。読み込みと書き込みを同じ方法でしたかったので、読み込みにはStreamReaderを使い、書き込みにはStreamWriterを使いました。
苦戦したのは、ゲームとしてビルドした後に読み込みと書き込みを行うには専用のフォルダに入れて、ビルドした後のゲームで読み込めるパスを通さなければならなかった部分です。

読み込むテキストは次のようなデータにしていました。

```
#ID data1 data2
1   abc   あいう
2   def   かきく
```

というように、データの間をタブで区切るようにして1行が1ステージに対応する形式でデータにしていました。

ビルド後のゲームで使えるパスにするためには、データを書き込んだテキストファイルをAssetsフォルダの下に作成したStreamingAssetsフォルダに入れます。そして、プログラムでパスを指定するときはこのようにすることで上手く動作します。

```c#
string filePath = Application.dataPath + "/StreamingAssets/" + "データの書き込まれたファイル名.txt"; //テキストファイルのパス
```

データの書き込みや読み込みはいくつか種類があり用途によってどの方法を使うか選ぶ方が良いと思うので、参考にしたサイトを以下に載せておきます。
[おもちゃラボ　【Unity】ファイルの読み込みと書き込み方法3選](https://nn-hokuson.hatenablog.com/entry/2020/10/27/151858)

#今後
今後も改良を重ねて楽しいゲームにしていきたいと思っています。
個人的な区切りとしてゲームとして遊べるようになるまで日記を書き続けようと思っていたので、今回で一区切りとなります。
今後もこの日記を続けるかはわかりませんが、ここまで読んでくださってありがとうございました！
お猿さんのためのReactまとめ：Vol.1　state & props編

猿というか自分自身の為のまとめです。
Reactを学習していく中で、「あれ？これはなんだったっけ？」的な事をまとめて行きたいと思います。
また、Qiitaの書き方に慣れる意味もあります。
恐れずに言うのであれば、「アルジャーノンに花束を」のようにどんどん書くレベルが上がることを目指します。（勿論、物語の途中までで良いですが・・・。）
##1...最もシンプルな表示例
![React (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/17b03aff-8d71-3f04-e04f-7cda2e7a7d9a.png)
親コンポーネント、子コンポーネントともにreturnしたい要素は`<div>`で囲む。
![React (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/ba7ca6b9-fedd-65b3-d9a3-bc135c0d4c2c.png)
##2...propsで要素を親から子に渡す。
![React (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/48f9c502-bef9-3bac-52fe-41a8ec364262.png)
図のようにして使いまわすことができる。
##3...propsで渡せる値の型
![React (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/e4e89833-a45e-728b-3c9e-242739aeb68f.png)
##4...stateについて
###stateとは？

* コンポーネント内で管理する変数(=ローカルステート) <-->グローバルステート
* propsとして子コンポーネントに渡せる。

###なぜstateを使うのか?

* render()では値を変更してはいけない。
* 値の変更にがsetState()を使う。
* stateの変更は再レンダーのきっかけになるのでrender()内で行うと無限ループになってしまう。
* 設定はクラスコンポーネントが前提。
* constructor()内でオブジェクト型で記述する。

```React:Blog.jsx
class Blog extends React.Component {
  //コンストラクター内で記述
  constructor(props) {
    super(props);
    //オブジェクト型で記述　カッコは波カッコ{}
    this.state = {
      isPublished: false
    }
  }
  render() {
    return (
      <div>
        <Article 
           title='React'
           //このように記述することで同じコンポーネント内は参照できる。
           isPublished={this.state.isPublished}
        />
      </div>
    )
  };
};

export default Blog;
```
```React:Article.jsx
const Article =(props)=> {
  return (
    <>
      <h2>{props.title}</h2>
      <label htmlFor="check">stateの状態</label>
      <input
        type='checkbox'
        //子コンポーネントはこのように受け取る。
        checked={props.isPublished}
        id='check'
      />
    </>
  )
};

export default Article;
```
![React (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/725274d3-0a4a-398f-9ffa-43d6a7d0c00b.png)
###stateを変更する

* setState()を使い、その中に記述されたstateのみ変更する。
* 関数にラップする。

![React (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/ce106406-8b9c-bb85-6c11-6d68c910a1e9.png)
参考：[日本一わかりやすいReact入門【基礎編】](https://youtube.com/playlist?list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7)
キャンペーンの基本 ⇒ キャンペーンのレポート

１．組み込みキャンペーンレポートはどこにありますか?
２．組み込みキャンペーンレポートにはどのような情報がありますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/b4cef413-9aac-3d64-fdaf-292fa772e227.png)
毎日投稿（ReactとTypescriptでTodoアプリ改修）

本日はReactとTypescriptで作ったTodoアプリの改善をしました。

ToDoアプリは以下で学習しながら作りました。

**【世界で7万人が受講】Understanding TypeScript - 2020年最新版**
https://www.udemy.com/course/understanding-typescript-jp/


このアプリを作り終えたときは、
以下の修正が必要だなと思いました。
１. 新しくTodo追加時にinputfromにそのTodoのテキストが残留してしまう。
２. 空欄でもTodoとして追加されてしまう。

3〜5時間考えて、、、

以下のとおりコードを足し、2点とも改修できましたが、、
（本質的には考えると２番目は解決できていません。）


```
const enteredText = textInputRef.current!.value;
if(enteredText !== "") {
   onAddHandler(enteredText);
   textInputRef.current!.value = '';
} else {
   alert('入力してください');
}
```


満足出来ていません。
バリデーションを使えばいいかなと思い、実装していたのですが、、途中で諦めました。。。
まだまだこれからも、TypeScriptもReactも勉強していきます。
追加機能しようと考えているので、できたら、またQiitaに書います！


以下、githubに公開しています。
ありがとうございました。

https://github.com/takeshi1201/React-Typescript-Todo.git
Pythonでのシリアル通信

### 概要
個人的に組み込み開発ではデバッグが難しいと感じており，ほとんどの場合シリアル通信を行うことでPCに何らかのデータを送って確認する．しかし，シリアル通信自身がおかしい場合，プログラムのどのパスを通ったのか，などはLEDを光らせて確認するしか無い．加えて，Arduino IDEにはシリアル通信を使ってデータの受信と表示，データ送信をできるツールが付属しているが，データ送信は文字として送られてしまうため，生データを送ることが難しい(できない？)．

そこで，今後のために，Pythonでシリアル通信を実行し，加えてLEDを使って正しくシリアル通信ができることを確認してみる.

### Arduino Unoのプログラム
Arduino Unoで以下のプログラムを実行する．

```c:main.c
#include "serial.h"


int putc(unsigned char c) {
	if (c == '\n') {
		serial_send_byte('\r');
	}
	return serial_send_byte(c);
}

unsigned char getc() {
	return serial_recv_byte();
}

void setout();
void turnon();
void turnoff();

int main(void) {

	serial_init();
	setout();     // シリアルの初期化


	putc('D');       // 1文字出力
	char c = getc(); // 1文字入力を待つ

	turnon();	     // LEDを点灯
	putc(++c);       // 受信した文字をインクリメントし，シリアルで出力
	putc('E');       // 1文字出力
	c = getc();      // 1文字入力を待つ

	turnoff();	    // LEDを消灯
	putc(++c);      // 受信した文字をインクリメントし，シリアルで出力
    putc(++c);      // 受信した文字をインクリメントし，シリアルで出力
    while(1){}
```

コメントにあるように，Arduinoでは1文字出力し，その後，受信->送信を2回繰り返して処理を終了する．そして，1回目の受信でLEDを点灯，2回めの受信でLEDを消灯する．よって，仮に送受信できない場合でも，LEDの点灯/消灯でどこまでプログラムが実行されたかわかる．

### Pythonでのシリアル通信
Pythonでシリアル通信を実行するために，`pyserial`をpipでインストールする

```
pip3 install pyserial
```
そして，Arduinoのプログラムに合わせてデータを送受信する．

```python:test.py
import serial
import time

ser = serial.Serial('/dev/cu.usbmodem142101', 9600, timeout = 1)


while True:
    data: bytes = ser.read();
    if len(data) > 0:
        break

int_data = int.from_bytes(data, 'big')
print(data)
print("data1 = {}".format(int_data)) # Dを読む

time.sleep(0.5)

ser.write(bytes([65])) # aを書く
time.sleep(0.5)
data: bytes = ser.read() # bを読む

int_data = int.from_bytes(data, 'big')
print(data)
print(len(data))
print("data2 = {}".format(int_data))
time.sleep(0.5)
data: bytes = ser.read() # Eを読む
print(data)
time.sleep(0.5)
ser.write(bytes([67])) # cを書く
time.sleep(0.5)
data: bytes = ser.read() # d
print(data)
```

特に解説は必要ないと思うが，シリアル通信は遅いので，送受信の間に0.5秒のsleepを入れている．これを入れないと，実行が早すぎて見えない．
![IMG_4669.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57629/a9bf8efc-47c4-2652-66ea-9fed9a5d8165.png)



この実装は，以下のコマンドで試すことができる．

```
>git clone https://github.com/hiro4669/iosv.git
>cd iosv
>cd serial_py
>make
>make write
>python3 test.py
```
Nuxt × firebaseでReferenceError: navigator is not defined

Nuxtでfirebaseを使用しているときに、`nuxt generate`したときに発生したエラー

```bash
ERROR   /form                                                                                                                                16:10:10

ReferenceError: navigator is not defined
```

## 解決策

```javascript:firebase.js
if (typeof window !== 'undefined' && firebase.apps.length === 0) {
  firebase.initializeApp(config)
  firebase.analytics()
}
```
javascript - file

■inputのtype=file選択時にjsでバリデーションする【vue.js】
https://taupe.site/entry/input-typefile-validation/

■JavaScriptのswitch文で正規表現を使う方法を現役エンジニアが解説【初心者向け】
https://techacademy.jp/magazine/35356

■JavaScript で URL やファイルの拡張子を取得する
https://loumo.jp/archives/23134

実際のコード

```
    fileTypeValidate() {
      switch(true) {
        case /.csv$/.test(this.uploadFile.name):
          console.log('csvです')
          this.getCsvData()
          break
        case /.xlsx$/.test(this.uploadFile.name):
          console.log('xlsxです')
          this.getXlsxData()
          break
        case /.xls$/.test(this.uploadFile.name):
          console.log('xlsです')
          this.getXlsData()
          break
      }
    }

```

this.uploadFile.nameでファイル名とれた！
IFTTTを使ってみるまで

実際に使ってみるには？をやってみる。
そのメモ

#IFTTTの設定

[IFTTT使用までの準備](https://qiita.com/bobrock/items/8c4a1f179e355be14b20)で設定したAppletを使用する。

##Emailを使ってみる

マイページ右上アイコンクリック⇒MY servicesを選択する。
![スクリーンショット (95).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/e25ea992-b2d0-b159-a530-d3549e0b7be7.png)

---

『Webhooks』を選択する。
![スクリーンショット (100).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/23ec3d85-111d-5fe2-1053-4893b8c0697b.png)

---

『Documentation』をクリックする。
![スクリーンショット (97).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/00202f49-fdd2-735e-a2da-fba7d4d1a1a0.png)

---

動作確認画面が表示されるので
`event`に作成時に設定したイベント名(ここでは`Email_Connect`と付けている)を入力
各`value`については適当に文言を入力する。
![スクリーンショット (101).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/2ea2ba31-ef64-e2c8-5c75-9f20f0c1a8f0.png)

入力が完了したら、『Test It』をクリックする。

---

設定した物が正常だと登録したアドレスに対してテストメールが送信されてきます。
![スクリーンショット (105).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/a5b5351f-8c72-4928-e793-e3ccea6742cd.png)

ちなみに間違えていても送信されてきたので軽くパニック
(間違えとしてはevent名を設定後に管理しやすい名前に変えていたのを忘れていた)

↓間違えていた時に送られてきたもの
![スクリーンショット (106).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/43b6f644-5575-924d-ed38-bdc5c11fb701.png)

自身がGoogleを基本にしているのでGmailで登録しているが
正常に送られて来たものは受信メールフォルダに入ったが
間違えていたものはプロモーションに入っていたのが謎

間違えない様に注意が必要。

間違え理由として
editでトリガー名を変更していたが
My Applet上に表示されているコメントが変更前のままだったので勘違いした。
設定を変えたら合わせて表示コメントを修正しないとたぶん間違える。

##LINEを使ってみる(接続テスト)

基本的にはEmail設定と同じ感じで対応可能。

`My services`→`Webhooks`に入る。
![スクリーンショット (100).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/661656c8-4661-246f-c498-036d98f8663c.png)
 
---

『Documentation』をクリックする。
![スクリーンショット (97).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/00202f49-fdd2-735e-a2da-fba7d4d1a1a0.png)

---

動作確認画面が表示されるので
`event`に作成時に設定したイベント名を入力
各`value`については適当に文言を入力する。

ここの`event`名をLINE設定した際のイベント名を入力する。(自身は`LINE_Connect`と設定している)
![スクリーンショット (101).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/2ea2ba31-ef64-e2c8-5c75-9f20f0c1a8f0.png)

入力が完了したら、『Test It』をクリックする。

---

するとLINE側にテスト通知が飛んできます。

![LINE1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/e05abf26-4600-686e-6942-ea25fd04669e.jpeg)


#Raspberry Piから送信する

Raspberry PiからEmailやLINEに通知を送る際には
赤枠部分のコマンドラインが必要となります。

![スクリーンショット (107).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/d75d66aa-4d39-67fd-dbf2-d700c2afa699.png)

コピーしてRaspberryPi側のターミナルに入力すればOKです。

ただ`curl`を使用しているのでインストールされていない場合は

```
sudo apt install curl
```

これでインストールしておく事。

準備が出来たら
ターミナルにコマンドラインをコピペすれば送信されます。

上記どちらもテストして、Gmail・LINE共に受信しています。

成功すればターミナルに成功したと表示が出ます。
![IMG-0354.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607764/ed0423df-f5d6-5037-e7b4-4000e9059b9d.jpeg)


後はどんな風に送信するか等は個別に設計すればOKかと

#まとめ

ここまで設定して初めて使用出来ると思います。
結構めんどくさいのと
IFTTT自体が参考資料時から使い方が変わっていたので
その辺りをフォローできていればよしかと。
【SwiftUI】ListでRowの開閉アニメーション

SwiftUIのListで、Rowタップ時にRowの高さをアニメーションさせつつ変化させます。

![sample1](https://user-images.githubusercontent.com/5576470/111035051-ce1f9a00-845b-11eb-91d7-97faeb3920ee.gif)

# 環境

- Swift: 5.3.2
- Xcode: 12.4 (12D4e)
- macOS: Big Sur 11.1 (20C69)

# コード

```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
	@State var selected: UUID?
	@State var scrollTop = false

	var items = (0..<100).map { ItemData(value: $0 * 2 + 10001) }

	var body: some View {
		ScrollViewReader { proxy in
			NavigationView {
				List(items) { item in
					ItemView(item: Binding.constant(item), parent: Binding.constant(self))
				}
				.listStyle(PlainListStyle())
				.navigationBarTitle(Text("List01"), displayMode: .automatic)
				.navigationBarItems(trailing:
					Button(scrollTop ? "Top" : "Bottom") {
						withAnimation {
							proxy.scrollTo((scrollTop ? items.first : items.last)!.id, anchor: .top)
							scrollTop = !scrollTop
						}
					}
				)
			}
		}
	}
}

struct ItemData: Identifiable {
	var value = 0
	let id = UUID()

	var idString: String {
		get { return String(id.uuidString.prefix(5)) }
	}
}

struct ItemView: View {
	@Binding var item: ItemData
	@Binding var parent: ContentView
	@State var openCell = false

	var body: some View {
		ZStack {
			Color.blue.opacity(0.3)
			VStack {
				Text("Item \(item.idString) => \(item.value)")
					.frame(maxWidth: .infinity, alignment: .leading)
				Text("--")
					.multilineTextAlignment(.trailing)
					.frame(maxWidth: .infinity, alignment: .trailing)
				Spacer()
			}
			.opacity(openCell ? 0 : 1)
			VStack {
				Text((0..<(openCell ? 5 : 1)).map { "Detail \($0)" }.joined(separator: "\n"))
					.multilineTextAlignment(.trailing)
					.frame(maxWidth: .infinity, alignment: .trailing)
			}
			.opacity(openCell ? 1 : 0)
		}
		.fixedSize(horizontal: false, vertical: true)
		.modifier(AnimatingCellHeight(height: openCell ? 120 : 60))
		.animation(.linear)
		.contentShape(Rectangle())
		.onTapGesture {
			openCell.toggle()
		}
	}

	init(item: Binding<ItemData>, parent: Binding<ContentView>) {
		_item = item
		_parent = parent
		print("init: \(item.wrappedValue.idString)")
	}
}

struct AnimatingCellHeight: AnimatableModifier {
	var height: CGFloat = 0

	var animatableData: CGFloat {
		get { height }
		set { height = newValue }
	}

	func body(content: Content) -> some View {
		content.frame(height: height)
	}
}

struct ContentView_Previews: PreviewProvider {
	static var previews: some View {
		ContentView()
	}
}
```

# リポジトリ

https://github.com/sugiharam2-samples/SwiftUIList01

# 問題点
- Rowの高さが固定値で入っている（GeometryReaderを使うとうまくいかなかった）
- アニメーションがぎこちない（modifierか何かがおかしい？）
sqlで先頭が数字で始まる文字列を検索する

##正規表現を使って調べる
```
SELECT * FROM テーブル名 WHERE 調べたいカラム名 REGEXP '^[0-9]';
```

###REGEXP以下をちょっと解説
```

・ ^　  先頭の文字列を指定
・ []　 []内のいずれかに一致
・ 0-9　0から9
```

つまり、**文字列の先頭が0から9のいずれかに一致する**ものを検索する正規表現になる


下記を参考にすれば色々応用できます
[正規表現を使ったパターンマッチングを行う(REGEXP演算子)](https://www.dbonline.jp/mysql/select/index8.html)
mysqldumpからDEFINERを削除するコマンド

##mysqldumpからDEFINERを削除するコマンド

```bash:terminal
LANG=C sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' < ~/hogehoge.sql > hogehoge_nodefiner.sql
```

##そもそもDEFINERとは
Viewの操作権限を持つユーザーのこと

##じゃあVIEWとは
MySQL5系から使えるようになった機能で、テーブルから取得したいデータの条件を定義してあたかも独立したテーブルのように扱えるようにしたもの。
VIEWそのものはデータを持たず、元となったテーブルからデータを参照する。
例えばテーブルの一部のカラムだけを取り出したVIEWを作成し、他のユーザーにはVIEWだけを閲覧できるように権限を設定するといった利用ができる。
【QA・障害002】リソースグループ単位でのリソース削除ができない(Delete Vault)

# Delete Vaultの操作でリソースグループ単位でのリソース削除が失敗

## エラー内容
エラー コード
ServiceResourceNotEmptyWithBackendMessage

メッセージ
Recovery Services vault cannot be deleted as there are backup items in soft deleted state in the vault. The soft deleted items are permanently deleted after 14 days of delete operation. Please try vault deletion after the backup items are permanently deleted and there is no item in soft deleted state left in the vault.For more information, refer https://aka.ms/SoftDeleteCloudWorkloads. The registered items are : testvm01 Please ensure all containers have been unregistered from the vault and all private endpoints associated with the vault have been deleted, and retry operation. For more details, see https://aka.ms/AB-AA4ecq5

でリソース削除が失敗してしまった。
これは、論理的削除機能があるタイミングから自動的に有効になり、悪意ある第三者にのっとられてバックアップが削除されデータが失われることを防ぐ目的にものらしい。

## 解決方法
こちらに関連情報の記載がある。

https://docs.microsoft.com/ja-jp/azure/backup/backup-azure-security-feature-cloud

で、この機能有効化しないと、リカバリサービスコンテナ内になにも情報が無くてもバックアップ削除して14日間経過しないとリカバリサービスコンテナが削除できなくなってしまう。このエラーが発生した場合、以下の設定変更でこの論理的削除機能を無効化して削除可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111921/082da7e2-e656-a49c-0820-79ed0227fb8e.png)
【wordpress】カスタムHTMLが保存されない！？→WAF対応せよ

WordPressでサイドバーなどにブログパーツを貼り付ける際に、「保存」ボタン押しても一向に保存が完了しない時に、参考にしてください。

# 現象
アフィリエイトやサイト紹介などのリンク作成ツールなどを使ってブログパーツを作り、WordPressのサイドバーに設置しようとカスタムHTMLにコピペして保存ボタンクリックしたけど、処理中アイコンがぐーるぐるして終わらない。。。

# wordpressのせいじゃない
これは、自分のせいでもwordpressのせいでもなく、あなたが借りているレンタルサーバーなどのセキュリティの設定がいい仕事をして大海のいろんな亡者からあなたのサイトを守っているからです。

# こう作業せよ
私は[自サイト](https://guppywebservice.info)を「[お名前.com](https://www.onamae.com/)」のレンタルサーバーで管理しています。
ロリポップやサクラなども同じような設定だと思いますので、ここでは私のレンタルサーバーでの設定を元に解決方法を示します。

## 1.レンタルサーバーのセキュリティ画面のWAFをクリック
![スクリーンショット 2021-03-01 15.18.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/4322e17d-310c-8ead-cd50-4e7c5ed42c6f.png)

## 2.WAF設定をOFFにする
![スクリーンショット 2021-03-01 15.38.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/fdaebbfc-a30b-0be8-b527-fe51040e53e7.png)

## 3.素早くwordpressでブログパーツを編集して保存をクリック
設定の反映が少し時間かかるかもしれないので、保存ができなかった場合は2,3分置いてから再チャレンジ。
![スクリーンショット 2021-03-01 15.24.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/33e66a39-054e-502c-178f-2370c74b496d.png)

## 4.サイトページをリロードして表示を確認

## 5.レンタルサーバーのWAF設定をONに戻す
![スクリーンショット 2021-03-01 15.25.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/d4e7b308-e66e-a51e-a67b-76ebc47924dc.png)

# 素早く作業
せっかくいい働きをしているWAFを解除するということは、シールドを解除して自分のサイトを敵に晒すようなものなので、更新作業は慌てず、でも素早く行い、更新を確認し終わったら素早くシールド（WAF)オンにしておきましょう。

また同じことを検索するかもしれないので、自分のためにも備忘録でした。
HTMLについて


#HTMLについて
　HTMLとは、私達が画面で見ている文字のことです
　コードで書く場合は"タグ"で囲みます。
　これをマークアップというみたいです。
#マークアップしてみよう！
```index.html
<h1>HTMLについて</h1>
```
ブラウザで表示するとこうなります。
これが見出しになります。
↓
![スクリーンショット 2021-03-01 15.00.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/905abeee-3acb-08ea-de76-c913a0065cb6.png)


と表示されます！
＊エディターはVSCodeです。  https://azure.microsoft.com/ja-jp/products/visual-studio-code/
＊ブラウザはGoogleChromeです。 
https://www.google.co.jp/chrome/?brand=FDKM&gclsrc=aw.ds&&gclid=CjwKCAiAm-2BBhANEiwAe7eyFAQxQ3wNHOAnBFJBOU2032-zXQrDrS3oUBTBkUxAFPLi0-XkEyfAFBoCuUwQAvD_BwE

#いろんなタグ

```index.html
<h1>HTMLについて</h1>
<P>この記事は初心者が書いていますので、<br>お手柔らかにお願いいたします。</br></p>
```
と入力するとこうなります
↓
![スクリーンショット 2021-03-01 15.25.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/fc6a9577-1b51-155e-bf57-575a1db536b9.png)

pタグ は、段落を表します。
brタグは、改行の場合に使います。

##写真挿入
では写真を挿入してみましょう。

```index.html
<h1>HTMLについて</h1>
<P>この記事は初心者が書いていますので、<br>お手柔らかにお願いいたします。</br></p>
<img src="images/images (1).jpeg">
```
と入力すると以下のようになります
↓
![スクリーンショット 2021-03-01 15.38.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/23ec8028-d243-7896-131a-d9ea4d191adf.png)


次回はCSSについてアウトプットしていきます。

ちなみにこのページ結構わかりやすいです。
https://developer.mozilla.org/ja/
タグについて解説してくれてます😊
[Rails] モデルが使用しているデータベースを調べる

# 方法

[ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#current_database](https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html#method-i-current_database) を使用する。

```rb
DemonSlayer.superclass #=> ApplicationRecord(abstract)
DemonSlayer.connection.current_database #=> 'kimetsu_production'
```
Intel oneAPIのダウンロードでユーザ登録のループに陥った時

`Sign in or Sign up`ではなく左下のリンクからダウンロード可能です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267183/20b871cd-d42e-32e2-d063-a53bada5f038.png)
salesforce如何在testclass里面测试exception,确保覆盖率

salesforce如何在testclass里面测试exception,确保覆盖率

解决方法就是在test类里面使用try catch。
并且通过catch来判断是否捕捉到了我们想测试的exception。

下面是一个例子


```

The idea is to:

 

a. Write code in the test class that will cause the trigger to 'addError()'.

b. Surround the above test class code with try - catch.

c. Assert that an exception is thrown and that the exception message is the same one you created with 'addError()'.

 

Here's an example (partly pseudo) code from both trigger and test class:

 

Trigger: 

 

if(myRecord.MyField == some value)

myRecord.addError('My Error Message');

 

 

Test Class: 

 

try

{

MyRecord.MyField = a value that will cause an error; 

update MyRocord;

throw new MyException('An exception should have been thrown by the trigger but was not.'); // 1. If we get to this line it means an error was not added and the test class should throw an exception here. 2. MyException class extends Exception.

}

catch(Exception e)

{

Boolean expectedExceptionThrown =  e.getMessage().contains('My Error Message')) ? true : false;

System.AssertEquals(expectedExceptionThrown, true);

}
AnsibleでCiscoルータのIPアドレスを変更する

#発端
Ansibleからネットワーク機器を触ってみようと思い、いろいろ調べました。しかしネット上のplaybookをコピペしてみたもののうまく動かず(エラーになる)、四苦八苦しました。ほかの方の参考になればと、ここにうまくいった例を挙げておきます。

SoftwareDesign2018年12月号の特集に触発されて実験しました。


#環境
Ansibleサーバ：Ubuntu16にインストールして実行しました。
https://docs.ansible.com/ansible/2.9_ja/installation_guide/intro_installation.html#ubuntu-ansible

```
XXX@XXX:~$ ansible --version
ansible 2.9.18
```
対象ネットワーク機器：Cisco1812J

```
Router#show version
Cisco IOS Software, C181X Software (C181X-ADVIPSERVICESK9-M), Version 12.4(15)T1, RELEASE SOFTWARE (fc2)
```

#Directory構成

```
.
--- playbook.yml
--- ansible.cfg
--- group_vars
   |--- ios.yml
--- inventory

```

#inventory

```
[ios]
my_router ansible_host=xxx.xxx.xxx.xxx #制御したいルータのIPアドレスを記載
```

#ios.yml

```
ansible_network_os: ios
ansible_connection: network_cli
ansible_user: XXXXX            #cisco routerのsshログインID
ansible_password: XXXXX        #cisco routerのsshログインパスワード
ansible_become: yes
ansible_become_method: enable
ansible_become_pass: XXXXX     #cisco routerのenableパスワード

```

#playbook
・やりたいこと：ルータのホストネームとFastEthernet0のIPアドレスを変更する。※hostnameをNew_RouterNameに、IP addressを1.1.1.1/24に変更。sshでアクセスしている物理ポートのIPアドレスを変えてしまわないように注意(^^;)
・Globalコンフィギュレーションモードで変更できるものと、階層がことなるInterfaceコンフィギュレーションモードで変更するもので、どのように書き方を変えなければいけないか検証。

```
- hosts: ios
  gather_facts: no

  tasks:
    - name: set hostname        #hostnameの変更
      ios_config:
        lines:
          - hostname New_RouterName
        save_when: changed

    - name: set ip address      #IP addressの変更
      ios_config:
        lines:
          - ip address 1.1.1.1 255.255.255.0
        parents:
          - interface FastEthernet 0
        save_when: changed

```


#はまったところ
・一次情報をあたっていないので何とも言えないのですが、commnadsにコマンドを書く方法と、linesに「-」でコマンドをを渡す方法があるらしく、モジュールの使い方をちゃんと見た方がよいw
・IPアドレスを「実験だから」と/32にしたらエラーでansibleがコケました。LoopBackだったらいけたのかも。
・ansibleサーバからciscoへsshで接続できることが前提です。そして設定方法をgroup_varsのios.ymlに書いておく必要があります。
・yamlなので、意図せずTABが入っていると動きませんw
・playbookの書式チェックに、--syntax-checkオプションを付けてお伺いを立てるのですが、
```
ansible-playbook -i inventory playbook.yml --syntax-check
```
おかしいと言われる場所が、該当の行でないことが多いです。「おかしいなぁ」と思ったら、直後の行等を調べると良いと思います。
Vue3 の nextTick は何か

## DOM の更新は非同期に行われる

Vue は 3.x, 2.x に関わらず、非同期に DOM 更新を実行しています。
DOM 更新が非同期であることは、以下の例で確認することができます。

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app"></div>
  <script>
    const { createApp, nextTick } = Vue

    const App = {
      template: `
          <div ref="sample">
            {{ msg }}
          </div>
      `,
      data() {
        return {
          msg: 'initial value'
        }
      },
      mounted () {
        this.msg = 'mounted value'
        console.log('mounted', this.$refs.sample.innerText)
        // mounted initial value
      }
    }
    createApp(App).mount('#app')
  </script>  
</body>
</html>
```

`this.msg = 'mounted value'` によって DOM 更新が必要なデータ更新をしていますが、直後に実行される `console.log` では、DOM 更新前のデータが出力されています。DOM 更新が同期的なら `console.log` では、`mounted value` が出力されるはずです。
**DOM 更新後のデータを確認するためには、DOM 更新をする非同期関数の実行後である必要があります。**

`nextTick` は、**DOM 更新をする非同期関数を全て実行した後に、第1引数として渡された関数を実行します。**そのため、`nextTick` に渡した関数で DOM を確認すると、DOM が更新されていることが確認できます。

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app"></div>
  <script>
    const { createApp, nextTick } = Vue

    const App = {
      template: `
          <div ref="sample">
            {{ msg }}
          </div>
      `,
      data() {
        return {
          msg: 'initial value'
        }
      },
      mounted () {
        this.msg = 'mounted value'
        nextTick(() => {
          console.log('nextTick', this.$refs.sample.innerText)
          // nextTick mounted value
        })
      }
    }
    createApp(App).mount('#app')
  </script>
</body>
</html>
```

`console.log` では、DOM 更新後のデータが出力されています。


## nextTick を実装してみる

稀なケースを除き、基本的には **DOM 更新をする非同期関数を全て実行した後に、DOM を確認すれば、DOM 更新後のデータを確認することができます。** これはとても簡単で、DOM 更新をする非同期関数より後に実行される非同期関数を実行し、その実行後に DOM を確認するだけです。

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
  <div id="app"></div>
  <script>
    const { createApp, nextTick } = Vue

    const App = {
      template: `
          <div ref="sample">
            {{ msg }}
          </div>
      `,
      data() {
        return {
          msg: 'initial value'
        }
      },
      mounted () {
        const self = this

        this.msg = 'mounted value'
        Promise.resolve().then(() => {
          console.log('promise', self.$refs.sample.innerText)
          // promise mounted value
        })
      },
    }
    createApp(App).mount('#app')
  </script>
</body>
</html>
```

DOM 更新をする非同期関数より後に実行される非同期関数は、`Promise` で実装します。とても簡単ですが、DOM 更新後のデータが `console.log` で出力されていることが確認できます。


## まとめ

nextTick について荒くまとめました。
もっと nextTick を理解するには、イベントループ、マクロタスク、マイクロタスクについて理解を深めることが大切です。これらについて知りたい場合、以下の URL は良い助けになると思います。

https://javascript.info/event-loop#macrotasks-and-microtasks
https://www.youtube.com/watch?v=8aGhZQkoFbQ
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
Nano editor 基本ショートカット

# あらすじ

CUIのテキストエディターである「[GNU nano](https://www.nano-editor.org/)」のショートカットです。`M-`の意味さえ思い出せば何とでもなりそうですね。

# 添え言葉

GNU nano は、vi、vim と違い、デフォルトで**ショートカットキーが下部**に表示されるので、CUIエディターの中でもダントツにラクです。「基本的に **Vscode 使い**なので、CUIで編集作業なんてしない！」という人向けではないでしょうか。

また、MacOSや多くの最新Linuxでは**プリインストール**されています。さらに、Windowsにインストールすることもできます。

# 行番号

特に重要な起動オプションが`-l`です。nanoの起動時に`-l`を付けると**行番号**が表示されます。**行数の多いものを編集する場合**に重宝します。

##### 実行例

```
sudo nano /etc/xxx/yyy.conf
```

また、毎回起動オプションを付けるのが面倒であれば、設定ファイルの`#set linenumbers`のコメントアウトを解除するといいです。

Debian系の場合、設定ファイルは`/etc/nanorc`にあります。

# 基本

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134703/0ad09fde-8889-235f-a6d4-727cf5015aa8.png)

# ショートカット一覧

| 表示 | 日本語 | Windowsキーボード |解説
|:-:|:-:|:-:|:--|
| ^G  | ヘルプ  | `Ctrl`+`G`  |ヘルプを表示します
| ^X | 終了  | `Ctrl`+`X`  |エディターを終了します
| ^R  | 読み込み  | `Ctrl`+`R`  |ファイル名を指定して読み込みます
| ^O  | 書き込み  | `Ctrl`+`O`  |ファイル名を指定して書き込みます
| ^\  | 置換 | `Ctrl`+`\`  |置換モードになります
| ^W  | 検索  | `Ctrl`+`W`  |検索モードになります
| ^U  | 貼り付け  | `Ctrl`+`U`  |カーソル位置に文字列または行を貼り付けます
| ^K  | 切り取り  | `Ctrl`+`K`  |選択範囲の文字列または行を切り取ります
| ^T  | スペル確認  | `Ctrl`+`T`  |
| ^J  | 均等割付  | `Ctrl`+`J`  |
| ^_  | 行を指定  | `Ctrl`+`_`  |行を指定してジャンプします
| ^C  | カーソル位置  | `Ctrl`+`C`  |列を指定してジャンプします
| M-U  | Undo  | `Alt`+`U`  |ひとつ前の状態に戻します
| M-E  | Redo  | `Alt`+`E`  |今の作業をもう一度行います
| M-6  | コピー  | `Alt`+`6`  |選択範囲の文字列をコピーします
| M-A  | マーク  | `Alt`+`A`  |選択範囲を作ります
| ^Q  | 検索（後方へ）  | `Ctrl`+`Q`  |単語を検索します
| M-]  | 対の括弧へ  | `Alt`+`]`  |対になる括弧までジャンプします
| M-W  | 次へ  | `Alt`+`W`  |次のページへ移動します
| M-Q  | 前へ  | `Alt`+`Q`  |前のページへ移動します
| ^F  | 進む  | `Ctrl`+`F`  |カーソルを１文字分だけ進めます
| ^B  | 戻る  | `Ctrl`+`B`  |カーソルを１文字分だけ戻します
| ^→  | 次の単語  | `Ctrl`+`→`  |カーソルを次の単語へ進めます
| ^←  | 前の単語  | `Ctrl`+`←`  |カーソルを前の単語へ戻します




::: note
<code>M-</code> は、<code>Meta</code>の略だそうです。
:::

# まとめ

もっと詳しく知りたい場合は、`man nano`です。

**Excelsior!**
Openframeworksで視線推定する

#はじめに
大学の研究で視線推定について勉強したので、記録として残しておきます。

#目次
1. 開発環境
2. 


#開発環境
使用した環境は以下の通りです。
Openframeworks0.11.0
addon:ofxOpenCV, ofxCV, ofxFaceTracker2
OpenCV 4.5.1

#顔検出
OpenCVのDNNモジュールを使って顔検出をします。
初めに、oFでファイルを読み込みます。

```
prototxt = "/ファイルのパス/deploy.prototxt";
    model = "/ファイルのパス/res10_300x300_ssd_iter_140000_fp16.caffemodel";
faceDetection = cv::dnn::readNetFromCaffe(prototxt, model);
```

#顔の特徴点検出

#視線推定

#参考文献
スマートデバイスプログラミング②（ランダムにカードを出して得点を競うゲーム）

UnityとGameCanvasのダウンロード

１：UnityHubをDLしてインストール。（一部のwindows環境では拡張子を.exeに変更する必要があります）

２：UnityHubを起動して、Unity2019.3.11f1をインストール。

３：GameCanvasのダウンロード
https://github.com/sfc-sdp/GameCanvas-Unity/
でGameCanvasをダウンロード

Game.csの編集

Assets内のGame.csを別エディタで編集

```c#

using Sequence = System.Collections.IEnumerator;

/// <summary>
/// ゲームクラス。
/// </summary>
public sealed class Game : GameBase
{
    // 変数の宣言
    int money;
    const int CARD_TYPE = 10;
    int[] card_count = new int [CARD_TYPE];
    string[] card_name =
         {"A","B","C","D","E","F","G","H","I","J"};
    bool isComplete;
    int new_card ;

    /// <summary>
    /// 初期化処理
    /// </summary>

    ///起動時に一回だけ呼ばれる・・初期化設定用
    public override void InitGame()
    {
      resetValue();
    }

    /// <summary>
    /// 動きなどの更新処理
    /// </summary>

    //１フレームごとに呼ばれる・動きの処理を入れる
    public override void UpdateGame()
    {
        //タップした時の処理
        if (gc.GetPointerFrameCount(0)==1 && ! isComplete) {
             money -= 100;
             if (gc.Random(0,3)==0){
             new_card = gc.Random(0,4);
           }else{
             new_card = gc.Random(5,9);
           }
             card_count[new_card]++;


           for (int i = 0; i < 5; i++) {
             if (card_count[i] > 4){
               isComplete = true;
             }
           }
        }
        //長押しした時の処理
        if(gc.GetPointerFrameCount(0) >= 120){
          resetValue();
        }
    }

    /// <summary>
    /// 描画の処理
    /// </summary>

    //１フレームごとに呼ばれる・描画の処理
    public override void DrawGame()
    {
      gc.ClearScreen();
      gc.SetColor(255,0,0);
      gc.SetFontSize(36);
      gc.DrawString("money:"+money,60, 40);

      if(new_card >= 0){
        gc.DrawString("new:"+card_name[new_card],60, 80);
      }

      for(int i=0 ; i< CARD_TYPE ; i++){
        gc.DrawString(card_name[i] + ":" + card_count[i],60, 120+i*80);
      }

      if(isComplete ){
        gc.DrawString("complete!!",60, 920);
      }

    }
    void resetValue(){
      money = 10000;
      for (int i = 0; i < CARD_TYPE; i++) {
        card_count[i] = 0;
      }
      isComplete = false;
      new_card = -1;
    }
}
```
【Macでcronを使ってNode.jsプログラムを定期実行させるまで】

cronせっかく勉強したのに、Macだとlaunchd使いましょうとかいわれてなんやそれってなってます。
***
**フルディスクアクセスにターミナル.appと、crontabを追加する。**

１，フルディスクアクセスにcrontabを追加
「システム環境設定」→「セキュリティとプライバシ」→「フルディスクアクセス」で鍵を解除 →「+」→「command + shift + G」で /usr/bin/cron/ を入力して開く → crontabを選択して開く

２，フルディスクアクセスにターミナル.appを追加
１と同じように、アプリケーション/ユーティリティ/を開く → ターミナル.appを選択して追加

ここまで行えば、cronを実行できるようになる
***
**crontabにcron文を記述する**

**cronの操作**
crontab -e でvimなどで開ける
crontab -l で記入したcron文一覧を見れる

**cron文**
毎日10時10分にnode ~といったnode.jsファイルを自動実行したい場合

```bash
10 10 * * * /Users/~/.nodebrew/current/bin/node /Users/~/programming/Nodejs/sample.js>>error.txt

#分 時 日 月 曜日 nodeコマンドのフルパス 実行したいjsファイルのフルパス
```

・nodeコマンドのフルパスは`which node` とterminalに入力するだけ
・>>error.txtとすると、jsならconsole.log()での出力内容を取得したtextファイルを作成できる。

これで指定した時間に指定したファイルを実行できる
***
**cronを実際に動かしてみてハマったときに確認したこと。**
・cronに設定したPATHは合っているか
・logは出力できているか
・logはどこまで出力されているか→原因の場所特定

→結果 .envファイルを読み込むdotenvモジュールのファイルパスが相対パスになっていたことが問題だった。

```jsx
require('dotenv').config() //動かなかったコード

require('dotenv').config({ path: '/Users/~/JS/Nodejs/scraping/.env' })
```
***
**cronを止める**
cronを一時的に止めたい場合は、#でコメントアウトすればいい
photon ボイスチャット

# ボイスチャット
# 環境
OS : windows10 pro
Unity 2020.2.1f1
Photon2 ver 2.28.1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/e5f7352a-9619-563d-7017-ebf1636e6091.png)
Device : ASUS,Galaxys7

Phothon Voice ver 2.23.1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/233c3c68-b296-c0e9-df67-374dad7808ac.png)


#　音声サンプル
PhotonVoice/Demos以下の*.unityをひらく

DemoVoiceMinimal　最小サンプル
ProximityVoiceChat  近づいたときに通話ができる
DemoVoicePun-Scene　モデル表示、通話状態アイコンの表示

# 設定

通常のPUN2設定に加えてVoice用のIDも設定しておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/9d85a1fd-6298-1f29-90f4-129b1c460096.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/d8a75d01-1bd1-503e-7093-8f13fedb27b5.png)

Environmentの下に赤字のmissingが複数あるので削除しておく。

有効になれば[DemoVoicePun-Scene]において、PUNが音を認識したときキャラの上に吹き出しアイコンが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/bcd4ac20-7a2a-47ff-3f0c-f4025264a6c4.png)

# 遅延時間、音量

# 通話中の制御

```
[RequireComponent(typeof(PhotonVoiceView))]
public class PointersController : MonoBehaviour
{
//[SerializeField] 属性をつけていると、CS0649警告が出るようになった。消したい。
    #pragma warning disable 649
    [SerializeField]
    private GameObject pointerDown;
    [SerializeField]
    private GameObject pointerUp;
    #pragma warning restore 649

    private PhotonVoiceView photonVoiceView;
    private void Start()
    {
        this.photonVoiceView = this.GetComponent<PhotonVoiceView>();
    }

    private void Update()
    {
        this.SetActiveSafe(this.pointerDown, this.photonVoiceView.IsSpeaking);
        this.SetActiveSafe(this.pointerUp, this.photonVoiceView.IsRecording);
    }

    private void SetActiveSafe(GameObject go, bool active)
    {
        if (go != null && go.activeSelf != active)
        {
            go.SetActive(active);
        }
    }
}

```
スマートデバイスプログラミング①（制限時間内にクリックした回数を競争するゲーム）

UnityとGameCanvasのダウンロード

１：UnityHubをDLしてインストール。（一部のwindows環境では拡張子を.exeに変更する必要があります）

２：UnityHubを起動して、Unity2019.3.11f1をインストール。

３：GameCanvasのダウンロード
https://github.com/sfc-sdp/GameCanvas-Unity/
でGameCanvasをダウンロード

Game.csの編集

Assets内のGame.csを別エディタで編集

```c#


using Sequence = System.Collections.IEnumerator;

/// <summary>
/// ゲームクラス。
/// </summary>
public sealed class Game : GameBase
{
    // 変数の宣言
    int sec = 0;

    int time = 600;
    int score = 0;

    /// <summary>
    /// 初期化処理
    /// </summary>
    public override void InitGame()
    {
        // キャンバスの大きさを設定します
        gc.SetResolution(720, 1280);
    }

    /// <summary>
    /// 動きなどの更新処理
    /// </summary>
    public override void UpdateGame()
    {
        // 起動からの経過時間を取得します
        sec = (int)gc.TimeSinceStartup;

        time = time - 1;
        if(gc.GetPointerFrameCount(0)==1){
          if(time >= 0){
            score = score + 1;
          }
        }
        if(gc.GetPointerDuration(0) >= 2.0f){
          time =600;
          score =0;
        }
    }

    /// <summary>
    /// 描画の処理
    /// </summary>
    public override void DrawGame()
    {
        // 画面を白で塗りつぶします
        gc.ClearScreen();

        // 0番の画像を描画します
        gc.DrawImage(0, 0, 0);

        // 黒の文字を描画します
        gc.SetColor(0, 0, 0);
        gc.SetFontSize(48);
        gc.DrawString("この文字と青空の画像が", 40, 160);
        gc.DrawString("見えていれば成功です", 40, 270);
        gc.DrawRightString($"{sec}s", 630, 10);

        if(time >= 0 ){
          gc.DrawString("time:"+time,60,0);
        }
        else {
          gc.DrawString("finished!!",60,0);
        }
        gc.DrawString("score:"+score,60,60);
    }
}
```
【React】関数コンポーネントとクラスコンポーネント

# 関数コンポーネント（Function Components）
- TypeScriptでは関数コンポーネントの型は `React.FunctionComponent` インタフェースとして定義されている  
-> エイリアスとして定義されている `React.FC` を使用可能

```./components/Hello.tsx
import * as React from 'react';

// Hello コンポーネントの定義
export const Hello: React.FC = () => {
  return <h1>Hello</h1>
};
```

```index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Hello } from './components/Hello';

ReactDOM.render(<Hello />, document.getElementById('root'));
```

# クラスコンポーネント（Class Components）
- TypeScriptでは `React.Component` を継承し、 `render()` メソッドを実装する

```./components/Hello.tsx
import * as React from 'react';

export class Hello extends React.Component<Props> {
  public render(): JSX.Element {
    return <h1>Hello</h1>
  }
};
```

```index.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Hello } from './components/Hello';

ReactDOM.render(<Hello />, document.getElementById('root'));
```

# 関数コンポーネントとクラスコンポーネントの違い
## state（状態管理）とLifecycle methodを使用可能か
|| Hooks導入以前 | Hooks導入後 |
| --- | --- | --- |
| クラスコンポーネント | 使用可能 | 使用可能 |
| 関数コンポーネント | 使用不可 | 使用可能 |

# 関数コンポーネントとクラスコンポーネントのどちらを使用するべきか
## 結論
- 関数コンポーネントを推奨

## 理由
- コードを簡潔に書けるため
  - `this` を使う必要がなくなる
  - `constructor` `render` が不要になる
- 同一ロジックが混入しにくいため
  - ライフサイクルメソッドに分割する必要がない
【Swift】条件に当てはまるFirebaseのドキュメントを一括削除

条件に該当するドキュメントを削除するコード

```swift
    Firestore.firestore().collection("users").whereField("user_name", isEqualTo : "田中").getDocuments() { (querySnapshot, err) in
      if let err = err {
        print("Error getting documents: \(err)")
      } else {
        for document in querySnapshot!.documents {
          document.reference.delete()
        }
      }
    }
```
このコードの場合user_nameが田中と書かれたすべてのドキュメントが削除されます

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
【Swift】Firebaseで認証済みユーザーかどうか振り分ける処理

最初の画面を認証済みユーザーと新規ユーザーとで切り替えたい時の処理

```swift
import UIKit
import Firebase
import FirebaseUI

class LaunchViewController : UIViewController{
        
    override func viewDidLoad() {
        super.viewDidLoad()
        //ロードされるまでの初期画面（ロゴ画像、ナビゲーションバーなど）
        }
    }
    override func viewDidAppear(_ animated: Bool) {
        
        if Auth.auth().currentUser != nil {
            self.performSegue(withIdentifier: "sign", sender: nil)
            print(認証済みユーザー)

        } else {
            self.performSegue(withIdentifier: "nosign", sender: nil)
            print(新規ユーザー)
        }
    }
}

```

ポイントはAuth.auth().currentUser != nilのif文

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
'Int64Index' object has no attribute 'reshape'の解決法

#はじめに
オライリージャパンの「Pyhtonではじめる機械学習」のp.238にて，citibikeの時刻データをPOSIX時刻に変換するコードで以下のようなエラーが発生した．

```python
X = citibike.index.astype("int64").reshape(-1,1) //10**9
```

**エラー内容**

```python
AttributeError: 'Int64Index' object has no attribute 'reshape'
```

#解決法
以下のように元のコードに**values**を加えると解決できます．

```python
X = citibike.index.astype("int64").values.reshape(-1,1) //10**9
```

どうも自分の持っている書籍の版が古いらしく，おそらく修正前のやつであるっぽいですね．．．（いろいろとエラーが多いと感じる笑）
【Swift】Eurekaでボタンの表示・非表示の切り替え


まずはフォームを作成
ここでは簡略化のため表示・非表示を切り替えたいボタンのみ実装しています

```swift
    override func viewDidLoad() {
        super.viewDidLoad()
        form
        <<< ButtonRow("Button") {row in
            row.tag = "delete_row"
            row.title = "商品を削除する"
            row.onCellSelection{[unowned self] ButtonCellOf, row in
                self.delete()
            }
        }
    }

```
次に表示・非表示を切り替えるコード

```swift
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if let buttonRow = self.form.rowBy(tag: "delete_row") as? ButtonRow{
               if delete_state == true {
                   buttonRow.hidden = true
                   buttonRow.evaluateHidden()
               }
           }
    }

```

変数delete_stateは自分で条件に合わせて設定しましょう

## おすすめ情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
raw現像をjpgに転換、meta-data解析

### 初めに

rawpyとはカメラの現像を解析するpythonのパッケージです。そもそもc++のlibrawと同じものです。画像処理にはpythonでよく使うので、librawをpythonで利用できるため、rawpyを使うのはlibrawと同じ効果を貰える。

以下はraw現像の解析、やmeta-dataを獲得の方法少し紹介したいと思います。

### rawからjpgに転換
- python環境にインストール　

```
$ pip install rawpy
```

- コードに使用

```
import rawpy # インポート
import cv2
import os

path="X:\\photo_test"　# 現像のディレクトリとファイル名
raw_name_sony = "sony.ARW" 　
output_name= "output.JPG" 　
raw = rawpy.imread(os.path.join(path,raw_name_sony))　#現像入力
decoded = raw.postprocess()[:, :, [2, 1, 0]]
cv2.imwrite(os.path.join(path,output_name),decoded) # opencvでjpgを出力
```
rawpyで画像転換機能は使いやすいですが、```postprocess```には沢山のパラメータを提供されて、実際使用した時、自分の需要によって、パラメータを入力します。

以下はキャンプ工学さんからのパラメータ説明です：
[こちら](https://campkougaku.com/2019/11/27/rawpy2/)

##### 注意点
1. rawのサイズは出力のjpgサイズと不一致の場合はあるかもしれません。その原因はカメラの設定された比率はcmosのサイズと違い場合、カメラやパソコンの写真ビューワは一部のピクセル自動的にマスクされました。でも、rawに隠されたピクセルは保存しているので、```postprocess```で全部出力されることです。

2. rawpyで出力されたjpgとカメラ出力のjpgは不一致あるかもしれません。その原因の一つはカメラに設定したwhitebalanceやgammaなど```postprocess```との設定異なることです。デフォルトでrawを出力したら、正常に見た写真より暗いです。whitebalanceをfalseと設定すると、出力の写真は暗いです。

### 写真meta-dataの出力

写真にカメラ設定パラメータなどいろんな情報がありますので、pillowでmeta-data出力が出来ます。pillowはrawを入力できなので、カメラ出力のjpgでmeta-dataあるいはexifを獲得出来ます。

- pillow をインストール

```
pip install pillow
```

- pillowの導入

```
from PIL import Image
from PIL.ExifTags import TAGS
```

- exifを抽出、dictに記録

```
im = Image.open("X:\\photo_test\\DSC00406.JPG")
exif = im._getexif()

exif_table = {}
for tag_id, value in exif.items():
    tag = TAGS.get(tag_id, tag_id)
    exif_table[tag] = value

for i in exif_table:
    print(i,"----->",exif_table[i])
```
##### 注意点
画像のexifは失った場合もあります。トリミングやフォーマット転換してから再保存する時はexifの情報はピクセルと共に保存されていないことです。
iTerm+fish+tmuxの環境で突如Permission deniedと言われた話

無駄に時間費やしたので次に同じことが起きた時のために書き残す

# 起きたこと
いつも通り「勉強するぞー」と思いiTermを立ち上げたら
`error: creating /tmp//tmux-501 (Permission denied)`
と言われ，tmuxを起動しようとしても上記のエラー文がひたすら出てきた

# 考えられる原因
見たらわかる通り権限の問題．
ただ，前日まで普通に使えていたものが突如使えなくなるのはよくわからない

# 対処法
`$ sudo chmod 1777 /private/tmp`をターミナルで実行して再起動することで無事にtmuxが起動した．
詳しい原因はわかっていないのでわかり次第追記する．たぶんMacOSの自動更新がよくなかったんじゃないかと思ってる．
【Swift】Eurekaのボタンの色を変更する方法

SwiftのライブラリEurekaでボタンの色を変更する方法に苦戦したので残しておきます。

```swift
        <<< ButtonRow("Button3") {row in
                row.tag = "delete_row"
                row.title = "商品を削除する"
                row.onCellSelection{[unowned self] ButtonCellOf, row in
                    
                        self.delete()
                    
                }
        }.cellSetup() {cell, row in
                cell.backgroundColor = UIColor.white
                cell.tintColor = UIColor.red
        }

```
他にもalpha、window、backgroundviewなどがあります。

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
composer self-update のエラー

php artisan make:authが使えなくなって久しいです。
代わりとなるcomposer require laravel/uiを入力すると、次のようなエラーが出ました。

```
Warning from https://repo.packagist.org: You are using an outdated version of Composer. Composer 2 is now available and you should upgrade. See https://getcomposer.org/2
```
要はcomposerをver２にアップデートしてくださいということです。
composer self-update --2と打ったところ、またエラーが出ました。

```
[Composer\Downloader\FilesystemException]                                                                                    
  Filesystem exception:                                                                                                        
  Composer update failed: "C:\ProgramData\ComposerSetup\bin\composer.phar" could not be written.                               
  rename(C:\ProgramData\ComposerSetup\bin/composer-temp.phar,C:\ProgramData\ComposerSetup\bin\composer.phar): ANZX  
  ܂B (code: 5)
```
リネームしろと言われていますが、その部分は無視してもできました。
今回注目したのは "C:\ProgramData\ComposerSetup\bin\composer.phar" could not be written.   の部分です。
書き込みができませんでしたということなので、書き込みができるようにします。

#プロパティのアクセスを変更
ローカルの  C:\ProgramData\ComposerSetup\bin\composer.phar　にアクセスし、右クリックします。
プロパティを選択すると、「セキュリティ」というタブが出てきます。
そのタブの下部にある「詳細設定」をクリックしてください。
詳細設定を押すと、プリンシパルごとにアクセス許可が表示されます。
そのほとんどのアクセス権限がフルコントロールだったのですが、ひとつ違うものになっている箇所があったので編集してフルコントロールにします。

OK、OKでプロパティを閉じたらPowerShellに戻って

```
composer self-update --2
```
できました。
ROS2よく使うコマンドメモ


ROS2開発でよく使いそうなコマンドを自分用にメモ

(2023/01/09 更新　ROS2 Humble対応)


# パッケージを作成

C++

```bash
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake <package_name>
```

Python

```bash
$ cd ~/ros2_ws/src
$ ros2 pkg create --build-type ament_python <package_name>
```

https://index.ros.org/doc/ros2/Tutorials/Creating-Your-First-ROS2-Package/


# パッケージのビルド

```bash
cd ~/ros2_ws
colcon build --symlink-install
```

--symlink-installオプションを付けるとpythonファイルやlaunchファイルを編集した後に毎回colcon buildを実行しなくてもよくなる。

https://docs.ros.org/en/foxy/Tutorials/Colcon-Tutorial.html


特定のパッケージだけをビルド

```bash
colcon build --packages-select <package_name>
```

# パッケージの依存関係を解決

```bash
rosdep install -i --from-path src --rosdistro <distro> -y
```

例）

```bash
rosdep install -i --from-path src --rosdistro humble -y
```

# rqt_graphを見る

```bash
rqt_graph
```

これはROS1と同じ


# TFツリーを見る

### rqt_tf_tree

ROS1と使い方は同じ
rqtを開いてpluginから起動するか以下のコマンドで起動する

```bash
ros2 run rqt_tf_tree rqt_tf_tree
```



インストールされていない場合以下でインストールする

```bash
 sudo apt install ros-humble-rqt-tf-tree
```

### pdfで保存する場合

以下を実行　
実行したディレクトリに.pdfファイルが作られる
```bash
ros2 run tf2_tools view_frames
```




# TFの情報を表示

```bash
ros2 run tf2_ros tf2_monitor 
```

実行例

```bash
RESULTS: for all Frames

Frames:
Frame: base_footprint, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
Frame: base_link, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
Frame: base_scan, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
Frame: caster_back_link, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
Frame: imu_link, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
Frame: wheel_left_link, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
Frame: wheel_right_link, published by <no authority available>, Average Delay: 1.6154e+09, Max Delay: 1.6154e+09
```




# colcon_cd コマンド

ROS1 のroscdにあたるコマンドがないのでこちらを使用

~/.bashrcにスクリプトを追加

```bash
echo "source /usr/share/colcon_cd/function/colcon_cd.sh" >> ~/.bashrc
echo "export _colcon_cd_root=~/" >> ~/.bashrc
source .bashrc
```


使用例

```bash
colcon_cd turtlebot3
```

ROS2 ワークスペース以下のパッケージがあるディレクトリに移動します。

https://docs.ros.org/en/foxy/Tutorials/Configuring-ROS2-Environment.html#add-colcon-cd-to-your-shell-startup-script
【Swift】WKWebViewをコードだけで使い回す

SwiftでUITableViewのセルごとに異なるウェブサイトに遷移させたい時に便利な使い回しコード。

まずは使い回すclassを指定

```swift

import UIKit
import WebKit

class WebView : UIViewController, WKUIDelegate{
    
    var webView : WKWebView!
    var request_url : URL?
    
    override func loadView(){
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url = self.request_url
        let request = URLRequest(url: url!)
        webView.load(request)
    }
}
```

後はtableviewのcellごとにURLを指定するだけ。

```swift
if indexPath.section == 1 {
            if indexPath.row == 0 {
                //チュートリアル
                let vc = WebView()
                vc.title = "チュートリアル"
                vc.request_url = URL(string: "https://sampe.com/tutorial/")
                self.navigationController?.pushViewController(vc, animated: true)
                
            }
            if indexPath.row == 1 {
                //アプリの使い方
                let vc = WebView()
                vc.title = "アプリの使い方"
                vc.request_url = URL(string: "https://sampe.com//use/")
                self.navigationController?.pushViewController(vc, animated: true)
                
            }
            if indexPath.row == 2 {
                //よくある質問
                let vc = WebView()
                vc.title = "よくある質問"
                vc.request_url = URL(string: "https://sampe.com/question/")
                self.navigationController?.pushViewController(vc, animated: true)
            }
以下略

```


## おすすめ情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html