OmniAICreator/Qiita-1.07M huggingface dataset:
全てのリポジトリに共通のgit hooksを適用するスクリプト(huskyにも対応)

# 作ったもの
下記にソース置いてます。
https://github.com/ktkn304/githooks

# できること
全てのgitリポジトリに共通のgit hooksを提供する。
リポジトリ個別のgit hooksも実行する(huskyにて作られたgit hookも実行できる)。
※ これらの動作を実現するためにグローバルなgitの設定(``` core.hooksPath ```)を書き換えているので注意

# 使い方

``` shell
# 任意のディレクトリにcloneする
$ git clone https://github.com/ktkn304/githooks.git

$ cd githooks

# インストールスクリプトを実行する
# これにより、以下が実行される
# 1. 下記のディレクトリ・ファイル作成
# ./hooks/pre-commit # 各フックスクリプトを呼び出すシェルスクリプトが作成される
# ./custom-hooks/pre-commit/ # グローバルに適用したいフックスクリプトを配置するディレクトリ
# 2. gitの設定変更(core.hooksPathにリポジトリのhooksディレクトリを指定)
$ ./setup/install
```

あとは、全体に適用したいフックスクリプトは./custom-hooks/pre-commit/ディレクトリへ配置すればよい。
また、リポジトリ毎のフックスクリプトはリポジトリの.git/hooksディレクトリへ通常通り配置する(huskyもこちらへ配置してくれるので、特に気にしなくてもよい。lefthookはわからない・・・)。

## pre-commit以外のフックについて
デフォルトではpre-commitのフックスクリプトしか実行しないようになっている。
```./setup/hook-types```を編集し、```./setup/install```を実行することで任意のフックに対応できる。
### 例: commit-msgを有効にした場合

``` path:./setup/hook-types
# applypatch-msg
commit-msg
# fsmonitor-watchman
# post-update
# pre-applypatch
pre-commit
# pre-merge-commit
# prepare-commit-msg
# pre-push
# pre-rebase
# pre-receive
# update

```

上記のように変更後、```./setup/install```を実行する
[JavaScript] DOM 要素の照合

# 概要

* ある DOM 要素を照合する API の忘備録です。

* 以下の３メソッドについて解説してます。
  1. element.contains(element)
  2. element.closest(selector)
  3. element.matches(selector)

## element.contains(element)

* 要素A と 要素B の親子関係を調べます。

```HTML
<div id="parent">
  <span id="child">8^-^8</div>
  <div><span id="grand-child">8^-^-^8</span></div>
</div>

<span id="friend">=^-^=</div>
```

```JavaScript
const parentNode = document.getElementById('parent')
const childNode = document.getElementById('child')
const grandchildNode = document.getElementById('grand-child')
const friendNode = document.getElementById('friend')

parentNode.contains(childNode)  // true
parentNode.contains(grandchildNode)  // true
parentNode.contains(friendNode)  // false
parentNode.contains(parentNode)  // true

parentNode.contains(null)  // false
parentNode.contains(undefined)  // false
```

## element.closest(selector)

* ある要素の祖先要素の内、`selector` にマッチする直近要素を返します。

```HTML
<h1>Title</h1>

<section class="root">
  <div class="message">
    <div class="target">8^-^8</div>
  </div>
</section>
```

```JavaScript
const targetElement = document.getElementById('target')

targetElement.closest('.message')  // <div class="message">
targetElement.closest('.root')  // <div class="root">
targetElement.closest('h1')  // null
```

## element.matches(selector)

* 指定要素が CSS セレクタにマッチするかどうかを論理値で返します。

```HTML
<div id="apple">🍎🍎🍎</div>
<div id="banana">🍌🍌🍌</div>
<div id="banana-fresh" class="fresh">🍌🍌🍌</div>
```

```JavaScript
const apple = document.getElementById('apple')
const banana = document.getElementById('banana')
const bananaFresh = document.getElementById('banana-fresh')

apple.matches('#apple')  // true
apple.matches('#banana')  // false

banana.matches('#banana')  // true
banana.matches('#banana.fresh')  // false

bananaFresh.matches('.fresh')  // true
bananaFresh.matches('#banana.fresh')  // true
```
グラフ描画ライブラリBokehの使い方

・ツールチップでデータの中身を確認することが可能

```python
import matplotlib.pyplot as plt
import numpy as np
import random

from bokeh.io import output_notebook, show
from bokeh.plotting import figure,show
output_notebook()

x = np.linspace(1, 10, 10)
y = [random.randint(0, 10) for i in range(10)]

TOOLTIPS = [
    ("index", "$index"),
    ("(x,y)", "($x, $y)"),
]

#グラフ設定
p = figure(tooltips=TOOLTIPS, title="グラフタイトル", x_axis_label="x軸", y_axis_label="y軸")
# 散布図
p.circle(x = x,y = y)
#show(p)

# 折れ線グラフ
#p.line(x = x,y = y)
#show(p)

# 棒グラフ
#p.vbar(x = x,top = y,width=0.5)
show(p)
```
how can I convert pdf to image using pdf2image in python on Mac OS X?

I want to convert pdf to image using pdf2image in python on Mac OS X.

```
from pdf2image.exceptions import (
    PDFInfoNotInstalledError,
    PDFPageCountError,
    PDFSyntaxError
)
# define pdf path
pdf_path = "./pdf_file/ooo.pdf"

# convert pdf to image（1200dpi）
images = convert_from_path(str(pdf_path), 1200)
# save image files one by one
image_dir = "./image_file"
for i, image in enumerate(images):
    file_name = pdfpath + "{:02d}".format(i + 1) + ".jpeg"
    image_path = image_dir / file_name
    # save JPEG
    image.save(str(image_path), "JPEG")
```

then I get the error message like

```
TypeError                                 Traceback (most recent call last)
<ipython-input-19-26e2710189ca> in <module>
     13 for i, image in enumerate(images):
     14     file_name = pdfpath + "{:02d}".format(i + 1) + ".jpeg"
---> 15     image_path = image_dir / file_name
     16     # save JPEG
     17     image.save(str(image_path), "JPEG")

TypeError: unsupported operand type(s) for /: 'str' and 'str'
```

I cannot understand what is happening. Please help!
【Kotlin】AndroidxのPreferenceFragmentCompatを使ってみる

##はじめに
今回も例によって初学者向けの内容になっているかと思います。私自身が初学者である為、理解の浅い所や間違いなどあるかも知れません。都度ご指摘頂けると嬉しいです。

さて、Androidには昔からアプリの設定画面を簡単に作る仕組みがあります。ググれば記事は沢山見つかるのですが情報が古くなっているものも多かったので、Androidxライブラリでの実装をKotlinで書いてみようと思います。
##準備
Androidxライブラリを使うため、build.gradle(appのほう)のdependencies内に記述が必要です。

```kotlin:build.gradle(Module.app)
dependencies{

        implementation 'androidx.preference:preference:1.1.1'//これを追加
}
```

##構成
先に必要なファイルを挙げておきます。
-SettingActivity.kt
-activity_setting.xml
-SettingFragment.kt
-preference.xml

##レイアウト
```xml:activity_setting.xml
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SettingActivity">

    <FrameLayout
        android:id="@+id/settings_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
```
constraintlayoutのところはlinearでもなんでも平気だと思います。

##SettingActivity
今回はフラグメントを表示するだけのシンプルなアクティビティです。
メインアクティビティなどからこのアクティビティに遷移すればオッケーです。

```kotlin:SettingActivity.kt
class SettingActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_setting)
 
        supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings_container,fragment)
                .commit()
    }
}
```
##SettingFragmentの実装
```kotlin:SettingFragment.kt
class SettingFragment: PreferenceFragmentCompat() {

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences,rootKey)
    }
}
```
##preference.xmlを作成する

まずresフォルダ内にxmlフォルダを作る(なければ)。xmlフォルダ内にpreference.xmlファイルを作成する。

```xml:preference.xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <PreferenceCategory android:title="@string/category">
        <CheckBoxPreference
            android:key="key1"
            android:title="@string/title1"
            android:summary="summary1"
            android:summaryOn="@string/on"
            android:summaryOff="@string/off"
            android:defaultValue="false"
            />
        <EditTextPreference
            android:key="key2"
            android:title="@string/title2"
            android:summary="@string/summary2"
            android:dialogTitle="@string/dialog"
            />
        <ListPreference
            android:key="key3"
            android:title="@string/list"
            android:summary="@string/summary3"
            android:entries="@array/list"
            android:entryValues="@array/value"
            />
    </PreferenceCategory>
</PreferenceScreen>
```
PreferenceScreenで括ってある以外はこれまでのPreferenceと殆ど変わりません。
中身についての説明は割愛しますので必要に応じて調べてみていただければと思います。
RESTなAPIでBasic認証

