OmniAICreator/Qiita-1.07M huggingface dataset:
[Swift] [UIView] UIView,UIStackViewに枠線(上下左右)をつけるExtension

## はじめに
UIStackViewに枠線を付けようと思ったときに使ったExtensionの備忘録です。

## イメージ
こんな感じにできますー

|  BEFORE  |  AFTER  |
| :----: | :----: |
|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520693/365c35e1-0ed6-3200-e06d-8d46b2117a89.png" width="300">  | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520693/d4a6b2ed-a86d-98f5-1f77-7ba8ffab628a.png" width="300">|



## コード
- widthと書いてありますが、こちらは枠線の太さを調整するパラメーターになっています。
- widthが固定の値しか使わないのであればpositionと同じようにenumで定義してあげるのも良いと思います。

```swift
import UIKit

enum BorderPosition {
    case top, left, right, bottom
}

extension UIView {
    
    /// viewに枠線を表示する
    /// - Parameters:
    ///   - width: 太さ
    ///   - color: 色
    ///   - position: 場所
    func addBorder(width: CGFloat, color: UIColor, position: BorderPosition) {
        let border = CALayer()
        
        switch position {
        case .top:
            border.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: width)
            border.backgroundColor = color.cgColor
            self.layer.addSublayer(border)
        case .left:
            border.frame = CGRect(x: 0, y: 0, width: width, height: self.frame.height)
            border.backgroundColor = color.cgColor
            self.layer.addSublayer(border)
        case .right:
            border.frame = CGRect(x: self.frame.width - width, y: 0, width: width, height: self.frame.height)
            border.backgroundColor = color.cgColor
            self.layer.addSublayer(border)
        case .bottom:
            border.frame = CGRect(x: 0, y: self.frame.height - width, width: self.frame.width, height: width)
            border.backgroundColor = color.cgColor
            self.layer.addSublayer(border)
        }
    }
}
```

## 使い方
枠線の色、太さ、場所（top, left, right, bottom）で調整が可能。

```swift

// viewの上部(top)に黒の枠線をつける
view.addBorder(width: 3, color: .black, position: .top)

// viewの左(left)に黒の枠線をつける
view.addBorder(width: 3, color: .black, position: .left)

// viewの右(right)に黒の枠線をつける
view.addBorder(width: 3, color: .black, position: .right)

// viewの下部(bottom)に黒の枠線をつける
view.addBorder(width: 3, color: .black, position: .bottom)

// stackViewでもできる
stackView.addBorder(width: 3, color: .red, position: .top)
```

### 注意
コードでviewのAutoLayoutを実装している場合に、
`self.frame.width`と`self.frame.height`が`0.0`になってしまうため、
layoutIfNeededかviewDidAppear内で、addBorderをする。

## まとめ
viewに枠線をつけるだけのシンプルなextensionでした。
extensionって便利ですよねー　
extensionのストックためたい。
CMake Error「This app targets API set 'X', but this build targets the latest API set 'Y'.」の解決方法

# 事象

自プロジェクトをAzure Sphere SDKの最新APIセットに対応させようと、CMakeLists.txtのTARGET_API_SETを最新（今回は"7"から"8"）に変更したところ、キャッシュを生成時にエラーが発生した。

```
1> 構成 'ARM-Debug' の CMake 生成を開始しました。
1> コマンド ライン: "cmd.exe" /c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\CMake\bin\cmake.exe"  -G "Ninja"  -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="C:\AzureSphere\azure-sphere-thief-detector\projects\multicore\control-hl\install\ARM-Debug" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="C:\Program Files (x86)\Microsoft Azure Sphere SDK\CMakeFiles\AzureSphereToolchain.cmake" -DAZURE_SPHERE_TARGET_API_SET:STRING="latest-lts"  -DCMAKE_MAKE_PROGRAM="C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2019\ENTERPRISE\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\CMAKE\Ninja\ninja.exe" "C:\AzureSphere\azure-sphere-thief-detector\projects\multicore\control-hl" 2>&1"
1> 作業ディレクトリ: C:\AzureSphere\azure-sphere-thief-detector\projects\multicore\control-hl\out\ARM-Debug
1> [CMake] -- The C compiler identification is GNU 9.3.0
1> [CMake] -- Detecting C compiler ABI info
1> [CMake] -- Detecting C compiler ABI info - done
1> [CMake] -- Check for working C compiler: C:/Program Files (x86)/Microsoft Azure Sphere SDK/Sysroots/7/tools/gcc/arm-poky-linux-musleabi-gcc.exe - skipped
1> [CMake] -- Detecting C compile features
1> [CMake] -- Detecting C compile features - done
1> [CMake] CMake Error at C:/Program Files (x86)/Microsoft Azure Sphere SDK/CMakeFiles/AzureSphere.cmake:104 (message):
1> [CMake]   This app targets API set '8', but this build targets the latest API set
1> [CMake]   '7'.
```

# 解決方法

CMakeLists.txtのキャッシュを生成では回避できず。
先に、プロジェクト配下の`out`フォルダを削除すればOK。
誤ったMIME type設定が原因で、JavaScriptが実行されなかった時の解決方法

