OmniAICreator/Qiita-1.07M huggingface dataset:
IBM Cloud Kubernetes Service でアプリのconnection refused の場合での確認


##### はじめに

IBM Cloud Kubernetes Service (IKS) で ALB(Application Load Balancer) pod が正しく動いていないことにより、Connection refused が発生しました。
メンテナンスで worker node がリロードされた場合などの後に起こっています。
備忘録で記載します。


---

##### 環境

IBM Cloud Kubernetes Service  v1.22 
  - worker node は 1 node 構成

---

##### 対応

マニュアルを見て、PDを実施します。

IBM Cloud Docs: [Debugging Ingress](https://cloud.ibm.com/docs/containers?topic=containers-ingress-debug)


この時にALB pod が正しく動いていないことを確認...


```
$ kubectl get pods -n kube-system | grep alb
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-6868584ff6-6jwc7   0/1     CrashLoopBackOff   132        132d
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-867fdb8cdf-2lnwp   0/1     Pending            0          4d14h
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-867fdb8cdf-rvv56   0/1     Pending            0          4d14h
```


Crash している Pod を消してみます。

```
$ kubectl delete po public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-6868584ff6-6jwc7 -n kube-system
pod "public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-6868584ff6-6jwc7" deleted
```

 pod の 作り替えが始まりました。



```
$ kubectl get pods -n kube-system | grep alb
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-6868584ff6-fdjhf   0/1     Pending           0          19s
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-867fdb8cdf-mnrbs   0/1     Pending           0          63s
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-867fdb8cdf-rvv56   0/1     PodInitializing   0          4d14h
```

１つの pod が Running 状態になりました。

```
$ kubectl get pods -n kube-system | grep alb
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-867fdb8cdf-mnrbs   0/1     Pending   0          4m59s
public-crefxxxxxxx5d741exxxx0422cdxxxx-alb2-867fdb8cdf-rvv56   1/1     Running   0          4d15h
```



この状態でアプリPodへの接続が可能でした。
Pending となっている ALB pod は後に削除しました。


----

##### 終わりに

1 node 構成だから発生しやすいのかもしれません。


以上です。
OSSで気持ちよくContributeしてもらうためのGitHub Actionsの設定

GitHub上のOSSにContributeする際はリポジトリをforkし、forkしたリポジトリにpushしたブランチで元リポジトリにPRを作成するという手順を踏みます。
この際、forkしたリポジトリを考慮したGitHub Actionsの設定になっていないと、権限不足等の問題でCIが落ち、Contributeの意欲を削ぐ結果になりかねません。
これを防ぐため、以下の表を参考に、forkしたリポジトリから元リポジトリへのPRやforkしたリポジトリでのPR (元リポジトリにPRを出す前の動作確認を想定) で実行してほしくないGitHub Actionsのjob・stepには適切な実行条件 ( `if` ) をつけてあげると良いでしょう。
なお、 `X` は条件の否定を表しています。

|動作させたい条件|`github.repository == github.event.pull_request.head.repo.full_name`|`github.repository == '元リポジトリ (org/repository)'`|
|:--:|:--:|:--:|
|forkしたリポジトリでのPR|O|X|
|forkしたリポジトリから元リポジトリへのPR|X|O|
|元リポジトリでのPR|O|O|

例: forkしたリポジトリでのPRと元リポジトリでのPRのみ、GitHub Container Registryへのpushを行うjobの実行を許可する

```.github/workflows/push.yml
---
name: Push GitHub Container Registry

on:
  pull_request:

jobs:
  push:
    runs-on: ubuntu-latest
    # (github.repository == github.event.pull_request.head.repo.full_name && github.repository != '元リポジトリ (org/repository)')
    # || (github.repository == github.event.pull_request.head.repo.full_name && github.repository == '元リポジトリ (org/repository)')
    # をまとめた条件
    if: github.repository == github.event.pull_request.head.repo.full_name
    steps:
      ...
```

なお、この設定を行うPRは動作確認を兼ねてあえてforkしたリポジトリから出すようにすると良いと思います。
React: useEffect [アウトプット全くしてこなかったのでアウトプットする010]

一言でいうと`描画が完了した後に処理を実行するもの`です

描画が完了 = 初期のロード時だけではなく、`props`や`state`が変更されたときにもコンポーネントが再構築される時も入る

> useEffect は毎回のレンダー後に呼ばれるのか？ その通りです！ デフォルトでは、副作用関数は初回のレンダー時および毎回の更新時に呼び出されます。
出典: 公式

使い方は以下

```tsx
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    文言を書き換えてます
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

useEffectの第一引数には実行したい処理を入れますが、第二引数には配列を入れることができます。
この配列には依存したい値を入れることになっており、例えばstateの値を入れたりして使います。

> 再レンダー間で特定の値が変わっていない場合には副作用の適用をスキップするよう、React に伝えることができるのです。そのためには、useEffect のオプションの第`2`引数として配列を渡してください。

```tsx
useEffect(() => {
  // countの値が更新された時に処理を実行
  document.title = `You clicked ${count} times`;
},[count]);
```

> 上記の例では、第`2`引数として [count] を渡しています。どういう意味でしょうか？ もし count が 5 で、次回のコンポーネントのレンダー時にも count がまだ 5 であった場合、React は前回のレンダー時に覚えておいた [5] と今回のレンダーの [5] とを比較します。配列内のすべての要素が同一 (5 === 5) ですので、React は副作用をスキップします。これが最適化です。

また空の配列を渡すと初期ロード時のみ処理を走らせることができます。

```tsx
useEffect(() => {
  // ロード時のみ処理を実行
  document.title = `You clicked ${count} times`;
},[]);
```

あと絶対誰もがやること紹介します。

```tsx
  const [obj, setObject] = useState({});

  useEffect(() => {
    setObject({ hoge: "hoge" });
  }, [obj]);
```

上記はobjというオブジェクトが更新された時にobjを更新するというコードなのですが、これは無限ループになります。

開発者ツールのコンソール画面で以下のように

```tsx
{hoge: "hoge"} === {hoge: "hoge"} 
```

と打ってもらうとfalseが帰ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660329/4608484b-dc25-999e-a601-034d26f4cfe7.png)

対処方法については以下の記事がわかりやすくまとまっていました

https://zukucode.com/2021/06/react-useeffect-loop.html



### 参考:

https://ja.reactjs.org/docs/hooks-effect.html

https://qiita.com/seira/items/e62890f11e91f6b9653f

https://qiita.com/shimarin/items/7b1e2ce8efc59d42f581
ケバブケースを使うならケバブケースに従わないと痛い目を見る

## 設定
- OpenAPIでAPI仕様書を書く
- API仕様書から[swagger\-api/swagger\-codegen](https://github.com/swagger-api/swagger-codegen)を使って、Node.jsのServer stubを生成する

## API仕様書からNode.jsのServer stubの生成
### API仕様書の一部抜粋
```yaml
 '/groups/{groupid}/users/{userid}':
    put:
      tags:
        - groupUser
      operationId: put-groups-groupId-users-userId
      parameters:
        - name: groupId
          in: path
          schema:
            type: string
            default: sampleGroupId
        - name: userId
          in: path
          schema:
            type: string
            default: sampleUserId
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupUser'
      x-swagger-router-controller: GroupUser
```

### 生成されたNode.jsのstub
上記のyamlファイルからは以下のようなcontrollerが生成される。
関数名は`operationId`をキャメルケースに変換した名前になる。
```javascript
module.exports.putGroupsGroupIdUsersUserId = function putGroupsGroupIdUsersUserId (req, res, next, groupId, userId) {
  GroupUser.putGroupsGroupIdUsersUserId(groupId, userId)
    .then(function (response) {
      utils.writeJson(res, response);
    })
    .catch(function (response) {
      utils.writeJson(res, response);
    });
};
```
ルーティングも生成される。
ルーティングは以下のように、[bug\-hunters/oas3\-tools](https://github.com/bug-hunters/oas3-tools)によって、API仕様書を用いて行うことができる。
```javascript
'use strict';

var path = require('path');
var http = require('http');

var oas3Tools = require('oas3-tools');
var serverPort = 8080;

// swaggerRouter configuration
var options = {
    routing: {
        controllers: path.join(__dirname, './controllers')
    },
};

var expressAppConfig = oas3Tools.expressAppConfig(path.join(__dirname, 'api/openapi.yaml'), options);
var app = expressAppConfig.getApp();

// Initialize the Swagger middleware
http.createServer(app).listen(serverPort, function () {
    console.log('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
    console.log('Swagger-ui is available on http://localhost:%d/docs', serverPort);
});
```
## 問題
しかし、`/groups/{groupid}/users/{userid}`へのリクエストが処理されない

## 原因
ルーティングは[bug\-hunters/oas3\-tools](https://github.com/bug-hunters/oas3-tools)を用いて行われる。
oas3-toolsは、API仕様書を読み込み、`operationId`をキャメルケースに変換して、ルーティングする。
`operationId: put-groups-groupId-users-userId`なので、キャメルケースに変換すると、`putGroupsGroupidUsersUserid`になる
しかし、関数名は`putGroupsGroupIdUsersUserId`である。

## 解決 
`operationId: put-groups-groupId-users-userId`ではなく、正しいケバブケースである、`operationId: put-groups-groupid-users-userid`にするべきだった。
Could not reach Cloud Firestore backendと出てemulatorに接続できない問題の解決法

こんにちは。[virapture株式会社](https://virapture.com)の[もぐめっと](https://mogmet.com)です。

本日はfirestoreのsecurity ruleのunit testを書いていた時に遭遇したエラーの解決策の共有です。

結論から言うと、**ファイアーウォールは切れ**です。

では詳細を解説します！

## エラー症状
**Could not reach Cloud Firestore backend**といわれてsecurity ruleのunit testが動かない問題に遭遇しました。

admin側では問題なく接続できるのですが、client側で接続しようとすると上記エラーがでてしまうという問題です。
security ruleのunit testを作るにはclientで接続できないとテストができないのでとても困ってしまいました。
なんでadminでは繋がるのにclientで繋がらないやねんと・・・

## 原因

原因は簡単な理由で、kasperskyを起動していたせいでした。
インターネットセキュリティ系のソフトウェアが入っていると通信が妨害されてテストができないようでした。
開発者にとって、とても大敵です。
しかしセキュリティも大事なので無碍にもできないので悩ましいところ。

## 対策

テストする時だけファイアーウォール系のソフトウェアはOFFにしておきましょう。
または、emulator系のプロセスは除外したり、対象portを除外したりと設定をしておくのも有効かと思われます。

## まとめ

**ネットワーク的な問題で困ったらセキュリティソフトを疑え**という教訓を得ました。
adminが繋がるというところでその意識が薄れてしまっていたのですが忘れないようにしたいと思います。


最後に、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/
AWS AppSyncでカスタムレスポンスヘッダーができるようになったのでやってみた

# はじめに

なんと！！AWS AppSyncのレスポンスヘッダーを設定できるようになりました！

以下の記事でレスポンスヘッダーを追加したいのにできなかったので、CloudFrontを活用して実現していました。


https://qiita.com/ta__k0/items/186e5d7f350ca485da62

それがAWS AppSyncがアップデートされて設定だけでできるようになったのです。素晴らしい。

なので、やってみます。

# レスポンスヘッダーの追加方法

↓↓　アップデート内容にある通り、VTLユーティリティヘルパーにて、リゾルバーマッピングテンプレートで設定することになります。

https://aws.amazon.com/jp/about-aws/whats-new/2022/02/aws-appsync-support-custom-response-headers/

↓↓　VTLユーティリティヘルパー：HTTP helpers in $util.http

https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html#http-helpers-in-utils-http

マッピングテンプレートはこんな感じになります。
```
...
$util.http.addResponseHeader("count", 9)
$util.http.addResponseHeader("testId", $ctx.args.testId)
...
```

:::note warn
ご注意
以下の制限事項があります。
* 既存のヘッダー名と重複することはできない。
* 「x-amzn-」、「x-amz-」から始まるヘッダー名は設定できない。
* ヘッダー名と値で4KBを超えることができない。
:::

# レスポンスヘッダーを追加してみる

※すでにAPIは作ってある前提になります。

スキーマより、対象のリゾルバーを選択し、リゾルバー編集画面を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129814/ad3e74ed-29ec-9feb-374a-7f18896f2bc1.png)

レスポンスマッピングテンプレートにレスポンスヘッダを追加するように追記します。
今回は↓を追記します。
```
$util.http.addResponseHeader("x-snow-key", "test")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129814/e3c6d740-2563-bbf5-c58c-367d293eed2d.png)

これで完了です。簡単すぎる。。。


# 確認する

実際にAPIを叩いて確認してみます。（Postmanでリクエストします。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129814/56ba14f7-fcf5-7c21-7dff-0ec4221a120c.png)