WebIOPiでBASIC認証してAPIにアクセスしたかったのでメモ

### Authorization:Basic の追加

![SnapCrab_NoName_2020-5-27_20-52-26_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/73ed70fb-8e8f-678c-ba64-8bcd8a654b50.png)

Base64にエンコードしたBASIC認証のUserとPassをxxxxxxに記載

```
Authorization:Basic xxxxxx
```

例）

userとpasswordをコロンでつないでBase64でエンコードすると

admin:pass -> YWRtaW46cGFzcw==

```
Authorization:Basic YWRtaW46cGFzcw==
```





### 参考サイト

Hitachi Command Suite REST APIリファレンスガイド
http://itdoc.hitachi.co.jp/manuals/3021/3021901610/HCSR0050.HTM

Basic認証のあるページにユーザ名とパスワードを書いたURLでブラウザからアクセスしました。
https://qiita.com/pugiemonn/items/a9787ed3063487498e82

Rest APIでBasic認証する方法を教えてください
https://smartdb.support-dreamarts.com/hc/ja/articles/360033375011-Rest-API%E3%81%A7Basic%E8%AA%8D%E8%A8%BC%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84
C++ ラムダ式の基本とキャプチャ

C++のラムダ式についてメモを残します。

## ラムダ式の基本

```cpp
// 引数と返り値を省略しない
auto show = [](int num)-> void{
	std::cout << num << std::endl;
};
  
// 引数と返り値を省略する
auto show2 = [](){
	std::cout << 'a' << std::endl;
};

show(42);  // 42
show2();   // a
```

- 関数をその場で定義する構文
- 関数の引数かautoで宣言した変数に代入することが多い
- ラムダ式はコンパイラが自動で作る一意の型を持ったオブジェクトになるのでautoで宣言する必要がある
- 引数がない場合や返り値がない場合もある

## キャプチャ
```cpp
int a = 0;
int b = 22;

// この時点のaがコピーされる
auto lamda = [a](){
  std::cout << a << std::endl;
};

// aのみコピーされてbはされない
// mutableを宣言したのでaは変更可能
auto lamda2 = [=]()  mutable{
  a = 200;
  std::cout << a << std::endl;
};

a = 100;

lamda();	// 0
lamda2();	// 200

```

- ラムダ式の外側で宣言されている変数のコピーをラムダ式内部で使えるようにする
- 引数のようにラムダ式を呼ぶときに渡さなくても良い
- [=]でデフォルトキャプチャ、コンパイラが必要な分だけ自動でキャプチャしてくれる
- キャプチャした変数は暗黙的にconstとなるため変更することはできない
- mutableを宣言すると変更できるが、すべてのキャプチャした変数に影響が出る
- [&a]など参照でキャプチャすることもできる
Android Emulatorで撮影したスクリーンショットの保存先変更

#はじめに
Android Studio付属のエミュレータでスクリーンショットをたくさん撮る必要があったときに、
いちいちデスクトップに保存されてしまうのをなんとかしたい！と思い調べたことの備忘録です。
#環境
Android Studio 4.0
Android Emulator 30.0.12
#方法
エミュレーター画面の横に表示されるパネルの最下部にある[詳細]ボタンを押すと表示されるメニューから、
[Settings]>[Screenshot save location]の項目で変更できます。
![C855A9C6-0034-43B8-8B12-670C268F1F8E.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631351/e05279c5-debe-0cb3-4cab-cc8950ab582f.png)
辞書型リストとDataFrameの相互変換

#辞書型リストをDataFrameに変換して処理したい
もう何度も調べたくない・・・。そんな自分へ備忘録です。
みなさんのお役にも立てればいいな・・・

##環境情報
・python: 3.7.3
・pandas: 1.0.3

##実装サンプル

```python:辞書型リストとDataFrameの相互変換.py

import pandas as pd

dict_list = [
    {"A": "a1", "B": "b1", "C": "c1"},
    {"A": "a2", "B": "b2", "C": "c2"},
    {"A": "a3", "B": "b3", "C": "c3"}
]

# 辞書型リスト -> DataFrameへ変換
df = pd.DataFrame(dict_list)
print(df)
#     A   B   C
# 0  a1  b1  c1
# 1  a2  b2  c2
# 2  a3  b3  c3

# DataFrame -> 辞書型リストへ変換
dfToList = list(df.to_dict('index').values())
print(dfToList)
# [{'A': 'a1', 'B': 'b1', 'C': 'c1'}, 
#  {'A': 'a2', 'B': 'b2', 'C': 'c2'}, 
#  {'A': 'a3', 'B': 'b3', 'C': 'c3'}]
```

以上、終わり。
JuliaでROS2のPub/Subをやってみた

# はじめに
みなさん，Pythonは好きですか？
僕は好きじゃないです（嫌いとは言っていない）。
そこで，Pythonに代わる言語としてJuliaを使ってROS2のPub/Subをやってみようと思います。

## 追記
ROS1ではhttps://github.com/jdlangs/RobotOS.jl というライブラリが使えそうです．
また，そのうち[ROS2サポートもされる](https://github.com/jdlangs/RobotOS.jl/issues/80)らしいです．

# Juliaのインストール
ここからダウンロードしてインストールしてください。
https://julialang.org/downloads/

# ROS2のインストール
ここが詳しいです。
https://qiita.com/k-koh/items/838c70004119c329c617

# JuliaにPyCallを追加
JuliaのREPLを起動します。

```
$julia
              _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.4.1 (2020-04-14)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |
```

起動したら，`]`キーを押します。
すると，以下のような文字列が表示されると思います。

```
(@v1.4) pkg>
```

ここで以下を入力します。

```
add PyCall
```
これでエラーが出なければパッケージの追加は完了です。

# コード（Pub）

```pub.jl
using PyCall
rclpy = pyimport("rclpy")
Node = pyimport("rclpy.node")
String = pyimport("std_msgs.msg")

rclpy.init()
node = Node.Node("talker")

pub = node.create_publisher(String.String, "chatter", 10)

msg = String.String()
msg.data = "Hello"

pubmsg() = pub.publish(msg) 

timer = node.create_timer(0.5, pubmsg)
rclpy.spin(node)

node.destroy_timer(timer)
node.destroy_node()
rclpy.shutdown()
```

# コード（Sub）

```sub.jl
using PyCall
rclpy = pyimport("rclpy")
Node = pyimport("rclpy.node")
String = pyimport("std_msgs.msg")

rclpy.init()
node = Node.Node("listener")

submsg(msg) = println(msg.data)

sub = node.create_subscription(String.String, "chatter", submsg, 10)

rclpy.spin(node)

node.destroy_node()
rclpy.shutdown()
```
# 動作

```
$julia pub.jl&
$julia sub.jl
Hello
Hello
Hello
...
```
# まとめ
JuliaでROS2のPub/Subを動かすことができました。
これでJuliaとロボットを連携させることができるとわかりました。
とはいっても，PyCallでPythonのrclpyを呼び出して使っているだけなのでrcljl(?)が欲しいです。
.NET FrameworkとMonoの関係

**Mono**
Ecma標準に準じた.NET Framework互換の環境を実現するためのオープンソースのソフトウェア群やプロジェクト名。
2018年3月現在、マイクロソフトの子会社Xamarinと.NET Foundationが開発・販売・サポートを行う。
共通言語基盤（CLI)の実装やC#のコンパイラなどが含まれる。

**Monoランタイム**
多くのプロセッサで動作するJITコンパイラを搭載。
JITコンパイラはアプリケーション実行中に共通中間言語（CLI）コードをネイティブコードに変換しそれを転送する。

###MonoTouch Framwork
iOSのAPIにアクセスするためのクラスライブラリ。
Objective-Cで作られたネイティブライブラリを直接アクセスするためにバインドされています。

**Xamarin**
2011年5月、Mono、MonoTouch、Mono for Androidの開発者により設立された企業。
これら３つのソフトウェアは共通言語基盤並びに共通言語仕様のクロスプラットフォームな実装。
作成できるアプリケーション
・Monowoを利用したアプリケーション、クラスライブラリ
・iOSアプリ
・Androidアプリ
・macOSアプリ
・複数のプラットフォームで再利用可能なクラスライブラリ(.NET StandartやPCL)


**クロスプラットフォーム(マルチプラットフォーム)**
異なるプラットフォーム上で、同じ仕様のものを動かすことができるプログラムの事。

**Ecma標準**
⇒情報通信システムの分野における国際的な標準化団体。
対応規格は国際標準化機構・国際電気標準会議の第一合同技術委員会が定める規格、
欧州電気通信標準化機構が定める規格(ETSI)、日本産業規格（JIS)がある。

