OmniAICreator/Qiita-1.07M huggingface dataset:
TMCで取得したあるクラスタのバックアップを他のクラスタで利用する

TMCであるクラスタで取ったバックアップを別のクラスタで使う方法を調べた時のメモ。
なお、ここではクラスタの情報が消えた時などを考慮して通常手順であるData Protectionの「RESTORE FROM ANOTHER CLUSTER」に頼らないやり方となっている。（要は変則的）

## TMCのバックアップの仕様
Veleroを使ってバックアップしているのだが、どこにバックアップを保存しているかというと、S3のバケット直下ではなく、階層を掘ってバックアップしている。

MinIOに保存したバックアップをmcコマンドで見てみる。
なお、バックアップはvelero-backupというバケットに保存している。
```
$ mc ls -r tmc-backup
[2023-02-16 19:56:59 JST]    29B STANDARD velero-bucket/01GR5GP72MF984ND40JTWNW6FG/backups/test-backup-tmc/test-backup-tmc-csi-volumesnapshotclasses.json.gz
[2023-02-16 19:56:59 JST]    29B STANDARD velero-bucket/01GR5GP72MF984ND40JTWNW6FG/backups/test-backup-tmc/test-backup-tmc-csi-volumesnapshotcontents.json.gz
[2023-02-16 19:56:58 JST]    29B STANDARD velero-bucket/01GR5GP72MF984ND40JTWNW6FG/backups/test-backup-tmc/test-backup-tmc-csi-volumesnapshots.json.gz
：（省略）
```
階層を書くと以下のような感じになる。
```
velero-bucket/
└── 01GR5GP72MF984ND40JTWNW6FG/
    ├──backups/
    |  └── test-backup-tmc/
    ├──restic/
 ：（省略）
```

`01GR5GP72MF984ND40JTWNW6FG`というのが恐らくクラスタ固有につけられた名前で、複数のクラスタが同じバケットにバックアップした際、バックアップオブジェクトが衝突するのを防ぐためにこのようなハッシュ値的な名前をつけているものと思われる。
これはkubernetes内では`backupstoragelocations`リソース(略称bsl)で管理されており、以下で確認することが出来る。
```
$ kubectl get bsl -n velero
NAMESPACE   NAME                   PHASE       LAST VALIDATED   AGE     DEFAULT
velero      imurata-h2o-location   Available   4s               2m49s
```
これの中身を見ると、このようなものが見つかる。
```yaml
  objectStorage:
    bucket: velero-bucket
    prefix: 01GR5GP72MF984ND40JTWNW6FG/
```
ここでバケットの名前とパスを管理している。

## TMCで別クラスタのバックアップを利用する
クラスタAとクラスタBで同じTarget Locationを設定してもそれぞれのバックアップは見えない。
これは前述の通りで、
- クラスタAのバックアップ保管先：velero-bucket/01GR5GP72MF984ND40JTWNW6FG/
- クラスタBのバックアップ保管先：velero-bucket/01GSCZS4K72YXZ19CQC07B8TG2/

といった感じでクラスタごとに暗黙的に階層が掘られているからである。
なので、クラスタBの`01GSCZS4K72YXZ19CQC07B8TG2`をクラスタAのものに書き換えてしまえばよい。
クラスタBで`kubectl edit bsl -n velero <Target Location名>`を実行して`spec.objectStorage.prefix`をクラスタAのものに変更して保存する。
保存後、`kubectl get bsl -n velero`で`LAST VALIDATED`が1周するのを待つ（最大1分）。
```
$ kubectl get bsl -n velero
NAME                   PHASE       LAST VALIDATED   AGE     DEFAULT
imurata-h2o-location   Available   52s              3h58m
```
1周したら、TMC側でバックアップが見えるようになっていることが確認できる。
![1676627400733.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/376af0ee-dcbf-ad5e-344a-f9742d9ca283.png)
plunkerでdeck.gl その9

# 概要
plunkerでdeck.glやってみた。
heatmapLayer、使ってみた。

# 参考にしたページ

https://qiita.com/syanseto/items/e074d0f5bb92c51f05dc


# サンプルコード

```

const tileLayer = new deck.TileLayer({
  data: "https://c.tile.openstreetmap.org/{z}/{x}/{y}.png",
  minZoom: 0,
  maxZoom: 19,
  tileSize: 256,
  renderSubLayers: props => new deck.BitmapLayer(props, {
    data: null,
    image: props.data,
    bounds: (({ west, south, east, north }) => [west, south, east, north])(props.tile.bbox),
  }),
});
const data = [
  {p: [141.3521727, 43.0620842], v: 1952356}, // sapporo
  {p: [140.8677736, 38.2686018], v: 1082159}, // sendai
  {p: [139.5196066, 35.4937089], v: 3724844}, // yokohama
  {p: [136.9043778, 35.1814347], v: 2295638}, // nagoya
  {p: [135.7696242, 35.0118413], v: 1475183}, // kyouto
  {p: [135.5023064, 34.6936616], v: 2691185}, // oosaka
  {p: [135.1959010, 34.6894819], v: 1537272}, // koube
  {p: [132.4556497, 34.3849809], v: 1194034}, // hiroshima
  {p: [130.4017854, 33.5902214], v: 1538681}, // fukuoka
];
const scatterplotLayer = new deck.ScatterplotLayer({
  data,
  opacity: 0.5,
  getPosition: ({p}) => p,
  getRadius: ({v}) => Math.sqrt(v) * 12,
  getFillColor: ({v}) => [Math.sqrt(v) / 10, 20, 60],
});
const OPTIONS = ['intensity', 'radiusPixels', 'threshold', 'opacity'];
const options = {};
OPTIONS.forEach(key => {
  const value = document.getElementById(key).value;
  document.getElementById(key + '-value').innerHTML = value;
  options[key] = Number(value);
});
const heatmapLayer = new deck.HeatmapLayer({
  data: data,
  id: 'heatmp-layer',
  pickable: false,
  getPosition: ({p}) => p,
  getWeight: 1,
  radiusPixels: 30,
  intensity: 2.5,
  threshold: 0.1,
  opacity: 0.3,
  ...options
});
const deckgl = new deck.Deck({
  initialViewState: {
    longitude: 137,
    latitude: 37,
    zoom: 5,
    minZoom: 2,
    maxZoom: 8,
    pitch: 30,
    bearing: 10,
  },
  controller: true,
  layers: [tileLayer, scatterplotLayer, heatmapLayer, ]
});




```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c28af6db-9f29-bbaa-f912-f56ebfe487e7.png)


# 成果物

https://embed.plnkr.co/plunk/YJHXVLoI9lVVGAns


以上。
『ABC081A	Placing Marbles』AtCoderをRubyで解説！

# 正解の解答例
```
s1,s2,s3 = gets.split("").map(&:to_i)
 
puts s1 + s2 +s3
```

問題の入力例で、１桁の数字をスペースを空けずに入力するよう指定されているため、split("")としている。
１桁の数字なら例えば101と入力画面で入力すれば[1,0,1]の配列として作成可能。その後mapメソッドで数値オブジェクトに変換。

あとはputsで合計を出力して終わり！

# おまけ
出力でprint "#{}"を使用している方がいらっしゃったので念の為確認。
puts p は改行があり
printは改行がない

ちなみにpメソッドはオブジェクト情報も出力される。（文字列なら""に囲まれた状態で、数値ならそのまま出力される。）

■参考元
https://yukimasablog.com/ruby-print-puts-p
Leetcode 530. Minimum Absolute Difference in BST

https://leetcode.com/problems/minimum-absolute-difference-in-bst/

## アプローチ
### DFS

```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    public int result = Integer.MAX_VALUE;
    public ArrayList<Integer> list;
    public int getMinimumDifference(TreeNode root) {
        list = new ArrayList<>();
        dfs(root);
        return result;
    }

    public void dfs(TreeNode node) {
        list.add(node.val);
        if (node.left != null) {
            for(int i = 0; i < list.size(); i++){
               result= Math.min(  Math.abs(list.get(i) - node.left.val) , result);
            }
            
            dfs(node.left);
        }
        if (node.right != null) {
            for(int i = 0; i < list.size(); i++){
                result= Math.min(  Math.abs(list.get(i) - node.right.val) , result);
            }
            dfs(node.right);
        }
    }
}
```
viewDidLoadって結局なに？

# はじめに
iOS開発を始めてすぐに出会う、これ。
```swift
override func viewDidLoad() {
    super.viewDidLoad()
}
```

最初から書いてありますが、これはなんなのか。

そして、iOS開発をある程度進めてみると、`viewWillAppear()`ってのも出てきます。これも一体なんなんだ。

これらを理解するためには、**ライフサイクル**というものを知らなくてはなりません。

