OmniAICreator/Qiita-1.07M huggingface dataset:
routeを設定する際にpathを使えば任意のパスを作れる

## 実装したクラス名とは異なるパスをつけたい
　例えば、hoge_controllerを実装していたが、パスだけhuga/indexにしたい時があったとする。
　こんな時、コントローラー名を変えて、クラス名をいろいろ変えて、、などとする必要はない。routes.rbの設定で何とかなる。（ただし、ファイルの管理はややこしくなってしまうかもしれない。。）

## パスだけを任意の形にしたいならpathを使う
### 例
```
  resources :クラス名, path: 実現したいパス do
    collection do
      get :メソッド
    end
  end
```

## もっとカスタムしたい場合は以下を参照

[rails5]routes.rbでprefix・URI・controller#actionの値を任意にカスタマイズできる
https://qiita.com/og3/items/d814bf1a81cce2af633a
Ansible + Hashicorp Vault でセキュアな値を安全に使ってみるぜ ～その後～

お久しぶりです！ @ktoshi です。

非常に遅くなりましたが、あけましておめでとうございます
本年の抱負としては「記事をもっと書く！（月3回）」と考えていましたが、
早速1月から躓きかけているのでこれから頑張っていこうと思います。

すっかり寒くなりましたね、という前に大寒が過ぎてしまった今日この頃。
今年は久しぶりに我が家の周辺でも雪が積もり、冬らしい冬ですね。