##参考資料
・Wikipedia
・C#によるiOS,Android,Windowsアプリケーション開発入門
【JavaScript】JavaScriptの基本構文

学習中に忘れてしまうことがありましたので、書き留めます。
特に初学者の方の参考になればと思います。
JavaScriptES6


##コンソール出力

```JavaScript:nicotine.js
console.log("文字列");
```

##コメントアウト

```JavaScript:nicotine.js
//コメント
```

##変数の定義

```JavaScript:nicotine.js
let 変数名 = 値1;
//値を上書き
変数名 = 値2;
```

##定数の定義

```JavaScript:nicotine.js
const 定数名 = 値;
//上書きできない
```

##テンプレートリテラル

```JavaScript:nicotine.js
//変数を文字列に連結
console.log(`こんにちは、${変数名}さん`);
```

##条件分岐

```JavaScript:nicotine.js
//if文
if (条件式){
	処理;
} ←セミコロン不要

//switch文
switch (条件の値){
	case 値1:
		処理;
		break;
	case 値2:
		処理;
		break;
	default:
		処理
		break;
}
```

##比較演算子

- 等号　===
- 不等号　!==

##繰り返し処理

```JavaScript:nicotine.js
//while文
while(条件式){
	処理;
	インクリメント;
}
//for文
for(変数定義; 条件式; インクリメント){
	処理;
}
```

##配列

```JavaScript:nicotine.js
//定義
const 配列名 = [値, 値, 値];
//値の参照
let 変数名 = 配列名[インデックス番号];
//値が無ければundefinedを返す
//undefinedは条件分岐ではfalse扱い

//配列の長さ
配列名.length;
```

##オブジェクト

```JavaScript:nicotine.js
//定義
const オブジェクト名 = {プロパティ1:値1, プロパティ2:値2};
//値の参照
オブジェクト名.プロパティ
//値が無ければundefinedを返す
//undefinedは条件分岐ではfalse扱い
```

##配列、オブジェクトの組み合わせ

```JavaScript:nicotine.js
//定義
const 配列名 = [
	{プロパティ:値, プロパティ:値},
	{プロパティ:値, プロパティ:値}
	];
//値の参照
配列名[インデックス番号].プロパティ;
```

##関数

```JavaScript:nicotine.js
//定義
const 関数名 = (引数名)=>{
	処理;
};
//オブジェクトに定義
const 定数名 = {
	プロパティ: ()=>{
		処理;
	}
};
//呼び出し
関数名(引数);
//オブジェクトに定義した場合
定数名.プロパティ();
```

##クラス

```JavaScript:nicotine.js
//定義
class クラス名 {}
//インスタンス生成
const 定数名 = new クラス名();
//コンストラクタ
class クラス名{
	constructor(引数){
		this.プロパティ = 値;
	}
}
//インスタンスのプロパティ参照
インスタンス名.プロパティ
//メソッド定義
class クラス名{
	constructor(引数){
		this.プロパティ = 値;
	}
	メソッド名(){
		処理;
	}
}
//メソッドの呼び出し
インスタンス.メソッド();
//メソッド内でのインスタンスのプロパティ参照
this.プロパティ
//クラス継承
class 子クラス名 extends 親クラス名{}
//コンストラクタのオーバーライド
constructor(引数1, 引数2, 引数3){
	super(引数1, 引数2)
	this.プロパティ = 引数3;
}
```

##ファイルの分割

```JavaScript:nicotine.js
//デフォルトエクスポート
	//クラス
	export default クラス名;
	//値
	export default 値;
	//ファイルがインポートされると自動でインポートされる
	//エクスポート時とインポート時の名前が違っても良い
	//一つのファイルに一つの値のみ
//名前付きエクスポート
export{値1,値2};

//デフォルトインポート
import 名前(クラス名) from "ファイル";
//名前付きエクスポート
import {値1,値2} from "ファイル";
```

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

```JavaScript:nicotine.js
import 定数名 from "パッケージ名";
```

##配列操作

```JavaScript:nicotine.js
//値の追加
配列名.push(値);
//配列繰り返し
配列名.forEach((変数名)=>{
	処理;
});
//find(条件に合う一つ目の要素取得)
const 定数名 = 配列名.find((変数名)=>{
	return 条件式;
});
//オブジェクトにも使える

//filter(条件に合う要素全ての要素取得)
const 配列名 = 配列名.filter((変数名)=>{
	return 条件式;
});
//配列として取得
//オブジェクトにも使える

//map(配列の全ての要素に処理を行い、新しい配列に取得)
const 新配列名 = 配列名.map((変数名)=>{
	return 処理;
});
```
js - 処理の流れ

#DOMとは

DOMはDocument Object Modelの略で、JSからHTMLの情報を取得し、データを作成する仕組みのこと。

このDOMによって解析されたHTMLは階層として捉えられる。

#DOMツリー

```html

<body>
  <header>
  </header>
  <div class = 'contents'>
    <div class = 'left-content'></left-content>
    <div class = 'right-content'></right-content>
  </div>
  <footer>
  </footer>
</body>
```
上記のコードを階層として捉えると

<img width="659" alt="スクリーンショット 2020-05-27 20.25.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533191/138ca759-04f0-a03d-95bf-e69f600723bd.png">

こんな感じ↑

そして階層構造のあるデータをDOMツリーやドキュメントツリーと言い、JSはこのDOMツリーを操作することができる。

DOMツリーの要素である、bodyやheaderなどの要素をそれぞれノードと言い、JSでHTMLを操作する時（表示の変更や、クラスの付与、いわゆるJSで画面に動きを持たせたい時）はまず、このDOMを構成する要素の取得が必要になる。

細かいメソッドなどは割愛するが、流れとしては

<font color="Red">①DOMツリーからノードを取得する</font>
↓
<font color="Red">②JavaScriptで、取得したノードに対する処理を書く</font>
↓
<font color="Red">③HTML側に反映させる</font>

といった具合。


また、②の取得したノードに対する処理を実装する上で重要な概念がある。

#イベント駆動

取得したノードオブジェクトに対して、処理が行われるきっかけとして、イベントと言う処理要求が起こる。

イベントは、クリック、特定の場所にカーソルを合わせる、ページの読み込みなど、様々だ。

イベントが発火することによって、取得したノードオブジェクトに対し、処理が行われ、画面上に反映される。


例えば、ボタンのクリックをした際に「送信しました」と言うアラートメッセージを表示させたい時↓

```js
#省略

let btn = document.getElementById("submit");

function message() {
  window.alert("送信しました");
}

btn.addEventListener("click", message);
```

まずid名が「submit」のノードオブジェクトの取得を１行目で行い、変数btnに代入。

そして最後の行で取得したノードに対し、クリックイベントが起きた場合、関数messageを行うと書かれている。

関数messageには「送信しました」と言うアラートメッセージを表示すると言う処理を記述。

つまり、取得したノードに対し、何らかのイベントが起きた場合、処理を行うと言うのがイベント駆動の概念であり、**JSはイベント駆動の概念を元に作られてる。**
C#のカラースキームをVisual Studio 2019以前のものから切り替える

#概要
Visual Studio 2020 16.4.0以前から16.4.0にアップデートした際、使用していたC#のカラースキームが以前のものに戻った。
この記事ではそれの対処法も兼ね、Visual StudioにおいてのC#のカラースキームの変更方法を記した。

#方法
**テキスト エディター→C#→詳細**タブの、**エディターの配色**のドロップダウンより変更可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216639/e9fec3c4-eb3d-2ad2-34ad-44fc3fa12770.png)

**Visual Studio 2017**の場合:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216639/f72cac12-29b1-5b98-b56d-b2042f646597.png)

**Visual Studio 2019**の場合:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216639/8282dd57-77cf-41ab-b970-0d0ac9538426.png)
となる。
はじめてのThree.js 3章 日記