追加したレスポンスヘッダーが返却されていることがわかります。


# まとめ

CloudFrontでレスポンスヘッダーを追加しないといけないアーキテクチャがCloudFrontが不要なアーキテクチャで実現できることを実際に試すことができました。

![cf-lambda-ページ1.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129814/2986007b-c3e7-2f42-a40b-6553e6fa3f1f.png)

↑が↓でよくなったわけです。

![cf-lambda-ページ1のコピー.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129814/4c57c79d-eaba-0c0b-88d9-48b8a3cc1f26.png)

これは便利です。
では。
2022/3/9主にITとかセキュリティの記事

「ProjectWEB」の被害組織数を上方修正 - 富士通
https://www.security-next.com/134678

印刷通販サイトで顧客の個人情報が流出
https://www.security-next.com/134528

不正送金マルウェアの検知数が大きく減少
https://www.security-next.com/134415

「WPS Office for Windows」に脆弱性 - 管理者権限奪取のおそれ
https://www.security-next.com/134681

「Emotet」に感染、診療業務には影響なし - 那須南病院
https://www.security-next.com/134639

職員のPCが「Emotet」に感染、日本気象協会の注意喚起についてまとめた記事に注目集まる(3/7)
https://internet.watch.impress.co.jp/docs/news/ranking/1393180.html

RTテレビのロシア語サイトにDDoS攻撃、攻撃の主な発信国は米国(3/7)
https://jp.sputniknews.com/20220307/10315928.html

「これ詐欺だったの？」──「えきねっと」をかたるメール、手口の巧妙さが話題に　“自動退会処理”に注意(3/7)
https://news.biglobe.ne.jp/it/0307/imn_220307_4603251153.html

ネット中傷対応、2社不十分　総務省がIT大手聴取(3/7)
https://www.nikkei.com/article/DGXZQOUA072YL0X00C22A3000000/

Mastercard、最新の国際的なクレジットカード不正利用とセキュリティ対策の動向について(3/7)
https://paymentnavi.com/paymentnews/116135.html

基本設計書は納品前ですが、システム作っちゃいました(3/7)
https://atmarkit.itmedia.co.jp/ait/spv/2203/07/news010.html

IT社会を「人質」にするな　サイバーが生む息苦しい現実(3/7)
https://www.nikkei.com/article/DGXZQOCD030TC0T00C22A3000000/

ウクライナ「IT軍」、ボランティア頼みの危うい現実(3/7)
https://www.technologyreview.jp/s/270285/the-propaganda-war-has-eclipsed-cyberwar-in-ukraine/

ツイッターで広がるウクライナ侵攻への抗議　300万件使われた#は(3/6)
https://www.asahi.com/sp/articles/ASQ346X5MQ33ULEI00J.html

コアラ保護、クラウドで遺伝分析　シドニー大とAWS(3/7)
https://www.nikkei.com/article/DGXZQOUC185M80Y1A111C2000000/

HTML5を利用しているWebサイトが90%を超える(3/7)
https://news.infoseek.co.jp/article/mynavi_2377845/?tpgnr=it

渾身の個人開発で「誰にも使ってもらえない」に陥らないための5つの指針(3/7)
https://qiita.com/Tyamamoto1007/items/050a1d42c18541de1a83

Firefox 97.0.2 リリース、2 件の ゼロデイ脆弱性を修正(3/6)
https://security.srad.jp/story/22/03/06/0847219/

IPv6とゲームの課題に向き合ったJAIPAのゲーム・エンタメWGの活動とは？(3/7)
https://ascii.jp/elem/000/004/084/4084962/?rss

すでに攻撃が開始されている致命的な脆弱性を修正した「Thunderbird 91.6.2」が公開(3/7)
https://forest.watch.impress.co.jp/docs/news/1393278.html

英内務大臣、インターポールにシステムへのロシアによるアクセスを停止するよう要請(3/7)
https://jp.sputniknews.com/20220307/10316334.html

金融庁が資金決済法「改正案」提出、ステーブルコイン取引業に規制方針も(3/7)
https://www.neweconomy.jp/posts/199636

年末調整に関するITシステム未導入企業のネックは? さくら情報システム調査(3/7)
https://news.mynavi.jp/techplus/article/20220307-2287136/

Pythonのlogging入門(3/6)
https://qiita.com/papi_tokei/items/6051cb55c2843b2c3cdf

サードパーティーからのアプリDLは危険〜米議会にAppleが文書を提出(3/7)
https://iphone-mania.jp/news-442643/

DeepLとGoogle翻訳の日本語は流ちょうか、無料翻訳サービスの実力診断(3/8)
https://xtech.nikkei.com/atcl/nxt/column/18/01974/030700002/

みずほ銀行と他の金融機関を徹底比較、ここまで違う「安定稼働対策」(3/8)
https://xtech.nikkei.com/atcl/nxt/column/18/01972/030400002/

セキュリティーだけではない、企業向け無線LANで重視すべき「3つのポイント」(3/8)
https://xtech.nikkei.com/atcl/nxt/column/18/01967/022800002/

名ばかりCISOなら空席にすべき、その真意は？ハッカー協会・杉浦代表理事が直言(3/8)
https://xtech.nikkei.com/atcl/nxt/column/18/00677/020700106/

