OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub ActionsからGitHub Container RegistryにDockerイメージをpushする


GitHub Container Registryそのものやコマンドによるpushは、[GitHub Container Registry(ghcr.io)にDockerイメージをpushする手順](https://qiita.com/zembutsu/items/1effae6c39ceae3c3d0a)で詳しく説明されていますので、そちらをご覧ください。

## 手順

### 概要

GitHub ActionsからDockerHubにDockerイメージをpushする手順がGitHub Docsにあります（[手順のドキュメント](https://docs.github.com/ja/actions/language-and-framework-guides/publishing-docker-images)）。
今回はそれを流用し、push先をGitHub Container Registry(ghcr.io)に向けるだけです。

### GitHub Container Registry(ghcr.io)へのログイン情報の設定

GitHubアカウントの設定からPersonal Access Token(PAT)を作成します（[手順のドキュメント](https://docs.github.com/ja/github/authenticating-to-github/creating-a-personal-access-token)）。
権限として、`read:packages` と `write:packages` にチェックします。
作成したPATをGitHubリポジトリに暗号化されたシークレットとして保存します（[手順のドキュメント](https://docs.github.com/ja/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository)）。
ここでは `CR_PAT` というキーで保存します。

### ワークフロー(GitHub Actions)の作成

[GitHub Packagesへのイメージの公開](https://docs.github.com/ja/actions/language-and-framework-guides/publishing-docker-images)ドキュメントを参考にワークフローを作成します。
変更するポイントは
- `GitHub Packages` を `GitHub Container Registry` に置換
- `docker.pkg.github.com` を `ghcr.io` に置換
- `${{ secrets.GITHUB_TOKEN }}` を `${{ secrets.CR_PAT }}` に置換
- `repository:` の値を `${{ github.repository }}` に変更

以下にGitHub Container Registry(ghcr.io)にpushするワークフローを示します。

```yaml:.github/workflows/docker-publish.yml
name: Publish Docker image
on:
  release:
    types: [published]
jobs:
  push_to_registry:
    name: Push Docker image to GitHub Container Registry
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repo
        uses: actions/checkout@v2
      - name: Push to GitHub Container Registry
        uses: docker/build-push-action@v1
        with:
          username: ${{ github.actor }}
          password: ${{ secrets.CR_PAT }}
          registry: ghcr.io
          repository: ${{ github.repository }}
          tag_with_ref: true
        env:
          DOCKER_BUILDKIT: 1
```

### 検証

上記のワークフローの例では、GitHub リリースの公開をトリガーに動作するため、公開して検証します。
検証の内容も[GitHub Container Registry(ghcr.io)にDockerイメージをpushする手順](https://qiita.com/zembutsu/items/1effae6c39ceae3c3d0a)でされていますので、そちらをご覧ください。

## まとめ

GitHub Container Registry(ghcr.io)の説明など諸々と省きましたが、GitHub ActionsでGitHub Container Registry(ghcr.io)にpushするワークフローを紹介しました。
とても簡単にできますので、ぜひ活用ください。
【Vuetify.js】モダンなダイアログで、フォーム送信しよう


jQuery UI等を使って、自作でダイアログを作ることができるが、手っ取り早くモダンな感じのダイアログを作るにはVuetifyがおすすめです、

今回は、記事を追加するフォームをダイアログで作成して、そのまま送信してみたいと思います。


ソースコードの全体像は以下になる。

```vuejs:
<template>
  <v-dialog v-model="dialog" max-width="600px">
    <!-- ベント発火するコンポーネント -->
    <template v-slot:activator="{ on, attrs }">
      <v-btn v-on="on" v-bind="attrs">記事を追加</v-btn>
    </template>

    <!-- ダイアログ本体 -->
    <v-card>
      <v-card-text>
        <v-container>
          <v-row>
            <v-col cols="12">
              <v-text-field label="RSS" v-model="rssForm.url" required></v-text-field>
            </v-col>
          </v-row>
        </v-container>
      </v-card-text>

      <v-card-actions>
        <v-spacer></v-spacer>
        <v-btn color="blue" text @click="dialog = false">Close</v-btn>
        <v-btn color="blue" text @click="addFeed">追加</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>
```

#ダイアログを表示する、イベント発火するコンポーネント

```vuejs

<template>
  <v-dialog v-model="dialog" max-width="600px">
    <template v-slot:activator="{ on, attrs }">
      <v-btn v-on="on" v-bind="attrs">記事を追加</v-btn>
    </template>
  ・・・
  </v-dialog>
</template>
```

記事を追加するボタンを押すと、ダイアログが表示できるようにする。
`template`のなかに`template`と、奇妙なかたちだが、v-slot等を駆使して連動させている。


#ダイアログの本体

```vuejs

<template>
  <v-dialog v-model="dialog" max-width="600px">
  ・・・
    <v-card>
      <v-card-text>
        <v-container>
          <v-row>
            <v-col cols="12">
              <v-text-field label="RSS" v-model="rssForm.url" required></v-text-field>
            </v-col>
          </v-row>
        </v-container>
      </v-card-text>
      <v-card-actions>
        <v-spacer></v-spacer>
        <v-btn color="blue" text @click="dialog = false">Close</v-btn>
        <v-btn color="blue" text @click="addFeed">追加</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</tempalte>

<script>
export default {
  data () {
    return {
      dialog: false,
      rssForm: {
        url: ''
      }
    }
  },
  methods: {
    addFeed: async function () {
      // 記事を追加
      const res1 = await this.$axios.$post('/api/v1/feeds', {
        feed: this.rssForm
      })
      this.dialog = false
      this.rssForm = ''
    }
  }
}
</script>
```

`<v-text-field>`
フォームの入力部分になる。

`<v-btn color="blue" text @click="addFeed">追加</v-btn>`
あとは、入力内容をaddFeedというメソッドを定義することで、APIに送信できるようにすれば良い


`<v-btn color="blue" text @click="dialog = false">Close</v-btn>`
いわゆるキャンセルボタンにあたる。
dialogデータの論理値をfalseにすることで、ダイアログを閉じるようにしている。
KivyによるGUIのアプリケーション化（matplotlib含む）

今回はKivyによるGUIにてグラフを表示する機能を実装したアプリを配布しようとして、
少し引っかかったので忘備録として。環境はWindows10

# 1. 必要ライブラリのインポート
matplotlibをKivy内で有効化する為、Kivy-Gardenをインポートする。
後にpyinstallerにてexe化するが、その際にgardenのディレクトリを見失うようなので、
matplotlibは--kivyを使用してインストールする。

```
$ pip install kivy-garden
$ garden install matplotlib --kivy
```

# ２. pyinstallerにてexe化
仮想環境にてpipで必要最低限のライブラリのみインストールする。
(anacondaだったりpyenvだったり仮想環境構築については省略)
不要なものが多いと200~300Mbの巨大exeファイルが誕生する...

```
$ pip install pyinstaller pypiwin32 #この二つは必須

#こいつらはkivyのインストールについてこないのでインストールが済んでいなければ忘れずに。
$ pip install kivy_deps.sdl2 kivy_deps.glew 
$ pip install 必要なライブラリ          #pyファイルに必要なライブラリ全て
```

# 3. パッケージ化
準備完了です。作業ディレクトリをpythonファイルに移動して以下を実行。
pyinstallerには色々とパッケージングの便利機能がありますがここでは
ファイルを一つにまとめてくれる--onefileを使用。

```
$ pyinstaller ***.py --onefile
```
作業ディレクトリに色々と生成されるが、とりあえずdistないにexeファイルが生成。
この状態だとまだGUIは立ち上がらない。

```
# 作業ディレクトリ内
***.py
***.kv
***.spec
dist
pycache
build
```

# 4. specファイルの編集
次にGUIを有効化するためにSPECファイルに依存関係などを記述していく。

```
#以下specファイル
> ***.spec

from kivy_deps import sdl2, glew  # 追加箇所①
block_cipher = None
a = Analysis(['＊＊＊.py'],
             pathex=['c:\\パッケージ化したディレクトリ'],
             binaries=[],
             datas=[],
             hiddenimports=[]
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],  # 追加箇所②
          name='main',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=True )

# 追加箇所③
coll = COLLECT(exe, Tree('c:\\kivyファイルのディレクトリ'),
               a.binaries,
               a.zipfiles,
               a.datas,
               *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
               strip=False,
               upx=True,
               name='main')
```

自分の場合は、pythonファイルと同ディレクトリに***.kv用にフォルダ（Layoutなどのフォルダ）を作成して入れてあげた。（あまり意味ないかもだが、collect処理で不要なものも拾わないように）

```
# 最後に以下を実行
$ pyinstaller ***.spec --onefile
```

# ５. 完成
下記のディレクトリにmainフォルダが生成しており、その中に新たなexeファイルが生成している。
この中には依存関係全てのファイルが存在していて、アプリ配布の際にはこのmainフォルダごと
必要になる。（もっと単一化できるとおもう。つーか今の自分にはこれが限界。）
どこかのディレクトリに隠しつつ、exeファイルのショートカットだけ上手いこと使ってもらえれば
それっぽくなると思い妥協した。

```
dist
|_main    # ←この中に新しいexeファイル
|_***.exe
```


特にmatplotlib==3.1.1を使用したが、最新だとできないような情報も見かけた。

とりあえず、これでGUIアプリケーションを配布可能になった。
【Flutter】もしかしたら最高のSharedPreferencesの使い方を思いついてしまったかもしれないので公開する

# 概要
shared_preferencesは割と必須パッケージになってきていると思います。
そんな中で、弱点を補う方法を思い付いたので公開しました。

詳しくはこちらのブログへどうぞ。

[【Flutter】もしかしたら最高のSharedPreferencesの使い方を思いついてしまったかもしれないので公開する](https://blog.dalt.me/2356)
batファイルで日付を取得

#目的
batで日付取得して使いたいとき。
たまにしか使わずすぐ出てこないのでメモ。

```bat:setdate.bat
set YYYY=%date:~0,4%
set MM=%date:~5,2%
set DD=%date:~8,2%
set TIMESTAMP=%time: = 0%
set HH=%TIMESTAMP:~0,2%
set MI=%TIMESTAMP:~3,2%
set DATETIME=%YYYY%%MM%%DD%%HH%%MI%

echo %DATETIME%

```

##過去使用した場面
* oracleのexpdp/impdpでlog/dmpファイル名称のprefix
* Windowsのサービス上げ下げするバッチの日時記録
【Laravel】マイグレーションでテーブルを作成する

こちらの記事は以下の書籍を参考にアウトプットとして執筆しました。
[PHPフレームワーク Laravel入門 第2版](https://www.amazon.co.jp/dp/B08625YD7H/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

マイグレーションでテーブルを作成する手順は以下

1. 専用スクリプト作成
2. スクリプトへ記述
3. マイグレーションの実行 

今回は以下のテーブルを作成していく

テーブル名はmembers

|カタム|フィールド名|
|---|---|
|ID|	id|
|作成日時|created_at|
|ユーザー名|name|
|パスワード|password|
|メールアドレス|email|
|プロフィール写真|icon|


#専用スクリプト作成
**カレントディレクトリへ移動して以下のコマンドを実行**

```
$ php artisan make:migration ファイル名
```

**ファイル名はどのような作業をするのかをわかるようにしておく。**
例えば
今回のような場合は作成するのであれば

```
$ php artisan make:migration create_members_table
```
としてファイルを作成する。

##databaseフォルダをチェック
作成したファイルは`database/migrations`の中に作成される。
##マイグレーション処理
作成されたphpファイルいついて

###upメソッド
テーブル生成のための処理を記述

デフォルトではidカラムとライムスタンプの項目を追加するコードが書かれている。
###downメソッド
テーブル削除の処理を書く

デフォルトではテーブルが有るなら消すという処理が書かれている。


この2つのメソッドはマイグレーションを実行したときに呼ばれる。

##テーブル生成の処理
###Schema::create
テーブル生成は**Schema::create**を使う。

```php:構文
Schema::create(テーブル名,function(Blueprint %table){
//テーブル生成処理
});
```
参考：[PHPフレームワーク Laravel入門 第2版](https://www.amazon.co.jp/dp/B08625YD7H/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

マイグレーションの実行でテーブル自体は作られ、フィールドはこのクロージャーに書く。

というわけで以下のように書き換える

```php5
public function up()
    {
        Schema::create('members', function (Blueprint $table) {
            $table->increment('id');
            $table->dateTime('created_at');
            $table->string('name');
            $table->integer('password');
            $table->string('email');
            $table->string('icon');
        });
    }
```
#マイグレーションを実行

```
$ phpa artisan migrate
```

##しかしエラー

```bash

   Illuminate\Database\QueryException

  SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
    667|         // If an exception occurs when attempting to run a query, we'll format the error
    668|         // message to include the bindings with SQL, which will make this exception a
    669|         // lot more helpful to the developer instead of just the database's errors.
    670|         catch (Exception $e) {
  > 671|             throw new QueryException(
    672|                 $query, $this->prepareBindings($bindings), $e
    673|             );
    674|         }
    675|

      +37 vendor frames
  38  artisan:37
      Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
```
これは`database.php`と`.env`のDB_HOSTを`localhost`にすることで解決した。

```.env
DB_HOST=localhost
```

```php5:database.php
'host' => env('DB_HOST', 'localhost'),
```
第5回：ニュースフィードの日付フォーマットを変換する(パイプ)

[目次：Webアプリ開発ロードマップ](https://qiita.com/radiance1104/private/7c5b04ce4cf8ec7bd708)
# 第5回：ニュースフィードの日付フォーマットを変換する(パイプ)
今回はパイプというものを使ってニュースフィードに表示される日時を好みのフォーマットに変換します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202428/ac8d39e2-35a8-b6b6-d1fb-a8cc46c514b1.png)

## ニュースフィードの日付を変換する
### パイプとは

「|」のことをパイプと呼びます。
左のプログラムの結果を右のプラグラムに渡す役割です。
コマンドラインで使われるパイプと同じ意味合いになります。

```
$ ls | grep *.ts
```

### パイプを作成する
下記のコマンドを実行し、パイプを作成します。

```
$ ng g pipe pipes/date-to-string
CREATE src/app/pipes/date-to-string.pipe.spec.ts (213 bytes)
CREATE src/app/pipes/date-to-string.pipe.ts (229 bytes)
UPDATE src/app/app.module.ts (836 bytes)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202428/1c8ca6d9-9584-6bf5-67ce-95a5faa67411.png)

### モジュールの変更を確認する
app.module.tsに下記の修正が行われていることを確認します。
これにより作成したパイプとアプリが紐づけられています。

```
・・・
import { DateToStringPipe } from './pipes/date-to-string.pipe';
・・・
  declarations: [
・・・
    DateToStringPipe,
  ],
・・・
```

### パイプの記載内容について
作成されたdate-to-string.pipe.tsを確認します。
@Pipeのnameに記載されている名前がhtmlに記載するときの名称になります。
transformメソッドは、パイプの左からもらった値をパラメータとして取得し、
戻り値で返した値が画面に表示されます。

```
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'dateToString'
})
export class DateToStringPipe implements PipeTransform {

  transform(value: unknown, ...args: unknown[]): unknown {
    return null;
  }

}
```

### コンポーネントから呼び出してみる
コンポーネントから呼び出してみます。
newsfeeds.component.htmlを下記の通り修正してください。
パイプ"|"の左から右に値が渡され、右のdateToStringの処理結果が表示されると思ってください。
```
    <p class="createdAt">{{newsfeed.createdAt | dateToString}}</p>
```

まだパイプの処理を何もカスタマイズしていないため、dateToStringは何も値を返しません。
そのためニュースフィードの日時は何も表示されなくなります。

## パイプの処理をカスタマイズする

パイプの処理をカスタマイズしてみます。
date-to-string.pipe.tsの処理を下記の通り修正します。

```
export class DateToStringPipe implements PipeTransform {

  transform(date: Date): string {
      return date.toLocaleString();
  }
```

パイプの使い方をわかりやすくするため、
`transform()`メソッドのパラメータを`value: unknown`から`date: Date`に、
戻り値の型を`uknown`から`string`に変更しています。
`date`はパラメータの変数名、`Date`はパラメータの型です。

これで元どおり日時がニュースフィードに表示されるようになりました。

## 課題
このままでは面白くないので、transform()をカスタマイズし、下記の仕様の動作になるよう修正してみましょう。

| (現在日時 - date)の値が | 動作 |
| --- | --- |
| 10分未満のとき | "たった今"を表示 |
| 1時間未満のとき | "x分前"を表示 |
| 1日未満のとき | "x時間前"を表示 |
| 1日以上のとき | "x日前"を表示 |

## 最後に
今回はパイプを学びました。次回はバックエンドの作成に入っていきます。
今回開発したソースコードは[GitHub](https://github.com/radiance1104/web-learning-loadmap/tree/create-pipe)に入っています。
サイバーレスキュー隊(J-CRAT)ー標的型サイバー攻撃特別相談窓口

応用情報技術者平成30年春期 午前問40

サイバーレスキュー隊(J-CRAT)の役割はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/b81ac64a-6700-e1f5-b2b0-c80283fa3f20.png)

１、サイバーレスキュー隊(J-CRAT)は、　Cyber Rescue and Advice Team against targeted attack of Japan
「標的型サイバー攻撃特別相談窓口」にて受け付けた相談や情報に対して調査分析を実施し、JPCERT/CCやセキュリティベンダ等と連携して助言や支援および情報共有を行うことで被害の低減と攻撃の拡大防止を図るIPAの取り組みです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5d11ade0-11f4-52df-9f00-fa0780864a4f.png)

・標的型サイバー攻撃」とは？
標的型サイバー攻撃とは、重要情報の入手を最終目標として、時間、手段、手法を問わず、目的達成に向け、特定の組織を攻撃対象として、その標的に特化して継続的に行われる一連の攻撃を指します。一般に「APT攻撃」、「持続的標的型攻撃」と呼ばれる場合もあります。

攻撃の手法・特徴
標的型サイバー攻撃は、組織的な攻撃者によって長期間にわたり段階的な攻撃を継続して行われま

攻撃目的：攻撃対象の持つ重要情報の入手を最終的な目標として攻撃が実施されます
攻撃対象：政府、官公庁、企業など、攻撃者の目的となる重要情報を持つ組織が標的となります
攻撃の「事前準備」段階では標的組織へ侵入するための足掛かりとして、関連する他の組織や個人が一時的な攻撃対象となる場合があります



２、内閣サイバーセキュリティセンター(NISC)の役割　National center of Incident readiness and Strategy for Cybersecurity
外部からのサイバー攻撃などの情報セキュリティ問題に対して，政府横断的な情報収集や監視機能を整備し，政府機関の緊急対応能力強化を図る。


３、サイバー情報共有イニシアティブ(J-CSIP)の役割　Initiative for Cyber Security Information sharing Partnership of Japan
重要インフラに関わる業界などを中心とした参加組織と秘密保持契約を締結し，その契約の下に提供された標的型サイバー攻撃の情報を分析及び加工することによって，参加組織間で情報共有する。

・イニシアティブ（英語: initiative）またはイニシアチブは、開始・先制・率先・先導などの意味を持つ言葉。 発案 - 案を出すこと、議案を提出すること。 国民発案、住民発案など。

４、日本セキュリティオペレーション事業者協議会(ISOG-J)の役割　Information Security Operation providers Group Japan
セキュリティオペレーション技術向上，オペレータ人材育成，及びサイバーセキュリティに関係する組織・団体間の連携を推進することによって，セキュリティオペレーションサービスの普及とサービスレベルの向上を促す。




参照：

https://www.ap-siken.com/kakomon/29_aki/q42.html

サイバーレスキュー隊J-CRAT（ジェイ・クラート）
https://www.ipa.go.jp/security/J-CRAT/index.html#:~:text=IPA%E3%81%AF%E3%80%81%E6%A8%99%E7%9A%84%E5%9E%8B%E3%82%B5%E3%82%A4%E3%83%90%E3%83%BC,against%20targeted%20attack%20of%20Japan

標的型サイバー攻撃」とは？
https://www.trendmicro.com/ja_jp/security-intelligence/research-reports/threat-solution/apt.html#:~:text=%E6%A8%99%E7%9A%84%E5%9E%8B%E3%82%B5%E3%82%A4%E3%83%90%E3%83%BC%E6%94%BB%E6%92%83%E3%81%A8,%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%82%8B%E5%A0%B4%E5%90%88%E3%82%82%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

内閣サイバーセキュリティセンター（ないかくサイバーセキュリティセンター、英: National center of Incident readiness and Strategy for Cybersecurity、略称：NISC）
https://ja.wikipedia.org/wiki/%E5%86%85%E9%96%A3%E3%82%B5%E3%82%A4%E3%83%90%E3%83%BC%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%82%BB%E3%83%B3%E3%82%BF%E3%83%BC
Githubのマスコットキャラクター、Octocat

本日の雑記として、
GithubのマスコットキャラクターことOctocat（オクトキャット）について調べたので、
Qiitaにも書き出そうと思います。


■Githubのマスコットキャラクター「Octocat」
![github-icon-png-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698926/7c1b0a7a-0dc6-d56f-184c-4b141664bca0.png)
Githubのアイコン画像になにやら猫のようなシルエットが見えますが、
これ、何だと思いますか？

こいつはOctocatと言います。
猫とタコを組み合わせたようなキャラクターで、
足らしきものが５本ある火星人のようなデザインです。
アイコンのシルエットになにやらしっぽのような紐状のものが伸びていますが、これは脚です。
脚を一本だけ上げている姿です。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698926/ff3d74a1-8ed0-0e23-e7bf-347e1429991e.png)
Octocatのデザインは、GithubのCEOであるTomさんがiStockPhotoというフォトストックサイトで見つけ、
気に入ったので二束三文の価格で購入したそうです。

ちなみにデザインしたのはイギリス人デザイナーのSimonさんで、
この人はTwitterのアイコンであるTwitter Birdをデザインした人でもあります。
どちらもiStockPhoto上で二束三文の値段で買い取られました。

現在の両者の知名度からすると、とんでもない話ですね。
![コメント 2020-09-02 204537.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698926/204f3fc0-96c5-a34c-02f0-9aa0e90a2b93.jpeg)
WordPressのカテゴリーとタグをnoindexに設定する方法【SEO対策】

##はじめに

WordPressで個別記事にカテゴリーやタグを設定すると、カテゴリーページやタグページも自動で生成されています。

カテゴリーページやタグページに、個別記事へのリンクが並べているだけであれば、SEO的には価値の低いコンテンツなので、noindexを設定しておきましょう。

noindexとは、GoogleやBingなどの検索エンジンにページを検索結果に表示しないように指示するメタタグです。

>ページが Google 検索に表示されないようにするには、noindex メタタグをページの HTML コードに挿入するか、HTTP リクエストで「noindex」ヘッダーを返します。Googlebot はそのページを次にクロールしたときに、このタグまたはヘッダーを検出すると、他のサイトがそのページにリンクしているかどうかにかかわらず、そのページを Google 検索結果から完全に削除します。
>[Google ヘルプセンター](https://support.google.com/webmasters/answer/93710?hl=ja)

コンテンツとしての価値がないページに対して、適切にnoindexを設定することで、WordPress全体としてのSEO評価を高めることができます。

>低品質なコンテンツがサイトの一部にしか存在しない場合でも、サイト全体の掲載順位に影響を与えることがあるということにご注意ください。低品質なページを削除したり、内容の薄いページをまとめて役に立つコンテンツに改善したり、もしくは低品質なコンテンツを他のドメインに移動させたりすることが、最終的に良質なコンテンツの掲載順位を改善することにつながります。
>[Google 良質なサイトを作るためのアドバイス](https://webmaster-ja.googleblog.com/2012/09/more-guidance-on-building-high-quality.html)

この記事では、function.phpへのコード追記により、カテゴリーページやタグページをnoindexに設定する方法を紹介します。

##WordPressのカテゴリーとタグをnoindexに設定する方法

WordPressのfunction.phpに以下のコードを設置してください。
管理画面から、外観→テーマエディター→テーマファイルで編集できます。

```function.php
function set_noindex(){ 
    if ( is_category() || is_tag() ) {
        echo '<meta name="robots" content="noindex,follow" />';
    }
}
add_action('wp_head', 'set_noindex');
```

上記の`is_category() || is_tag()`の部分でカテゴリーページやタグページであることを判断して、`<meta name="robots" content="noindex,follow" />`というnoindex用のメタタグを出力しています。

カテゴリーやタグだけでなく、投稿者・年月などのアーカイブページをnoindexにしたい場合は、`is_archive()`で指定すればOKです。
ポリモーフィック型、マルチプラットホーム型、ステルス型マルウェア、ボット

応用情報技術者平成30年春期 午前問39

ポリモーフィック型マルウェアの説明として，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/a800d099-2836-165e-f433-1fcffb3c7391.png)


１、ポリモーフィック型マルウェアは、　Polymorphic
パターンマッチングによる検出を免れるため、感染のたびに異なる暗号化/復号ルーチンで暗号化を行って、自身のプログラムコードを都度変化させる機能を有するマルウェアです。ミューテーション型ともいいます。
ウイルス対策ソフトの定義ファイルによるパターンマッチングでは検知することができないので、検出にはマルウェアの活動を監視して判定を行う「ヒューリスティック法」や「ビヘイビア法」などの行動検知型の手法を利用する必要があります。

・ポリモーフィック型ウイルス（Polymorphic Virus）
ポリモーフィックは「多様な」という意味で、ポリモーフィック型ウイルスとは、感染する都度ウイルス自体のコードをランダムに変更し形を変えるコンピュータウイルスのことです。

・ヒューリスティック法とは、ウイルスを検知するための手法の一つである。 あらかじめウイルスの取る行動を登録しておき、検査対象と比較する。 ウイルス定義ファイルを使ったパターンマッチング方式では検知できない新たなウイルスを検知することも可能である。
※ヒューリスティック（Heuristic）は、「経験則の」「試行錯誤的な」の意味。


２、ボットの説明
インターネットを介して，攻撃者がPCを遠隔操作する。

・ボット（BOT）とは、コンピュータを外部から遠隔操作するためのコンピュータウイルスです。 ボットに感染したコンピュータは、ボットネットワークの一部として動作するようになります。 そして、インターネットを通じて、悪意のあるハッカーが、常駐しているボットにより感染したコンピュータを遠隔操作します。


３、マルチプラットホーム型マルウェアの説明
複数のOS上で利用できるプログラム言語でマルウェアを作成することによって，複数のOS上でマルウェアが動作する。

・クロスプラットフォーム（英: cross-platform）とは、異なるプラットフォーム（例えばPC/AT互換機とMacintosh、あるいはWindows・macOS・FreeBSD・Linuxなどのように、仕様が全く異なる機械（ハードウェア）またはオペレーティングシステム）上で、同じ仕様のものを動かすことが出来るプログラム（ソフトウェア）のことを言う。同様の呼称にマルチプラットフォーム[1]がある。

４、ステルス型マルウェアの説明
ルートキットを利用して，マルウェアに感染していないように見せかけることによって，マルウェアを隠蔽する。

・ステルス（英語: stealth）. 英語で「隠密」「こっそり行う」という意味。 センサーなどに対する低被探知性。ステルス性、ステルス機。 コンピュータ分野. 不正プログラム（ウイルスなど）がアンチウイルスソフト類の検出を逃れる技術。

・ルートキット（rootkitあるいはroot kit）
ルートキットとは、対象のPCに感染する、攻撃者がそのPCへ継続的にリモートアクセスするためのツール一式をインストール可能とする、といった目的を持つマルウェアを指します。通常ルートキットはOSの奥深くに潜み、アンチマルウェア製品などのセキュリティツールによって検知されないように設計されています。ルートキットには、キーロガー、パスワード窃盗ツール、クレジットカードやオンラインバンキングの情報を盗むモジュール、DDoS攻撃用のボット、セキュリティソフトウェアを無効にする機能など、多数の悪意あるツールが含まれている場合があります。ルートキットはバックドアとして動作することが多く、攻撃者は感染したマシンにリモートからいつでも侵入でき、特定のコンポーネントを削除したり、インストールしたりできます。

参照：

https://www.ap-siken.com/kakomon/30_haru/q39.html

ヒューリスティック法
http://www.ne.senshu-u.ac.jp/~proj28-19/tobe/goku-main/goku_hyuri.html#:~:text=%E3%83%92%E3%83%A5%E3%83%BC%E3%83%AA%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E6%B3%95%E3%81%A8%E3%81%AF%E3%80%81%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9,%E3%81%93%E3%81%A8%E3%82%82%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82

クロスプラットフォーム
https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%82%B9%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0

ルートキット
https://blog.kaspersky.co.jp/what-is-a-rootkit/607/#:~:text=%E3%83%AB%E3%83%BC%E3%83%88%E3%82%AD%E3%83%83%E3%83%88%E3%81%A8%E3%81%AF%E3%80%81%E5%AF%BE%E8%B1%A1,%E3%81%AB%E8%A8%AD%E8%A8%88%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82
【Django】herokuデプロイ時に遭遇したエラー その②

# 何があったか？
Djangoで作成したWebアプリをherokuでデプロイするため

```terminal
$ git push heroku master
```

を実行したところ、以下のエラーが発生した。

```terminal
remote: !   No such app as xxx-yyy-1234.
fatal: repository 'https://git.heroku.com/xxx-yyy-1234git/' not found
```

# 原因は？

[その①](https://qiita.com/nissy7ok/items/716cc6e973104c6d660d)でのデプロイ失敗時に`heroku create`コマンドで作成したアプリを消していた。
そのため`git push heroku master`で存在しないURLが指定されていた。

# 解決方法

URLを存在するアプリに指定し直せば良い

```terminal
$ heroku create    # なければ作成する

$ git remote set-url heroku https://git.heroku.com/aaa-bbb-9876.git    # 作成したURLを指定
```

これで再度プッシュしてあげれば通りました。

```terminal
$ git push heroku master
```

# 参考
[【Heroku】デプロイ（fatal: repository 'app_url' not found）](https://qiita.com/tanaka-t/items/61a455142eb5e01b5d9a)
teeコマンドを使っtee

teeコマンドをつかってますか?

teeコマンドは，標準出力に吐き出しながらファイルに吐き出してくれるスグレモノです．

個人的に使っているTipsを紹介します．

# sudoでファイルに書き出す

例えば，example.confのコメントを取り除いた設定ファイル example.conf.simpleを作成したい場合

```shell
sudo grep -v "^#" example.conf > example.conf.simple
```

このディレクトリに一般ユーザの書き込み権限がないと怒られます．

よくある方法はsudoでシェルを呼び出しでコマンド全体の実行です．

```shell
sudo sh -c 'grep -v "^#" example.conf > example.conf.simple'
```

これをteeで書き直してみると...

```shell
grep -v "^#" example.conf | sudo tee example.conf.simple
```

# クリップボードの内容をsudoでファイルに書き出し

Configの流し込みに使えます．

```shell
sudo tee /etc/example.conf
hoge:
  fuga: 100
  foobar: 2000
[Ctrl + D]
```

# sudoでファイルに追記

`-a` を使うと追記ができます．リダイレクトの `>>` で書かれているものは置換できます．

```shell
find /opt | sudo tee -a /etc/example.list
```
Module not found: Can't resolve 'fs'に悩まされました。


どうも、
今日という日、僕は Module not found: Can't resolve 'fs' というエラーにとても悩まされました。
このエラーを通じて、 色々と参考になりそうな記事いくつかを発見したので
この記事を

#'fs'完全攻略ガイド
と名付けて書かせてもらいたいと思います。 （エラー解決したばっかなので少し調子乗ってます🙇）  
<br/>
**記事引用しすぎて停止されたのでタイトルだけ載せさせてもらいます**

<br/>
##解決策１
まずは落ち着いて
npm i fs
or
yarn add fs
これで一時期は解決したのですが、 おそらく根本的な解決には至らないでしょう。
 

##解決策2
Can't resolve 'fs'という記事です
node: { fs: 'empty'} を追加しようという内容です。
これらは、臭いものに蓋をするだけで根本的な解決にはなりません
 
たしか次の記事で同じようなこと言ってました。 （というか全く同じでした。）
 
同じような記事で、
//webpack.configにコレを加える

target: 'node',
or
target: 'web'


//package.jsonにコレを加える
"browser": {
"fs": false
},
などという内容がいくつかありましたが、 これらはサーバーに関する場合の対処法だそうなので、 僕の場合はダメでした。。
 

##解決策3
お次はこちら   webpack 実行で Module not found: Error: Can't resolve 'fs' というエラー
 
こちらの記事では webpackに関する丁寧な記事も載っていたので 読んでみて損はないと思います。

##解決策4
この記事はこういうこともあるかもなーと一回考えさせてくれる記事でした！ 【Vue】npm run buildでModule not found: Can't resolve 'child_process'【Webpack】
 
そしてお待たせしました。

##解決策５
この記事が僕の救世主メシアでした。 モジュールが見つかりません：node_modules / destroyの 'fsを解決できません ＃9768
 
githubありがとう。。.
￼
 

##結論
なにかエラーでつまずいたときは エラー文　　言語
で調べると答えがでてきやすいですね！！
超初心者っぽい感想ですが改めて思い知らされたので ここに書き残しとこうと思いました。
 
異常、（エラーだけに） ご視聴ありがとうございました。
一人笑ってはいけないゲームができるWEBアプリを機械学習でつくった

# ガキ使の「〇〇、アウト！」の声を聞けなきゃ年は越せない

2020年もあっという間に2/3が過ぎ、残り4ヶ月ですね。たぶん、あっという間に年末になります。

で、年末と言えば、やっぱり恒例の「ガキ使の笑ってはいけない」ですね。「〇〇、アウト」の声がないと、年は越せません。


でも、あれ、実は自分もやってみたいなー、なんてことはないですかね？
自分のテレビ越しで参加できたら。。


という願いを叶えるために、テレビを見ながら「1人笑ってはいけない」が体感できるアプリを作ってみました。



# 作ったもの

ひとまずご覧ください。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">１人で「笑ってはいけない」ゲームができるウェブアプリを作りました。ゲーム中は、自分の顔がカメラ内に入るようにしておくと、笑ったときにおなじみの音が流れます！笑<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a>　<a href="https://twitter.com/hashtag/%E7%AC%91%E3%81%A3%E3%81%A6%E3%81%AF%E3%81%84%E3%81%91%E3%81%AA%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#笑ってはいけない</a> <a href="https://t.co/pXOgrk8JI3">pic.twitter.com/pXOgrk8JI3</a></p>&mdash; 柳瀬浩之@人材開発×UX専門家 (@btap_hiro) <a href="https://twitter.com/btap_hiro/status/1301110958769672192?ref_src=twsrc%5Etfw">September 2, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

このアプリを起動して、自分の顔がカメラ内に収まってる状態にしておくと、笑ってしまった時に、例の音が流れます。「・・・アウト！」まで実装できると尚よかったですが、一旦はよしとします。

１点注意点としては、部屋が暗めのところでやると、うまく反応しません。部屋が明るいところでご使用ください。


アプリは[こちら](https://amazing-jennings-3cb620.netlify.app)


# 笑顔を機械学習で読み込ませる方法

googleのteachableMachineを使いました。私でも使えるので、とっても便利です。

ネットで「笑顔の写真」と「真面目な顔の写真」を約30-40枚集めました。で、これだけだと枚数が少ないかなと思ったので、自分の笑顔の写真、笑ってない写真も20枚ずつ程度入れて読み込ませました。

そうすると、まだ反応が弱いところがありますが、なんとか作ることができました。


# コードシェア

コードは[こちら](https://gist.github.com/kaiser355/7f3dc41a1933434091cee70bd6a71d5e)をご覧ください。


# 難しかったところ

①笑顔が検出されると、音楽を鳴らす

同じスクール同期の@twtjudy1128 さんの[こちら](https://qiita.com/twtjudy1128/items/4c29a98a035a6e8cbcb4")を参考にさせていただきました。
ありがとうございます。


②笑顔が検出されると、文字で「アウト！」と表示する

これをVue.jsで実装しようと思ったのですが、うまくいきませんでした。

エラーコードは以下

![]()

<img width="500" alt="スクリーンショット 2020-09-04 9.02.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664861/d9b5a0aa-8e3e-6fa8-07b2-cf75837e711d.png">

```html

<div id="app">
  {{ message }}
</div>
```

```javascript
classifier.classify(onDetect);
function onDetect(err, results) {
    if (results[0]) {
        console.log(results[0].label);
    }
    classifier.classify(onDetect);
    if (results[0].label === 'ニコニコ') {
       const app = new Vue({
           el: '#app',
           data: {
             message: 'アウト！',
           },
       });
   }
}
```

ひとまずこれだと表示されないのはわかりました。が、なぜダメなのかはいまいちわかりません。

（更新）
単純に、Vue.jsを読み込む時に必要な以下のコードが抜けていました。

```javascript
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 
```

これを追記したら、笑顔が認識された時に、アウトと表示させることができました。gistのコードの方も修正いたしました。


しかし、スクールの先生に伺ったところ、通常こういう書き方はしないとのこと。

```javascript

if (results[0].label === 'ニコニコ') {
       const app = new Vue({
           el: '#app',
           data: {
             message: 'アウト！',
           },
       });
   }
```

また修正方法を考えます。



# このアプリをつくった意図

　今回、スクールで、ml5.jsとteachableMachineを学びました。最終的には、オンライン会議やオンライン研修の動画から、音声、表情、動きなど、様々な情報を取得して、瞬時に会議や研修の分析ができるようなものを作ることを目指しています。

　その一環として、まず表情を読み取って反応するものを作ってみようと思って、ひとまず笑顔の画像分析ができるものをつくってみました。その後に、「笑顔という情報が取得できる」ところから何ができるか？と考えた時に、年末の「笑ってはいけない」を思い出して、それを作ってみようと思いました。

## よかったら、LGTMお願いします！！
firestoreのコレクション内のドキュメントを削除したときにサブコレクションも削除したい

firestoreのコレクションを削除しても、その下にあるサブコレクションは削除されない

#コレクションの削除

```javascript
//...省略

  db = firebase.firestore();

//...省略

 collectionDelete(docId: string) {
    this.db
      .collection("myCollection")
      .doc(docId)//myCollectionのなかのドキュメントID
      .delete()
      .then(() => {
        console.log("削除完了");
      });
```
これでドキュメントは削除完了
ただこの状態だとこのコレクションにあるサブコレクションは残ったまんま

#サブコレクションの削除

```javascript
   subCollectionDelete(docId: string) {
    this.db
      .collection("myCollection")
      .doc(docId)//myCollectionのなかのドキュメントのID
      .collection("mySubCollection")
      .get()
      .then((subDoc) => {
        subDoc.forEach((doc) => {
          console.log(doc.data());
          this.db
            .collection("myCollection")
            .doc(docId)
            .collection("mySubCollection")
            .doc(doc.id)
            .delete()
            .then(() => {
              console.log("mySubCollection削除");
            });
        });
      });
  }
```
これで先ほど消したドキュメントのサブコレクションが__``全部``__消せます。
サブコレクションを削除する場合は一度``.get()``で消したいサブコレクションを取得して
その取得したサブコレクションに対して``forEach``を使って一つずつ消す形になります。
サブコレクションの数が多い場合はcloudFunctionsを使って削除した方がいいのかもしれません。

後はこの二つのメソッドを実行すれば完了です。

```javascript

allDelete(docId: string) {
    this.collectionDelete(docId)
    this.subCollectionDelete(docId)
  }
```

間違いがあったらご指摘いただけると嬉しいです。

以上です！
ディレクトリトラバーサル攻撃、OSコマンドインジェクション攻撃、SQLインジェクション攻撃、不正アクセス

応用情報技術者平成30年春期 午前問38


ディレクトリトラバーサル攻撃はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/5b4ca009-d155-f8df-f977-c125e789bc77.png)


１、ディレクトリトラバーサル攻撃は、ファイル名を要求するプログラムに対してサーバ内の想定外のファイル名(親ディレクトリの移動「../」など)を直接指定することによって、本来許されないファイルの不正な閲覧・取得を狙う攻撃方法です。


２、OSコマンドインジェクション攻撃の説明
OSの操作コマンドを利用するアプリケーションに対して，攻撃者が，OSのディレクトリ作成コマンドを渡して実行する。


３、SQLインジェクション攻撃の説明
SQL文のリテラル部分の生成処理に問題があるアプリケーションに対して，攻撃者が，任意のSQL文を渡して実行する。


４、不正アクセスの事例
シングルサインオンを提供するディレクトリサービスに対して，攻撃者が，不正に入手した認証情報を用いてログインし，複数のアプリケーションを不正使用する。


参照：
https://www.ap-siken.com/kakomon/27_haru/q46.html
クロスサイトスクリプティング(XSS)、クラッキング、バッファオーバフロー攻撃、ディレクトリトラバーサル攻撃の手口

応用情報技術者平成30年春期 午前問37

クロスサイトスクリプティングの手口はどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/a4c9f142-7c05-eac6-d810-c46cde918bea.png)


１、クロスサイトスクリプティング(XSS)は、　cross site scripting
動的にWebページを生成するアプリケーションのセキュリティ上の不備を意図的に利用して、悪意のあるスクリプトを混入させることで、攻撃者が仕込んだ操作を実行させたり、別のサイトを横断してユーザのクッキーや個人情報を盗んだりする攻撃手法です。
XSS脆弱性のあるWebアプリケーションでは、以下の影響を受ける可能性があります。
・サイト攻撃者のブラウザ上で、攻撃者の用意したスクリプトの実行によりクッキー値を盗まれ、利用者が被害にあう。
・同様にブラウザ上でスクリプトを実行され、サイト利用者の権限でWebアプリケーションの機能を利用される。
・Webサイト上に偽の入力フォームが表示され、フィッシングにより利用者が個人情報を盗まれる。


２、クラッキングの手口　Cracking
インターネットなどのネットワークを通じてサーバに不正にアクセスしたり，データの改ざん・破壊を行ったりする。


３、バッファオーバフロー攻撃の手口
大量のデータをWebアプリケーションに送ることによって，用意されたバッファ領域をあふれさせる。

プログラムが処理するデータを一時的に保持する固定長のメモリ領域が「バッファ」だ。バッファに許容量より多くのデータが書き込まれると、データがあふれる。この脆弱（ぜいじゃく）性を「バッファオーバーフロー」と呼ぶ。攻撃者が**バッファオーバーフローを悪用すると、システムで任意のコマンドを実行できるようになる恐れがある**ため注意が必要だ。


４、ディレクトリトラバーサル攻撃の手口
パス名を推定することによって，本来は認証された後にしかアクセスが許可されていないページに直接ジャンプする。

ディレクトリトラバーサル (英語: directory traversal) とは、利用者が供給した入力ファイル名のセキュリティ検証/無害化が不十分であるため、ファイルAPIに対して「親ディレクトリへの横断 (traverse)」を示すような文字がすり抜けて渡されてしまうような攻撃手法のことである。


参照：

https://techtarget.itmedia.co.jp/tt/news/2005/15/news09.html


https://www.ap-siken.com/kakomon/25_aki/q42.html

ディレクトリトラバーサル
https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%83%88%E3%83%A9%E3%83%90%E3%83%BC%E3%82%B5%E3%83%AB#:~:text=%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%83%88%E3%83%A9%E3%83%90%E3%83%BC%E3%82%B5%E3%83%AB%20(%E8%8B%B1%E8%AA%9E%3A%20directory%20traversal,%E6%89%8B%E6%B3%95%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82
Laravelの認証機能をカスタマイズしてデータベースにレコードを作成する

## 現状
`Laravel`の認証機能を有効化したけど、どうカスタマイズすればデータベースにレコードを登録できるんだろう…?

## 解決法
**めちゃくちゃ簡単だった**

`(プロジェクト名)\app\Http\Controllers\Auth\RegisterController.php`から下記のコードをコピーして、挿入したいテーブル名、カラムとデータをコントローラーで指定するだけ。

```RegisterController.php
protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }
```

**こんな感じに↓**

```CustomiseController.php
<?php

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Table;
//(↑モデル宣言)
use Illuminate\Support\Facades\Hash;
//(↑パスワードなどハッシュ化するなら忘れないように)

class CustomiseController extends Controller
{
    public function customise(Request $request)
    {
    	$name = $request -> input('post_name');
    	$email = $request -> input('post_email');
    	$pass = $request -> input('post_pass');
    	$comment = $request -> input('post_comment');
    	$delete_flag = $request -> input('post_delete_flag');
    	Table::create([
            'name' => $name,
            'email' => $email,
            'password' => Hash::make($pass),
            'comment' => $comment,
            'delete_flag' => $delete_flag
        ]);
        return view('/home');
    }
}
```
DjangoでTypeError: resolve() got an unexpected keyword argument 'strict'という見慣れないエラーが出た

# はじめに
作成したDjangoアプリをAWS EC2（Ubuntu16.04)にデプロイする過程で、以下のエラーに遭遇したため対処法を書き残します。

# エラーの内容
Ubuntu内でDjangoプロジェクトを`git clone`した後、`python3 manage.py makemigrations`を実行したところ、

`TypeError: resolve() got an unexpected keyword argument 'strict'`

というエラーが表示されました。


```python:settings.py
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
```

の１文がエラーとなっているようです。
これはDjangoのmanage.pyがある基本ディレクトリの絶対パスを取得する記述です。

ここについては特にいじった記憶がないためなんでだろうと思いググると、Django3.1以降とその前でこの部分の記述が変わっていることがわかりました。

今回ローカルではPython3.8+Django3.1で開発していましたが、確認したところUbuntuにはPython3.5+Django2.2がインストールされており、どうやらバージョンの違いによるエラーのようです。

resolveメソッドのstrict引数はpython3.6以降で追加されたようなので、ここが根本の原因でしょう。

# 解決方法
本来であればUbuntu内のDjangoのバージョンに合わせて開発する必要がありますが、今回はデプロイできるか簡単に試したかっただけなので、settings.pyをDjango2.2に合わせた記述に変えてあげます。

```python:settings.py
# こちらはDjango3.1以降
# from pathlib import Path
# BASE_DIR = Path(__file__).resolve(strict=True).parent.parent

# 従来の記述
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
```
こうすることで無事エラーは解消され、migrationが成功しました。

言語やフレームワークのバージョン管理は開発において特に重要なことだと思うので今後は十分に気を付けていきたいと思います。

# 参考
+ [BASE_DIRを分かりやすく解説【これで場所と構造がわかります】 - code for Django](https://codor.co.jp/django/about-basedir#:~:text=BASE_DIR%E3%81%A8%E3%81%AF%E3%80%81%E3%81%9D%E3%81%AE%E5%90%8D,%E3%81%84%E3%82%8B%E5%A0%B4%E6%89%80%EF%BC%88%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%EF%BC%89%E3%81%A7%E3%81%99%E3%80%82)
+ [Python, pathlibの使い方（パスをオブジェクトとして操作・処理） | note.nkmk.me](https://note.nkmk.me/python-pathlib-usage/)
+ [pathlib --- オブジェクト指向のファイルシステムパス](https://docs.python.org/ja/3/library/pathlib.html)
+ [Use Pathlib in Your Django Settings File - Adam Johnson](https://adamj.eu/tech/2020/03/16/use-pathlib-in-your-django-project/)
Githubで不要なリポジトリを削除する方法

Githubで不要なリポジトリを削除したいときには、これまでに作成したリポジトリの中から不要なリポジトリを選択し

Settingsのボタンを押す、次に画面を一番下までスクロールし「Delete this Reposotory」のボタンをクリックします。

画面にPlease type in the name of the repository to confirm.

(リポジトリの名前を入力してね)と出るので不要なリポジトリ名を入力し、

I understand the consequenses, delete this repositoryと赤色で書かれているボタンを押すと

リポジトリを削除することができますっっ！！
二つのIPv4ネットワークの集約

応用情報技術者平成30年春期 午前問35

二つのIPv4ネットワーク192.168.0.0/23と192.168.2.0/23を集約したネットワークはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/2a9bee88-38cb-a4d1-530c-d79b5cbfa7fd.png)


１、ネットワーク集約
複数のネットワークアドレスを1つにまとめることをルート集約といい、**複数のIPアドレスを2進数表記にしたときに共通しているビット列の位置までサブネットマスクを左にずらすことでルート集約を行う**ことができます。

二つのIPv4ネットワーク192.168.0.0/23と192.168.2.0/23を2進数表記にすると、

　**11000000 10101000 000000**10 00000000
　**11000000 10101000 000000**00 00000000

となり上位から22ビットまでが共通のビット列であることがわかります。共通している22ビット目までをサブネットマスクとした192.168.0.0/22がルート集約後のネットワークになります。

２、/後ろの数字
/後ろの数字は、サブネットマスクまでの２進数の桁数ですね。

上記１の操作を例としたら、共通している22ビット目までをサブネットマスクとし、それ以後をホストアドレスとして使用することで2つのネットワークを内包する1つのIPネットワークとしていると考えて、/22になりますね。


参照：
https://www.ap-siken.com/kakomon/24_haru/q34.html
DoxygenでPythonコードをドキュメント化


DoxygenでPythonコードをドキュメント化するとき、嵌ったのでmemoを残しておきます。

pythonでdocstring形式のコメントは、関数にカーソル置くとVScodeの編集支援機能でコメントが表示されます。


■docstring形式コメント例

```python

def leftCosets(self, H: FiniteGroup) -> Set[Set[GroupElement]]:
	"""
	@brief Calculates left cosets of H in self.

	@details foo

	:param H: subGroup of self
	:return:

	@note bar
	"""

	cosets = {frozenset(copy.deepcopy(H.elements)),}
	remain = self.elements - H.elements

	while len(remain) > 0:
		#〜中略〜

	return cosets
```


関数にカーソルをあわせるだけで、関数定義位置に移動しなくてもコメントで確認できるので便利です。

ただしdocstring形式は、「doxygenの特殊コマンドはどれもサポートされていない」ため、Doxygenでドキュメント化するときれいに表示されません。
- [DoxygenでPythonプロジェクトをドキュメント化しましたが、パラメータがうまくリスト表示されません。](https://teratail.com/questions/237671)


そこで、docstring形式をdoxygen形式に変換するフィルターを使います。


■docstring形式をDoxygen形式に変換するフィルター
[doxyfilter_python(GitHub)](https://github.com/UwePfautsch/doxyfilter_python)


このフィルタを使うとdocstring形式がdoxygen形式に変換されてDoxygenに渡されます。

■doxygen形式コメント例

```python
	##
	#@brief Calculates left cosets of H in self.
	#@details foo
	#
	#@param H (FiniteGroup) subGroup of self
	#@return (Set[Set[GroupElement]])
	#
	#@note bar
	def leftCosets(self, H: FiniteGroup) -> Set[Set[GroupElement]]:
	cosets = {frozenset(copy.deepcopy(H.elements)),}
	remain = self.elements - H.elements

	while len(remain) > 0:
		#〜中略〜

	return cosets
```


※注意※Windows環境でこれをそのまま使うと、cp932で動作して日本語が文字化けしてしまいます。
Windows環境で使う場合、doxyfilter_python.pyを編集してエンコーディング”utf-8”を指定します。

```python：doxyfilter_python.py
import io

#〜中略〜perform_fh関数のはじめに以下の行を追加
        sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8')


#〜中略〜main関数のファイルオープンの箇所にエンコーディングを指定。
        with open(file, 'r',encoding='utf-8') as fh:

```



■Doxygenの設定などの注意事項
>Python は、C や C++ より、見た目が Java に似ているので、設定ファイルでは OPTMIZE_OUTPUT_JAVA から YES に設定してください。

『 [Comment blocks in Python](http://www.doxygen.jp/docblocks.html#pythonblocks)』より


>- @briefや@detailsの間は必ず1行分空けること。そうしないと VS Code のツールチップで項目が改行されずに1行になって表示されてしまう。
>- 必ずファイルコメントを入れること。そうしないとグローバルメソッドがドキュメント化されない。

『[VS Code の編集支援を生かしつつ Python3 で Doxygen を使う](https://motchy99.blog.fc2.com/blog-entry-177.html)』より




-  Expert タブ -> Topics -> Input -> INPUT_FILTERにdoxyfilter_python.pyをフルパスで指定してください。




参考にしたサイト（『[VS Code の編集支援を生かしつつ Python3 で Doxygen を使う](https://motchy99.blog.fc2.com/blog-entry-171.html)』）には
>必ず doxyfilter_python.py をフルパスで指定し、python3 で実行するように明示すること(そうしないと失敗した)。

と書かれていていますがが、python3.x系しか入っていない環境ではpython3を明示する必要はなさそうです。
スクラム・アジャイル・ウォーターフォール開発について説明しました


# なにこれ
面接を受けた際に、スクラム・アジャイル開発とは何ですか？と質問されて、
自分でも言語化できてないことに気づいたので、
整理する意味でそれぞれの単語の意味や役割についてまとめました。

# アジャイル開発とは？
ウォーターフォール開発のように一度にまとめてではなく、
少しずつ確認をはさみながら開発を進めていくこと。
クライアントに「こんな感じだけどオッケー？」って聞きながら仕事する感じ。
利用者や関係者（クライアント）の反応やレビューを得ながら、計画を調整しつつ進めていく。
細かく作って細かく確認するので、後述するウォーターフォール開発と比較して仕様変更に鬼強い。まじやばい（語彙力）

## アジャイル開発におけるキーワード
- スプリント
    - 一つの開発周期のこと。
    - 概ね1週間1スプリントにすることが多い。
- スプリント計画ミーティング
    - 各スプリントが始まる日に実施する。
    - そのスプリントでやることや、到達すべき点について共有する！
- スプリントレビュー
    - 各スプリントの終了日に実施する。
    - プロダクトオーナーにスプリントでの成果をレビューしてもらう場。
- スプリントレトロスペクティブ
    - スプリントレビュー終了後に実施する。
    - スプリントでの反省点や維持すべき施策・改善点などについてチームで共有する場。

![すぷりんtp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629015/e400af2d-f38e-5b5b-46f8-e09dd6ad44a0.png)

# ウォーターフォール開発とは？
最初に決めた要件を、ある期限までに完了すること。滝みたいに流れ落ちるように開発する。
契約➡️開発➡️納品というシンプルなフローで進めるよ。
厳密な要件定義と納期に合わせた進捗管理ができればオッケー牧場（古い）
でも、要件定義が上手くいってなかったり、仕様変更が起きると対応が鬼ムズい（語彙力）

# アジャイル・ウォーターフォールのメリット・デメリット
|    |  アジャイル  |ウォーターフォール |
| ---- | ---- | ---- |
|  メリット  |  仕様変更に柔軟に対応できる。  |  	開発計画が滝みたいにシンプルで進捗管理しやすい。  |
|  デメリット  |  進捗が把握しずらい。今どこやってんの？みたいな  |  仕様変更に対応しにくい。仕様変更やめてくれ〜って感じ。  |

# スクラムとは？
アジャイル開発手法の中の1つ。いっちゃん有名らしい。
アジャイル開発のデメリットを回避するために、
チーム内で円滑なコミュニケーションを取るために使う。
リーダー・マネージャー主体じゃなくてメンバー全員が主体性を持って、
プロダクト完成に向けた責任を持つ（全員がリーダーや！みたいな）

# スクラムの大まかな進め方
- 1．アプリケーションの要件定義
    - ヒアリングして、どんなアプリを作るか決める。
    - アジャイルでも要件定義はめちゃんこ大事。超大事！

- 2．開発の意図を、開発する人々が完全に把握する！
    - 何を達成するためにそのプロダクトを作るか把握。
    - 目的と矛盾する機能や優先順位付けは排除することが求められるから、
    - 開発メンバー全員がこれを理解することが大事らしい。
- 3．実証すべき作業を洗い出し〜
    - 完成までに行う作業を洗い出してリスト化。見える化しましょう。
- 4．作業量を見積もる
    - タイトル通り。僕たちは全員でやりました。
- 5．スプリントごとに実装する！
    - スプリントの期間を設定して、スプリント開始時にスプリント計画ミーティングする
- 6．スプリントの成果を発表（結果発表だドン）
    - スプリント計画で決めた実装が計画通りに終えられたかを確認。
- 7．振り返りをする
    - 次の期間でより早く進めるための対策を立てる。

# スクラムにおける役割分担
- プロダクトオーナー：プロダクトバックログの管理責任者
    - プロダクトの結果責任を負う。俺に任せとけ〜
    - スクラムは個人の主体性を意識した手法だけど、最終決定を下すのはプロダクトオーナーです。
- スクラムマスター：スクラムの調整役
    - スクラムが上手くいくようにサポートする。縁の下の力持ち。
    - 人間関係が悪くなる要素は削除して推進役になる。
    - 決してリーダーではなく（ここ大事）、スクラムを円滑に回すための世話役ポジション
- 開発チームメンバー：実際に開発に携わる
    - 計画に沿ってプロダクトを作るマン。
    - 日々開発計画について話し合って、必要なら計画の変更を提案する。
    - 上下関係はなく、チーム内で仕事の進め方は、メンバー同士で決める。フラットな社風ですね。

# スクラムを用いたアジャイル開発の実際のフロー
- 1．要件とゴールの確認
    - 「何を作るのか」と「作ることで達成したいことは何か」を共有
- 2．作業を洗い出してToDoリストを作成
    - プロダクトの完成に必要な工程（要件定義〜運用まで）を全て洗い出し、一つのリストにまとめる。
    - これを`プロダクトバックログ`と言う。超大事。開発全体のToDoリスト
    - プロダクトバックログから作業を分担して、着手する。
- 3．スプリント計画ミーティングをする
    - このスプリントで開発する内容を、プロダクトバックログの中から決める。
    - タスクを決めたら具体的なタスクに落とし込んで（細分化）、スプリントバックログと言うリストにまとめる。そのスプリントのToDoリストってこと。
    - 各タスクの担当者は予め決めない。実際に作業する時に開発メンバーがスプリントバックログの中から選択するように！

# タスク細分化の例
```
#プロダクトバックログ
- Pictweetのツイート機能を作成する
↓
#スプリントバックログ
- ツイート保存用のテーブルを作成する
- 投稿の一覧画面の見た目を作成する
- ツイートが保存されるまでの処理を書く..など
```

- 4．デイリースクラムをする
    - 毎日15分間のミーティング（かっこよく言うとMTG）する。
    - 内容は、「昨日やったこと」「今日やること」「問題点」を全員で話し合う
- 5．スプリントレビューをする
    - スプリント計画ミーティングで決めた、リリースできるプロダクトになってるかレビューを受ける。
- 6．スプリント振り返り（スプリントレトロスペクティブ）
    - 「このスプリントで良かった点」「改善したい点」「次回のスプリントで挑戦すること」の3項目（KPI）について話し合う。
ARP、RARP、NAT、DNS、DHCP、ICMP

応用情報技術者平成30年春期 午前問34

TCP/IPネットワークにおけるRARPの機能として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/9ef4ca45-65e9-498f-63b9-cd34141ef112.png)


１、RARP(Reverse Address Resolution Protocol)は、
ARPがIPアドレスから機器のMACアドレスを得るのとは逆に、機器固有のMACアドレスから対応するIPアドレスを取得するためのプロトコルです。

MAC　→　IP　

２、ARP(Address Resolution Protocol)は、
IPアドレスから対応する機器のMACアドレスを取得するプロトコルです。
・要求パケットに送信元のIPアドレス・MACアドレスと通信相手の IPアドレスの情報を格納して、Ethernet ネットワークにブロードキャストする。
・要求パケットを受け取った各ノードは、自分の IPアドレスと同一であれば、自分の MACアドレスを送信元に伝える。

ARPはこの手順で、IPアドレスから MACアドレスを取得しています。
・ARP要求：ブロードキャスト
・ARP応答：ユニキャスト
　　・ユニキャスト(UNICAST)とは、コンピュータネットワークにおいて、単一の送信相手を指定して、データを送信することである。 最も頻繁に使用される送信方法であり、ブロードキャストやマルチキャスト、エニーキャストなどの用語との対比で使われる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c4aed15c-0e4f-fcef-db5c-e809f00e1fb5.png)


IP　→　MAC


３、TCP(Transmission Control Protocol)の説明
IPネットワークにおける誤り制御のためのプロトコルである。

４、RIP(Routing Information Protocol)の説明
ゲートウェイ間のホップ数によって経路を制御するプロトコルである。

５、DHCP(Dynamic Host Configuration Protocol)の説明
端末に対して動的にIPアドレスを割り当てるためのプロトコルである。

動的にIPを割り当てる


６、ICMP(Internet Control Message Protocol)の機能
IPパケットが通信先のIPアドレスに到達するかどうかを調べる。


７、RPC(Remote Procedure Call)の役割
サーバのIPアドレスを意識せず，プログラムの名前を指定するだけでサーバのプログラムの呼出しを可能にする。

８、DNS(Domain Name System)の機能
ドメイン名とホスト名からIPアドレスを求める。

９、NAT(Network Address Translation)の機能
プライベートIPアドレスとグローバルIPアドレスを相互に変換する。

プライベートIPアドレス　⇔　グローバルIPアドレス



参照：
https://www.fe-siken.com/kakomon/19_haru/q35.html

https://www.ap-siken.com/kakomon/24_haru/q33.html

https://www.ap-siken.com/kakomon/25_haru/q33.html
Ruby技術者認定試験

Ruby技術者認定試験の勉強をする中で学んだことを記録に残すもの。

#zip
Enumerableモジュールで提供されるメソッド。Arrayクラスは、Enumerableモジュールをインクルードしている。

```ruby
a = [1,2,3]
b = [4,5,6]
a.zip(b) #=>[[1, 4], [2, 5], [3, 6]]

[1,2,3].zip([4,5,6])
#=>=> [[1, 4], [2, 5], [3, 6]]
```

#範囲演算子（../...）
```ruby
(5..10).to_a   #=>[5,6,7,8,9,10]
(5...10).to_a  #=>[5,6,7,8,9]
```

#select/find_all
Enumerableモジュールで提供されるメソッド。Arrayクラスは、Enumerableモジュールをインクルードしている。
各要素に対してブロックを実行し、結果が真となる要素を探して（find/select）配列にして返す。

```ruby
numbers = [1,2,3,4,5]
numbers.select{|n|.even?}   #=> [2, 4]
numbers.find_all{|n|.even?} #=> [2, 4]
```
【PHP_エラー】session_start前に何かを出力した際に発生するエラー

PHP開発中に起きたエラーを備忘録として記録します。
#発生したエラー
```
Warning: session_start(): Cannot start session when headers already sent in C:\xampp3\htdocs\staff_login\staff_top.php on line 22

Warning: session_regenerate_id(): Cannot regenerate session id - session is not active in C:\xampp3\htdocs\staff_login\staff_top.php on line 23
```
session_start()を記述したところ上記のようなエラーが発生しました。
該当のコードを確認すると、下記のように記述されていました。

```php

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>coffeeapp</title>
</head>
<body>
<?php
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login'])==false)
{
:
:
```

#原因
session_start();前に何か出力していることが原因でした。
下記のように記述したところ問題なく実行することができました。

```php
<?php
session_start();
session_regenerate_id(true);
:
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
```
NFV(Network Functions Virtualisation)、AR(Augmented Reality，拡張現実)

応用情報技術者平成30年春期 午前問32

ETSI(欧州電気通信標準化機構)によって提案されたNFV(Network Functions Virtualisation)に関する記述として，適切なものはどれか。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/435c1569-fc33-6e8f-3e51-d20509f617c9.png)


１、NFV(Network Functions Virtualisation，ネットワーク機能の仮想化)は、仮想化技術を利用して、従来はルータ、スイッチ、ファイアウォール、ロードバランサなどの専用機器で行われていた機能を、汎用サーバ内の仮想マシン上で動くソフトウェアとして実装するアーキテクチャです。複数のネットワーク機器の機能を1つの物理サーバに集約できるため、コスト削減や信頼性向上などのメリットがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c33f5b27-0e34-8060-1c3d-26b6227f505d.png)


２、AR(Augmented Reality，拡張現実)の説明
インターネット上で地理情報システムと拡張現実の技術を利用することによって，現実空間と仮想空間をスムーズに融合させた様々なサービスを提供する。


３、ディープラーニングの説明
様々な入力情報に対する処理結果をニューラルネットワークに学習させることによって，画像認識や音声認識，自然言語処理などの問題に対する解を見いだす。


４、ペトリネットの説明
プレースとトランジションと呼ばれる2種類のノードをもつ有向グラフであり，システムの並列性や競合性の分析などに利用される。
・ペトリネット（英: Petri net）とは、カール・アダム・ペトリが1962年に発表した離散分散システムを数学的に表現する手法である。 モデリング言語としては分散システムを注釈付の有向2部グラフとして視覚的に表現する。


参照：

ペトリネット（英: Petri net）
https://ja.wikipedia.org/wiki/%E3%83%9A%E3%83%88%E3%83%AA%E3%83%8D%E3%83%83%E3%83%88#:~:text=%E3%83%9A%E3%83%88%E3%83%AA%E3%83%8D%E3%83%83%E3%83%88%EF%BC%88%E8%8B%B1%3A%20Petri%20net,%E8%A6%96%E8%A6%9A%E7%9A%84%E3%81%AB%E8%A1%A8%E7%8F%BE%E3%81%99%E3%82%8B%E3%80%82


https://www.ap-siken.com/kakomon/30_haru/q32.html
Snowflake のウェアハウスの起動時間を5分未満にしてお金を節約する話

# 背景

ウェアハウスの一時停止になるまでの不使用時間（自動一時停止）を減らすと、無駄な起動時間が減って、コストが減らせるなと思いました。
WebのUIだと最小が5分なので、いつも5分にしていたのですが、もっと減らせることに今さら気づきました。

![ウェアハウス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75613/3f0ed79f-b06d-241e-d90e-e4ef146efecd.png)


# やりかた

クエリでできます。
下記のように `AUTO_SUPEND` に任意の秒数を指定すれば5分以下の値にできます。

```SQL
CREATE WAREHOUSE TEST_WH
  WITH WAREHOUSE_SIZE = 'XSMALL'
    WAREHOUSE_TYPE = 'STANDARD'
    AUTO_SUSPEND = 60
    AUTO_RESUME = TRUE
    MIN_CLUSTER_COUNT = 1
    MAX_CLUSTER_COUNT = 1
    SCALING_POLICY = 'ECONOMY';
```


# 注意点

最小請求単位が60秒なので、それ以下に設定する場合はユースケースに合わせて決めましょう。
参考：https://docs.snowflake.com/ja/user-guide/warehouses-overview.html#impact-on-credit-usage-and-billing
IQ Bot：テーブルのマッピングの２つのやりかた

IQ Botでテーブルのマッピングを学習させるには、実は２通りの方法があります。

基本編となる[こちら](https://qiita.com/IQ_Bocchi/items/117778e2ef3e87460f62)の記事ではそのうち１つにしか触れていないのですが、この記事ではもう少し細かいことを説明します。

#２つの方法

##１．基本の方法

基本の方法は、「列名の位置にかぶせて、列の幅を指定する」というやりかたです。

[こちら](https://qiita.com/IQ_Bocchi/items/117778e2ef3e87460f62#%E3%81%BE%E3%81%9A%E3%81%AF%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E3%81%A4%E3%81%8B%E3%82%82%E3%81%86)の記事で説明しているのも、基本のやりかたです。

![01_基本の方法.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/181e5064-57be-8c13-c747-3de86e31dba1.jpeg)

[IQ Botは行数が可変の明細でも取得ができる](https://qiita.com/IQ_Bocchi/items/b16826ef46113ea8b3f0)のですが、可変の行数の明細を取得する場合は、必ずこの基本の方法でマッピングを設定する必要があります。


##２．１行目の値の位置を指定する方法

基本の方法ではうまくいかない場合、以下のように、１行目の値の位置を選択する方法もあります。

![１行目の値を選択.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/1bfc8d53-e5d3-c57b-b257-8c4065265892.jpeg)

このやりかたをすると、行の幅・高さともに１行目に準じた繰り返しを認識しようとするので、**行数が可変の明細には対応できない**というデメリットもあります。

ただし、**行数が固定の場合には、基本のやりかたよりも安定して繰り返しが認識できる**というメリットもあります。

#注意点

上記の２つのマッピングの方法を、同じ**テーブルの中で混在させることはできません**。

基本の方法で取得する場合は、同一テーブル内の全項目を基本の方法で学習させる必要があります。

１行目の値の位置を指定する方法をとる場合も、同一テーブル内の全項目を基本の方法で学習させる必要があります。
【Rails】動画を表示するvideo_tagの使い方

carrierwaveを使用し、画像＆動画のアップロード機能を実現しました。
動画表示用の「video_tag」は初めて使用したので備忘録として残しておきます。
Rails初心者のどなたかの役にたてば幸いです。

## 環境
MacOS Catalina
Rails 6.0.3.2
Ruby 2.6.3

## video_tagとは
![スクリーンショット 2020-09-02 18.22.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682425/57b27d28-45b5-a998-d2ee-144f286af559.png)
こんな感じで動画を表示する際によく使われるやつ。
image_tagの動画版だと思えば良いかな。

#よく使う属性
| 属性 | 意味 | 
|:-----------:|:------------:|
| autoplay     | ページ読み込み後自動再生するかどうか        |
| controls     | コントローラを表示するかどうか      |
| autobuffer   | 自動でバッファリングするかどうか     |
| muted        | 音を出すかどうか     |    
| size         | サイズを指定       |
| width        | 幅を指定 |
| height       | 高さを指定 |

# 使い方サンプル

```ruby:movie.html.erb
<%= video_tag post.video.url, height: "50%", width: "50%" controls: true, autobuffer: true %>
```

sizeもしくはwidth,heightでのサイズの指定は必須だと思われる。
カメラで撮った動画はブラウザではとんでもなくデカイ範囲に表示されるし、スマホで撮った動画は縦に長い。
そして、スマホで撮った動画だけ幅を狭くするとコントローラが出なくなるのはなぜだろう・・・（再生はできる）

# 終わりに
Twitterみたいにサムネイルを表示して、あとはユーザーに再生ボタンを押してもらう方がスマートなのかもしれない。 
どうやって実現するのかわからんが。。。
PHPでS3からファイル一覧を取得する

使う機会あると思うのですが、
依存関係とかそういったものを意識せずに使えるコードが無かったので。

## 準備
```sh:console
% composer require aws/aws-sdk-php
# 中略

% touch get.php

% tree -L 1
.
├── composer.json
├── composer.lock
├── get.php
└── vendor
```

ユーザやバケットは作成してあり、画像が格納されている前提です。

### コード

```php:get.php
<?php
declare(strict_types=1);

require_once __DIR__ . '/vendor/autoload.php';

use Aws\S3\S3Client;

define('REGION', 'ap-northeast-1');
define('BASE_URL', sprintf('https://s3-%s.amazonaws.com/', REGION));
define('BUCKET_NAME', 'bucket_name');

$s3 = new S3Client([
    'version' => 'latest',
    'credentials' => [
        'key' => 'mykey',
        'secret' => 'mysecret',
    ],
    'region' => REGION,
]);

// S3バケットの画像を全て取得
$objectContent = $s3->listObjects([
    'Bucket' => BUCKET_NAME,
    'Prefix' => 'path/to/file/',
])['Contents'];

// URLを組み立ててHTML生成
foreach ($objectContent as $object) {
    // ここで$object['Key']の拡張子で処理分けたらもっと良いかも
    echo sprintf("<img src=\"%s%s/%s\" width=\"300\"><br>", BASE_URL, BUCKET_NAME, $object['Key']);
}
```

## 参考
https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjects