OmniAICreator/Qiita-1.07M huggingface dataset:
OMCのセキュリティを強化する

ここでは、認証を強化することで、OMCのセキュリティを向上させる方法をご紹介します。

OMCは、Oracle CloudのIDCS(Oracle Identity Cloud Service)で認証されています。このIDCSは、Oracle Cloud Infrastructureのコアな機能として提供されており、多要素認証やIPアクセス制御などの認証周りのセキュリティを強化する様々な機能を持っています。

このIDCSの機能を利用することで、特定のIPアドレスからしかOMCをアクセスできないように制限し、かつ、従来のパスワードだけでなくモバイルアプリでのニ要素認証に変更することで、OMCへのアクセスを強化しセキュリティを高めます。

以下からは実際の設定例です。

- Oracle CloudのコンソールからIDCSの管理画面に移動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/53d64612-3ff3-c9b2-e54e-da8b6cfb70cd.png)

- セキュリティ -> MFAを選択し、モバイルアプリケーションをチェックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/078b9da9-df49-aa63-f948-7473d895bd19.png)

- ネットワーク・ペリメータを選択し、追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/fef30a4e-1bc5-6473-43ed-c8696da16a3c.png)

- 許可するIPアドレスのリストを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/4c88834a-9fae-23f5-4593-d77cca66b530.png)



- サインオン・ポリシーを選択し、追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/02860844-bd35-07b1-7fcc-16c3f8db898f.png)

- 赤枠の内容に応じて、ルールを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b402bb1f-61a0-6aef-5244-1148298cc6dd.png)

- アプリケーションの割り当ては、対象のOMCインスタンス(OMCEXTERNAL_インスタンス名)をチェックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/91fb1b54-839e-475b-359f-185cb053a6a4.png)

- 作成したサインオン・ポリシーのアクティブにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/5cb02724-79fe-3228-3efd-5b18fa20fe3f.png)

- OMCにログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/bf69fc81-99a7-3f78-8f31-61b2f24c55a5.png)



- パスワードチェック後に、2ステップ認証の有効化が求められる。画面に従ってモバイルアプリケーションをインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/ef7f2820-e812-2ac9-0211-6a9f092075c0.png)

- モバイルアプリケーション側の認証許可待ち画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b202da8f-2b80-6dfa-8b06-da3e7f9af269.png)

- モバイルアプリの許可をクリックするとログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b0700e4a-62fa-3183-1d3d-aa6f397285a5.png)



今回はモバイルアプリケーションを使用しましたが、SMSやメールへのアクセスコード送信など、従来のパスワード認証に追加することで認証を簡単に強化することができます。