ワコムの直販サイトで10日間続いたトラブル、原因は物流会社へのサイバー攻撃(3/8)
https://xtech.nikkei.com/atcl/nxt/column/18/00598/121500155/
ブロックエディターの見出しからH1を削除する方法

WordPressのブロックエディター（Gutenberg）の見出しからH1を削除する方法です

WordPress5.9以降の方法です

単純にCSSで非表示にしちゃいましょう！

H1の他に、H5なども非表示にできますよ

```php:qiita.php

function my_h_style() {
  echo '<style>
  button[aria-label="見出し1"],button[aria-label="見出し4"],button[aria-label="見出し5"],button[aria-label="見出し6"]
{
	display: none;
}
  </style>'.PHP_EOL;
}
add_action('admin_print_styles', 'my_h_style');

```

スッキリしましたね
【React】一定の数値になると押せなくなるカウントボタンの作成方法

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

## 一定の数になると押せなくなるカウントボタンの作成方法
以下のように記述することで一定の数になるとカウントボタンが非活性化され押せなくなります。

※ スタイリングにstyled-componentsを使用しています。


```shared_style.js
import styled from "styled-components";

export const BaseButton = styled.button`
  cursor: pointer;
  :hover {
    opacity: 0.7;
  }
  :focus {
    outline: 0;
  }
`;

export const RoundButton = styled(BaseButton)`
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: none;
  background-color: #eeeeee;
`;

```

```CountUpButton.jsx
import React from "react";
import { RoundButton } from "../shared_style";

export const CountUpButton = ({ onClick, isDisabled }) => {
  return (
    <RoundButton onClick={onClick} disabled={isDisabled} >
      ＋
    </RoundButton>
  )
}
```

```CountDownButton.jsx
import React from 'react'
import { RoundButton } from '../shared_style'

export const CountDownButton = ({ onClick, isDisabled }) => {
  return (
    <RoundButton onClick={onClick} disabled={isDisabled}>
      −
    </RoundButton>
  )
}
```

```App.jsx
import './App.css';
import React, { useState } from 'react';
import styled from 'styled-components';
import { CountUpButton } from './components/Buttons/CountUpButton.jsx';
import { CountDownButton } from './components/Buttons/CountDownButton.jsx';

const CountersWrapper = styled.div`
  margin: 50px 50px;
  display: flex;
  padding: 0 15px;
`;

const CountItem = styled.div`
  margin: 0 10px;
`;

const CountNum = styled.div`
  padding-top: 10px;
`;


function App() {
  const [count, setCount] = useState(1)
  const onClickCountUp = () => {
    setCount(count + 1);
  }
  const onClickCountDown = () => {
    setCount(count - 1);
  }

  return (
    <CountersWrapper>
      <CountItem>
        <CountDownButton
          onClick={() => onClickCountDown()}
          // 数量が1以下だったら、カウントダウンさせない
          isDisabled={count <= 1}
        />
      </CountItem>
      <CountItem>
        <CountNum>
          {count}
        </CountNum>
      </CountItem>
      <CountItem>
        <CountUpButton
          onClick={() => onClickCountUp()}
          // 数量が9以上だったら、カウントアップさせない
          isDisabled={count >= 9}
        />
      </CountItem>
    </CountersWrapper>
  );
}
export default App;

```
【Linux】よく使うショートカットキー

TeraTermなどコマンドラインにて
私がよく使っているショットカットキーを紹介します。

<BLOCKQUOTE>カーソル移動系</BLOCKQUOTE>

・ctrl + a
　　カーソルを行頭へ移動

・ctrl + e
　　カーソルを行末へ移動

<BLOCKQUOTE>文字列操作系</BLOCKQUOTE>

・ctrl + u
　　カーソルより後の文字列を全削除

・ctrl + k
　　カーソルより前の文字列を全削除

<BLOCKQUOTE>その他</BLOCKQUOTE>

・ctrl + l
　　コンソール上の出力を全てリセット

・ctrl + c
　　処理を中断

以上です。
既に使っている方も多いと思いますが、良かったら使ってみてください。
直前のリクエストURLからクエリパラメータを抽出

### リクエストクラスのquery()メソッドと同様の結果にしたい
```
use Illuminate\Http\Request;
$request->query()
```
<details><summary>array:1 [▼</summary>
 
 "email" => "desc"
]
</details>

# 直前のリクエストURLからクエリパラメータを抽出
`parse_url(url()->previous())`
 laravelヘルパのurl()から直前リクエストのurlを取得後にphpのparse_url関数で以下の形で取得できる
array:1 [▼
 "scheme" => "http"
  "host" => "http://localhost"
  "path" => "/sort/index"
  "query" => "email=desc"
]
ここから必要なqueryの値を取得して無理やり「=」で区切り、配列にする
その配列の最初をkeyにして最後をvalueにすることで、query()メソッドと同様にした
```  qiita.rb
$query = explode('=', Arr::get(parse_url(url()->previous()), 'query'));
$queryParam[Arr::first($query)] = Arr::last($query);
```

#### 注意点
これはクエリパラメータがemail=descのように一つで来る前提なので、email=desc&name=hogeのように2つ以上きた場合は`"query" => "email=desc&name=hoge"`の形になるので、対応できない

##### 他に良い方法ないかな〜

#### 2022/03/09　追記
```
parse_str(Arr::get(parse_url(url()->previous()), 'query'), $queryParam);
```
`$queryParam`には上記の`$queryParam`と同様の結果が格納される
こちらであれば注意点は解消され、複数クエリパラメータで来ても問題ない
certbotでSSL証明書を発行しようとしたらunauthorizedで弾かれた場合の対策 

# 概要

`certbot` コマンドでSSL証明書を発行しようとした。

```bash
# certonly:証明書のみ発行
#  --webroo webサーバを起動させたままでSSL証明書を発行
# -w webrootを使用する場合に証明書の一時保管ディレクトリを指定
# -d 証明書を作成するホスト名（FQDN）を指定
certbot certonly --webroot -w /var/www/html -d xxxx.com
```

すると`unauthorized`で弾かれてしまったので対策を備忘録として残す

参考サイト

https://belhb.hateblo.jp/entry/2018/02/24/134643

```bash
Domain: xxx.com
Type: unauthorized
Detail: Invalid response from
http://xxxx.com/.well-known/acme-challenge/b4jxv6KqxnmZrC8_6eZEE677UPvWZ8Dg1_v_5hgnwu4
```

# `nginx`の設定ファイルに追加

```conf:/etc/nginx/conf.d/default.conf	
server{
    # リクエストを受け付けるポート番号	
    listen 80;

    # アクセストークン確認用リクエストの場合は、https にリダイレクトしない
    location ^~ /.well-known/acme-challenge/ {
        # レスポンスのデフォルトのMIMEタイプ
        default_type "text/plain";
        # ドキュメントルート	
        root /var/www;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}
```

# SSL証明書を発行すると成功するようになった

```bash
certbot certonly --webroot -w /var/www/html -d xxxx.com

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
```
土壌湿度センサ


# 用語
GPIOは、General Purpose Input/Output（ジェネラル・パーパス・インプット/アウトプット）の略、汎用I/Oポート

I2Cインタフェース（以下I2Cインタフェース）は、1982年にPhilips（現NXP）が開発した IC間の通信規格です。クロック信号SCL、データ信号SDA、GNDの3本の配線で複数のI2C機器との通信が行えます。

規格の名称：Gravity（DFRobot社 Gravityシリーズ）,Groove(Seeedstudio):
 →　I2C接続は面倒だから、取り回しが簡単な規格ができたという認識（あってる？）

# 参考

ラズパイ、YL69 + MCP3208
https://qiita.com/ksk8/items/1e467dce91e084edb2ca

ラズパイ、YL69 + MCP3002
https://qiita.com/ksk8/items/81db8b49727861bde9f2

Arduino /Zhiwei Robotics Corp.(DFROBOT)センサ
https://qiita.com/YUZU/items/9ed27901af2bed2a4e64

2015年、Seeedのセンサ
https://qiita.com/kemurayama/items/9bca8dd29a504d2ecfe4


https://thepihut.com/blogs/raspberry-pi-tutorials/raspberry-pi-plant-pot-moisture-sensor-with-email-notification-tutorial
https://www.instructables.com/Soil-Moisture-Sensor-Raspberry-Pi/

# H/W

謎の互換品より、SEEEDや秋月で取り扱っているセンサを購入するのがよさそう。
https://www.seeedstudio.com/Grove-Moisture-Sensor.html

https://akizukidenshi.com/catalog/g/gM-07047/

SwitchScienceのGrove水分センサー
https://www.switch-science.com/catalog/7515/
https://www.switch-science.com/catalog/4024/