[『体系的に学ぶ-安全なWebアプリケーションの作り方-第2版-』](https://www.amazon.co.jp/体系的に学ぶ-安全なWebアプリケーションの作り方-第2版-脆弱性が生まれる原理と対策の実践-徳丸/dp/4797393165"amazon")で学んだことを基に、
ログイン機能のサンプル作成中につまづきました。

あるJavaScriptライブラリの利用を試みましたが、
ブラウザ(safari)上で、以下のエラーが発生し、JavaScriptが起動しませんでした。

```console:console(safari)
[Error] Refused to execute http://「ファイル名」.js as script 
because "X-Content-Type-Options: nosniff" was given and 
its Content-Type is not a script MIME type.
```

今回は、このエラーを解消した方法を投稿します。

# 開発環境

+ Mac OS（safari）
+ docker-compose

**使用しているimage**
 PHP:7.3-apache
mysql:5.7

# 解決方法
apacheの設定を変更する。以下の設定を追加しました。

```apache:apacheの構成を設定するファイル
AddType text/javascript .js

<Directory "設定を適用させたいディレクトリ">
<Files "設定を適用させたいディレクトリ/*.js">
Header set Content-Type application/javascript; charset=utf-8
</Files>
</Directory>
```

# エラーの原因
apache全体を対象とした設定に、
`Header set Context-Type text/html; charset=utf-8`
を記述していたので、Javascriptを読み込む際のレスポンスヘッダーが、
`Content-Type: text/html; charset=utf-8`
となっていたことが原因のようです。

このため、apacheで設定していた
`Header always set X-Content-Type-Options nosniff`によって、
レスポンスヘッダー `Content-Type: text/html; charset=utf-8`通りに、
MIME typeを`text/html`として、JavaScriptファイルを処理した為に、
エラーが発生したようです。

# 参考文献
[apache official セクションの設定](https://httpd.apache.org/docs/2.4/ja/sections.html "apache official")

# 追記（2021(R.3).03.17(水)）
HTTP Response Header(Content-Type)の設定は、
サーバー(Apache)の構成ファイルではなく、
スクリプトファイルで個別に設定しようと思います。
今回の場合であれば、PHPのheader() functionを利用した方が良いと感じました。

ただし、これがセキュリティ的に良いのかはわかりませんので、調べて行きたいです。
Chromeのタブが増えすぎるのを防ぐ方法

[Tab Wrangler](https://chrome.google.com/webstore/detail/tab-wrangler/egnjhciaieeiiohknchakcodbpgjnchh?hl=en)というChrome拡張機能を使うと、ある一定の時間が経つと自動的に設定した数までタブを減らしてくれます

https://chrome.google.com/webstore/detail/tab-wrangler/egnjhciaieeiiohknchakcodbpgjnchh?hl=en

例えば以下の設定では1200秒（20時間）以上使っていないタブは自動的に閉じられて、タブの数が5つに保たれます

![Screen Shot 2021-03-13 at 8.27.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527661/89b15a65-3ed9-f02c-08cb-b4e4b0dd327b.png)

タブの整理の方法としてグループ化する方法もありますが、探すのが面倒ですし、タブを消しても履歴から簡単にアクセスできるので、私はこのchrome拡張機能でどんどん消していくという方法が好みです
写真（Photo Library）へのアクセス許可を任意のタイミングで求める

Info.plist のprivacy設定をしていると、フォトライブラリへのアクセスのタイミングでアラートが出るのですが、ユーザーの操作を邪魔したくない場合など、あらかじめ許可を得ておきたい場合などはこちらで。

```swift

PHPhotoLibrary.requestAuthorization { (status) in
    if status == .authorized {
        DispatchQueue.main.async {
            // 許可された場合の処理        
        }
    }
}
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Vue CLIでプロジェクト作成をしたらErrorになったときのこと

Vue CLIでプロジェクト作成をしたらErrorになったので、その時の履歴です。
原因はnpmが古すぎて入れられないpackageがあったようです。

# Vue CLIでプロジェクト作成

まずはvue/cliをインストール

```
$ npm install -g @vue/cli
```

プロジェクトを作成します。ここではchatという名前にしました。

```
$ vue create chat
```

オプションは以下を選択

```
❯ Default (Vue 3 Preview) ([Vue 3] babel, eslint) 
❯ Use NPM 
```

ほかは聞かれなかった気がする :thinking:
（選ぶものによるのかな）

プロジェクトができたらディレクトリに移動して起動

```
 $ cd chat
 $ npm run serve
```

ここでエラーが出ました

```
 ERROR  Error: Cannot find module 'vue-loader-v16/package.json'
```

# ログを確認

ログを確認すると、警告が出てました。
npmが古いらしい

```
WARN  You are using an outdated version of NPM.
there may be unexpected errors during installation.
Please upgrade your NPM version.
```

バージョンを確認。
確かに古い…

```
$ npm -v
6.4.1
$ node -v
v10.15.3
```
# Nodeのバージョンを変える
Nodeのバージョンを上げるとnpmのバージョンも上がるので、Nodeのバージョンをあげます。

私はnodenvを使っているので、nodenvでバージョンを変えます。

```
$ nodenv versions
  system
* 10.15.3 (set by /Users/okada/.nodenv/version)
  12.19.0
  14.16.0
$ nodenv local 14.16.0
```

バージョンが変わったことを確認

```
$ nodenv versions
  system
  10.15.3
  12.19.0
* 14.16.0 (set by /Users/okada/project/chat/.node-version)
$ node -v
v14.16.0
$ npm -v
6.14.11
```

生成された``.node-version``はコミットしておきます。
（あとでどのバージョンで作ったかわかるように）

# もう一度インストール

もう一度インストールしてから起動

```
$ npm i
$ npm run serve
```

立ち上がりました :clap: 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11545/f7bf44f2-5d09-6f7a-5f64-a3da1dc6da15.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11545/fd969761-a866-c858-094d-b72c81e87f90.png)
SAM+Node.jsでLambdaをInvokeした際に「Error: Cannot find module 'luxon'」が出た時の対処法

## 問題点
以下でluxonをインストール

```
npm install luxon --save-dev
```

package.jsonに以下が追加される

```package.json
  "dependencies": {
    "luxon": "^1.26.0"
  }
```

SAM+Node.jsでLambdaをInvokeした際に以下エラー発生

```bash
sam local invoke TranslationFunction --event request.json
Invoking index.handler (nodejs12.x)
Skip pulling image and use local one: amazon/aws-sam-cli-emulation-image-nodejs12.x:rapid-1.20.0.

(中略)

2021-03-12T22:47:33.403Z	undefined	ERROR	Uncaught Exception 	{"errorType":"Runtime.ImportModuleError","errorMessage":"Error: Cannot find module 'luxon'\nRequire

(中略)
```

## 原因
以下の実行に問題あり

```bash
npm install luxon --save-dev
```
## 解決策
### まずはアンインストール
```bash
npm uninstall luxon --save-dev
```

### 再度インストール(オプションを変更する)
```bash
npm uninstall luxon --save
```
### package.jsonを確認
以下が追加されていればOK

```package.json
  "dependencies": {
    "luxon": "^1.26.0"
  }
```

## 参考
* https://stackoverflow.com/questions/42880987/serverless-framework-with-aws-lambda-error-cannot-find-module
ずっとFPGA初心者（その５：遅延）

# 遅延
今回は、Delay（遅延）を実現する。用いるボードおよび開発環境は、すべて[その１](https://qiita.com/infinite1oop/items/4b0f03b97ed859fbd954)と同じである。

## 実現したいこと
ボタン押下3秒後にLED点灯。

## VHDLコード

```vhdl:ClkLedDelay.vhd
library ieee;
use ieee.std_logic_1164.all;

entity ClkLedDelay is
  port (
    BTN: in std_logic;
    CLK: in std_logic;
    LED: out std_logic);
end ClkLedDelay;

architecture RTL of ClkLedDelay is
constant CYCLE : integer := 3*50000000;  -- ①
signal CNT: integer range 0 to CYCLE-1 := 0;  -- ②
signal TimerFlag: std_logic := '0';  -- ③
signal LedFlag: std_logic := '1'; -- Off  ④
	
begin	
  process (BTN, CLK) -- ⑤
    begin
      if (BTN'event and BTN='0') then	-- Pushed
        TimerFlag <= '1'; -- ⑥
      end if;	
      if (rising_edge(CLK)) then
        if (TimerFlag='1') then
          if (CNT = CYCLE-1) then
            LedFlag <= '0'; -- On  ⑦
          else
            CNT <= CNT+1;  -- ⑧
          end if;
        end if;
      end if;
    end process;
	
    LED <= LedFlag; -- ⑨
end RTL;

```

コードの解説。

①：3秒の定義（用いるボードのクロックは50MHzのため）
②：カウンタ(0で初期化)
③：カウンタ開始のためのフラグ
④：LED制御(On/Off)フラグ(負論理)
⑤：ボタン(BTN)やクロック(CLK)に変化があったときに処理されるProcess文
⑥：ボタン押下時にカウンタ開始フラグOn
⑦：クロック立ち上がり、かつ、カウンタが3秒経過後に、LED制御フラグOn
⑧：クロック立ち上がり、かつ、カウンタ開始フラグOnの時に、カウンタインクリメント
⑨：LED制御フラグの値をLEDに代入

⑤と⑨とは同時に実行されることに注意。[その２](https://qiita.com/infinite1oop/items/b4d9b644ac59ed422524)参照。

C'est tout!
GitHubにAPIキーを漏洩させない方法(dontenv-rails)

#導入方法
```:Gemfile
gem 'dotenv-rails'
```

```:ターミナル
$ bundle install
```

gemを入れた後にアプリケーションのフォルダの直下に.envファイルを作成します。
.envファイルにAPIキーなどGitHubで管理したく無いものを記述します。

```:.env
OPEN_WEATHER_MAP_API="APIキー" #GitHubに管理させたく無いものを記述します
```

ENV['OPEN_WEATHER_MAP_API']など使いたいところに書いたら
.envファイルに記述しているものを参照にしてくれます。
**[注意]**Rubyで管理しているためjsファイルやなどで書く場合は書き方が少し変わります



#.gitignoreに.envを追加する

Gitで管理したくないファイルやフォルダは.gitignoreを書くことで
GitHubに.envファイルをあげないようにできます。

```:.gitgnore
/.env    #一番下に追加する
```

#確認方法
```:ターミナル
$ git status
```

.envファイルが表示されていなかったら成功です。
git pushをしてもGitHubに反映されません。
Qiita Daily Survey memo 2021.03.13

# Qiita Daily Survey memo 2021.03.13
Qiita の記事を可能な限り毎日読むために、読んだmemoを公開することでモチベーションを維持しようという試み。

## [「CSS完全に理解した」でCSS完全に理解する](https://qiita.com/ichimonji_haji/items/96fb2e7c482ed77dea07)
ichimonji_haji さんの記事。
いろいろなところで目にする「CSS完全に理解した」について、実は意図的にあれをやろうとすると大変という導入から、「CSS完全に理解した」を再現することでCSSを理解しようという試みです。
様々なアプローチでCSSを完全に理解しようと試みられています。
ただでさえ技術的な記事としてしっかり書かれているのに加えて、言葉選びが面白く「完全に理解していない」などの非常に面白いワードが登場します。
こういった遊び心あふれる記事を高い技術力と合わせて書けるようになりたいです。


## [【Vue/Firebase】ユーチューバー関連のサイトを立ち上げた話【個人開発】](https://qiita.com/ok-bokujou/items/38393da89bc14eaa5c34)
ok-bokujou さんの記事。
タイトルの通り、YouTuber関連のサイトを立ち上げた、という記事になります。
概要欄と途中に出てくる図、説明の流れから、情報を整理するのが非常に上手な方という印象を受けました。
ものすごくすっきり頭に情報が入ってきました…SUGOI。
開発の流れ、各フェーズで行ったこと、使用したツールなどを紹介してくださっています。

コメント書いてからもう一度読み返しましたが、本当に綺麗です…。


## [機械学習を使って一番安い家賃の家に住む。〜スクレイピング編〜](https://qiita.com/tommy24/items/52048b98bc1169b95c05)
tommy24 さんの記事。
タイトルの通り、いい感じのおうちに住むためにスクレイピングでお家の情報を取得するという記事になります。
この後、機械学習を行うということで続きの記事も楽しみです。
スクレイピングの流れでは、コメントにもあるとおりpd.read_html()の関数を初めて知りました。
スクレイピングにかかった時間なども書かれているため参考になります。
次の引っ越しに向けてお家の情報を調べなくてはなので、参考になりました。


## [【音声生成+機械学習】ポケモンの鳴き声をWaveGANで生成する](https://qiita.com/zassou65535/items/5a9d5ef44dedea94be8a)
zassou65535 さんの記事。
流行りのGANでポケモンっぽい音声を生成してみた、という内容を説明してくださっている記事になります。
音声版のGANでWaveGANというのがあるのですね…学びです！
GANは試したことがないため、流れも含めて勉強になりました。説明もとても分かりやすいです。

やはりGANと言えば真っ先に思い浮かぶのは画像生成ですが、zassou65535 さんも余談にて画像生成もされているとのこと…SUGOI。
VRChat の住人ということで、お会いしたらよろしくお願いいたします…！
Prettierについて


# Prettierについて

## Prettierの利用方法

### package.jsonの生成

```
npm init -y
```

### Prettier のインストール
```
npm install prettier@2.1.1 -D
```
-Dは--save-devの略で、ローカルインストールを意味する。

### パスを通す
```bash
export PATH=$PATH:./node_modules/.bin
```

### Prettierの実行
```
prettier ファイル名 --write
```

## ESLintとの併用
* Prettierはあくまでコードフォーマッター
* ESLintのような構文チェック機能はない
* Prettierでコードフォーマット、ESLintで構文チェックすることで、双方の利点を活用する
* eslint --fixだけでコードの整形と構文チェックを可能とする

### 併用に必要なパッケージのインストール
```
npm install eslint eslint-config-prettier eslint-plugin-prettier -D
```

* eslint（ESLint 本体）
* eslint-config-prettier → ESLint のフォーマット関連のルールを全て無効化し、Prettierに任せる）
* eslint-plugin-prettier → PrettierをESLint上で実行可能とする

### .eslintrcの設定
```bash
{
  "env": {
    "browser": true,
    "es6": true
  },
  "extends": [
    "eslint:recommended", // esLintの推奨設定をチェック
    "plugin:prettier/recommended" // prettierの推奨設定をチェック
  ],
  "rules": {
　　 // prettierの場合のエラールール設定(.prettierrcに別ファイルとして記載しても良い？)
    "prettier/prettier": [
      "error",
      {
        "singleQuote": true,
        "trailingComma": "es5"
      }
    ]
  }
}
```

### eslintの実行
```bash
eslint --fix ファイル名 
``` 

## git commit時にeslint --fixが実行されるようにする

### パッケージのインストール
```bash
npm install lint-staged husky -D
```

### package.jsonに以下を追加

```json
{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.js": "eslint --fix"
  }
}
```




# 参考
* https://qiita.com/soarflat/items/06377f3b96964964a65d
* https://blog.ojisan.io/eslint-prettier
* https://www.tam-tam.co.jp/tipsnote/javascript/post11934.html
*
スクリプト言語の作成とメモリリークのデバッグの話

## スクリプト言語作成のきっかけ

文法をパースするプログラムを自作してみたところ正規表現でパースできないことがわかった。

正規表現は有限回の文法をパースできるが無限回の文法をパースできないことが原因だ。正規表現の限界を感じた。

BNFのBisonなら無限回の文法をパースできるのでBisonを使ってみようと思った。

## Yash

Bison記述が爆速化するVisual Studio Codeの拡張機能。

Flex/Bisonの構文を強調表示するだけでなく、自動的なコード診断でエラー表示するリンターでもある。

## Bisonを使ってみた感想

Yaccが1970年代、Bisonが1980年代に開発された。歴史のあるパーサー生成器だ。

月並みな表現だがBisonはすごいと思った。BNFを受け付ける範囲が広い。+や**などで演算子の優先順位や結合法則を気にして異なる非終端記号を使ってBNFを記述するのかと思っていたが、同列に記述できた。マニュアルに、異なる演算子の相対的な優先順位は、それらが宣言される順序で決まるとある。

## var変数とクロージャ関数を作った

JavaScriptのようなvar変数を作った。関数呼び出しにC++のmapを付けることでvar変数を作った。

後からクロージャ対応するのは二度手間になると思ったので最初からクロージャ対応した。関数呼び出しの戻り値が関数ならmapを保持したままにするようにした。異なる関数呼び出しは異なるmapを保存するようにした。

## スクリプト言語作成の感想

メモリリークのデバッグが大変だった。

デバッガで調べる方法ではメモリリークの原因を特定できなかったが新たなデバッグ法で解決した。その方法とはデバッグのためにプログラミングすることだ :sunglasses:

## メモリリーク問題

フィボナッチ数の計算でメモリが1ギガを超えた :sob:

### C++のmapによるメモリリーク対策

mallocのアドレスをキーにして型ごとにC++のmapに登録し、freeしたらmapから削除する。これによりfreeされず残ったmallocの数が型ごとにわかる。

実行後に数が多いことでメモリリークが起きたことはわかったが、原因を特定できなかった。実行するたびにメモリのアドレスがランダムに変わるからだ。

### ASLRと自作mallocによるメモリリーク対策

ASLR(address space layout randomization)とはアドレス空間配置のランダム化のことだ。

gccなら-Wl,--disable-dynamicbaseで、clなら/link /DYNAMICBASE:NOのオプションでメモリのアドレスがランダムになるdynamicbaseの機能を無効化した実行ファイルを作成できる。peflags -vで実行ファイルからdynamicbaseのフラグが消えることを確認できる。

私の環境では、大域変数のメモリアドレスを固定化できたが、mallocのメモリアドレスを固定できなかった。

大域変数に大きな領域を取ってメモリを割り当てる単純なmallocを自作した。mallocのアドレスが大域変数になりメモリアドレスを固定化できた。

メモリリークの疑いのあるメモリアドレスをmallocかfreeする場所でブレークポイントを設定することができ、メモリリークの原因を特定できた。

## 車輪の再発明のススメ

車輪の再発明はよくないという格言があり、mallocを自作しようと思わないかもしれない。var変数を作るときC++のmapを使った。

しかし、格言に例外もありえる。メモリリークの原因を特定できたようにmalloc自作は可能性を広げると思う。標準のmallocはプログラマーが期待する機能を提供していないと思う。バッファオーバーフローを防ぐためメモリ参照ごとに範囲チェックをしたら役に立ちそうだと思う。

## 参考

- [パース](https://e-words.jp/w/%E3%83%91%E3%83%BC%E3%82%B9.html)  IT用語辞典 e-Words
- [AddressSanitizer](https://github.com/google/sanitizers)  LinuxやOS Xで動作するバッファオーバーフローなどの検知ツール。
- [Linux: mallocで返されるアドレスを固定する](https://qiita.com/aosho235/items/852d88518f1709741d30)  Linuxでmallocアドレスを固定できるという記事。
- [Bison のマニュアルの日本語訳](http://guppy.eng.kagawa-u.ac.jp/2019/Compiler/bison-1.2.8/bison-ja_toc.html)

## まとめ

Bisonを使ってスクリプト言語を作成してみた。デバッガで調べる方法ではメモリリークの原因を特定できなかったが、自作mallocで解決した。

GitHubリポジトリ: [QKumaScriptのソースコード](https://github.com/querykuma/QKumaScript)
Open Watcom Cの呼び出し規約

Open Watcom C(x86 16ビット)の呼び出し規約を確認してみました。サンプルコードを書いてコンパイルして、.oをwdisで逆アセンブルして確認します。

まず関数名ですが、デフォルトでは

test() -> test_

になります。オプションで一般的な\_testにすることもできます。データはデフォルトで前に_が付きます。

引数はレジスタが最初に使われ以下のようになっています。

void test(short a) -> a = AX

void test(short a,short b,short c,short d) -> a = AX, b = DX, c = BX, d = CX

void test(short far *b, short a, short c) -> b = DX:AX, a = BX, c = CX

void test(short a, short far *b, short c) -> a = AX, b = CX:BX, c = DX

32ビット値はAX,DXかBX,CXが使われるようです。

引数がレジスタに収まらない場合はスタックに積まれます。積んだ分をreturnする時に直値で取り除きます。

void test(short a, short b, short c, short d, short e) -> ret 2

エラー処理を一箇所にまとめている場合、スタックに詰まれた数ごとに別々に用意する必要がでてくるので、ちょっと厄介です。

これを調べているのはTEENのC用のライブラリのアセンブラコードがTurbo Cの呼び出し規約で作られているのOWにポートしているためでした。Turbo Cはレジスタは使わずすべてスタックに積み上げてるようです。

wccで-ecc -zp1を指定するとTurbo Cなどの呼び出し規約になり、ライブラリもそのまま使えるようです。
２個目以降のサーバーを動かすには、公開鍵認証が必要である。

<h2>複数のサーバーをクライアントで操作する

異なるサーバーを契約したので、ログインしようとしたのですが、二つ目のサーバーに入る事ができませんでした。その時のエラー内容が

```
WARNING: POSSIBLE DNS SPOOFING DETECTED! 
```
これは「複数のサーバーの設定がありますよ。以前のサーバーの内容が残ってますよ」という時にでます。よって、サーバー再構築の時はkonwn_hostsの内容をrmコマンドで、削除する事でどうにかなりましたが、今回は二つのサーバーの内容を両立する必要があります。

それには.ssh/configの内容を変える必要があります。サーバーに入っていない状態で、

```
cd ~/.ssh
ls
```
をすると、

```
known_hosts config 鍵のファイル等
```
が入っている事がわかります。この中のconfigをvimで確認します。https://qiita.com/passol78/items/2ad123e39efeb1a5286b
が詳しいです。IdentityFileを新しく編集しましょう。この時のパスはサーバーの秘密鍵情報があるファイルに、パスを通す必要があります。cd ~/.sshに置いておくと簡単なので、この場所に秘密鍵をコピーして置いておくと、~/.ssh/秘密鍵にする事ができます。

　ここまで設定をして、再度ログインを試みると、今度は

```
WARNING: UNPROTECTED PRIVATE KEY FILE! 
や
bad permissions
```
がエラーとして排出されます。これは秘密鍵の権限が緩いから、鍵として使えないよ。を意味します。
権限を確認しましょう。サーバーの秘密鍵までのパスをもう一度使って、

```
cd ~/(サーバーのパスまでの道)
ls -la
```
これで権限を確認できます。権限は、root権限以外はダメです。という600にしたい。権限が６００のときは、以下のようになります。

```
drwx------
```
それ以外の場合は権限が600以外の数値になっていることを示すので、

```
chmod 600 ~/(サーバーまでの道)
```
これで権限を変更しました。この場所で少し躓きましたが、known_hostsの権限を変更しても意味はありません。必ず変更するのは、秘密鍵の権限の変更であるという点に注意しましょう。

これで当初の目標であるSSH接続ができます。最初のサーバーでは、SSH接続するのに、必ずしも公開鍵認証を必要としませんが、2個以上のサーバーを動かす時、１個目のサーバーの情報が残っているので、別のサーバーであることを伝える必要があります。
nvmで固定のNode.jsのバージョンを使わせる方法

## nvmのインストール方法からnvmの使い方について

以下が参考になる
* https://qiita.com/ffggss/items/94f1c4c5d311db2ec71a

## プロジェクトで固定のNode.jsのバージョンを使わせる方法

versionを"v12.21.0"で固定する場合

```
$ echo "lts/*" > .nvmrc
```

最新のltsで固定する場合

```
$ echo "lts/*" > .nvmrc
```

nvm installの実行(初回のみ)

```
$ nvm install
Found '/path/to/project/.nvmrc' with version <v12.21.0>
Now using node v12.21.0 (npm v6.14.11)
```

nvm useの実行(初回のみ)

```
$ nvm use
Found '/path/to/project/.nvmrc' with version <v12.21.0>
Now using node v12.21.0 (npm v6.14.11)
```

## 参考
* https://scrapbox.io/ebiken/.nvmrc
Nginxってなんぞ？？(入門編)

#まず始めに

この記事はNginxについて、自己理解のために簡単に仕組みと使い方をまとめたものです。







#Nginx(えんじんえっくす)って？？
　ミドルウェアの中のWEBサーバソフトフェアの1つ
　**オープンソースソフトウェア(OSS)**で、無償で誰でも利用可能
　2004年10月に最初の公開リリースが行われ、10000以上の同時コネクションを処理する際の
　パフォーマンス課題である「C10k問題」への解決策として本ソフトウェアを作成された
　よくApacheと比較されていますが、どちらも設定・追加モジュール次第である程度対応できます。
　Nginxは高速で高負荷に強く、柔軟な設定を行うことができます。
　また大量の動的コンテンツの処理には不向きで、設定情報などはApacheの方が充実しています。

　
#Nginxの基本機能
　HTTPサーバーとしての基本的な機能はもちろん、以下のような機能を備えています。
　・リバースプロキシ（キャッシュ機能あり）
　・負荷分散（ロードバランサ）
　・FastCGIサポート（キャッシュ機能あり）
　・URI Rewrite
　・WebSockets
　・静的ファイル・インデックスファイルの処理、自動インデクシング
　・TLS/SSL 

主な特徴的機能の説明をまとめました。　
####リバースプロキシ
　特定のサーバへのリクエストが必ず通過するように設置されたプロキシサーバ。
　不特定多数のクライアントに対するアクセス制限や、キャッシュ機能によるサーバの負荷軽減のため用意される。
####負荷分散
　コンピュータネットワークにおける技法の一種。
　クライアントとサーバの間に設置し、複数のサーバが分散処理を行う。
　また、故障や保守によりサーバが停止した際にも、サービスを続行させることができる。
####FastCGIサポート
　FastCGIとは、Webサーバ上でユーザプログラムを動作させるためのインタフェース仕様の一つ。
　従来のCGIのリクエスト毎に新しいプロセスを作成する代わりに、
　FastCGI は永続的なプロセスを使用して一連のリクエストを処理する。
 
 
 
#Nginxのインストール
　nginxの[公式サイト](http://nginx.org/en/download.html)からZIPファイルをダウンロード 
　nginx.exeをダブルクリック
　ブラウザで http://localhost/ を開いてみる

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1195805/0a2b994f-2ce1-e622-fe4f-90953543fa0b.png)

上のページが出ればインストール完了です。
　
　`sudo nginx -s quit`
　で終了します。
 
 linux上でインストールする場合は　`yum install nginx` 
　起動：`systemctl start nginx`
　停止：`systemctl start nginx`
　
 
#Nginxで設定できること
・アクセス制限
　　Basic認証(特定パスへの制限)
　　大量リクエスト制限(コネクション数の抑制)
・リクエストの書き換え
　　リダイレクト
　　エラーページを返す(後続のサーバ・アプリケーションでの特定ページの表示)
・gzip圧縮転送
　　圧縮して転送
　　あらかじめ圧縮してあるファイルを転送

　その他の項目、書き方は[公式ドキュメント](http://nginx.org/en/docs/)や他記事を参照ください。


#最後に

Apacheに比べ、細かな設定を行う際の情報が少なく初心者には難しいかもしれませんが
アクセス数の多いサイトやアプリには必須といっていいほど、需要は増えていると思います。
また、ApacheとNginxを組み合わせることで、どちらのメリットを生かした開発を行うことができます。
今後もより深く理解できるように、細かな機能などの学習・紹介ができればと思います。
最後まで読んでいただきありがとうございました。
yukicoder contest 286 参戦記

# yukicoder contest 286 参戦記

## [A 1422 Social Distance in Train](https://yukicoder.me/problems/no/1422)

奇数の場合には1種類しかないのはすぐ分かる. 偶数について、N=2 の場合には「ox」「xo」の2つ、N=4 の場合には「oxox」「oxxo」「xoxo」の3つ、N=6 の場合には「oxoxox」「oxoxxo」「oxxoxo」「xoxoxo」の4つ……の辺りでピンとくるはず.

```python
N = int(input())

if N % 2 == 0:
    print(N // 2 + 1)
elif N % 2 == 1:
    print(1)
```

## [B 1423 Triangle of Multiples](https://yukicoder.me/problems/no/1423)

非退化三角形ってなんだよ、3頂点が同一直線上にあるってことは面積が0だけど、それって三角形なのかよとあまりの分からなさに混乱したが、非退化三角形でググったら Codeforces の解説が出てきて、満たすべき条件は分かったので解けた…が、単に A✕B✕C や lcm(A, B, C) でも良いことには全く気づいてなかった.

```python
from math import gcd


def lcm(x, y):
    return x * y // gcd(x, y)


T = int(input())

for _ in range(T):
    A, B, C = map(int, input().split())
    x = lcm(lcm(A, B), C)
    print(x + A, x + B, x + C)
```
Digdagの画面上部のヘッダの色を変えるChrome拡張機能(ローカル)

# はじめに

Digdagの開発中に誤って本番環境のワークフローをRUNしないよう、
Digdag画面上部のヘッダの色を変えるChrome拡張機能を作ったので、
簡単ですが作り方を紹介します。

今回はローカルでhostsをいじってホスト名を操作した形で環境分離風にして試してます。

```shell:/etc/hosts
127.0.0.1 localhost      # ローカル
127.0.0.1 prd-digdag.com # 本番
```

# やりたいこと

この黒っぽい色を環境ごとに変えたい。
本番はそのまま。ローカルは別の色にしたい。
![スクリーンショット 2021-03-13 2.06.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48316/b963c616-5402-0500-ae37-91392e77f8e8.png)

# 実装方法

適当にディレクトリを作り(dig-color)、以下の2ファイルを作るだけ。

```
dig-color
├── content.js
└── manifest.json
```


```manifest.json
{
    "name": "Dig Color",
    "version": "1.0.0",
    "manifest_version": 2,
    "description": "DigDag Color Change For Environment",
    "content_scripts": [{
      "matches": ["http://localhost:65432/*"],
      "js": [
        "content.js"
      ]
    }]
  }
```
※matchesのところは自分が使うホスト名に合わせて設定します。

```content.js
/* ロード時にナビゲーションバーの背景色を変える */
window.onload = function() {
  var nav = document.getElementsByTagName('nav');

  if(location.host == "localhost:65432"){
    nav[0].style.backgroundColor = '#008b8b';
  } 
};

```

※localhostは他のポートでも使ってたので、hostnameではなくポート番号込みのhostで判定してます。こちらもご自身の環境に合わせてよしなに設定します。

# Chrome拡張機能を読み込む

1. chrome://extensions/を開く。

2. デベロッパーモードをONにする
  (2021/03/13時点の最新版だと以下のようなトグルボタンが右上の方にあります）
  <img width="200" alt="スクリーンショット 2021-03-13 1.48.42.png" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48316/c67b9ee7-a6c7-b023-4556-795a9b753994.png?100x100">

3. "パッケージ化されていない拡張機能を読み込む"ボタンが出てくるのでクリック
  <img width="400" alt=スクリーンショット 2021-03-13 1.45.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48316/c81f37c2-0e87-7226-d6cc-4feb5eae4f92.png">

4. 先ほど作ったファイルを格納したディレクトリ(dig-color)を選択

これで設定完了。

## 各環境にアクセスすると色が変わっている。

以下のように環境ごとにナビゲーションバーの色を変ることができます。

## ローカル環境
![スクリーンショット 2021-03-13 1.25.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48316/ae7e3783-8c4d-3aef-94d7-450e0bd14388.png)

## 本番環境
![スクリーンショット 2021-03-13 1.25.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48316/b0732ef7-1e18-bace-2d45-24593162526c.png)

はい。出来上がり。

# おわりに

今回はローカルで擬似的な環境分離風に試しましたが、
ローカルではなく、実際に利用してる環境に対して動かすと挙動が異なる可能性もありますので、ご了承ください。
【TypeScript】Utility TypesのReturnTypeを深く理解する

# この記事は何？
この記事は、Utility Typesの一つである**ReturnType**について深く理解する記事です。
Utility Typesってそもそも何？という型（方）は以下の記事を御覧ください🙇🏻
👉 [TypeScriptのUtility Typesを理解して活用する](https://qiita.com/NOMURA_keibyou38/items/84caee0657f57650577d)

そもそも、TypeScriptって何？って型は以下を御覧ください
👉 [JavaScriptを知っている方がTypeScriptをなんとなく理解するための記事① ~はじめに~](https://qiita.com/NOMURA_keibyou38/items/06a3218de3ff480ce9de)

# ReturnType＜Type＞とは
TypeScript公式には以下のように書かれています。
> Constructs a type consisting of the return type of function Type.
> 関数型の戻り値の型で構成される型を構築します。
> https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype

つまり、ReturnTypeは、**関数の戻り値の型**から新たな型を生成します。

実際にコードの場合、以下のように表すことが出来ます。

```typescript
type hogehoge = ReturnType<関数型>
```


```typescript
// type MojiType = string
type MojiType = ReturnType<() => string>; // 返り値がstringの関数

// type ObjectType = { name: string; old: number; }
type ObjectType = ReturnType<(value: string) => { name: string; old: number }>; // 返り値がオブジェクトの関数

const callAnimal = (animalName: string, owner: string): void => {
  console.log(`${animalName}！${owner}の近くにおいで！`);
};

// type AnimalType = void
type AnimalType = ReturnType<typeof callAnimal>; // 返り値がvoidの関数

```

このReturnType<>はどのようなシーンで利用するのでしょうか？

これは個人的に考えた用途なのですが、サードパーティーの関数を利用する時に使えるのではないかと考えています。

例えば、以下のような関数を含むパッケージをインストールするとします。

```typescript:calculateByAllOperator.ts
interface Calculate {
  addition: number;
  subtraction: number;
  multiplication: number;
  division: number;
}

export const calculateByAllOperator = (
  num1: number,
  num2: number
): Calculate => {
  return {
    addition: num1 + num2,
    subtraction: num1 - num2,
    multiplication: num1 * num2,
    division: num1 / num2,
  };
};
```

そして、この関数を利用してみます。

```typescript
// calculateByAllOperator関数をimport
import { calculateByAllOperator } from "./calculateByAllOperator";

// 予めcalculateByAllOperator関数の返り値の型を`ReturnType`で作る
type FunctionReturnType = ReturnType<typeof calculateByAllOperator>;

// 返り値の型でオブジェクトを定義
const result: FunctionReturnType = calculateByAllOperator(5, 2);

// calculateByAllOperatorの結果を使う
console.log(
  `+: ${result.addition}, -: ${result.division}, *: ${result.multiplication}, /: ${result.subtraction}`
); // +: 7, -: 2.5, *: 10, /: 3
```

このように、`ReturnType`でオブジェクトの型を作っておきます。
この関数の返り値から作った型を使えば、誤った型を持つオブジェクトを出力することが防げます。
また、わざわざplusOnecalculateByAllOperator関数の返り値の型を`interfece`で作る必要もありません。

また、React&TypeScriptであれば、以下のように使っても良いかもしれません。

```jsx
import { calculateByAllOperator } from "./calculateByAllOperator";

type Props = ReturnType<typeof calculateByAllOperator>;

const hogehogeComponent: React.FC<Props> = (props) => {
 ...
}
```

以上のように、利用できるかと思います。
他にも、良い利用方法があれば是非コメント欄で教えて下さい！

# おわりに
今回は、Utility TypesのReturnTypeについて紹介しました。
是非、ご活用ください！

# 参考
- https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype
Salesforce勉強：Trailhead紹介

はじめ
　■Trailhead のしくみ
　　テストまたは Challenge を完了することでポイントを獲得できます。モジュールの単元をすべて完了すると、プロファイルに新しいバッジが表示されます。

　■Trailhead の対象者
　　すべての人が対象です、英語、ドイツ語、日本語、フランス語、スペイン語、ポルトガル語の 6 つの言語利用可能
　■開始方法
　　いくつかのオプションがあります。Salesforce、Google、LinkedIn、またはメールアドレスを使用して Trailhead にサインアップできます。
　　ソーシャル ID：転職した場合でも Trailhead プロファイルを維持できます。
　　既存の Trailhead アカウントにリンク（プロファイル→設定→接続）、既存の Trailhead アカウントにバッジなどがある場合、マージできます。
　　会社の Salesforce ログイン：Trail Tracker アプリケーション（従業員の学習状況把握可能）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/08e3f016-d6b3-c529-56ae-46b257d15f8c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/64e024e4-2f91-bc7e-9ea5-fc402d774fd4.png)
　　
　　リンク：
　　　https://trailhead.salesforce.com/

　■Trailhead Playground
　　定義：ハンズオン Challenge、新機能の学習、カスタマイズのテストに使用できる組織です。challenge別でも作成可能。
　　デフォルトレイアウト：「Lightning Experience」に配置、右上の写真をクリックし、[Salesforce Classic に切り替え] をクリックすると、classicに変更可能
　　ユーザ： 2 人しか作成できない。
　　期限：継続的に使用していれば、Trailhead Playground の期限が切れることもありません。

　◆ハンズオン Challenge可能環境
　　Developer Edition 組織とTrailhead Playground
　　　区別：
　　　　Trailhead Playground：Trailhead 固有のデータとインストール済みの未管理パッケージが付属しています。Trailheadから直接作成とアクセス可能
　　　　Developer Edition：上記のTrailhead Playgroundのメリット以外、差異がない。

操作方法

■トレイル
　順序付けされたモジュール、プロジェクト、またはその両方のグループのことで、新しいスキル、製品、役割を学習するためのガイド付き学習パスとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/54e60e1c-2c52-8592-b75a-e4cf13d0eafb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/7e3909f4-4546-32f1-fca9-4a02cf0cf1b0.png)

■モジュール
　1 つの学習トピックが取り上げられます、指定の知識勉強したい場合、検索可能。（経験者の知識補強するため）
　ハンズオン Challenge またはテスト含まれている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/692addf9-de43-b48f-ddf2-e0c4ea42df6b.png)

■プロジェクト
　一連の実践ステップです。実際操作（ハンズオン Challenge）だけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/4008cf65-7754-108f-bf7f-d92ac606d08e.png)

プロジェクトとハンズオン Challenge の違い
　ハンズオンChallengeでは満たすべき要件セットが与えられるのに対して、プロジェクトではステップごとの手順が与えられる。
■Trailmix
　任意のモジュール、トレイル、プロジェクト、Superbadgeなど自由に組み合わせる。一意の URL を送信することで誰とでも共有できます。

※あるモジュールまたプロジェクトの全部ステップ完成すると、バッジ自動付与。
　バッジは右上の写真クリックし、プロファイルから確認可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/b9b8c218-62f2-7a3e-aa1f-407319f5d2e5.png)



■資格
　二つ種類：SuperbadgeとSalesforce 認定資格
　　Superbadge：指定のバッジ集、一連のトレイル完成すると、取得する。Superbadge は複雑で一定のスキルが必要になります。
　　Salesforce 認定資格：指定場所で、受験を参加して、合格したら、取得する。
　　　※一部の受験の前提条件は指定のSuperbadge完成必要。

[Credentials (認定資格)] タブからSuperbadgeまた認定資格一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/bfe43e3a-644c-d96d-b060-bc4c97733592.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/b3625156-3228-1752-d1b6-dcbe96b8d745.png)

■Trailhead GO
　スマートフォン、padなどでどこでも利用できるApp

■myTrailhead（社員向け）
　myTrailhead には社内の他のユーザのみがアクセスできることと、各社のカスタムコンテンツとブランドが含まれることです。
【Swift】2つの??について

# Swiftの??

1. オプショナルの変数にデフォルト値を指定する
1. ダブルオプショナルな変数を取り出す

## Nil-Coalescing Operator
??演算子（Nil-Coalescing Operator）は、オプショナルの変数がnilだった場合の別の値を指定することが可能です。

```swift
var str: String?
print(str ?? "default value")
// 結果: default value
str = "hoge"
print(str ?? "default value")
// 結果: hoge
```


## 存在がオプショナルであるオプショナル変数


```swift
let window = UIApplication.shared.delegate?.window // UIWindow??という型で取り出せる

// ??での取り出し方
guard let frame = UIApplication.shared.delegate?.window??.frame { return }
```

アンラップする方法は他にもあります。（シンプルに2回アンラップする）
[[Swift] ダブルオプショナルな変数をアンラップする方法 - YoheiM .NET](https://www.yoheim.net/blog.php?q=20190104)

### Double optionalとは？

[window | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623056-window) より抜粋

```swift
public protocol UIWindowSceneDelegate : UISceneDelegate {
   optional var window: UIWindow? { get set }
```
`var window: UIWindow?` ではなく、`optional var window: UIWindow?`となっています。
先頭に `optional`がついているのは、「プロパティもしくはメソッドの実装任意」ということを表しています。
[Protocols — The Swift Programming Language (Swift5.4)](https://docs.swift.org/swift-book/LanguageGuide/Protocols.html)のOptional Protocol Requirementsより
>You can define optional requirements for protocols. These requirements don’t have to be implemented by types that conform to the protocol. Optional requirements are prefixed by the optional modifier as part of the protocol’s definition.
(プロトコルのオプション要件を定義できます。 これらの要件は、プロトコルに準拠するタイプで実装する必要はありません。 オプションの要件には、プロトコルの定義の一部としてオプションの修飾子が接頭辞として付けられます。)

他には、
`UITableViewDataSource`の`numberOfRowsInSection` がoptionalなメソッドです。（TableViewにおいてセクション数は任意）

```Swift
optional func numberOfSections(in tableView: UITableView) -> Int // Default is 1 if not implemented
```

ダブルオプショナルな変数は「そもそもこの変数自体が存在しない可能性もある」ため、

* 1つ目の ? : 変数が実装されているか
* 2つ目の ? : 変数の値が設定されているか

で、2回のアンラップが必要になり、「??」という記載になるようでした。

# 補足

純粋な Swift ( Pure Swift ) にはオプショナルなメソッドは宣言できないようですが、
使い方はコメント欄でご教授いただきましたのでご参照ください〜
[Swift におけるオプショナルなメソッドについて真面目に考える – PSYENCE:MEDIA](https://tech.recruit-mp.co.jp/mobile/swift-optional-method/)
【TypeScript】Utility TypesのExtractを理解する

# この記事は何？
この記事は、Utility Typesの一つである**Extract**について理解する記事です。
Utility Typesってそもそも何？という型（方）は以下の記事を御覧ください🙇🏻
👉 [TypeScriptのUtility Typesを理解して活用する](https://qiita.com/NOMURA_keibyou38/items/84caee0657f57650577d)

そもそも、TypeScriptって何？って型は以下を御覧ください
👉 [JavaScriptを知っている方がTypeScriptをなんとなく理解するための記事① ~はじめに~](https://qiita.com/NOMURA_keibyou38/items/06a3218de3ff480ce9de)

# Extract＜Type, Union＞とは
TypeScript公式には以下のように書かれています。
> Constructs a type by excluding from Type all union members that are assignable to ExcludedUnion.
> ユニオンに割り当て可能なすべてのユニオンメンバーをタイプから抽出することにより、タイプを構築します。
> https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union

Extractは**"抜き取る"**という意味ですので、Extractは、
Typeの中から、指定した`Union型`を抜き取るという意味になります。

つまり、**Union型（"hoge" | "duga"）で記述した型をTypeから抜き取ることが出来ます。**

実際にコードの場合、以下のように表すことが出来ます。

```typescript
type hogehoge = Extract<Type, 抜き取るUnion型>
```

```typescript
// 3つの文字列のうち、"miso", "shoyu"を抜き取る
type Ramen = Extract<"shio" | "shoyu" | "miso", "miso" | "shoyu" > 

// "shio"は抜き取られていないのでアウト
const morning: Ramen = "shio"; // Type '"shio"' is not assignable to type 'Ramen'.
// "shoyu"は抜き取られているのでセーフ
const lunch: Ramen = "shoyu";
// "miso"は抜き取られているのでセーフ
const dinner: Ramen = "miso";
```

このように、特定の型を抜き取ることが出来ます。
また、関数型も抜き取ることが出来ます。

```typescript
const jiroRamen = ():string => {
  return "にんにくあぶらからめ"
}

// 3つの型のうち、返り値がstring型の関数を抜き取る
type Ramen = Extract<string | number | (() => string), Function >

// string型が返り値の関数は抜き取られているのでセーフ
const ramen: Ramen = jiroRamen;

// string型は抜き取られていないのでアウト
const morning: Ramen = "文字列"; // Type 'string' is not assignable to type '() => string'.
```

以上のように、Extractを使えば特定の型を取り除くことが出来ます。


# おわりに
今回は、Utility TypesのExtractについて紹介しました。
是非、ご活用ください！

# 参考
- https://www.typescriptlang.org/docs/handbook/utility-types.html#extracttype-union
アソシエーションを組んでいる特定のレコードのカラムを取得する

アソシエーションを組んでいる特定のレコードのカラムを取得する。
（最新のデータ編）

**BEFORE**

```rb:コントローラー
@last_asset = @account.assets.find(params[:id])
```

この記述でカラムのデータは取得できるようになったものの、求めている最新のデータは取得できずにいた。

# 自分なりの解決策

``` order('created_at DESC') ``` を使って最新のデータを取得できるようにする。
これしか情報がなく、findメソッドとこの記述を合わせて使おうとしていたが、
どうも併用できないらしい。記述の仕方が悪かったのかもしれませんが。



#　調べた結果
findではなく、find_byとorderなら併用できるようでしたので、メソッドの記述の順番を試行錯誤したら
答えにたどり着いた。

**AFTER**

```rb:コントローラー
@last_asset = @account.assets.order('created_at DESC').find_by(params[:id])
```
aptなどでパッケージをremoveした後

```$ XXX
-bash: /usr/bin/XXX: No such file or directory
```

てなるけど、本当は

```$ XXX
Command 'XXX' not found, but can be installed with:
sudo apt install XXXX
```
ってなって欲しい時は

コマンドキャッシュをクリアするコマンド（ちょっと嘘）。
``` hash -r ```

太古の昔はrehashだった。
【TypeScript】Utility TypesのExcludeを理解する

# この記事は何？
この記事は、Utility Typesの一つである**Exclude**について理解する記事です。
Utility Typesってそもそも何？という型（方）は以下の記事を御覧ください🙇🏻
👉 [TypeScriptのUtility Typesを理解して活用する](https://qiita.com/NOMURA_keibyou38/items/84caee0657f57650577d)

そもそも、TypeScriptって何？って型は以下を御覧ください
👉 [JavaScriptを知っている方がTypeScriptをなんとなく理解するための記事① ~はじめに~](https://qiita.com/NOMURA_keibyou38/items/06a3218de3ff480ce9de)

# Exclude＜Type, ExcludedUnion＞とは
TypeScript公式には以下のように書かれています。
> Constructs a type by excluding from Type all union members that are assignable to ExcludedUnion.
> ExcludedUnionに割り当て可能なすべてのユニオンメンバーをタイプから除外することにより、タイプを構築します。
> https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion

Excludeは**"除く"（除外）**という意味ですので、Excludeは、
Typeの中から、`ExcludedUnion`を除くという意味になります。

つまり、**Union型（"hoge" | "duga"）で記述した型をTypeから除外することが出来ます。**

実際にコードの場合、以下のように表すことが出来ます。

```typescript
type hogehoge = Record<Type, 除くUnion型>
```

```typescript
// 3つの文字列のうち、"miso"を除外
type Ramen = Exclude<"shio" | "shoyu" | "miso", "miso" > 

const morning: Ramen = "shio";
const lunch: Ramen = "shoyu";
// "miso"は除外されているので、エラー
const dinner: Ramen = "miso"; // Type '"miso"' is not assignable to type 'Ramen'.
```

このように、特定の型を取り除くことが出来ます。
同様に複数の型も取り除くことが出来ます。

```typescript
// 3つの文字列のうち、"miso", "shoyu"を除外
type Ramen = Exclude<"shio" | "shoyu" | "miso", "miso" | "shoyu" > 

const morning: Ramen = "shio";
// "shoyu"は除外されているのでエラー
const lunch: Ramen = "shoyu"; // Type '"shoyu"' is not assignable to type '"shio"'.
// "miso"は除外されているので、エラー
const dinner: Ramen = "miso"; // Type '"miso"' is not assignable to type 'Ramen'.
```

以上のように、Excludeを使えば特定の型を除外することが出来ます。


# おわりに
今回は、Utility TypesのExcludeについて紹介しました。
是非、ご活用ください！

# 参考
- https://www.typescriptlang.org/docs/handbook/utility-types.html#excludetype-excludedunion
HoudiniでExpressionのデバッグ

## お断り

これはメモであり、クオリティの高い記事ではないことを了承いただきたい。

## Expression

Houdiniでは、パラメータにプログラムを書き込むことができる。これをExpressionという（らしい）。この書き込むことができるスクリプトはHScriptという（らしい）

このExpressionをデバッグする時にprintなどしたいが、どこにもそれらしい記事がなかったのでここに書く。工程は3つ。

## 注意

print中はExpressionの結果がおかしくなる（当然だ、元のコードを消すのだし）。printデバッグで状況把握したら、Expressionを元に戻す必要がある

##１ Houdini TerminalからHoudiniを起動する

HoudiniのフォルダにUtilitiesというフォルダがあり、その下にHoudini Terminalがある。これを起動して、`Houdini`と打つとHoudiniが起動する

```
The Houdini 18.5.408 environment has been initialized.
~
➜  ~ Houdini

```

##2 ExpressionをExpression Editorで開く

１行なら必要ないが、たいていデバッグ時は複数行書きたいので、Editorを開く。

Expressionを書きたいパラメータで、右クリック->Expression->Expression Editorを選択し、Editorを起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65391/387af86f-d0c5-76fb-131e-267a4e032c7e.png)

##3 元のコードを消して、以下のように書く

たとえば、このようなコードの、chの結果が知りたい場合

```
ch("../resample1/length")/(bbox("../sweep1",D_YSIZE))
```

元のコードを消して、以下のように書くと、Terminalに結果が表示される。影響する値が変更された時に都度実行される。

```
print("ch",ch("../resample1/length"))
```

```
ch 0.20999999999999999
ch 0.20999999999999999
```

もし複数のprintを行いたい場合は、このように書く。{}で囲めば、複数行OKなので、元のコードもコメントアウトでのこせる

```
{
#ch("../resample1/length")/(bbox("../sweep1",D_YSIZE))
print("ch",ch("../resample1/length"));
print("bbox",bbox("../sweep1",D_YSIZE));
}
```
C言語と数学で回るドーナツを作ってみたら面白すぎたW

# C言語による回るドーナツ
![donut.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/904294/282b3a24-9232-b668-f2cf-7a7c91a2b6a5.gif)

元ネタ
https://www.youtube.com/watch?v=SHhoFsgaWjA

※動画を真似してもできない時は下記のソースコードからコピペして遊んでみてください。↓

```
ディレクトリ構成
SPINNINGDONUT
 ┗donut
 ┗donut.c

--------
donut.c

#include <stdio.h>
#include <math.h>
#include <string.h>

           int k;double sin()
         ,cos();int main(){float A=
       0,B=0,i,j,z[1760];char b[
     1760];printf("\x1b[2J");for(;;
  ){memset(b,32,1760);memset(z,0,7040)
  ;for(j=0;6.28>j;j+=0.07)for(i=0;6.28
 >i;i+=0.02){float c=sin(i),d=cos(j),e=
 sin(A),f=sin(j),g=cos(A),h=d+2,D=1/(c*
 h*e+f*g+5),l=cos      (i),m=cos(B),n=s\
in(B),t=c*h*g-f*        e;int x=40+30*D*
(l*h*m-t*n),y=            12+15*D*(l*h*n
+t*m),o=x+80*y,          N=8*((f*e-c*d*g
 )*m-c*d*e-f*g-l        *d*n);if(22>y&&
 y>0&&x>0&&80>x&&D>z[o]){z[o]=D;;;b[o]=
 ".,-~:;=!*#$@"[N>0?N:0];}}/*#****!!-*/
  printf("\x1b[H");for(k=0;1761>k;k++)
   putchar(k%80?b[k]:10);A+=0.04;B+=
     0.02;}}/*****####*******!!=;:~
       ~::==!!!**********!!!==::-
         .,~~;;;========;;;:~-.
             ..,--------,*/


```
Visual Studioのライセンスキーを変更する方法

# 概要

Visual Studioで既に登録してあるライセンスキーを削除し、別のライセンスキーを登録したいということがあった。
Visual Studioをアンインストールしただけではライセンスキーが削除されずライセンスキーの変更ができなかった。
そのため、変更手順を記載する。

# 参考サイト

https://stackoverflow.com/questions/46731291/how-to-change-visual-studio-2017-license-key

# 手順

## レジストリキーの削除

1. `Winキー＋R`で、「ファイル名を指定して実行」を起動する。
2. 名前ボックスに`regedit`と入力してOKを選択する。
3. `HKEY_CLASSES_ROOT\Licenses\41717607-F34E-432C-A138-A3CFD7E25CDA`を右クリックし、メニューから「削除」を選択する。

**※Licenses以下の削除する対象はライセンスキーを変更したいVisual Studioのバージョンによって違うため注意！**
今回は Visual Studio 2019のライセンスキーを変更したかったため、`41717607-F34E-432C-A138-A3CFD7E25CDA`を削除した。

## Visual Studioの修復インストール

Visual Studio Installer を開き、Visual Studioの「その他」から「修復」を選択する。

## ライセンスキーの登録

Visual Studioの修復が完了したら Visual Studioを起動し、「ヘルプ」の「バージョン情報」から新たにライセンスキーを登録する。
[Node.js] 非同期処理 - async/await編

# async/await

### async/await構文

~~~js
function parseJSONAsync(json) {
	return new Promise((resolve, reject) => {
		setTimeout(() => {
			try {
				resolve(JSON.parse(json))
			} catch (err) {
				reject(err)
			}
		}, 1000)
	})
}
async function asyncFunc(json) {
	try{
		const result = await parseJSONAsync(json);
		console.log('パース結果', result);
	}catch (err) {
		console.log('エラーをキャッチ', err);
	}
}
asyncFunc('{"foo": 1}')
asyncFunc('不正なJSON')
>>>
ース結果 { foo: 1 }
エラーをキャッチ SyntaxError: Unexpected token 不 in JSON at position 0
	at JSON.parse (<anonymous>)
	...(省略)
~~~
asyncキーワードの付いた関数は必ずPromiseインスタンスを返します。それは関数内で非同期処理が実行されない場合でも、同様です。

~~~js
async function asyncReturnFoo() { return 'foo' }
const result = asyncReturnFoo()
console.log(result)
>>>
Promise { 'foo' }
~~~

また、async関数内でエラーが投げられると、async関数はrejectedなPromiseインスタンスを返します。

~~~js
async function asyncTrhow() { throw new Error('エラー') }
const result = asyncTrhow()
console.log(result)
>>>
Promise {
  <rejected> Error: エラー
  ...(省略)
}
(node:23161) UnhandledPromiseRejectionWarning: Error: エラー
...(省略)
~~~

awaitはasync関数ないの処理を一時停止するものの、非同期I/Oのようにスレッドの処理をブロックするわけではありません。asunc関数が一時停止している間も、async関数の外の処理は動作を続けます。

~~~js
async function pauseAndResume(pausePeriod) {
	console.log('pauseAndResume開始')
	await new Promise(resolve => setTimeout(resolve, pausePeriod))
	console.log('pauseAndResume終了')
}
pauseAndResume(1000)
console.log('async関数外の処理はawaitの影響を受けない')
>>>
pauseAndResume開始
async関数外の処理はawaitの影響を受けない
pauseAndResume終了
~~~

### 並行処理
async/await構文には並行実行のための機能はないため、Promise.all()などのスタティックメソッドと組み合わせる必要がある。

~~~js
async function doSomethingAsyncConcurrently() {
	const result = await Promise.all([
		asyncFunc1(),
		asyncFunc2(),
		asyncFunc3()
	]);
}
~~~

### for await ...of 構文
for await ... of はasyncイテラブルに対して反復処理を行います。
asyncジェネレータ関数を使って簡単な例を書いてみます。

~~~js
sync function* asyncGenerator() {
	let i = 0;
	while(i <= 3) {
		await new Promise(resolve => setTimeout(resolve, 1000));
		yield i++
	}
}
for await (const value of asyncGenerator()) {
	console.log(value);
}
>>>
0
1
2
3
~~~
みんな大好きRIGOLオシロスコープを静音化


#はじめに

みんな大好きRIGOLのオシロスコープは低価格の割に
高機能で一家に一台欲しいオシロ．
ですがファンの音がうるさいので静音ファンに交換しました．


#用意するもの
秋葉原ラジオデパート３Fのトモカ電気さんで購入しました．
DC12V 50mmサイズが適合します．
・分解用の星形ドライバー
・RDM5010S：300円
<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/54048538-f2e3-cf35-6af8-8f61314d6db2.jpeg">

#分解
DS1054, DS1052ではなくDS1104Zのオシロですが構造は同じです．
<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/3b19a99f-1737-51b2-fdbb-bd20f01fe716.png">

底面のテープを切らないと開封できませんが，１年保証なので問答無用で切断．

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/df3a10e7-9417-854f-c466-7f55bfda74d6.jpeg">

開かないなーと思ってネジを探してみたら，取っ手裏に隠れてます．

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/aad27a65-d082-4f75-060b-306c03a21c7b.jpeg">

見えるネジを外していきます．

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/20a99667-9deb-e8b3-1230-7e19b945e0ed.jpeg">

ここまで分解すると，裏蓋に電源装置，表蓋にディスプレイ等があり
電源ケーブルとファンケーブルがコネクションされているので両方取ります．

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/9fd3bf98-1b07-9786-9647-47ab4bd1aa48.jpeg">


<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/adfc05bd-5d09-8634-4f36-56ac789095ee.jpeg">


元々取り付けられているファンにはXHコネクタが付いています．
ファン根本のはんだを溶かしてケーブルを再利用します．

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519618/5905fbab-46e5-48fc-e2fd-85a300864704.jpeg">

交換後，こんな感じにほとんどファンの音が気にならなくなります．
イメージは水道を流すと遠い水道管に水が流れる音みたいな感じに静かになります．

https://twitter.com/WaatH5/status/1370389633742237696
Raspberry Pi Desktop「USキーボード」の設定方法

# はじめに

時々英語キーボードを接続することがあるので、キーボード種別の変更手順を残しておく。

特に、[**こちらの記事**](http://koba5884.com/archives/7213155.html)とか[**こちらの記事**](https://zenn.dev/nekocodex/articles/79148efbcc289d583bd2)では、解決しなかった方向け。
# 初期設定時に「_USキーボード_」を選択していない場合

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/fd6e6aa4-cd05-2bc2-22af-38bb2080647d.png)

上図のように、初期設定時（のセットアップウィザード`piwiz`）に、Country:**Japan**／Language:**Japanese**を選択し、**Use US keyboard**にチェックを**入れない**場合は、**日本語キーボード**が設定され、チェックを**入れた**場合は、**USキーボード**が設定される。
本稿タイトルの「USキーボードを設定したい」ということは、ここではチェックを入れなかったはずだ。



# 日本語入力メソッド`fcitx-mozc`のインストールの有無

上記で**日本語キーボード**が設定された状態で、日本語入力メソッド`fcitx-mozc`をインストールすると、再びセットアップウィザード`piwiz`で上記の**Use US keyboard**にチェックを入れても、日本語キーボード配列のままでUSキーボード配列にならない。これは、**fcitx**がキーボードを制御しているためである。
なお、**USキーボード**が設定された状態で、日本語入力メソッド`fcitx-mozc`をインストールすると、そのまま**USキーボード**が有効である。


# fcitxをインストールしている場合

**fcitx**をインストールしている場合、セットアップウィザード`piwiz`の**Set Country**、下図`Raspberri Pi設定`の**キーボードの設定**、下図`raspi-config`の**Keyboard**のいずれの方法で**USキーボード**を選択しても、実際のキーボード配列は変更されない。前項でも述べたが、これは**fcitx**が制御しているためである。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/fb20733d-8e41-2576-579d-851e4a424728.png)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/4115defa-6bc8-0de1-b0fd-7328ad5d05b8.png)

**fcitx**をインストールしている場合は、`fcitx設定`で設定する。
「メニュー」→「設定」→「fcitx設定」
![2021-03-13-000234_1024x600_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/239f538f-e044-fbf9-a485-b46d59e2caa2.png)

下図のように「キーボード - 日本語」と「Mozc」が並んでいるはずだ。左下の「**＋**」をクリック。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/64506fb5-37f4-0bb7-976d-699efb762b82.png)

「**キーボード - 英語(US)**」を選択し、「**OK**」。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/169ea933-5ccd-4123-891d-5e53cc660ef9.png)

左下の「**↑**」を数回クリックして、追加した「キーボード - 英語(US)」を**最上段**に移動する。
![2021-03-12-224610_1024x516_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283293/13b91727-1cec-858b-e0eb-44f3e156db53.png)

ウィンドウ右上の「**×**」で閉じて良い。
再び日本語キーボードに戻したい場合は、「キーボード - 日本語」を**最上段**に移動するだけだ。

以上で、USキーボード/日本語キーボードが自由に変更できるようになったはずだ。
Shopify LiquidでPC/SPでセクションに登録する画像を分ける

## 今回の目的

Shopifyのセクションでは何もしなければ登録される画像はPC/SPで共通であり、画面のサイズで画像を切り替えたりすることはできません。

調べてみると、意外と簡単にPC/SPで登録する画像を分ける方法があったので紹介します。

## PC/SPで登録したい画像をわける

Debutにあるセクションを編集しても良いのですが、やり方の紹介なので今回は新しくセクションを作成します。

sectionディレクトリで```image.liquid```というものを作成し、下のコードを貼り付けます。
pictureタグを使うことによって画面幅に応じて、別の画像を表示する事が可能になります。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/picture

```
<picture>
  <source  class="feature-row__image-wrapper " media="(min-width: 768px)" srcset="{{ section.settings.image_pc | img_url: 'large' }}">　// 幅768px以上はsourceタグの画像を表示
  <img  class="feature-row__image-wrapper" src="{{ section.settings.image_sp | img_url: 'large'}}"/> // 幅768px未満はimgタグの画像を表示
</picture>

{% schema %}
  {
    "name": "画像切り替え",
    "settings": [
   	{
          "type": "image_picker",
          "id": "image_pc",
          "label": "画像(PC)" //pc画像用のセクション定義
        }, 
        {
          "type": "image_picker",
          "id": "image_sp",
          "label": "画像(SP)"　//sp画像用のセクション定義
        }
   ]
  }
{% endschema %}
```

トップ画面で確認する為、```index.liquid```に```{% section 'image'%}```を追加します。

```
{{ content_for_index }}
{% section 'image'%}
```
ちなみにcontent_for_indexを入れることによってトップ画面に動的セクション(セクションの位置を変更したりセクションを削除、非表示する事ができます)を入れる事ができ、
```{% section 'image'%}```を入れる事で静的セクション(位置は変更できず、コメントアウトとかコードから消さないとセクションを削除できません)を入れる事ができます。

https://help.shopify.com/ja/manual/online-store/os/using-themes/change-the-layout/theme-settings/sections


これでホームページのカスタマイズ画面に画像切り替えセクションが追加されています。

![スクリーンショット 2021-03-13 0.03.13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435480/0f084b79-53d0-420b-781c-61393a290128.jpeg)

PC/SP画像登録すると画像が切り替わっているのが確認できました！

PC画像
![スクリーンショット 2021-03-13 0.10.47.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435480/18081ffa-779d-b0a9-dcb5-20665d145135.jpeg)


SP画像
![スクリーンショット 2021-03-13 0.11.00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435480/15dbe227-8e35-bda9-fc43-e423066303cd.jpeg)

## まとめ

`<picture>`タグ便利です。
セクションだけでなくブログ記事(wisywig)とかでも簡単に画像を切り替える事ができるのでおすすめです。