# ライフサイクルとは
さきほどの`viewDidLoad()`は、**画面の読み込みが終了した時**に呼び出されるメソッドです。
当たり前ですが、画面それぞれに「画面の読み込み」や「画面の表示」、「画面の破棄」などが存在します。

これら、**画面の表示から破棄までの一連の状態変化のこと**をライフサイクルといいます。文字通り画面の一生というわけです。

また、画面にライフサイクルがあるならアプリ自体にもライフサイクルがありますが、本記事では割愛します。`AppDelegate`などについて調べてみると、分かってくることがあるかと思います。

# 画面のライフサイクル一覧

さて、画面のライフサイクルを列挙してみましょう。

**1. loadView**
**2. viewDidLoad**
**3. viewWillAppear**
**4. updateViewConstraints**
**5. viewWillLayout**
**6. viewDidLayout**
**7. viewDidAppear**
**8. viewWillDisappear**
**9. viewDidDisappear**

ひとつずつ見ていきましょう。

## 1. loadView
**最初に画面を読み込む際の処理がここになります**。このとき、view自体の大きさなども決まる上、関連付けされたUIパーツなども読み込まれていきます。
`super.loadView()`が終わった後ならviewの背景色などのプロパティを変更できるということになりますね。

ここで、overrideするときに`super.loadView()`をしないと画面が真っ黒になります。（overrideしているので当たり前ですが。）気をつけましょう！

## 2. viewDidLoad
最初から記入されている子ですよね。**画面の読み込みが終わった時の処理がここで書かれます**。前述の通り、画面の背景色だったり、関連付けされたUIパーツを角丸にしたりなどの処理がここで行えます。

ちなみに、今後のライフサイクルにおいてもですが、自分でコードを書く際にはoverrideをすることになります。loadViewだけは特別ですが、それ以外は処理が始まる前後に呼び出される子たちなので例えば`super.viewDidLoad()`と書かなくても基本的にバグは起こりません。しかし、一定数のライブラリ（僕の経験上ではEureka）では、これを行わないとバグるものが存在しますので、書いておくことをおすすめします。

## 3. viewWillAppear
**画面が表示される直前に呼び出されます**。`viewDidAppear()`の次によく使う印象ですが、画面が表示される前に呼び出されるので、遷移先の画面から戻ってくる時にも呼び出されます。例えば表示するデータの取得などをここでするといいでしょう。

## 4. updateViewConstraints
**AutoLayoutがあれば、それを実行します**。これもoverrideするなら`super.updateViewConstraints()`をしてあげないと怒られます。

## 5. viewWillLayout & 6. viewDidLayout
UIViewは`layoutSubViews()`というメソッドを持つのですが、これの実行前と実行後に呼び出されます。

## 7. viewDidAppear
**画面が表示された直後に呼び出されます**。画面のアニメーションやアラートなどをここで呼び出すといい感じでしょう。

## 8. viewWillDisappear & 9. viewDidDisappear
もうわかると思いますが、**画面が遷移する直前と完全に遷移した直後によびだされます**。僕はよくtimerのinvalidateを（念の為）ここで行います。

注意点として、segueがPresent ModallyでpresentationがSame As Destinationなどの時、要するに遷移元の画面が裏にちょっとだけ見えるような遷移の場合、**これらは呼び出されません**。呼び出したければPresentationをFull Screenにするなどすればいいでしょう。

# まとめ
たまにライフサイクルを理解していないために起こしてしまうバグが存在しますので、どのタイミングでなにを使っていいのかをしっかりと確認しておきましょう。
Leetcode 783. Minimum Distance Between BST Nodes

https://leetcode.com/problems/minimum-distance-between-bst-nodes/

## アプローチ
### DFS

```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int result = Integer.MAX_VALUE;
    public ArrayList<Integer> list;

    public int minDiffInBST(TreeNode root) {
        list = new ArrayList<>();
        dfs(root);
        return result;
    }

    public void dfs(TreeNode node) {
        list.add(node.val);
        if (node.left != null) {
            for(int i = 0; i < list.size(); i++){
               result= Math.min(  Math.abs(list.get(i) - node.left.val) , result);
            }
            dfs(node.left);
        }

        if (node.right != null) {
            for(int i = 0; i < list.size(); i++){
                result= Math.min(  Math.abs(list.get(i) - node.right.val) , result);
            }
            dfs(node.right);
        }
    }
}
```
[laravel]Factoryの基本的な使い方とちょっと便利な使い方

## はじめに
laravelではテスト時など決まったデータなどが欲しい場合に自動で投入してくれるFactoryという機能がある。
今回はそのFactoryの基本的な使い方のおさらいと少し拡張した便利な使い方を書いていく。

## Factoryファイルを作成する
```terminal
$ php artisan make:factory Test
```
こんな感じで出ればOK
```
 INFO  Factory [database/factories/TestFactory.php] created successfully.  
```

作られたファイルを以下のような感じで書いていく
```
namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class UserFactory extends Factory
{
    /**
     * モデルのデフォルト状態の定義
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}
```

> 一番基本的な形式では、ファクトリはLaravelの基本ファクトリクラスを拡張し、definitionメソッドを定義するクラスです。
definitionメソッドは、ファクトリを使用してモデルを作成するときに適用する必要がある属性値のデフォルトセットを返します。

上記は公式ページからの引用だが、
原則`definition`メソッドの中にFactoryの処理を書いていく。
そうすることで、別のファイルから`Test::factory()->create()`などのコマンドが打たれたときに該当の箇所が呼び出される。
※以下でまたまとめる

### FactoryとModelの対応付けをする
Factory生成後はIlluminate\Database\Eloquent\Factories\HasFactoryトレイトを対象となるモデルクラスに読み込んであげる
```
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Test extends Model
{
    use HasFactory;
```


Factory側にも以下のような感じで書いてあげる。(マストではないのかな?)
```
class TestFactory
{
    protected $model = Test::class;
    //
}
```

### Factoryの呼び出し方
テストファイルやシーダーファイルに書いてあげることが多いが、
基本的に下記のように書いてあげる。
```
$test = Test::factory()->create(); // DBに追加する
```
複数作成する場合は
```
$test = Test::factory(2)->create();
```
などとしてあげる。


### 場合によってデフォルト値を変えたい場合
テストなどをするときに、デフォルト値以外の値を入れて確かめたい。という場合があるかもしれない。
そんなときに使えるのが、`state`。

> 状態変換メソッドは通常、Laravelの基本ファクトリクラスが提供するstateメソッドを呼び出す。
stateメソッドは、このファクトリ用に定義する素の属性の配列を受け取るクロージャを受け入れ、変更する属性の配列を返す必要がある。

```
/**
 * ユーザーが一時停止されていることを示す
 *
 * @return \Illuminate\Database\Eloquent\Factories\Factory
 */
public function suspended()
{
    return $this->state(function (array $attributes) {
        return [
            'account_status' => 'suspended',
        ];
    });
}
```

テスト実行時やSeederでなにかデータを投入するときなどにデフォルトの値から変えたいという場合にstateは使うことができる。
読み出す際は、Seederファイルから`Test::factory()->suspended()`という感じで呼び出すことができる。

## 参考
https://zenn.dev/fagai/articles/1ad4a85695c4f9
Fラン文系大学生がメガベンチャーに内定をもらった話

# はじめに
就活記録的な記事を書こうと思います。
この記事が誰かの原動力になれたら嬉しいです。

# 対象読者
- 文系だけどエンジニアになりたい人
- エンジニア志望の学生
- 就活に不安がある人

# 自己紹介
||||
|-|-|-|
|2017年3月|公立中学校|卒業|
|2017年4月|私立高校(全日制)|入学|
|2017年10月|私立高校(全日制)|退学|
|2017年10月|私立高校(通信制)|入学|
|2020年3月|私立高校(通信制)|卒業|
|2020年4月|私立大学(経済学部)|入学|
|2024年3月|私立大学(経済学部)|卒業予定|

こんな感じの学歴です。
通っている大学はFラン大学って調べると名前が出てくるくらいの偏差値です笑

私は大学に入学してからプログラミングと出会いました。
経済学部ですので、周りにはプログラミングをやっている友達などいません。
学習は書籍やインターネットを利用して独学で行いました。

最初に学習した言語はPythonでした。
理由は本屋に1番本があったからです。