「Gravity: アナログ容量性土壌水分センサー-耐食性」が公式ページも充実していてよさそう。
https://www.amazon.co.jp/DFROBOT-SEN0193-Gravity-%E3%82%A2%E3%83%8A%E3%83%AD%E3%82%B0%E5%AE%B9%E9%87%8F%E6%80%A7%E5%9C%9F%E5%A3%8C%E6%B0%B4%E5%88%86%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC-%E8%80%90%E9%A3%9F%E6%80%A7/dp/B01GHY0N4K/ref=sr_1_14?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=56ZHCIY4A4QF&keywords=%E5%9C%9F%E5%A3%8C%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC&qid=1646629274&sprefix=%E5%9C%9F%E5%A3%8C%E3%82%BB%E3%83%B3%E3%82%B5%2Caps%2C195&sr=8-14

# SensorKit
https://osusumepc.com/raspberry-pi-sensor/
JavaScriptのクラスと継承、オーバーライド

# クラスとは
クラスは***設計図***だとイメージしてください。

# クラスとインスタンス
クラスという設計図を作って、
それを元に作られたのが***インスタンス***です。

例えば車を1台作ればそれを元にいろいろな車を作れますよね。
そういうイメージです。

***クラスを１つ作ると、他のプロジェクトなどに流用できる***みたいです。

https://qiita.com/Hashimoto-Noriaki/items/e94a27c3d5d40ba4d41c

# クラスの定義のやり方
クラスを定義する時の定義のやり方です。

```js
class ClassName {} //クラスの宣言
const instance = new ClassName();　//newでクラスのインスタンス作成
```
実際のコードをみていきます。

```js
//基地のクラスを定義
class Base {}

const base = new Base();

```

⚫︎メソッドを定義
　クラスにメソッドを定義していきます。

```js
class ClassName {
 methodName(){ //処理
}

const instance = new ClassName();
instance.methodName();
```

実際のコードをみていきます。

```js
class Base {
  weapon() {　　//weaponメソッドを定義
    console.log('兵器');
  }
}
const base = new Base();
base.weapon();
//兵器が出力
```

# constructor
constructorは```初期化する処理```のことです。(Rubyだとinitializer)
クラスの中で関数を呼ぶときに```　this```を使います。

```js
class ClassName {
 constructor(color){
 this.color = color;
}
}
```

実際のコードをみていきます。

```js
class Car {
  constructor(color) {
    this.color = color;
  }
}
const car = new Car('white');
//ゲッター
console.log(car.color);
//whiteと出力
//セッター
car.color = 'red';
console.log(car.color);
//redと出力
```

# クラスの継承とオーバーライドについて
クラスで作った設計図を元に、新たに定義してデータなどを上書きすることを```オーバーライド```と言います。
継承とオーバーライドのやり方を書いていきます。
クラスを継承するのに```extends```を使います。

```js
class User {
#メソッド定義
}
 class AdmnUser extends User {
 #メソッド等の定義
}
```

実際にコードを書いていきます。

```js
class NormalCar {
  engine() {
    console.log('車のエンジンをかける');
  }
}

const car = new NormalCar();
car.engine();
//車のエンジンをかける   が出力
```

継承を使うと

```js
class NormalCar {
  engine() {
    console.log('車のエンジンをかける');
  }
}

class SilverCar extends NormalCar {    //継承
  engine() {
    console.log('銀色の車のエンジンをかける');
  }
}

const car = new NormalCar();
car.engine();

const silvercar = new SilverCar();  //継承
silvercar.engine();

//車のエンジンをかける
// 銀色の車のエンジンをかける  //オーバーライドされた
```



こちらも参考にしてください。
https://qiita.com/Hashimoto-Noriaki/items/a9cec16753db70c52033


# おすすめ動画
クラスと継承のアプトプットにいい動画なのでよかったら見てみてください。

https://www.youtube.com/watch?v=t7hLDtK8MO4&list=PLLFOC5fk1ILlZX9HshL0ntSXxV-K88v5e&index=4

⚫︎参考資料
https://wa3.i-3-i.info/word138.html
https://ja.javascript.info/class
https://javascript.keicode.com/lang/javascript-class.php
URL管理ツール作成とその記録 Part2

# フロントエンド
## 目標
画面作成
+ アバウト画面
+ コンタクト画面
+ アカウント作成画面
+ ログイン画面
+ url一覧画面
+ url登録画面
+ url編集画面

## TODO
+ 画面構成を考える

## 画面構成を考える
+ 共通部
  + ヘッダー
    + ホーム画面へのリンク(ログイン済みならホーム、そうでないならアバウト)
    + (アカウント作成、ログイン)orログアウト
 + フッター
   + アバウトページへのリンク
   + コンタクトページへのリンク
+ アバウト
  + 概要
+ コンタクト
  + コンタクト
+ アカウント作成
  + 見出し
  + フォーム
+ ログイン
 + 見出し
 + フォーム
+ url一覧
  + urlのリスト
+ url登録
  + 見出し
  + フォーム
+ url編集
  + 見出し
  + フォーム

# バックエンド
## 目標
urlの登録ができること。

## TODO
* エンドポイントの設計
* dbの設計

## エンドポンとの設計
|method|url|controller|
|-|-|-|
|GET|/users/:id/urls|ShowUrls|
|POST|/users/:id/urls|CreateUrl|
|GET|/users/:id/urls/:id|ShowUrl|
|PUT|/users/:id/urls/:id|UpdateUrl|
|DELETE|/users/:id/urls/:id|DestroyUrl|

## dbの設計

|カラム名|型|制限|
|-|-|-|
|ID|gormに任せる|gormに任せる|
|title|varchar|128文字まで,必須|
|url|varchar|128文字まで、必須|
|作成日|gormに任せる|gormに任せる|
|更新日|gormに任せる|gormに任せる|

https://qiita.com/itkr/items/9b4e8d8c6d574137443c

https://github.com/go-playground/validator

# 収穫
vagrantが作動しなくなった。
どうやらosのアップデートが問題らしい。
virtualboxのサポート外になってしまったようだ。
エス・エイチ・アイ・ティー！
frontもDockerで環境構築なり。
と思ったら日本語版のサイトでなく公式のサイトからインストールすればちゃんと動いた。
vagrantのrsyncはホストの方のデータでゲストを上書きするのでパッケージをインポートしてプロジェクト内に設置するタイプの言語だとrsyncを使っていると終了時に全てのデータが消されてしまう。オプションを上書きすれば消さないようにはできるが逆の同期はできないので気を付ける。

# まとめ
## フロント
react router domを使ってページ遷移する方法を調べたところで終了
## バック
db設計までで終了
## 反省
フロントでvagrantでホットリロード機能がうまく動作しない原因を調べるのに時間がかかってしまった
## 明日の計画
### フロント
装飾なしでいいのでまず各画面の作成、遷移ができるようにする。
### バック
URLのコントローラ、モデル、レポジトリ作成。

# 今後作っていきたいもの
テンプレート機能
テーマ機能

テスト作成
テストに関しては使ったことがないものに使ったことがないものを使おうとするからぐちゃぐちゃになった。
まずは簡単なプログラムを作っそのテストを作るとこから始めていく。
* mock
* ginko
* validater

GOOD NIGHT.
100日でSQLの達人になる@LeetCode! Day37 <ROW_NUMBER OVER(ORDER_BY 変数1 ASC, 変数2 DESC)>

## 1112. Highest Grade For Each Student （問題レベル: Medium）要課金
今日の問題はこれ。
ユーザー毎に最高点とその科目のIDをリストアップするという問題。
ただし、最高点が同じ科目が複数ある場合、科目のIDの小さい方をリストする必要がある。

最高的のみならば単純な`GROUP BY`句でできそうであったが、細かい条件があったので、
いつもの様に`ROW_NUMBER`を使用した。ただし今回は順序の条件が複数必要であった。

そのため、今日のポイントは、
行番号を複数条件で指定する場合の書式は`ROW_NUMBER OVER(ORDER BY 変数1 ASC, 変数2 DESC)`とするとした。
`PARTITION BY`と`ORDER BY`の間に`,`は必要が無いが、複数条件の列挙には`,`が必要なのが地味なポイント。

最終的な解答はこれで提出した。
```:SQL
SELECT a.student_id, a.course_id, b.grade
FROM enrollments a
JOIN 
(SELECT student_id, course_id, grade,
 ROW_NUMBER() OVER(PARTITION BY student_id ORDER BY grade DESC, course_id ASC) AS rnk 
 FROM enrollments) b
ON a.student_id=b.student_id AND a.course_id=b.course_id
WHERE b.rnk=1
ORDER BY a.student_id
```

