OmniAICreator/Qiita-1.07M huggingface dataset:
pacemaker下でNGINXがsystemctl stopで切り替わらない現象に遭遇しました

CentOS 7の仮想マシン２台でHAクラスタを構成したのですが、NGINXが思うように切り替わらない現象に遭遇しました。どうやら、切り替わり条件の設定が足りなかったようです。

## 環境

マシンAとマシンBにそれぞれNGINXサーバを立てて、仮想IP（192.168.1.15）で外部にサービスする構成を作ってみました。

* CentOS 7.4(1708)
  * 仮想IP ： 192.168.1.15
  * マシンA(serverA)：　固定192.168.1.13
  * マシンB(serverB)：　固定192.168.1.14
* pcs 0.9.158
* pacemaker 1.1.16
* corosync 2.4.0

### HAクラスタ構築

NGINXは障害で切り替わってほしいというより、人間系（systemctl stop）で切り替わるようにしたかったので、RAはsystemdを使いました。

```bash:#はrootでの設定を表しています
# pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.1.15 cidr_netmask=24 op monitor interval=30s
# pcs resource create webserver systemd:nginx op monitor timeout="5s" interval="5s"
# pcs constraint colocation add webserver virtual_ip INFINITY
# pcs constraint order virtual_ip then webserver
# pcs property set stonith-enabled=false
# pcs property set no-quorum-policy=ignore
# pcs cluster stop --all
# pcs cluster start --all
```

## 問題発生のきっかけ

上記の環境下で以下のように現用系を止めても片側に切り替えてくれませんでした。

```text
[root@serverA ~]# systemctl stop NGINX
```

## 問題解消

LINUX-HA JAPANメーリングリストの中で解決方法を教えていただき、設定に以下を追加しました。

```text:#はrootでの設定を表しています
# pcs resource defaults migration-threshold=1
```

この設定を適用した後は期待通り切り替わるようになりました。

## 参考