さて、今回は前回記事にした Ansible + Hashicorp Vault の後日談をお話ししたいと思います。
※ 前回の記事: [Ansible + Hashicorp Vault でセキュアな値を安全に使ってみるぜ](https://qiita.com/ktoshi/items/1a6b2c339dbb934cacad)

# 概要
前回記事の「Ansible で使ってみよう」の項目で分かるように、
トークンやVaultサーバのURLがめちゃくちゃべた書きな状態でした。
正直これじゃバージョン管理できないや、という状態でした。

そこで、バージョン管理ができるようにより設定をスマートにしよう！というのが今回です。

# 前回記事での課題
前回書いた記事から下記を課題と設定し、本記事で解消したいと思います。
* トークンがべた書き
* Vault サーバのIPアドレスがべた書き

# 課題解決
今回の課題についてはいずれも Ansible の設定ファイルに追加することで解決できました。

早速設定ファイルをお見せします。

```ini:/etc/ansible/ansible.cfg
[lookup_hashi_vault]
token_file = /etc/ansible/.vault-token
url = http://192.168.100.50:8200
```

| 項目名 | 説明 | デフォルト |
|:-----------|:------------|:---|
| token_file | トークンを記載したファイルパス|.vault-token|
| url | Vault サーバのURL及びポート|http://127.0.0.1:8200|

トークンファイルにはトークンだけ記載しておけばOKです。

```/etc/ansible/.vault-token
s.bEQ3adfSwxusg2kdAMQ4Jel5n
```

こうすることでインベントリファイルに直接記載せずとも、
各種値を Ansible で利用することができます。

また、インベントリファイルで指定しなくて済むので記載もシンプルになります。

```yaml:hosts.yaml
---
test.example.com:
  hosts:
    192.168.50.1:
      ansible_user: worker
      ansible_ssh_pass: "{{ lookup('community.general.hashi_vault', 'secret/password)['passwd'] }}"
```

# まとめ
機密情報をセキュアに使う、という話は前回記事に記載しておりますので、
今回の記事では割愛しておりますが、これでより効率的に利用できるようになったかと思います。

ただ、元々の課題解決方法自体はいくつもあり、今回のやり方はセキュアではないと思っております。
というのも、Vault には各ロールが設定できるので今回サーバでがっつり設定すると
誰が使っても同じロールを使うことになります。
より厳格化するのであれば、Ansibleのplaybookを実行する際に環境変数で情報を渡してやる方が
良いのかなと思っております。
しかし、弊社の運用方針と効率性を考えた結果、今回の手法を採用しております。

ぜひ、皆様も Ansible の Playbook をバー所管理されている方はノウハウを授けてください！！

それでは皆様、よい Infrastructure as Code ライフを！！
本年もよろしくお願いいたします。
「高専キャリア クラウドAI開発講座」に参加してみた

#講座の説明
高専キャリアとFIXERがコラボして開催しているイベント。
昨年(2020年)、高専キャリア×Microsoftで同様のイベントが行われていました。
今回は通年で、4タームに分けて行うみたいです。
（第１タームは 2021/1/16 ~ 2021/3/20 に開催）

link : [クラウドAI開発講座(高専キャリア × FIXER)](https://online.kosen-career.tech/fixer-x-ai)

記事一覧↓
1. [「高専キャリア クラウドAI開発講座」に参加してみた](https://qiita.com/nomukoh/items/dd2bd4abed2075ff62ba) **→今回の記事**
2. [「高専キャリア クラウドAI開発講座」_中間報告会編](https://qiita.com/nomukoh/items/aa920b6f0dac29a83e89)
3. [「高専キャリア クラウドAI開発講座」_Twitter API 登録編](https://qiita.com/nomukoh/items/1032a62ab5b357029856)
4. [「高専キャリア クラウドAI開発講座」_最終報告会編](https://qiita.com/drafts/0d71064cbabc5e3b360c)
#クエスト
学生冒険者に3つのミッションが与えられました。

1. 初級編    「おうむ返しをするTeams BotをAzure上で作る」
2. 中級編    「Teams BotをAzure上で作り、プログラムを変更し、おしゃべり内容をカスタマイズする」
3. 上級編    「Teams BotをAzure上で作り、AzureのAIを使っておしゃべりさせる」

#自分の目標
おーちょさんのかいた記事があるので、それを参考にLINEとTeamsでBotを作成したい。

link : [やさしいチャットボットのつくりかた -1.Bot Frameworkでチャットボットを作ってみよう！](https://qiita.com/miokawa/items/6f1a3e480580e1e29abc)

#進捗
難しいことはなしでとりあえずBotを作りたいっていう人用に、おーちょさんが記事を書いてくださった。とりあえすTeams上で動くBotを作ってみる。

link : [Ｗindows環境で手っ取り早くAzureのボットアプリを作ってみた - Qiita](https://qiita.com/miokawa/items/6ef5255a1ea45e9c2056)
link : [【30分でつくれる！】初心者向け Azure Bot開発説明 - YouTube](https://www.youtube.com/watch?v=oiqZ7FiKsqM)

YouTubeの資料がわかりやすかったのでおすすめ。

いまのところ、BotをローカルとAzure上で動かすところまでできました。

#参考資料
高専キャリアさんからのお告げ

- de:code 2020
    - [学生諸君！ Azure であそぼう！ ～Microsoft の AI を自作アプリに取り入れるまで～ （おーちょさんのセッション）](https://www.microsoft.com/ja-jp/events/decode/2020session/detail.aspx?sid=Z01)
    - [Azure Bot Services を使って Teams bot を開発する （ちょまどさんのセッション）](https://www.microsoft.com/ja-jp/events/decode/2020session/detail.aspx?sid=A02)
- [Microsoft Learn for Students](https://docs.microsoft.com/ja-jp/)
- Qiita
    - [Windows環境で手っ取り早くAzureのボットアプリを作ってみた @miokawa ](https://qiita.com/miokawa/items/6ef5255a1ea45e9c2056)
    - [やさしいチャットボットのつくりかた -1.Bot Frameworkでチャットボットを作ってみよう！ @miokawa ](https://qiita.com/miokawa/items/6f1a3e480580e1e29abc)
    - [[完全無料で] Microsoft Teams で動く オレオレ bot を 1 時間で作る @chomado ](https://qiita.com/chomado/items/6bda10abde0551f25723)

#最後に
また進捗があれば投稿したいと思います。
####Now
- [x]  Azureアカウント作成
- [x]  環境構築
- [ ]  おうむ返しBotを作る
- [ ]  teamsにアップロード
- [ ]  ・ ・ ・
form_withを使って、ユーザーが新規作成される仕組みを理解する

webサービスで新規登録やユーザログインのときに使われる、<b>form_with</b>というヘルパーメソッド。

Railsチュートリアルなどで突然登場して、なんとなく使い方が分かってるけど説明はできない「曖昧状態」になっていませんか。

今回は、<b>form_withを使って、ユーザーが新規作成される仕組み</b>を理解する記事を書いていこうと思います！




## そもそも「フォーム」とは？


> 
* nameとvalueがペアになってサーバに送られる
> 
* nameとvalueはinputやselectやradioなどに付与される
> 
* action属性に指定されたURLに対して入力値が送られる


引用記事:
[https://qiita.com/DaichiSaito/items/cd66115569b0a75f1bfa#11-%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%A8%E3%81%AF%E3%81%8C%E6%9B%96%E6%98%A7]


この3つをはじめてみたとき？？？という感じでした。

例を挙げて説明してみます。

railsチュートリアルから以下のコードを引っ張ってきました。

```
<%= form_with(model: @user, local: true do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %>

      <%= f.submit "Create" %>
    <% end %>
```

これがHTMLソースに変換されると

```
<form accept-charset="UTF-8" action="/users" class="new_user"
      id="new_user" method="post">
  
  <label for="user_name">Name</label>
  <input id="user_name" name="user[name]" type="text" />

  <input  name="commit" type="submit"
         value="Create" />
</form>
```

※local: trueとは？
local: trueがない場合、Rails5ではAjaxによる送信という意味になる。
HTMLとしてフォームを送信する場合にlocal: trueが必要になります。


例えば、フォームの名前に「たろう」と入力されると
```
  <input id="user_name" name="user[name]" type="text" value="たろう" />
```
このようになります。

そしてformタグのaction属性に指定されたURL("/users" )に対して、nameとvalueが送られます。

コントローラ
```
    @user = User.new(params[:user])
```

params[:user]というのは、送られてきたnameに対応しています。今回であればname="user[name]"  value="たろう"が送られてきているので、@userというインスタンスにname:"たろう"が格納されます。


## form_withのしていること

```
<%= form_with(model: @user, local: true do |f| %>
      <%= f.label :name %>
      <%= f.text_field :name %>
```

整理すると、

* model: @user・・・入力値を格納するインスタンスとaction属性を指定("/users")

* local: true・・・HTMLとしてフォームを送信する場合にlocal: true必要

* <%= f.label :name %>・・・フォームのラベルを決めている

* <%= f.text_field :name %>・・・HTMLに変換されるとname="user[name]" type="text"になる



何が起きているかわからないとなってしまうform_withですが、
HTMLコードに分解して考えると、理解しやすいですね。
ブラウザの開発者ツールからHTMLソースを見る癖をつけていきましょう。
【Ubuntu 】 sudo apt install 実行時の404エラーがなぜsudo apt-get updateで解決できるか


# 環境

```
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.1 LTS"
```
# やったこと

中国語入力できるようにしたくて以下のコマンドを入力したら、404エラーが発生。

```
sudo apt install fcitx-googlepinyin
```
```
Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/f/firefox/firefox-locale-zh-hans_84.0+build3-0ubuntu0.20.04.1_amd64.deb 404  Not Found [IP: 160.26.2.187 80]
```
いろいろ調べて以下のコマンドで解決できたのは良いけど、ただコマンド打ってるだけで実際何が起きたのかよく分からなかったので調べてみた。

```
sudo apt-get update
```

# 何が起きていたのか

そもそも「apt install」は/var/lib/apt/listsからインストールされるコマンド。

「apt-get update」はパッケージリストがUbuntuリポジトリからダウンロードされ、/var/lib/apt/listsに保存される。だからエラー解消できたみたい。
【git】error: failed to push some refs to [githubのURL]プロテクトされたブランチにプッシュした場合

共同開発を初めて、初期に出たエラーです。
なんとも簡単なエラーですが、自分の戒めとして備忘録として載せておきます。

## プロテクトされたブランチにプッシュしちゃった
```:ターミナル
git push origin HEAD
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 1000 bytes | 1000.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote: error: GH006: Protected branch update failed for refs/heads/develop.
remote: error: At least 1 approving review is required by reviewers with write access.
To https://githubのURL
 ! [remote rejected] HEAD -> develop (protected branch hook declined)
error: failed to push some refs to 'https://githubのURL'
```

本来なら新しいブランチを切って、そこから開発用であるdevelopブランチにプッシュするのですが、ロックされているdevelopブランチに直でプッシュしちゃいました。
１つのエラー事例として参考になれば幸いです。
gem gretelの使い方　~パンくずリストを作ってみよう~

```
gem 'gretel'
```

このgemを使って、パンくずリストを作っていこうと思います。


## パンくずリストってなんぞや？？

 [![Image from Gyazo](https://i.gyazo.com/2cb4c1458d4b87e1e59f348414166c3e.png)](https://gyazo.com/2cb4c1458d4b87e1e59f348414166c3e)

ホームページのすみっこで見られる、ページの階層ですね。Webサイト内で、どの位置にいるのかがわかる機能です。

「ユーザー」を押すとユーザーページへ、「ホーム」を押すと最初のページへ飛ぶことができます。(ハンバーガーメニューとかパンくずリストとか、プログラミングの世界は、遊び心があって良いですよね。)

## gem 'gretel'を使う

こちらのGithubのREADMEをご覧ください↓↓

[https://github.com/kzkn/gretel:embed:cite]


gem 'gretel'をbundle installしたあと、

```
$ rails generate gretel:install
```

こちらのgenerateコマンドを使って、config配下にbreadcrumb.rbというファイルが生成されます。

それではbreadcrumb.rbに作りたいパンくずリストの設定を記述していきます。


## breadcrumb.rbにパンくずリストの設定を記述

 [![Image from Gyazo](https://i.gyazo.com/2cb4c1458d4b87e1e59f348414166c3e.png)](https://gyazo.com/2cb4c1458d4b87e1e59f348414166c3e)


先ほどのリストを試しに作っていきます。

```
#breadcrumb.rb

crumb :dashboard do
  link ' Home', dashboard_path
end

crumb :users do
  link 'ユーザー', users_path
  parent :dashboard
end

crumb :user do |user|
  link 'プロフィール', user_path(user)
  parent :users
end
```

上記のような記述になります。書き方としては、

```
crumb :"シンボル名" do
  link 'パンクズに表示したい名前', URL
  parent :"一つ上の階層名"
end
```

このように当てはめていきます。parentは一つ上の階層がなければ(今回ならHome)記述しなくてOKです。

breadcrumb.rbの設定をこれで完了です。


## viewファイルに記述していく

それぞれのviewファイルにbreadcrumbを記述していきます。


```
#Homeのviewファイル
<% breadcrumb :dashboard %>
```

```
#ユーザーのviewファイル
<% breadcrumb :users %>
```

```
#プロフィールのviewファイル
<% breadcrumb :users, @user %>
```

プロフィールのviewファイルで気をつけることは、

breadcrumb.rbにもあるように、プロフィールページはuser_path(user)というURLに飛ぶので、どのidのURLに飛んで欲しいのか(今回なら@user)を記述しないとエラーが出てしまいます。


あとはCSSなどで、ページの好きな位置にパンくずを表示すればOKです。とても簡単。。！

パンくずリストはヘッダーの下などに記述することが多いかと思いますので、部分テンプレートに分けておくのが便利かと思います。

## gem gretelを使って、パンくずリストを作ってみよう
 [![Image from Gyazo](https://i.gyazo.com/2cb4c1458d4b87e1e59f348414166c3e.png)](https://gyazo.com/2cb4c1458d4b87e1e59f348414166c3e)

一見むずかしそうな機能が、とても簡単に作れることが分かったと思います。

便利なgemを駆使しながら、より使いやすいRailsアプリケーションを作っていきましょう！
PRにマイルストーンを自動設定

# 概要
定期的にリリースするサービス向けにマイルストーンでPRをまとめている。
GithubのマイルストーンをGithub Actionsを利用して自動設定する方法の備忘。

- [マイルストーン](https://docs.github.com/ja/github/managing-your-work-on-github/about-milestones)
- [GitHubのGraphQL API](https://docs.github.com/ja/graphql)


# スクリプト

```prreview.yml
name: PullRequest assign the latest milestone automatically

on:
  pull_request:
    branches:
      - develop
      - 'feature/**'
    types: [opened, ready_for_review]

jobs:
  add-milestone:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            // https://octokit.github.io/rest.js/v18#issues-list-milestones
            const milestones = await github.issues.listMilestones({
              owner: context.repo.owner,
              repo: context.repo.repo,
              sort: "due_on",
              direction: "desc",
              state: "open",
            })
            // サービスのルールに依存: マイルストーンのタイトルが日付のもので最新のものを取得してくる
            const milestone = milestones.data.find(({ title }) => title.match(/^\d{4}-\d{2}-\d{2}$/)) || null
            if (!milestone) {
              console.log("マイルストーンが取得できませんでした")
              return
            }
            // PRのnumberを取得
            const prNumber = context.payload.pull_request.number
            const result = await github.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: prNumber,
              milestone: milestone.number,
            })
            console.log(result.status)
```

# 補足
マイルストーンの自動生成は下記を見る
https://qiita.com/stnamco/items/6778adcaa47569409825
マイルストーンを自動生成

# 概要
定期的にリリースするサービス向けにマイルストーンでPRをまとめている。
GithubのマイルストーンをGithub Actionsの定期実行で自動生成する処理の備忘。

- [マイルストーン](https://docs.github.com/ja/github/managing-your-work-on-github/about-milestones)
- [Github Actionsの実行トリガー](https://docs.github.com/ja/actions/reference/events-that-trigger-workflows#schedule)
- [GitHubのGraphQL API](https://docs.github.com/ja/graphql)


# スクリプト

```milestone.yml
name: Create Milestone

on:
  schedule:
    - cron: "0 17 * * *"

jobs:
  create-milestone:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/github-script@v3
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            // https://octokit.github.io/rest.js/v18#issues-list-milestones
            const milestones = await github.issues.listMilestones({
              owner: context.repo.owner,
              repo: context.repo.repo,
              sort: "due_on",
              direction: "desc",
              state: "open",
            })
            // サービスのルールに依存: マイルストーンのタイトルが日付のもので最新のものを取得してくる
            const milestone = milestones.data.find(({ title }) => title.match(/^\d{4}-\d{2}-\d{2}$/)) || null
            if (!milestone) {
              console.log("マイルストーンが取得できませんでした")
              return
            }
            const date = new Date(milestone.due_on)
            // サービスのルールに依存: 最新のマイルストーンのリリース日の4日前に次sprintのマイルストーンを作成
            const baseDate = new Date()
            baseDate.setDate(baseDate.getDate() + 4)
            if (date.getTime() > baseDate.getTime()) {
              return
            }
            date.setDate(date.getDate() + 14)
            date.setHours(9)
            const dueOn = date.toISOString()
            const month = ("00" + (date.getMonth() + 1)).slice(-2)
            const day = ("00" + date.getDate()).slice(-2)
            const releaseDate = date.getFullYear() + "-" + month + "-" + day
            // https://octokit.github.io/rest.js/v18#issues-create-milestone
            github.issues.createMilestone({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: releaseDate,
              due_on: dueOn,
              description: "定期リリース"
            })
```

# 補足
PRにマイルストーンを自動アサインする方法
https://qiita.com/stnamco/items/06d2147c93a1cca97371
PowerShell 文字コード


#### デフォルト確認(ファイル出力 $OutputEncoding)
デフォルトの出力は日本語環境だと `sjis` になっている
でも `-Encoding Default` 指定しないと違う `utf16` になってしまう。。。 

```
$OutputEncoding

BodyName          : iso-2022-jp
EncodingName      : 日本語 (シフト JIS)
HeaderName        : iso-2022-jp
WebName           : shift_jis
WindowsCodePage   : 932
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 932

```

#### ファイル読み込み -> 書き込み
結果としてはファイル読み込み、書き込み時にそれぞれ適切なエンコーディングを指定する必要がありそう。
読み込みは処理を挟まなければ問題ないけど置換とか処理したい場合はエンコーディング指定しないと思った結果にならない

```
# utf8 -> sjis
$read = Get-Content $filePath -Encoding UTF8;
$read | Out-File $filePath -Encoding default;

# sjis -> utf8
$read = Get-Content $filePath -Encoding default;
$read | Out-File $filePath -Encoding UTF8;

```
マイクなどの使用許可が得られなかった時のことを考慮した話

## はじめに
　アプリの中でマイクやカメラを使うときは、「マイクの使用を許可しますか？」といったアラートが表示されます。そこでユーザーが誤って「許可しない」を選択した場合、ユーザーにそのことを伝えるにはどうすれば良いでしょうか。ここではその解決策を共有します。

## 流れ

![ezgif-2-11aa8ab89fc0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/2f0f624b-a636-717a-a50a-d9c71d407f7c.gif)

初めて許可を求める -> アラートを表示
許可されている場合 -> 何もアラートを表示させない
許可されていない場合 -> そのことをアラートで表示させる
といった処理をやっていきます。


　
## ボタンが押された時
ここでは画面表示を担当するクラスでの動きを書いています。

```Swift
@objc func startButtonTapped() {
        let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.audio)
        if status == AVAuthorizationStatus.authorized {
            startButton.isHidden = true
            pauseButton.isHidden = false
            
        } else if status == AVAuthorizationStatus.restricted {
            audioRequestDelegate?.showPermissionChangeAlert()
        } else if status == AVAuthorizationStatus.notDetermined {
            audioRequestDelegate?.requestPermission()
        } else if status == AVAuthorizationStatus.denied {
            audioRequestDelegate?.showPermissionChangeAlert()
        }
    }
```

上の関数は収録ボタンが押された時の動きを表す関数です。`AVCaptureDevice.authorizationStatus(for: AVMediaType.audio)`でマイクの使用許可に関する値を判定しています。その後、値に応じて処理を分けています。

なお`AVAuthorizationStatus`は列挙型で

```Swift
public enum AVAuthorizationStatus : Int {

    case notDetermined = 0

    case restricted = 1

    case denied = 2

    case authorized = 3
}
```
と定義されているのですが、`case restricted = 1`はほとんどとる値ではないことがリファレンスに書かれているので、その値を取ることを想定していません。

## ボタンが押された時のコントローラーの動き

上のビュークラスから処理を委譲されたコントローラークラスの動きです。

```Swift
extension RecordingViewController: AudioRequestDelegate{
    //許可を求めるアラートを出す
    func requestPermission() {
        recordingModel?.requestRecord()
    }
    //拒否されているので、設定し直すアラートを出す
    func showPermissionChangeAlert() {
        print("拒否されてます")
        let alert = UIAlertController(title: "マイクの許可", message: "設定からマイクの使用を許可してください", preferredStyle: .alert)
        let alertAction: UIAlertAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default)
        alert.addAction(alertAction)
        present(alert, animated: true, completion: nil)
    }
    //許可されている時
    func authorized() {
        recordingModel?.start()
    }
}
```
許可をされている時は録音をスタートし、まだ聞いていない時は確認アラートが表示されます。そして拒否されている時は`UIAlertController`を作成し、アラートでユーザに設定を変えることを伝えます。
許可が既に得られている場合とまだ許可を求めたことがない場合の処理はモデルクラスで定義したものを持ってきています。
AWS ALB の LCU の料金計算方法の備忘録

AWS ALB の LCU の料金計算方法のメモ

https://aws.amazon.com/jp/elasticloadbalancing/pricing/ から LCU の計算方法が個人的にわかりにくかった(僕の頭が悪いだけなのですが…)ので整理したメモ。

ただし、例 1 しか整理してない。

金額は アジア・パシフィック/東京 リージョンをベースにした。

## 例1の条件

- (a) アプリケーションが 1 秒あたり平均 1 個の新しい接続を受信
- (b) それぞれ 2 分間継続する
- (c) クライアントは毎秒平均 5 つのリクエストを送信
- (d) リクエストと応答の合計処理バイト数は毎秒 300 KB
- (e) クライアントのリクエストをルーティングする 60 個のルールを設定

### 新しい接続(1秒あたり)

LCU は 1 秒あたり 25 個の新しい接続を提供する ← 既定値

アプリケーションは 1 秒あたり1この新しい接続を受信する ← (a)

つまり

1 / 25 = 0.04 LCU

と評価する

### アクティブ接続(1分あたり)

LCU は 1 分辺り 3000 このアクティブな接続を提供する ← 既定値

アプリケーションは 1 秒あたり 1 個の新しい接続を受信し、 ← (a)

それぞれ 2 分間継続する ← (b)

つまり

1 分辺り 120 個のアクティブ接続が存在する状態となる

つまり

120 / 3000 = 0.04 LCU

と評価する

### プロセスされたバイト数(GB / 時)

LCU は 1 時間辺り 1 GB の処理バイトを提供する ← 既定値

アプリケーションのレスポンスは平均 300 KB であり ← (d)

1時間あたりの応答総量は、

(d) 応答 300 KB * 60 * 60 = 1080000 KB = 1.08 GB

となる

つまり、

1.08 GB / 既定値である LCU 1時間あたり 1 GB = 1.08 LCU

と評価される

### ルール評価(1秒あたり)

LCU 1 秒あたり1000 個のルール評価を提供します( 1 時間あたり / 設定されたルールが全て処理される前提) ← 既定値

このアプリケーションは 1 秒あたり 5 個のリクエストを受信する ← (c)

ので、各リクエストに対して 60 個のルールが評価れます ← (e)

その結果、

1 秒あたり ( 60 個のルール - 無料分 10 のルール) * 5 = 最大 250 個のルール評価

となり、

上記 250 個のルール評価 / 既定値容量の 1000 個のルール評価 = 0.25 LCU

と評価される

### 最終評価

これらの評価の結果、最も LCU の値が大きい プロセスされたバイト数( GB / 時) = 1.08 LCU が計算軸となる

この結果、以下の利用金が算定される

- 1 時間あたりは  1.08 LCU * 0.008 USD = 0.00864 USD となり
- 1ヶ月換算すると 0.00864 USD * 24 * 30 = 6.22 USD となる
Ubuntu 20.04 LTSへssh接続時の文字化け対策

# 現象
さくらVPS上にインストールしたUbuntuに対してssh接続し、Bitnami Redmine Stackインストール時、メッセージが文字化けした

> ----------------------------------------------------------------------------
> ???? Bitnami Redmine Stack ?????????????
> 
> ----------------------------------------------------------------------------
> ????????????????????????????????????????????????????????????????????????????

# 環境

- 接続先：Ubuntu 20.04（さくらVPS　お試し期間中）
- 接続元：Windows10 コマンドプロンプト

# 対象方法

「参考URL」のサイトを参考に日本語に下記手順を実施し対応した

- ランゲージファイルのインストール
- ローケールの変更
- プロファイルへの登録

# 参考URL
[Ubuntuで文字化けしたときの対処法](https://www.t3a.jp/blog/infrastructure/ubuntu-text-garbled/)
BoltでSwitch文を使う方法【Unity】

UnityのBoltでSwitch文を使う方法

##Ver
unity -2018.4
Bolt -1.4.13
(https://assetstore.unity.com/packages/tools/visual-scripting/bolt-163802)

##目的

- Switch文をBoltで実装する方法を記述
- Boltの日本語記事があまりないから外向けにも書く

##ノード作成方法

(BoltのインストールとFlowGraph作成までは省略)

Flow Graph上で
右クリック→（「Add Unit...」→）「Control」→「Switch on ~」を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319508/a1b8c9b0-007c-026e-6027-353401ef1f19.png)


デフォルトのBoltでは
- Switch on Integer
- Switch on String
- Switch on Enum
が存在します


##caseを増やす方法
（例はSwitch on Integerですが、Switch on Stringも同様です）

初期ノードの出力先（Output）は「Default」のみとなっています
これを増やすためFlowGraph上の「Switch on Integer」をクリック
左側のGraph InspectorのOption下部の「＋」をクリック
**（※FlowGraphのタブが小さいと表示されないため注意！！！！！！！）**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319508/c897f846-438e-589f-48f3-c7c84f02de05.png)


####(オマケ)Switch on Enumについて

現在VerではenumをInspector上では作成できないみたいです（スクリプトを書いて作るしかないらしいです。未試行）

ただ、Boltに備え付きの列挙型があるので、そこから選ぶのでも事足りるかと思います
用途に合わせてSwitch on EnumのOptionから選びます

- Value type（変数の型によって遷移先を変える）
- Mouse Button（マウスの右クリ左クリのどこを押されたかで遷移先を変える）
- Read Status（ファイル入出力の状況で遷移先を変えられる）

など、コードが書けなくても十分使えそうです！
Cloud Functions Pythonを使ったローカル開発環境とデプロイ方法

# Cloud Functions Pythonを使ったローカル開発環境とデプロイ方法

## はじめに

最初に毎回、Functionsにデプロイして実行するのは手間なのでローカル実行できるようにする
function-frameworkをインストールしローカル実行する
その後、Cloud Functionsにデプロイする

```
$ pip install functions-framework
```

## HTTPサンプル作成

main.py 作成

```
def sample_http(request):
    return "sample"
```

main.py ディレクトリに移動
下記functions-frameworkコマンド実行で `localhost:8080` がFunctionsの呼び出し元になる

```
$ functions-framework --target sample_http --signature-type=http --port=8080 --debug
 * Serving Flask app "sample" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with fsevents reloader
 * Debugger is active!
 * Debugger PIN: 120-504-718
```

デプロイ

```
$ gcloud functions deploy sample_http \
--runtime python37 --trigger-http --allow-unauthenticated
```

確認

```
$ curl "https://REGION-PROJECT_ID.cloudfunctions.net/sample" 
```

## PUBSUBサンプル作成

main.py作成

```
from flask import current_app


def sample_pubsub(event, context):
    current_app.logger.info("sample")
```

main.py ディレクトリに移動
下記functions-frameworkコマンド実行で `localhost:8080` がFunctionsの呼び出し元になる

```
$ functions-framework --target sample_pubsub --signature-type=event --port=8080 --debug
 * Serving Flask app "sample" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with fsevents reloader
 * Debugger is active!
 * Debugger PIN: 120-504-718
```

PUBSUB実行はPOST、Content-typeは`application/json`アクセスしないといけない
ログがコンソールに出力される

```
curl -X POST -H'Content-type: application/json' -d "{\"key\":\"value\"}"  "http://localhost:8080"
```

```
[2021-01-23 03:40:15,954] INFO in main: sample
```

デプロイ

```
gcloud functions deploy sample_pubsub \ 
--entry-point=sample_pubsub --runtime python37 \
--trigger-topic sample_pubsub --allow-unauthenticated
```

Cloud Functions コンソールのテストにて確認
![screencapture-console-cloud-google-functions-details-us-central1-sample-pubsub-2021-01-23-03_53_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59264/0caca26e-301b-a766-43e4-e493d349e25e.png)
AL2にanyenv,nodenvをインストールする



## anyenvのダウンロード
```
git clone https://github.com/anyenv/anyenv ~/.anyenv
```

## パスを通す
```
echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
```

## シェルを再起動する
```
exec $SHELL -l
```

初期化

```
anyenv install --init
```

確認

```
anyenv --version
```

## pluginをインストールする
```
anyenv install --init
```

## nodenvのインストール

インストールできるリストの確認

```
anyenv install --list
```

nodenvをインストール

```
anyenv install nodenv
```

## シェルを再起動する

```
exec $SHELL -l
```

確認

```
nodenv -v
```
setup.pyのないGitHubリポジトリからライブラリをimportする方法

ハマったので備忘録として残しておきます。

Pythonでライブラリをインストールするとき一番楽な方法は`pip install`ですが、これは開発者がライブラリをPyPIに登録している必要があります。

GitHubのリポジトリから直接インストールする場合は`pip install git+`が使えますがこれも開発者が`setup.py`を用意している必要があります。

上記以外の場面でGitHubのライブラリを使いたい時は、以下のようにします。

## 1. ローカルでライブラリが格納されている場所を調べる

``` python
import numpy
numpy.__file__

# /usr/local/lib/python3.6/dist-packages/numpy/__init__.py
```

適当なライブラリを使ってライブラリが格納されている場所を調べます。この場合`/usr/local/lib/python3.6/dist-packages/`にライブラリが格納されています。

## 2. GitHubリポジトリをクローンする

以下のようにして上記で調べたライブラリが格納されている場所に、目的のGitHubレポジトリをクローンします。

```
git clone [リポジトリのURL] [ライブラリが格納されている場所][任意のライブラリ名]
```

以上で目的のライブラリがimportできるはずです。
もちろんパッケージの依存関係などは考慮されてないのでその辺りは注意する必要がありますが、とりあえず使いたい場合には上記の方法で大丈夫です。
[PlayCanvas] Assetの動的読み込み

# はじめに
PlayCanvasのアセットはPreloadにチェックが入ってるものは全て起動時に読み込みます。それでは重いですし、何より全てのアセットが起動時に必要とも限らないので、必要最低限のアセットだけにPreloadにチェックを入れ、他のアセットは必要に応じて動的に読み込む必要があります。

# 方法
## 読み込むだけ
アセットの読み込みは`app.assets.load()`を使用するだけです。

``` javascript:Sample
var Sample = pc.createScript('sample');

Sample.attributes.add('picture', {type: 'asset'});

Sample.prototype.initialize = function() {
    this.app.assets.load( this.picture );
};
```
`load()`はまだ読み込まれていないデータをロードするメソッドです。すでに読み込まれている場合は何もしません。

## 読み込みを待ってから処理を実行する
先の方法は読み込むだけなので、読み込まれたら反映をする必要があります。それを実現する為に`ready()`を使用します。

``` javascript:Sample
var Sample = pc.createScript('sample');

Sample.attributes.add('picture', {type: 'asset'});

Sample.prototype.initialize = function() {
    this.picture.ready( this.onLoaded );
    this.app.assets.load( this.picture );
};

Sample.prototype.onLoaded = function( asset ) {
    this.entity.element.textureAsset = asset ;
};
```

`ready()`は読み込みが完了していた時に処理を行うメソッドです。
すでに読み込まれていれば即時実行されます。

## まとめて読み込む
上記の方法は、1つのアトリビュートに1つの処理を書いているので、数が増えれば当然煩雑になります。ある程度決まったルールがあるのであれば、アセットタグを使用した読み込みを実装するべきです。

``` javascript:Sample
var Sample = pc.createScript('sample');

Sample.prototype.initialize = function() {
    var assets = this.app.assets.findByTag( 'Tag' );

    var self = this;
    assets.forEach(( elm )=>{
        self.app.assets.load( elm );
    });
};
```

# おわりに
覚書程度ですが、一先ず基本的な手段を書きました。
凝ったことをしなければ、これで十分なはずです。(多分)

# おまけ
ここからはただの個人的覚書

## 一連の処理をメソッド化する
紹介したコードを全ての場所に書いていたらはっきり言って手間ですし汚くなるのは目に見えてるので、一連の動作をメソッド化します。

``` javascript
function checkLoad( asset, callback ){
    const app = pc.Application.getApplication();
        
    if( asset ){
        asset.ready( callback );
        app.assets.load( asset );
    }
}
```

## プロジェクト外のリソースを読み込む
定期的にキャラを追加するゲームだったとして、キャラを追加する度にプロジェクトにインポートしてビルドしてサーバーに上げるのは非効率なので、そういったデータは別に管理するとなったとしましょう。そういったデータを読み込む方法として`loadFromUrl()`というメソッドが用意されています。

``` javascript
var Sample = pc.createScript('sample');

Sample.prototype.initialize = function() {
    const url = "";
    const type = "texture";
    this.app.assets.loadFromUrl( url, type, this.onLoaded );
};

Sample.prototype.onLoaded = function( asset ) {
    this.entity.element.textureAsset = asset ;
};
```
AWS Cognito とは

## 勉強前イメージ

正直聞いたことないからイメージがつかない

## 調査

### AWS Cognito とは

読み方は `コグニート` と読み、
ウェブやモバイルのアプリケーションにユーザがサインイン・サインアップできたり、
複数の端末でも情報を共有できるようなサービスです。

### AWS Congnito の機能

大きく分けて以下の2つが機能としてあります。

- Cognito Identity : 固有のIDを割り振る
- Cognito Sync : 固有のデータストレージの提供

### Cognito Identity : 固有のIDを割り振る

`Cognito Identity` の機能としては、アプリケーションを使用するユーザのサインイン・サインアップを提供します。
Cognito を使って、ユーザーに固有のIDを振ることができます。
また、ユーザを一意にするために以下の方法があります。

- パブリックなサービスのログインユーザIDと紐付ける

パブリックなサービスとはgooge, twitter, facebookなどで公開されているログインすることが出来るサービスになります。
いずれかのサービスでログインしたユーザIDとCognitoのIDを紐付けて一意であることを証明します。

- 匿名ユーザ

匿名ユーザは上記のいずれも使用しない場合でも固有のユーザIDを割り振ることができます。
どちらであってもIDは重複することはありません。

### Cognito Sync

`Cognito Sync` は、ユーザにAWSのサービスを提供するサービスです。
ユーザIDが割り当てられたユーザに対して、データを保管する場所を提供します。
これは、AWSのサービスでローカルで保存するのではなくクラウドで保存するので、
デバイスが変わっても、同様のユーザであればデータが同期出来るという特徴があります。

![syncUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b4e026f5-f465-9ab9-7314-95db3deb018d.png)

## 勉強後イメージ

ログインが簡単に出来るサービスかー
ログイン画面とか裏側の認証とかも確かに自作で作るのめんどくさそう....

## 参考

- [マルチプラットフォームのモバイル・WebアプリのアクセスをコントロールするAmazon Cognito](https://business.ntt-east.co.jp/content/cloudsolution/column-123.html)
- [図解！よく分かる Amazon Cognito 入門 #アドカレ2015](https://dev.classmethod.jp/articles/what-is-the-cognito/)
- [Amazon Cognitoを使ったサインイン画面をつくってみる～サインアップ編～](https://www.tdi.co.jp/miso/amazon-cognito-sign-up)
- [AWSの「Cognito」とは？｜AWS（Amazon Web Service）](https://www.acrovision.jp/service/aws/?p=2568)
openssl verifyでunable to get local issuer certificateになる

# openssl verifyでunable to get local issuer certificateになる

```shell
openssl verify -show_chain -verbose /etc/letsencrypt/live/test.example.com/fullchain.pem
CN = test.example.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error /etc/letsencrypt/live/test.example.com/fullchain.pem: verification failed
```

これは、`openssl verify`が、中間証明書がチェーンされた証明書を想定していないことによるもの。
中間証明書の`Let's Encrypt Authority X3`を`-untrusted`指定で教えてあげると良い。

```shell
openssl verify -show_chain -verbose -untrusted /etc/letsencrypt/live/test.example.com/fullchain.pem /etc/letsencrypt/live/test.example.com/fullchain.pem
/etc/letsencrypt/live/test.example.com/fullchain.pem: OK
Chain:
depth=0: CN = test.example.com (untrusted)
depth=1: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 (untrusted)
depth=2: O = Digital Signature Trust Co., CN = DST Root CA X3
```

`-untrusted`で指定する証明書は、中間証明書だけにして、 `/etc/letsencrypt/live/test.example.com/chain.pem` でも良い。


## 参考
- https://stackoverflow.com/questions/28080408/how-to-verify-certificate-chain-with-openssl
- https://serverfault.com/questions/720250/openssl-verify-outputs-unable-to-get-local-issuer-certificate
- https://stackoverflow.com/questions/25482199/verify-a-certificate-chain-using-openssl-verify
世界一わかりやすいグリッドデザイン入門

# 前提知識
- HTMLの基礎
- CSSの基礎

# 概要
複雑そうなグリッドデザインもコツを掴めれば簡単に実装できます！
今回はそんなグリッドデザイン超入門初心者向け講座です！！


# 早速やってみよう
とりあえずindex.htmlとstyle.cssを作成

最初は超入門
![スクリーンショット 2021-01-23 1.19.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/17a6557d-299b-754e-4e49-a5d92fa045e3.png)



```index.html
  <div class="oya">
    <div class="red-box"></div>
    <div class="blue"></div>
  </div>
```
```style.css
body {
  margin: 0;
}
.oya {
  display: grid;
  grid-template-rows: 400px;
  grid-template-columns: 50% 50%;
  width: 100%;
}

.red-box {
  background-color: red;
}
.blue-box {
  background-color: blue;
}

```

この場合columnが横に50%ずつ
rowが縦に400pxって感じになります！

# ちょっと応用

![スクリーンショット 2021-01-23 1.36.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825833/7d728b44-3e4a-8c4f-0366-00c35bb403e4.png)

```index.html
<div class="oya">
    <div class="red-box"></div>
    <div class="blue-box"></div>
    <div class="yellow-box"></div>
    <div class="green-box"></div>
  </div>
```

```style.css
.oya {
  display: grid;
  grid-template-rows: 100px 100px 100px;
  grid-template-columns: 200px 100px;
}

.red-box {
  background-color: red;
  grid-row: 1 / 2;
  grid-column: 1 / 2;
  /* 1から2  */
}
.blue-box {
  background-color: blue;
  grid-row: 2/3;
  grid-column: 1/2;
  /* rowは2から３、columnは1から2 */
}

.yellow-box {
  background-color: yellow;
  grid-row: 1/3;
  grid-column: 2/3;
  /* rowは1から3, columnは2から３  */
}

.green-box {
  background-color: green;
  grid-row: 3/4;
  grid-column: 1/3;
  /* rowは3から4
  columnは1から3 */
}

```

まず始めに親要素に
display: gredを宣言します。
そのあとrowとcolumnの配置をそれぞれ決めていきます！

あとは簡単！
grid-rowとgrid-columnで各要素の場所を指定するだけです！

今回は超入門と言うことで簡単な構成でしたがもっと応用すると複雑なデザインができると思います！

お疲れ様でした！
え、まだエラー処理を一括管理していないの？

まずは謝ります。

タイトルで煽ってしまい申し訳ありません。

ところで皆さん、まずは下記のエラーメッセージをご覧ください！

>NavigationDuplicated: Avoided redundant navigation to current location

vue-routerを使っている方は、一度は遭遇しているであろうこのエラー。

意味は、「同じページに遷移できないよ！」と言う意味です。

まずは、このエラーの回避策をお教えします。

```
this.$router.push('/').catch(() => {})
```

たった``catch(() => {})``を付けるだけでエラーが出なくなります！

これでエラーを解決した気にならずにもうちょっと我慢して見て下さい。

では、大規模な開発になった場合、いちいち``catch(() => {})``を付けるとなると面倒ですよね？？？

そこで、出てくるのが**errorHandler**というモジュールです！

これは、Vue特有のエラーを検知してくれる優れものです。

これは、同じようなエラーメッセージが何度も出てる場合に有効です。

使い方としては、エラーメッセージごとに処理を分けて使うといった感じです。

それでは使い方を見てみましょう！

``main.js``にて以下のように関数の宣言を行います。

```main.js
Vue.config.errorHandler = function (error) {
  //処理
}
```

<font color="red">※注意</font> アロー関数にするとエラーが起きます！！！

次に、今回のエラーを例に処理を書いていきます。

```main.js
Vue.config.errorHandler = function (error) {
  if (error.name === 'NavigationDuplicated') {
    // routerで遷移する時、同じページに遷移しようとすると起こるエラーを回避
    return
  }
}
```

このようにして、エラーメッセージを表示させることなく処理を終えることができます！

これはめちゃくちゃ使えるのでぜひ皆さんも使ってみてください！！！

以上、「え、まだエラー処理を一括管理していないの？」でした！

良かったら、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
Alpine.js をさわってみた（x-cloak編）

[Alpine.js](https://github.com/alpinejs/alpine) は、Vue.jsによく似たコードの書き方で、より簡単にリアクティブなサイトが構築できるJSフレームワークです。

今回は、`x-cloak` ディレクティブについての記事です。

## `x-cloak` ディレクティブ

[Alpine.js](https://github.com/alpinejs/alpine) 日本語ドキュメントの `x-cloak` の説明欄には、

> Alpine の初期化時に、要素から `x-cloak` 属性が削除されます。これは、事前に初期化された DOM を隠すのに役立ちます。

と、あります。
む、むずかしい…。

つまり、htmlタグ内に `x-cloak` 属性を付けておけば（ `<div x-data="{}" x-cloak></div>` ←こんな感じ ）、Alpineの初期化時に `x-cloak` 属性を取り消してくれるそうです … これ実際に実装してみないと、イメージわかないっすな (;・∀・)

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

```html:例１
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        [x-cloak] { 
            color: red;
            font-size: 3rem;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
</head>
<body>
    <div x-data="{ foo : 'foo' }" x-cloak>
        <p>x-cloakをつかってみよう！</p>
    </div>    
</body>
</html>
```

上記の「例１」をブラウザで表示してみると、**ブラウザで開いた瞬間**は、`head`タグ内の`style`によって、`x-cloak` 属性がある `div` タグにスタイルが適応されます（文字が赤く、大きな文字が表示されます）。

しかし、その後 `Alpine.js` の初期化時に `<div x-data="{ foo : 'foo' }" x-cloak>` の `x-cloak` 部分が削除されるために、`style`タグ内で定義されている`[x-coak]` 部分が適応されなくなります。

## x-cloak の使いどころ

この、`x-cloak` が役立つのはドロップダウンやモーダルを実装するときです。下の例をご覧ください。下記のCodePenでは、**`x-cloak` を使用しないでドロップダウンを実装**したケースです。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="masahiro111" data-slug-hash="abmrmwM" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="abmrmwM">
  <span>See the Pen <a href="https://codepen.io/masahiro111/pen/abmrmwM">
  abmrmwM</a> by Masahiro (<a href="https://codepen.io/masahiro111">@masahiro111</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

上記CodePenのページを別タブで開いて、一度更新してみると、更新した瞬間にドロップダウンの内容である**「ボタンもしくは、ボタンの外をクリックすると閉じます」**という文字列が見えてしまうのが確認できますでしょうか？
これは、`Alpine.js` が初期化することによって、`ul`タグ部分が非表示になるので（ `ul` タグの `x-show` で `open` の値が `false` になったら非表示）、**`Alpine.js`が初期化するまで `ul` タグ内が見えてしまう** ためです。

では、ブラウザで開いた瞬間にドロップダウン内の情報を見せないままにするためにどうするかというと、ここで `x-cloak` を使用します。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="html,result" data-user="masahiro111" data-slug-hash="xxENEzv" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="xxENEzv">
  <span>See the Pen <a href="https://codepen.io/masahiro111/pen/xxENEzv">
  xxENEzv</a> by Masahiro (<a href="https://codepen.io/masahiro111">@masahiro111</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

このようにすると、ページ開いた瞬間でも、ドロップダウンの内容が非表示のままで良い感じになります。
ローカルでposrgresqlを起動する

# 課題
postgresqlでmigratioinしようとしたら下記のエラーが出てしまう

```
FATAL:  role "postgres" does not exist
```

## 前提
・macOS Big Sur ver11.1 
・homebrewでpostgresqlをインストール済み(今回は13.1)

## 解決法

homebrewでpostgresqlを起動させます

```
brew services start postgresql
```
Vue.jsでページごとにhead,meta,titleを変える方法

皆さん、すべてのページでタイトルを同じにすると検索に引っかかりにくいってご存じですか？

他にも、サイトを作る際にパンくずリストを作っておくと、Googleロボットが認識しやすいだとか。

あまりSEOには詳しくないのですが、ここらへんの基礎知識には対応させた方が良いと考えているので、今回はタイトルの通り、ページごとに``head,meta,title``を変えていくパッケージをご紹介したいと思います。

その名も**vue-head**です！

説明はこの辺にしておいて、解説していきます。

#パッケージのインストール#

まずは``vue-head``をインストールします。

```
npm i vue-head --save
```

#パッケージをインポート#

次に、``main.js``にて以下のように記述します。

```main.js
import Vue from 'vue'
import VueHead from 'vue-head'

Vue.use(VueHead)
```

そしたら、後はコンポーネントにて好きなように設定していくだけ！

```App.vue
<script>
export default{
  head: {
    title: {
      inner: 'グーグル',
      separater: ' | ',
      complement: '会員登録'
    },
    // グーグルリキャプチャのAPI取得
    script: [
      {
        type: 'text/javascript',
        src: 'https://www.google.com/recaptcha/api.js?render=' + process.env.VUE_APP_SITE_KEY,
        async: true
      }
    ]
  },
}
</script>
```

ただし、ここで注意してほしいのがscriptタグは``nuxt.js``や``vue-router``でページ遷移する際にここで読み込まれたスクリプトファイルがそのまま残ってしまいます。

画面自体に影響がなければ良いのですが、例えば「Google reCAPTCHA」では画面右下にロゴマークが出てしまうなど邪魔になる場合があります。

その時は、``window.location.href``などを設定することで、この問題を解消することができます。

以下にその例を挙げます。

```App.vue
<script>
export default{
  beforeRouteLeave(to, from, next) {
      window.location.href = to.path
  }
}
</script>
```

このようにすることで、スクリプトタグを次のページに持ち込まないようにしました。

ただ、このやり方はいかがなものかなと思います。

恐らくやり方としては適切な形ではないので、悪魔で参考程度に知っておいてください。

他のやり方を知っている方は、ぜひコメント欄にてご教示お願いします。

以上、「Vue.jsでページごとにhead,meta,titleを変える方法」でした！

良かったら、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
cherry-pick:あるブランチの特定コミットを取り入れたい時に使うコマンド

複数の作業ブランチがあり、その中から特定コミットを反映させたい。
しかし、リリースの日程調整上、全てマージするわけにはいかないと言ったこともあり得ます。
このコミットの内容だけ欲しいのになぁという場面で使えます。

# cherry-pick

```
// これを実行するとコミットまで実施される。
git cherry-pick 1fdc89d0

// コミットはせずステージングにあげる
git cherry-pick -n

// 名前を指定する
git cherry-pick -e

// 複数コミットに対して行う(1fdc89d0 ~ 546fc501の間のコミットを対象に)
git cherry-pick 1fdc89d0..546fc501
```

コミットIDの調べ方

```
git log
```

## コンフリクトが起きた

コンフリクトの解消をしたら下記で処理を再開できる

```
git cherry-pick --continue

// やめる時
git cherry-pick --abort
```

## cherry-pickは再使用できない

これはすでにcherry-pickしようとしているコミットIDがブランチに記録されている場合の話。
例えばあるコミットでデグレを起こし、該当箇所をrevertし解消した後Pushしたとする。
この後、再度ローカルブランチで一部コミットだけをcherry-pickして修正を加えるなどができない。**そのコミットは履歴に組み込まれているという認識になるため。**

こんな場合にも使えるのがcheckout。

## checkout branch名 -- file名 で該当ファイルの内容を引っ張る

```
git checkout branch名 -- file名
```

これならcode内容をとってくるだけなので、自分で新規コミットを作る形になる。
岩永さんの配信の「Visual Studio 16.9 Preview 3 リリース (C# 10.0 追加予定機能ちょっとあり)」に参加してきました

[Visual Studio 16.9 Preview 3 リリース (C# 10.0 追加予定機能ちょっとあり)](https://qiita.com/drafts/ca0f86a7c34e2c385923/edit)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/9fd0f04f-1124-1c24-f2b5-75ca36980ffc.png)

今回も岩永さんの動画にお邪魔させてもらいました。

岩永さんの配信は 1 つの配信に対して 1 Issue という感じになっています。なので、Issue を見るとポイントになった箇所のコードとかが簡単な説明と共に書いてあるので、Issue を見るだけでも内容がわかって忙しい人にはお勧めです！（一番はライブで見るですけど！）

https://github.com/ufcpp-live/UfcppLiveAgenda/issues/24

## 今回のおすすめポイント

自分的には最後にあった XALM で DataContext プロパティに設定する ViewModel を生成してくれるところと、PInvoke のコードを生成している CsWin32 です。

該当コメントへの直リンク

[P/Invoke 話が盛り上がった。](https://github.com/ufcpp-live/UfcppLiveAgenda/issues/24#issuecomment-765497347)

[XAML からの ViewModel 生成。INotifyPropertyChanged も生成してる。プロパティ生成もあった。](https://github.com/ufcpp-live/UfcppLiveAgenda/issues/24#issuecomment-765479640)

## まとめ

ということで、今後も配信に参加したらこんな感じで軽いまとめを書いてみようと思います。
ruby のLoadErrorでつい忘れがちなこと

# よく出るこういうエラー


Traceback (most recent call last):
	2: from /Users/*******/.********/********.rb:5:in `<main>'
	1: from /Users/******/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require'
/Users/******/.rbenv/versions/2.6.3/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- parseconfig (LoadError)


今回はparseconfigというgemファイルをそもそもインストールしていなかったのが原因でした


##解決策
gem install parseconfig -v <バージョン名＞
フロントエンドメモ

#項目
1. コンテナにトリミングせず良い感じに画像をはめ込む
2. アンカー使ったリンクでPOSTしてvalueを渡す
3. PDFを表示する
4. 縦中央寄せ(毎回検索してる気がする)
5. コンテナ内改行
6. リンクの下線消す
7. 区切り線を引く
7. テーブルにスクロールバー

#1.コンテナにトリミングせず良い感じに画像をはめ込む
- `object-fit: contain;`

```css:css
img {
  width: 100px;
  height: 100px;
  object-fit: contain;
}
```

#2.アンカー使ったリンクでPOSTしてvalueを渡す
```html:html
<form  name="form_ex" action="/index method="post">
 <input type="hidden" name="test_send" value=0>
 <a href="javascript:フォームのname.submit()">リンク名</a>
</form>
```

#3.PDFを表示する
- `embed`

```html:html
<!--この世で最も優れたタグ-->
<embed src="file_name.pdf" width="800px" height="2100px" />
```

#4.縦中央寄せ(毎回検索してる気がする)
```css:css
.test {
  height: 150px;
  line-height: 150px;
}
```

#5.コンテナ内改行
```css:css
.test{
  word-wrap: break-word;
}
```

#6.リンクの下線消す
```css:css
.test{
  text-decoration: none;
}
```

#7.区切り線を引く
- `hrタグ`
- `align`に`left,center,right`が入れられる

```html:html
<hr size="1px" width="600px" color="gray" align="center">
```

#8.テーブルにスクロールバー
- overflow-y:scroll テーブル横にスクロールバー
- overflow-x:scroll テーブル下にスクロールバー
- overflow:scroll テーブル横・下にスクロールバー
- overflow-y:auto 内容に応じて横にスクロールバー
- overflow-x:auto 内容に応じて下にスクロールバー
- overflow:auto 内容に応じて横・下にスクロールバー

```html:html
<div style="height:~~~px; width:~~~px; overflow-y:scroll;">
<!--テーブルタグ-->
</div>
```
yukicoder contest 279 (Zelkova and Cherry) 参戦記

# yukicoder contest 279 (Zelkova and Cherry) 参戦記

事前にググって Zelkova が欅なのは分かってたが、問題タイトルを見るまで欅坂だとは分からなかった(名前が変わったことを知らなかった).

## [E 1362 [Zelkova 8th Tune] Black Sheep](https://yukicoder.me/problems/no/1362)

書くだけ. yukicoder でこんなに簡単な問題出るの珍しい. 辞書かなんかで素直に出現数を集計して、出現数が1の文字を確認して、もう一回スキャンして位置を確認すれば良い.

```python
from collections import Counter

S = input()

c = Counter(S)
a = [k for k in c if c[k] == 1][0]
print(S.index(a) + 1, a)
```

## [C 1360 [Zelkova 4th Tune] 協和音](https://yukicoder.me/problems/no/1360)

N≦18 なので、見るからにビット全探索だなと. 一つも鳴らさないのは答えにならないことに注意.

```python
from itertools import product

N = int(input())
A = list(map(int, input().split()))
B = [list(map(int, input().split())) for _ in range(N)]

W = -(10 ** 18)
for bits in product(range(2), repeat=N):
    if sum(bits) == 0:
        continue
    w = 0
    for i in range(N):
        if bits[i] == 1:
            w += A[i]
    for i in range(N):
        for j in range(i + 1, N):
            if bits[i] & bits[j] == 1:
                w += B[i][j]
    if w > W:
        W = w
        max_bits = bits
print(W)
print(*(i + 1 for i in range(N) if max_bits[i] == 1))
```

## [B 1359 [Zelkova 3rd Tune] 四人セゾン](https://yukicoder.me/problems/no/1359)

直感的に小さい順か大きい順に消化してかないとだめだよなと思いつつ、★の数が多いのでそんなに単純ではないのかとドキドキしながら流したら AC したのであっていたようだ.

```python
N, K, M = map(int, input().split())
P = list(map(int, input().split()))
E = list(map(int, input().split()))
A = list(map(int, input().split()))
H = list(map(int, input().split()))

P.sort()
E.sort()
A.sort()
H.sort()

result = 0
for x in zip(P, E, A, H):
    y = sorted(x)
    result += pow(y[-1] - y[0], K, M)
    result %= M
print(result)
```
Azure Data Factoryで、BOM付きUTF-8のCSVファイルを出力する。

#ハマったことメモ
Azure DataFactoryで出力したCSVファイルをエクセルで開くと、UTF-8なのに、文字化ける。

#解決策
出力先の文字コードを、SHIFT-JISでも、（Default）UTF-8でもなく、UTF-8を選ぶ。
（下図の3番目）
エクセルで直接開けるのは、BOM付きUTF-8。
どうも、リスト先頭の(Default)UTF-8は、BOMなしUTF-8。
リスト3番目のUTF-8がBOM付きらしい。


![スクリーンショット 2021-01-23 0.02.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43829/961ee3c6-472d-5209-c052-bec5078c7912.png)
[Ruby]文字列と整列の変数展開に関して(+英語)

こんばんは、たにーです。

今回は、Twitterでもつぶやいたことがある
Rubyにおけるメソッド（文字列と整数の変数展開）に関してです。

これはややこしいものかなと思うけども、個人的には
英語として分解して理解すればよりすっと理解できるのではと思います。

いつもですが、なにか略をみた際に、
なぜその英語表記なのか(略されているのか)と私は気になってしまいます。笑

#文字列と整数の変数展開

学習した変数展開は、二つあります。
①.to_s
②.to_i

それらの意味（使い方）と英語で分解してみると、下記の通りになります。

| メソッド | 機能 |略|
|:-:|:-:|:-:|
|.to_s   |　整列　→　文字列へ   |to string  (意味：文字) |
|.to_i   | 文字列　→　整列へ  |to integer  (意味：整数) |

**参考例**

.to_s に関して

```ruby:string.rb
age = gets.to_s
puts "私の年齢は、#{age}歳です。"
```

to_iに関して

※こちらに関して例が思いつきませんでした。
　もし何かあればコメントいただけると嬉しいです。
　今後勉強していく中で、あった際にはまだ記事を書こうかと思います。

#個人的には、、
英語として分解してみると、だからそういった表記になるのか！と納得できると思いますし、
変な文字列だったものが、理解できるものへと変わっていくと思います。
そうなれば、きっとプログラミング言語も少しは苦じゃなくなると思います。

以上、たにーでした。
PHPの最低限必要スキルのメモ

###・条件分岐やループ処理ができる（itやfor)

###・共通処理は関数化できる

###・オブジェクト指向プログラミングが簡単にできる
クラスとインスタンス、継承、カプセル、ポリモーフィズムを理解し、使いこなせる

###・データベースに対して、CRUD操作ができる
create, read, update, delete

###・セッションやクッキーを扱い、ステートフルなプログラムを実装できる

###・ログインとログアウト機能を実装できる
【受験記】AWS 認定 機械学習 – 専門知識

# はじめに

この記事は、先日合格した**AWS 認定 機械学習 – 専門知識**の受験記録になります。

準備のためのメイン教材に**英語教材**を使用したという点で、内容的にはレアケースになるかと思います。それでも、この記事がどなたかの参考になれば幸いです。

# 公式情報
- 試験ついてはこちらの[**公式サイト**](https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/)でご確認ください。

# 一般的な準備方法
- [**こちらの記事（AWSの機械学習エンジニア認定試験を受けてきた）**](https://qiita.com/si1242/items/c7b5d2f3916bf6b159de)に上手くまとめられていると思います。＊試験を受けた感想としても、こちらの内容はいまだ概ね有効だと感じました。

- ただ、私は機械学習はもとよりAWS自体実務経験がなく、上記の記事で紹介されているような（公式ドキュメントやブログを読む）学習法は敷居が高く感じられました。

- そもそも、今回の受験目的はこれまで受験したAWS資格試験同様、準備の過程を通じて該当範囲に関する知識（景色）を体系的かつ効率的に習得することでした。しかし、その中でネックになったのが、他資格のような日本語教材がこの資格に関してはまだないということでした。それで、いっそのこと英語教材を使用してみればいいのではないかと思うに至りました。
- 因みに、私は関連する資格としてこれまでに以下のものを取得していました。
  - AWS 認定 クラウドプラクティショナー
  - AWS 認定 ソリューションアーキテクト – アソシエイト
  - JDLA G検定
  - 英検１級

- なお、下記講座を受講して講義や受講生のコメントで思ったことは、英語圏においては以下の様なスタイルが「一般的な準備方法」（このセクションのタイトル）なのではないかということです。 

# 試験準備で使用した教材一覧

## ① **Udemy**: [**AWS Certified Machine Learning Specialty 2020 - Hands On!**](https://www.udemy.com/course/aws-machine-learning/) (英語)
- 広範囲にわたる知識を整理された形で効率よく学ぶことができました。
- 英語は大変聞きとりやすく、テンポよく（程よい集中力が要求される速さで）進んでいきます。＊英語字幕の表示や速度調整もできます。
- 多くはないものの、ハンズオンも含まれています。
- 私は講義の内容を自分なりにノートにまとめることを通じて、知識を再整理し、記憶に定着させました。

## ② **Udemy**: [**AWS Certified Machine Learning Specialty: 3 PRACTICE EXAMS**](https://www.udemy.com/course/aws-certified-machine-learning-specialty-full-practice-exams/) （英語）
- 模擬試験はあえて①とは異なる講師が作成したものを購入しました。
- それによって、より多角的な試験準備ができたと思っています。
- 模擬試験の得点率は１周目が概ね５割、２周目が概ね９割でした。
- 実施後は全ての問題を選択肢まで含めて見直して、分からないところは解説にリンクが貼ってあった様々な記事（これが充実していました）も参考にしながら調べました。
- なお、説明欄に「技術寄りだった25題をユースケース/シナリオベース寄りに改訂した」とありますが、本試験を受けた後の感想としては、この点はまだ弱いと感じました。

## ③ [**公式サンプル問題**](https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/)（日本語）
- ①を行う前に、試験の雰囲気を把握するために一度行いました。
- また、②の１周目が終わった後で2回目を行いました。
  
## ④ [**公式模擬試験**](https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/)（日本語／英語）
- 無料クーポンを利用して②の一周目の後で行いました。
- 得点率は7割程度でした。
- 問題をキャプチャして、全て解き直しをしました。


# 結果

結果は自分の予想をはるかに上回る、890点台での合格でした。
因みに、学習自体は楽しめたのですが、本試験はシステムの影響で終了まで4時間以上を要し、大変な苦痛でした。。
最後まで読んできただきまして、ありがとうございました。
PHPでログイン機能

前回の続きです。
PHPカレンダー:https://qiita.com/x49_n/items/64a04a85b72c6d581421
#ログイン機能作成
前回作成したカレンダーにログイン機能を追加していきます。

ご参考に：https://www.youtube.com/watch?v=uCvPMe5wsNk

#ログイン機能
・新規登録（ユーザー登録）
・ログイン＋ログイン確認画面
・ログアウト＋ログアウト確認画面

#ER図

![ER図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934823/6c07b5de-f207-75ba-c072-db07bf795ec9.png)


簡単ですが、ER図を作成しました。（本当はツールを使って作成したかった、、、）
ER図動画化したものについてはTwitterにて公開しています。
https://twitter.com/x49_n/status/1352600436616830976

次回は予定入力欄を作成します！
[Swift]プロパティについて

##はじめに
[前回の記事](https://qiita.com/akitonanndaze/items/3b314625da1d34b9b220)にプロパティのことを説明しました。
しかし、プロパティの分類の仕方がもう一つあるのでそれについて紹介します。
#プロパティの分類
プロパティは、値を保持する`ストアドプロパティ`と、値を保持しない`コンピューテッドプロパティ`があります。今回はその2つについて説明していきます。
##ストアドプロパティ
以下のtateやyokoのプロパティは、ストアドプロパティです。

```swift
struct Area{
    var tate=10
    var yoko=10
}
var A_1=Area()//インスタンス化
var A_2=Area()//インスタンス化
A_1.tate=3
A_2.tate=7
print(A_1.tate)//3
print(A_2.tate)//7
```
ここで、プロパティの値が変更されるとき、変更前と変更後に値を監視する機能があります。

```swift
struct Area{
    var tate=10{
        willSet{
            print("old numver=",self.tate)
        }
        didSet{
            print("new number=",self.tate)
        }
    }
    var yoko=10
}
var A_1=Area()
A_1.tate=3

//実行結果
//old numver=10
//new number=3
```
willSetの{}では、プロパティの変更前に実行されます。
didSetの{}では、プロパティの変更後に実行されます。
また、このような仕組みを`プロパティオブザーバ`と言います。

##コンピューテッドプロパティ
コンピューテッドプロパティは、プロパティを初期化せずに、なんらかの計算をして値を返すプロパティです。
そして、そのプロパティにアクセスするタイミングで、値を保存することができます。
__ほとんど関数みたいなもんですね__

```swift
struct Area{
    var yoko=10
    var tate:Int{
        get{
            return yoko
        }
        set{
            self.yoko=newValue+2
        }
    }
}
var A_1=Area()
A_1.tate=9
print(A_1.tate)//11
```
プロパティに代入するときはset{}が呼び出されて、A_1.tateみたいに値にアクセスする時(代入する時以外)はget{}が呼び出されます。
A_1.tateでは9を代入しているのでSet{}が呼び出されます。
その時、9にアクセスするにはnewValueを用います。newValue=9です。
それがyokoに代入されるのでyoko=11になります。
最後に,A_1.tateにアクセスしているのでget{return yoko}が実行されます。
yoko=11なので実行結果は11になります。
###また、`set{}は省略可能で、get{}は必須です。`