[はじめてのthree.js](https://www.amazon.co.jp/dp/4873117704)

#新たに知った知識
- webGLにライトのサポートなしなのでゼロからライティング書くとしたら[ここ](https://developer.mozilla.org/en-US/docs/web/API/WebGL_API/Tutorial/Lighting_in_WebGL)

```javascript
THREE.LensFlare // lightingにlensflareが存在する
```
- decay ・・・ライトからの距離に応じて光が減衰する量
- penumbra・・・spotlightがどのくらい急速に減速するかの値
- spotlightはtargetが必要
- flareにはtextureが必要

#気づいたこと
- 3Dモデリングを経験しているとかなりやりやすい
- lensflareかっこいい
- lensflare２つのテクスチャ使うけど、違いわからなかった


#wow moment
- lensflareのところ

#まだ解決していない点
- 01ライティング
- 一回突然chromeが落ちたけど演算処理が重かったのかしら
- サンプルが動かなかったのが数回あったが発動条件が謎

[4章はこちら](https://qiita.com/asadsexyimp/items/1ab42dc65a70fce96d17)
【Salesforce】アプリケーションランチャーに表示するアプリケーションの並び替え・表示/非表示の切り替え

Salesforceを活用した業務改善ITコンサルタントのkazuyaです！

本日は「Salesforceのアプリケーションランチャーに表示するアプリケーションの並び替え・表示/非表示の切り替え」について解説します。

## アプリケーションランチャーとは

ユーザがアプリケーションを切り替えるために使用する機能です。
Salesforceログイン後の画面左上に、縦と横に3個ずつ合計9個の丸が表示されています。

↓こんなやつ
●●●
●●●
●●●

これがアプリケーションランチャーです。
ユーザはこのボタンをクリックすることでアプリケーションを切り替えることができます。

■参考リンク
https://help.salesforce.com/articleView?id=identity_app_launcher.htm&type=5

## アプリケーションランチャーの設定画面「アプリケーションメニュー」への遷移方法
1. 設定画面を開く
2. クイック検索に「アプリケーションメニュー」と入力する
3. アプリケーションメニューリンクをクリックする
4. アプリケーションメニューが表示される

## アプリケーションランチャーに表示するアプリケーションの並び替え方法
1. アプリケーションメニューを表示する
2. 表示順を変更したいアプリを選択し、所定の場所までドラッグする
3. アプリケーションランチャーのアプリケーションの表示順が変更される

■参考サイト
https://help.salesforce.com/articleView?id=reordering_applauncher_lex.htm&type=5

## アプリケーションランチャーに表示するアプリケーションの表示/非表示切り替え
### アプリケーションを表示する
1. アプリケーションメニューを表示する
2. 非表示にしたいアプリケーションの「✔アプリケーションランチャーで非表示」リンクにカーソルを合わせる
3. 「✔アプリケーションランチャーで表示」リンクに切り替わったらクリックする
4. アプリケーションランチャーにアプリが表示される

### アプリケーションを非表示にする
1. アプリケーションメニューを表示する
2. 非表示にしたいアプリケーションの「✔アプリケーションランチャーで表示」リンクにカーソルを合わせる
3. 「✔アプリケーションランチャーで非表示」リンクに切り替わったらクリックする
4. アプリケーションランチャーのアプリが非表示になる
An error occurred while installing libv8 / therubyracer

### エラー

>An error occurred while installing libv8 (3.16.14.19), and Bundler cannot continue.
Make sure that `gem install libv8 -v '3.16.14.19' --source 'https://rubygems.org/'` succeeds before bundling.


解決

```
bundle config build.libv8 --with-system-v8
bundle i
```

### エラー


>An error occurred while installing therubyracer (0.12.3), and Bundler cannot continue.
Make sure that `gem install therubyracer -v '0.12.3' --source 'https://rubygems.org/'` succeeds before bundling.

解決

```
brew install v8@3.15
bundle config build.therubyracer --with-v8-dir=/usr/local/opt/v8@3.15/
bundle i
```
Integerメモ

今回はIntegerクラスのメソッドの使い方について学んでいきます。
随時更新予定です。

#compare(int x, int y)
2つのint値を数値的に比較します。
x == yの場合は値0、
x < yの場合は0より小さい値、
x> yの場合は0より大きい値

```java
System.out.println(Integer.compare(1, 2));
System.out.println(Integer.compare(2, 2));
System.out.println(Integer.compare(5, 2));
```
```java
-1
0
1
```

#compareTo(Integer anotherInteger)
2つのIntegerオブジェクトを数値的に比較します。

このIntegerが引数Integerと等しい場合は値0。
このIntegerが引数Integerより小さい数値の場合は0より小さい値。
このIntegerが引数Integerより大きい数値の場合は0より大きい値。

```java
Integer number = new Integer(100);

System.out.println(number.compareTo(10));
System.out.println(number.compareTo(500));
System.out.println(number.compareTo(100));
```
```java
1
-1
0
```

#decode(String nm)
StringをIntegerにデコードします。

```java
Integer num = Integer.decode("100");
Integer nm = 100;

System.out.println(num + nm);
```
```java
200
```

#equals(Object obj)
このオブジェクトを指定されたオブジェクトと比較します。

```java
Integer number = new Integer(100);
Integer num = new Integer(100);
Integer nm = new Integer(500);

System.out.println(number == num);
System.out.println(number.equals(num));
System.out.println(number.equals(nm));
```
```java
false
true
false
```

#parseInt(String s)
文字列の引数を符号付き10進数の整数型として構文解析します。
戻り値がint型

```java
String str = "123";
int i = Integer.parseInt(str);
int sum = i + 100;

System.out.println(sum);
```
```java
223
```

#valueOf(int i),valueOf(String s)
指定されたint値を表すIntegerインスタンスを返します。
指定されたStringの値を保持するIntegerオブジェクトを返します。
戻り値がInteger型

```java
int i1 = Integer.valueOf(100);
int i2 = Integer.valueOf("100");

System.out.println(i1 + i2);
```
```java
200
```
テーブルに追加された計算列はどのように格納されるのか？という話

計算列はとても便利な機能だから使わない選択はない。経験上であったり勉強したりしてすでに知ってはいたことなのだけど、どのように格納されるのか試ししてみよう。ついでに計算テーブルも。SQL Server Analysis Service (Tabular)じゃなくて、Power BI だったらどうなっているのかな？という内容ではある。

**計算列であっても通常のテーブルの列同様エンコードされる。**でも、計算列って圧縮低くね？って話です。

# そもそも
ストレージ モード が Import / Dual であるとき、

- Table
    - Partition
        - Segment

という構造になっていて データは Segment に格納されている。で、メモリの消費をできるだけ小さくできるよう整理(Encode / Sort) される。集計や計算に利用されるデータのフットプリントが小さければ一度に読み込めるデータ量が増えるはずだから、パフォーマンス向上に期待ができるわけ。

# どうなるか見てみる
計算列(Calculated column) だけじゃなく、同時に 計算テーブル(Caluclated table) も。

- 1 から 130 までの整数値 と それらに対応する 偶数であるか否かの論理値の列
- 130 行のテーブルを 3つ 用意して比較した。"130" というのはこのケースで見つけた値

## データロード前に用意
```text:PowerQuery
let
    Source = Table.FromColumns(
        { { 1 .. 130 } },
        type table [ Column1 = Int64.Type ]
    ),
    AddedCustom = Table.AddColumn(
        Source,
        "Column2",
        each Number.IsEven( [Column1] ),
        Logical.Type
    )
in
    AddedCustom
```

## 計算列の追加で

```text:DAX
Table1 = GENERATESERIES( 1, 130, 1 ) 
```

```text:DAX
CalculatedColumn = ISEVEN( [Value] ) 
```
## 計算テーブルで

```text:DAX
Table2 = 
ADDCOLUMNS(
    GENERATESERIES( 1, 130, 1 ),
    "AddColumnCalculatedTable", ISEVEN( [Value] )
)
```

# 結果など
DAX Studio の Vertipaq Analyzer 機能で違いを観察する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/c627303a-4f2c-0179-c6e7-26ba525aa040.png)
Encoding / Dictionary / Hier Size は変化ないのでそれ以外を。

||Table|Col Size|Data|
|:--|--:|--:|--:|
|計算列(Table1)|2,384|1,464|24|
|あらかじめ用意した列|2,368|1,448|8|
行数 130 は極小なので差は小さいけど、行数増えることや計算列で得られる値によって差が大きくなる可能性はあるでしょう。

## なぜ？
### 行のソート
考えられる要因としては xVerocity Engine による行のソートでしょう。これは Power BI desktop の テーブル ビュー でみると想像できる。行がソートされているのではないかというのが観察できた。このケースでは 130 行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/5807b262-a7a7-f755-7592-1b45826976c2.png)
データをロードするとき、列ごとの整理(Encode) に加え、どのように行の整理(Sort)するとよいのかな🙄と考慮されているのです。

Column1 は 1 から 130 の連続した整数値。もろもろ考慮され VALUE encoding が選択されていた。VALUE encoding はできるだけ少ない bit 数になるよう変換されたデータ(整数値)を格納する仕組みなのだけど、連続した整数値(高いカーディナリティ)なので Run Length Encoding の適用はスキップ。値の順番に依存する Encoding の効果がないから。
一方、Column2 は 論理値のみ。カーディナリティが低いし量もそこそこあったので、HASH encoding (Dictionary encoding)が選択された。
低いカーディナリティ(TRUE / FALSE しかない)からRun Length Encoding の効果は高いと推測され、テーブル全体で適用されるソートのうち優先順位の高いソート条件に利用されたということでしょう。

### 計算テーブルでも
最適化された行のソートが適用されているように見える。Vertipaq Analyzer での結果も同じだし同様に扱われたということが予想できている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/f5dc24b6-6f65-c296-886f-7191d1ebf85b.png)
### 計算列では？
同じ集計結果をえられるテーブルではあるけれども 行のソートがされていないように見える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/7361715c-78fa-4efe-0aa3-9fdde90a84c4.png)