ひとつ注意事項としては、IDCSのMFA(マルチ・ファクタ認証)の機能は、IDCSのStandardの機能となるため利用は有償となります。詳しくは、[IDCSのドキュメント](https://docs.oracle.com/cd/E83857_01/paas/identity-cloud/uaids/oracle-identity-cloud-service-pricing-models.html#GUID-05F56DF0-0F71-436C-A103-3A10AEB38650)でご確認下さい。
いまさらのMFC

# MFCの選択

C++でWindowsの処理をするのにC++/Cliとか、C++/CXとか、C++/WinRXとかついていけないし、ハードウエア周りの処理なので、MFCでとりあえず実装することにする。
C++のDLLにして、C#でGUI実装のほうが簡単だけど、ちょっと理由があってC++ですべて作成しないといけない。
MFCのUI部と、ハードウエア周りのコードは別にして、ハードウエア周りは標準のC++で作成したいものです。
C++は最新の文法を使いたい。しかしWin32がwchar_tなので、std::stringとうまく調和しない。いろいろ変換をいれる必要がある

## std::string 周りの対応

ハードウエア側はstd::stringでデータを取得するが、MFCのUIに表示するときは、whar_tに変換しないといけない。Windowsの設計思想が20年前ですからね。

MFCのCStringAとCStringを使って変換するのが簡単らしい。

```
std::string str = "ABCDE";
CStringA str2(str.c_str());
CString str3(str2);
```

エンコードがUTF-8の場合はこの方法ではうまくいかず、MultiByteToWideChar()関数で変換する必要があります。

## スレッド

_biginthread　などの、Windowsのローカルなスレッド関数は引数が多すぎて理解できないので、std::threadを使用したい。
ただ、メインスレッドでUIをコントロールしないといけないので、メインスレッドにメッセージを送る必要があります。
ワーカースレッド側から、postMessage関数にてWindowsのメッセージをポストし、メインスレッドのメッセージキューから独自のメッセージを処理するメソッドを設定してそちらでUIの更新をおこなうことにします。

### Windowsメッセージの定義

ユーザー定義のメッセージを準備します。

```SampleDialog.cpp
#define WM_SAMPLEMSG (WM_APP + 1)
```

それを取得するメッセージマップをMFCのマクロに追加します。
OnStart とOnStopでスレッド開始、停止をできるようにします。

```SampleDialog.cpp
BEGIN_MESSAGE_MAP(SampleDialog, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_START, &SampleDialog::OnBnClickedButtonStart)
	ON_BN_CLICKED(IDC_BUTTON_STOP, &SampleDialog::OnBnClickedButtonStop)
	ON_MESSAGE(WM_SAMPLEMSG, SampleDialog::OnMessage)
END_MESSAGE_MAP()
```

OnMessageメソッドをヘッダに追加

```SampleDialog.h
Class SampleDilaog : public CDialogEx
{
///省略

//追加
public:
    LRESULT OnMessage(WPARAM w_param, LPARAM l_param);
    volatile bool run;
    std::thread th;

};
```

OnBnClickedButtonStart　OnBnClickStop実装

```SampleDialog.cpp

void SampleDialog::OnBnClickedButtonStart()
{
   run = true;
   th= std::thread([&]() -> void {
       while(run){
          //ハードウエアから何かデータが来る。
          if(something) {
             //ヒープに割り当てる
             std::string *ptr = new std::string("aaaa");
             PostMessageW(WM_PHOENIXMSG, 0,(LPARAM) ptr);
          }
       }

   });
}

//スレッド停止
void SampleDialog::OnBnClickedButtonStop()
{
   run = false;
}


```

OnMessageをソースコードに追加
ヒープの文字列データを取得して、リストビューに追加


```SampleDialog.cpp
LRESULT SampleDialog::OnMessage(WPARAM w_param, LPARAM l_param)
{
    std::String * data = (Std::String*)l_param;
    CStringA dataA = CStringA(*data.c_str());
    CString dataB = CString(dataA);
    listTag.InsertItem(0,dataB );

    delete data;

	return 0;
}
```

コードを実行すると、スレッドからUIへデータが受け渡されます。
2020/6/25 これまでのプログラミング学習　独学

## これまでの学習
### 3月・4月　progate
・HTML&CSS 初級・中級・上級
・Ruby
・Ruby on Rails
・SQL

「そもそもプログラミングって何？」という疑問を解決するために、progateから始めた。

### 5月　ドットインストール
・HTML＆CSS　復習
・JavaScript　メイン

ここから本格的にプログラミング学習を開始した時期、動画を使った方が自分には合っているなと実感した。

### 6月　上旬
基礎学習を終え道に迷う

### 6月　中旬・下旬　（これを書いてる最中）
Udemyの教材を使って基礎学習の深掘りをする。
＋
同時並行で模写コーディング・自分が作ってみたいと思ったサイトを作ってみる
（Udemyで学んだことを生かせるような内容で）
＋
Qiitaを使ってその日の学習内容を記録する。

Qliitaを利用するきっかけとして、3月から6月上旬までインプットばかりしていたので、アウトプットする機会を少しでも増やそうと思ったから。
模写コーディングもアウトプットの一貫。

##環境構築

ドットインストールで使用していたものを継続して使い続けている。
・Google Chrome（ブラウザ）
・Visual Studio Code（コードエディター）
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

##今後の学習内容と流れ

Udemyでインプットしながら、Qiitaにアウトプットする。
（これを主軸）
仕事でHTMLとCSSを使うので、復習も兼ねてHTML＆CSSから開始し、Qiitaに学習メモを残す。

模写コーディングに関して、自分のアイデアでCSSを書いた後に、CSSのフレームワークであるbootstrapを使ったコーディングもやってみる。

## 最後に
プログラミング独学自体は1年以内に終えることを目標とし、継続することに重きを置きながら頑張る。
[超超易しい] クラウドコンピューティング周りのこと（AWS寄り）

仕事で、AWS,EC2,EKS・・・という単語が出てきて何やらわからず、さっと調べた時のメモ

# AWSって？
Amazon Web Service
Amazonが提供するクラウドコンピューティングシステムです

MicrosoftやGoogleもクラウドコンピューティングシステムを提供していますが、その中でもAWSは高いシェアを誇り、高いシェア率=利用者が多いという図式のもと、情報が豊富に出揃っています

[【EC2ってなに？】初心者でもわかる簡単 AWS 用語解説](https://www.wafcharm.com/blog/ec2-for-beginners/)

# EC２とは？
Amazon Elastic Compute Cloud
AWSで利用できるシステムの一つ

このシステムを使うことで、AWS上に仮想サーバーを構築し利用することができる
この仮想サーバーの単位をEC2では「インスタンス」という単位で扱います
EC2インスタンス上でコンテナを動かします

[【EC2ってなに？】初心者でもわかる簡単 AWS 用語解説](https://www.wafcharm.com/blog/ec2-for-beginners/)

## 似たような機能を持つものでFragateがある
AWSがインスタンスを管理してくれる方式で、読み方は「ファーゲート」です
裏にあるリソースを気にすることなく、コンテナを登録するだけで利用できます

# EKSとは？
Amazon Elastic Kubernetes Service
AWSでKubernetesを簡単に実行できるようにする

[Amazon EKSとは](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/what-is-eks.html)

## じゃあKubernetesって？
複数のコンテナの管理と自動化をするオープンソースのシステム
クバネティス、またはクーベネティスなどと読む（ギリシャ語で操舵手やパイロットという意味）

Dockerにも複数のDockerの管理や自動化をする機能があるが、コンテナ間の設定や管理でできないことがあるため、小規模向け。規模が大きくなると煩雑になるため、Kubernetesのような専用ツールを利用する。

[Kubernetesとは？仕組みと構造をわかりやすく解説します](https://www.kagoya.jp/howto/rentalserver/kubernetes/)

# 似たような機能を持つものでECSがある
Elastic Container Service
Amazonが開発したコンテナ管理サービス

### ちなみにDockerというのは、 
1台のサーバー上に、複数のサーバーとして利用できる仕組みを構築する方法を仮想化技術といい、それを支える手段には種類があり、ハイパーバイザー、ホスト型、コンテナ型が公開されている
Dockerというのはコンテナの種類の一つ
他にはVirtual machineなど

[【入門】Dockerとは？使い方と基本コマンドを分かりやすく解説します](https://www.kagoya.jp/howto/rentalserver/docker/)

# 資料
![スクリーンショット 2020-06-25 14.42.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570918/42a6d34d-0a24-07c5-5d35-609c4d6bef59.png)
[Kubernetesとは？仕組みと構造をわかりやすく解説します](https://www.kagoya.jp/howto/rentalserver/kubernetes/)


# 参考
[サーバー構築と設定 ～初心者にも分かりやすく解説～](https://xn--o9j8h1c9hb5756dt0ua226amc1a.com/?p=2025)
次元数の異なる配列のコピー

```C#
float[,] src = { {  0, 0, 0 },
                 { -1, 0, 1 },
                 {  0, 0, 0 },
};

var dst = new float[9];

Buffer.BlockCopy(src, 0, dst, 0, Buffer.ByteLength(dst));

Console.WriteLine(Dump(dst, new List<int>()));
```
結果：
[ 0, 0, 0, -1, 0, 1, 0, 0, 0 ]
IBM CloudのEメール配信サービス（SendGrid）でInbound Parse Webhookを使用するにはFree PackageまたはEnterprise Packageを使う必要がある

IBM CloudのEメール配信サービス（SendGrid）にはInbound Parse Webhookという機能があり、受信メールをWebhookで飛ばすことができますが、これを使用するには無料プラン（Free Package）またはEnterprise Packageでないとだめということです。

有料でもBasic Packageなどでは設定画面でこのようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/542857fa-c887-fe84-c154-5806a4f76d43.png)

利用の際はご注意を。
【Nuxt】WARNING in asset size limit: The following asset(s) exceed the recommended size limit を対処する

## Buildしたらvendors.appのサイズが大きすぎた

```terminal
vendors.app.347b3bb.js    612 KiB       6  [emitted] [immutable]  [big]  vendors.app

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
  vendors.app.347b3bb.js (612 KiB)
```

このようなwarning

## nuxt.configにmaxAssetSizeを設定してのりきる

700KiBまでは大丈夫にする

```js:nuxt.config.js
...
  build: {
    /*
    ** You can extend webpack config here
    */
    extend (config, ctx) {
      config.performance.maxAssetSize = 700 * 1024
    }
  }
...
```

おそらくvendors.appの容量を減らす方法を検討すべきだと思いますが、
今の所はこれでのりきりました。
Spring Bootの高速化について

AWS Lambdaなんかで使う場合は意味あるかも。

https://www.slideshare.net/AmazonWebServicesJapan/serverlessjava-199195000

ポイントは
- (身も蓋もないけど)Springは使わない。
- GraalVMはまだ時期尚早だと思うが、チャレンジする？
- Micronautも使ったことないけどチャレンジする？

https://qiita.com/tshk_mtsys/items/f30ae44e6d644691deda
https://spring.io/blog/2020/06/10/the-path-towards-spring-boot-native-applications

でもまあこれやるくらいなら、golangやPythonのほうがまだ出来そうな気がする。
2020/10にリリースするSpringFramework5.3では正式にGraalVMのNativeImageサポートするらしいけど。今のところ実験版しかなさそう。

https://www.slideshare.net/apkiban/graalvm-native-image-spring-boot
https://qiita.com/tkani/items/37878d268db54d581a1b
Rails6のJavasqriptとJ.Queryの取り扱い方法

##概要
Rails6からJS周りの取り扱いが大きく変わったようなので、
JavascriptとJ.Queryの取り扱いについてまとめました。

##概念
まずRailsではブラウザにJ/Sファイルの内容を表示するときには、
基本的にwebpackで複数のJ/Sファイルコンパイルして出力するという流れがあります。

##Rails6におけるJavasqriptの使用方法
Rails6では下記のjsに参照を書き込む事でコンパイル対象のモジュールを追加できる。
app/javascript/packs/application.js

コンパイルされたjsは、下記のタグヘルパーを記載する事でscriptタグが記載される。

`javascript_pack_tag`

デフォルトでは共通レイアウト(※)に書かれていて、全てのページにこれが読み込まれるようになっている。

```javascript:app/views/layout/application.html.erb

<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
```

##実際作成したJ/Sファイルを仕込む方法
`application.js`に参照を追加する事でコンパイル対象にする。
app/javascript以下の任意のディレクトリもしくは直下にjsを作成する。`
(※packs以下に作らない事。)`

```javascript

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
 
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
 
// 追加
require ('user/sample')
 
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
```

##Rails6でjQueryの導入方法

`ターミナル`

```
$ yarn add jquery
```

```javascript:webpacker/environment.js
const { environment } = require('@rails/webpacker')

#追記
const webpack = require('webpack')
environment.plugins.prepend('Provide',
    new webpack.ProvidePlugin({
        $: 'jquery/src/jquery',
        jQuery: 'jquery/src/jquery'
    })
)
#ここまで

module.exports = environment
```

```javascript:app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery') #追記
require("J/Sファイル名")#実際に読み込むファイル
```
【Swift】一度だけ実行したい処理の書き方

何回も呼ばれるメソッドで1度だけ行いたい処理の記述方法をまとめました。
やり方はたくさんありますが、これが1番私的には使いやすかったです。

## 1番簡単な方法

```swift
class OnceTrackerSample1 {
    var isFirst = Bool

    func manyCalledFunc() {
        if !isFirst { return }
        // 1回のみ行いたい処理 
    }
}
```
1番最初に全ての人間が思いつきそうな処理。
やっぱりダサいので、使い勝手よくカッコよく書きたい。

## DispatchQueueを拡張して使いやすくする
`DispatchQueue`を`extension`します。

```swift
private static var _onceTracker = [String]()

class func once(token: String, block:()->Void) {
    // 排他制御
    objc_sync_enter(self); defer { objc_sync_exit(self) }
    // token: Stringで一意に実行状況を管理しています
    if _onceTracker.contains(token) { return }

    // 実行履歴を残して、block:()->Voidで渡された処理を実行
    _onceTracker.append(token)
    block()
}
```
使う側はこんな感じです。

```swift
class OnceTrackerSample1 {
    func manyCalledFunc() {
        DispatchQueue.once(token: "key name") {
            // 1回のみ行いたい処理 
        }
    }
}
```
スマートでいい感じ！
`String`の`key`はどこかでまとめて管理したらより使いやすそう。
Windows コマンド プロンプトでcopy&pasteを有効にするために

コマンド プロンプトで
![command_prompt1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136761/44f1f6a5-7c68-3aa9-57a7-9a244be782b0.jpeg)

![command_prompt2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136761/c2a55f56-6ac1-fc0f-f098-961e0eda7ae2.jpeg)

以上
【バリデーション】rails 今日の日付以降を指定する方法

##【ゴール】
日付入力の際に、今日以降の日付しか入力できないように
バリデーションをかける


##【メリット】
■　UXの向上
■　validate理解度向上


##【開発環境】
■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7

##【実装】

※任意のメソッド名でvalidateを作成
※メソッドの処理を追記
　①「return if start_day.blank?」　で空かどうか判断
　②「if start_day < Date.today」で今日の日付を取得 & 条件分岐　＆　比較
　③「errors.add」でエラー文もついでに定義
　

```model/item.rb



validate :date_before_start
validate :date_before_finish



  def date_before_start
    return if start_day.blank?
    errors.add(:start_day, "は今日以降のものを選択してください") if start_day < Date.today
  end

  def date_before_finish
    return if finish_day.blank? || start_day.blank?
    errors.add(:finish_day, "は開始日以降のものを選択してください") if finish_day < start_day
  end

```

以上！！

##【合わせて読みたい】
■RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い
https://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c

■ 【ERROR メッセージ表示】rails 部分テンプレートでいつでも使える　簡易版
https://qiita.com/tanaka-yu3/items/63b189d3f15653cae263

■ 【Date.today】 今日だけの情報を取り出す方法　rails
https://qiita.com/tanaka-yu3/items/741711bd743b80eda51a
【解決方法】PowerShell スクリプトを実行するとエラーが発生する

## はじめに

- 今回この記事を書こうと思ったのは、前回投稿した[【感想】Vue.js & FirebaseでTwitterライクなSNSアプリを作ろう](https://qiita.com/Glint_No95/items/755379c3e67251d517c8)でタイトルにあるようにエラーが発生してfirebaseにログイン出来なくてデプロイの際に困ったからです。

- 同じようにこのエラーで自分のように躓く方もいる可能性があると思ったので投稿することにしました。

## 実際に起こったエラー
``` :PowerShell
PS C:\example> firebase login
firebase : このシステムではスクリプトの実行が無効になっているため、ファイル C:\example\firebase.ps1 を読み込むことができません。
詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ firebase login
+ ~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
```

## エラーの原因

- デフォルトの設定ではスクリプトの実行が許可されていないことが原因でした。

## エラーの解決方法

- 実行ポリシーを変更してスクリプトの実行を許可してあげることが必要でした。

``` :PowerShell

Get-ExecutionPolicy //これで今どの権限が設定されているのかを確認できます。

PowerShell -ExecutionPolicy RemoteSigned firebase login
//このコマンドで私の場合は解決することが出来ました。

```

- 以下に実行ポリシーの設定値を書いておきます。

| 実行ポリシー | 説明 |
|:-:|:-- |
| Restricted  | スクリプトの実行禁止。 |
| RemoteSigned  | ローカルの署名なしスクリプトと、インターネットからダウンロードした署名付きのスクリプトのみ実行可能。 |
| AllSigned  | 署名付きのスクリプトのみ実行可能で、インターネットからダウンロードした署名付きのスクリプトは実行不可。  |
| Bypass  | 警告やユーザへの確認無しで全てのスクリプトが実行可能。 |
| Unrestricted  | Bypassと同じく全てのスクリプトが実行可能だが、インターネットからダウンロードしたスクリプトは実行するかどうかを確認される。  |

## 参考サイト

- エラー解決の際に以下のサイトを参考にして解決しました。

[WindowsでPowerShellスクリプトの実行セキュリティポリシーを変更する](https://www.atmarkit.co.jp/ait/articles/0805/16/news139.html)

[[PowerShell]スクリプトを実行すると「このシステムではスクリプトの実行が無効になっているため、ファイル *スクリプトファイル名* を読み込むことができません。」エラーが発生する](http://www.curict.com/item/d1/d1c4a3e.html)

[PowerShell のスクリプトが実行できない場合の対処方法](https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750)

## 最後に
今回デプロイの際に躓いたエラーを記事にしてみました。
難しいエラーではなかったので数分で解決したので良かったです。
エラーが発生して解決した時に「まだまだ知らないことが沢山あるな…」としみじみ思います。
次回以降勉強していてエラーで躓いたりした部分も記事にできる部分は記事にしていこうと思います。
Can't open /home/laradock/.nvm/nvm.sh　がでたとき

/etc/hosts に以下を追記
（具体的なIPアドレスはhttps://githubusercontent.com.ipaddress.com/raw.githubusercontent.com　ここで調べられる）

199.232.68.133 raw.githubusercontent.com

Windowsユーザの場合は、ローカルにあるhostsファイルも編集が必要

C:\Windows\System32\drivers\etc\hosts
Windows 10 ProにDocker Desktop (+ Kubernetes) をインストールする

# 対応するDockerのバージョン
- Docker Desktop 2.0.0.0-win81

下記の手順は最新のインストール手順とは異なっている可能性があります。

# Docker Desktop for Windowsのシステム要件
Docker Desktop for Windowsは、Microsoftの仮想化テクノロジーであるHyper-Vを利用します。
そのためWindows Homeエディションや古いバージョンのWindowsはサポートされません。

Docker公式ページに提示されているDocker for Windowsのシステム要件は次の通りです。

- Windows 10 64bit版のPro、EnterpriseまたはEducation（1607 Anniversary Update, Build 14393またはそれ以降）であること
- BIOS設定で仮想化テクノロジーが有効になっていること
- CPUがSLAT（メモリ管理の仮想化）をサポートしていること
- 少なくとも4GBのメモリーが利用できること

Hyper-Vを有効にすると、VirtualBoxなど他の仮想化テクノロジーを利用するアプリケーションが利用できなくなります。導入には十分注意してください。

なお、システム要件を満たさないWindowsでKubernetesを試したい場合には、Minikubeを利用する方法もあります。Minikubeは、Hyper-Vの他にVirtualBoxをサポートしています。詳細については次のURLを参照してください。

https://kubernetes.io/docs/tasks/tools/install-minikube/

# インストール手順

(1) Docker Hubからダウンロードしたインストールイメージ（ `Docker Desktop Installer.exe` ）をダブルクリックします。

(2) "ユーザーアカウント制御"のダイアログが表示されるので[はい]ボタンをクリックします。

(3) "Configuration"画面で[Ok]ボタンをクリックします。

<img width="530" alt="01-configuration.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/5c694fc0-38cc-88ee-d966-03a607ce528b.png">

(4) インストールが成功すると"Installation succeeded"と表示されるので[Close and log out]ボタンをクリックします。この際、Windowsのデスクトップから自動的にサインアウトするので、あらかじめ起動中のアプリケーションを終了しておいてください。

<img width="530" alt="02-installation-succeeded.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/f8ddec5b-f7fc-924b-070e-c83393b2bd7e.png">

(5) 再度デスクトップにサインインします。Hyper-Vが有効になっていない場合には、次のダイアログが表示されるので[Ok]ボタンをクリックしてコンピューターを再起動します。

<img width="517" alt="03-Hyper-V-confirm.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/ea42a13d-0c8a-ed76-52a8-e2f6ff1ef4a8.png">

(6) 再起動後、デスクトップにサインインするとログインダイアログが表示されます。

<img width="268" alt="04-login.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/425fc053-9853-7754-13d4-26ce890d647b.png">

(7) 事前に登録したDocker IDでログインします。

(8) インジケーターのDockerのアイコンの点滅が終わるまでしばらく待ちます。

# Kubernetesの有効化（必要に応じて）

以下の手順は、Docker内にKubernetesの環境を作りたい場合のみ実行してください。

(1) 点滅が終わったら、タスクバーのDockerのアイコンのをクリックし[Settings]を選択します。

<img width="393" alt="05-task-bar-menu-docker.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/f142d6f1-f58c-7174-e4a7-5db60d333944.png">

(2) "Kubernetes"タブに移動し、[Enable Kubernetes]にチェックを入れ[Apply]ボタンをクリックします。（インストールが完了するまでしばらく時間がかかります）

<img width="625" alt="06-enable-kubernetes.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/52fe4af7-1101-ebdc-1727-e68372a7bf16.png">
Ansible: shellモジュールで実行された複数行にわたるコマンドを改行された状態で表示


## 要望
shellモジュールで実行された複数行にわたるコマンドを、後続のdebugモジュールにて、改行された状態で確認したい

##ソリューション

フィルターでは適当なものが見つからなかったが、pythonのsplitlines()にて可能


## playbook 例
```yaml:playbook.yml

---
- hosts: all
  gather_facts: false
  tasks:

    - shell: |
        echo a
          echo b
        echo c
      register: r

    - debug: { var: r.cmd }              # <= そのまま出力すると読みにくい
    
    - debug: { var: r.cmd.splitlines() } # <= splitlines()にて分離

    - debug: { var: r.stdout_lines }
    - debug: { var: r.stderr_lines }

```

## 実行例
```
$ ansible-playbook -i localhost, -c local playbook.yml

PLAY [all] *******************************************************************************************************

TASK [shell] *****************************************************************************************************
changed: [localhost]

TASK [debug] *****************************************************************************************************
ok: [localhost] => {
    "r.cmd": "echo a\n  echo b\necho c\n" # <= そのまま出力した例
}

TASK [debug] *****************************************************************************************************
ok: [localhost] => {
    "r.cmd.splitlines()": [
        "echo a",　　　　　　　　　　　　　　　# <= 行で分離して出力した例　
        "  echo b",　　　　　　　　　　　　　　# <= 行で分離して出力した例
        "echo c"　　　　　　　　　　　　　　　　# <= 行で分離して出力した例
    ]
}

TASK [debug] *****************************************************************************************************
ok: [localhost] => {
    "r.stdout_lines": [
        "a",
        "b",
        "c"
    ]
}

TASK [debug] *****************************************************************************************************
ok: [localhost] => {
    "r.stderr_lines": []
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=5    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

```

なお、(shellモジュールではなく、)commandモジュールでは、レジストリー変数に文字列として渡されないので使用できない。
fail時にも行で分離して表示できると嬉しいが。
vkd3d(WINE D3D12 Vulkan 実装)のビルドメモ

# 背景

* D3D12 アプリを Wine で動かしたりテストしたい
* ゲームを動かすわけではなくて, ちょっとした D3D12 アプリをテストしたり動かしたりしたい


vkd3d を試します.

https://github.com/d3d12/vkd3d

## Build

Wine 5.0 or later とします.

Ubuntu 18.04 で apt で入る spirv-headers, vulkan-headers は古いので, 自前で git clone とかしておきます.

CFLAGS で SPIRV-Headers, (vulkan-headers, libvulkan) へのパスを指定します.
Vulkan は Vulkan SDK や, GPU ベンダの SDK があればそちらを見てくれるかもしれません.

あとは configure して make するだけです!

```
$ CFLAGS="-I../SPIRV-Headers/include" ./configure --prefix=$HOME/local
$ make
$ make install
```

## Windows で動かす.

Windows native 版もあります.

https://github.com/HansKristian-Work/vkd3d-standalone

## TODO

* [ ] 実際に D3D12 アプリを WINE で動かしてみる
VimでPythonのコードを自動整形する

## 使うものリスト
今回使っているプラグインのリンクです。
各自READMEなど確認しておいてください。

- https://github.com/nvie/vim-flake8
- https://github.com/tell-k/vim-autopep8
- https://pypi.org/project/autopep8/

## autopep8のインストール

```
pip install autopep8
```

## vim pluginのインストール
vimのプラグイン管理をdeinで行っている人は、`plugin_lazy.toml`に以下の行をコピーして貼り付ける。（deinを使ってない人は今すぐdeinを使いましょう）

```
[[plugins]]
repo = 'nvie/vim-flake8'
on_ft = ['python']

[[plugins]]
repo = 'tell-k/vim-autopep8'
on_ft = ['python']
```

## .vimrcの編集
gitにpushする前に自動で実行したりファイルを保存するときに自動で実行したりすることも可能ですが、あまり勝手に実行されても怖いのでvim上でsift+fを押したときに自動整形が実行されるように設定します。
以下を.vimrcに追記します。

```
"autopep8を<sift>+fで実行
function! Preserve(command)
    " Save the last search.
    let search = @/
    " Save the current cursor position.
    let cursor_position = getpos('.')
    " Save the current window position.
    normal! H
    let window_position = getpos('.')
    call setpos('.', cursor_position)
    " Execute the command.
    execute a:command
    " Restore the last search.
    let @/ = search
    " Restore the previous window position.
    call setpos('.', window_position)
    normal! zt
    " Restore the previous cursor position.
    call setpos('.', cursor_position)
endfunction
function! Autopep8()
    call Preserve(':silent %!autopep8 --ignore=E501 -')
endfunction
autocmd FileType python nnoremap <S-f> :call Autopep8()<CR>
```
#### 参考
これは[こちら](https://stackoverflow.com/questions/12374200/using-uncrustify-with-vim/15513829#15513829)のStackoverflowのページを参考にしています。

## 使い方
- vimのノーマルモードでF7キーを押すと、Flake8が実行されてpep8に準拠していない箇所が表示される。
- 同じくノーマルモードでsift+fキーを押すと、Autopep8が実行されて、ソースコードの自動整形が行われる。
spring bootを例えて言うなら

springを学習するにあたって調べてみるとspring xxxというものがいくつもヒットして分かったような分からないような。
そこで、技術的な話は抜きにして、spring bootがどんなものかを日常に例えて整理してみました。
スタートアップの助けになればと。

#spring framework
ベースとなるのはこのspring frameworkとなります。
いわゆるjava開発におけるフレームワークで、代表的な便利機能としては、
**DI（依存性注入）**や**AOP（アスペクト指向プログラミング）**や**spring MVC**があります。


|ピュアjava|spring F/W
|:-----------------|:------------------
|![daiku_nokogiri_kiru.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228646/1a2fc012-210d-5427-5576-b294507772cc.png)|![chain_saw_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228646/13549c0b-f2f0-9288-c271-21e73e6b6060.png)
|基本的な機能しかないので、できない事は無いが時間と労力がかかる。|予め便利な機能が提供される事によって、簡単に成果を達成できる。

###つまり
今どき大木を倒すのにギコギコのこぎりで切る事はほとんど無いように、
今どきjavaで開発するのにフレームワークも使わないでやることはほとんど無い。という感じですかね。
更にその開発がWeb系であるなら、今回紹介しているspring frameworkというものが良く使われているという事になります。

#spring boot
**スタンドアロンで実行できるWebアプリケーションをすぐに作成できます。**
”すぐに”というのがコンセプトなのでしょう。

前述のspring frameworkをベースとしたjava開発ができるとともに、Webサーバも基本構成で作ってくれます。
簡単な設定は必要ですが、短期間でアプリの動作確認を始める事が可能です。

|従来のWeb開発|spring boot
|:-----------------|:------------------
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228646/250c26a9-5350-ad6c-c713-9279ec75e716.png" >|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228646/09bedfe4-09df-c3d2-3856-56726de6fc94.png"height="150px"> 
|javaを開発してからWebサーバ構築をする事になる。|spring bootが助手となり裏でWebサーバ構築をお膳立てくれている。

###つまり
ニンジン(Webアプリ)を料理し終わっても載せるつもりのハンバーグ(Webサーバ)が無ければ完成とはなりません。
spring bootはそれをある程度やってくれるので、あとは盛り付けて出すだけになるのです。


#まとめ
『spring framework』という便利な道具を使って、
『spring boot』という見えない助手の協力を得ながら簡単にWebアプリを作成する。

これがspring bootを使う大きなメリットでしょう。
Google Kubernetes Engineの始め方

# 最終更新日
2020年6月25日

この記事が古くなった場合、下記の手順は最新のインストール手順とは異なっている可能性があります。

# 無料トライアルへの登録

Google Cloudでは、サービス内容の確認のために無料トライアルを提供しています。無料トライアルへ登録すると1年間有効な300ドル相当のクレジットが付与され、Google Kubernetes Engineをはじめとする各種サービスを利用できます。

> 無料トライアルに登録するするためにはクレジットカードの登録が必要です。クレジットカードの登録は不正利用の排除を目的としたもので、付与されたクレジットを使い切っても明示的に契約を切り替えない限り引き落としは行われません。

(1) Webブラウザーを開きGoogleアカウントでログインします。（Googleアカウントを持っていない場合は、事前にアカウントを作成しておいてください）

(2) 次のURLを指定してGoogle Kubernetes Engineのトップページを開きます。

https://cloud.google.com/kubernetes-engine/

![01-google-kubernetes-engine-top-page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/95dce7ed-9f34-2f14-39bd-390a0764edef.png)

(3) 右上にある[無料で開始]ボタンをクリックします。

(4) 利用規約を読み、[Google Cloud Platform 無料トライアルの利用規約を読んだうえで内容に同意します。]にチェックを入れ[続行]ボタンをクリックします。（同意がないと利用できません）

![02-account-setup-step-1-license-agreement.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/1ed6c765-0403-fb48-d72b-b178c1783ddc.png)

(5) アカウント登録に必要な情報を入力し[無料トライアルを開始]ボタンをクリックします。

![03-account-setup-step-2-customer-info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/8804ae45-b7ef-a165-f8f7-bc3e0c9c0424.png)

(6) [OK]ボタンをクリックします。

![04-welcome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/c8de73e7-d4c1-1501-7563-06ed1b89c8c5.png)

(7) [課金を有効にする]ボタンをクリックします。その後は数分の時間がかかります。

![05-enable-payment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/f52b0e45-e36f-1371-f530-78808d70e9ce.png)

# Kubernetesクラスターの作成

(1) 左側のメニューから[Kubernetes Engine]-[クラスタ]を選択します。

![06-console-top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/b25f9176-2828-b189-8d3d-ca36a40946a4.png)

(2) [クラスタを作成]ボタンをクリックします。

![07-create-cluster.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/767ebf8a-45f1-cdbd-22c9-fb666ed3b2b4.png)

(3) 各項目を入力して[作成]ボタンをクリックします。（今回はデフォルトのまま作成しています）

![08-cluster-template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/759d8bae-c007-486d-3a54-04ccb7bb6907.png)

# Kubernetesクラスターへの接続

(1) 一覧から作成したKubernetesクラスターの[接続]ボタンを選択します。

![09-cluster-created.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/35838d25-5448-3e08-dbe4-4ce6ee4ac14c.png)

(2) [Cloud Shellで実行]ボタンをクリックします。

![10-connect-to-cluster.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/91593e25-b45e-34f5-e01d-38ff56653dfd.png)

(3) [続行]ボタンをクリックします。

![11-google-cloud-shell-info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/3d6d2ec0-465a-6ccb-94c3-5a0701ce1d01.png)

(4) 画面下部にCloud Shellが開きます。
Kubernetesクラスターへの接続設定を行うコマンドが入力されているので、そのまま[Enter]キーを押してコマンドを実行します。

![12-google-cloud-shell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/b9fa51ef-a322-eb8b-f2a3-0585a76af055.png)

Cloud Shell内で `kubectl` コマンドが利用できるようになります。
（デザイナー向け？）jsのデバッグコンソールに見覚えのないエラーが大量発生した時に原因解析を少し楽にしたい（特殊ケース）

# タイトルについて
私用のアプリをサクッと作っていた時にコンソールがエラーで埋め尽くされたので原因を調べていたら、参照できないオブジェクト（null）に対し操作をしているらしい事が分かった。
ページごとに必ず発生しているがエラー件数も違うので原因がつかめずハマったのでviewを見ながらビルドしたところjsファイルに問題がある事が発覚した。

昨今のフレームワークはこういう作りになっている事は珍しいが、古いCMSだとありそうだな、と思ったので提案。

**良かれと思って書いているがバッドノウハウである**（後述）事は留意しておいてほしい。

# 前提
- 生成側ではhtmlソースを管理していない
  - たとえばindex.phpとかcontents.phpのようなファイルは存在しないか、編集不可である
  - 生成されたhtmlファイルをview側で変更できない
- 複数のページで同じjsファイルを呼び出している
- 呼び出されるjsファイルはscript.jsしかない
- jsとcssは編集できる

という場合を想定。
なお、実際はユーザーが参照するファイルはhtmlではないのですが、説明をしやすいようにここでは生成物をhtmlとしている。

## 生成されるソースコード例
``` index.html
（中略）
<script src="script.js">
（中略）
<section id="top_block">
（中略）
<!-- こちらにid:contents_blockは存在しない -->
```

``` contents.html
（中略）
<script src='script.js'>
（中略）
<section id="contents_block">
（中略）
<!-- こちらにid:top_blockは存在しない -->
```

この時、`id:top_block`と`id:contents_block`に対して何かしらのアプローチをしたい場合、他のページで存在しない要素に対して制御を行うとブラウザのコンソールに期待しないエラーが発生するためデバッグが面倒になる。
これが少ない数なら無視できるが、それぞれのページや要素に対して何か行っている場合、呼び出している回数だけエラーが発生することになってしまう。

# 解決（提案）
``` script.js
function run_judge_function ( obj, func )
{
  obj == null ? null : func();
}
```

関数を実施させる際に直接呼び出すのではなく、`run_judge_function`に**対象となるオブジェクト**と**実施したい関数**を渡してnull(undefined)を検出してあげて、見つかれば実施したい関数を実行するというアプローチを検討する。

## 注意
この関数が想定される・本来は検出したいエラーを揉み消す可能性があり、本番環境に乗せてしまうと異常が発生した場合に適切なエラーログが取得できない事が考えられる。

``` script.js
let stage_flg = true;  // ※１
function run_judge_function ( obj, func )
{
  if (stage_flg) obj == null ? null : func();
}
```

（※１[^1]）
としておくと、消し忘れを防止できるが検証環境と本番環境で差異が発生する事に留意。
検証環境の時はtrue、そうでなければfalseにする環境変数を用意しておく事も検討すべきか。

## 備考
本来は呼び出し側で適切なスクリプトを参照するようにしてあげるのがスマートだが、これらのhtmlソースを生成する側のファイルでヘッダ情報などを共通化しているために起こってしまう。
生成側のファイルを変更できるなら調整や対応をissueに上げるべきだが、今回はあくまでview側で解決する場合を考えた。

## 注意とお節介
この問題は現場でも起こる可能性があるのではないかと考えており、たとえばプロジェクト初期に想定されなかった要素を継ぎ接ぎで追加した時に起こりがちな問題ではないだろうか？
後で継ぎ接ぎした時に**良かれと思って**こういう関数をかますと（既存部分への影響が大きすぎてテストが大変になり）メチャクチャ怒られるのが普通なので導入時は注意するか、なんならstage環境にも上げるべきではない。

githubなどコードレビュー文化が根付いているならチェックが入るはずだが、**コードを書けるプロの人はレビューもプロか？というとそうではない**ので運用上の注意が必要。

# お願い
ページを参照した（view）がイコール最後まで読んでもらった（complete）と思っていないので、お手数を掛けて恐縮だがLGTMをいただけると、読みやすい書き方や記事がどういうものか分析しやすくなり大変助かります。

# 注釈
[^1]: 【※１】実際の使用例としてstage_flgは環境変数か何かで設定する事が望ましい。
RubyのSeleniumでAttributeの値を変更したい

#概要
RubyのSeleniumでスクレイピングの処理を書いているときにどうしても属性値の変更を行いたくなる場面があります。UIの振る舞いを忠実に追跡したい場合では使いませんが、UIの挙動がわかっている場合に面倒な処理を飛ばして目的のものをすぐ欲しいという場合に有効です。
#方法
RubyでAttributeへのアクセスはGetAttributeがあるにも関わらずSetAttributeが見つかりません。(探し方の問題かもしれませんが)GetではDOMに変更を与えませんが書き込みでは予期せぬ振る舞いを起こす可能性から用意されていないのではと勝手に推測し、今回は「execute_script」を使用します。

```ruby:execute_script.rb
#ドライバーの初期化
client = Selenium::WebDriver::Remote::Http::Default.new
driver = Selenium::WebDriver.for :chrome, http_client: client

#<div id="mw-content-text" lang="ja" dir="ltr" class="mw-content-ltr">
#jaをenに変えたい

#対象になる要素の取得
target_element = driver.find_element(:class_name, 'mw-content-ltr')
driver.execute_script("arguments[0].setAttribute('lang', 'en');", target_element)

```

#参考
https://www.rubydoc.info/gems/selenium-webdriver/0.0.28/Selenium%2FWebDriver%2FDriver:execute_script
NTTPCのVPS「Indigo」でスワップの設定

# はじめに
NTT PCコミュニケーションズのVPSサービス「[Indigo](https://web.arena.ne.jp/indigo/)」を使い始めたのですが、一番ミニマムなプランで契約している貧乏性な性格のため、メモリが心もとなくなってきました。。

```
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            985         649          76           3         260         191
```

デフォルトではスワップが無効になっているので、スワップを有効にしてみたいと思います。

#前提条件
以下の環境で検証しています。
- NTT PC コミュニケーションズ「[Indigo](https://web.arena.ne.jp/indigo/)」上の、KVM Instance 1 CPU 1 GB - Ubuntu 18.04


#設定
## スワップファイルの作成
`dd`で2GBのスワップファイルを作成し、パーミッションを変更します。

```
# dd if=/dev/zero of=/swapfile bs=1M count=2048
# chmod 600 /swapfile
```

## スワップに設定

```
# mkswap /swapfile
```

## `/etc/fstab`の設定
起動時にスワップが有効になるように`/etc/fstab`に設定します。

```
# vi /etc/fstab
LABEL=cloudimg-rootfs   /        ext4   defaults        0 0
LABEL=UEFI      /boot/efi       vfat    defaults        0 0
# add here
/swapfile       swap    swap    defaults        0 0
```

##スワップを有効
再起動するか、以下のコマンドでスワップを有効にします。

```
# swapon -a
```

`-a`で`/etc/fstab`の内容にしたがってスワップを有効にします。


#確認
ちゃんとスワップが有効になっているか確認します。大丈夫ですね。

```
$ free -m
              total        used        free      shared  buff/cache   available
Mem:            985         647          70           3         267         192
Swap:          2047           6        2041
```

#おわりに
スワップなんて使わなくて良いなら使いたくないですが、リソースが限られている場合は有効な手段です。
私と同じく貧乏性な方はご参考に。
interface からunion をつくる ~ not keyof interface ~

# TL;DL
```ts
interface IHoge {
    A: string,
    B: number,
    C: boolean
}
const Hoge: IHoge = {
    A: "",
    B: 0,
    C: true
}
const h = (p: keyof IHoge) => {
    return p in Hoge ? Hoge[p] : undefined;
}
type IHogeValues = NonNullable<ReturnType<typeof h>>;
// IHogeValues = string | number | boolean
```

追記 2020/06/25
コメントで教えていただきました。@nagtkk さん、ありがとうございます😭

インターフェースから

```ts
interface IHoge {
    A: "a",
    B: "b",
    C: "c"
}
type IHogeValues = IHoge[keyof IHoge];
```

オブジェクトから

```ts
const Hoge = <const>{
  A: "a",
  B: "b",
  C: "c"
};
type IHogeValues = (typeof Hoge)[keyof typeof Hoge];
```

# なぜつくるのか

## こんなことをしたかった

```ts
const Hoge = {
  A: "a",
  B: "b",
  C: "c"
}
function Say(t: "a" | "b" | "c") {
  console.log(t);
}

Say(Hoge.A); // -> a
Say("b");    // -> b
Say("d");    // error
```

ライブラリが提供する列挙型だけ受け付ける関数をつくりたかった

## しかし
このやり方の場合確かに問題なく動作するが、列挙型の中身が増減するたびに該当箇所を書き換える必要が出てくる　→　追記漏れが怖い😭

# interface から union をつくる
## 完成コード
```ts
interface IHoge {
    A: "a",
    B: "b",
    C: "c"
}
const Hoge: IHoge = {
    A: "a",
    B: "b",
    C: "c"
}
const h = (p: keyof IHoge) => {
    return p in Hoge ? Hoge[p] : undefined;
}
type IHogeValues = NonNullable<ReturnType<typeof h>>;
// IHogeValues = "a" | "b" | "c"

function Say(t: IHogeValues) {
    console.log(t);
}

Say(Hoge.A); // -> a
Say("b");    // -> b
Say("d");    // error
```
## 解説
### ReturnType
`ReturnType` は与えた関数の情報を元に、その関数が返す値の型情報を取得します。
そのため、上記コード内に出てきた`関数h`では、`IHoge`内のキー名を受け取る`引数p`をインデックスとし`Hoge`から対応する値を返し、存在しない場合は`undefined`を返します。
❗️p は動的に決まるため仕様上`return Hoge[p]`とは書けません。(keyof IHogeしているのに。。。)

そのため`関数h`が返す値は`"a" | "b" | "c" | undefined`になります。

### NonNullable
`NonNullable`は受け取ったTypeから`undefined`と`null`を除いた値を返します。

そのため`ReturnType`から受け取った`"a" | "b" | "c" | undefined`を`"a" | "b" | "c"`にすることが出来ます。

# あとがき
これで追記漏れなどもなくなるので安心ですね！
１コマンドで特定のバージョンのBurpを起動するシェルスクリプトをzshで用意しました

# 経緯
業務でBurpSuiteというプロキシツールを使用しています。
不測の事態に備えて、バージョンごとにjarファイルをローカルに保存しておいて、必要なバージョンを起動して使用しています。
ただ、いちいちフォルダから探すのがだるすぎたので、１コマンドで起動したい！　ということで下記記事を参照し `burp.sh` というシェルスクリプトを作って起動しておりました。
[【初心者向け】シェルスクリプトの作り方](https://qiita.com/Lambda34/items/7d24ebe6f7bde5bedddc)

ところが、MacOS Catalinaからデフォルトシェルがzshになっています。
業務用のMacbook Proを交換することになったので移行を進めていたのですが、新しいMBPちゃんはデフォルトシェルがzshでした。

検索したら、zshからbashに戻す方法もたくさん出てきたのですが、いい機会だしzshに移行してみました。
というメモです。

# 手順(3分くらいで終わるよ！)
1. 自分の環境でどのシェルが使えるか確認
2. `burp.sh` の中身を `burp.zsh` を作成してコピー
3. `.zprofile` を作成してPATHを通す
4. ファイルに書かれたコマンドを現在のシェルで実行
5. １コマンドで特定のバージョンのBurpを起動できるようになりました

## 1. 自分の環境でどのシェルが使えるか確認
まず、現在自分が使っているシェルがなにか調べます。

```
echo $SHELL
```
自分の環境で使えるシェルを調べます。

```
cat /etc/shells
```

## 2. 「burp.sh」の中身を「burp.zsh」を作成してコピー
`shellscript` という名前のディレクトリに `burp.sh` を作ってあったので、コピーして `burp.zsh` を作ります。

```
cd shellscript
cp burp.sh burp.zsh
```

念のため中身を確認しておきます。

```
vi burp.zsh
```

ちゃんとコピーされて同じ内容が書かれていることが確認できました。

```
java -Xms4G -Xmx4G -jar ./<Name>/tools/burp/burpsuite_pro_v2020.5.1.jar
```

## 3. 「.zprofile」を作成してPATHを通す
`.zprofile` を作ります。

```
vi  ~/.zprofile
```

`.bash_profile` と同じように下記内容を `.zprofile` に書きます。

```
PATH=$PATH:~/shellscript
export PATH
```

## 4. ファイルに書かれたコマンドを現在のシェルで実行
下記でファイルに書かれたコマンドを現在のシェルで実行できるようになります。

```
source ~/.zprofile
```

## 5. １コマンドで特定のバージョンのBurpを起動できるようになりました
これで、どこのディレクトリにいても`burp.zsh` に書いてあるバージョンのBurpSuiteを起動できるようになりました！

```
burp.zsh
```
IM-Juggling とは

# 序文

IM-Jugglingとはなんぞやって質問が後輩から飛んできた。
IM-Jugglingについて言及して居る記述は[intra-martの公式サイト](https://www.intra-mart.jp/document/library/iap/public/setup/iap_quick_setup_guide/texts/create_war/create_project.html)では以下の記載となっております。

> IM-Juggling はモジュールの管理、WARファイルのリモートデプロイを実行できる環境構築ツールです。
> このツールを使用し、新しい機能の導入や不具合修正の適用をします。

質問してきた後輩は物理ネットワークの出身でWebアプリケーションに明るくない。 
ましてや「``イントラマート``」って言われても何のことかわからない。
後輩なりに色々調べてWebアプリケーションっぽいってことは理解した様なのですが、
具体的には理解できていない様だった。

幸いな事に私の所属している組織ではintra-martを利用しており、
[イントラマート社](https://www.intra-mart.jp/)が[デモサイト](https://www.intra-mart.jp/demosite/)を公開しているのでintra-martの画面を見せながら説明することが出来た。
うまく説明出来たかはさて置き、、、

前置きが長くなりましたが、本稿では後輩に向けた``IM-Jugglingとはなにか``を説明していこうと思います。


# 本文

Webアプリケーションに明るくない後輩向けに公式サイトの文言を分解していきます。 
・モジュールの管理（モジュール）
・Warファイル
・デプロイ
・環境構築ツール

### モジュールの管理
これを説明するのにintra-martとは何かを説明する必要がありました。
**誤解を恐れずに言うと**、[intra-martとは](https://qiita.com/m-_-m/items/b5a667f33f6843bf5378)に記載した基本機能単位を``モジュール``と言うことができる。


### Warファイル
私は「ウォー」じゃなくて「ワー」と呼んでます。正解は知りません。
Webアプリケーションをまとめたファイルの種類です。
・プログラム
・HTML
・画像
・設定ファイル

### デプロイ
Webアプリケーションをアプリケーションサーバに配置すること
この手順を実行することでWebアプリケーションとして実行可能となります。

### 環境構築ツール
IM-jugglingの場合、利用者が選択した各種モジュールの整合性を確保した状態でWarファイルを作成するツールです。


# 終わりに

多分、IM-Jugglingについてはこんな感じだと思います。
Javafxで簡単なゲームを作ってみた①　”幸せを探そうゲーム”（未完成）

#Javafxで簡単なゲームを作ってみた①
##”幸せを探そうゲーム”（未完成）
```sample.java
package happy_unhappy_game;

import java.util.Random;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;


	public class Sample extends Application {

		public static void main(String[]args) {
			launch();
		}

		 public static Scene scene1 = null;
		 public static Scene scene2 = null;

		 public static String txt=null;
		 public static String txt2=null;
    	 public static Label status=new Label();
    	 public static Button btn2 =null;
    	 public static VBox root=new VBox();
    	 public static TilePane pane=new TilePane();



    @Override
    public void start(Stage stage) throws Exception {

    	stage.setTitle("main");
    	stage.setWidth(380);
    	stage.setHeight(500);
    	  // ステージの作成
    	initScene2(stage);
    	initScene1(stage);

    	stage.setScene(scene1);
    	stage.show();
    }

    public static void initScene1(Stage stage){
    	stage.setWidth(380);
    	stage.setHeight(500);
    	stage.setTitle("1");

    	Random rnd=new Random();

    	Button button[]=new Button[144];
    	for(int i=0;i<144;i++) {
    		button[i]=new Button("辛");
    		button[i].setPrefWidth(30);
    		button[i].setPrefHeight(30);
    		String txt=String.format("それは\"辛い\"です。");
    		button[i].setOnAction(event->status.setText(txt));
    	}

    		int number=rnd.nextInt(144);
			button[number]=new Button("幸");
    		button[number].setPrefWidth(30);
    		button[number].setPrefHeight(30);
    		txt2=String.format("\"幸\"がクリックされました。");
    		button[number].setOnAction(event->push(stage));

    	pane=new TilePane();
    	pane.getChildren().addAll(button);

    	root=new VBox();
    	root.getChildren().addAll(pane,status);

    	scene1=new Scene(root);
    }


    public static void initScene2(Stage stage) {
    	stage.setWidth(380);
    	stage.setHeight(500);
    	stage.setTitle("2");

    	Button btn = new Button("シーン変更完了！！！");
    	    btn.setPrefWidth(100);
    	    btn.setPrefHeight(50);
    	    btn.setOnMouseClicked(event -> setScene2(stage,scene1));

    	    AnchorPane root = new AnchorPane();
    	    root.getChildren().add(btn);
    	    scene2 = new Scene(root);

    }

    public static void push(Stage stage) {
    	status.setText(txt2);
    	btn2 = new Button("次へ");
		btn2.setPrefWidth(100);
		btn2.setPrefHeight(50);
		btn2.setOnMouseClicked(event -> setScene(stage,scene2));
    	root.getChildren().addAll(btn2);
    }

    public static  void setScene(Stage stage,Scene changeScene) {
        stage.setScene(changeScene);
        stage.show();
     }

    public static  void setScene2(Stage stage,Scene changeScene) {
	    stage.setScene(changeScene);
	    stage.show();
	  }

 	}



```
##ゲームの概要と現段階での問題点
多数の"辛"ボタンの中から、一つの"幸"ボタンを探すゲーム。
今のところ、画面推移がうまくできず苦戦中。
今後は時間制限や、カウント機能を付けていきた。


![200625.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527593/3e709df5-e74b-db87-fcb2-35d5cf5b60b7.gif)
SNMPの勉強メモ

参考URLのメモ　順不同
https://software.fujitsu.com/jp/manual/manualfiles/M090045/J2X12071/05Z200/J2071-00-07-10-00.html
https://www.itbook.info/network/nwope10.html
https://www.ibm.com/support/knowledgecenter/ja/SSSHTQ_8.1.0/com.ibm.netcool_OMNIbus.doc_8.1.0/omnibus/wip/ua_mibmgr/reference/omn_ref_mib_mibobjects.html
https://www.manageengine.jp/support/kb/OpManager/?p=531
BacklogのwebhookでJenkinsのジョブを実行する方法（パラメータ付き）

# 経緯
backlogの`Gitプッシュ`をトリガーにして、pushされたブランチに対してJenkinsのジョブを実行することを考えていました。

[BacklogのWebhookでJenkinsのビルドを走らせる](http://dwmemo.hatenablog.com/entry/2018/02/11/200308)の記事を参考に解決できそうでしたが、
パラメータ付きビルドのジョブの場合WebhookのURLが変わってくるので補足で記録しておきます。

細かい説明は上記の記事を参考にしてください。

# backlog に登録する WebHook URL
- your_jenkins_domain : jenkinsのドメイン名
- job : Jenkinsのジョブ名
- token : ジョブに設定したtoken


### 前提
以下プラググインをインストール
[Build Authorization Token Root](https://plugins.jenkins.io/build-token-root/)

### パラメータなしビルド（build）

```
https://your_jenkins_domain/buildByToken/build?job=RevolutionTest&token=TacoTuesday
```

### パラメータ付きビルド(buildWithParameters)

```
https://your_jenkins_domain/buildByToken/buildWithParameters?job=RevolutionTest&token=TacoTuesday&Type=Mexican
```
### 参考

[Build Authorization Token Root](https://plugins.jenkins.io/build-token-root/)のEXAMPLE


# 使用例
### Gitプッシュをトリガーにプッシュしたブランチを対象にジョブを実行する方法
#### Jenkins側の設定
ビルドのパラメータ化にチェックをいれてデフォルト値は何も入力しません。
名前は任意ですが、ここでは`GIT_BRANCH_PARAMETER`としておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123603/694d8262-18e4-0573-ea6d-ca322b11966c.png)

ビルドするブランチに`$GIT_BRANCH_PARAMETER `を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123603/4dc5e011-70a7-279d-ba1c-9bcfdf0ad0d1.png)

#### Backlogの設定
WebHook URLを以下の様に設定します。

```
https://your_jenkins_domain/buildByToken/buildWithParameters?job=RevolutionTest&token=TacoTuesday&GIT_BRANCH_PARAMETER=
```

- job, tokenは環境によって変更してください。
- GIT_BRANCH_PARAMETERは何も指定しないでおきます。
    - Jenkins側の設定でビルドするブランチ名が空白だと、全てのブランチが対象となります。全ブランチの中でジョブ実行されていないブランチのコミットを探しに行くみたいなのでそれを利用します。


#### 動作確認
Backlogの実行テストを行うと、Jenkins側でジョブが実行されることを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123603/711a2ad4-3714-1a81-7ef4-35697f78b6ac.png)

---

参考になれば幸いです。
SQLのCASE文をExcelのIF文で表現する

自分で書いたSQL文を自分でテストするときに、別途同じテストデータでExcel使って作っておいたアンサー値と、実際にSQLを実行して取り出してきた値とを比較するってことがあります。

出来る先輩は簡単におっしゃるんだ。
「エクセルで答え作っといて！それと比べれば良いから！」

「はい、わかりました（エクセルでどうやって作るねん）」

エクセルのやり方を先輩に質問するのはさすがに忍びないので、自分でなんとかします。今回はCASE文と同じ処理を表現します。IF文の入れ子でやります。

SQLのCASE文で付与した値が、例えばGROUP BYのキーになっていたりする場合、エクセルで表現するにはIF条件分岐で作業列を作ってから、ピボットするなりして模擬実行結果を作ります。

#SQLのCASE文例
例えば、
「学生番号, 名前, ……」のCSVファイルがあります。

▼テーブル名：KOHUN_ASUKA_CLASS

| 学生番号(列名：STUDENT_ID) | 名前(列名：STUDENT_NAME)  |
|:-----------------|:------------------|
| 0010           | 卑弥呼             |
| 0011           | 蘇我馬子             |
| 0012           | 聖徳太子             |
| 0013           | 小野妹子             |
| 0014           | 中臣鎌足             |
| 0015           | 中大兄皇子           |
| 0016           | 天武天皇             |
| 0017           | 仁徳天皇             |


修学旅行に行くので、1班・2班に分けたいと思います。
学生番号が0010～0013が1班、
0014～0017なら2班にすることにしました（列名：GROUP_NUM）

```sql:CASE.sql
SELECT
    STUDENT_ID,
    STUDENT_NAME,
    CASE
        WHEN STUDENT_ID BETWEEN '0010' AND '0013' THEN '1'
        WHEN STUDENT_ID BETWEEN '0014' AND '0017' THEN '2'
        ELSE '0'
    END AS GROUP_NUM
FROM
    KOHUN_ASUKA_CLASS
```

▼実行結果

| STUDENT_ID | STUDENT_NAME | GROUP_NUM |
|:-----------------|:------------------|:------------------|
| 0010           | 卑弥呼            　 | 1        　     |
| 0011           | 蘇我馬子             | 1        　     |
| 0012           | 聖徳太子             | 1        　     |
| 0013           | 小野妹子             | 1        　     |
| 0014           | 中臣鎌足             | 2        　     |
| 0015           | 中大兄皇子           | 2        　     |
| 0016           | 天武天皇             | 2        　     |
| 0017           | 仁徳天皇             | 2        　     |

#Excelの条件分岐でCASEと同じ事をする
![WS000014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/d40215c1-785f-6132-eb77-134ae02e066c.jpeg)

ExcelのA列にSTUDENT_ID, B列にSTUDENT_NAME, C列にGROUP_NUMを出力します。
C2に下の関数を書いて、後は下までオートで埋めれば完成です。

```shell:IF.xlsx
# GROUP_NUM
=IF(AND(0010<=A2,A2<=0013),"1"
    ,IF(AND(0014<=A2,A2<=0017),"2","0")
    )
```

![WS000017.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/b948951e-89dc-434c-febf-88d9a1a06197.jpeg)

※Excel自体のセル表示形式（数値、文字列等）がズレていると、求める結果が得られない場合があるので、そこは調整してください。

![WS000016.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/86827aa4-4435-3eab-b5d9-5fb8968790f8.jpeg)

```shell:IF関数の引数_Excel
=IF(条件式, 真の場合, 偽の場合)
```

##条件がもっと多い時は？
条件が増えても、入れ子になった「偽の場合」に随時追加していけばOK。

学生がもっと多くて、こうしたい時、
0010～0013→1班
0014～0017→2班
0018～0021→3班
0022～0025→4班

```shell:IF_2.xlsx
# GROUP_NUM
=IF(AND(0010<=A2,A2<=0013),"1"
    ,IF(AND(0014<=A2,A2<=0017),"2"
        ,IF(AND(0018<=A2,A2<=0021),"3"
            ,IF(AND(0022<=A2,A2<=0025),"4","0")
           )
       )
   )
```

以上
コンフリクト 時にどちらの変更か分からない

コンフリクト時のどちらの変更か分からないとき(自分用)

```
# for image uploader with AWS S3
gem 'carrierwave'
<<<<<<< HEAD(現在の変更)←今のコードを適用する
gem 'fog-aws'
gem 'fog-local'
=======

# ローカルではfog-awsを使用
# gem 'fog-aws'
gem 'fog'

>>>>>>> 1dba7da3812b21420804f1fb844ce1f80d0a99d7(入力側の変更)←pullしてきたコードを適用する
# text_areaのフォームを自動調整
gem 'autosize', '~> 2.4'

gem 'thin'

```


```

```
プロジェクト内にtsconfigが複数あるときに、今開いているtsファイルに適用されるコンフィグを簡単に開く for VSCode

front,server,api,testなどで、tsconfigを分けて管理したいときに、
当該tsファイルに適用しているtsconfigファイルを簡単に開く方法の紹介。

* 該当のファイルを選択した状態で、VSCodeの右下にある`TypeScript`のバージョンを選択
<img width="401" alt="スクリーンショット 2020-06-25 12.06.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624296/fbffb4d0-ad6c-6121-b8fe-21121f5aba3d.png">

* コマンドパレット上に選択子がでてくるので、 `tsconfigを開く`を選択
<img width="503" alt="スクリーンショット 2020-06-25 12.08.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624296/872609a2-7480-d4a6-e938-27ffae7446e7.png">
サクっと！CSSでNeumorphismのボタンを作る

#tl;dr;
2020年初頭から注目されているデザイン、**Neumorphism**をご存知ですか？
広く普及しているマテリアルデザインと比較して紹介します。
**マテリアルデザイン**は、**影**を用いて要素を**浮かび上がらせ**ます。
一方、**Neumorphism(ニューモーフィズム)**では、**影**と**光**を用いて要素の**凹凸を表現**します。

**Neumorphism(ニューモーフィズム)**の基本的なパーツはCSS3のbox-shadowを用いて簡単に実装できます。
この記事ではCSSとHTMLを用いて簡単なパーツの作成方法を紹介します。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548175/5c634561-df84-d1ca-1126-ceecd11f9eda.gif)
[図1 : Neumorphismを用いたアプリケーション例 \(neutodo.com\)](https://neutodo.com)


#膨らみの表現
**Neumorphism(ニューモーフィズム)**の膨らみの表現について解説します。
次の3ステップで基本的な要素が実現できます。
1. border-radiusを指定して要素の四隅に丸みをつける。
2. box-shadowを用いて、要素の左上（光を当てる場所）に背景色よりも明るい色をつける。
3. box-shadowを用いて、要素の右下（影を落とす場所）に背景色よりも暗い色をつける。

box-shadowで指定する値を調整することで、凹凸の高さやなだらかさを調節できます。
box-shadowの詳しい説明は以下のようなドキュメントに譲ります。

box-shadowについて: [https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow](https://developer.mozilla.org/ja/docs/Web/CSS/box-shadow)

以下に簡単なHTMLとCSSを示します。


```index.html
<link rel="stylesheet" type="text/css" href="neumorphism.css" />
<body>
  <div>button</div>
</body>
```
```neumorphism.css
body {
  background-color: #dddddd;
}

div {
  margin: 50px;
  padding: 10px;
  width: 50px;
  border-radius: 5px;
  box-shadow: 5px 5px 10px #bbbbbb, -5px -5px 10px #ffffff;
}
```





<img width="413" alt="スクリーンショット 2020-06-25 11.38.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548175/c975c83e-befe-3299-fd71-fa83e8ddab56.png">
Chrome83での表示結果


#凹みの表現
**Neumorphism(ニューモーフィズム)**の凹みの表現について解説します。
次の3ステップで基本的な要素が実現できます。
1. border-radiusを指定して要素の四隅に丸みをつける。
2. box-shadow insetを用いて、要素の右下内側（光を当てる場所）に背景色よりも明るい色をつける。
3. box-shadow insetを用いて、要素の左上内側（影を落とす場所）に背景色よりも暗い色をつける。



以下に簡単なHTMLとCSSを示します。


```index.html
<link rel="stylesheet" type="text/css" href="neumorphism.css" />
<body>
  <div>button</div>
</body>
```
```neumorphism.css
body {
  background-color: #dddddd;
}

div {
  margin: 50px;
  padding: 10px;
  width: 50px;
  border-radius: 5px;
  box-shadow: inset 3px 3px 5px #bbbbbb, inset -3px -3px 5px #ffffff;
}

```

<img width="413" alt="スクリーンショット 2020-06-25 11.46.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548175/9652fff9-4b16-31e1-36d9-5914c4bb1b86.png">
Chrome83での表示結果

#組み合わせて応用
上述の凹凸の表現それぞれを組み合わせることで、応用した表現も可能です。
以下に例を示します。

```index.html
<link rel="stylesheet" type="text/css" href="neumorphism.css" />
<body>
  <div>button</div>
</body>
```
```neumorphism.css
body {
  background-color: #dddddd;
}

div {
  margin: 50px;
  padding: 10px;
  width: 50px;
  border-radius: 15px;
  border: 5px solid #dddddd;
  box-shadow: 5px 5px 10px #bbbbbb, -5px -5px 10px #ffffff,
    inset 3px 3px 5px #bbbbbb, inset -3px -3px 5px #ffffff;
}
```

<img width="413" alt="スクリーンショット 2020-06-25 12.03.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548175/685f8c1a-a4a5-489d-b3ba-3d27e679e5dc.png">
Chrome83での表示結果

#まとめ
Neumorphismのスタイルを生成するツール等もありますが、今回はCSSで作成しました。
注目を浴びているNeumorphismについて、webではHTMLとCSSで簡単に実現できます。

できる限り多くの方の参考になればと思い、シンプルで簡単に記述しました。