* [LeetCode](https://leetcode.com/)の問題は、`MS SQL Server`で解いています。
【初心者向け】Rails開発での注意点

# はじめに
Ruby on Rails チュートリアルでの学習(1ヶ月)を含め、
初めてRailsに触れてから約半年でアプリケーションを開発した結果
色々荒が目立ちすぎだったのでメモとして残しておきます。
指摘は多々ありましたが、クリティカルだと思ったポイントについてピックアップしています。
(なお、自身で気が付くことができずに指摘されたポイントです)

## 自身の来歴(言い訳含む)
工業高校 => 理系大学(情報系)出身。
新卒で就職し、3年程エンジニアとしてJava一辺倒で開発を行う。
過度の残業・追い込みから退職し、病院にお世話になり、
約1年半程、業界無関係のアルバイトでフラフラしてみる。(ブランク)
その後二十代後半で転職し「Ruby on Rails チュートリアル」を1月かけて学習する。
初めてRuby及びRailsに触れてから約半年で社内用に新規アプリケーション開発を実施。

## 開発環境
Windows10 Pro
Hyper-V(Ubuntu 18.04 LTS)
VSCode(Remote–SSHを利用)
Ruby：2.7.3
Rails：6.0.3.7

## 指摘事項(加筆・修正の可能性あり)
(2)、(3)の打ち消し線の箇所については
現状記述する時間がないので、メモ代わりに記述しています。
今後、時間を捻出できた場合に追記する(かもしれない)ための
私的メモなので見逃していただければ幸いです。
(指摘いただいても返答いたしかねますのでご了承ください)

(1) Scope化しましょう。(コントローラ内にwhereメソッドは極力書かない。)
~~(2) default_scopeは極力使用しないようにしましょう。~~
~~(上記を使用する例：DB側で一意になる順序制御用のカラムがあり、そのモデルが他の並び順で出力するという仕様自体が稀である場合。)~~
~~(3)「rails new」コマンドではオプションを活用しましょう。~~

### 各指摘について

* (1) Scope化しましょう について(コードは脚色してあります)

```ruby

// 悪い例 (コントローラ内に直接記載)
class FooController < ApplicationController

…省略
   FooModel.where(hoge_date:search_hoge_date_start..search_hoge_date_end)
…省略

```

改善策
scopeを使いましょう。
(以下コード例)

```ruby
//モデルにスコープを定義する
class FooModel < ApplicationRecord
  scope :sorted_with_search_date, -> { where.sorted_with_search_date(hoge_date:search_hoge_date_start..search_hoge_date_end) 
}

//コントローラ内ではscopeを呼び出すようにする
class FooController < ApplicationController

…省略
   FooModel.sorted_with_search_date
…省略

```

他の指摘や解説については
時間が割けた時に記述します。
production.ERROR: Database (/var/www/releases/1/backend/database/data     base.sqlite) does not exist. 解決方法

## 初めに
この記事では、deployerを使った手動デプロイで発生したmigrateのエラーに関してご紹介していきます！

## エラー
Dockerコンテナから手動デプロイを実行
→migrateの実行時に「sqliteが存在しない」とエラーで指摘。


```
 [Deployer\Exception\RuntimeException (128)]                                            
  The command "cd /var/www/ && (/usr/bin/git clone -b "main"  --recursive  https://gith  
  ub.com/yu00212/laravel-zaikokanri.git /var/www//releases/1 2>&1)" failed.              
                                                                                         
  Exit Code: 128 (Invalid exit argument)                                                 
                                                                                         
  Host Name: LaravelWeb1                                                                 
                                                                                         
  ================                                                                       
  Cloning into '/var/www//releases/1'...                                                 
  fatal: could not read Username for 'https://github.com': No such device or address 
```

## 解決手順
今回の環境ではRDSでMySQLをつかっていますが、エラーではsqliteに関して指摘されました。
エラーの内容から、`.env`もしくは`/config/database.php`でsqliteの指定をしている可能性があると考えたので、EC2上に配置されているファイルを確認してみます。

確認したファイルのフルパスはこちらです。
`/var/www/アプリディレクトリ/.env`
`/var/www/アプリディレクトリ/config/database.php`

```
[ec2-user@ip-172-31-33-88 backend]$ cat .env

DB_CONNECTION=mysql
DB_HOST=????
DB_PORT=????
DB_DATABASE=????
DB_USERNAME=????
DB_PASSWORD=????
```

```
[ec2-user@ip-172-31-33-88 config]$ cat database.php

'default' => env('DB_CONNECTION', 'mysql'),
```

確認しましたが問題なくmysqlの設定がされていますね。。。

エラー文をもう一度読んでみると、`/var/www//releases/1'...`のパスが気になります。
クローンしたのは/var/www/アプリディレクトリ/のはず？

メンターに相談したところ、どうやら.envを他のディレクトリに配置しないといけないようです。
EC2でLaravelを使っている場合、EC2上の/var/www/下には`/shared`というディレクトリが作成されています。
ここに.envを配置させてあげる必要があるとのことなのでさっそく実施！

```
[ec2-user@ip-172-31-33-88 www]$ ls #sharedディレクトリありますね！
cgi-bin  html  laravel-zaikokanri  release  releases  sample  shared

[ec2-user@ip-172-31-33-88 www]$ chmod 777 shared #書き込みできるように権限の変更

[ec2-user@ip-172-31-33-88 www]$ ls #権限が変更できてれば、sharedが紫文字から緑に変わってます
cgi-bin  html  laravel-zaikokanri  release  releases  sample  shared

[ec2-user@ip-172-31-33-88 www]$ cd shared

[ec2-user@ip-172-31-33-88 shared]$ touch .env
[ec2-user@ip-172-31-33-88 shared]$ vi .env #アプリディレクトリと同じ内容で.envを編集
```

では、コンテナから再度デプロイしてみます！

```
root@5dfb0b5f66db:/work# ./vendor/bin/dep deploy LaravelWeb1 -vvv
・
・
・
Successfully deployed!
```

デプロイが成功しました！
.envの配置場所が違っているということには中々気づきずらいかと思うので、是非参考になれば幸いです！
VBAでファイルを読み込む

# VBAでファイルを読み込む

テキストファイルを読み込むにはOpenしてLine Inputで一行ずつ読み込む。
ただしVBAの外部ファイルはSJISを想定しているためUTF8のファイルを文字化けせずに読み込むことはできない。

~~~Visual Basic
Sub readfile(filepath As String)
    Dim buf As String
    Open filepath For Input As #1
        While Not EOF(1)
            Line Input #1, buf
            Debug.Print buf
        Wend
    Close #1
End Sub
~~~

# VBAでUTF8のファイルを読み込む

**ADODB.Stream** オブジェクトを使用してファイルを読み込む。
ReadTextでファイルを一括して読み込む。

または.ReadText(adReadLine)で一行ずつ読み込み
.EOSでファイルの終了を検知する。
.EOSの検知するのは.ReadTextより先に判定する。

~~~Visual Basic
Sub readutf8file(filepath As String)
    Dim buf As String
    Dim line() As String
    
    ' read file block
    With CreateObject("ADODB.Stream")
        .Charset = "UTF-8"
        .Open
        .LoadFromFile filepath
        buf = .ReadText
        .Close
    End With
    
    ' separate crlf
    line = Split(buf, vbCrLf)
    Dim i As Integer
    For i = 0 To UBound(line) - 1
        Debug.Print line(i)
    Next
End Sub
~~~

[参考](https://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_110_037.html)
Google Cloud Professional Cloud Architect ケーススタディ【EHR Healthcare】

Google Cloud Professional Cloud Architectのケーススタディ「[EHR Healthcare](https://cloud.google.com/certification/guides/cloud-architect/casestudy-ehr-healthcare?hl=ja)」の私なりの整理。
（あくまで私なりの整理です）

## ■会社概要
医療業界に電子カルテSWを提供する会社。
多国籍の医療機関、病院、保険会社にSaaSソリューションを提供。
※コンプライアンス、セキュリティ、可用性などかなりシビアな会社

## ■経営陣のメッセージ
・システムを停止させない
・スケーラブルで耐障害性に優れたプラットフォーム
・複数の環境をシームレスにつなぐ

## ■開発環境
新しい継続的デプロイ機能を導入して、ソフトウェアを頻繁に更新する必要がある。
→保険会社のオンボーディングを迅速化したい　`【CI/CDまわり】`
→新しい保険会社からデータを取り込んで処理するためのインターフェース`【DataFlow】`

## ■インフラ環境
顧客向けアプリはWebベース。最近はコンテナ化。
→コンテナベースのアプリを一貫した方法で管理 `【GKE、Anthos】`

## ■データ活用
データの保存はRDBとNoSQLが混在
→医療動向の知見の提供能力向上
　保険会社からのデータに基づいた業界動向を予測してレポート生成 `【BigQuery】`

## ■シームレス
オンプレ→Google Cloudへ置き換え。
オンプレ環境にファイルベース、APIベースのレガシーなシステムがある。
→オンプレとGoogle Cloud間の安全、安心な接続　`【Direct Interconnect】`

## ■ユーザ管理
ユーザ管理はMicrosoft Active Directory　`【Google Cloud Directory Sync】` 

## ■その他要件
・環境をスケール。　
　スケーリングとプロビジョニングを動的に行う `【オートスケーリング】`

・レイテンシー低減　`【CDN】【グローバルLB】`

・障害復旧計画。顧客向けシステムの可用率99.9%以上

・コスト削減

## ■運用
・モニタリングはオープンソースツールを活用。ただし、アラートが度々無視される。
　→システムのパフォーマンスと使用状況を一元的に可視化。プロアクティブな対応を可能とする。
　→一貫性のあるロギング、ログ保持、モニタリング、アラートの機能の提供
`【Stackdriver】【Cloud Storage】`

■法令遵守
・機密情報の保持`【IAM】【リソースマネジメント】【VPCサービスコントロール】`
・鍵管理`【KMS】`
・コンプライアンス監査→[Google Cloud Platform での HIPAA コンプライアンス](https://cloud.google.com/security/compliance/hipaa)
Hyper-V と VirtualBox を同一マシン上で実行する

# 背景

あるプロジェクトでは VirtualBox を利用して環境を作っていて、そこに Lando 環境を作りたくて、Hyper-V も有効にする必要がでてきた。
備忘のため、やれそうなことを調べた結果をまとめておく

# Lando をインストールしようとしたら

下記の記載があった。  

> ### Optional checks
>
> * If you already have Docker installed it needs to be set to factory defaults.
> * If you are also running VirtualBox on Windows check out [this](https://docs.lando.dev/help/win-also-vb.html).

以下、this のページのまとめ。

## Windows is also running VirtualBox

> > 同一マシン上に VirtualBox と Hyper-V を共存させることはできない。一度に実行できるハイパーバイザーは1つのみで、Hyper-V が常に実行されるため、VirtualBox は起動できない。
> 
> 上記について、[こちら](https://derekgusoff.wordpress.com/2012/09/05/run-hyper-v-and-virtualbox-on-the-same-machine/)のページに回避策がある。

ということなので、さらに飛んで確認する

## Run Hyper-V and VirtualBox on the same machine

> bcdedit を使用してブート構成を変更することでできるぞ！

ということらしい。

# 回避方法

1. VirtualBox を使用するために Hyper-V を無効にするには、管理者としてコマンド プロンプトを開き、次のコマンドを実行する。
    ```
    bcdedit /set hypervisorlaunchtype off
    ```

2. 再起動する

これによって、VirtualBox を実行できるように設定されるらしい。

# 戻す場合

1. Hyper-V を再度オンにするには、次のコマンドを実行します。
    ```
    bcdedit /set hypervisorlaunchtype auto
    ```

2. 再起動する
PEP 8 による暗黙の仕様

# シーケンスの長さを判定するケース

list,tuple,str などのシーケンスの場合、長さ 0 の判定では

```python:
if seq:      # PEP 8 - OK
if len(seq): # PEP 8 - NG
```

とされているようです。


# この記述がトラブルとなるケース

独自クラスやモジュールでシーケンスに対応しつつ

　　**中身が特定パターンのときに \_\_bool\_\_() が True （長さが 0 でなくても False）を返す**

オブジェクトを作ると不具合の原因になりかねません。

```python:どう呼び出されるかのテスト(シーケンス非対応だが)
class A:
    def __init__(self): pass

    def __bool__(self):
        print('A.__bool__')
        return False

    def __len__(self):
        print('A.__len__')
        return 1


class B:
    def __init__(self): pass

    def __len__(self):
        print('B.__len__')
        return 1

a = A()
if a:
    print('if a >> TRUE')
else:
    print('if a >> FALSE')
if len(a):
    print('if len(a) >> TRUE')
else:
    print('if len(a) >> FALSE')

b = B()
if b:
    print('if b >> TRUE')
else:
    print('if b >> FALSE')
if len(b):
    print('if len(b) >> TRUE')
else:
    print('if len(b) >> FALSE')
print('bool(b) >>', bool(b))
```

```text:ターミナルでの実行結果
$ python3 sample.py
A.__bool__
if a >> FALSE
A.__len__
if len(a) >> TRUE
B.__len__
if b >> TRUE
B.__len__
if len(b) >> TRUE
B.__len__
bool(b) >> True
$
$ python3
>>> l = list()
>>> l.__bool__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute '__bool__'
>>> l.__len__()
0
>>> bool(l)
False
>>> s = str()
>>> s.__bool__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__bool__'
>>> s.__len__()
0
>>> bool(s)
False
>>> t = tuple()
>>> t.__bool__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute '__bool__'
>>> t.__len__()
0
>>> bool(t)
False
```

if 文では \_\_len\_\_() より \_\_bool\_\_() が優先されることが分かる。

list, str, tuple は \_\_bool\_\_() を持っていないらしい。


# PEP 8 に従うならば

シーケンスを扱う PEP 8 準拠のプログラムに、独自のオブジェクトを渡すのならば

```python:
    def __bool__(self):
        return self.__len__() != 0
```

長さを調べて 0 かどうか（上記相当）以外の処理を \_\_bool\_\_() メソッドで作るのはやめたほうがいいことになります。

世の中のプログラムが PEP 8 準拠ばかりならば、事実上の仕様と考えた方がよさそうです。

シーケンスに対応しつつ、シーケンスの中身で \_\_bool\_\_() の戻り値を決めるオブジェクトを作った場合、それをシーケンス処理が出来る他所のプログラムに渡すには、長さが 0 のときの判定方法を確認する必要がありそうです。\_\_bool\_\_() で判定していないかを…

---

この地雷は以前踏んだので、シーケンスの長さで判定する処理は必ず len を書くようにしている。
Rails タグ編集・一覧・詳細機能とコードの解説

# コントローラの作成
```posts_controller.rb
 def index
    @posts = Post.all.order(created_at: :desc)
    @tag_list = Tag.all #ビューでタグ一覧を表示するために全取得。
  end

  def show
    @post = Post.find_by(id: params[:id]) #クリックした投稿を取得。
    @post_tags = @post.tags   #そのクリックした投稿に紐付けられているタグの取得
  end

  def edit
    @post = Post.find_by(id: params[:id])
    @tag_list = @post.tags.pluck(:tag_name).join(',')
  end
  def update
    @post = Post.find_by(id: params[:id])
    @post.content = params[:content]
    tag_list = params[:post][:tag_name].split(nil)
    if @post.save
      @post.save_tag(tag_list)
      flash[:notice] = '投稿を編集できました！'
      redirect_to('/posts/index')
    else
      flash[:notice] = '投稿は100文字以内で入力してください'
      render('posts/edit')
    end
  end
```
# 投稿詳細ファイルの作成
```posts/show.html.erb
 <%@post_tags.each do |tag|%>
 <%=link_to(tag.tag_name, tag_posts_path(tag_id: tag.id))%>
　　#タグに関する投稿数の取得
 <%="#{tag.posts.count}"%> 
 <% end %>
```
# 投稿一覧ファイルの作成
```posts/index.html.erb
<h3> タグリスト</h3>
<% @tag_list.each do |list|%>・・１
<%= link_to(list.tag_name, tag_posts_path(tag_id: list.id))%>・・２
<%="#{list.posts.count}"%>投稿//現在そのタグを持つ投稿が幾つ存在するかをカウントして表示
<% end %>
```
##  コードの解説
１・・indexアクションで全取得したタグを全て表示
２・・そのタグに関連する投稿を表示するパスへのリンクを張りこのリンクをクリックすることで、そのタグに関連付けられた投稿を表示
# 参考記事
[[Ruby on rails]タグ付け機能① 複数のタグ付け](https://qiita.com/ki_87/items/a344ea566c88b10b950c)
[[Ruby on rails]タグ付け機能① 複数のタグ付け](https://qiita.com/ki_87/items/a344ea566c88b10b950c)
[]()
7つのアクション以外のアクション

オリジナルアプリでグループ共有で使えるカレンダーアプリを作成中。

昨日マイページをルートパスに設定しようとしたところ、パラメーターはルートパスに設定するのは難しいと知り、急遽ルートパスの変更を余儀なくされた。
どんなページに遷移させようか考えた末、グループ登録のページをルートパスにしようと思いついた。

### やりたいこと
まず実装させたいことは、
①グループの新規作成ボタン（sign_in）
②既存グループで自信が未参加のグループへ参加するボタン(sign_up)
③自信が参加中のグループへログインするボタン
以上3点である。

そこで新たに行き詰まったのは、これらのボタンを実装させるためには、どういったアクションがベストなのか、ということ。

まずこのアプリを作る上で意識していることは「シンプルで使いやすいアプリ」である。
ユーザーにはできるだけクリックする回数や入力の手間を省きたいと考えている。
要は③を実装するにあたり、「eachメソッドを使って参加中のグループを一覧として表示させ、グループ名をクリックするだけで、該当ページへ遷移する」といった実装を行いたいわけである。
上記を踏まえると、indexアクションが妥当か？と思ったが、ユーザーコントローラーのindexアクションだと、なんとなくユーザー一覧の表示というイメージがある。

そこで考えたのは、7つのアクション以外のアクションを定義しようと結論に至った。

### アクションを定義する前に
初めての試みなので、いろいろ調べてみると、7つのアクション以外でルーティングを定義する時には、collectionかmemberを使用するということ。
collictionはidが紐つない。
逆にmemberはidを紐つけることができる。

今回はgroup_idが関連してくるので、memberを選択することに。

### コードを記述
では、さっそくコードを書いてみる。

ちなみに今回定義したいアクション名は**toppage**アクション
ますは``config/routes.rb``と``users_controller.rb``へ記述する。

```ruby:config/routes.rb
Rails.application.routes.draw do
  devise_for :users, controllers:{
    registrations: 'users/registrations',
    sessions: 'users/sessions'
  }
  root to: "users#toppage"
  resources :users, only: [:show, :edit, :create]do　　#doを追記
    member do            #追記
      patch 'toppage'　　　　　　　　#追記
    end　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　#追記　
  end　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　#追記　
end
```

```ruby:users_controller.rb
class UsersController < ApplicationController

  def toppage  #追記
  end　　　　　　　　　　　　　　　　　　　　　#追記

#以下省略
```

続いてビューファイル
```erb:toppage.html.erb
<%# 共通部分%>
<%= render "share/header" %>
<%# 共通部分ここまで%>

<div class="main">
  <div class="hello">
    <h1>HELLO!! </h1>
  </div>
  <div class="message1">
    <p>グループを作成、またはグループに参加、</p>
  </div>
  <div class="message2">
    <p>もしくは参加中のグループを選択してください</p>
  </div>
  <ul class="center-display">
    <li><%= link_to "グループを作成する", "#" , class: "create-group" %></li>
    <li><%= link_to "グループに参加する", "#" , class: "join-group" %></li>
  </ul>

   <%# 参加中のグループの有無で表示を変える%>
  <div class="created-group">
    <div class="joined-group">
      <p>参加中のグループ</p>
      <%# if current_user.gropus == nil %>
        <div class="no-group">
          <P>まだ参加していません</p>
        </div>
      <%# else %>
        <div class="your-group">
            <div class="groupーlist">
              <%# current_user.groups.each do |group| %>
                <div class="group">
                  <%#= link_to group.name, "#",  class: "group-name" %>
                </div>
              <%# end %>
            </div>
        </div>
      <%# end %>
    </div>
  </div>
```

参加中のグループの有無で表示を変えるように条件分岐をした。

まだ色々と未実装の部分がおおいが、ひとまず無事に完了！
新しい知識がまた一つ追加された！！
【初心者向け】asdfを使用したPythonの環境構築

## はじめに
筆者の環境は以下のとおりです。
　・VSCodeを使用
　・Windows10にてWSL2でUbuntu20.04LTSを使用
　・Bash、Gitを使用

上記にasdfを使ってPythonを入れる予定です。

Pythonのセミナーを受講するにあたり、環境構築が必要になったため
どうせならasdfも使ってみようと思いメモ代わりに記述します。

元々、anyenvを使用していましたが
GitHubの更新が停滞していること、
ロードに時間がかかることを加味し、
乗り換え時かな、と個人的に考えたためこのタイミングで導入してみます。

https://github.com/anyenv/anyenv

## asdf導入編
以下の公式サイトを参考に進めます

https://asdf-vm.com/guide/getting-started.html#_1-install-dependencies

※大元が気になる方は以下のリポジトリを参照してください

https://github.com/asdf-vm

ふむふむ、どうやら全6工程あると…
今回はPythonなので工程の3まで実施します。
(4～はデモ用に Node.js を設定する手順で、今回は不必要なため除きます)
とりあえず、順にやってみましょう。

◇手順1
後の手順で「curl」、「Git」の2つが必要になるので、
あなたが使っているパッケージマネージャ(aptとかDNFとか)に合わせて
コマンド実行してインストールしといてね、ということです。

筆者は素のUbuntuなのでAptitude(apt install curl git)です。
※筆者は既にcurlもGitもインストール済みのため、今回実行しておりません。

◇手順2
筆者はGitを使用しているので前述の通り、
Gitを介してasdfをインストールします。

```bash
# 〇の部分は任意のバージョンを指定してください
$ git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v◯◯.◯◯.◯◯
```

今回は手順に記載の通りv0.9.0を指定します。

◇手順3
筆者の環境はBashとGitなので「Bash＆Git」の方法です。
(ご自身のシェル等の種類に沿った手順を参照してください)

```bash
# viもしくはvimでbashの設定ファイルを開きます
# (linuxの各エディタ操作方法は記載しないので調べてください)
$ vim ~/.bashrc

# 最下行に以下を追記(windowsで言うところのPATHを通すようなものだと思ってください)
. $HOME/.asdf/asdf.sh

# コマンドの補完を有効にしたい場合は更に以下を追記してください
. $HOME/.asdf/completions/asdf.bash

# 追記後、保存して閉じる

# asdfが使えることを確認する(インストールしたバージョンが表示されればok)
$ asdf --version
```

ここまでで、asdfの準備はできました。

## Python導入編
ここからはコマンドだけざっと書いてしまいます。
(時間があれば再編集するかもしれません)

```bash
# Pythonのプラグインを追加する
$ asdf plugin-add python

# インストールできるPythonを一覧で表示する
# 念の為の確認なので必要であればgrepで絞ってください
$ asdf list-all python

# 一覧にあることを確認し、Pythonをインストールする
# ◯.◯.◯ の部分は任意で指定してください。
$ asdf install python ◯.◯.◯

# 指定したバージョンのPythonがインストールされたことを確認する
$ asdf list python

# グローバルで使用するPythonのバージョンを指定する
# ◯.◯.◯をインストールしたバージョンと一致させてください
$ asdf global python ◯.◯.◯

# auto reshimがうまくいかないissueがあったので念の為
# 手動でシンボリックリンクを設定する(貼り直す)
$ asdf reshim python

# インストール、設定したPythonが表示されるか確認する
$ python -V

# pipenvが必要な人は別途以下のコマンドを活用して入れてください
# おまけ程度の記述なので不安な方は実行前にコマンドを調べてください
$ pip install --upgrade pip
$ pip install pipenv
$ asdf reshim python
$ pipenv --version
$ asdf which pipenv
```

## おまけ(VSCodeでの実行確認まで)
画像があれば分かりやすいのですが、
筆者の「めんどくさい」という理由で一切ないです。
おまけなのでご了承ください。

まず、VSCodeを起動してください。
左側面のツールバーに表示されている「拡張機能」というアイコンを
クリックしてください。(Ctrl + Shift + xでも同じウインドウが表示されます)

開いたら「Marketplaceで拡張機能を検索する」と書いてある検索フォームに
「Python」と入力してください。
そうすると「Python」という拡張機能が候補として表示されます。
(他に「Python◯◯」という様々な拡張機能が表示されますが、
「Python」とだけ書いてあるモノをクリックしてください)

表示された拡張機能をクリック後、
水色の「インストール」ボタンをクリックし、インストールしてください。

以下はインストールできた後の動作確認です。
VSCode上部メニューより、「ファイル」-「新規ファイル」をクリック、新規ファイルを作成します。

作成したファイルにPythonのコードを記述し、「〇〇.py」というファイル名で保存します。
以下は「Hello World!」と表示する例です。
```python
print('Hello World!')
```

記述・保存後、ファイル名の右端にある
再生ボタンのような形の三角形のアイコン(Run Python File)を押下します。

以下のようなメッセージが表示され、実行が確認できれば環境構築完了です。
(セキュリティ上ぼかしている箇所がございます)
``` bash
hoge $ ~/.asdf/shims/python◯.◯ ~/◯◯.py
Hello World!
```

## おわりに
勢いで書いたため、表記ゆれや
分かりにくい部分もあるかもしれませんが、
少しでも何かの役に立てば幸いです。
(今後、もしかしたら見返して修正するかもしれません)
sailでテスト用データベースに接続できないときの対処法

[Laravelのtestで画面回りのテストをする](https://qiita.com/apricotcomic/items/76a5c4cf63dbd0e1b39c)を参考に、
テスト用の.env.testingを作成し、
mysqlでhoge_testingデータベースを作成し、
マイグレーションをしようとしたところ、
`SQLSTATE[HY000] [1044] Access denied for user 'sail'@'%' to database 'hoge_testing' `とのエラーが出た。
sailにテスト用データベースの権限を与えれば良い

mysqlのコンテナに接続
```
docker container exec -it [ハッシュ値] bash
mysql -u root -p
```
sailにテスト用データベースの全てのテーブルに対し全権限を与える。
```
mysql> grant all on hoge_testing.* sail;
```
ガウス過程とはなにか

# はじめに
研究でガウス過程回帰が必要になったので、『ガウス過程と機械学習』（講談社，著：持橋 大地，大羽 成征）で勉強を始めました。勉強開始時、ガウス過程が以下のように表現されているのは知っていました。
- 無限次元のガウス分布
- ランダムに関数 $f$ を出力する箱

ある程度理解できるとこの表現の通りだとわかるのですが、初読時にこれらを理論的に理解するのに苦戦しました。

これから勉強される方がこれらのとっつきから理論へスムーズに進めるよう、私なりの説明を残しておきます。本記事では、上の表現が以下のように補足されることを述べます。
- ガウス過程は、無限個の入力に対してガウス分布を与えるものである。（分布自体ではない）
- ガウス過程によって与えられた分布から、各入力に対する出力をサンプリングし、それらの対応をまとめたものが関数 $f$ であり、$f(x)=x^2$ のような具体的な関数形が得られるわけではない。

# 目次
<!-- タイトルとアンカー名を編集 -->
[1.ガウス過程とは](#1-ガウス過程とは)
[2.まとめ](#2-まとめ)

# 1. ガウス過程とは
まずは「（確率）過程」[^1]という言葉を理解しましょう。

- （確率）過程：入力 $x$ に対して確率分布 $p(y)$ を与えるもの。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594096/4cd1a8ae-e603-a27d-4a16-810f2ef46b5c.png)

入力が入ったとき、関数が出力を確定的に返すのに対し、過程は出力についての確率分布を返します。この確率分布 $p(y)$ がガウス分布である過程を特にガウス過程といいます。入力 $x$ に対して具体的な出力 $y$ を得るには、この確率分布 $p(y)$ からサンプリングすればよいです。

では、ガウス過程が「ランダムに関数 $f$ を出す箱」と呼ばれる理由を説明します。
説明のために、ガウス過程のより厳密な定義を以下に載せます。
>Def. ガウス過程
>入力 $x_1, x_2, \ldots, x_N$（$N$は任意の自然数）に対応する出力のベクトル
>$$\vec{f} = (f(x_1),f(x_2),\ldots,f(x_N))$$
>が，平均を $\mu = (\mu(x_1),\mu(x_2),\ldots,\mu(x_N))$，共分散行列を $K$ $(K_{i,j}=k(x_i,x_j))$とする [^2]ガウス分布 $\mathcal{N}(\mu,K)$に従うとき，関数 $f$ はガウス過程に従うといい，
>$$f \sim \mathcal{GP}(\mu(x),k(x_i,x_j))$$
>と書く．

この定義で、$N$は任意の自然数なので $N \to \infty$ として、無限個の入力 $x_k$ $(k=1,2,\ldots)$ を考えてもよいです。無限個の入力を決定すると、平均 $\mu$ と共分散行列 $K$ が決まり、無限次元のガウス分布 $\mathcal{N}(\mu,K)$ ができます。そしてサンプリングによって、この分布から各入力 $x_k$ に対する出力 $y_k$ がそれぞれランダムに決まります。得られた入出力の組$$(x_1,y_1),(x_2,y_2),\ldots$$をプロットすると以下の図のようになります。（簡単のため入力は１次元としています。）
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594096/f3975be8-7dc3-e0c2-0e8b-1a382676e574.png)

図を見ると、何かグラフが浮かび上がっているように見えます。これがガウス過程によって生成された関数（箱から出た関数）のグラフです。しかし、この関数は $f(x)=x^2$ のように具体的に書けるわけではありません。イメージとしては、$x$ と $y$ の大きな対応表が得られたような状態になります。

以上が、ガウス過程（箱）から関数が出る説明になりますが、ガウス過程を理解するポイントは以下の認識だと思います。

　「具体的な関数形（$f(x)=x^2$とか）ではなく、任意の入力 $x$ から出力 $y$ への対応が出てくる 」

「入出力の対応＝関数」は確かにそうなんですが、それが$f(x)=～$の形で統一的に書けると思い込むとわかりづらくなると思います。

# 2. まとめ
ガウス過程から関数が出てくる流れは以下のようになります。
（１）入力 $x$ を決定
（２）ガウス分布 $\mathcal{N}(\mu(x), k(x_i, x_j))$ を計算
（３）$\mathcal{N}(\mu(x),k(x_i, x_j))$ から入力 $x$ に対する出力 $y$ をサンプリング
（４）任意の入力 $x$ と出力　$y$ の対応（関数）が出る

ご意見・ご指摘がございましたら、コメントまでお願いします。

本記事をお読み頂き、ありがとうございました。

[^1]:元々、理論の対象が時系列データ（入力 $x$ が時刻 $t$ ）だったので「過程」という語が使われているようですが、「確率場」と置き換えるとわかりやすいように感じました。この換言は [ガウス過程回帰の基礎（赤穂 昭太郎）](https://www.jstage.jst.go.jp/article/isciesci/62/10/62_390/_article/-char/ja) に記載がありました。
[^2]:$\mu(x)$は平均関数、$k(x_i,x_j)$はカーネル関数と呼ばれる関数です。
ディレクトリ検索

# VBAのディレクトリ検索

Dir()関数を使う。
Dir()関数は初回検索時に検索パスとファイルパターンを与え、2回目以降は引数を持たない。
Dir()関数の戻り値が””のときはそれ以上のファイルはない。
デフォルトではDir()は実ファイルしか検索しない。
またDir()は再帰的には呼べないので一度全部読みだす。

## 単純検索（サブディレクトリは検索しない）

~~~Visual Basic
Sub main()
    traverse ("D:\download")
End Sub

Sub traverse(path As String)
    Dim leaf As String
    leaf = Dir(path & "\*")
    While leaf <> ""
        Dim fullpath As String
        fullpath = path & "\" & leaf
        Debug.Print fullpath
        leaf = Dir()
    Wend
End Sub
~~~

## 再帰的検索

Dir()は再帰的に使用することができないためディレクトリは一気に読み込む必要がある。
Dir()の第二パラメータにいろいろなフラグを立てないとそのフラグを持つファイルが検索できない。
イメージとしては

検索該当 =（ファイルタイプビットマップ ＆ ～検索タイプマスク) == 0

少なくともDir()の第二パラメータにvbDirectoryを指定しないと、ディレクトリは検索できない。
またこれによりDir()はファイルやディレクトリ以外のものも検索可能なため
実際に何が検索できたかどうかはGetAttr()にファイルパターンマスクのアンドと取って調べなくてはならない。
以下のソースのdir dealerとfile dealerにそれぞれ希望のファイル処理を実装または呼び出す。
dir dealerは特にディレクトリの処理に興味がなければなくてもよい。

~~~Visual Basic
Sub subtraverse(path As String)
    ReDim leafs(1)
    Dim i As Integer
    i = 0
    Dim leafnumber As Integer
    
    'scan directory
    Dim leaf As String
    leaf = Dir(path & "\*", vbNormal + vbHidden + vbReadOnly + vbSystem + vbDirectory)
    While leaf <> ""
        If UBound(leafs) < i Then
            ReDim Preserve leafs(2 * UBound(leafs))
        End If
        leafs(i) = leaf
        i = i + 1
        leaf = Dir()
    Wend
    leafnumber = i

    'deal directory
    For i = 0 To leafnumber - 1
        Dim fullpath As String
        fullpath = path & "\" & leafs(i)
        If GetAttr(fullpath) And vbDirectory Then
            If leafs(i) <> "." And leafs(i) <> ".." Then
                subtraverse (fullpath)
                ' dir dealer
                Debug.Print "dir ", fullpath
            End If
        Else
            ' file dealer
            Debug.Print "file", fullpath
        End If
    Next
End Sub
~~~
HTMLのinputの配列は添字に key が指定できる

## はじめに
inputで入力された値をphp側で把握してdbに登録したいようなケースがあるよな（例えばマスタとして全量が登録してあって、そのなかから取り扱ういくつかを選択して、以降は選んだものだけを表示する管理画面みたいなやつな）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94562/27982df3-3863-99d7-5e2b-8801ce9d1e74.png)

探すと `name="use_cert[]"` みたいにやるんだぜ、って出てくるんだけど、配列の index は 0ベースである。stackoverflow を当たっても javascript で上書きするようなやり方しかねぇ。
・・・上書き？:rolling_eyes:　ふとひらめいた

https://www.google.com/search?q=html+input+%E9%85%8D%E5%88%97&oq=html+input+%E9%85%8D%E5%88%97&aqs=chrome..69i57j0i512j0i30l2j0i8i30l4.6214j0j7&sourceid=chrome&ie=UTF-8

https://stackoverflow.com/questions/21295760/get-nth-key-value-of-input-array

[IT女子の仕事メモ｜php checkboxのオン/オフ（checked）の値を取得](http://none.3rin.net/wordpress/php%20checkbox%E3%81%AE%E3%82%AA%E3%83%B3-%E3%82%AA%E3%83%95%EF%BC%88checked%EF%BC%89%E3%81%AE%E5%80%A4%E3%82%92%E5%8F%96%E5%BE%97)

## 結論
あっいけるじゃん。えっ？これって見つけちゃったってやつ？:sunglasses:

```html:配列に変数つっこめるじゃん
<table>
    <thead>
    <tr>
        <th>使う</th>
        <th>資格名</th>
    </tr>
    </thead>
    <tbody>
    <?php foreach ($certifications as $k => $v) : ?>
        <tr>
            <td><label><input type="checkbox" name="use[<?= $k ?>]" <?= $v['checked'] ?>></label></td>
            <td><label><input type="text" name="name_short[<?= $k ?>]" value="<?= $v['name'] ?>"></label></td>
        </tr>
    <?php endforeach; ?>
    </tbody>
</table>

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94562/cbdfdd42-4f06-dd45-1585-5c82abbb0d18.png)