計算テーブル / 計算列 が用意されるプロセスは、その性質上、通常のテーブルすべての用意が終わってからになる。実際にはもっと複雑なプロセスを経ているけれども、計算列のテーブルへの追加はテーブル行のソートは適用済み。計算列の結果をどのような行のソートにするかの考慮に含めることができない。なので、結果的に圧縮率が低い傾向にあるということ。"計算列 = 圧縮率が低い" ではない。

# 思ったこと🙄
計算列は便利なので、効果的に使いたいものである。

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
[BigQuery]failed with error INVALID_ARGUMENT: Bad int64 value

毎日スケジュールしている、BigQuery集計クエリでエラーが発生した

```
failed with error INVALID_ARGUMENT: Bad int64 value: NULL
```

int64へのCASTで失敗している。
対象コードは以下

```
CREATE TEMPORARY FUNCTION
  getValue()
    ...
    return value ? value : 'NULL';
  }

CAST(getValue() AS INT64) AS user_id FROM ~~~
```

getValue で valueを取り出すが、無理だった場合に 'NULL' を返す仕様。

文字列の 'NULL' は、 INT64 にCASTできないためエラーになっている。

```
SELECT CAST(NULL, AS INT64) FROM ~~~
-> 通る

SELECT CAST('NULL', AS INT64) FROM ~~~
-> エラー
-> Could not cast literal "NULL" to type INT64
```

文字列ではないNULLに変えてあげればOKだと思い変更したが、エラー。

```
CREATE TEMPORARY FUNCTION
  getValue()
    ...
    return value ? value : NULL;
  }
-> Uncaught ReferenceError: NULL is not defined
```

`TEMPORARY FUNCTION` は、Javascriptで動いている。
Javascriptでは、 NULL は変数名とみなして null でヌルの挙動をする

![スクリーンショット 2020-05-27 19.39.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/dbd7f18e-65d6-e1ac-7815-ce416d8e2829.png)

最終的に以下で修正。再集計完了。

```
CREATE TEMPORARY FUNCTION
  getValue()
    ...
    return value ? value : null;
  }
```
GROWI 上で Slack 通知をデフォルトで有効にする

## 前提