* [LINUX-HA JAPAN](http://linux-ha.osdn.jp/wp/)
* [LINUX-HA JAPANメーリングリスト](http://linux-ha.osdn.jp/wp/ml)
* [pacemakerでsystemdリソースを設定](https://qiita.com/k-awa/items/539571dc00a427688e89)
* [Create Nginx High Availability with Pacemaker and Corosync on CentOS 7](https://www.osradar.com/create-nginx-high-availability-with-pacemaker-and-corosync-on-centos-7/)

以上
英英辞書使おうとして読めなくて何度も挫折したので、LINEボットに辞書と翻訳機能とテスト機能を組み込んでみた

# はじめに
「**英語力を高めたいなら英英辞書を使うといい**」と聞いたのですが、
**「単語を調べる」→「その単語の解説文に出てくる単語がわからない」→「解説文をコピペして別ウィンドウでGoogle翻訳に突っ込む」→「調べたことを忘れる」→「単語を調べる」→...**
の無限ループでGoogle翻訳を毎回開くのが面倒になってきました。

なので、
・英英辞書での検索
・（必要な場合は）Google翻訳
・自動で単語帳に追加
・好きな時に単語テスト
がまとめてできるサービスを自作することにしました。
（英和辞書？知らない子ですね...）

# 作ったもの紹介
**「辞書 × 単語帳」WordNote**
[<img width="362" alt="コメント 2020-07-26 141738.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304608/6e17b284-9d42-f006-03b9-8a4573239e56.jpeg">](https://sites.google.com/view/learnwithtrial/Japanese/wordnote)
*)Oxford Dictionariesの[規約](https://developer.oxforddictionaries.com/branding-resources)に従ってPowered by OXFORDのロゴを使用しています。

**サイトは[こちら](https://sites.google.com/view/learnwithtrial/Japanese/wordnote)**

## 辞書モード
![GifMaker_20200725215629430.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304608/0116fa17-62f1-5c19-4faa-609bfa56489c.gif)
・[Oxford Dictionaries API](https://developer.oxforddictionaries.com/)から単語データを取得し、適当に成形して表示しています。
・日本語訳は[Google翻訳APIを無料で作る方法](https://qiita.com/satto_sann/items/be4177360a0bc3691fdf)を参考に自分のアカウントで作成したAPIを使っています。

## テストモード
![GifMaker_20200725200304841.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304608/60152b23-faff-8265-67e2-ec573440619c.gif)
・テスト方法はスペルテスト（スペルを入力）、単語テスト（意味から単語を推測、OX回答）、意味テスト（単語から意味を推測、OX回答）の３種類を用意しています。
・各単語は出題間隔は[SuperMemo2](https://www.supermemo.com/en/archives1990-2015/english/ol/sm2)をベースにしたアルゴリズムで決定しています。


# 技術的なあれこれ
## 言語
・Python
・MySQL
・GAS

## 環境&APIs
・Google Cloud Functions
・Cloud SQL
・LINE Messaging API
・Oxford Dictionaries API

## 運用コスト
Cloud SQLが毎月1000円ちょい（一番安いIowa US-centralを使っています）かかりますが、初年度は$300分のクレジットが使えるため実質無料です。
（最初は何も調べずに東京リージョンでやって7000円ほど吹っ飛びました...）


## 技術習得
・**Python**
[note.nkmk.me](https://note.nkmk.me/)には超絶お世話になっています。
Pythonで困ったらまずここを見るようにしていました。

・**GCP**
[公式ドキュメント](https://cloud.google.com/docs)（日・英）を中心に時々QiitaやStack Overflowを見ていました。
公式ドキュメントの日本語版は情報が遅いとのことで英語版主に見ていたのですが、出てくる単語がわからないことが多く、だからこそこのボット開発のモチベーションを維持できていた気がします。

・**LINE Messaging API**
こちらも公式ドキュメントがかなり充実していたので、それほど困ることはなかったです。

・**Oxford Dictionaries API**
先々月くらいのアップデートで[サンプルコード](https://developer.oxforddictionaries.com/documentation)にPythonが追加されたので、そこを見れば十分扱えると思います。
またこのAPIに関する日本語の情報があまりなかったので、[Oxford Dictionaries APIの使い方](https://qiita.com/Tommyyyyyyy/items/26bf7aae9f464217ad72)を書きました。


# 最後に
コード解説は別記事で書く予定です。
Amazon EFS CSI DriverがGAした件

# AmazonがEFS CSI DriverのGAをアナウンスした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/f8f81aca-268a-3d71-8efa-8a8e5c08a1fb.png)

参考: https://aws.amazon.com/about-aws/whats-new/2020/07/amazon-efs-csi-driver-now-generally-available/

# EFSをPersistent Volumeとして使う場合の、以前までの方法
Kubernetesのincubatorリポジトリ内に、Amazon EFS用のPV Provisionerがある
これを用いることで、EFSをPVとして使用できる。
こちらは、CSIを用いていないため、CSI Driver経由でEFSが使用できることは嬉しい。

[eft-provisioner](https://github.com/kubernetes-incubator/external-storage/tree/master/aws/efs)

# CSI Driver経由でEFSを使うことの嬉しさ
KubernetesにCSI関連の機能が、追加されてきているためその恩恵を得られることと
Kubernetes側でボリューム(EFS, EBS)のバックアップを透過的に行えるのは利点

特に、Kubernetes 1.17でBetaとなった[Volume Snapshot](https://kubernetes.io/docs/concepts/storage/volume-snapshots/)や、Kubernetes 1.18でGAとなった[CSI Volume Cloning](https://kubernetes.io/docs/concepts/storage/volume-pvc-datasource/)が嬉しい。


# GAとなったEFS CSI Driverの詳細と課題
KubernetesのCSI Driverは下記のページにて一覧されており、EFS Provisionerも記載されている。
https://kubernetes-csi.github.io/docs/drivers.html

下記は、CSI Driverごとの機能を示した表だが、赤枠部分に注目したい。
- Dynamic Provisioning(PVの動的確保)がまだサポートされていない(2020/07/26時点)。
- Other FeaturesにCloning, Snapshotの記載がない

上記より現時点(2020/07/26時点)での導入は控えるのが無難と思われる。
特にDynamic Provisioning機能がないのは厳しい。

![Screen Shot 2020-07-26 at 17.23.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/1d859f8a-1cb5-d457-bd48-a7a0d3bc4d03.png)

# EFS CSI DriverのDynamic Provisioning対応状況
EFS CSI DriverのIssue["Implement dynamic provision support"](https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/6)にて、2019/01よりDynamic Provisioningの検討はされてきており、現在も続いている状況。

下記コメント(2020/07/07)にて、 LogMeIn社のリポジトリにてDynamic Provisioningを実装したものが提案されており、EFS CSI Driverに統合したいと申し出ている状況。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/dfe6ad5e-a3b1-bdf2-663d-392c1abd79df.png)

https://github.com/kubernetes-sigs/aws-efs-csi-driver/issues/6#issuecomment-654912928

# まとめ
- KubernetesのCSI対応状況が進む中で、Amazon EFS CSI DriverがGAしたため詳細を確認した。
- Amazon EFS CSI DriverはDynamic ProvisioningやVolume Snapshot, Volume Cloningには対応していてない状況であり、Github上にて対応が進められている状況を確認した
Outlookアドイン開発勉強（サイドロードの仕方）

# はじめに
久々の記事投稿となります。
Outlookアドインを開発してみようと思ったきっかけは、大量のメールをいい具合に分析して申請処理とか自動化できないかと考えたからです。

ざっと調査した感じだと、今のアドインってJavascriptとHTMLで作れるんですね。開発現場から・・・というか流行にも乗り遅れている感じがして、ちょっと焦りました。前置きはさておき、Microsoftのサイトを参考にまずは作ってみました。

# 準備
Microsoft製品で開発するならVisual Studioでしょーと思ったら、もっと簡単に準備できる環境があるんですね。知らない事ばっかり。Visual Studioでもいいのでしょうけど、せっかくなんでNode.js入れました。以下サイトを参考にしました。
　参考：[開発環境をセットアップする](https://docs.microsoft.com/ja-jp/office/dev/add-ins/overview/set-up-your-dev-environment)

# 作ってみよう
以下サイトを参考にしました。
　参考：[最初の Outlook アドインをビルドする](https://docs.microsoft.com/ja-jp/office/dev/add-ins/quickstarts/outlook-quickstart?tabs=yeomangenerator)

作る内容は上記サイトで十分わかるので、ここでは自分で進める上で突っかかった点を記載します。タイトルにもあるサイドロードの仕方です。
「試してみる」で「テスト用にOutlookアドインをサイドロードする」という対応が必要なのですが、サイドロードにあたり以下の対応が必要です。

#### 1. ローカルループバック適用除外を追加
普通にサイドロードすると以下のエラーが発生します。
![error1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107228/54730a69-0c49-d5f8-3734-fcd345117385.png)
なので、管理者権限でコマンドプロンプトを起動して以下コマンドを実行してください。

```powershell:checknetisolation.bat
CheckNetIsolation LoopbackExempt -a -n="microsoft.win32webviewhost_cw5n1h2txyewy"
```
仕様的なことまでは調査していませんが、ローカルで開発するときのおまじない的な事ですかね。

#### 2. 開発用のルート証明書を追加
これでいけるかなーと思ったら、再度エラー。どうやら開発用のルート証明書がインストールされておらず、証明書検証に失敗していたようです。`npm run dev-server`実行すると、C:\Users\<ユーザー名>\.office-addin-dev-certsディレクトリにサーバ証明書ができているようなのですが、ルート証明書が何故かインストールされておらず・・・
なので、ca.crtファイルをルート証明書にインストールします。
![Ca.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107228/4099c178-1ea3-1df3-b5e0-472431c43112.png)

試験的に再度ルート証明書を削除して、再度起動しましたが今度はエラーが出ず！んーイマイチ挙動が解らない。

#### 3. アドインの実行
ともあれ、一応Outlookにアドイン追加できました。ボタンを押すとタイトルが表示されるだけですけどね。
![run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107228/69e5a615-e3b0-c5fb-eb22-d29936c13776.png)

# 終わりに
今回、ソースコードには触れませんでしたが、見てみると非常にシンプルです。HTMLとJavaScript解る方ならスラスラと作れそう。作りつつ、ボチボチ投稿していきたいと思います。
【Windows10版】Virtualbox × Vagrant PHPINFOでエラーメッセージ出て、ファイル同期も出来ない。

##【開発環境】
Windows 10 HOME
VirtualBox 6.0
Vagrant 2.2.9


【仮想環境側】
CentOS Linux release 7.8.2003 (Core)
Apache/2.4.6 (CentOS)
PHP Version 7.3.20
mysql  Ver 14.14 Distrib 5.7.31, for Linux (x86_64)

##【目次】

|  | 　　項目　　　　　|
|:----:|:-------------|
| - | [はじめに](#はじめに) |
| - | [対応](#対応) |
| - | [余談](#余談) |
| - | [参考](#参考) |



#はじめに

vagrantで作成したゲストOSにPHPの情報をphpinfo.phpで表示させようとしましたが
ブラウザでアクセス時に下記のエラーメッセージが出ました。
んでもってホストOSとゲストOSのファイル同期も出来ません。

```
Forbidden
You don't have permission to access /info.php on this server.
```



#いろいろやってみた

[Apacheで403 Forbiddenが表示された時のチェックポイント5選](https://engineers.weddingpark.co.jp/?p=1031)

上記で
SELinuxが有効になっている時、
DocumentRootへのアクセスが拒否されている可能性があるという事で
ゲストOSのSELinuxを無効にしてみた。


```ruby:/etc/selinux/config
SELINUX=enforcing
↓
SELINUX=disabled
```
こんな感じで修正し、再起動しましたが効果無し。

#対応

```ruby:Vagrantfile
config.vm.synced_folder ".", "/vagrant", mount_options:['dmode=777','fmode=777']
```
Vagrantfileのsynced_folderの設定でパーミッションを777に変更するという内容。

ホストOSのVagrantfileファイルに上記を追記すると、、

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/4118394e-ad3d-3a34-ed4e-cebb9d781930.png)

無事PHPINFOが表示されました。

またホストOSとゲストOSのファイルの同期も無事に出来ました。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/42826878-100e-0c33-443d-aac857640f0e.png)

クライアントはWinscp。

#余談

【バージョン確認 コマンド】

OS 

```ruby:comannd
cat /etc/redhat-release
```
Apache

```ruby:comannd
httpd -v
```

PHP

```ruby:comannd
php -v
```
MysQL

```ruby:comannd
mysql --version
```

#参考

またこちらも参考にしました。

[vagrant でディレクトリを共有するとブラウザから192.168.33.10がForbiddenになる](https://qiita.com/htk_jp/items/77190bff53abaa845515)
Unity スクロール領域の端が表示されているかを検出する

# 概要
今回はUnityのScrollRectにおいて、スクロール領域の4辺いずれかが画面に表示されているかを実装しました。

分かりやすくするため以下の例では、端が表示されているかどうかを検出し、対応する辺を黄色くしています。画面の上や左端に達したとき黄色く表示されているのが確認できると思います。
![trim2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323576/bc05e32b-ff6a-d1a1-5ec9-225eaaf124a6.gif)

プロジェクト全体はこちらから
https://github.com/Arihide/scroll-edge-detection

# 説明
今回作成したソースコードは以下の通りです。

```csharp
using UnityEngine;
using UnityEngine.UI;

public class EdgeDetect : MonoBehaviour
{
    [SerializeField] private ScrollRect scroll = null;
    [SerializeField] private Image top = null;
    [SerializeField] private Image bottom = null;
    [SerializeField] private Image left = null;
    [SerializeField] private Image right = null;

    private void Update()
    {
        Bounds contentBound = RectTransformUtility.CalculateRelativeRectTransformBounds(scroll.viewport, scroll.content);
        Rect viewportRect = scroll.viewport.rect;

        top.enabled = viewportRect.max.y >= contentBound.max.y; // 上までスクロールされているか？
        bottom.enabled = viewportRect.min.y <= contentBound.min.y;
        left.enabled = viewportRect.min.x <= contentBound.min.x;
        right.enabled = viewportRect.max.x >= contentBound.max.x;
    }
}

```
一番重要な箇所は
`RectTransformUtility.CalculateRelativeRectTransformBounds`
で、viewportからみたcontentの領域を計算している点ですね。
あとは、viewportとcontentの最大値や最小値を比較してあげれば良いです。

もしかすると、[Scrollbar.value](https://docs.unity3d.com/ja/2018.4/ScriptReference/UI.Scrollbar-value.html)を使えば良いんじゃないかと思われる方もいらっしゃると思います。
ただこの場合だと、スクロール全体の領域が表示領域より小さい場合は4辺すべてが表示されることになりますが、それを検出することができないので、このような方法を用いています。


基本的なロジックは以上の通りなのですが、このままの条件で使用すると、しばしば端にあるのに正しく判定されないことがあります。その場合は以下のように小さい値を加えて条件を緩くすると良いです。

```csharp
using UnityEngine;
using UnityEngine.UI;

public class EdgeDetect : MonoBehaviour
{
    [SerializeField] private ScrollRect scroll = null;
    [SerializeField] private Image top = null;
    [SerializeField] private Image bottom = null;
    [SerializeField] private Image left = null;
    [SerializeField] private Image right = null;

    private const float eps = 0.1f;

    private void Update()
    {
        Bounds contentBound = RectTransformUtility.CalculateRelativeRectTransformBounds(scroll.viewport, scroll.content);
        Rect viewportRect = scroll.viewport.rect;

        top.enabled = viewportRect.max.y >= contentBound.max.y - eps;
        bottom.enabled = viewportRect.min.y <= contentBound.min.y + eps;
        left.enabled = viewportRect.min.x <= contentBound.min.x + eps;
        right.enabled = viewportRect.max.x >= contentBound.max.x - eps;
    }
}
```

スワイプによる画像切り替えなどを実装するときに役に立つと思います。
リリース戦略の整理

## All in Once
言葉の定義をよくわからなかったのでこの表現にしました。(一般的に呼ばれている名前があったら教えて欲しいです)
新旧バージョンのアプリケーションを1度に切り替えるリリース方式です。
新バージョンのアプリケーションと、旧バージョンのアプリケーションの互換性がない場合はこの方法1択になると思います。
リリースにバグが含まれていた場合すべてのユーザーに影響があります。

## canary release
サービスの変更を一部ユーザーから段階的に全体に向けて展開していくリリース方式です。

**どれだけテストやQAを実施したとしても、実稼働のトラフィック上で新バージョンのサービスに問題が見つかることは少なくない。**という前提のもとに、
**運が悪いユーザーがいることを許容することで大規模なサービスダウンを未然に防ぐ。また、ロールバックは早期に行い頻繁に行う。**とういう戦略です。

### メリット

実稼働のトラフィックを使用し、段階的にリリースする事で以下の指標を大幅に削減できます。

* 問題平均検知時間（MTTD）
* 平均修復時間(MTTR)
* 影響を受けるユーザー数

### 段階的にリリースする方法
リリース対象を限定して段階的にリリースしていく方法は大きく2つあります。

1. トラフィックをランダムで振り分ける方法
2. 条件分岐をする方法

#### 1. トラフィックをランダムに振り分ける。
トラフィックをランダムに新バージョンに振り分けていき、システムアラートをモニタリングしながら徐々にトラフィックの振り分けの比率を変更していく方法。
一般的にカナリアリリースと言ったらはこの方法を指す事が多い。

#### 2. 条件分岐をする方法
指定のユーザーIDやfeature toggleなどの条件分岐予め定義しておいて、新旧のバージョンのサービスに振り分ける方法。
一部のユーザーにのみ新サービスを公開する方法をsoft launchという。
マーティン・ファウラー曰くfeature toggleは最後の手段であるべきとの事。

> Release toggles are a useful technique and lots of teams use them. However they should be your last choice when you're dealing with putting features into production.

See: https://martinfowler.com/bliki/FeatureToggle.html

ユーザテストの意味合いが強いと言う解釈。

### ダークカナリアリリースとは？
条件分岐をする方法のカナリアリリースで、開発者のみを新バージョンのサービス利用できる状態にしておく事。主な用途はサービスのデモンストレーションや本番環境でのテストが必要な時に行う。

### 参考
https://cloud.google.com/blog/ja/products/gcp/how-release-canaries-can-save-your-bacon-cre-life-lessons

## Dark launch
稼働中のサービスに来たトラフィックを新バージョンのサービスにも流すことで実際のユーザのトラフィックを使用し、ユーザに影響与えずにテストする方法。
レスポンスは旧バージョンからのレスポンスを使用し、新バージョンのレスポンスは破棄する為ユーザーへの影響はないです。
シャドウプロキシともいう。
Cookpad製の[kage](https://github.com/cookpad/kage)が有名。他にもNginxやFluentdでやる方法など手段はたくさんある模様。

### 参考
https://cloudblog.withgoogle.com/ja/products/gcp/cre-life-lessons-what-is-a-dark-launch-and-what-does-it-do-for-me/amp/

## Cookpadでのサービスリプレイス時の戦略
新サービスでは、リプレイス済みの場合は新サービスでリクエストを処理してレスポンスを返す。まだリプレイスしてない場合はエラーを返す。
新サービスからエラーが返ってきた場合は、旧サービスに再びリクエストを投げて旧サービスでリクエストを処理してレスポンスを返す。
https://techlife.cookpad.com/entry/2019/03/05/115000

同じCookpad製のgemのchankoのrevorkと同じ発想と言う解釈。
Laravelでプロジェクト作成～MVC作成　手順、コマンドまとめ

###環境
言語：php html
フレームワーク：Laravel
サーバ環境：xampp
DB：MySQL(xamppで管理)
OS：Windows 10

※xampp、laravel、composer　環境構築は完了済み。

##Laravelプロジェクト作成

```
laravel new プロジェクト名
```

#####サーバ起動

```
php artisan serve
```
http://localhost:8000/
にて、Laravelページが表示されることを確認。

<br>
<br>
<br>




<font color="Red">ここから先MVC作成</font>

##コントローラ作成

```
php artisan make:controller HogeController
```
#####コントローラー追記
app/Http/Controllers/HogeController.php

```php3
public function contact()
{
	return view("contact"); //viewファイル"contact.blade.php”呼び出し
}
```

##ルーティング作成
routes/web.php

```php3

Route::get("contact", "HogeController@contact");
// http://localhost:8000/contact が呼ばれたとき、HogeController内contactメソッド呼び出し
```


##ビュー作成
resources/views/contact.blade.php(手動で新規作成する)

```html
<!DOCTYPE HTML>
<html>
<head>
	<title>contact</title>
</head>
<body>
	<h1>Hello World!!</h1>
</body>
</html>
```
##マイグレーション
※ユーザテーブルはデフォルトでマイグレーションファイルが作成されている。
#####マイグレーションファイルの作成

```
php artisan make:migration create_books_table
```
名前は複数形で作成するのが慣例

#####マイグレーションファイル書き込み
/database/migrationsフォルダにmigrationファイルが作成される。
この中に、変数を追記する。

```php3
Schema::create('books', function (Blueprint $table) {
     $table->id();
     $table->string("title"); //追記
     $table->text("body"); //追記
     //etc...
     $table->timestamps();
});
```

#####マイグレーション実行

```
php artisan migrate
```

#####マイグレーションが成功しているかの確認

```
php artisan migrate:status
```

##モデル作成
```
php artisan make:model Book
```
名前は単数形で書くのが慣例(migrateは複数形)
app/ 直下に Book.phpが作成される。
Unity　TIPS　カードを生成する方法

unityでよく使う　

オブジェクトを生成するやり方を見ていきます。　

unityのvrは、　２０１９．４ LTSを使用しています。



では今回はカードを生成していきます。　

まず　用意するものは　カードのオブジェクト　

今回はトランプのクラブを使っています。　

ちなみに　トランプのカードはアセットストアで無料であります。



そしてヒエラルキーで　　ＵＩから　キャンバス、パネルを入れて

カードのオブジェクト【プレハブにしておく】を入れて　

親子関係にしておいてください。　

キャンバスの下にパネルを入れて　

パネルの下にオブジェクトを入れていきます。　

次にスクリプトを作って、　以下のコードを記入します。　



```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardIn : MonoBehaviour
{
public GameObject Club;


public GameObject Panel;
void Start()
{
for(int i =0; i<5; i++)
{
GameObject cardObj = Instantiate(Club);
cardObj.transform.SetParent(Panel.transform);
}

}

// Update is called once per frame
void Update()
{

}
}
```




クラス名は　CardInという名前にしています。
updateは使わないので消しても大丈夫です。

今回は　Clubのカードを生成したいので　Clubという名前です。

for文では　5回としていますが、　ここは好きな数字でＯＫです。　

これによって、パネルの上にカードを5枚

生成することができます。　

次にこのスクリプトを　カードオブジェクトにアタッチして　

インスペクターで

Ｃｌｕｂの所に　カードのオブジェクトをドラッグ　

パネルの所に　パネルをドラッグして入れてください。　

![bandicam 2020-07-26 16-52-50-535.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/74146a75-e8c7-ebe7-10a3-ec76ca60087e.jpeg)




これらを入れたら　ゲームを再生してみましょう。　

そしたら　こんな感じにカードが生成されていると思います。　

ヒエラルキーを確認して　クローンが５枚　できていればＯＫです。

![bandicam 2020-07-26 16-40-08-380.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295760/530d034b-bfcb-d5c9-6d7a-bf669a504aa6.jpeg)







ＰＳ　

今度新しいunity２Ｄ講座をリリースする予定です。　

今度出す講座では、　boltの使い方も入れていくので　

まだ当分はかかるけどね。

講座作っている最中に　ｖｒ変わったり、新しい機能とか出てくると　
ほんと困るのよね。　とりあえず、boltは無料で使えるようになりましたから　
これは入れていきまっせ。
ウェブサイトに「視点の追跡機能」を実装

Gigazainの記事。これぜひ試してみたい。

https://gigazine.net/news/20200724-webgazer-js/?fbclid=IwAR2G2sJd835-bQlk53koyrLNKQR-ZRmcqOeq5BiCbge1k0-XyvsY6SP2pTQ

WebGazer.js: Democratizing Webcam Eye Tracking on the Browser
https://webgazer.cs.brown.edu/#

WebGazer.js: Scalable Webcam EyeTracking Using User Interactions - YouTube
初めてのJulia

# はじめに
この記事はJuliaに入門して数日の素人が書いたものなのであまり鵜呑みにしないでください. 環境構築は[この記事](https://qiita.com/catfishjl47/items/3074345d54e2bcd5ace0)に色々まとまっているので参考にさせていただきました.
# Juliaの導入
Mac環境で話を進めます.
[公式サイト](https://julialang.org/)からdmgファイルをダウンロードして[ここ](https://julialang.org/downloads/platform/#macos)に書いてあるようにやれば終わりです. 簡単！ ちなみにjupyterでも使えます. 詳しくは上の参考記事をみてください. 以下はjupyter上で実行しています.

# Juliaで半円則を実証
ものは試しということでJuliaでウィグナーの半円則を実証してみようと思います.
半円則については[こちら](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A3%E3%82%B0%E3%83%8A%E3%83%BC%E5%8D%8A%E5%86%86%E5%88%86%E5%B8%83)
ようは対称ランダム行列の固有値分布が半円型になるというものです.
まずはランダム行列を作りましょう. 今回は行列のサイズを$size=10000$としました.
Juliaでは各要素が標準正規分布に従う行列はrandn関数を用いて作ることができます.

```julia
using Plots
using LinearAlgebra
size = 10000
mat=randn(Float32, size, size)
```
これだと対称行列になっていないので, 普通にfor文を用いて対称行列にしました.

```julia
for i in 1:size
    for j in i+1:size
        mat[i, j]=mat[j, i]
    end
end
```
あとは固有値を求めるだけです. LinearAlgebraのなかにeigvals関数があるので,

```julia
@time eigenvalues = eigvals(mat)
```
とします. @.timeは実行時間を測ってくれるマクロです. 僕の環境では約40sでした.
最後に固有値のヒストグラムを書きましょう. これはPlotsの中のhistogram関数でできます.

```julia
histogram(eigenvalues, bins = range(-200, 200, step=4), label="eigenvalues")
```

![Wigner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339162/9f66eabc-a438-7fd0-2951-16ca1d691421.png)
綺麗な半円が見えました！
# 終わりに
JuliaはPythonライクに書けて非常に使いやすくていいと思います. Pythonとの差別化ポイントは実行速度だと思うのですが, 今回はほぼライブラリを使っただけなのであまり速度差はなさそうです...と思ったのですが, np.linalg.eigvalsでやってみたところ死ぬほど時間がかかりました...ということでjuliaすごい！ あと最初に実行するときはかなり時間がかかったりしますが大体二回目以降は高速になるので大丈夫です.
【現行版未対応】Mildomのチャット取得

2022年2月頭に仕様変更がありました。
メッセージの暗号化、復号化のロジックをここにベタで書くとオイコラされそうなのでやめておきます

以下は過去の仕様に則ったもの
---

コメントビューア用。
OAuthが要るようなAPIは使わず、未登録で取得できるコメントを取得。
あくまで執筆時点の情報です。仕様が変わる可能性もあるのであしからず。

## ユーザのチャンネルURL

- `https://www.mildom.com/{ユーザID}`
  - 例: `https://www.mildom.com/10946091`

## 手順

1. 以下にWebSocket接続
  - `wss://jp-room1.mildom.com/?roomId={ユーザID}`

2. メッセージ送受信

```typescript:send
{
    /** ユーザID。 */
    "userId": 0,
    /** ユーザレベル。 */
    "level": 1,
    /** ユニークなID。guest766863みたいな。 */
    "userName": string,
    /** ユニークなID */
    "guestId": string,
    /** リファラ */
    "nonopara": string,
    /** ユーザID */
    "roomId": number,
    /** コマンド。ここでは固定 */
    "cmd": "enterRoom",
    "reConnect": 0,
    "nobleLevel": 0,
    "avatarDecortaion": 0,
    "enterroomEffect": 0,
    "nobleClose": 0,
    "nobleSeatClose": 0,
    "reqId": 1
}
```

以降はメッセージが送られてくる。cmdがメッセージ種別。

| cmd | 内容 |
| ---   |  ---   |
| enterRoom | 最初に受信する。チャットに入ったことを表す。 |
| onBroadcast | 規約文のメッセージが入ってる。  |
| onAdd  | 不明。<br/>他のユーザが入ってきた時のような気もする。
| onChat | コメント |


- enterRoom

```json:receive
{"admin": 0, "cmd": "enterRoom", "fobiddenGlobal": 0, "forbidden": 0, "reqId": 1, "rst": 0, "type": 2, "userCount": 590}
```

- onChat

```typescript:receive
{
  /** メッセージの種別 */
  "cmd": "onChat"
  /** メッセージ */
  "msg": string,
  /** メッセージID */
  "msgId": string,
  /** ユーザID */
  "userId": number,
  /** アイコン画像のURL */
  "userImg": string,
  /** ユーザ表示名 */
  "userName": string,
  // 省略
}
```
【iOSアプリ開発】Macのloalhostに実機(iOS)から接続する方法

iOSアプリ開発をしていて、サーバサイドとの連携機能を作成するにあたって、
Macのlocalhostに実機(iOS)から接続する方法を調べました。

# はじめに
Mac上に立てたlocalhostに対して実機(iOS)のアプリから接続する方法と、
iOSシュミレータから接続する方法になります。

# 対象バージョン
- Xcode ver.11.6
- Simulater ver.13.6
- iOS ver 13.5.1

# http接続できるように設定
1. はじめにhttp接続できるようにInfo.plistに設定を追加します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99869/7d9ba61c-2fc1-9843-32c6-e0ef372392a7.png)
2. App Transport Security SettingのAllow Arbitrary LoadsをYESにします。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99869/44e85ca8-4daf-8228-2544-6d67576a97bb.png)  
(もしApp Transport Security Settingが表示されていなければ追加すれば大丈夫です。)

# iOSシュミレータから接続する方法
iOSシュミレータから接続するだけならHTTPリクエストするURLはhttp://localhost (ポート)で大丈夫です。

# iOS実機から接続する方法
iOS実機から接続するにはiOSシュミレータと同じhttp://localhost (ポート)では接続できません。
localhostの部分をMacのIPアドレスにする必要があります。
MacのIPアドレスの確認方法は以下になります。(すみません、言語設定が英語になっています。)
1. Macの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99869/2c99b7e7-8d9e-6f4b-cae5-4c329f41e0b8.png)
2. ネットワーク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99869/74069afc-7d03-137f-adef-a74e2472e325.png)
3. 接続されているネットワークのIPアドレス(赤い部分がMacのIPアドレスになります。) 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99869/348e4874-677b-067e-2634-024455e716ea.png)

# まとめ
意外に簡単に接続することができました。
これでサーバサイドのプログラムをサーバにアップしなくても連携を確認することができます。
＜Slack＞Slackに通知する関数を書いて、いつでも引用できるようにする(GAS)


slackでいつでも通知できる関数を作ってしまえば楽なのでは？と思い作成しました。

slack.gs

```
function notifySlack(payload) {
  var payload = {
    text: message,
    icon_emoji: ":XXXX:",
    username: "byGAS",
  }
  var options = {
    method: "post",
    contentType: "applidation/json;",
    payload: JSON.stringify(payload),
  }

  UrlFetchApp.fetch("YOUR_WEBHOOK_URL", options);
}
```

このgsを作っておいて、
次に「Slackに通知したい」となった時に呼び出せるようにしておきます。
呼び出し方は以下。


main.gs

```
function main() {
  // 今回の処理
  notifySlack("ここに今回のメッセージをかく")
}
```
Postgresだとcreate tableと同時にindex作成ができなそう

## はじめに
MySQLならテーブル作成時にインデックスの作成も

```
create table staff(id int, name varchar(10), index id_index (id));
```
とかでできるが、postgresは？
と調べた時にできなそうということがわかったので書いておく

## 結論
できなそうだったので素直に

```
create table public.staff (id int, name varchar(10));
create index on staff(name);
```
というように2文に分けてやることにしている。

## 結論に至るまでにやったこと
### 軽くググる
調べてみると、少し古いが下記のstack overflowの記事でも、公式ドキュメントを引用しながら、create tableでインデックスで指定する方法はなさそうとの記載があった。
https://stackoverflow.com/questions/6239657/postgresql-can-you-create-an-index-in-the-create-table-definition/6239678
> There doesn't seem to be any way of specifying an index in the CREATE TABLE syntax.

この記事が引用している公式ドキュメントも参照してみると、プライマリーキーのindexは自動で生成されるとのことが記載されていた。
> PostgreSQL automatically creates an index for each unique constraint and primary key constraint to enforce uniqueness. Thus, it is not necessary to create an index explicitly for primary key columns.



#### ドキュメントをみる

11系を使っていたので、11系のドキュメントも確認してみたのですが、そこにも上で紹介した記事と同じことが書かれていた。
https://www.postgresql.org/docs/11/sql-createtable.html
#### DB Client Toolなどでも試してみる
ドキュメントの量が膨大だと「見落としている」という可能性もなくはないと思い、
既にindexが作成されているtableのDDLをSQLクライアントツール（今回使ったのはDBeaver）が生成するDDLを確認してみたりもした。

![スクリーンショット 2020-07-26 16.56.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140790/632c57f3-f1e1-dd65-d177-419e4af27c46.png)
上図では、email columnにindex貼ったテーブルのDDLを確認しているのだが、やはりcreate tableとは別でcreate indexされていることがわかる。

SQLクライアントツールのDDLも2文になってるので、できないという結論で問題なさそう。
勉強メモ

CCNP ENARSI(300-410)勉強したメモをココにまとめます。


#はじめに
Qiitaを資格勉強のアウトプットとして。
学んだことをちょこちょことアウトプットしていきます。

# CCNP ENARSI(300-410)

#参考図書
[CCNP Enterprise Advanced Routing ENARSI 300-410 Official Cert Guide 
By Raymond Lacoste, Brad Edgeworth](https://www.ciscopress.com/store/ccnp-enterprise-advanced-routing-enarsi-300-410-official-9781587145254)
Qiitaの書き方　超初心者用

##はじめに
Qiita Markdownの書き方を自分用にまとめています。

##見出しの書き方
文頭に#を付けると見出しになる。
\#の数で見出しの大きさを変えられる。
>\#\#見出し1
\#\#\#見出し2

で
>##見出し1
###見出し2

##コードの書き方
\`\`\`でコードをくくる。
>\`\`\`C++:title
printf("Hello World\n);
\`\`\`
と書くと

>```C++:title
printf("Hello World\n");
```

##引用の書き方
\>を書く。改行すると元に戻る。

>\>あいうえお
\>\>かきくけこ

で

>あいうえお
>>かきくけこ

##表の書き方
>\|左揃え|中央揃え|右揃え|
|:---|:---:|---:|
|a|b|c|
|d|e|f|

で

>|左揃え|中央揃え|右揃え|
|:---|:---:|---:|
|a|b|c|
|d|e|f|

##イタリック、太字の書き方
* イタリック

>\_italic\_
\*italic\*

で
>_italic_
*italic*

* 太字

>\_\_太字\_\_
\*\*太字\*\*

で

>__太字__
**太字**

##リストの書き方
リストの上下は改行する。また、記号の後に半角スペースを入れる。

* 番号なし

>\* リスト1
\+ リスト2
\- リスト3

で

>* リスト1

>+ リスト2

>- リスト3

* 番号付き

>1\. リスト1
2\. リスト2
3\. リスト3

で

>1. リスト1
2. リスト2
3. リスト3

##エスケープ
\\を前につける。
>\\#見出し
で
\#見出し
となる。
Golangのテストはテーブルドリブンテストで！

# はじめに
Golangでテストを書こうとしたときに推奨されてる実装方法として**テーブルドリブンテスト**（TableDrivenTests）というものがあります。
このテスト方法はGoの公式のwiki( https://github.com/golang/go/wiki/TableDrivenTests )でも紹介されてるテスト方法です。

# テーブルテストとは？
とりあえずにテーブルテスト書いてみます

```go:square.go
package main

// Square ２つのintを受け取りそれらを掛け合わせた物を返す関数
func Square(a, b int) int {
	return a * b
}
```

```go:square_test.go
package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSquere(t *testing.T) {
	asserts := assert.New(t)
	for _, td := range []struct {
		title  string
		input  []int
		output int
	}{
		{
			title:  "2×3の答えが6になる",
			input:  []int{2, 3},
			output: 6,
		},
		{
			title:  "3×5の答えが15になる",
			input:  []int{3, 5},
			output: 15,
		},
	} {
		t.Run("Square:"+td.title, func(t *testing.T) {
			result := Square(td.input[0], td.input[1])
			asserts.Equal(td.output, result)
		})
	}
}
```

よくみるテストと違い、

- name
- input
- output

というstructを持った配列をfor文ででまわし様々なテストパターンを確認するというテスト方法です。
このテストの最も大きな利点は***複雑な条件のあるテストをテストしやすい***という点です。
それは、インプットの値とインプットの値の可読性が高いためどのようなテストパターンを行っていて、どのようなテストパターンをやっていないかを理解しやすいためです。

またこのテーブルドリブンテストで重要なのは`input`と`output`をわかりやすく記述ことが最も重要ですので、その点はしっかりと注意して実装を行った方がいいと思います。

# テストを並行処理する
テストをどんどん書いていくとテスト処理を並行化したいという思いが出てくると思います。
その時はGoのtestingパッケージでは`t.Parallel()`という関数を噛ませてあげることでテストを並行化することができますが、このテーブルテストでやるとバグがおこってしまうそうです。
そのため並行処理を行う時は以下のように書く必要があるそうです
（ https://github.com/golang/go/wiki/TableDrivenTests#parallel-testing ）

```go:square_test.go
package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestSquere(t *testing.T) {
	t.Parallel() //←追記
	asserts := assert.New(t)
	tests := []struct {
		title  string
		input  []int
		output int
	}{
		{
			title:  "2×3の答えが6になる",
			input:  []int{2, 3},
			output: 6,
		},
	}

	for _, td := range tests {
		td := td //←追記
		t.Run("Square:"+td.title, func(t *testing.T) {
			result := Square(td.input[0], td.input[1])
			asserts.Equal(td.output, result)
		})
	}
}
```


# まとめ
テストの方法には様々な方法がありますが、それぞれのメリットデメリットをしっかり理解してテストコードを書いていきたいですね。
Business Intelligence（BI）における汎用的な機能分類について

## 概要
Business Intelligence（BI）の製品選定を行う際に、BIに求められる機能を分類してみました。
この機能分類を分解していき、製品間で比較することを想定しております。

BIは単なる可視化機能だけでなく、データ解析（AI統合による拡張アナリティクス）やデータプリパレーション機能も、より求められるようになってきました。そういった状況も考慮した機能分類となっております。

## 機能分類について

| 機能分類                       | 概要                                                         |
| ------------------------------ | ------------------------------------------------------------ |
| データストアへの接続           | 外部データストアサービスへ接続し、データの入出力を行う機能   |
| データプリパレーション         | データを抽出・変換・書き込み等を行い、データモデリングの事前準備、あるいは、対データストアへのデータ連携の処理を行う機能 |
| データモデリング               | データ可視化、AI統合による拡張アナリティクス 、シミュレーションを行うために、データを構造化する機能 |
| データ可視化                   | データをビジュアルとして表現する機能                         |
| 共有とコラボレーション         | データ可視化、AI統合による拡張アナリティクス 、シミュレーションを共有し、コミュニケーションを図る機能 |
| AI統合による拡張アナリティクス | AIによる自動的なインサイト、機械学習との統合に関する機能     |
| シミュレーション               | 仮想的な手法により様様なシチュエーションを想定し、想定結果・リスク・最適解等を算出する機能 |
| ガバナンス                     | BI機能要件の機能を統合管理する機能                           |
| 運用保守性                     | 運用環境でシステムを継続的に動作させる運用プロセス           |
| セキュリティ                   | 脅威からアプリケーションとデータを保護する能力               |
| 拡張性                         | 増加した負荷を処理するシステムの能力                         |
| 回復性                         | 障害から回復して動作を続行するシステムの能力                 |
| 可用性                         | システムが動作し実際に使用可能である時間の割合               |
| コスト計算                     | システムを利用するための費用                                 |
| ベンダー評価                   | システムを継続的に利用するためのベンダーの評価               |


## 機能分類の分類について

| 第一分類   | 第二分類                   | 機能分類                       |
| ---------- | -------------------------- | ------------------------------ |
| 機能要件   |                            | データストアへの接続           |
| 機能要件   |                            | データプリパレーション         |
| 機能要件   |                            | データモデリング               |
| 機能要件   |                            | データ可視化                   |
| 機能要件   |                            | 共有とコラボレーション         |
| 機能要件   |                            | AI統合による拡張アナリティクス |
| 機能要件   |                            | シミュレーション               |
| 機能要件   |                            | ガバナンス                     |
| 非機能要件 | サービスにおける非機能要件 | 運用保守性                     |
| 非機能要件 | サービスにおける非機能要件 | セキュリティ                   |
| 非機能要件 | サービスにおける非機能要件 | 拡張性                         |
| 非機能要件 | サービスにおける非機能要件 | 回復性                         |
| 非機能要件 | サービスにおける非機能要件 | 可用性                         |
| 非機能要件 | その他                     | コスト計算                     |
| 非機能要件 | その他                     | ベンダー評価                   |


## 次のステップについて
データモデリングを例にすると、下記のように機能として分解することを想定しております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a8e0c0ca-4f9d-7c7f-b120-4ce067965282.png)

セキュリティについては、下記の記事で整理しております。

- [データストア（データ分析基盤）におけるデータへの権限付与（認可、アクセス制御）に関する指針の検討](https://qiita.com/manabian/items/ad7c5927817e7d76be0b)
javascript-ゲームを作ってオブジェクトを学ぶ-

#この記事について
現役プログラマーさんから教えていただいたことをまとめている記事です。今回はJavaScriptの基礎を使ったゲームづくりを通して、教えていただいたことをまとめていきます。

#関数
まずfunctionを使った足し算をする簡単な関数をみていきます。
sumNumberは関数名で、自由に名前をつけることができます。
a,bは引数で、後にから代入する具体的な数字を入れるための箱のようなものです。

```.js
//aとbを足して、コンソールに表示する関数を定義
function sumNumber(a,b){
	console.log(a+b);
}
//関数名とa,bに入る数字を記入すると、上の関数に代入されます。
sumNamber(3,4);

//結果：７
```
#allow関数
上の関数をallow関数で書いてみます。

```.js
const sumNumber = (a,b) =>{
  console.log(a+b);
}
sumNumber(3,4);
```
先ほどのfunctionを使った関数を下のように書き換えています。
`const 関数名 = (引数) => {　関数の中身　} `

functionを使った関数に問題が見つかり、allow関数で回避することができるので、こちらを主に使っていくのがベターみたいです。

#オブジェクト
オブジェクトを使うと、今までsumNumber(3,4)のように、数字や文字などを単体だった情報をまとめて管理できるようになります。

```.js
const user1 = {
  name:"ポチ",
  age:7,
  weight: 15
}
```
このオブジェクトだとオブジェクト名はuser1です。nameやageなどの要素はプロパティと呼びます。プロパティは「 , （カンマ）」でつなぎます。最後のプロパティの後ろは何もつけないので注意！
オブジェクトは、オブジェクト名.プロパティ名　で呼び出すことができます。

```.js
console.log(user1.name);
console.log(user1.age);
```
結果：ポチ
　　　7

**◎関数の引数としてオブジェクトを渡すことができます！**
name,age,weightを表示させる関数を作り,その引数に先ほどのオブジェクトuser1を代入してみます。

```.js
const loginUser = (u) =>{
 console.log(u.name);
 console.log(u.age);
 console.log(u.weight);
}
loginUser(user1);
```
結果：ポチ
　　　７
　　　15

関数の引数“u”が“user1”が置き換わるイメージです。初めの引数の“u”は、ただの数字を代入する箱のようなイメージで意味を持たないと考えようにすると、分かりやすくなると思います。


#ゲームを作って覚えよう
私は、鬼滅の刃が好きなので、それぞれの剣士の階級を求めるプログラムを作りたいと思います。剣士の腕前を、腕力、速さ、技術に分けて、点数化し、その合計値を元に階級を表示していきます。

###1.炭次郎のオブジェクトを定義

剣士のプロパティーは
・name（文字列）
・power（数字）
・speed（数字）
・technique（数字）
 名前以外は、それぞれ1~100の数字。

炭次郎のオブジェクト名は、kenshi1とします。

```.js
const kenshi1 = {
  name:"竈門炭治郎",
  power: 50,
  speed: 60,
  technique: 70
}
```
###2.剣士の階級を求める関数を作成する
剣士の階級はpowerとspeedとtechniqueの合計値で求めます。
合計値が250以上なら甲（キノエ）
合計値が150以上250未満なら丙（ヒノエ）
合計値が150未満なら丁（ヒノト）とします。

```.js
//まず腕力、速さ、技術の合計値を求める関数を定義します。この時の、“kenshi”は引数で後で定義する具体的な数値を入れるためのただの箱のようなものです。
const calcSum = (kenshi) => {
  return kenshi.power + kenshi.speed + kenshi.technique;
}

//次に剣士のランクを求める関数を定義します。
const getRank = (kenshi) => {
  const sum = calcSum(kenshi);
  //rankは変化していくので、変数で定義します。文字列になるので、""をつけています。"階級"などの文字を入れてもOK   
  let rank = "";     
  if(sum>=250){
    rank = "甲（キノエ）";
  }else if(sum>=150){
    rank = "丙（ヒノエ）";
  }else{
    rank = "丁（ヒノト）";
  }
　return rank;
}
```
###3.それぞれのランクをconsoleに出力する

```.js
//炭次郎は定義したので、他2人のオブジェクトを定義します
const kenshi2 = {
	name:"煉獄杏寿郎",
	power: 98,
	speed: 96,
	technique:80
}
const kenshi3 = {
	name:"不死川玄弥",
	power: 20,
	speed: 40,
	technique:70
}
//3人の名前とランクをコンソールに表示します
console.log(kenshi1.name);
console.log(getRank(kenshi1));
console.log(kenshi2.name);
console.log(getRank(kenshi2));
console.log(kenshi3.name);
console.log(getRank(kenshi3));
```

結果
<img width="320" alt="スクリーンショット 2020-07-26 15.29.08.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663834/6f142bb5-3bd4-0b1e-d90a-a18aa3cebe85.jpeg">
【ポートフォリオ を作成される方へ】ransackで作る検索機能



##ransackとは
検索機能を少ないコードで簡単に実装できるgemです。
設定も簡単でできることもたくさんあります。
##導入方法

```ruby:Gemfile
gem 'ransack'
```
```
$ bundle install
```

##使い方
①検索パラメーターは ":q"
②Ransack版form_forは"search_form_for"
③検索結果は"resultメソッド"で取得できる

```controller.rb
class ProductsController < ApplicationController
  def index
    @q = Product.ransack(params[:q])
    @products = @q.result(distinct: true)
  end
end
```
```view.html.erb
<%= search_form_for @q do |f| %>
  # nameカラムに対して部分一致検索ができる
  <%= f.label :name_cont, "商品名を含む" %>
  <%= f.search_field :name_cont %>

  <div class="actions"><%= f.submit "検索" %></div>
<% end %>
```

f.search_field :name_contのnameのところを変えるだけで違う検索を変更することができます。

| 検索方法 | 意味 |
|:-----------:|:------------:|
| *_eq       | 等しい        |
| *_cont     | 部分一致      |
| *_lteq       | 以下        |
| *_gteq        | 以上          |
| *_start       | で始まる       | 
| *_end    | で終わる     |
【Mac】Macで使うショートカットキーのまとめ

# Macでやったことのまとめ

今まで使ったことのあるショートカットのまとめ
頻出するショートカットを教えるときにこの記事使うのが目的
※ 適宜更新する予定

細かいところは公式ホームページに書いてあるのでそっちを参照。

[Mac のキーボードショートカット - Apple サポート](https://support.apple.com/ja-jp/HT201236)


キー表示については以下抜粋

> command (または cmd) ⌘
> shift ⇧
> option (または alt) ⌥
> control (または ctrl) ⌃
> caps lock ⇪
> fn



## 基本的な操作
基本はcommand[⌘]キープラスキーボードの文字を入力する。
⌘は機種依存記号なのでCommandキーは以下[cmd]と表記

Windowの場合はControlキーがcommandキーに相当する。

大体左手で押せる範囲にある。

### Mac共通のショートカット

💾 ファイルを保存する。

[cmd] + s :現在のファイルを保存する。

### 📝 テキストの選択

[cmd] + a :全範囲を選択

[cmd] + c :コピー

[cmd] + v :ペースト

[cmd] + ｘ :カット(切り取り)

### 🖌 文字入力時の変換系

fn + F7 :カタカナに変換する。

fn + F10 :小文字英字に変換する。

### 🖥 画面キャプチャ系

[cmd] + [Shift] + 4 : 画面を選択してキャプチャする。
Dovecotが「Fatal: mkdir(/usr/local/var/run/dovecot) failed: Read-only file system」と言われて起動できない

## 状況

CentOS8でDovecot(2.3.10.1)をソースからコンパイルしてインストールして、起動しようとすると、「Fatal: mkdir(/usr/local/var/run/dovecot) failed: Read-only file system」と言われて起動できませんでした。

Permissionの問題かと思い、デレクトリをあらかじめ作ったり、ディレクトリのPermissionを777などにするなどいろいろ試しても、最終的に「master: Fatal: chmod() failed for /usr/local/var/run/dovecot/login: Read-only file system」が出て、にっちもさっちもいかなくなりました。

## 解決方法

/usr/lib/systemd/system/dovecot.service を修正します。

```ini:/usr/lib/systemd/system/dovecot.service
[Service]
...略...
ProtectSystem=false   <== full を false に変えます
...略...
```

systemdの設定をリロードします。

```sh
systemctl daemon-reload
```

## ソースに対するパッチ

再コンパイルしてインストールしたら上書きされてしまうので、ソースへのパッチも置いときますね。

```patch
diff -uNr dovecot-2.3.10.1.org/dovecot.service.in dovecot-2.3.10.1/dovecot.service.in
--- dovecot-2.3.10.1.org/dovecot.service.in     2020-05-13 00:44:05.000000000 +0900
+++ dovecot-2.3.10.1/dovecot.service.in 2020-07-26 23:22:05.897623807 +0900
@@ -21,7 +21,7 @@
 ExecStop=@bindir@/doveadm stop
 PrivateTmp=true
 NonBlocking=yes
-ProtectSystem=full
+ProtectSystem=false
 ProtectHome=no
 PrivateDevices=true
```

## おまけ

systemdの設定ファイルをインストールするには、configureするときに

```sh
./configure --with-systemdsystemunitdir=auto
```

のオプションを付けます。

## 参考

https://forum.iredmail.org/topic13321-iredmail-support-dovecot-error-open-failed-readonly-file-system.html
GitOps始めるぞ！の前に用語や周辺技術を整理してみた

## はじめに

GitOpsなるものがちまたで流行しているので、GKEで個人で運用しているサービスにも試しに取り入れてみようかと思っている今日このごろ

そもそもGitOpsが何者なのかもわかってないので、用語や周辺技術をまずはまとめてみる

## 用語の前提知識

#### CI

継続的インテグレーションのことで、コンパイル・テスト・デプロイといったソフトウェア開発のサイクル（ビルド）を頻繁に繰り返し実行させる

#### CD

継続的デリバリーのことで、ビルドやテストだけでなく、リリースプロセス全体を自動化

#### 宣言的

一連の指示ではなく一連のファクトによって構成している
[この記事](https://qiita.com/Hiroyuki_OSAKI/items/f3f88ae535550e95389d)がとてもわかりやすかった！


## ここからが本題、GitOpsって何？

Weaveworks社が提唱する、CI/CDパイプラインの概念！
https://www.weave.works/blog/gitops-operations-by-pull-request

google翻訳を駆使しながら読んで、簡単にまとめると
コマンドラインツールを使わずに、gitの操作ですべての開発作業（もちろんデプロイも）を完結させる運用、そしてKubernetesの宣言的な構成と相性が良いと理解した

時間あるときにもう少しちゃんと読んでみようと思う

## GitOpsのメリットは？

じゃあ、そのメリットでどこにあるのって話で、考えられるだけ洗い出してみた

- git上の履歴を見るだけで環境に対して何が行われたかを追える
- 実際に動いている環境とgitで宣言しているコードの違いを検知できる
- コマンドラインによる人的な操作をなくすことで、オペミスをなくす
- 人的な操作を削減は人的コストの削減につながる
- CI/CDの分離
- コードとコンフィグを分けることでセキュリティもよくなる


Docker、Kubernetesによる、Infrastructure as Codeが実現できている環境であるからこそ、GitOpsの強みを発揮できそうな印象（というよりInfrastructure as Codeであることが前提か）

また、個人の運用しているサービスに当てはめると、デプロイはkubectl applyコマンドを使っていて、本番との差分もkubectl diffに確認するという、人的オペレーションだらけとなっているので、これが自動化できるだけでも保守性がとても上がる！


## どうやって実現するか？

CI、CD、manifestの管理ツールについて簡単にまとめた

### CIツール

- [jenkins.io](https://www.jenkins.io/)
- [circleci.com](circleci.com)
- [travis-ci](https://travis-ci.org/)

...etc

### CDツール

- [Spinnaker](https://spinnaker.io/)
- [Argo CD](https://argoproj.github.io/argo-cd/)
- [Weave Flux](https://github.com/fluxcd/flux-get-started)

...etc

### manifest管理ツール

- [Helm](https://helm.sh/)
- [Kustomize](https://github.com/kubernetes-sigs/kustomize)

...etc

## まとめ

今回はGitOpsを導入する前に用語や周辺技術に関して簡単にまとめてみた
今度は実際に導入してみる


### 参考

https://style.biglobe.co.jp/entry/2020/06/12/100000
https://knowledge.sakura.ad.jp/21870/
https://kabukawa.hatenablog.jp/entry/2018/12/21/130304
【Github Actions】CIのstepでmysqlにSQLを実行する

自分用メモ：
github actionsのstepにmysqlを使ったテストを組み込みたかった。
そのテストは初期データが必要なため、stepの途中で予め用意したsqlを実行させる


## github actions yml

`.github/workflows/hoge.yml`

```yml
  test:
    name: Test
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:5.7
        ports:
          - 3306:3306
        env:
          MYSQL_ROOT_PASSWORD: hoge_password
        options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10
    steps:
      - name: exec hoge.sql
        run: |
          mysql -h 127.0.0.1 --port 3306 -u root -phoge_password -e "$(cat $(find ./ -name hoge.sql))"
```

## hoge.sql

このファイルに予め実行したいsqlを書いておく。
今回は適当に以下のようにする

このファイルの配置場所はどこでも良いが、 `./sqls/hoge.sql`とかがいいかも

`hoge.sql`

```sql
USE hoge_test;

CREATE TABLE users(
id int,
name varchar
)
```
AWS CDKをTypeScriptで使い始める単純な例

## AWS CDKとTypeScriptのインストール

```
sudo npm install -g aws-cdk
sudo npm install -g typescript
```

* macOSの人はsudoは不要
* typescriptがインストール済みの場合typescriptは不要


## 作業用ディレクトリ作成

```
mkdir my-cdk && cd my-cdk
```

## テンプレートプロジェクトの作成

```
cdk init app --language typescript
```

## EC2パッケージを入れる

```
npm install @aws-cdk/aws-ec2
```

[@aws-cdk_aws-ec2.Instance](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.Instance.html)

## サンプルのファイルを開く

ファイルは、`lib/tutorial-stack.ts`にある。

```typescript
import * as cdk from '@aws-cdk/core';

export class TutorialStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
  }
}
```

## サンプルファイルを編集する

```typescript
export class TutorialStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = new ec2.Vpc(this, 'TheVPC', {
      cidr: "10.0.0.0/16"
    })

    const i = new ec2.Instance(this, id, {
      instanceType: new ec2.InstanceType("t2.medium"),
      machineImage: new ec2.AmazonLinuxImage,
      vpc: vpc,
    })
  }
}
```

## デプロイする

```
cdk deploy
```

## 参考

* [Working with the AWS CDK in TypeScript](https://docs.aws.amazon.com/cdk/latest/guide/work-with-cdk-typescript.html)
* [@aws-cdk_aws-ec2.Instance](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-ec2.Instance.html)
エンジニア歴10ヶ月目で「PHP7技術者認定初級試験」を受けてみた

## はじめに
2019年の9月にエンジニアに転職して、約10ヶ月が経過しました。
PHPも業務で初めて触ったのでエンジニア歴とPHP歴はほぼイコールです。

ネットで色々調べていたら、「PHP7技術者認定初級試験」という検定があることを知りました。
実際に試験を受けて合格したので、
どのような試験で、どのくらいの期間何を試験対策として行ったのかを簡単に共有できればと思います。

- この試験を受けるか迷ってる方
- PHPを触り初めて1年くらいの人で自分の理解度の把握をしたいと思われている方
- 基本構文の習得程度で、FWでPHPを書いている方
などの参考になれば幸いです。

## PHP7技術者認定初級試験とは
[一般財団法人PHP技術者認定機構](https://www.phpexam.jp/about/)が実施している、
PHP技術の習得度合いを測るための試験です。

体系だてたPHP学習の総チェックにいかがですか？という感じで、
検定試験の部類で資格試験ではないです。

PHP5とPHP7の試験があり、
PHP5は上級試験/準上級試験の2つ
PHP7は初級試験のみ
という構成です。

私はPHP7初級試験を受けました。

試験内容はPHPの仕様や基本構文、設定周りなど基礎的な部分となります。
正誤選択形式で、試験会場のPCで受験します。
60分で40問。
７割正解で合格。
試験料は13,200円(税込)
結果は試験終了後にすぐ確認できます。

出題範囲はオライリーの『初めてのPHP』（PHP7版）の内容に沿って出題されます。
実際の出題内容については公言できないので、詳細な出題範囲は公式でチェックしてみてください。
https://www.phpexam.jp/summary/novice7/
![スクリーンショット 2020-07-26 16.06.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530688/f4992fa7-67a4-80bc-307c-a76f7608f329.png)



業務でPHPを使用していれば、問題集を何周かすれば合格できると思います。

## 試験対策
出題された問題については言及できませんので、
実際に試験当日までどのくらいの期間で何をやったのかをまとめます。
私の試験の結果は850点/1000点でした。

**対策期間**

- 2週間(月~金で各日15分~30分程度、土日で２時間程度)

**やったこと**

- 下記の問題集を３周  
徹底攻略PHP7技術者認定［初級］試験問題集 徹底攻略シリーズ  
https://www.amazon.co.jp/dp/B07V2MK63C/ref=cm_sw_em_r_mt_dp_U_E8rhFbRSVEMS6
- 独習PHP 第3版を1周通読  
https://www.amazon.co.jp/dp/B01FH3KVNU/ref=cm_sw_em_r_mt_dp_U_b-rhFbPCFQ8ZS


おそらく業務でPHPに触っている方は[試験問題集](https://www.amazon.co.jp/dp/B07V2MK63C/ref=cm_sw_em_r_mt_dp_U_E8rhFbRSVEMS6)をやり込めば問題なく合格レベルまで達せると思います。

その他にPHPの基礎的な書籍で問題集での説明が不十分な箇所や自分の理解が浅いところを補完するとより完璧に近づきます。

公式の出題範囲は[初めてのPHP](https://www.amazon.co.jp/dp/4873117933/ref=cm_sw_em_r_mt_dp_U_5bshFbY2GDKJN)ですが、基本的な内容は同じなので同一の書籍がなくても問題ないと思います。
実際に私は独習PHPという書籍を持っていたのでそちらを使用しましたが、全く問題ありませんでした。

この試験でPHPに初めて触れるという方は[初めてのPHP](https://www.amazon.co.jp/dp/4873117933/ref=cm_sw_em_r_mt_dp_U_5bshFbY2GDKJN)→[試験問題集](https://www.amazon.co.jp/dp/B07V2MK63C/ref=cm_sw_em_r_mt_dp_U_E8rhFbRSVEMS6)の順番で進めるのがいいと思います。

## 対策のポイント
初級試験の内容は基礎的なもので、決して難しい内容ではありません。
基礎構文や条件分岐、繰り返し、配列の操作などは
業務で1年程度PHPでコードを書いていれば改めて勉強する必要はないと思います。

しかし、文章での正誤選択問題となるので細かい部分の理解が必須となります。
**実際に問題集や教材で出てくるコードは実際に動かして一つ一つ確認して行くのが大切です。**
**特に組み込みメソッドの返り値などはしっかり把握する必要があります。**


## 苦労したポイント
私はPHPの基本的な構文を最低限覚え、その後業務でFWでの開発に移ってしまいました。
そのため、PHPの仕様(動作環境)やPHPコマンド、設定周り、など根本的な部分の理解がなく、試験対策を通じて知ることが多かったです(恥ずかしい...)。

実際に問題集の1周目は基本的な条件分岐、ループ、配列操作、webフォームでのやり取り、DB操作、CookieとSessionなど以外は全然解けませんでした。

公式の出題範囲でいうと下記の部分の知識が完全に抜け落ちていました。

- PHPの特徴
- ファイルの操作
- 情報の保存：データベース(PDOのオプションやプリペアドステートメント等の部分)
- ファイルの操作
- メールの送信
- コマンドラインPHP(サーバ起動やドキュメントルートの設定,php.iniや構成ディレクティブあたり)

この辺りは私のようにすぐにFW中心の開発に移ってしまった方は抜けている部分が多いと思います。

オプション指定などについても細かく聞かれるので、問題集に出ている部分は確実に習得する必要があります。

**本番の試験は問題集の出題より少しだけ難しく感じました。**
**より迷わせる問題が多く、問題集の内容を暗記だけではなくしっかり理解しているかを突いてくる問題が多かったです。**

## まとめ
実際にこの試験を受けてみて、PHPのことを全然知らなかった/理解していなかったと痛感しました。
「言語そのものの理解」を深めることの重要性も知ることができました。
試験対策をして、PHPについての理解が深まったことでFWを使っていてモヤモヤしていた部分がすっきりと理解できる、使えるようになった部分もたくさんありました。

特に有名な試験でもないし、合格したからと言って自身の価値向上に繋がるような試験ではないですが、
言語について再度しっかり学びたい方、これから習得を目指す方にはとてもいい試験だと思いました。

試験を通してPHPにより興味を持ったので、継続して言語について理解を深めていこうと思っています。

最後まで読んで頂きありがとうございました。
【PHP】問題集への解答

#ID 10
##200万までの素数の合計値を求める
```php
<?php
$start = microtime(true);
play();
$end = microtime(true);
print "\n".'処理時間 = ' . ($end - $start) . '秒'."\n" ;

function play()
{
  printf("%8d",2);
  $sum=2;

  	for($i=3;$i<=2000000;$i+=2)
  	{
  		$k=0;
  		for($j=3;$j<=sqrt($i);$j+=2)
  		{
  			if($i%$j==0)
  			{
  				$k=1;
  				break;
  			}
  		}

  		if($k==0) {
        // printf("%8d",$i);
        $sum+=$i;
      }
  	}

  	print "\n\n\n$sum\n\n\n" ;
    
}
```

#ID 16 

```math
2^{15}=32768の3+5+2+7+6+8=26
では2^{1000}はなにか
```
とりあえず2の1000乗を見てみると

```php5
print 2**1000;1.0715086071863E+301
```

指数表記される。
`E+N`というのは10のN乗という意味
`1.0715086071863E+301`は

```math
1.0715086071863☓10^{301}
```
という意味。

```php5
<?php
$start = microtime(true);
play();
$end = microtime(true);
print "\n".'処理時間 = ' . ($end - $start) . '秒'."\n" ;

function play(){
  $num=2**500;
  var_dump($num);
  if(strpos((string)$num,'E') !== false){
  //'abcd'のなかに'bc'が含まれている場合
  preg_match('/(.*)E/',(string)$num,$match);
  $num=$match[1];
  $num=str_replace('.', '', $num);
  
}
var_dump($num);
  preg_match_all('/(\d)/',(string)$num,$match);
  print_r((array_sum($match[0])));
  
}
```
53だと思ったが違うみたい
CloudFrontを使ってs3パケットを公開したらAccess Deniedになり、ハマるポイントが多いのでまとめてみた

いきなりですが、AWS基盤で独自のwebサイトを作りたいと思っています。


HTMLやCSSなどフロントのコンテンツは別のサービスを使っていい感じに作るとして、AWSを使うメリットはバックエンドがいい感じにできることです。

登竜門となるのが、s3といったストレージサービスに格納したファイルをいかにしてCloudFrontに乗っけるのか、という部分になると思います。

雑なイメージですが、AWSであれば以下のような構成にすることでいい感じに作れます。
![AWSImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303716/e982579c-84ed-7ac5-96bf-f99539f663d6.png)

詳しい作り方は、ぜひAWS公式のハンズオンなどを見てみてください。

[“AWS 上で静的な Web サイトを公開しよう！” 編を公開しました！- Monthly AWS Hands-on for Beginners 2020年5月号 | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/aws-hands-on-for-beginners-07/)

個人的にハマリポイントがいくつかあったので、そういった点について備忘録として乗っけます。

うまく設定しないと、URLにアクセスしても「AccessDenied」のページとなってしまいます。

## CloudFrontには、s3パケットのHTMLファイルURLをそのままコピペしてもうまくいかない

以下のように、s3にindex.htmlをインポートした後、オブジェクトURLをCloudFrontに貼り付けると思います。
<img width="1190" alt="スクリーンショット 2020-07-26 15.48.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303716/2d7b3002-d97d-2c5e-12da-7ee9312346d2.png">

そのやり方では上手く行かなくて、CloudFrontのOriginには以下の形式でDomain nameを登録する必要があります。
`{your-bucket-name}.s3-website-{your-bucket-region}.amazonaws.com`

この辺の書き方は、以下の記事を参考にしました。
[CloudFront×S3で403 Access Deniedが出るときに確認すべきこと - Qiita](https://qiita.com/sakuraya/items/add2cb7ced954215fb03)

<img width="1175" alt="スクリーンショット 2020-07-26 15.52.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303716/5a909a06-c9a5-f5d4-ff31-263b86d46f90.png">

Orign Pathにも、`/index.html`を登録する必要はありません。

Origin IDは特に変える必要はありません。

## s3の権限は特にいじる必要はない

公開設定がうんぬん、などありますが、特に権限周りは変えなくてもうまくいきました。

わからなければ公開設定にして、成功次第絞るやり方でよいと思われます。
redirect(リダイレクト)についてのメモ書き

アプリ制作時に、redirectの意味や使い方に、ついて
曖昧なまま実装していたので、簡単に書いてみた。

redirect
翻訳・あて名を(…に)書き換える。(…を)向け直す、変える。

一言で言うと、
リクエストされたURLとは別のURLに直ちに再リクエストさせること。

動作例、

・アクセス条件を満たせなかったときに、別のサイトへ遷移させる
・処理のあとにトップページを表示する
・ページの改修中に、一時的に別ページへ遷移させる
Netlify でレスポンスヘッダーをカスタマイズするときは大文字小文字に注意

Netlify でカスタムヘッダーを出すには、`_headers` というファイルを使うか `netlifuy.toml` を使うかの2つの方法がありますが、どちらの方法をつかっても `content-type` ヘッダーの値をカスタマイズしたいときは、以下のように Sneak Case にしないと重複して出力されてしまいます。

## 正しい書き方

```yaml
/xxx
  Content-Type: application/javascript; charset=UTF-8
```

## 間違った書き方

`Content-Type` が全部小文字。

```yaml
/xxx
  content-type: application/javascript; charset=UTF-8
```

この場合、レスポンスヘッダーで以下のように2つの `content-type` が出力されてしまいます。

```
content-type: text/plain
content-type: application/javascript; charset=UTF-8
```

他のヘッダーも多分同じじゃないかなと。