OmniAICreator/Qiita-1.07M huggingface dataset:
Typescript の Enum の個人的なまとめ

[Typescript ドキュメントの Enum のページ](https://www.typescriptlang.org/docs/handbook/enums.html) の概要を日本語でまとめる。

# enum の定義

typescript での enum は下のように定義できる。値を省略したり、文字列にしたりもできるがそれらは元記事参照。

```ts
enum Direction {
  UP = 1,
  RIGHT = 2,
  DOWN = 3,
  LEFT = 4
}
```

# enum の値を参照・代入する

Direction という enum 型を定義しているときは下のような感じで使う。

```ts
const userDirection : Direction = Direction.UP;
console.log(userDirection); // 1 を出力
```

# value から key を取り出す

ドキュメントの [#reverse mappings](https://www.typescriptlang.org/docs/handbook/enums.html#reverse-mappings) に書いてある

```ts
const directionString : string = Direction[1];
console.log(directionString); // "UP" を出力
```

# すべての key を取り出す

[Typescript ではそのような機能をサポートしていない](https://github.com/Microsoft/TypeScript/issues/17198)。今の所自分でなんとかするしかなさそう。

```ts
// key と value が混ざっている
const list: string[] = Object.keys(Direction);

// key のみ
const keys: string[] = list.filter((k: any) => typeof Direction[k] === "number");

// value のみ
const values = keys.map((k: any) => Direction[k]); // なぜか型指定できない…。
```

# ヘルパーメソッド（ユーティリティ関数）を追加する

[#Enum with static functions](https://typescript-jp.gitbook.io/deep-dive/type-system/enums#wotsuenum-with-static-functions) に書いてある。export がない場合はサンプル通りで良いのだが export がある場合は、見慣れない書き方になる。たとえば下のような感じ。

```ts
enum Direction { ... } // 略

namespace Direction {
  export function helper(){ ... } //略
}

export {Direction}
```

また、これは eslint の [no-namespace](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-namespace.md) でエラーになってしまうという問題もある。しかたがないので Enum にヘルパーメソッドを追加するのは諦めたほうがよいかもしれない。

- [ヘルパーメソッドを追加するのは諦めてUnitlity class を作る](https://stackoverflow.com/a/28151986) 
- [Enum 自体をやめて一つの Class にする](https://qiita.com/keito1024/items/b7e55c8d6db433678282) 

あたりが次善策という感じ。
ngrx/example-appのreduxアーキテクチャ

## ngrx/example-app

ngrxのexample-appが、reduxアーキテクチャの参考になったので、まとめてみました。

https://github.com/ngrx/platform/tree/master/projects/example-app

## 画面

アプリケーションのイメージを掴むために、まずは画面から見てみます。
画面は５つです。

### LoginPageComponent

![localhost_4200__1366×768_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244226/5d5ed16b-0042-87e1-ef09-dd0592f071a9.png)

### CollectionPageComponent

![localhost_4200__1366×768___7_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244226/cc066224-1b7d-31da-bd37-ca046be50625.png)

### ViewBookPageComponent

![localhost_4200__1366×768___6_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244226/6803eea6-6eef-9f91-3ebd-fcb6ba8804a0.png)

### FindBookPageComponent

![localhost_4200__1366×768___4_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244226/9d288c28-e73f-8301-2e05-dbcbbcdcf631.png)

## コンポーネントの分け方

Container ComponentとPresentational Componentで分けてるみたいですね。
これはReduxが提唱しているベストプラクティスの１つです。

https://redux.js.org/style-guide/style-guide#move-complex-logic-outside-components

## 画面とEffects、ACTION

![名称未設定-Copy of ページ1 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244226/48893cd7-6901-4d96-2bea-5b2c9a125606.png)
Rのパイプ演算子（%>%） --- 初心者向け ---

###### tags: `rBasicLearning`
# パイプ演算子（%>%）
## 1. パイプ演算子とは
パイプ演算子の役割は, パイプ演算子の左にあるデータを
右の関数の第一引数に渡すというもの.

### 1-1. 前準備
パイプ演算子は, Rに元々入っているものではなくdplyrに入っているもの. 
library()を用いてインストールしなくてはならない.
今回は, tidyverseで行う.

```r
#install.packages("tidyverse")
library(tidyverse)
```

### 1-2. 具体例

```r
data <- c(1, 3, 5, 10, 11, 15) #自分の使いたいデータを入れてください
data %>% head(3)
data %>% mean()
```
```r
> data %>% head(3)
[1] 1 3 5
> data %>% mean()
[1] 7.5
```
以下のように, 複数個繋げることもできる

```r
data %>% head(3) %>% mean()
```
```r
> data %>% head(3) %>% mean()
[1] 3
```
## 参考 ショートカット
MACは `Control + Shift + m` で `%>%` を出力できます.

Windowsは `Ctrl + Shift + m` で `%>%` を出力できます.
全アプリ開発者に伝えたい、レガシーコードから脱却するための具体的な手法、“ルール駆動開発”

# ルール駆動開発

全アプリ開発者に伝えたい、レガシーコードから脱却するための具体的な手法、“ルール駆動開発”
スパゲティ化・ブラックボックス化したレガシーなアプリケーション。
このまま塩漬けにしてよいわけもないが、はたしてどこから手を付ければよいか、どんな手法でモダナイズしていけばよいのか。

その一つの答えとして、「ルール駆動開発」があります。
複雑に絡み合った既存システムをどのように解きほぐしていけばよいのか。
ルールエンジンを使った開発を数多く手掛けてきた中で、レッドハット社内で培われたノウハウと、見えてきたベストプラクティスの一部を紹介します。

発表者　松田 絵里奈[レッドハット]

### 本日のいいたいこと「業務ルール＝ビジネスルール＝ビジネスロジック」

## 業務アプリケーションの設計・開発手法
 - クラウドネイティブアーキテクチャ！
 - 初めから改修を前提においた開発！
 - レガシーアプリの移行時にも有効な手法！

##　ルール駆動開発の３つの特徴
 - ルールとデータアクセスを完全分割
 - 業務目線でルールを整理し、そのまま実装
 - イテレーション開発

### やりがちなこと　現行プログラムコードの解析　をやめましょう。
　⇒そもそも実りある成果があるのか
　- 現行コードの解析しても継ぎ足し継ぎ足しの秘伝のタレ様態
　- リファクタリングされていない冗長なコード
　- 不要なゴミコードの山
　- 不要かどうかはコードからは不明
　- ゴミの移行に時間とお金をかけることに（60%は使わなかったロジック）

### 知りたいことは業務要件＝業務ルール
  - 業務を知っている人に聞く
  - 全部は聞かない、知っているところを確認する
  - 業務マニュアルや業務フロー図など、設計からわかることもある
  - ヒアリング内容をDMNで整理（Decision Model and Notation）　「判定ロジック」と「データ」
　　　**業務用語で書くこと**

###　DMNから一連の業務ルールをサービスとして切り出す

![2020_02_14 10_06 Office Lens (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265259/b71a0436-4fc2-7a71-9c0c-6f0f16603521.jpeg)

 - ルールのテストがしやすい
 - 回収時の影響分性範囲がSE馬原
 - DB構成の変更影響を受けにくい

RedHat Decision Manager
ルールエンジン利用時の実装
![2020_02_14 12_28 Office Lens.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265259/896d38c7-564e-2938-d2f9-e8b78cdcf821.jpeg)

小さく作ってテストを繰り返しながらルールを育てていく

##　ルールのイテレーション開発
![2020_02_14 12_31 Office Lens.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265259/8a98342c-1646-d428-a6eb-1d691c15f385.jpeg)


新旧一致テストを繰り返し、ルールの精度を高速にあげていくテスト・開発手法

##　正しいルール駆動開発
![2020_02_14 12_34 Office Lens.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265259/b1d6fc51-9ee5-4e12-efe3-657593bbee82.jpeg)

繰り返しになるが、現行コードは見ないというのは新たな見地だと思う。その代わりに業務ロジックの理解と図式（DMN）を作るのがよいと思われる。

## まとめ
 - 現行コードからではなく業務ルールからのアプローチで無駄を省く
 - 最新業務ルールが常に可視化された状態
 - データアクセスとルールを分離し、メンテナンス性向上
 - 実験⇒テストで品質向上
Unityで始めるゲーム制作 導入編

#はじめに
もっぱら技術ブログなどは、
自分が所属している同人サークル「[RomanesqueFreaks](http://romanesquefreaks.jp)」のブログで書いてたんですけど、
Unityの導入部分くらいはこっちにも書いちゃおうと思ったので、書きます。
導入といっても簡単なミニゲームを作るところまでやるつもりです！

技術系やゲーム・IT系のイベントの話をしてるので、
是非ブログものぞいていってください！

#環境
Windows10
Mac（スクリーンショットはこちらの画面です）

#インストール
現在のオススメは複数バージョンのUnityを管理できるUnity Hubです。
[こちら](https://unity3d.com/jp/get-unity/download)から「Unity Hubをダウンロード」を選択してダウンロードしてください。
exe/dmgを実行するとHubがインストールされます。
<img width="1068" alt="Screen_Shot_2020-02-14_at_12_12_53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123827/d2264734-4dba-f799-6c6c-063995f11d09.png">


#テキストエディタのインストール
Unityでの開発は主に、Unityのエディタを開きながらオブジェクトを配置したりして、それに対してC#を別のテキストエディタで書いていく、という流れになります。
（個人的にデュアルディスプレイがまじで使える場面です！）

フリーで使えるエディタの中ではVisual Studioがとても強いのでインストールしてみましょう。

今回は個別にインストールしますが、もともと入っている場合はそれを使うことができるので、この手順はスキップしてください。

Visual Studioは統合開発環境、英語にした時の頭文字でIDE (Integrated Development Environment)と呼ばれる高機能なエディタです。
そのためPCのスペックが高くない時には、処理が重く大変になるかもしれません。
そんな時はVS Codeと呼ばれる Visual Studioの低機能軽量版での開発をお勧めします。
自分も一時期この環境で開発してました。
詳しくは[こちら](https://qiita.com/4_mio_11/items/e7b0a5e65c89ac9d6d7f)を。

ではエディタのインストールの手順に入ります。

まず、Unity Hubを実行し、「インストール」をクリック。
<img width="981" alt="Screen_Shot_2020-02-14_at_12_21_08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123827/fcb83221-9a4f-b074-c281-b7f155b95173.png">
インストール済みUnityのメニュー（グレーの3つの点）を選択。
<img width="982" alt="Screen_Shot_2020-02-14_at_12_21_29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123827/8e851fe6-fcbf-25b7-77cb-829a01557609.png">
「モジュールを加える」を選択
<img width="316" alt="Screen_Shot_2020-02-14_at_12_21_40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123827/61f8d2bb-a317-5f3c-a111-4934b069644f.png">
 Windowsでは「 Microsoft Visual Studio Community 2017」、
Macでは 「Visual Studio for Mac」を選択し、「次へ」を押す。
<img width="641" alt="Screen_Shot_2020-02-14_at_12_21_58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123827/423b5c41-cb60-1869-813b-7328734654c0.png">
<img width="641" alt="Screen_Shot_2020-02-14_at_12_25_42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123827/01a49a85-27be-3f97-4fc3-824ed3bbdd99.png">

すると規約が表示されるので、了承できる場合は「実行」を押すとインストールが開始されます。

続く
(2月下旬執筆予定・完了予定4月末)
Vue/Nuxtで`is-active`みたいなclassを条件によって追加しようとしたら'v-bind' directives require an attribute value.と出る件

小ネタ。特に

 * NuxtでESLintを有効にし
 * CSSフレームワークをBulmaにして(`is-active`とかのclass名をよく使うため)
 * **ハイフン付きの`is-active`とかのclassを** 条件によって追加しようとすると

遭遇しやすいです。


## `require an attribute value.` って言われてもわかりづらいよ！

Vue/Nuxtで条件によってHTMLのclassを動的に変更したい場合、 [Vue.jsのドキュメント](https://jp.vuejs.org/v2/guide/class-and-style.html#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%A7%8B%E6%96%87) で紹介されていますが、

```vue:「HTMLクラスのバインディング」の例
<div v-bind:class="{ active: isActive }"></div>
```

そのとおりに `is-active` などのclassを追加しようとする次のエラーが発生します。

> 'v-bind' directives require an attribute value.

```vue:v-bindで失敗する例
<template>
  <div 
    :class="{ is-active: isDropdownShown }"
    class="dropdown" 
  >
...
</div>
</template>
```

「attribute valueを設定したはずなのにどうして…🤔」と考えてしまうとハマり始めます。


## 解決法: 追加しようとするクラス名をシングルクォーテーションで囲む

これだけです。class名に `-` が含まれている場合、そのままだとattribute valueとして認識されません。

```vue:追加しようとするクラス名をシングルクォーテーションで囲む
<template>
  <div 
    :class="{ 'is-active': isDropdownShown }"
    class="dropdown" 
  >
...
</div>
</template>
```

JavaScriptの識別子…Objectのkey…と考えると気づきやすいですね！
FrescoのSimpleDraweeViewで新しい画像をセットしても古い画像が表示された問題の解消

## 問題
Androidの開発で[Fresco](https://frescolib.org/)を使ってることは多いと思う。

そのFrescoのSimpleDraweeViewを使用していた際、新しい画像をセットしても画面に反映されない現象に遭遇した。

## 解決方法
キャッシュを消す。(by [stack overflow](https://stackoverflow.com/questions/30455900/how-i-can-update-image-of-fresco-simpledraweeview-if-it-was-set-once-by-setimag))

```kotlin
Fresco.getImagePipeline().evictFromMemoryCache(uri)
```

## 解決までの流れ
R1. 新しくセットするuriをBitmap化して、そのuriがセットしたい画像かをDebugで確認する
    ・ 下記コードで`bitmap`変数を作成し、このコード直後にbreak pointを貼る。

```kotlin
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri)
```

R2. break pointで止まったら、ToolbarのDebugから`bitmap`変数の`View Bitmap`をクリックして画像を目視確認する。

R3. 画像がセットしたい画像なので、キャッシュを疑い消す。

R4. 解決。
【Unity】Sceneを切り替えるコード

これでスタート画面やエンド画面を作ることができる!!

**関連**

- [キー押下でScene再読み込みをする(リロード、リトライ的なもの)](https://qiita.com/sanpeita/items/acc518a3fd8176164405)
- [【unity】爆速でunitychanを動かしたい時【unitychan】](https://qiita.com/sanpeita/items/ab3bb9ce5a5b7e6cf6a0)

---

#クリア画面で、リターンキー押下でスタート画面へ遷移したい場合

下記の例では、クリア画面で、リターンキー押下で、
SceneStartというSceneへ遷移するようにしている。

```clear.cs

using UnityEngine.SceneManagement; //ここ必要
using UnityEngine;

public class clear : MonoBehaviour
{
    void Update()
    {
        //ここから
        if (Input.GetKey(KeyCode.Return)) //リターンキー押下時に
        {
            SceneManager.LoadScene("SceneStart"); //"SceneStart"というSceneへ遷移する
        }
        //ここまで
    }
}
```

---

# プレイヤーが、Targetというタグに触れたらゲームオーバーのSceneへ遷移する場合の記述

また、
プレイヤーがTargetというタグに触れたらゲームオーバーのSceneへ遷移したい場合は下図参照

```

        if (col.gameObject.tag == "Target") {
            SceneManager.LoadScene("SceneEnd");
        }
```

---

# スタート画面で、ボタン押下時にゲーム画面へ遷移する場合

```btn_start.cs

using UnityEngine;
using UnityEngine.SceneManagement;

public class btn_start : MonoBehaviour
{
    public void OnClick()
    {
        SceneManager.LoadScene("GameScene"); //ここに遷移先のSceneファイル名を記入する
    }
}

```

## ボタンの設定の仕方メモ
- ボタンを追加
- ボタンのコンポーネントの中で「Button」コンポーネントがあるので、そこにリストを追加
- スクリプトがアタッチされているオブジェクトをアタッチして、
- Scene遷移を記述しているメソッドを指定する

---

実行時は、ビルド設定で、Sceneファイルを含めておく必要があるので、スクリプトを書いて満足しないように!!

---

# おまけ:FPSゲームなどでマウスカーソル非表示後のエンドシーンでマウスカーソルを復活させる場合

- StandardAssetsのFPSコントローラーを使っていると、よくぶつかる問題です。
- 下記スクリプトは単体として記述していますが、実際には、エンドシーンのリトライなどのボタン押下のスクリプトに織り交ぜても良いと思います。

```cursorFormat.cs
using UnityEngine;

public class cursorFormat : MonoBehaviour
{
    void Update()
    {
        Cursor.lockState = CursorLockMode.None; //マウスカーソルの設定を初期化して、
        Cursor.visible = true; //マウスカーソルを表示する
    }
}
```
その英語の発音は間違ってる！（気付いたら追加、質問も受けます！）

# 経緯
日々、現場でコードを書いていると聞こえてくる、あんな言葉、こんな言葉。

**「その発音間違っているよ！！！」**
そっと、心の内だけでツッコミ続ける日々にさよならしたい！

と個人的な強い思いが動機ではあるものの、伝えたい理由は他にもある。

間違っているだけなら、よしとしましょう。伝わるし。
場合によっては **口に出したら品性を疑われる様な「別の単語」になってしまっていることがある**。
日本人だけの職場なら誰も気がつかない。誰も疑問に思わない。

しかし、一歩外に出れば、社会の荒波に揉まれることになります。
今後、外国人との会話も増えていきます。
恥ずかしい思いをする前に、この投稿に出会っていただけたらと思い執筆しています。

## 誰が書いている？
iOSアプリエンジニア・フロントエンジニア
１６歳で渡米。英語オンリーの世界で１０年。日本に戻る。プログラミングの基礎は英語で覚えました。
※ですので、アメリカ語に寄ります。
※英語以外が由来の場合は読み方が違う場合もありますが、基本英語ベースとします。

# 質問・相談受けます！
日々のエンジニア活動で使われる専門用語やその他、自信のないもの、知りたいもの、気軽にきいてください！
こちらに順次追加してまいります。

**一緒に国際的に活動できるエンジニアを目指していきましょう！**

#　カテゴリ別　単語と発音
## 基本編
プログラミング初学者など、どの言語でも避けては通れない、比較的初めの段階で出会ってしまうであろう単語をまず書いておきます。

|単語|ハツオン|間違い|コメント|
|----|----|----|---|
|false|フォルス f-all-s|ファルス|（調べない方がいいです）|
|null|ナル n-al |ヌル|日本語がヘビーにヌルによってるのだけど「なる」です<br>ヌルと日本語発音で外国人に言わない方が良いです。<br>全く別の意味で取られます。|
|allow|アラウ a-la-u|アロウ|slowとかがスロウなので同じように読みがちですが、クラウド cloud と同じような発音をします。|

## ビジュアル編
フロントエンジニア、アプリエンジニア、ウェブエンジニアなどが使うビジュアル、UIに関する単語をまとめます。

|単語|ハツオン|間違い|コメント|
|----|----|----|---|
|width|ウィッス wi-th|ウィズス|thの前の子音はほぼ発音しないので無視します。<br>dとthは舌の位置が近いのでネイティブでも滑舌良い人でないと分けられない|
|depth|デプス dep-th|デプス|間違ってるものの「でっす」と発するのは恥ずかしい。<br>このプの発音は 上のdよりも明らかに大きいので|

## CSS編
CSSの中にもいくつか曖昧なものがありますね。

|単語|ハツオン|間違い|コメント|
|----|----|----|---|
|relative|レラティヴ|リレイティブ|発音がリレイト、リレーションとはちょっと違うので注意！|

## DB編
|単語|ハツオン|間違い|コメント|
|----|----|----|---|
|column|カラム|コラムン<br>カラムン|英単語覚えたときのまま発音しちゃってる系。心の中だけで。|
Windows用の64-bit版MeCabを簡単にインストールする

ちゃお・・・†

# はじめに
64-bit版Pythonでは、[MeCab公式サイト](https://taku910.github.io/mecab/)で配布されているWindows用32-bit版MeCabバイナリが実行できません。そこで、Windows用64-bit版MeCabバイナリが必要となるわけですが、わざわざ自分でMeCabのコードをいじってコンパイルするのは面倒です。

そこで、わたしが作ったWindows用64-bit版MeCabバイナリのインストーラーの紹介をしたいと思います。

# インストール
まず、Windows用64-bit版MeCabバイナリのインストーラー (拡張子に `.exe` が付いてるもの) を下記URLからダウンロードします。新しいものほど改善されているので新しいバイナリの利用を推奨します。

https://github.com/ikegami-yukino/mecab/releases

# 使い方
まず、前のセクションでダウンロードした `exe` 形式のインストーラーファイルを実行します。インストーラーでの手順はMeCab公式インストーラーと全く同じです。辞書をビルドする時の文字コードは昨今の風潮により `UTF-8` を選択するとよいです。ただしWindowsのコマンドプロンプトの初期設定の文字コードは `Shit-JIS` なので、WindowsのコマンドプロンプトでしかMeCabを使わない場合は `Shift-JIS` をおすすめします。

# メリット/デメリット
## メリット

- 64-bit版にするためにMeCab公式のコードをわざわざ自分で書き換えなくて済む
- PyPIの [`mecab` ラッパー](https://qiita.com/yukinoi/items/990b6933d9f21ba0fb43)を入れることで64-bit版PythonでMeCabが使えるようになる
- もしWindowsが32-bitソフトウェアのサポートをやめた場合でも問題なくMeCabを使うことが出来る
- 現時点では[公式のMeCabリポジトリ](https://github.com/taku910/mecab)は2018年3月でコミット止まっていますが、Windows用64-bit版MeCabの作者 (わたし) はサポートする気がある

## デメリット

- CaboChaの公式Windowsバイナリは32-bitなので、Windows用64-bit版MeCabを入れるとCaboChaが動かなくなる

# さいごに
昨今はTensorFlowやPyTorchなど64-bit版Pythonでしか動かないライブラリ/パッケージが増えています。なのでWindowsでMeCabを使ってテキストデータの前処理をしたいときに、わざわざ32-bit版Pythonに切り替えるのは面倒です。そこで今回紹介した64-bit版MeCabバイナリを入れて、pipで [`mecab` ライブラリ](https://qiita.com/yukinoi/items/990b6933d9f21ba0fb43)を入れるとそうした切り替えの手間が省けて楽になります。

ただし、64-bit版MeCabバイナリを入れるとCaboChaが動かなくなるので、CaboChaが必要な方は公式の32-bit版MeCabを利用してください。他にも動かなくなるライブラリやアプリがあるかもしれません。そうした場合も公式の32-bit版MeCabを利用してください。

# 厚かましいお願い
もしも気に入ったら[64-bit版MeCabのGitHubリポジトリ](https://github.com/ikegami-yukino/mecab/)にスターをつけていただけると嬉しいです。たったの1クリックだけで、わたしの開発のモチベーションがアップします。

スターだけじゃ物足りない！という方は、[64-bit版MeCabのGitHubリポジトリ](https://github.com/ikegami-yukino/mecab)のSponsorボタンを押すとわたしにお金や物を送ることが出来ます。わたしの開発のモチベーションがかなりアップします。
リンク画像にマウスホバーすると画像がふわっと(重要)変化する方法

## これからすること
ユーザビリティの観点から、リンクできる画像やボタンなどのパーツには ”リンクできそう” な見た目や演出が要求されるのですが顧客受けが良いのか
**画像にマウスのカーソルを乗せるとふわっと変化する**
を求められる場面が結構あります。
ホバーした時に画像を変えるだけなら

```js
$(function(){
  $('a img').hover(function(){
    $(this).attr('src',$(this).attr('src').replace('_off','_on'));
  },function(){
    $(this).attr('src',$(this).attr('src').replace('_on','_off'));
  });
});
```
img01_on と img01_off という2種類の画像を用意して JSに ↑ を書くだけで対応できるのですが**ふわっと**することなく一瞬で変わってしまします。

## 解決方法(JS不要)
<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="sphenisc" data-slug-hash="poJgWeQ" 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="poJgWeQ">
  <span>See the Pen <a href="https://codepen.io/sphenisc/pen/poJgWeQ">
  poJgWeQ</a> by sphenisc (<a href="https://codepen.io/sphenisc">@sphenisc</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
CSSでホバーしていない状態の画像を上から被せておき、ホバーするとimgタグで入れた方の画像が現れる仕組みになっています。

```css
  transition: all 1s;
```
の部分をいじれば変化のさせ方を変えることができます。

```css
ul li a:hover::after {
  opacity: 0;
}
```
の部分に `height:0;` を追加するだけでカーテンが上がるような動きにできます。
ネットワーク機器のログをsyslogサーバーに転送しlogrotateで世代管理する

# 概要
Cisco Catalyst2960Xなどのネットワークスイッチのログをsyslogサーバーに転送し、syslogサーバー側では受信したログをlogrotateで世代管理する設定を行います。
またおまけでlogrotate用のファイルをpythonで生成するサンプルも記載します。

### 環境

想定環境は以下の通りです。
・Catalyst 2960X (WS-C2960X-48TD-L) IOS Version 15.2(4)E5
・CentOS Linux release 7.5.1804 (Core)
・logrotate-3.8.6-15.el7
・rsyslog-8.24.0-16.el7
・Python 2.7.5

IPアドレス
・スイッチ：192.168.1.1
・syslogサーバー：192.168.1.100

以下説明では上記環境が既に構築済であるとします。

## Catalystスイッチ側の設定

Catalystスイッチにログイン後、特権モード、グローバルコンフィギュレーションモードに移行し
以下コマンドでsyslogサーバーへのログ転送を設定します。

```
switch1(config)#logging host 192.168.1.100
```

## syslogサーバー側の設定

### firewalldの設定

firewall-cmdにてsyslogサービス用ポートを開放します。
※ --add-service=syslogで開放するポートはudp514です。

```
# firewall-cmd --add-service=syslog --zone=public
# firewall-cmd --add-service=syslog --zone=public --permanent
```

### rsyslogの設定

スイッチから送信されるログを /var/log/networkdevices 以下に、スイッチのIPアドレスのディレクトリ、
スイッチのIPアドレスのファイル名 + ".log"の形式で保存することを想定します。

以下設定を /etc/rsyslog.conf の #### TEMPLATES #### 以下に追加します。

```
#### TEMPLATES ####
$template RemoteHost,"/var/log/networkdevices/%fromhost%/%fromhost%.log"
```

また /var/log/networkdevices/ ディレクトリを作成しておきます。

```
# mkdir /var/log/networkdevices
```

### logrotateの設定

/var/log/networkdevices/スイッチのIP/スイッチのIP.logファイルを圧縮、ローテーションさせるための設定を行います。

/etc/logrotate.d/以下にスイッチのIPを名前とするファイルを以下内容で作成します。

```
# pwd
/etc/logrotate.d

# vi 192.168.1.1
/var/log/networkdevices/192.168.1.1/192.168.1.1.log {
        daily
        rotate 31
        compress
        delaycompress
        missingok
        notifempty
        create 0664 root root
}
```

これにより192.168.1.1.logファイルは圧縮され、31世代でローテーションされるようになります。

# おまけ

ipアドレスのリストが記載されたテキストファイルを1行ずつ読み込みlogrotate用の設定ファイルを生成するpythonプログラムの例です。

```list.txt
192.168.1.1
192.168.2.1
・・・
```

```python:sample01.py
#!/usr/bin/env python

f = open('list.txt', 'r')
line = f.readline()

while line:
        af = line.strip()

        file = '/etc/logrotate.d/' + af

        with open(file, 'w') as outp:
                outp.write("/var/log/networkdevices/" + af + "/" + af + ".log {\n")
                outp.write("\tdaily\n")
                outp.write("\trotate 31\n")
                outp.write("\tcompress\n")
                outp.write("\tdelaycompress\n")
                outp.write("\tmissingok\n")
                outp.write("\tnotifempty\n")
                outp.write("\tcreate 0664 root root\n")
                outp.write("}\n")

        line = f.readline()
f.close()
```
JSで要素間を線で繋いだり動かしたりライブラリ調査@202002

JSでオブジェクト間に線を引きたい調査メモ

|ライブラリ名|GitHub|サンプル|
|---|---|---|
|diagramflowjs|https://github.com/luisalvesmartins/diagramflowjs|https://lambot.blob.core.windows.net/github/diagramflowjs/index.html|
|SimpleFlowchart|https://github.com/mmazo/SimpleFlowchart|http://mmazo.de/flowchart/|
|svg.connectable.js|https://github.com/jillix/svg.connectable.js|http://jillix.github.io/svg.connectable.js/|
|svg.draggy.js|https://github.com/jillix/svg.draggy.js|http://jillix.github.io/svg.draggy.js/|
|leader-line|https://github.com/anseki/leader-line|https://anseki.github.io/leader-line/|
|Drawflow|https://github.com/jerosoler/Drawflow|https://jerosoler.github.io/Drawflow/|
|Flowy|https://github.com/alyssaxuu/flowy|https://alyssax.com/x/flowy/|

###diagramflowjs

削除や追加、リネームなど機能が豊富な感じで実用向けな感じ

https://lambot.blob.core.windows.net/github/diagramflowjs/index.html

![NoName_2020-2-14_11-52-43_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/fbea43e5-e08e-f55b-2ee3-9d00da76faa4.png)


###SimpleFlowchart

バインバイン動く

http://mmazo.de/flowchart/

![NoName_2020-2-14_11-53-42_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/8f1cd81a-58b1-a848-5e22-bbf0bc218f56.png)




###svg.connectable.js

ソースコードなどが合って使いやすい

http://jillix.github.io/svg.connectable.js/

![NoName_2020-2-14_11-55-2_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/2b7fcf07-c259-c697-62c1-49f2ac096c4d.png)


###svg.draggy.js

SVGドラック簡単に追加できて便利

http://jillix.github.io/svg.draggy.js/

![NoName_2020-2-14_11-54-54_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/93bdb933-b924-4505-48d1-b3d5b55486c5.png)

###leader-line

結構いろんな線があるのでウェブで線を引きたいときには使いたい感じ

https://anseki.github.io/leader-line/

![NoName_2020-2-14_11-55-42_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/16055984-4cea-8718-788b-0eb5cd0a3fc2.png)

###Drawflow(202009追加)

NodeRedみたいな感じで使えそうなので便利化なる

https://jerosoler.github.io/Drawflow/

![NoName_2020-9-24_14-4-54_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/7e2958bd-931c-f73c-cf41-ad2f6ea02f29.png)


###Flowy(202106追加)

自分でオブジェクト同士の線引きはできないが、処理フロー可視化としては使えそう

https://alyssax.com/x/flowy/

![20210628_093405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/5dc07f82-4440-f0cc-53c9-1ac53cdcb0ab.png)
【Rails】Modelで定義した定数にViewからアクセスする方法

表題の通り、定数にアクセスできずに困った人のための記事です。

# 結論
**Model名::定数名**とすればOKです。

# 解説
下記のUserクラスがあるとします。

```models/user.rb
class User < ActiveRecord::Base
  MAX_NUMBER = 10
  ...
end
```

Viewから参照するには、下記のようにします。

```views/xxx.html.erb
最大値は#{User::MAX_NUMBER}です。
```

　
これが下記のようになっていると、

```views/xxx.html.erb
最大値は#{MAX_NUMBER}です。
```

↓

```ruby
uninitialized constant ActionView::CompiledTemplates::MAX_NUMBER
```

そんな定数は無いと怒られてしまいます。

以上です！
ActiveRecordのトランザクションのネストに気をつけること


- 確認した環境
  - Ruby 2.5.1
  - Rails 5.2.1
  - MySQL 5.7.27

腕試しに以下のスクリプトを実行した場合、最終行の `User.first.name` は何が得られるか考えてみてください.

```ruby
User.first.update!(name: 'Alice')

ActiveRecord::Base.transaction do
  User.first.update!(name: 'Bob')

  ActiveRecord::Base.transaction do
    User.first.update!(name: 'Carol')
    raise ActiveRecord::Rollback
  end
end

User.first.name
```

<details>
<summary>正解はここをクリック</summary>
<p>

`User.first.name` の結果は **Carol** になります.
正解しましたか？
正解する人もいると思いますが直感と違うかと思います.
</p>
</details>

<br/><br/><br/><br/><br/><br/><br/>

## TL;DR
- 可能ならトランザクションをネストしない設計する
- トランザクションをネストする設計の際は `requires_new: true` を使う
  - 付けないと思いのよらないゴミができる可能性がある

## 検証

分かりやすくするため、SQLをコメントに加えました.

```ruby
User.first.update!(name: 'Alice')
# BEGIN
# UPDATE `users` SET `name` = 'Alice' WHERE `users`.`id` = 1
# COMMIT

ActiveRecord::Base.transaction do
  # BEGIN

  User.first.update!(name: 'Bob')
  # UPDATE `users` SET `name` = 'Bob' WHERE `users`.`id` = 1

  ActiveRecord::Base.transaction do
    User.first.update!(name: 'Carol')
    # UPDATE `users` SET `name` = 'Carol' WHERE `users`.`id` = 1
    raise ActiveRecord::Rollback
  end
end
# COMMIT

User.first.name # => 'Carol'
```

### requires_new を使った場合
いくつかのRDBにはトランザクションにSAVEPOINTをサポートしているものがあります.
このSAVEPOINTを利用するには `requires_new` を指定することで有効になり直感に近い挙動をする様になります.

```ruby
User.first.update!(name: 'Alice')
# BEGIN
# UPDATE `users` SET `name` = 'Alice' WHERE `users`.`id` = 1
# COMMIT

ActiveRecord::Base.transaction do
  # BEGIN

  User.first.update!(name: 'Bob')
  # UPDATE `users` SET `name` = 'Bob' WHERE `users`.`id` = 1

  ActiveRecord::Base.transaction(requires_new: true) do
    # SAVEPOINT active_record_1

    User.first.update!(name: 'Carol')
    # UPDATE `users` SET `name` = 'Carol' WHERE `users`.`id` = 1
    raise ActiveRecord::Rollback
  end
  # ROLLBACK TO SAVEPOINT active_record_1

end
# COMMIT

User.first.name # => 'Carol'
```
色を作る時はHSBで考えるのが良き！


今回は色についてのお話です :art: 

CSSで色を指定すると言われて想像するのはどんなものでしょう :thinking: ？

恐らくカラーコードというものを指定しているかと思います。
(#FFFFFFみたいなやつ。16進数ですね。)

勿論、色を指定するだけならカラーコードでも良いのですが、

:star2::star2: **色を作る** :star2::star2:

という観点だとカラーコードは色が想像しにくいという難点があります。

## HSBという考え方
**HSB**は**Hue(色相) Saturation(彩度) Brightness(明度)**の略で、
カラーコードとは違い、各数値で色を指定することができます:bulb:
各指定できる範囲はこんな感じ
色相 : 0 - 360
彩度 : 0 - 100
明度 : 0 - 100

(下記画像は私の師匠のデザイナーからいただいた貴重な画像です :sparkles: )
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498647/9cb12c8c-1cbc-32b2-34eb-248de903d23d.png)

### 色相
色相は、上記画像に見える虹色のバーの部分で、色の様相の相違を表します。
グラデーションを作るときは、色相の流れに沿って色を選択すると、
濁らずに綺麗なグラデーションを作ることができますョ🐥

### 彩度
彩度は色の鮮やかさ度合いを調整することができます。
色味を濃くしたり薄くしたりすることができるので、色味が強すぎたときに彩度を下げたりすると、淡い感じの色をつくることができます(パステルカラーとか)。
白 - (自分の指定した)色の間を行くので色を濁らせる働きはしないのが特徴です。

### 明度
明度は色の明るさを調整することができます。
数値が低ければ低いほど暗くなっていきます。
あまり低くしてしまうと色が濁ってきてしまうので注意が必要です。
(特に黄色はくすみやすいので上級者向けです)
慣れないうちは100の状態で固定しておくのも有りかもしれません。
彩度とは違い、こちらは黒 - (自分の指定した)色の間を行くので、
色を薄める働きはしないです。



## HSBの使い方
HSBを使いこなすには以下の手数を踏む必要があります :bulb: 

1. 色味を決める(H)
2. 彩度(S)・明度(B)を決める
3. 微調整する

### 1. 色味を決める(H)

上記画像にも記載ありますが、
例えば青を作りたいときは170 - 240の間でHの数字を指定します。

### 2. 彩度(S)・明度(B)を決める

おさらいになりますが、
彩度と明度は以下の特徴があります。

- 彩度は数値が高ければ高いほど鮮やかに
- 明度は数値が高ければ高いほど澄んだ色に

上記を踏まえて、デザインをする上での色の役割に併せて決めていきます。
もし、今回作る色が(メイン / ベース / アクセント)でいうアクセントカラーであれば、
ユーザーの目を引く鮮やかな色を選ぶ必要があります。

鮮やかな色を作るにはどうすればよいかもうお分かりですね？

彩度と明度の数値を100に近づければOKです :+1: 
(ただ、どちらも100に振り切ると色によってはキツイ印象を与えるので
色をみながら適宜調整してみてください)

実際にiOSのapple公式で出しているミュージックアプリや
App Storeアプリではアクセントカラーの明度が100になってます :star2: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498647/3595be24-d7b5-0bb0-ae7c-b30fe0a1007e.png)


### 3. 微調整する
おおよその数値を決めてもなんだかしっくりしない場合は、
HSBの数値を少しずつ弄ってみましょう。
同じ青でも緑寄りの青や紫寄りの青によって色相の最適数値が変わってくるので、
ひたすら色々な数値を入れてみるのも良いかもしれません:sparkles: 

このように、HSBを使うと直感的に明るい色や鮮やかな色を指定することができるという
最大のメリットがあるんです:sunglasses: 

ここまでできたらHSBの基本を習得したと言っても過言ではないでしょう :point_up_tone1:

## HSBに慣れると
街中の色がどのように構成されているかがわかるので楽しいです :musical_note: 
※個人的な意見です

例えば
「あの緑薄いけど、澄んだ色してるから、明度高めの彩度低めかな〜」
とか
「あの赤なんかくすんでる〜ちょっと明度低い気がするな〜」
とか:relaxed: 
色に対して意識するだけで、何だかちょっと世界が広がる気がしません？:laughing: 

## CSSでHSBを扱う
ただ、一点注意しないといけないのは、CSSではHSBではなく、
**HSL**で色を出力することになります。(Hue(色相)、Saturation(彩度)、**Lightness(輝度)**)
HSBに似てはいますが、別物なのでそのままの数値をHSLに指定しても思った通りの色は出てきません......:disappointed: 

そういうときこそSassのFunctionの出番です:kissing_heart: 
こんな感じでFunctionを作ってあげると

```sass
// @function hsb: HSBに変換する
// @param	{String} : $h-hsb: Hue(色相)
// @param	{String} : $s-hsb: Saturation(彩度)
// @param	{String} : $b-hsb: Brightness(明度)
// @return HSB color
@function hsb($h-hsb, $s-hsb, $b-hsb, $a: 1)
	@if $b-hsb == 0
		@return hsla(0, 0, 0, $a)
	@else
		$l-hsl: ($b-hsb/2) * (2 - ($s-hsb/100))
		$s-hsl: ($b-hsb * $s-hsb) / if($l-hsl < 50, $l-hsl * 2, 200 - $l-hsl * 2)
		@return hsla($h-hsb, $s-hsl, $l-hsl, $a)
```

HSBをそのまま使うことができます:revolving_hearts: 

```sass
$blue: hsb(200, 100, 100)
```

これでもう色は迷うことなくHSBが使えますね:smirk: 
色についてもっと深めたい方はぜひ**HSB**を使ってみてください〜！
ラムダ式

```python:lambda.py
l = ['Mon','Tue','wed']
def change_words(words, func):
    for word in words:
        print(func(word))

#ラムダ式を使わない場合
#def sample_func(word):
    #return word.capitalize()
#change_words(l,sample_func)

#ラムダ式を使うと、1行で書ける
change_words(l,lambda word:word.capitalize())
```
出力：

```
Mon
Tue
Wed
```
UIAppearanceの優先度

# UIAppearance の基礎
これですべての `UILabel` の `textColor` が茶色に変わります。
（現実的には `UILabel` の `textColor` を `UIAppearance` で設定するのは稀だと思いますが、あくまでサンプルとして）

```swift
UILabel.appearance().textColor = .brown
```

# 特定のView上にあるUILabelのtextColorを変える
## View階層が1つだけの時
すべての `ViewA`  上の `UILabel` を変えたいなら、こんなふうに書けば良いですね。

```swift
UILabel.appearance(whenContainedInInstancesOf: [ViewA.self]).textColor = .red
```

## View階層が2つ以上の時
`SampleViewController`  上の `ViewA`  上の `UILabel` だけを変えたい時など、
階層が2つ以上の時は、対象となるViewから親View/ViewControllerを順に配列の要素に加えます。

```swift
UILabel.appearance(whenContainedInInstancesOf: [ViewA.self, SampleViewController.self]).textColor = .red
```

## 優先度
例えば以下のような階層構造の時

```
SampleViewController
┣ UILabel
┣ ViewA
┃ ┗ UILabel
┗ ViewB
  ┗ ViewA
    ┗ UILabel
```

このように設定するとどうなるでしょうか。

```swift
UILabel.appearance().textColor = .brown
UILabel.appearance(whenContainedInInstancesOf: [SampleViewController.self]).textColor = .magenta
UILabel.appearance(whenContainedInInstancesOf: [ViewA.self]).textColor = .blue
UILabel.appearance(whenContainedInInstancesOf: [ViewB.self, SampleViewController.self]).textColor = .red
```

この場合、より外側の要素での指定が優先され、以下のように解決されます。

<img width="352" alt="UIAppearance_demo.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12896/d2ec2354-6932-fdee-47fd-a4f11ab40f54.png">

`ViewA` 上の `UILabel` は `blue` にはならず、
`SampleViewController` 上の `UILabel` を `magenta` にする処理が優先されます。

`SampleViewController` 上の `ViewB` の `UILabel` を `red` にする処理は、指定した順に解決され問題なく実行されます。

# 参考
* [UIAppearance - UIKit | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uiappearance)
Lightning Web ComponentのDatatableでSortする方法_2

# 概要

Lightning Web Componentでプログラミングしている最中にLightning Web ComponentのDatatableを使ってソート機能を実装したい状況が前の記事を書いたが、ソースコード全体を記載し忘れていたので、改めて書く。

## 実演

![olg75-aufqk.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246162/11330b36-2c8c-2630-946b-cda18b9e3799.gif)

## ソース

```html
<template>
    <lightning-datatable data={sorted_data} columns={columns} key-field="id" sorted-by={sorted_by}
        onsort={handle_sort_data} sorted-direction={sorted_direction}>
    </lightning-datatable>
</template>
```

```js
import { LightningElement, track } from 'lwc';

const columns = [
    { label: 'sample1', fieldName: 'sample1', type: 'text', sortable: true },
    { label: 'sample2', fieldName: 'sample2', type: 'date', sortable: true },
    { label: 'sample3', fieldName: 'sample3', type: 'percent', sortable: true },
    { label: 'sample4', fieldName: 'sample4', type: 'currency', sortable: true },
];

const data = [
    { sample1: 'sample3', sample2: '2020-01-10', sample3: 0.784, sample4: 321456 },
    { sample1: 'sample1', sample2: '2020-01-15', sample3: 0.3248, sample4: 3214 },
    { sample1: 'sample5', sample2: '2020-01-20', sample3: 0.321149, sample4: 356 }
]

export default class Qiita_sample_code_2 extends LightningElement {
    @track sorted_data = data;
    @track columns = columns;
    @track sorted_by;
    @track sorted_direction;

    handle_sort_data(event) {
        this.sorted_by = event.detail.fieldName;
        this.sorted_direction = event.detail.sortDirection;
        this.sort_data(event.detail.fieldName, event.detail.sortDirection);
    }

    //実際にソートしてる関数
    sort_data(fieldname, direction) {
        let sorting_data = JSON.parse(JSON.stringify(this.sorted_data));
        // ソートするカラムの値を参照
        let keyValue = (a) => {
            return a[fieldname];
        };
        let isReverse = direction === 'asc' ? 1 : -1;
        sorting_data.sort((x, y) => {
            x = keyValue(x) ? keyValue(x) : '';
            y = keyValue(y) ? keyValue(y) : '';
            return isReverse * ((x > y) - (y > x));
        });
        this.sorted_data = sorting_data;
    }
}
```
zabbix4.4をインストールするもMySQL8.0とつなげることができない

# はじめに
zabbixの学習を始めようと公式ページ通りに進めるものの、エラーが出たので、まとめておきました。

# 環境
zabbix 4.4
mysql 8.0 →　mariadb 5.5
php 5.4
httpd 2.4
centos7

# 問題
zabbixとmysqlが接続されない。
## エラーと出会うまでの流れ
以下の手順を元に進めたものの、ブラウザからのDBの設定画面でエラーが発生。DBと接続できないとのこと。。
https://www.zabbix.com/jp/download?zabbix=4.4&os_distribution=centos&os_version=7&db=mysql&ws=apache

以下サイト（上記サイトを2まですすめた後の設定）のInstalling frontend step3でエラーが発生した。
https://www.zabbix.com/documentation/current/manual/installation/install#installing_frontend

## アプリケーションがMySQL８.0のパスワード認証プラグインに対応していないのが原因
いくつかググってみると、mysql8.0のパスワード認証プラグインがzabbixやphpのアプリケーションに対応していない可能性があるとのこと。
インストールするために、mysqlを削除してmariaDBをインストール。
ブラウザからアクセスすると、今度は、「403 Forbidden」のエラーが発生。。

## zabbix-web-serverがインストールされていなかった。
ブラウザからの設定ができなかった時に、エラーログを開くと以下が表示された。

```
less /var/log/httpd/error_log
----省略----
[Thu Feb 13 21:27:20.625853 2020] [authz_core:error] [pid 8180] [client 172.16.1
00.107:55133] AH01630: client denied by server configuration: /usr/share/zabbix
```

webサーバが/usr/share/zabbixを探していることがわかる
→/usr/share/zabbixのファイルは、zabbix-web-mysqlによって追加されるらいし（社内の方に聞きました）

```
yum list installed | grep zabbix-web-mysql
→　何も出力されず、パッケージがインストールされていないことが確認できた。
yum install zabbix-web-mysql
```

ブラウザからアクセスすると無事403エラーを解消できた！！

# 学び
エラー発生の時は、以下を気をつける！！
・自分が打ったコマンドとドキュメントを確認して、間違っていないかを確認。
・パッケージインストール時は、インストールしたいパッケージと依存関係を必ず確認する。
→removeするときも確認する！

なぜかインストールできなかったパッケージがあったという初歩的なミスでハマってしまった。。
自主学習だと思い、適当にコマンドを打ってしまってたのが、ミスの原因かも。。
次からは同じようなミスがないようにする！！！
Cloudformationでcognitoを作ったときにハマったメモ

またくだらないことでハマったのでメモ。
今思えば、普通に頭悪い。

## やりたいこと
* Cloudformation使いたい
* ALBにCognito組み合わせたい

具体的には
1. ALBを叩きに来たアクセスをCognitoに飛ばしたい
2. Cognitoの認証をパスしたら、ALBの後ろにいるEC2へforwardさせたい


##とりあえずyaml書く。
ALBとCognitoの連携は、`ElasticLoadBalancingV2`の`Listener`で指定。

```
(中略)
  hogeALBLISTENER:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties: 
      #Certificates: 
      #  - Certificate
      DefaultActions: 
        - AuthenticateCognitoConfig: 
              UserPoolArn: "arn:aws:cognito-idp:ap-northeast-1:xxxxx:userpool/hoge"
              UserPoolClientId: "hogeid"
              UserPoolDomain: "https://hoge.auth.amazoncognito.com"
          Type: 
            - "authenticate-cognito"
            - "forward"
          TargetGroupArn: !Ref 'hogeALBTG'

      LoadBalancerArn: !Ref 'hogeALB'
      Port: 443
      Protocol: "HTTP"
```

…これじゃ通らない。
今見ると、書き方がひどすぎる。。。
`「cognitoの認証をパスしたら、targetgroupに向けてforwardして」`を1行で書いて通るわけがない。

## 通る書き方

```
(中略)
  hogeALBLISTENER:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties: 
      Certificates: 
        - CertificateArn: "arn:aws:acm:ap-northeast-1:xxxxxxxx:certificate/hogehoge"
      DefaultActions: 
        - AuthenticateCognitoConfig: 
              UserPoolArn: "arn:aws:cognito-idp:ap-northeast-1:xxxxxxx:userpool/hogehoge"
              UserPoolClientId: "hogehoge"
              UserPoolDomain: "hogehoge.auth.com"
          Order: 1
          Type: "authenticate-cognito"
        - TargetGroupArn: !Ref 'hogeALBTG'
          Order: 2
          Type: "forward"
          
      LoadBalancerArn: !Ref 'hogeALB'
      Port: 443
      Protocol: "HTTPS"
```

ちゃんと段階踏ませる書き方をすれば通る。

1. Cognitoで認証させる → `Order :1`
2. 通ったらtargetgroupへforwardさせる → `Order :2`

リファレンス読んで書いてたけど、あっちこっち飛ばされたらよくわからなくなる…
skpyで、pythonからskypeで通知する！



#インストール
pip3 install SkPy


#初期化
from skpy import Skype
sk = Skype(#ID#, #PASS#)


#相手にメッセージ
c=sk.contacts["相手のID"].chat
c.sendMsg("ハロー")

#グループチャットに送る
g=sk.chats.chat("グループチャットのID")
g.sendMsg("ヘロー、グループ")


#相手のIDやグループチャットのIDを知る
sk.chats.recent()





#webページ
https://skpy.t.allofti.me/usage.html
ぼっち演算子

Deviseを使ったRailsのコードがあるとします。
これはDeviseを使用したときのcurrent_userに対して、nicknameカラムに
あるデータを取得して@nicknameに代入することを意図したものです。

------------

@nickname = current_user.nickname

--------------
ただし、ログインしないときにこれを実行するとnilに対してメソッドを使おうとしてエラーになってしまいます。

これを回避できる記述がRuby2.3からできるようになりました。
それがどのような記述か、またそれはどのような動きをするのかについて説明していきます。



解答
@nickname = current_user&.nickname


&はsafe navigation operator、 lonely operator（ぼっち演算子）などと呼ばれる演算子です。

メソッドに続けて記述すると、そのメソッドがnilでなかった場合のみ右辺のメソッドが実行されます。

もしnilだった場合は全ての演算結果としてnilを返します。つまり@nicknameにnilが代入されます。

とても使い勝手の良い演算子のため、覚えて活用していきましょう。

なお、ぼっち演算子という命名は、&の記号が一人ぼっちで膝を抱えている人に見えるところからきています。


＜参考記事＞
・https://kossy-web-engineer.hatenablog.com/entry/2018/09/20/060701
・https://ja.wikipedia.org/wiki/Null%E6%9D%A1%E4%BB%B6%E6%BC%94%E7%AE%97%E5%AD%90
・https://matt-note.hatenadiary.jp/entry/2018/11/14/083307
Railsのform_forで、bootstrap4を使ってフォームを横並びにする方法

#概要
Railsのform_forを使っている箇所で、フォームを横並びにするのに少しハマったので、共有させていただきます。

#環境
ruby 2.6.3 Rails 5.1.6 bootstrap 4.4.1

##方法
bootstrapのグリッドシステム(rowとcol-*(数字))を使う。
フォームをdiv.rowで囲って、横並びにしたい要素をdiv.col-*で囲む。
（上記少し誤解を与える表現ですが、下記注意点をご参照ください）

##注意点
form_forメソッドの外側でなく、内側にdiv.rowを配置する。

##具体的な方法(OKパターン)
```erb:home.html.erb
<%= form_for(:session, url: login_path) do |f| %>        
  <div class="row">
    <div class="col-2">
      <div class="form-group">            
        <%= f.label :email %>
        <%= f.email_field :email, class: 'form-control' %>          
      </div>
    </div>
    <div class="col-2">
      <div class="form-group">            
        <%= f.label :password %>
        <%= f.password_field :password, class: 'form-control' %>
      </div>  
    </div>
    <div class="col-2 align-self-end">
      <div class="form-group">        
        <%= f.submit "ログイン", class: 'btn btn-primary' %>
      </div>
    </div>
  </div>
<% end %>
```

![スクリーンショット 2020-02-14 10.38.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555201/bb5a80f1-d19e-4f66-3106-307bd435ba95.png)

##ダメなパターン
```erb:home.html.erb
<div class="row">
  <%= form_for(:session, url: login_path) do |f| %>        
    <div class="col-2">
      <div class="form-group">            
        <%= f.label :email %>
        <%= f.email_field :email, class: 'form-control' %>          
      </div>
    </div>
    <div class="col-2">
      <div class="form-group">            
        <%= f.label :password %>
        <%= f.password_field :password, class: 'form-control' %>
      </div>  
    </div>
    <div class="col-2 align-self-end">
      <div class="form-group">        
        <%= f.submit "ログイン", class: 'btn btn-primary' %>
      </div>
    </div>  
  <% end %>
</div>
```
![スクリーンショット 2020-02-14 10.51.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555201/4fd7914b-4106-dd45-c479-22596db9b4f5.png)

以上です。

##その他
Qiitaにちゃんとした(ちゃんとしてますか!?)投稿をするのが初めてでした。
ご指摘あればぜひお願いいたします。
【JavaScript】Vue.js(Element UI)を使用している際に「async-validator」単体で使う場合のカスタムバリデーション実装方法



# 概要
Vue.js([Element (Element UI)](https://element.eleme.io/#/en-US))を使用している場合に[「async-validator」](https://github.com/yiminghe/async-validator)単体で使う実装方法例を少々
# インストール（npm）

[async-validator - npm](https://www.npmjs.com/package/async-validator?activeTab=versions)

```npm
npm i async-validator
```

※筆者は[Element (Element UI)](https://element.eleme.io/#/en-US)（Vue.jsのコンポーネントライブラリ）を使用しているので別途インストールしなくても使える状況ですので単体でインストールしたことはないです

# 実装例

簡単なアカウント登録画面の例として以下のように実装してみました

```form.vue
<template>
    <div class="form">
        <div class="text-center">アカウント登録</div>

        <input type="email" v-model="ruleForm.email" placeholder="メールアドレス*">
        <input type="password" v-model="ruleForm.password" placeholder="パスワード*">
        <input type="password" v-model="ruleForm.passwordConf" placeholder="パスワード（確認）*">

        <div class="text-center">
            <input type="button" @click="beforeSubmit" value="登録">
        </div>

    </div>
</template>

<script>
import schema from 'async-validator';

export default {
	data() {
        // カスタムバリデーション定義する場合はここに記述
        var validatePasswordConf = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('パスワード（確認）を入力してください。'));
            } else if (value !== this.ruleForm.password) {
                callback(new Error('二つのパスワードが異なります。'));
            }
            callback();
        };
		return {
            // フォーム用変数
			ruleForm: {
				email: '',
                password: '',
                passwordConf: '',
            },
            // バリデーションルール定義（項目毎）
            rules: {
                email: [
                    { required: true, message: 'メールアドレスを入力してください。', trigger: 'blur' },
                    { type: "email", message: '正しいメールアドレスを入力してください。', trigger: 'blur' },
                    { min: 1, max: 255, message: '1文字以上255文字以内で入力してください。', trigger: 'blur' }
                ],
                password: [
                    { required: true, message: 'パスワードを入力してください。', trigger: 'blur' },
                    { min: 1, max: 50, message: '1文字以上50文字以内で入力してください。', trigger: 'blur' }
                ],
                passwordConf: [
                    // 上記で定義したカスタムバリデーションを使用
                    { validator: validatePasswordConf, trigger: 'blur' }
                ],
            },
		}
    },
    methods: {
        beforeSubmit() {
            var validator = new schema(this.rules);
            validator.validate(this.ruleForm, (errors, fields) => {
                if(errors) {
                    // バリデーションエラー時
                    return alert(errors[0]["message"]);
                }
                // バリデーションパス
                return alert("登録しました");
            });
        },
    }
}
</script>
```

バリデーションのルール詳細は[「async-validator」](https://github.com/yiminghe/async-validator)のREADMEとかを参考にしてください。

# 参考URL

- [「async-validator」](https://github.com/yiminghe/async-validator)
- [Element (Element UI)](https://element.eleme.io/#/en-US)
- [使用 async-validator 编写 Form 组件 - 掘金](https://juejin.im/post/59f09e135188255f9b339817)
[WordPress] Docker 環境下の wp-cron.php を cron で実行する方法

# WP-Cron(wp-cron.php)とは？
> WP-Cron works by: on every page load, a list of scheduled tasks is checked to see what needs to be run. Any tasks scheduled to be run will be run during that page load. WP-Cron does not run constantly as the system cron does; it is only triggered on page load. Scheduling errors could occur if you schedule a task for 2:00PM and no page loads occur until 5:00PM.

> WP-Cronは次のように機能します。ページをロードするたびに、スケジュールされたタスクのリストをチェックして、実行する必要があるものを確認します。実行がスケジュールされているタスクは、そのページのロード中に実行されます。 WP-Cronは、システムcronのように常に実行されるわけではありません。ページの読み込み時にのみトリガーされます。午後2時のタスクをスケジュールし、午後5時までページの読み込みが行われない場合、スケジューリングエラーが発生する可能性があります。

> https://developer.wordpress.org/plugins/cron/#why-use-wp-cron

WordPress のコアファイルの一つの wp-cron.php はアクセストリガーで実行します。その結果、トラフィックが少ないサイトだと正しく予約投稿が動作しない問題が発生します。

そこで、アクセストリガーの cron である WP-Cron を停止して、Docker コンテナ内で cron が動作するようにしました。

以下、備忘録です。

# 概要
### 1. アクセストリガーの WP-Cron を停止
### 2. Docker 環境下で cron が動作するように設定
### 3. wp-cron.php を 1 分に 1 回のペースで叩くスケジュールを登録

# やったこと

## WordPress
```php

define('DISABLE_WP_CRON', 'true');
```

## Docker
```bash

apt update
```

```bash

apt install cron
```

```bash

apt install vim
```

```bash

export EDITOR=vim
```

```bash

/usr/sbin/cron -f &
```

```bash

crontab -e
```

```bash

*/1 * * * * /usr/local/bin/php /var/www/html/wp-cron.php
```

```bash

:wq!
```
ルーティングを設定してCSVデータのダウンロード(出力)を実装する方法

# 目的 
- Qiitaの記事に大まかな流れをテンプレート化しておき、作業効率を上げる。
- 今までの実装では `send_data` しか使ったことなかったのでメモ

# 前提条件
- ruby 2.6.0 
- ruby 5.2.2

# 手順

1. routes.rbにCSVダウンロード用のルーティングを設定する
2. コントローラーに変数を定義、その他諸々を設定
3. 出力データを作成(アクション名.csv.ruby)
4. CSVダウンロードボタンを設定したいviewファイルに書く

※コード内容は適当


## 1. routes.rbにCSVダウンロード用のルーティングを設定する

```ruby:config/routes.rb

resources :card_infos do
  collection do
    # デフォルト形式をcsvに設定
    get :csv_download, defaults: { format: 'csv' }
  end
end
```

|Helper|HTTP Verb|Path|Controller#Action|
|----------|----------|----------|----------|
|csv_download_card_infos_path|GET|/card_infos/csv_download(.:format)|card_infos#csv_download {:format=>"csv"}|







## 2. コントローラーに変数を定義やその他諸々を設定

```ruby:app/controllers/card_infos_controller.rb
class CardInfosController < ApplicationController
  def csv_download
    @cards = CardInfo.all

    # CSVダウンロードファイルのヘッダーを生成する
    create_csv_file_header("card_info_#{ Time.zone.now.strftime('%Y%m%d') }")
  end
end
```

```ruby:共通化メソッド
  # CSVダウンロードファイルのヘッダーを生成する
  def create_csv_file_header(file_name)
    file_name = ERB::Util.url_encode(file_name) if (/MSIE/ =~ request.user_agent) || (/Trident/ =~ request.user_agent)
    headers['Content-Disposition'] = "attachment; filename=\"#{file_name}.csv\""
  end
```

## 3. 出力データを作成(アクション名.csv.ruby)

<font color="Red">※viewディレクトリ配下に設置する</font>

```ruby:app/views/card_infos/csv_download.csv.ruby
require 'csv'

columns = %w(
  番号
  会社
  子会社
  カード種類
  カード会社
  管理区分
)

# encoding等のoptionは仕様によって変えてください
CSV.generate(encoding: Encoding::SJIS, row_sep: "\r\n", force_quotes: true) do |csv|
  csv << columns
  @cards.each_with_index do |card, number|
    csv << [
      number + 1,
      card.company.parent_company.company_name,
      card.company.company_name,
      card.card_type.card_type_i18n,
      card.card_type.card_company.card_company_name,
      card.management_type_i18n,
    ]
  end
end
```

## 4. CSVダウンロードボタンを設定したいviewファイルに書く

```erb:（例）app/views/card_infos/index.html.erb
<%= link_to csv_download_card_infos_path, class: "btn_blue btn_big csv_dl", download:"", style: "padding: 8px 25px; font-family: Arial;" ) do %>
  <i><img src="<%= asset_path 'icon_download.svg' %>" alt="CSVダウンロード"></i>CSVダウンロード
<% end %>
```

## 📂🌲変更するファイル

```bash
.
├── app
｜   ├── controllers
｜　 ｜　　　｜　　
｜　 ｜　　　└── card_infos_controller.rb ②アクションを設定
｜　 ｜
｜　 ｜
｜　 ｜
｜   └── views
｜　 　　　　｜　　
｜　 　　　　└── card_infos
｜　 　　　　　　　　　｜　　
｜　 　　　　　　　　　└── csv_download.csv.ruby　③出力ファイルを設定
｜
｜
├── config
｜　 　　｜　　
　 　　　└── routes.rb ①ルーティングを設定


④ViewファイルにCSVダウンロードボタンを設置
```


# 関連URL
[send_dataでの日本語ファイル名文字化け対策(IE11対応)]
(https://qiita.com/hi-nakamura/items/ed48a17f86051c2d0061)
[【簡単3ステップ】RailsでCSV出力する方法](https://qiita.com/ngron/items/60915083cb2bc3622c79)
🐈【GitHub】ブラウザからプルリクのファイルを再度編集しようとしてもできないときの対応

## 環境
GitHub

## やりたいこと
GitHubにてPull Requestを出し、再度ファイルを編集しようとした際に鉛筆アイコンをクリックしようとすると下記文言が表示されて編集できない

```
You must be on a branch to make or propose changes to this file
```

![band_top1 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188242/88c840b1-020e-dc1b-e48c-35db6d3425ce.png)


## やったこと

右上にあるTree:[コミット番号]をクリックして対象のブランチに変更

![band_top1 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188242/1bac7e23-5494-3c31-146d-91e9f188800b.png)

↓

編集可能
[Rails] scriptタグ内でRuby/Railsのメソッドを使用する際のescape_javascriptについて

## この記事を書くきっかけ

jQueryを書いていると、scriptタグ内でRailsのメソッド（正確にはapplication_helper内のメソッド）を使用したいときがあります。
正しい書き方をしないと正確に呼び出せないため、失敗した書き方と成功した書き方をまとめます。


## 前提

current_userの属性によってpathを切り替えるメソッドを
`def hogehoge_path_for`とし、application_helper.rbに定義します。

```ruby:application_helper.rb
def hogehoge_path_for
  if ...
   hoge_path
  else
   hogehoge_path
  end
end
```

これをとあるviewのscriptタグ内で呼び出します。
`let path = hogehoge_path_forの返り値`
としたいです。

## 失敗例1


```erb:あるview
<script>
  let path = <% hogehoge_path_for %>;
</script>
```

普通はこう考えるはずですが、これだと呼び出せません。

## 失敗例2
```erb:あるview
<script>
  let path = <% hogehoge_path_for %>;
</script>
```

これも呼び出せません。

## 失敗例3

`escape_javascript`というメソッドを使用します。
なお、これはaliasとして`j`の使用が許されています。

```erb:あるview
<script>
  let path = <% escape_javascript hogehoge_path_for %>;
</script>
```

上記は下記と同じです。

```erb:あるview
<script>
  let path = <% j hogehoge_path_for %>;
</script>
```

どちらも失敗します。

## 失敗例4
=をつけます。

```erb:あるview
<script>
  let path = <%= escape_javascript hogehoge_path_for %>;
</script>
```

上記は下記と同じです。

```erb:あるview
<script>
  let path = <%= j hogehoge_path_for %>;
</script>
```

これもどちらも失敗します。


## 失敗例5
=を外して、`''`で囲います。

```erb:あるview
<script>
  let path = '<% escape_javascript hogehoge_path_for %>';
</script>
```

上記は下記と同じです。

```erb:あるview
<script>
  let path = '<% j hogehoge_path_for %>';
</script>
```

これもどちらも失敗します。



## 成功例
<b>`=`をつけて`''`で囲います！</b>

```erb:あるview
<script>
  let path = '<%= escape_javascript hogehoge_path_for %>';
</script>
```

上記は下記と同じです。

```erb:あるview
<script>
  let path = '<%= j hogehoge_path_for %>';
</script>
```

<br>

これで無事呼び出すことができました。
エンジニア志望動機を考える　未経験　面接対策

#はじめに...

未経験でエンジニアの志望動機について考えていきたいと思います。
特に未経験からIT転職を目指す場合、「なぜIT業界を選んだのか」を明確にする必要がある！
そこが難しい...
皆さんの参考になればと思います！！

##1.なぜIT業界（エンジニアに）転職したいのかを明確にする

＊例＊
####「IT技術で世の中を便利にするエンジニアに魅力を感じた」


1.前職での経験からどのような課題、問題があったか、それによりどんな人が、どんな風に困っているのか。

2.そのような課題、問題点がIT技術、システム、アプリケーションがどのように改善、解決したか。

3.そのような経験、きっかけなどから...~に魅力を感じた。

4.そのような課題を解決することでどんな人にどんな風になってほしいのか。

5.自分自信がどのようなエンジニアになりたいのか。

####＊ポイント＊
志望理由に根拠があれば説得力がまします

##参考サイト
https://yukituna.com/1513/
##2.その中でもなぜ該当企業なのかを明確にする

・業界への志望度の高さを伝えることも大切ですが、該当企業への志望度の高さを伝えることも大切です、企業の情報を含めてアピールする

・その企業でしかできないこと、その企業ならではの強みに触れながら仕事がしたい、志望度の高さをアピールすることができる。

・企業研究ができていることも同時にアピールできますので、該当企業ならではの情報を含めてアピールする。


##3.自分がどのように貢献できるかを伝える
＊例＊ ***エンジニアに求めらる人材像（コミュニケーション能力、マネージメント能力）***

御社ではこのような業務、仕事内容で、プログラミングスキルだけでなく、コミュニケーションスキルやマネジメントスキルが重要と伺いました。私のこれまでの前職での経験で培ったコミュニケーション能力やマネージメント能力を、貴社で貢献できると思います。

##最後に
未経験は必ず聞かれる質問です！
だからこそ、自分自身の本音、思いをしっかりと伝えることが重要かと思います。
Cognitoのトークンと有効期限について

# Cognitoから発行されるトークン
Cognitoからは以下3つのトークンが発行されます。

## IDトークン(IDToken)
Cognito User Poolsのユーザー属性(例えばメールアドレスなど)を含めたトークンです。
ユーザーに関する情報をすべて取得したい場合に使用します。
`APIGatewayではこのトークンを使用します。`

**有効期限**
ユーザーが認証した`3600秒後(1時間後)`に有効期限切れになります。

## アクセストークン(AccessToken)
Cognito User Poolsの最低限のユーザー情報を含めたトークンです。

**有効期限**
ユーザーが認証した`3600秒後(1時間後)`に有効期限切れになります。

## 更新トークン(RefreshToken)
IDトークン、アクセストークンを更新するために利用します。
Cognito User PoolsのクライアントSDKを利用している場合は自動で更新されるようです。

**有効期限**
デフォルトではアプリのユーザーがユーザープールにサインインしてから`30日後`に有効期限が切れます。
有効期限は`1日～3650日`の任意の値に設定できます。

#有効期限について
ユーザ認証には基本的に`IDトークン`を使用します。
IDトークンは1時間後に有効期限切れとなり、有効期限が切れたら`更新トークン`を使用して新しいIDトークンを発行します。

※クライアントSDKを使用している場合は更新トークンによって自動的にIDトークンが更新されるようです。


`更新トークン`はデフォルトで30日後に有効期限切れとなり、有効期限が切れたら`サインイン`が必要となります。