[GROWI](https://growi.org/ja/) には [Slack](https://slack.com/intl/ja-jp/) に更新情報を通知する機能があります。

通知できるものとしては、

- ページ作成の通知
- ページ更新の通知
- コメント投稿の通知

などがあります。

通知を流したい場合、投稿時に以下のようにチェックボックスをオンにします。

<img width="489" alt="スクリーンショット 2020-05-27 18.58.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59802/f6e3e131-6953-05d7-5633-7a725fb60330.png">

このチェックボックスはデフォルトではオフになっており、通知を流したい時に都度オンにします。

## なぜデフォルトで通知を有効にしたいか

- チーム内の情報共有のスピード感を上げたいため。
- 「通知したいときだけ通知」よりも「通知したくない理由がなければ通知」の方がチームのスタイルに合っていそうだった。
- 「Global notification」の設定により漏れなく通知することも可能だが、できれば任意で通知しないことも選択できる「User trigger notification」でやりたかった。

## 環境

- GROWI 3.8.2-RC
- Chrome 81.0

## カスタムスクリプト

管理者権限で「Wiki の管理 →カスタマイズ」を開き、カスタムスクリプトに以下を設定すればデフォルトで有効にできます。

```js
// ページエディター上でチェックボックスを有効にする （ページの新規作成時 or 更新時）
function turnOnSlackNotificationOnPageEditor() {
  const target = document.querySelector('body');
  const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
      if (mutation.attributeName !== 'class') {
        return;
      }

      const isEditorMode = mutation.target
        .classList
        .contains('on-edit');

      if (isEditorMode) {
        const checkbox = document.querySelector('#save-page-controls input[type=checkbox]');
        // チェックボックスがオフならオンにする
        if (checkbox && !checkbox.checked) {
          $(checkbox).closest('label').click();
        }
      }
    });
  });

  observer.observe(target, { attributes: true });
}

// コメントエディター上でチェックボックスを有効にする (コメント投稿時)
function turnOnSlackNotificationOnCommentEditor() {
  const target = document.querySelector('div.page-comments');
  if (!target) {
    return;
  }

  const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
      for (const node of mutation.addedNodes) {
        const isElement = (node && node.nodeType === 1);
        if (!isElement) {
          continue;
        }
        const checkboxes = node.querySelectorAll('.input-group-slack input[type=checkbox]');
        checkboxes.forEach(checkbox => {
          // チェックボックスがオフならオンにする
          if (!checkbox.checked) {
            $(checkbox).closest('label').click();
          }
        });
      }
    });
  });

  observer.observe(target, { childList: true, subtree: true });
}

$(() => {
  // ここに読み込みたい関数の名前を列挙する
  const functions = [
    turnOnSlackNotificationOnPageEditor,
    turnOnSlackNotificationOnCommentEditor,
  ];
  for (const i in functions) {
    functions[i]();
  }
});
```

エディターは動的に表示される場合があるので MutationObserver でノードの変更を監視し、エディターが表示されたタイミングでチェックボックスをオンにします。

## 参考にさせていただいた記事（記事作成の経緯）

既に同じ試みをされている記事があります。

- [【Growi】 編集するときに自動でSlack投稿のチェックボックスを有効にする \- Qiita](https://qiita.com/nao-guitarist/items/82ed2ed7cb2e9eacd08a)

こちらの記事ではキー入力を監視し、何か入力される度にチェックボックスをオンにする方法が取られています。

試させてもらったのですが、以下の点が気になりこの記事を書いてみました。

- コメント投稿時でも有効にしたかった。
- 「手動でチェックを外したはずなのにまた付いてる」ということが起こりそうだと思った。
- 試した環境では上手く通知されなかった。
    - `checkbox.checked = true` とするとチェックは付くが、どうやら内部的には有効にならないみたい（バージョンの問題かも？）。
    - `$(checkbox).closest('label').click()` のようにして外側の label に対してクリックを発生させたら上手く動いた。
Androidの時にテキストが真ん中寄せにならない

# どんな問題か
こんな感じで縦方向にテキストを中央配置しようとしたが、
IOSではうまくいくものおの、Androidは

```
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignContent: 'center', alignItems: 'center', height: 40}}>
  <Text style={{fontSize: 14, fontFamily: 'NotoSansJP-Regular'}}>テキスト</Text>
</View>
```

IOSではうまくいっているが、Androidではうまくいかない
微妙に上に寄ってしまう

# 解決策
https://react-mongolia.github.io/react-native/docs/0.40/text-style-props#includefontpadding
公式を見に行ったら解決策が書いてあった

> Set to false to remove extra font padding intended to make space for certain ascenders / descenders. With some fonts, this padding can make text look slightly misaligned when centered vertically. For best results also set textAlignVertical to center. Default is true.

どうやらAndroidだとfontによってはpaddingがあたってしまうみたい
-> includeFontPadding: falseに設定することでpaddingを取り除く

```
<View style={{flexDirection: 'row', justifyContent: 'space-between', alignContent: 'center', alignItems: 'center', height: 40}}>
  <Text style={{fontSize: 14, fontFamily: 'NotoSansJP-Regular', includeFontPadding: false}}>テキスト</Text>
</View>
```
【MySQL】データベースの文字コードを後から変更する

MySQLにて、作成済のデータベースの文字コードを後から変更する方法です。

## 環境
- Amazon Aurora(MySQL5.7)2.07.2（「開発/テスト」用）
- クライアントOS：Windows10

## 手順

### 1. データベースの文字コードの変更
データベースの文字コードを変更するDDLは以下の通り。

```sql
ALTER DATABASE `データベース名` DEFAULT CHARSET 変更したい文字コード COLLATE 変更したい照合順序;
```
データベース「hoge」の文字コードを「utf8mb4」、照合順序を「utf8mb4_bin」に変更する場合は以下の通り。

```sql:例

ALTER DATABASE `hoge` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_bin;
```

### 2. 変更内容の確認
以下のSQLを実行して変更内容を確認します。

```sql
SELECT SCHEMA_NAME,  DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'データベース名';
```
データベース「hoge」の確認を行う場合は以下の通り。

```sql:例

SELECT SCHEMA_NAME,  DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'hoge';
```

## 参考
[データベース属性(文字セットと照合順序)を変更する(ALTER DATABASE文) | DBOnline](https://www.dbonline.jp/mysql/database/index6.html)
Cloudflareを使ってみた

## Cloudflareとは
DNS + CDN のサービスです。
オリジンサーバーとの間でリバースプロキシのように動作し、画像、CSS、JavaScriptなどをキャッシュしてくれます。

## 良いところ
- 無料
- 設定が簡単
    - やらなきゃいけないことが少なく、情報が多い
- ルートドメイン(wwwなしのドメイン)でも問題なくCDNが使える
    - 基本的にルートドメインはCNAMEレコードの設定ができないので、他のCDNサービスを使う時は設定が面倒なことが多い
    - Cloudflareは`CNAME Flattening`という技術でルートドメインでもCNAMEレコードを設定することができる
- リダイレクトの設定が簡単
    - wwwありなし、http→httpsなど
    - 管理画面上で設定
    - `.htaccess`に`RewriteEngine...`とか書かなくて良い

## 設定方法
Herokuで運用しているサイトに導入してみます。
基本的にこちらの記事に沿って設定を進めました。
[『Heroku + Cloudflare』でルートドメインかつSSLでサイトを運用する | vdeep](http://vdeep.net/cloudflare-rootdomain-ssl-heroku)

### 登録
- [Cloudflareのトップページ](https://www.cloudflare.com/ja-jp/)からサインアップ
- メールアドレス、パスワードを入力
- サイトのドメインを入力
- 無料プランを選択
- メールの受信を確認し、Verify

### DNSの設定
- 管理画面より「DNS」タブを選択
- 自動で取得されているレコード情報があれば、すべて削除する
- 「レコードを追加」より以下の2つのレコードを追加
    - 「CNAME」「example.com」「sampleapp.herokuapp.com」「プロキシ済み」
    - 「CNAME」「www.example.com」「sampleapp.herokuapp.com」「プロキシ済み」
- 同じページ内の「Cloudflare ネームサーバー」という箇所に書いてあるネームサーバーを、ドメインを購入したサイトで登録([ネームサーバーの変更｜お名前.com Navi ガイド](https://www.onamae.com/guide/p/67))

### SSLの設定
- 「SSL/TLS」タブをクリック
- 「エッジ証明書」をクリック
- 「常にHTTPSを使用」「HTTPSの自動リライト」をONにする

### リダイレクトの設定
- 「ページルール」タブをクリック
- 「ページルールを作成」より、以下の2つのルールを作成
    - 「 http://example.com/* 」「常にHTTPSを使用」
    - 「 www.example.com/* 」「URLの転送」「301」「 https://mcbattle-ch.jp/$1 」

### Herokuにドメインを登録
まだドメインを登録していない場合は
Heroku管理画面 > 「Settings」 > 「Add domain」でドメインを追加します。

以上で設定完了です。
反映に時間がかかることがあるので、気長に待ちましょう。
私の場合、リダイレクトの設定が反映されるのに時間がかかりました。

## CDNにキャッシュされていることを確認
- 上記の設定が終わってから数時間待つ
- デベロッパーツールのNetworkタブを開く
- サイトを表示
- 画像やCSSファイル等をクリック
- Response Headersの中に「cache-control: max-age=14400」「cf-cache-status: HIT」などの記載があれば、正常にキャッシュされています。
    - 普通にみたらダメで、シークレットモードで見たら表示されてたことがありました。

ちなみに、キャッシュされたコンテンツが返ってくる時のレスポンスヘッダーは各CDNベンダーが独自に定義しているので、使っているCDNサービスによってヘッダーの名前が微妙に違ったりするらしいです。
[キャッシュがHitした情報を示すCacheヘッダの標準化提案 - ASnoKaze blog](https://asnokaze.hatenablog.com/entry/2018/09/09/225433)

## 終わりに
導入後、[Pagespeed Insights](https://developers.google.com/speed/pagespeed/insights/?hl=JA)のスコアが84→91くらいに上がりました。これだけいろんなことが出来て無料って最高ですね。
プログラミング初心者が知っておきたいサイト

## この内容について
この記事の内容は、あくまで私個人がプログラミングを始めた時に知っておきたかったサイトなどを
まとめたものです。特にWeb系エンジニアを目指す方に参考になるかと思います。

## プログラミング初心者が知っておきたいサイト
### [Progate](https://prog-8.com/)
<img width="1792" alt="Progate.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/74499ea1-4fc4-5e67-c373-3c54388d74d4.png">
問題を解きながら、プログラミングを学べるサイトです。
これからプログラミングを勉強し始める方は、必ず利用すべきです。

### [ドットインストール](https://dotinstall.com/)
<img width="1792" alt="ドットインストール.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/e3bde9ea-0f71-2f79-0d4c-376eba86b003.png">
短い動画を見ながら、プログラミングを学べるサイトです。
実際に動画を見ながら勉強することで、力が付きます。

### [サルワカ](https://saruwakakun.com/)
<img width="1792" alt="サルワカ.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/188feaa1-a024-a9fb-7235-f5c63eef45ce.png">
ゼロからプログラミング、Web制作について学べるサイトです。
特にコピペで使えるCSSサンプル集は、デザインの参考にもなります。

### [webliker](https://webliker.info/)
<img width="1792" alt="webliker.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/9a22338d-c6e6-15eb-54fd-eab9d1e21f80.png">
ゼロからプログラミング、Web制作について学べるサイトです。
特にCSSセレクタチートシートは、ブックマーク必須です。

### [Webクリエイターボックス](https://www.webcreatorbox.com/)
<img width="1792" alt="Webクリエイターボックス.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/13b942d9-a816-0cbd-1de6-2ae040011317.png">
最新のWebデザインやHTML・CSSの記事が多いサイトです。
特にCSSのFlexboxチートシートは、分かりやすいので必見です。
書籍「1冊で全て身につくHTML&CSSとWebデザイン入門基礎」も初心者に分かりやすく、買いでしょう。

### [ICS MEDIA](https://ics.media/)
<img width="1792" alt="ics.media.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/9bc2e040-61df-d2fa-82c4-c47d01cf81d4.png">
最新のフロントエンド技術の記事が多いサイトです。
読んでいて面白いと思える記事ばかりで、読むのが楽しいです。

### [MUUUUU.ORG](https://muuuuu.org/)
<img width="1792" alt="MUUUUU.ORG.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/7646aa1f-8022-c137-c85a-2fb8be52c860.png">
様々なデザインのサイトを一覧にまとめているサイトです。
実際にあるサイトを見て比較して、デザインの勉強に役立てます。

## まとめ
プログラミングは楽しみながらやることが大事です。
今回紹介したサイトを活用しながら、プログラミングに没頭しましょう！
上記のサイトに加えて、私が公開しているサイト「[コレワカ](https://korenarawakaru.com)」も
活用してもらえると嬉しいです。
Azure Durable Functions：ローカル開発環境構築

# はじめに

大した内容ではありませんがAzure Durable FunctionsをCore Toolsでローカル実行するための環境の導入手順を備忘録として纏めます。

# やりたいこと

PowerShell, Bash等のターミナルからCore ToolでDurableFunctionsOrchestration関数をローカル実行できるようにしたい

# 導入環境

- Windows 10 バージョン 20H2 (OS ビルド 19042.423)
- Azure Functions Core Tools 3.0.2534
- PowerShell 7.0.1

# 手順

Azure Functionsが接続するStorage Accountとして[Azure ストレージ エミュレーター](https://azure.microsoft.com/ja-jp/downloads/)をインストールする。





PowerShell（からでなくてもいいが）でユーザー環境変数にAzure ストレージ エミュレーターのパスを追加する。

```powershell
$CurrentSystemPath = [System.Environment]::GetEnvironmentVariable("Path", "User")
$CurrentSystemPath += "C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator"
[System.Environment]::SetEnvironmentVariable("Path", $CurrentSystemPath, "User")
```





Microsoft DocsではMicrosoft SQL Server 2012 Express LocalDBを使用することが記載されているがここはあえて[SQL Server 2019 Developer](https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads)をインストールする。





Azure ストレージ エミュレーターからSQL Server Express 2019のSQL データベース インスタンスを参照するように次のコマンドを実行する。

```
AzureStorageEmulator.exe init -server localhost

# 出力例
Windows Azure Storage Emulator 5.10.0.0 command line tool
Found SQL Instance localhost\SQLExpress.
Creating database AzureStorageEmulatorDb510 on SQL instance 'localhost\SQLExpress'.

Granting database access to user DESKTOP-UGLTD41\saiky.
Database access for user DESKTOP-UGLTD41\saiky was granted.

Initialization successful. The storage emulator is now ready for use.
The storage emulator was successfully initialized and is ready to use.
```

# 動作確認

Azure Functionsのローカル関数プロジェクトを作成する。

```
func init ProjectTestDurableFunctions

# 出力例
Use the up/down arrow keys to select a worker runtime:dotnet
```





ローカル関数プロジェクト内にDurableFunctionsOrchestration関数を作成する。

```
cd ./ProjectTestDurableFunctions/
func new --template "DurableFunctionsOrchestration" --name TestDurableFunctions

# 出力例
Use the up/down arrow keys to select a template:Function name: TestDurableFunctions
The function "TestDurableFunctions" was created successfully from the "DurableFunctionsOrchestration" template.
```





Azure ストレージ エミュレーターを起動する。

```
AzureStorageEmulator start

# 出力例
Windows Azure Storage Emulator 5.10.0.0 command line tool
The storage emulator was successfully started.
```





関数をローカルで実行する。

```
func start

# 下記の出力例が出力されていたら成功
Http Functions:

        TestDurableFunctions_HttpStart: [GET,POST] http://localhost:7071/api/TestDurableFunctions_HttpStart
```



# 参考文献

[Microsoft Docs :: Azure Functions Core Tools の操作](https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=windows%2Ccsharp%2Cbash)

[Microsoft Docs :: Azure ストレージ エミュレーターを使用した開発とテスト](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-use-emulator)
【3分解説】UNIXタイムって何？

##UNIXタイムの起源について調べてみた

なんで人間がわかりやすい時間表記じゃないの？わかりにくい。としか思っていなかったが、西島秀俊主演のドラマ「名探偵明智小五郎」で、UNIXタイムの話が出てきて、起源が気になったので調べてみた話。

##UNIXタイムって何？
wikipediaでは以下のように書かれている（抜粋）。

> UNIX時間（ユニックスじかん）またはUNIX時刻（ユニックスじこく、UNIX time（ユニックスタイム）、POSIX time（ポジックスタイム））とはコンピューターシステム上での時刻表現の一種。UNIXエポック、すなわち協定世界時 (UTC) での1970年1月1日午前0時0分0秒から形式的な経過秒数（すなわち、実質的な経過秒数から、その間に挿入された閏秒を引き、削除された閏秒を加えたもの）として表される。GPS時刻などとは異なり、大多数のシステムでは、本当の経過秒数を表すものではない[注 1]。

##疑問点
何故、起点が1970年1月1日なのか。

##1970年1月1日が起点になっている理由
特に意味はないらしい_(:3」∠)_

Wikipediaによると、
>時刻の表現として「UNIX時間」《協定世界時における1970年1月1日0時0分0秒からの経過秒数[注釈 1]》を使用しているコンピュータ等のシステムがある。この起点の時刻は、最初にUNIXにそのような機能が実装された時にキリがよかった過去の時刻であり、たまたまそう決めたというだけのものに過ぎない。

UNIXの開発者の一人であるデニス・リッチー氏によれば、深い考えがあって1970年1月1日0時0分0秒にしたわけではないということらしい。

1970年1月1日が起点になった理由は特にないということでスッキリした。
Route53のバックアップ

自分の備忘です。
取得したものをそのまま戻したいなんて要望、普通はないんじゃないかな？

#Route53をバックアップしておきたい

んですが、、、


##AWS-CLIを使ってホストゾーンとレコードセットの一覧取得
は、出来るんです。

```:ゾーンリスト取得
aws route53 list-hosted-zones --profile PROFILENAME --output json 
```

```:ゾーンのレコードセット取得
aws route53 list-resource-record-sets --hosted-zone-id ${zoneId} --output json 
```

##しかし、取得したjsonをそのままインポートすることはできない

なんかないかなーってDoc読んでいたら、[別のAWSアカウントへのホストゾーンの移行](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/hosted-zones-migrating.html)という記事を見つけた。

AWSさんとしては、json取得後手で加工して戻してとな・・

うーん。
開発中に結構Route53に対して破壊的なことやるから何かあったら手動ってのは面倒だし、焦ってる時の手作業は嫌だなぁ

##ということで作った
[スクリプト](https://github.com/shihou22/environment-scripts/tree/master/aws-scripts/route53-backup)

- AWS-CLIは導入済みの前提（そりゃそうだ）
- スクリプト内でjq使っているんでjqも必須
    -  sudo apt-get install jq
- 実行したらzoneidでフォルダ作成→フォルダ内にレコードセットのjson作成（.txtも作るけど使わないっすわ）
    - 個人的な趣により、zoneid毎にフォルダ作るようにしてある
- impoprtするときはAWS CLI使ってjsonをそのままインポートすればよい
    - コピー目的で別のホストゾーンに移行するときは中身のドメイン名書き換えて
    - Docsの作業内容を簡単にするためのツールなんで、Docsの通りに戻せるようにした

```:インポート
aws route53 change-resource-record-sets --hosted-zone-id id-of-new-hosted-zone --change-batch file://path-to-file-that-contains-records
```

jq・・・扱い方本気で忘れてる。それにshell触るの久しぶりすぎてきたないなぁ
--profileにも対応していないから時間作って対応しておかないと。

##検証環境
バックアップスクリプト実行環境

- Linux(Ubuntu18.04LTS)
    - aws cli 
        - aws-cli/2.0.16 Python/3.7.3 Linux/5.3.0-53-generic botocore/2.0.0dev20
    - jq
- 対象のDNS
    - AWS(Route53)
        - パブリップホストゾーン
        - プライベートホストゾーン

##参考
- [AWS CLI を使用して Route 53 でエイリアスリソースレコードセットを作成する方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/alias-resource-record-set-route53-cli/)
- [ゾーンファイルをインポートしてレコードを作成する](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-creating-import.html)
- [AWS CLI を使用して Amazon Route 53 のリソースレコードセットを作成する際に発生するエラーのトラブルシューティング方法を教えてください。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/troubleshoot-route53-resource-record/)
- [route53 Command List](https://docs.aws.amazon.com/cli/latest/reference/route53/)
"ExecJS::RuntimeError" 

####起動はするのに、、、

railsにて、初めの段階でハマったのでメモメモ。


##エラー内容
 ExecJS::RuntimeError

###バージョン
 Rails 5.2.4
 ruby 2.5.1

###解決策
Gemfile
>gem 'mini_racer', platforms: :ruby

上記のコメントアウトを外してあげて、ターミナルで[bundle install]してあげれば、完了。


##参考URL
ExecJS::RuntimeError（2019年版）
https://github.com/railsgirls-jp/coach.info/issues/27
UIWebViewを使っているFrameworkを探す

アプリにUIWebViewが含まれている場合、App Store Connectへのアップロード時にITMS-90809の警告がメールで送信されたりするかと思います。

> ITMS-90809: Deprecated API Usage - App updates that use UIWebView will no longer be accepted as of December 2020. Instead, use WKWebView for improved security and reliability. Learn more (https://developer.apple.com/documentation/uikit/uiwebview).

警告にもある通り、既存アプリでUIWebViewを利用している場合は2020年12月で受け付けがされなくなるようなので、それまでに対応が必要です。
(参考: [ウェブビューを使ったAppのアップデート \- ニュース \- Apple Developer](https://developer.apple.com/jp/news/?id=12232019b))

アプリ本体のコードに含まれている場合は "UIWebView" のようなキーワードでgrepして探せばいいのですが、依存しているFrameworkの中にあると探しづらいです。
ここでは、`nm` コマンドを使ってシュッと探す方法をご紹介します。

## 方法

```sh
FRAMEWORK_DIRS=$(find . -name '*.framework')
for framework in $FRAMEWORK_DIRS; do
    fname=$(basename $framework .framework)
    echo $framework/$fname
    nm $framework/$fname | grep UIWeb
done
```

こんな感じのシェルスクリプトを作って実行すれば楽に探せます。

## 解説

`nm` コマンドは、オブジェクト内のシンボルをリストするコマンドです。
(参考: [nmコマンドでオブジェクトからシンボルのリストを表示 \- Qiita](https://qiita.com/sassy_watson/items/64ecc34157e71c98d6dc))

このコマンドを使ってFramework内にUIWebViewのシンボルがあるかを調べることができます。
アプリで使われているFrameworkは複数あることが多く、CocoaPodsやCarthageなどで管理されていることも多いと思います。そのため、シェルスクリプトにしてプロジェクトディレクトリ配下のFramework全てに `nm` するようにしています。

## 参考記事

- [CordovaのUIWebView→WKWebView移行についてまとめ \- Qiita](https://qiita.com/kishisuke/items/d201790aeae2129ff2e3)
- [Determining which frameworks use UIWebView \- Igor Kulman](https://blog.kulman.sk/determining-which-frameworks-use-uiwebview/)
Photonを使ってのカメラワーク

FPSなどのゲームをつくって自分からのカメラ視点を設定した場合

Photonなどのネットワークを介して動作したときにカメラの視点がうまく
自分の視点に切り替わらなかったのでその時の対処法を備忘録的に、、

photonManager的スクリプトで
// マッチングが成功した時に呼ばれるコールバック
    public override void OnJoinedRoom()
    {
        // マッチング後、ランダムな位置に自分自身のネットワークオブジェクトを生成する
        GameObject camera PhotonNetwork.Instantiate("Camera",player.transform.position,Quaternion.identity);
    }
いたって簡単で
cameraのスクリプトに
if(!photonView.IsMine)
{
  gameObject.SetActive(false);
}
にするだけでした。

ちなみに私のプレーヤー追従のカメラスクリプトは以下です
参考までに




void FixedUpdate()
    {
        if(!photonView.IsMine)
        {
            gameObject.SetActive(false);
        }

        if(photonView.IsMine)
        {
            // カメラの位置を設定
            Transform player = GameObject.FindGameObjectWithTag("Player").transform;


            var desiredPos = player.position - player.forward * baseDistance + Vector3.up * baseCameraHeight;

            cam.position = Vector3.Lerp(cam.position, desiredPos, Time.deltaTime * chaseDamper);

            // カメラの向きを設定
            cam.LookAt(player);
        }
         


        
        
    }
```
Googleカレンダーの添付ファイル順を調べた話

#背景
Googleカレンダーのスケジュールに添付ファイルを付けたら、順序が思った様に並んでくれない！
って問いかけがあったので、ググってみるも、中々無さそうだったので調べてみました。
#結論
どうやらURLの昇順になっている模様
#調べてみた事
##ファイル名順にならない事を確認する
ファイル名を01~05で始まる名前でgoogleドライブ上にスプレッドシートを作成し、カレンダーの予定にファイル名順で貼り付けたり、逆順にしたり。
ファイル名順では無さそうだが、決まった順序にはなることを確認。
##作成日順を疑う
作成日順も疑ったが、ファイル名順と変わらないので、違いそう。
##更新日を疑う
05ファイルを更新してみるものの、変化なし。
貼り付け直しても変化なし
##ファイルの種類を増やしてみる。
どうやら、ファイルの種類で棲み分け出来ている模様、とは言え、ファイルの種類内ではバラバラ。
##URLを疑う
ファイルの種類って事は、URLも違うなって事に気づき、各ファイルのURLをスプレッドシートに貼り付け、ソートしてみたら、カレンダーに添付している順序と一致した。

#最後に
順序性を持たせたいファイル群であれば、予定作成時の説明にファイルのリンクを貼る等の措置を施した方が良さそう。（Carl+kおすすめ）
固有値と固有ベクトル : 線形代数をPythonで<7>

# 線形代数
理系大学で絶対に習う線形代数をわかりやすく、かつ論理的にまとめる。ちなみにそれをPythonで実装。たまに、Juliaで実装するかも。。。
・Pythonで動かして学ぶ！あたらしい数学の教科書 -機械学習・深層学習に必要な基礎知識-
・世界基準MIT教科書 ストラング線形代数イントロダクション
を基に線形代数を理解し、pythonで実装。

# 環境
・JupyterNotebook
・言語：Python3, Julia1.4.0

# 固有値と固有ベクトル
固有値と固有ベクトルは人工知能でデータの要約する主成分分析法で用いられる。

### 固有値、固有ベクトル
正方行列Aを考える。
この行列Aにたいして、

```math
A\vec{x}=λ\vec{x}
```
を満たすとき、

```math
λを行列Aの固有値\\
\vec{x}を行列Aの固有ベクトル\\
```
という。

### 固有方程式
上のような式に対して、ベクトルに影響を及ぼすことのない単位行列Eをかける。

```math
A\vec{x}=λE\vec{x}
```
右辺を移項して整理する

```math
(A-λE)\vec{x} = \vec{0}
```
これは***要素がすべて0のベクトルを表す。これに対して、逆行列を考えても零
ベクトルである。
この式を***固有方程式***という。

### 固有方程式による固有値、固有ベクトルの求解

```math
(A-λE)\vec{x} = \vec{0}
```
に沿って、

```math
A=\begin{pmatrix}3 & 1\\2 & 4\end{pmatrix}
```
として具体例で行う。
そうすると、

```math
det(A-λE)\vec{x} = 0\\
⇔
det(\begin{pmatrix}3 & 1\\2 & 4\end{pmatrix}-λ\begin{pmatrix}1 & 0\\0 & 1\end{pmatrix})\vec{x} = 0\\
⇔
det\begin{pmatrix}3-λ & 1\\2 & 4-λ\end{pmatrix} = 0\\
⇔(λ-2)(λ-5)= 0\\
```
これによって、***固有値は2または5***になる。
固有値によって固有ベクトルも変わってくるので。2,5のときそれぞれで考える。

```math
\vec{x} = \begin{pmatrix}p\\q\end{pmatrix}
```
とおくとき、λ＝2で計算すると、

```math
det(A-λE)\vec{x} = 0\\
\begin{align}
det(A-λE)\vec{x}&=
det(A-2E)\begin{pmatrix}p\\q\end{pmatrix} \\
&=\begin{pmatrix}1 & 1\\2 & 2\end{pmatrix}\begin{pmatrix}p\\q\end{pmatrix}\\
&=\begin{pmatrix}p+q\\2p+2q\end{pmatrix} \\
&= \vec{0} 
\end{align}
```
これより、p+q = 0であるといえるので、任意の実数tを置いて、xベクトルは

```math
\vec{x}=\begin{pmatrix}t\\-t\end{pmatrix}
```
と固有ベクトルを求められる。

λ=5のときは、

```math
\vec{x}=\begin{pmatrix}t\\2t\end{pmatrix}
```
となる。

###プログラム
#####固有値、固有ベクトルを求めるプログラム

#####python

```python:7pythoneigenvaluevector
import numpy as np

A = np.array([[3, 1],[2, 4]])

ev = np.linalg.eig(A)
print(ev[0])
print(ev[1])
```

```terminal
[2. 5.]
[[-0.70710678 -0.4472136 ]
 [ 0.70710678 -0.89442719]]
```

ここで`linag.eig関数`を使っている。固有値が英語で、***eigenvalue***というからだ。

原理的なプログラムを組もう。今回は固有値までを求める。
##### python(原理的)

```python:7pythoneigenvaluevector2
import numpy as np
import sympy

#A = [[a, b],
#     [c, d]]
a = int(input())
b = int(input())
c = int(input())
d = int(input())
#=>3
#=>1
#=>2
#=>4

x = sympy.Symbol('x')
eigenequa = x**2 - (a + d)*x + (a * d) - (b * c)```
print(eigenequa)
# factorization = sympy.factor(eigenequa)
# print(factorization)
solve = sympy.solve(eigenequa)
print(solve)
#=>x**2 - 7*x + 10
#=>[2, 5]
```

juliaはものすごい簡単なので、載せときます。
##### julia

```julia:7juliaigenvaluevector
using LinearAlgebra
F = eigen([3 1; 2 4;])

#=>Eigen{Float64,Float64,Array{Float64,2},Array{Float64,1}}
#=>values:
#=>2-element Array{Float64,1}:
#=> 2.0
#=> 5.0
#=>vectors:
#=>2×2 Array{Float64,2}:
#=> -0.707107  -0.447214
#=>  0.707107  -0.894427
```
たった2行だけ！すごい...

今日はここまで
JavaScriptでの非同期通信実装①

# 非同期通信を実装
まず結論はrespond_toを用います。
以下、定義です。

```javascript
respond_to do |format|
  format.html { render ... } 
  format.json { render ... } 
end
```
html形式だとそのまま該当するビューを返して終わりですが
JSONを返す場合は下の書き方で指定してあげましょう。
非同期通信を施したい箇所をrender以下に記述してください。
なお、記述箇所はやり方にもよりますが
コントローラーのcreateアクション内に記述します。

次は肝となるajaxについて記述します。
相対パスの書き方でハマった

##chmod 755 /.bash_profileと書いてはまった
この書き方だとルートディレクトリにある.bash_profileを探している。
ホームディレクトリにいる状態で、ホームディレクトリ下のやつを探すので、(2020/5/28追記)
本当は`~/.bash_profile`か`.bash_profile`と書く。

言い訳をすると、
viでbash_profileを編集しようとして、"e212 can't open file for writing"と怒られて読み取り権限しかないことに気づいて、chmodを使っていた。
`sudo vi /.bash_profile`でviが起動できてたから、/.bash_profileで正しいと思って、`chmod 755 /.bash_profile`と書いてしまっていて時間を無駄にしました。


###パスはしっかり書かないといけないということを学びました。`~/.bash_profile`か`.bash_profile`と書くようにします。

もうこんなハマり方は二度としたくないけど、自分のことだからまたやりそうなので備忘録として書きました。