当時はパソコンを持っていなかったので「[Pythonista](https://apps.apple.com/jp/app/pythonista-3/id1085978097)」というiOSアプリでPythonを勉強していました。

学習を進めていくと言語によって作れるものが変わってくるということを知りました。
モバイルアプリで動くものが作りたかった私は、iPhoneアプリが作れる「Swift」を学習することにしました。

この時にMacBookを購入しました。

最初はiPadアプリの「[Swift Playgrounds](https://apps.apple.com/jp/app/swift-playgrounds/id908519492)」を使用して学習しました。

1ヶ月くらい勉強して、初アプリである「[G-Search](https://apps.apple.com/jp/app/g-search/id1570395606)」をリリースしました。

初アプリリリースから1年半程度で13個のアプリをリリースしました。

https://qiita.com/SNQ-2001/items/8002961602ce9bfbb9b6

この1年半で4社のインターンシップに参加させていただきました。
2社は記事にしてあるので見てみてください。

https://qiita.com/SNQ-2001/items/3ffe607dc30267feb55f

https://qiita.com/SNQ-2001/items/eea4a640f6d799bf565f

以上、自己紹介でした。

# やってて良かったこと
### 個人開発
1人でサービスを形にできているという実績は大きいと思います。

個人開発をしているとユーザーとの関わり方も学ぶことができるのでかなりいい経験になります。

企画からデザインまで全て自分で行う必要があるので大変ですが、とても楽しいです。

(マネタイズが上手くいけば不労所得ゲットできます笑)

個人開発のことは別記事でも書いたので短めにしておきます笑

### Qiitaの毎日投稿
私は2022年4月18日〜現在まで10ヶ月間、毎日Qiitaに記事を投稿しています。

理由は2つあって、

1つ目は、備忘録です。
意外と忘れるので、記事として投稿することで、やり方を記録しています。

2つ目は、自分と同じことで困った人を助けたいからです。
私が初学者の時は教えてくれる人が周りにいなかったので、ネット記事が頼りでした。
私と同じような環境で学習してる人の助けになればと思い、記事として残しています。

初学者が見てわかるように、手順には番号を振って、スクショ付きで記事にするように心がけています。

### GitHubでの活動記録
毎日コードを書いてコミットする習慣をつけていました。
![github](https://user-images.githubusercontent.com/84154073/219011497-5958d7f0-6516-4c04-9675-b083e093447d.jpg)

年始から忙しくて何個か穴が空いちゃってるんですけど、なるべく草を生やすようにしていました。


# 就活面接で大切なこと
就活で大切なことは色々あると思いますが、私が実感したことは2つあります。

### 逆質問を考える
私は初めての本選考面接でやってしまいました。

「逆質問はありますか？」

「特にないです」

これは終わりですね笑

今の時代調べればなんでも出てくるので、「質問なんてないわ！！」と思っちゃいます。
しかし、なんとしてでも、5個は用意しておくべきです。

面接中の会話に沿った質問が良いのはもちろんなのですが、
面接中は緊張しているので質問なんて考えられません。
事前に準備しておくのが良いと思います。

質問を用意しようと思うと、自然と企業研究もできるので必ず準備しておくべきです。

### なぜその企業を選んだのかを言語化しておく
「就活の軸」と「企業の特徴」がどのようにマッチしてたのかをベースで組み立てると、説得力のあるものになると思います。
例えば、

技術的に成長できる環境があるか
→勉強会が頻繁に開催されていて技術的に成長できそう
→界隈の有名エンジニアが多数在籍していて吸収できることが多そう

働いていて楽しいかどうか
→モダンな技術を採用していてワクワクしながら開発できそう
→事業に幅広く関わることができて楽しそう

こんな感じです。

# おわり
振り返ってみると「行動する勇気」が最も重要な要素だと思います。
インターンシップに行く前はすごい不安だったりします。
周りが有名大学ばっかりで萎縮することもあります。
でも、自分は誰よりも努力してるし大丈夫という気持ちでどんどん行動しましょう
(未来の自分にも向けて)
Elixir 挑戦記 - 衛星データからNDVI算出

# Elixir 挑戦記

- 統合的アプローチによる学習
- とりあえず手を動かしてみるシリーズ
- 調べたり取り組んだりした内容をひたすら書いていく
- あとで整理してまとめたい

# やりたいこと

## 衛星データからNDVIを算出

### mixプロジェクトの作成

https://qiita.com/nishiuchikazuma/items/be911dd1d202c1227d19

https://elixir-lang.jp/getting-started/mix-otp/introduction-to-mix.html

https://elixirschool.com/en/lessons/basics/mix

### kmlの読み込み

https://github.com/socrata/exkml

### Tellus APIからのデータ取得~NDVI算出

https://qiita.com/RyoWakabayashi/items/c87fe1256bcd105d370c

Livebook -> exs へのエクスポートで適宜module化していきたい

## Phoenix + LiveViewで可視化

https://qiita.com/piacerex/items/6714e1440e3f25fb46a1

NDVIはjsonに吐き出して参照するなどして、プロジェクトをわけてもいいかも
## 開発環境構築

### dockerで構築

とりあえず必要そうなものは入れてしまう？

https://github.com/RyoWakabayashi/elixir-learning/blob/main/Dockerfile

Elixir自体やライブラリのインストールについて学ぶため、ubuntuで試してみるのもありか?

### リモートサーバの開発用コンテナで作業する

以下でお手軽接続

- VSCode
    - Remote Explorer
    - Dev Containers

### なるべく軽量化したい（後から)

以下が参考になりそう

https://zenn.dev/gr8distance/articles/f5590c87bbdd14

### デプロイも試してみたい

- [fly.io](https://fly.io/)
- [Gigalixir](https://www.gigalixir.com/)
module 

exportsは公開。
opensは非公開、reflectionのみ可能
requiresでモジュール取り込み

以下のサンプルは、
ParentProject side、opensでreflection可能し、Factoryを公開、
ChildProject side、requiresし、invoke。

なお、other-projectはnetbeansでbuild-timeに出力されるjarをお互いにbuild-pathにいれてある。これによりモジュールとして参照ができるようになる

```ParentProject/default-package.module-info.java
module ParentModule {
    opens parentproject to ChildModule;
    exports publicpackage;
}
```
```ParentProject/parentproject.ParentProject.java
public class ParentProject {
    public static void main(String[] args) {
        new ParentProject().method();
    }
    public void method() {
        System.out.println(" i am parentproject method");
    }
}
```
```ParentProject/publicpackage.Factory.java
public class Factory {
    public static ParentProject create() {
        return new ParentProject();
    }
}
```
```ChildProject/default-package.module-info.java
module ChildModule {
    requires ParentModule;
}
```
```ChildProject/chileproject.ChildProject.java
public class ChildProject {
   public static void main(String[] args) {
        Object o = Factory.create();
        try{
            Method m = o.getClass().getMethod("method");
            m.invoke(o);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
```
実行結果
```
 i am parentproject method
```
Laravel bladeからcontrollerへのルーティング

## はじめに
bladeタグに記載したformタグやaタグからcontrollerへのルーティングについて、なんとなく使ってしまっていたところがあったのでまとめておきます。

## bladeからのルーティング
下記のようなbladeとルーティングを考えます。
```php:hello.blade.php
<form method="POST" action="{{ action('GreetingController@hello') }}"></form>
<a href="{{ action('GreetingController@hello') }}"></a>
```
```php:web.php
Route::post('/hello', 'GreetingController@hello')->name('greeting.hello');
```
この場合、formのサブミット(リンクのクリック)によって、GreetingControllerコントローラーのhelloメソッドが実行されます。流れとしては

1. サブミットによって`action=""`や`href=""`に設定したURLへ遷移する。
2. web.phpに記載したルーティングのうち、1で指定したURLに一致するルーティングのコントローラのメソッドが実行される。

という形です。
つまり、`action=""`や`href=""`にはルーティング先に紐づくURLを指定すればよく、`action(…)`の部分はこのURLを作成してくれています。
実際に`action(…)`で作成された値を確認してみると`http://localhost/hello`となっていて、下記のようにこのURLを直接`action=""`や`href=""`に設定しても、同じようにルーティングされます。
```php:hello.blade.php
<form method="POST" action="http://localhost/hello"></form>
<a href="http://localhost/hello"></a>
```
ただ、実際に開発する際にはURLを直接書くことはなく、冒頭に使用した`action()`などのURLを生成するメソッドを使用します。このURLを生成するメソッドには、`action()`の他にも`route()`、`url()`などいくつか種類があります。

## 参考文献
[laravel formのrouteとactionによる処理の書き方](https://qiita.com/Yado_Tarou/items/6b3033ccc7c0e7ac6211#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)
[Laravel公式 URL生成](https://readouble.com/laravel/9.x/ja/urls.html)
【Einstein Bot】Bot の Version データをVSCode からデプロイするときの注意点

# はじめに

Einstein Bot のデータはメタデータとしてxml形式で取り組むことができます。そのため文言の修正はVSCode上でBotのバージョンファイルを編集することで可能となります。

そして編集したファイルをコマンドにてデプロイすることができます。ただしこのとき3つ注意するべきことがあります。今回はそれら注意点についてまとめました。

# デプロイでの注意点
## Botのバージョンファイルをデプロイするのではなく、バージョンを含むフォルダをデプロイする。

Botのバージョンファイルをコマンドにてデプロイする場合、次のようになります。

```jsx
sfdx force:source:deploy --sourcepath ./force-app/main/default/bots/Bot_test/v2.botVersion-meta.xml
```

しかしこれを実行すると次のようなエラーが出ます。

```bash
An object 'v2' of type BotVersion was named in package.xml, but was not found in zipped directory
```

正直よくわからないエラーですが、おそらくボットのバージョンは単体でデプロイすることができないためです。というのも変更セットでボットバージョンをデプロイする際は**その大元となるボットも一緒にリリースしなければなりません**。

そのためデプロイするときは**1つ上のディレクトリをデプロイする**必要があります。今回の場合次のようになります。

```jsx
sfdx force:source:deploy --sourcepath ./force-app/main/default/bots/Bot_test
```

## 有効なBotのバージョンが1つもあってはいけない。

デプロイする際に注意すべきことは**デプロイ先のBotに有効なバージョンがあってはいけないということ**です。1つでも有効化されているバージョンがある状態でデプロイを行うと下記のようなエラーが発生します。

```bash
Bot_test.v3  有効なボットバージョンは編集できません
```

先ほどのデプロイコマンドは結局全てのバージョンをリリースしようとしています。そのため対象のバージョンが有効化になってなくても他のバージョンが有効化されているとデプロイすることができません。よってデプロイ作業を行うときは全て無効化しましょう。

## デプロイにとても時間がかかる

これは作業を行うときの注意点です。某案件でバージョンファイルが18個ある状態で行ったところデプロイするのに**30分**かかりました。これはおそらくバージョンファイルが増えれば増えるほど時間がかかると考えられます。

そのため**作業を行う時は完了時間に注意が必要**です。

# 最後に
以上がBotデプロイ時の注意点になります。Einstein Bots に関しては他の製品と比べて日本語の情報が少ないので今後も継続的にナレッジを記事化していきたいと思います。
最後まで読んでいただきありがとうございました！
paizaラーニング レベルアップ問題集 新・Bランクレベルアップメニュー JavaScript 【マップの扱い 4】マップのナンバリング

【マップの扱い 4】マップのナンバリング (paizaランク B 相当)

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__grid_numbering

# 解説
問題文の図は、入力例1のH=4 W=4 D=1ではなく、
入力 H = 3, W = 4, D = 1 ~ 4なので、これでテストした方がよい。

問題文の図を見ながら、法則性を見つけて実装していく。

***

D=1のときは、ナンバリングのスタートが、0列目固定で、0行目、1行目、２行目と移り変わる。
H-1行までいったら行固定で、今度は1列目,2列目,3列目と移り変わる。

スタートから斜め右上にナンバリングしていく。行は-1、列は+1している。
斜めの最大移動数は、HかWのうち小さい方-1。
マップからはみ出ないようにして、ナンバリングする。

***
D=2の時は、

0行目固定、列全部ナンバリング、
1行目固定、列全部ナンバリング、
としていく。以下同様
***
D=3の時は、
0列目固定、行全部ナンバリング、
以下同様。
***
D=4の時は、ナンバリングのスタートが、
0行目固定で、0列目、1列目、2列目と移り変わる。
W-1列目までいったら、列固定で、今度は1行目、２行目と移り変わる。

ナンバリングは、スタートから左下にいく。行は+1、列は-1している。
D=1と同様に、最大の移動数はHかWのうち小さい方-1。
マップからはみ出ないようにして、ナンバリングする。

***

デバックは、入力例1~4において、D=1~4についても行うとより確実。

なお、ifで場合分けをしているが、switchでも可能。


# 解答例
変数について、iは行、jは列、aが斜めで使用するようにした。
```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");
//盤面の行数を表す整数 H , 盤面の列数を表す整数 W 
const [H, W, D] = lines[0].split(" ").map(Number);
//マップ
const S = Array(H).fill().map(row => row = Array(W).fill());

let num = 1;//ナンバリング用変数
if (D === 1) {
  //j=0,0<=i<H-1
  for (let i = 0; i < H; i++) { //i行
    //斜め右上に
    for (let a = 0; a < Math.min(H, W); a++) { //斜めa
      if (i - a >= 0 && 0 + a < W) { //マップ内
        S[i - a][0 + a] = num;
        num++;
      } 
    }
  }
  //i=H-1,1<=j<W
  for (let j = 1; j < W; j++) { //j列
    //斜め右上に
    for (let a = 0; a < Math.min(H, W); a++) { //斜めa
      if (H - 1 - 1 >= 0 && j + a < W) { //マップ内
        S[H - 1 - a][j + a] = num;
        num++;
      }  
    }
  }
  
} else if (D === 2) {
  for (let i = 0; i < H; i++) { //i行
    for (let j = 0; j < W; j++){ //j列
      S[i][j] = num;
      num++;
    }
  }
  
} else if (D === 3) {
  for (let j = 0; j < W; j++) { //j列
    for (let i = 0; i < H; i++) { //i行
      S[i][j] = num;
      num++;
    }
  }

} else if (D === 4) {
  //i=0,0<=j<W-1
  for (let j = 0; j < W; j++) { //j列
    //斜め左下に
    for (let a = 0; a < Math.min(H, W); a++) { //斜めa
      if (0 + a < H && j - a >= 0) { //マップ内
        S[0 + a][j - a] = num;
        num++;
      }
    }
  }
  
  //j=W-1,1<=i<H
  for (let i = 1; i < H; i++) { //i行
    //斜め左下に
    for (let a = 0; a < Math.min(H, W); a++) { //斜めa
      if (i + a < H && W - 1 - a >= 0) { //マップ内
        S[i + a][W - 1 - a] = num;
        num++;
      }
    }
  }
  
}

console.log(S.map(row => row.join(" ")).join(("\n")));
```
【保存版】viエディタの使い方&コマンド集



## viエディタとは
viエディタとはLinuxで使用される、
**テキストファイルを編集する**ためのツールです。

編集や保存など、ファイルの中身に対する操作を行うことが出来ます。

今回はこのツールの基本的な使い方とコマンドについてまとめていきます。




## viエディタの使い方
まずは以下のコマンドで編集したいファイルを開きます。

`$ vi <ファイル名>`

これで編集準備完了です。

（ちなみにこの時、存在しないファイル名を指定すると、新しいファイルが作成されますのでご注意ください。）

### モード切替

~~ややこしいことに~~、viエディタには2つのモードが存在します。

①**入力モード**　…テキストを直接編集する
②**コマンドモード**　…それ以外の操作全般

操作をするには、これらのモードを上手く使い分けていく必要があります。

モードの切り替え方法はシンプルです。

|モード切り替え  | |
|---|---|
|`i`|コマンドモード → 入力モードへ切り替える|
|`Escキー`|入力モード → コマンドモードへ切り替える|

先ほどの`$ vi <ファイル名>`でファイルを開いた段階では
**コマンドモード**になっていますので、`i`キーを押すことで**入力モード**に切り替わり、テキストの入力ができるようになります。

そして入力モード状態のときには`Escキー`を押すことで、
再び**コマンドモード**に切り替えることが出来ます。


### カーソルの移動

カーソル移動は、キーボードの矢印キー(↑)(↓)(←)(→)でも可能ですが、
コマンドモードのときは以下のコマンドでも移動をすることができます。

|カーソル移動| |
|---|---|
|O|行の先頭へ移動する|
|＄|行の末尾へ移動する|
|gg|ファイルの先頭行へ移動する|
|G|ファイルの最終行へ移動する|
|nG|n行目に移動|


- - -

## 操作別コマンド集

ここから先は、コマンドモード状態で使用できる操作についてまとめていきます。
これが全てではありませんが、知っていると便利そうなものを集めています。


#### 削除コマンド
|削除| |
|---|---|
|x|カーソル位置の文字を削除(Deleteキーでも可)||
|X|カーソル位置の手前の文字を削除(BackSpaceキーでも可)|
|dd|カレント行(現在カーソルがある行)を削除|
|:%d|全て削除|

#### コピー・貼り付けコマンド
|コピー・貼り付け| |
|---|---|
|yy|カレント行(現在カーソルがある行)をコピー|
|:%y|全選択してコピー|
|p|カレント行の下にコピー内容を貼り付け|
|P|カレント行の上にコピー内容を貼り付け|


#### 検索コマンド
|検索| |
|---|---|
|/ [検索したい文字列]|カーソル位置より後ろを検索|
|? [検索したい文字列]|カーソル位置より前を検索|
|n|次の検索結果の位置を表示|
|N|次の検索結果の位置を表示(逆方向)|
|:noh|候補のハイライト表示を解除|

#### 置換コマンド
|置換| |
|---|---|
|:%s/[文字列A]/[文字列B]|最初に見つかった文字列Aを文字列Bに置換|
|:%s/[文字列A]/[文字列B]/g|すべての文字列Aを文字列Bに置換|

#### 行番号表示コマンド
|行番号| |
|---|---|
|:set nu|行番号を表示|
|:set nonu|行番号を非表示|

#### 終了・保存コマンド
|終了・保存| |
|---|---|
|:q!|内容を保存せずに終了|
|:wq|内容を保存して終了|
|:w|上書き保存|
|:e!|最後に保存した内容に戻す|


### その他便利機能
viエディタ操作中の便利機能として以下のようなものもあります。

|その他機能| |
|---|---|
|:!<コマンド>|viを起動させたままコマンドの内容を実行|


例えばファイルを編集中、カレントディレクトリ(自分が今いるディレクトリ)のファイル一覧を確認したくなったとします。
この場合、一度編集を終了し`ls`コマンドで一覧を表示させるという方法もありますが、上記のコマンドを使うことで、エディタを終了させることなく手軽に一覧確認をすることが出来ます。

---

今回はviエディタの基本操作とコマンドについてまとめてみました。

新卒の頃から「とりあえずこれで何とかなりますように…」と書き溜めていたコマンドメモたちがお役に立てれば幸いです。


ありがとうございました！
【AWS/Python】Cloud9 環境で Lamda layer にアップロードするための zip を作成する

# Cloud9 環境で Lambda Layer にアップロードするための zip ファイルを作成する

こちらの記事は Zenn に移行しました。
[https://zenn.dev/ndjndj/articles/69a2aabb227530](https://zenn.dev/ndjndj/articles/69a2aabb227530)
【Rails+dynamodb-local】dynamodb-localのテスト環境をつくりたい

# はじめに
テスト環境を作る際に色々と詰まった点を簡単にまとめてみます。

dynamodb-localなどの構築はこちらの記事で行っています

https://qiita.com/does_not_exist/items/19c35639e466844e8b0e

# 詰まった点1：dynamodb-localのコンテナを開発用とテスト用に分ける？
結論から言うと1つにまとめました。
dynamoidで勝手にテーブルを作成してくれるので、コンテナを分けないと開発用とテスト用で同じテーブルを使用することになってしまうのではと思いました。しかし、helperでdynamoidの設定を作成することでこの問題を解決することができました。

# 必要な設定

```backend/spec/rails_helper.rb
require 'spec_helper'
require 'dynamoid'

略

Dynamoid.configure do |config|
  config.namespace = 'test'
  config.region = 'ap-northeast-1'
  config.endpoint = 'http://dynamodb-qiita-local:8000'
  config.credentials = Aws::Credentials.new('test', 'test')
end

略

  config.after :each, dynamodb: true do
    Dynamoid.adapter.list_tables.each do |table|
      # Only delete tables in our namespace
      Dynamoid.adapter.delete_table(table) if table =~ /^#{Dynamoid::Config.namespace}/
    end
    # tablesにテーブル情報が残っているので削除
    Dynamoid.adapter.tables.clear
    # Recreate all tables to avoid unexpected errors
    # テスト後にデータを削除したいのでコメントアウト、初期化でテーブルを作り直したい場合はコメントを外す
    # [Test].each { |m| m.create_table(sync: true) }
  end
end
```

・namespaceでtestと設定することで、テーブル名にtestが入るようになります
・delete_tableでテーブル名にnamespaceが含まれるものを削除しています
・エンドポイントはdynamodb-localのコンテナを指定しています
・credentialはダミー情報を設定しています
・テスト実行時にdynamoidの設定を反映するには`dynamodb: true`をrails_helper.rbとspecに記載する必要があります

```backend/spec/models/hoge_spec.rb
require 'rails_helper'

RSpec.describe Hoge, type: :model, dynamodb: true do
    略
end
```

# 詰まった点2：Dynamoid.adapter.tables.clearについて
テーブルを削除した後に実行している`Dynamoid.adapter.tables.clear`がなぜ必要なのか気になったので、公式ドキュメントでadapterについて調べてみました。
するとdelete_tableメソッド内でtablesを参照していました。
delete_tableを実行するとdbからテーブルは削除されるのですが、tablesにはテーブル情報が残ってしまうようです。
なので、Dynamoid.adapter.tables.clearは必要でした。

```dynamoid/lib/dynamoid/adapter.rb
    def delete_table(table_name, options = {})
      if tables.include?(table_name)
        benchmark('Delete Table') { adapter.delete_table(table_name, options) }
        idx = tables.index(table_name)
        tables.delete_at(idx)
      end
    end
```

https://github.com/Dynamoid/dynamoid/blob/c280f2d95c03fd971ca01823aa6c121ce6a7ff46/lib/dynamoid/adapter.rb#L20

# おわりに
これでテスト実行後にテストで作成したテーブルがdbから消えている状態になりました。
色々と詰まりましたが、良い勉強になりました。
19.擬似クラス




```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf8">
    <title>はじめてのCSS</title>
    <meta name="description" content="初めてCSSを勉強するサイトです。">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <ul>
        <li><a href="https://google.com" target="new">Google</p></li>
        <li><a href="https://www.yahoo.co.jp" target="new">Yahoo</p></li>
        <li><a href="https://www.apple.com" target="new">Apple</p></li>
    </ul>
    <h2>習い事ランキング</h2>
    <ol>
        <li>プログラミング</li>
        <li>水泳</li>
        <li>サッカー</li>
    </ol>
    
    <h2>学校の授業</h2>
    <ul>
        <li>国語</li>
        <li>算数</li>
        <li>理科</li>
        <li>社会</li>
    </ul>
</body>
</html>

```

``` style.css
ol li:first-child {
  color: red;
}

ul li:last-child {
  color: blue;
}
```
[C#].NET6でnullチェックからおさらば！

null合体演算子やnull条件演算子（オプショナルチェーン）によって多くのnullチェックから解放されたのは記憶に新しい。

```C#:1件以上のデータがある時に処理
if ( result?.list?.Length > 0 ) { // result?.list?.Any() の方が見やすいが、後々の説明の為にLengthを使用
	// 処理
}
```

しかし、```getData()```のような関数から取得した結果をチェックするような場合には、以下のように一度変数に入れてからnullチェックしている人もいるのではないだろうか。

```C#:昔ながらのnullチェック
using System;

string getData() => "abc";

var data = getData();
if (data != null)
{
	Console.WriteLine(data);
}
```

C#9(.NET5)では以下のように書ける。nullの場合は条件式がfalseで評価され、ifブロック内は実行されない。

```C#:パターンマッチング構文を使ったnullチェック
if (getData() is string data  ){
	Console.WriteLine(data);
}
```

但し、残念ながらdata変数のスコープは完全にはifブロック内に閉じていない。
ifブロックの外でdataを使おうとするとエラーになるが、様々な理由から、data変数自体はif文の外で定義されている形になっているようだ。
その為、上記のようなif文を連続で書いた場合、dataという名前の変数を何度も使うことはできない。
（このあたりの経緯については「埋め込みステートメント（embedded statements）」で検索すると詳細がわかる）

C#10(.NET6)からとなるが、IsNullOrEmptyに相当するチェックを行いたい場合には、次のようにLengthプロパティにパターンマッチングさせることで可能だ。
先ほどと同様に、nullの場合はfalseで評価される。

```C#:パターンマッチング構文を使ったnull or emptyチェック
if (getData() is { Length: > 0 } data  ){
	Console.WriteLine(data);
}
```

ちなみに、値を変数にキャプチャする必要がないならば、単純に次のように書ける。
```!string.IsNullOrEmpty(getData()) ```よりも読解しやすいように思う。

```C#:パターンマッチング構文を使ったnull or emptyチェック
if (getData() is not (null or "") ){
	Console.WriteLine("データがあります");
}
```

上記は取得されるデータが文字列の場合だったが、次のようにクラス型だった場合にももちろん使える。
nullチェックを書かなくてよいのがとても気持ち良い。

```C#:Person型を返すgetPerson()
Person getPerson() => new Person {Name = "Jun", Age = 5};

public class Person
{
	public string Name {get; set;}
	public int Age {get; set;} 
}
```

```C#:結果がnullでないときのみ変数pにキャプチャ

if (getPerson() is Person p ) {
	Console.WriteLine($"person is Age: {p.Age}");
}
```

文字列でLengthをチェックしたのと同様に、プロパティ値をチェックすることもできる。

```C#
if (getPerson() is { Age: > 3 } p ) {
	Console.WriteLine($"person is Age: {p.Age}");
}
```

上記ではPersonオブジェクト全体をpという変数にキャプチャしているが、Ageのみを変数ageにキャプチャすることもできる。
相変わらずnullチェックを書かずとも、nullはfalseになる。

```C#
if (getPerson() is { Age: > 3 and var age }) {
	Console.WriteLine($"person is Age: {age}");
}
```

ちなみにもし、```Person.Age``` が ```int``` ではなくNull許容型の ```int?``` で、```Age``` の nullチェックもしなければならないとしたらどうだろうか。

```C#
public class Person
{
	public string Name {get; set;}
	public int? Age {get; set;} // Null許容型
}
```

この場合、```Age```プロパティを```var age```ではなく```int age```で受ければ良い。
```var```で受けると```null```も受けてしまうが、```int```で受ければ```null```はマッチングしなくなる。

```C#
if (getPerson() is { Age: int age } ) { // int型でキャプチャする
	Console.WriteLine($"person is Age: {age}");
}
```

このパターンマッチングに慣れてくると、次のようなWhereメソッドも自然と書けるようになる。

```C#
// Age > 5のものを抽出。nullはもちろん除外してくれる。
var results = list.Where( p => p is { Age: > 5 } );
```

クエリ式だとこうなる。

```C#:クエリ式
var result = from p in list where p is { Age: > 5 } select p;
```

不要な ```!= null```からは積極的におさらばしつつ、上記のようなコードもすらすらと読めるようになっていきたい。
bindのsrttについて

## 概要
bindでフォワード先が複数ある場合、どこが優先されているのかを知りたい。
複数ある場合は問い合わせの結果が一番近いところになるが、どうやって管理しているのかが謎。
どうやらsrttという値によるらしいが、判断基準がわからないため検証する。
※ rtt(ラウンドトリップタイム）なので小さい方が良いと予想

## 設定
```
zone "amazon.com" IN {
        type forward;
        forward only;

        forwarders {
            1.1.1.1;
            8.8.8.8;
            123.123.123.123;
        };
};
```
1.1.1.1.と8.8.8.8は疎通できるが、123.123.123.123は不可


## 検証メモ

- 初回はcacheをクリア
- それぞれTTLが切れてからdigをする


**キャッシュクリア**
```
sudo rndc flush
```

**ダンプコマンド**
```
sudo rndc dumpdb
```


1回目
```
sh-4.2$ sudo cat /var/named/data/cache_dump.db | grep -e '1\.1\.1\.1' -e 8.8.8.8 -e 123.123.123.123
;       123.123.123.123 [srtt 30] [flags 00000000] [edns 0/0/0/0/0] [plain 0/0] [ttl 1791]
;       8.8.8.8 [srtt 3947] [flags 00004000] [edns 1/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1791]
;       1.1.1.1 [srtt 1379] [flags 00004000] [edns 1/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1791]
```

2回目
```
sh-4.2$ sudo cat /var/named/data/cache_dump.db | grep -e '1\.1\.1\.1' -e 8.8.8.8 -e 123.123.123.123
;       123.123.123.123 [srtt 171860] [flags 00000000] [edns 0/1/1/1/1] [plain 0/0] [ttl 1744]
;       8.8.8.8 [srtt 3939] [flags 00004000] [edns 1/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1744]
;       1.1.1.1 [srtt 1748] [flags 00004000] [edns 2/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1744]
```

3回目
```
sh-4.2$ sudo cat /var/named/data/cache_dump.db | grep -e '1\.1\.1\.1' -e 8.8.8.8 -e 123.123.123.123
;       123.123.123.123 [srtt 171524] [flags 00000000] [edns 0/1/1/1/1] [plain 0/0] [ttl 1549]
;       8.8.8.8 [srtt 7002] [flags 00004000] [edns 2/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1549]
;       1.1.1.1 [srtt 46507] [flags 00004000] [edns 3/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1549]
```

4回目
```
sh-4.2$ sudo cat /var/named/data/cache_dump.db | grep -e '1\.1\.1\.1' -e 8.8.8.8 -e 123.123.123.123
;       123.123.123.123 [srtt 171188] [flags 00000000] [edns 0/1/1/1/1] [plain 0/0] [ttl 1453]
;       8.8.8.8 [srtt 19456] [flags 00004000] [edns 4/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1453]
;       1.1.1.1 [srtt 46416] [flags 00004000] [edns 3/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1453]
```

5回目
```
sh-4.2$ sudo cat /var/named/data/cache_dump.db | grep -e '1\.1\.1\.1' -e 8.8.8.8 -e 123.123.123.123
;       123.123.123.123 [srtt 170853] [flags 00000000] [edns 0/1/1/1/1] [plain 0/0] [ttl 1392]
;       8.8.8.8 [srtt 14647] [flags 00004000] [edns 5/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1392]
;       1.1.1.1 [srtt 46325] [flags 00004000] [edns 3/0/0/0/0] [plain 0/0] [udpsize 512] [ttl 1392]
```


この間tcpdumpで問い合わせ先を見ていたところ、ほぼ8.8.8.8へ問い合わせしていた。（たまに1.1.1.1へ行く程度）


## 結論
srttは小さい方が優先される（と思う）
C#/VB.NET Excel でデータを検索して強調表示する

ワークシートに大量のデータが含まれている場合は、検索してハイライトすることで目的のデータをすばやく取得できます。この機能は、プログラムの方法で実装できます。使用したの.NETライブラリは[Free Spire.XLS for .NET](https://jp.e-iceblue.com/introduce/free-spire-excel-for-net.html)です。次に、具体的な操作手順とコードについて説明します。お役に立てばと思います。
## Free Spire.XLS for .NETをインストールする
方法1：[NuGet](https://www.nuget.org/packages/FreeSpire.XLS)を介してFree Spire.XLS for .NETをインストールする
「ツール」>「NuGetパッケージマネージャ」>「パッケージマネージャコンソール」の順に選択し、次のコマンドを実行します。
PM> Install-Package FreeSpire.XLS
方法2：プログラムに手動でSpire.xls.dllファイルを導入する
[Free Spire.XLS for .NET](https://jp.e-iceblue.com/download/free-spire-excel-for-net.html)をローカルにダウンロードし、解凍してインストールします。インストールが完了したら、Visual Studioを開いて新しいプロジェクトを作成し、右側のソリューションエクスプローラで「参照」を右クリックし、「参照を追加」>「参照」を選択して、インストールパスの下のBINフォルダのdllファイルを見つけ、「OK」をクリックして、プログラムに参照を追加します。
## 操作方法
* Workbook クラスのインスタンスを作成します。
* Workbook.LoadFromFile() メソッドを使用して、Excel ファイルをロードします。
* Workbook.Worksheets[sheetIndex] プロパティを使って、指定したワークシートを取得します。
* Worksheet.FindAllString(string stringValue, bool formula, bool formulaValue) メソッドで、一致するテキストがあるセルをすべて検索しています。
* CellRange.Style.Color プロパティを使って、セルを強調する色を設定します。
* Workbook.SaveToFile() メソッドを使用して、結果ファイルを保存します。

## コード
C#:
```C#
using Spire.Xls;
using System.Drawing;

namespace FindHighlight
{
    class Program
    {
        static void Main(string[] args)
        {
            //Workbookクラスのインスタンスを作成する
            Workbook workbook = new Workbook();

            //Excelファイルをロードする
            workbook.LoadFromFile("Sample.xlsx");

            //最初のワークシートを取得する
            Worksheet sheet = workbook.Worksheets[0];

            //テキスト「500」を含むすべてのセルを検索する
            foreach (CellRange range in sheet.FindAllString("500", true, true))
            {
                //セルを強調するための色を設定する
                range.Style.Color = Color.Yellow;
            }

            //結果ファイルを保存する
            workbook.SaveToFile("データの検索とハイライト表示.xlsx", ExcelVersion.Version2016);
        }
    }
}
```
VB.NET:
```VB
Imports Spire.Xls
Imports System.Drawing

Namespace FindHighlight
    Class Program
        Shared Sub Main(ByVal args() As String)
            'Workbookクラスのインスタンスを作成する
            Dim workbook As Workbook = New Workbook()

            'Excelファイルをロードする
            workbook.LoadFromFile("Sample.xlsx")

            '最初のワークシートを取得する
            Dim sheet As Worksheet = workbook.Worksheets(0)

            'テキスト「500」を含むすべてのセルを検索する
            Dim range As CellRange
            For Each range In sheet.FindAllString("500", True, True)
                'セルを強調するための色を設定する
                range.Style.Color = Color.Yellow
            Next

            '結果ファイルを保存する
            workbook.SaveToFile("データの検索とハイライト表示.xlsx", ExcelVersion.Version2016)
        End Sub
    End Class
End Namespace
```
![2023-02-17_151617.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/bbd4c86a-d67c-a929-6a81-c51abb88e92c.png)
画像圧縮ツールsquoosh-cliをつかってみた

画像を一括で圧縮とか、webpに変換してくれるsquoosh-cliが便利だったのでメモ

## 環境
macOS Monterey

## node バージョン
v14.20.0

* 他のバージョンだとインストールエラーがおきたり、インストールできても変換するときにエラーがでたりした。18と16でだめだった。
 
## squoosh-cli
[@squoosh/cli - npm](https://www.npmjs.com/package/@squoosh/cli)

## インストール
```
npm i -g @squoosh/cli
```

## コマンド例

```
# jpgを80%で圧縮
squoosh-cli --mozjpeg '{"quality":80}' -d ./compressed ./*.jpg

# pngを80%で圧縮
squoosh-cli --oxipng '{"quality":80}' -d ./compressed ./*.png

# jpgをwebpに変換
squoosh-cli --webp auto -d ./ ./*.jpg
```

## 参考サイト
[SEOの画像最適化を一括で超簡単に行う方法【squoosh-cli】](https://cocorograph.co/knowledge/easy-to-optimize-images/)
新卒1年目で実施した資格取得へのモチベーションを保つ方法

# 初めに
運転免許しか持っていなかった勉強嫌いの私が新卒1年目で実施した資格取得に向けてモチベーションを保つ方法について紹介したいと思います。

# 取得した資格
・ITパスポート
・Python 3 エンジニア認定基礎試験
・AWS Certified Cloud Practitioner
以上の3つを新卒1年目で取得し、現在はAWS Certified Solutions Architect - Associate取得に向けて勉強中です。
私が実施して良かったと思う勉強の取り組み3点を紹介していきたいと思います。

# ①資格勉強をする仲間を作る
まず初めに、一緒に勉強する仲間を作ることがモチベーションの維持に繋がったと感じています。私は、新卒の同期内で同じ資格勉強をしている友人とお互いに助け合いながら勉強したことで、途中で挫けることなく勉強を続けることができたと思っています。

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728372/8adf228c-f55c-d224-f731-d03638329cc8.png">

1人で勉強するとどうしても途中で投げ出したくなってしまうときも、お互いを見張りあう仲間がいることで最後まで走りきることができました。

# ②通勤時間を利用する
家に帰ってしまうとゲームや他のことに手が伸びてしまう私は、解決策として通勤時間を有効活用することにしました。

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728372/3a8e66a9-222e-bd47-eb60-30963073275e.png">

通勤時間をフルで勉強時間に使うと途中で苦しくなり、継続することが苦しくなったため、私は行き帰りどちらかは勉強する、乗り換えまでは勉強するなど適度に自分を甘やかしながら継続的に取り組むこと意識していました。
職場につく前に少し頭を使っておくことで、始業時にだらけずに頭を動かすことができ始めてよかったルーティンの1つとなりました。

# ③声に出して勉強する
黙々と勉強するだけでは、ただやっているだけになってしまう時があったため声に出しながら説明するかのように問題を解く時間を作っていました。声に出すことにより自分がどのように理解しているのか自分で確認できる時間ができました。また、声を出すことで気分がリフレッシュされ勉強があまり苦痛に感じませんでした。
<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728372/93ee8ca4-8abc-e7a8-4d12-89afe744fa97.png">
他にも、友人に解説をしてみる、他の人に教えてもらうなど会話をすることでその問題の印象が頭の中に残りやすいと自分は感じています。
①で紹介した勉強する仲間を見つけ、お互いに解説しあう時間を作ることは短い時間で知識を身に着ける手段の1つになると思います。

# 取得した資格の解説
##### ・ITパスポート
以下私が紹介してる記事となりますので参考にしていただけると幸いです。

https://qiita.com/taka_da/items/5d47421fd9695c94ef5b

##### ・Python 3 エンジニア認定基礎試験
一緒に勉強していた同期が紹介している記事になります。
参考になると思いますので是非一読してみてください。

https://qiita.com/noooooda/items/7f25653d7c835dfc39ca

https://qiita.com/takuma-shimoyama/items/fc1f84dcca68b1870400

##### ・AWS Certified Cloud Practitioner
Tech Stockを利用することを強くお勧めします。

https://techstock.jp/

AWSの数多くの資格勉強ができる教材となっています。
実際の試験問題と近い問題が多くあり、この教材をひたすら解くことが合格への近道になります。
スマートフォンで勉強ができるため、通勤時間にも勉強しやすい点もおすすめです。
また、問題集を解くことで自分の点数の伸びや苦手分野も見えてくるためモチベーションの向上や、テスト対策として最適です。


# 最後に
今回私が1年目で実行していたモチベーションの保ち方ついて紹介しました。
社会人になり自由に使える時間も学生に比べ減っているかもしれませんが、自分の取り組みやすい形を見つけてみてください。
少しで資格取得に向けて頑張っている方の参考になれば幸いです。

私も継続して自己研鑽に取り組むように頑張っていきまので、是非ともこの記事を読んでいただいた方のおすすめのモチベーションを保つ方法がありましたらコメント等で教えてください。
テーブルと列の名前

# テーブルとテーブルの物理定義における列の名前に関するルール

### 名前に使える文字集合
* 半角のアルファベット
* 半角の数字
* アンダーバー(_)

日本語や＄、＃といった特殊文字を名前として使うことが許されているDBMSもありますが、
DBMSを変えたときは使えるかどうかは保証されない。

```テーブルの物理的な定義において日本語を使って良い訳ではありません。```

### 最初はアルファベット
名前の```先頭はアルファベット以外で始めない```でください。

### 名前は重複してはならない
```同じ名前を持つテーブル、同じ名前を持つ列は存在してはいけません```。

#### 範囲を跨げば同じ名前を使ってもいい。
DBMSが設定する範囲内において同じ名前を使うことができません。
この範囲を```ドメイン```といいます。
DBMSによって```スキーマ```と呼ぶこともあります。
```この範囲をまたがって入れば、同じ名前のテーブルを作ることも可能```です。

# 感想
テーブル、列の名前だけでもルールがあるのか。
あやふやだったのがはっきりしてよかった。

# 出典
https://www.shoeisha.co.jp/book/detail/9784798124704
WindowsによるPython入門 #11: モジュール

# はじめに

今回はモジュールを解説します。

# YouTube動画

[]()

# モジュールの定義と使用

.pyファイルを作成すると、それがモジュールになります。

```sample.py
NUM = 10
def get_number():
    return NUM
```

モジュールを使用するには、import 文を使用します。

```main.py
import sample
print(sample.get_number() + 20)  # sample モジュールの get_number() 関数を呼び出し
```

コマンドプロンプトから main.py を実行します。

```
>py main.py
30
```

## 別名でインポート

as を使用すると、モジュールに別名を付けられます。

```main.py
import sample as s  # sample モジュールを s という名前でインポート
print(s.get_number() + 20)
```

## 一部をインポート

from を使用すると、モジュール内の一部の内容をインポート出来ます。

```main.py
from sample import get_number  # sample モジュール内の get_number のみインポート
print(get_number() + 20)
```

「*」を使用すると、モジュール内の全ての内容をインポート出来ます。

```main.py
from sample import *  # sample モジュール内の全ての内容をインポート
print(NUM + 20)
```

# ＿main＿ に関して

モジュール自身の名前を ```__name__``` で取得出来ます。

```main.py
import sample
print(sample.__name__)
print(__name__)
```

以下、実行結果です。

```
sample
__main__
```

実行中のモジュールは、```"__main__"``` という文字列が返ります。
ですので、py コマンド(python コマンド) で実行した場合のみ実行されるコードを書くには以下のようにします。

```py
import sample

def main():
    print(sample.get_number() + 20)

if __name__ == "__main__":  # py コマンドで実行した場合のみ実行される(importでは実行されない)
    main()
```

main() という関数名は慣例的に使用されますが、何でも構いません。
if 文のブロック内がモジュールの import 時には実行されず、py コマンドで実行した時のみ実行されます。

# おわりに

以上、モジュールに関して解説しました。
今回が最終回になります。
お疲れ様でした。
制約

# NOT NULL制約
```NULLを禁止する```ことができます。
列に```NULLのデータベースを登録しようとしたり、NULLに更新しようとしたりした場合は、そのSQL文はエラー```となります。

データベースにデータを登録するとき、```登録するとき、その値がわからない```ことがある。
不明という場合や、```原理的にデータの値が定まらない場合```もある。
そうするときに```NULL```という扱いにすることができます。

# 一意制約
```ある列の組について一意性を求める```制約

主キーと違って1テーブルに対して一意制約は```何個でも設定```できます。

# CHECK制約
```ある列の取りうる値の範囲を制限するための制約```です。

# 出典
https://www.shoeisha.co.jp/book/detail/9784798124704
【React】イベント,Props,Stateとは

## この記事の目的
- Reactの理解とアウトプット、振り返り用
- Reactでよく使われている基本的な技術を言語化できるようする

# イベント
イベントとはユーザが「クリック」や「入力」などの操作行うことで、
イベント処理とは、ユーザが「クリック」や「入力」などの操作が発生したときにプログラム側が行う処理のことを言います。

```react
import React from "react";
import ReactDom from "react-dom";

const App = () => {
  // ボタンクリックで呼び出すアロー関数を定義する
  const onClickButton = () => alert();
  return (
    <> 
      <h1>Reactイベント処理</h1>
      <p>React学習中</p>
      <button onClick={onClickButton}>ボタン</button>
    </>
  );
};
export default App;
```
### イベントまとめ
- HTMLタグの中で扱うイベントやスタイルの名称はキャメルケースとする。
- {}で囲った部分はjavascriptを書くことができる。
- イベントはcamelCaseで名付ける（「onclick」ではなく「onClick」）
- イベントハンドラには文字列ではなく関数を渡す（{onClickButton}部分）

# Props
Propsとは親から子のコンポーネントへ値を渡すために利用するもの。
引数みたいなものとらえるとわかりやすいかと思います。

例として、色のついたメッセージを返すコンポーネント（ColorfulMessage）に対してpropsでメッセージの色を渡してみます。

```./components/ColorfulMessage.jsx
import React from "react";

// ColorfulMessageコンポーネントを定義し引数としてpropsを受け取る
export const ColorfulMessage = (props) => {
  // propsオブジェクトから分割代入でcolorとchildrenを受け取る
  const { color, children } = props;
  const contentStyle = {
    color,
    fontSize: "18px"
  };
  return <p style={contentStyle}>{children}</p>;
};
```
```./App.jsx
import React from "react";
// ColorfulMessageコンポーネントをインポートする
import { ColorfulMessage } from "./components/ColorfulMessage";

const App = () => {
  // ボタンクリックで呼び出すアロー関数を定義する
  const onClickButton = () => alert();

  //ColorfulMessageコンポーネントにcolorというPropsを渡す
  return (
    <> 
      <h1>ReactのProps</h1>
      <ColorfulMessage color="blue">React学習中</ColorfulMessage>
      <ColorfulMessage color="pink">Props例題学習中です</ColorfulMessage>
      <button onClick={onClickButton}>ボタン</button>
    </>
  );
};

export default App;
```
### propsまとめ
- Propsとはコンポーネントに対して渡す引数のようなもの。
- コンポーネントタグで囲んだ要素はpropsオブジェクトのchildrenプロパティとして受け取ることができる。

# State（useState）
Stateとは「状態」という意味になります。
Stateとはコンポーネント利用時に設定ができる値のことで、Propsとは異なり後から変更することができます。
Stateを扱う場合、useStateという関数を使用します。

例として、レベル０の状態からボタンを押下することで+1加算された状態にしてみます。
```./App.jsx
// useStateをインポート
import React, { useState } from "react";
import { ColorfulMessage } from "./components/ColorfulMessage";

const App = () => {
  // ボタンが押されたら、State（num）をインクリメントして更新する
  const onClickCountUp = () => {
    setNum(num + 1); // UseState関数から分割代入で受け取ったState更新用の関数を呼び出す
  };
  // Stateを扱う場合、useStateという関数を使用する
  // useStateの中から配列の分割代入で1つ目として「Stateとして使用する変数名」2つ目として「Stateの更新用の関数」を受け取る
  const [num, setNum] = useState(0);   // [変数名, set変数名]と命名するのが一般的

  // onClickイベントにState更新処理を登録
  // State（num）を表示する onClickCountUpが呼ばれるたびにインクリメントされた状態で表示が更新される
  return (
    <> 
      <h1>ReactのProps</h1>
      <ColorfulMessage color="blue">React学習中</ColorfulMessage>
      <ColorfulMessage color="pink">State例題学習中です</ColorfulMessage>
      <button onClick={onClickCountUp}>学習レベルアップ！</button>
      <p>{num}</p>
    </>
  );
};

export default App;
```
### Stateまとめ
- Stateとはそれぞれのコンポーネントが持っている可変の状態のこと。
- 条件によって動的に変わる部分をStateとして定義してあげることで様々な画面を表示していくことができる
- コンポーネント内で動的に変わる部分は、useStateで定義して変数と更新関数と初期値を設定していく。
- Stateが変更されると再レンダリングする。
- Stateを扱う場合はuseStateをインポートしuseStateという関数を使用する
keras.layers.RNN (GRU) の return_state, return_sequences

keras.layers.RNN (GRU)の return_state, return_sequence に True を指定したときの戻り値の形を整理しておきます。

# モデル
```python:モデル作成
# 1つのデータのシーケンス数 None(後で与える), 要素数 1
inputs = keras.layers.Input(shape=(None,1))

# モデル作成時に重みが常に同じ値になるようにinitializerをセットする。
x = keras.layers.GRU(
    units=1,
    return_state=False,      # 最終状態を返す
    return_sequences=False,  # 入力シーケンスの個々の出力値を返す。
    kernel_initializer="ones",
    recurrent_initializer="ones",
    use_bias=False,
  )(inputs)
model = keras.models.Model(inputs=inputs,outputs=x)
model.summary()

# データ2つ、1つのデータのシーケンス2で要素数1
input_x = [ [[0],[1]], [[0],[-1]] ]
output_y = model.predict(input_x)
print(type(output_y))
print(output_y)
```

GRUで作成しています。SimpleRNNでも基本は同じです。LSTMの場合は内部状態が増えます。

# 入出力
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275020/8c90680c-fcda-7607-2a5e-0107c5eed83b.png">

入力データは2つあります。1つのデータは2つのシーケンスで、1つのシーケンスは1要素でできています。

return_state=False, return_sequences=False で実行した結果が一番上の黄色のものです。モデルの出力の要素数は 1 なので、データ1つに対して1つの出力が返ってきています。

return_state=Trueの場合、緑のデータの最終状態が追加されます。arrayと記述されているのは、pythonのリストの中にnumpyのarrayが入っているからです。

return_sequences=Trueの場合、青のデータが追加されます。青のデータは、入力シーケンスごとの出力です。今回の入力データはシーケンス数が2なので青と黄色と合わせて1データにつき2つになっています。

最後に両方をTrueにすると、戻り値の1つ目がシーケンスの出力が追加されたもの、2つ目が最終状態のものとなります。
PHP：配列の最終要素の後にカンマを付ける場合と付けない場合（慣習的に）

# 配列の最終要素の後にカンマを付ける場合

複数行に渡っている時（慣習的に）

```php
$group = [
    'hr',
    'sales',
    'marketing',
];
```

# 配列の最終要素の後にカンマを付けない場合

単一行の時（慣習的に）

```php5
$group = ['hr', 'sales', 'marketing'];
```
Rubyを使おうとした時のエラー対応

# 初めに
今回は自分がRubyをAndroid Studioで使おうとした時に起こったエラーへの対応を紹介していこうと思います
### 本文
今回は`.bash_profile`がないと言われた時の対応を紹介していきます
まず、必要なフォルダ直下で下記のコマンドを打ちます
```terminal: bash_profileの作成
vi .bash_profile
```
そうすると、`.bash_profile`というファイルが作成されるので`I`キーを押して入力モードにし、下記を入力します
```terminal: bash_profileの中身の設定
eval "$(rbenv init -)"
```
入力が終わったらエスケープキーを押し入力モードを終了した後に`:wq`を入力して保存して終了します
最後に下記のコマンドを打ち込めば終了です
```terminal: bash_profileを参照するように設定
source ~/.bash_profile
```
### 最後に
今回は、自分が詰まってしまっていた部分を備忘録程度に紹介していきました
どなたかのお役に立てれば幸いです
データの誤り制御

データリンク層で行われている技術の一つと思われる。
# 誤り制御の種類
### 誤り検出により再送を行う方法
> パリティチェック、CRC

### 誤り訂正により自己修復を行う方法
> ハミング符合

# パリティチェック
>最もシンプルな検査方法です。例えば、７ビットのデータを送信する場合、８ビット目に誤り検出用のパリティビットを付加してデータの整合性を検査します。

# CRC（巡回冗長検査)
>`送信するデータに生成多項式を適用して誤り検出用の冗長データを作成`し、それを付けて送信します。受信側は、`送信側と同じ生成多項式で受信データを徐算`し、同じ結果であればデータ誤りがないと判断できます。パリティビットも冗長データですが、CRCではさらに複雑な演算を行うことによって、バースト誤りも検出できる点が特徴です。

# ハミング符号方式
>情報ビットに対して検査ビットを付加することで、`２ビットまでの誤り検出`と`１ビットの誤り自動訂正機能`を持つ誤り制御方式です。

# 水平垂直パリティチェック
>ハミング方式と似ていますが、パリティチェックを水平方向と垂直方向で同時に行うことで、`１ビットの誤りを訂正`できます。

# 出典
https://gihyo.jp/book/2023/978-4-297-13865-3

# 感想
記事を書いた当時はデータリンク層で行われていることを知らなかった。
しかしまだ頭がモヤモヤするので理解できるまで頑張りたい。


https://www.lineeye.co.jp/html/term_ayamari.html