OmniAICreator/Qiita-1.07M huggingface dataset:
SwiftUIでドラゴンクエストの吹き出しのデザインを表現

# はじめに
[ドラゴンクエストウォーク](https://www.dragonquest.jp/walk/)リリースおめでとうございます:clap:

とても面白い位置ゲーですよね！
昨日夜中にコンビニ行くついでにやるかと気軽にアプリ開いてからかれこれ1時間ほど散歩してました:blush:
ドラクエ8に熱中していた小学生時代を思い出したりと懐かしい気持ちにもなれるゲームかなと！



前回はInstagramのHome画面をSwiftUIで表現してみましたが、
今回はドラクエの吹き出しをSwiftUIで表現してみました！

# プレビュー

<img width="297" alt="スクリーンショット 2019-09-13 18.24.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/b84ae821-7f94-9003-be87-073df650cad5.png">

# コード
背景が白だと吹き出しの白枠が背景に溶けこんでしまうため今回は背景色を緑にしてます！

```swift:DQW.swift
import SwiftUI

struct DQW: View {
    var body: some View {
        ZStack(alignment: .center) {
            Color.green
            ZStack {
                Rectangle().foregroundColor(Color.white)
                    .cornerRadius(15.0)
                Rectangle().foregroundColor(Color.black)
                    .frame(width: 242, height: 92)
                    .cornerRadius(15.0)
                VStack {
                    HStack {
                        Text("ドラクエウォークリリースおめでとう!").bold()
                            .font(.system(size: 12))
                            .foregroundColor(Color.white)
                            .padding(.leading, 10)
                            .padding(.top, 10)
                        Spacer()
                    }
                    Spacer()
                }
            }.frame(width: 250, height: 100)
        }
    }
}

struct DQW_Previews: PreviewProvider {
    static var previews: some View {
        DQW()
    }
}
```
Xcode10.2にしたらCarthageでinstallしたライブラリがエラーになる

#なんだこれ
今日xcodeを10.1から10.2.1にあげたのですが、コンパイルが通らなくなったので忘却録で残します。

エラーメッセージは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325497/cc11f180-bc3b-7655-8342-49d150f890a2.png)

で、google先生に翻訳をお願いすると
`Swift 4.2.1でコンパイルされたモジュールは、Swift 5.0.1コンパイラーではインポートできません：・・・・`
とのこと。

コンパイラが違うよ！ダメだよ！とのこと。いいじゃん別に！（ダメです）
なのでちゃんとどっちかに合わせる必要がありそうです。

#コマンドラインに使うToolを確認
Xcode→preference→Locationsの
Command Line Toolsを合わせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325497/8cb88b5f-da99-fc1b-caf3-a5b3e76890e7.png)

#Charthageでupdateの前に

じゃあ早速carthageをと行きたいところですが、その前にcarthageのバージョンを確認しましょう。

例えば普通に
```sh
carthage update --platform iOS
```
と実行すると下のようなエラーになリました。

```sh
*** Downloading RxSwift.framework binary at "[4,5]"
***  Skipped installing RxSwift.framework binary due to the error:
	"Incompatible Swift version - framework was built with 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3) and the local version is 5.0.1 (swiftlang-1001.0.82.4 clang-1001.0.46.5)."

    Falling back to building from the source
```
これはリモートブランチに**あなたのxcodeで使えるバージョンのバイナリがないよ！！**って言っています。
ので、こういう場合はローカルでビルドしてバイナリを作る必要がありますが、
Charthageのversion0.20からは**Swiftのバージョンが異なる場合ビルドしてくれる**そうです。👍(連打！！)

なので、Charthageをversion0.20以上にあげておきましょう。

#Charthageでupdateだー

--no-use-binariesオプションを指定してあげると、できているバイナリを使わないでビルドし直してくれます。
👍(連打！！)

```sh
carthage update --platform iOS --no-use-binaries
```
エラーなくなった！

# 終わりに

普段何気なく使ってるCarthageですが、versionで色々できることとか増えてるのでちゃんと調べないと駄目だなあと改めて実感しました。壁に当たって乗り越えて成長ですね。（よく当たるんですがw）


#参考
大変おせわになりました。
https://qiita.com/kokoheia/items/7d3c2107d281316173be
https://doroidpanic.com/xcode10-2-10e125%E3%81%AB%E3%81%97%E3%81%9F%E3%82%89carthage%E3%81%A7incompatible-swift-version/
windowsでJavaを使用するbatファイル

<h1>内容</h1><br>
<div style="background-color: #d2efff;padding-left:5px;">
<p>@echo off</p>
<p>cd %~dps0</p>
<p>SET CLASSPATH=%CLASSPATH%;gson-2.3.1.jar<br />SET CLASSPATH=%CLASSPATH%;mongo-java-driver-2.14.3.jar</p>
<p>SET DATETIME=%date:~-10,4%%date:~-5,2%%date:~-2,2%%time:~0,2%%time:~3,2%%time:~6,2%<br />SET RESULT_FILE_KPF=%~dps0result\%DATETIME%\favorite_kpf.txt<br />SET PROPERTIES_FILE=%~dps0env_Accountadditionals.properties</p>
<p>SET INPUT_FILE_KPF=%RESULT_FILE_KPF%<br />SET RESULT_FILE_KPF_URL=%~dps0result\%DATETIME%\favorite_kpf_url.txt<br />SET RESULT_FILE_KPF_DATE=%~dps0result\%DATETIME%\favorite_kpf_date.txt<br />SET RESULT_FILE_KPF_UNIQUEID=%~dps0result\%DATETIME%\favorite_kpf_uniqueId.txt</p>
<p>javac -encoding UTF-8 DataCollect_DB_Accountadditionals_kpf.java<br />javac -encoding UTF-8 DataCollect_Accountadditionals_kpf_url.java<br />javac -encoding UTF-8 DataCollect_Accountadditionals_kpf_date.java<br />javac -encoding UTF-8 DataCollect_Accountadditionals_kpf_uniqueId.java</p>
<p>java DataCollect_DB_Accountadditionals_kpf %RESULT_FILE_KPF% %PROPERTIES_FILE%<br />java DataCollect_Accountadditionals_kpf_url %INPUT_FILE_KPF% %RESULT_FILE_KPF_URL%<br />java DataCollect_Accountadditionals_kpf_date %INPUT_FILE_KPF% %RESULT_FILE_KPF_DATE%<br />java DataCollect_Accountadditionals_kpf_uniqueId %INPUT_FILE_KPF% %RESULT_FILE_KPF_UNIQUEID%</p>
</div>
HULFT8 インストール

# 事前準備
HULFTインストールイメージに同梱のVisual C++をインストール
※64bitOSの場合は2つとも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/e73b01a9-a790-da18-9d8b-9261827aa697.png)



# インストール
1. Setup.exe実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/dbb1a548-288c-0f7a-17ac-241692861c3a.png)




2. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/e68af137-52e9-d0cc-eb85-9289d8145943.png)





3. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/7af2043e-e6e3-8c31-1d26-c5793b43ade5.png)



4. ライセンス情報を入れて、次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/2ce303f9-74d8-f138-4586-e765466a66a6.png)



5. そのまま、次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/6627b7d5-062e-c54d-3bfa-3116a8299001.png)



6. はい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/5c03aa38-ebcd-ab42-ec15-8edb49a08a00.png)



7. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/8e20ef44-144c-460c-3c9d-b6e7d790a76e.png)



8. はい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/aa2e3609-0f38-e811-7d01-f95358793a9b.png)



9. はい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/7f46ba0d-4aef-a269-2b1b-a1cbdebc8c19.png)



10. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/8783fddc-195a-70a6-13f1-97c7718ec24f.png)


11. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/87a4d047-236b-4f16-5f5a-e56284be8e60.png)


12. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/70ad2ff9-268e-664e-7cba-237bb8984967.png)


13. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/e87a9da6-21ab-fd7c-b1dd-a2dd09a1d359.png)


14. 次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/c3ba8c1b-9be8-9831-038c-367107a5e3d1.png)


15. 完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315938/c5c8ea88-32ca-6cd4-51d5-229e9c52a432.png)


16. OS再起動
HULFTサービスは自動起動設定になっているが、インストール直後は止まっている







# 事後作業
1. a
2. a
3. a
4. a
5. a
UnityWebViewがうまく動かない問題を解決した

最新のUnity WebViewにて、何も考えずに入れると、MacのUnityEditorで開いたらUnityが落ちたり、iOSで開けなかったりしたので解決策共有

## Mac
Macは、PlayerSettingsにて Metal Editor Support のチェックを外せばOK.
古いUnityだった場合は、 Auto graphics API のチェックを外すらしい
参考：https://github.com/gree/unity-webview#mac-editor

## iOS
iOSは、webViewObject.Init時に enableWKWebView: trueを指定すればOK.
webViewObject.Init(enableWKWebView: true)
参考：https://github.com/gree/unity-webview#ios

## その他
あと、Unityバージョンによって必要な作業がある場合があるっぽいので参考URLの下の方も目を通しておくと良さそう。
Androidは開くけどスクロールがガクガクするの、設定で直ったりもするらしいので。


**※ 教訓：新規入れ直しのときは、Readmeを読もう！**
Go言語でNamed Typesで定義した変数に基底型の値を入れようとするとエラーがでる

## 遭遇した問題
Go言語にて Named Types で定義した変数に基底型の値を入れようとすると以下のエラーをはく。
`cannot use hogehoge (variable of type string) as fugafuga value in variable declaration`

## 内容
```go
type NameType string // named types

func funcName (val string) {
    var nt NameType = val // ここでerror
}
```

## 解決策


```go
type NameType string

func funcName (val string) {
    nt := NameType(val)// ok
}
```

## 原因
変数を経由して代入しようとすると、 **型が確定している** ため、「型が違うよ!」 というエラーが出る。
変数を経由せず、値をそのままいれるか、

```go
type NameType string

var nt NameType = "row data"
```

変数を経由する場合は以下のようにする。

```go
type NameType string

val = "row data"
nt := NameType(val)
```

## まとめ

```go

type MyString string
var x MyString
x = "hogehoge" //<-これはできる
s := "hugahuga"
//x = s  <- これはできない
x = MyString(s) // <-これはできる
```
何度やってもNill class、原因不明のmigrate faild、問題はcredentials.yml.encが握っていた。

# なんかgit cloneしたプロジェクトが・・・
git coloneしてきたプロジェクトのデータベースをmigrateしようとすると、うまく動作しない。

```
$ bundel exec rails db:migrate
/Users/naoya.ohsaki/.rbenv/versions/2.6.2/gemsets/finacial_analysis/gems/bootstrap-sass-3.4.1/lib/bootstrap-sass/version.rb:2: warning: already initialized constant Bootstrap::VERSION
/Users/naoya.ohsaki/.rbenv/versions/2.6.2/gemsets/finacial_analysis/gems/bootstrap-4.3.1/lib/bootstrap/version.rb:4: warning: previous definition of VERSION was here
/Users/naoya.ohsaki/.rbenv/versions/2.6.2/gemsets/finacial_analysis/gems/bootstrap-sass-3.4.1/lib/bootstrap-sass/version.rb:3: warning: already initialized constant Bootstrap::BOOTSTRAP_SHA
/Users/naoya.ohsaki/.rbenv/versions/2.6.2/gemsets/finacial_analysis/gems/bootstrap-4.3.1/lib/bootstrap/version.rb:5: warning: previous definition of BOOTSTRAP_SHA was here
rails aborted!
NoMethodError: Cannot load database configuration:
undefined method `[]' for nil:NilClass
(erb):53:in `<main>'
・
・
・
```

railsのエラーっていうのはものすごいファイルパスが出てくるから疲れますよね。早くエラーが出ないように扱い慣れていきたいもんです。

## 解決策。というか、今回の落ち
本来あるはずのファイルが無い

### secrets.ymlが無い。
secrets.ymlとは

> configフォルダ内に新しくsecrets.ymlファイルが生成されます。デフォルトでは、このファイルにはアプリケーションのsecret_key_baseが含まれていますが、外部API用のアクセスキーなどの秘密キーもここに保存できます。

### credentials.yml.encとmaster.key
 
ということなのだが、rails5ではこのファイルに成り代わり、rails newをすると、credenticial.yml.encとmaster.keyって奴ができるということなので、こいつを作ってやればいい。

```
$ EDITOR="vi" bin/rails credentials:edit
```

editコマンド使ってるから、もともとファイルが作られてること前提で使われるものだと思っていましたが、ファイルがない場合にこいつを使うと、新しく生成されます。vimが立ち上がるはずなので、何もせずに:wqで作業は完了です。
そうすれば、migrateできるようになりました。
SVGのクリック座標取得

## 参考

>```js
>var pt = svg.createSVGPoint();  // Created once for document
>
>function alert_coords(evt) {
>    pt.x = evt.clientX;
>    pt.y = evt.clientY;
>
>    // The cursor point, translated into svg coordinates
>    var cursorpt =  pt.matrixTransform(svg.getScreenCTM().inverse());
>    console.log("(" + cursorpt.x + ", " + cursorpt.y + ")");
>}
>```
>javascript - How to get the click coordinates relative to SVG element holding the onclick listener? - Stack Overflow
>https://stackoverflow.com/questions/29261304/how-to-get-the-click-coordinates-relative-to-svg-element-holding-the-onclick-lis

 
## React+TypeScript サンプル

```ts
const handleClick = (event: React.MouseEvent<SVGSVGElement, MouseEvent>) => {
  const svg = event.currentTarget
  const pt = svg.createSVGPoint()

  pt.x = event.clientX
  pt.y = event.clientY

  const ctm = svg.getScreenCTM()
  if (ctm) {
    const cursorPt = pt.matrixTransform(ctm.inverse())
    console.log(cursorPt)
  }
}
```
【Flutter】iOSアプリがMultiple commands produce '/build/ios/Debug-iphonesimulator/Runner.app/Frameworks/Flutter.frameworkでビルドエラーになる

# 対処
下記の手順でアプリをビルドしたところ、うまく動作しました。

```
git clone <reopsitory>
Xcode > File > Workspace Settings > Build Systems > Legacy Build System
flutter clean
flutter pub get
carthage bootstrap --platform ios
pod clean
pod setup
pod install
flutter run
```

# 追加対応
上記対応だけでは足りなかったようで、何かを拍子にまたビルドできなくなりました。
参考リンク2つ目の記事を参考に、Embed FrameworksからFlutter.frameworksを削除したところ、ビルドできるようになりました。

# 参考
https://github.com/flutter/flutter/issues/20685
Build SystemをLegacy Build Systemにすると解消することが記載されていました。

https://qiita.com/SatoTakeshiX/items/047a313f564879e290ec
Embed Frameworksからframeworkを削除する対応が記載されています。
AIZU ONLINE JUDGE 4探索

#4_A(線形探索)

```c++
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n; cin >> n;
    vector <int> A(n);
    for (int i=0; i<n; i++) cin >> A[i];
    int m; cin >> m;
    vector <int> B(n);
    for (int i=0; i<m; i++) cin >> B[i];
    
    int cnt=0;
    for (int i=0; i<m; i++){
        int searchValue=B[i];
        for (int k=0; k<n; k++){
            if (searchValue==A[k]){
                cnt++;
                break; //breakすることで重複を防げる！
            }
        }
    }
    cout << cnt << endl;
}
```

#4_B(二分探索)
```c++
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n; cin >> n;
    vector <int> A(n);
    for (int i=0; i<n; i++) cin >> A[i];
    int m; cin >> m;
    vector <int> B(n);
    for (int i=0; i<m; i++) cin >> B[i];
    
    int cnt=0;

    
    for (int i=0; i<m; i++){
        int right=n-1;
        int left=0;
        while(left<=right){//見つからなければ,left>rightになるので"<="の条件でok!
            int middle=(left+right)/2;
            if (A[middle]==B[i]) {
                cnt++;
                break;
            } else if(A[middle]>B[i]){
                right=middle-1;
            } else{
                left=middle+1;
            }
        }
    }
    
    cout << cnt << endl;
}
```

#4_C(ハッシュ)

```c++
#include <bits/stdc++.h>
using namespace std;

#define M 1046527
#define NIL (-1)
#define L 14

char H[M][L];

//文字から数値に変換
int getChar(char ch){
  if ( ch == 'A') return 1;
  else if ( ch == 'C') return 2;
  else if ( ch == 'G') return 3;
  else if ( ch == 'T') return 4;
}

//文字列から数値へ変換してkey(ハッシュ関数の入力値＆ハッシュ値)を同時生成
//AAAのキーは文字列"AAA"。これをハッシュ関数の引数として数値に変換したい。
long long getKey(char str[]){
  long long sum = 0, p = 1, i;
  for ( i = 0; i < strlen(str); i++ ){
    sum += p*(getChar(str[i]));
    p *= 5;
  }
  return sum; //ハッシュ値(数値変換出来上がり！)
}

//配列の添え字を決める(ハッシュ値が0~M-1になるように設定する)

//key=ハッシュ値(関数getKeyの返り値sumのこと！)
int h1(int key){ return key % M; }
int h2(int key){ return 1 + (key % (M-1)); }
//異なるkeyが同一のハッシュ値になっても大丈夫なオープンアドレス法
int hash(int key, int i){ return (h1(key)+i*h2(key))%M;}

int find(char str[]){
  long long key, i, h;
  key = getKey(str);
  for ( i = 0;; i++){
    h = hash(key, i);
    if( strcmp(H[h],str) == 0 ) return 1;
    else if ( strlen(H[h]) == 0 ) return 0;
  }
  return 0;
}

int insert(char str[]){
  long long key, i, h;
  key = getKey(str);
  for ( i = 0; ; i++ ){
    h = hash(key, i);
    if( strcmp(H[h],str) == 0 ) return 1;
    else if ( strlen(H[h]) == 0 ){
      strcpy(H[h], str);
      return 0;
    }
  }
  return 0;
}


int main(){
  int i, n, h;
  char str[L], com[9];
  for ( i = 0; i < M; i++ ) H[i][0] = '\0';
  scanf("%d", &n);
  for ( i = 0; i < n; i++ ){
    scanf("%s %s", com, str);

    if ( com[0] == 'i' ){
      insert(str);
    } else {
      if (find(str) ){
        printf("yes\n");
      } else {
        printf("no\n");
      }
    }
  }
  return 0;
}
```
UISearchBarのプライベートなプロパティにアクセスするコードがiOS 13では禁止になったようです

## 「UISearchBarのプライベートなプロパティにアクセスする」とは

`UISearchBar` の `textField` に色を設定するために `attributedPlaceholder` をセットしたいときなど、(UISearchBarに限らないが)公開されていないUI要素などにアクセスするために `value(forKey:)` を使う方法を使うことがあった。

```swift
searchBar.textField?.attributedPlaceholder = placeholder

extension UISearchBar {
	var textField: UITextField? {
		return value(forKey: "_searchField") as? UITextField
	}
}
```

iOS 13でこの方法を用いると以下のようなエラーがランタイムで発生して、アプリがクラッシュします。
「このアクセスの方法は禁止されており、アプリケーションのバグです」的なことが言われます。

```
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UISearchBar's _searchField ivar is prohibited. This is an application bug'
```

## iOS 13以降の対応方法

iOS 13以降では `searchTextField` というプロパティが外部公開されているので、次のように書いて解決させました。

```swift
extension UISearchBar {
	var textField: UITextField? {
		if #available(iOS 13.0, *) {
			return searchTextField
		} else {
			return value(forKey: "_searchField") as? UITextField
		}
	}
}
```

## 参考
- [UISearchBarのカスタマイズ \- Qiita](https://qiita.com/noppefoxwolf/items/ccbe9bb93edb874064b0)
iPhoneにQuickTypeバーが表示されない場合（名前、メールアドレス、電話番号など）

# 概要
入力フィールドで、名前、e-mail、電話番号の候補が表示されない時の対処方法
proactive suggestions contact interactions

# 環境
- iPhone Xs

# 対応
設定 > 連絡先.app > Siriと検索 > Siriおよび提案を**ON**

<img width="375" alt="IMG_4EE73B3F101F-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/9f27c956-7735-8481-6fa8-c36463b33596.jpeg">

# 参考
- [How to Allow Contact Suggestions in Apps on an iPhone: 3 Steps](https://www.wikihow.com/Allow-Contact-Suggestions-in-Apps-on-an-iPhone)
- [Understanding iOS Proactive Suggestions SitePoint](https://www.sitepoint.com/understanding-ios-proactive-suggestions/)
WebViewのデバッグでSafari Webインスペクタを使う

#要約
- iOSでWebViewを使う機能は、SafariのWebインスペクタを使うと楽だった
- iPhone simulatorにWebViewを表示

#準備
- Safari>開発>シミュレータ-iPhone ** -iOS **

#Webインスペクタ
<img width="722" alt="スクリーンショット 2019-06-10 17.03.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/ade53bf2-f6c4-44f7-39f4-4ec8c807df05.png">

#シミュレータ
背景はグレー
（Webインスペクタで表示されているCSSの通り）
<img width="500" alt="スクリーンショット 2019-06-10 17.03.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/3a213080-3456-fa53-cbf3-f92a0bcf95c5.png">


#Webインスペクタでcolorを変更する
変更は瞬時にシミュレータへ反映されるのでデバッグしやすい
<img width="1119" alt="スクリーンショット 2019-06-10 17.04.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405675/df4f9e74-1b52-c31e-1219-f0ea471231a1.png">
Swift カウントアップアニメーション

# 概要
よくある、数字がカウントアップしていくアニメーション

# 前提条件
- Swift 4.2
- Xcode 10.2

```swift

    var startTime: CFTimeInterval!
    
    var fromValue: Int!
    var toValue: Int!
    var duration: TimeInterval!

    func animate(from fromValue: Int, to toValue: Int, duration: TimeInterval) {
        text = "\(fromValue)"
        
        self.startTime = CACurrentMediaTime()
        
        self.fromValue = fromValue
        self.toValue = toValue
        self.duration = duration
        
        let link = CADisplayLink(target: self, selector: #selector(update))
        link.add(to: .current, forMode: .commonModes)
    }


	@objc func update(link: CADisplayLink) {
		let dt = (link.timestamp - startTime) / executionInterval
		
		if dt >= 1.0 {
            self.label.text = toValue
			stopDisplayLink()
			return
		}
		
		let current = Int(Double(toValue - fromValue) * dt) + fromValue
        self.label.text = current
	}

```

# 参考
- [CADisplayLink - Core Animation | Apple Developer Documentation](https://developer.apple.com/documentation/quartzcore/cadisplaylink)
- [CADisplayLink and its applications – Dmitrii Ivanov – Medium](https://medium.com/@dmitryivanov_54099/cadisplaylink-and-its-applications-bfafb760d738)
【Cakephp2.x】 BoostCake3で Bootstrap4のPaginationを使いたい。


初投稿です。
誤字・脱字・間違い等あればご指摘お願いします。
拙いところがあるかもしれませんがよろしくお願いします。  
ㅤ
この記事はCakephp2.xで、BoostCake3を使ってなんとかBootstarp4の
ページネーション機能を使おうとしています。
ですのでまだBoostCakeを導入していない方は先に導入の方をお願いします。

ㅤ
参考: [CakePHP BoostCake の導入手順](https://qiita.com/BUN/items/d1e48d07d34de475bc77)


コードから先に載せます。



```test.php
<!-- ページネーション -->
<nav aria-label="Page navigation example">
	<ul class="pagination">
		<?php
		$this->Paginator->options(array('class' => 'page-link'));
		echo $this->Paginator->prev(__('Previous'), array('tag' => 'li class="page-item"'));
		echo $this->Paginator->numbers(array('currentTag' => 'a class="page-link"'));
		echo $this->Paginator->next(__('Next'), array('tag' => 'li class="page-item"'));
		?>
	</ul>
</nav>
```


`$this->Paginator->options(array('class' => 'page-link'))`は、
前へ・次へ・全てのページ番号に`page-link`クラスが付属されるようにするためのメソッドです。
opitionsで渡されたクラスを一つ一つの要素に付属してくれます。

`prev()` `numbers()` `next()`メソッドには、
タグに必要なクラスである`page-item`と`page-link`を付属させています。

表示結果こうなりました。

　　　　![スクリーンショット 2019-09-13 16.03.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488284/aab659c0-1f67-46f5-aeb3-8ca11cb3047d.png)

残念ながら、現在表示しているページ番号の背景が青く塗り潰される機能と、
ページ端に来た時に、前へ/次へボタンがグレーアウトする機能は実装できませんでした。
これらを実装するにはプラグインの中身を弄るか、PaginatorHelperを継承した独自ヘルパーでオーバーライドする必要があります。

お察しの通りこのコードはプラグインの機能を全く使っていないのですが、
BoostCakeプラグインを適用しないとこうなります。

　　　　![スクリーンショット 2019-09-13 16.13.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488284/94b6878a-38db-b958-7fda-8de9b15f4f1f.png)

`page-link`クラスが前へ/次へボタンに付属してくれないので変になっちゃうんです。
これだけのためにプラグインを使うのはなんだかなーと思いますが、
オーバーライド等をしないで、無理くり出来ないか考えた結果の末です。
もっと楽にできる方法があればコメントでご教授頂けるととても有り難いです。

誰かのお役に立てれば幸いです。
以上です。


参考：[bootstrap4でcakePHPのページングを実装したい](https://teratail.com/questions/35717)
マイクロマウスをはじめまチュー（３）

[「マイクロマウスをはじめまチュー（２）」](https://qiita.com/tkato635/items/db812ac1f7d3aaf451df#_reference-42c4a131219020d41467)の続きです。

#ハードウェア完成
組み立て作業は主に半田付けで、約6時間で完了しました。作業時間は個人差があります。
部品が入っている小袋に番号が印字されていて、取扱説明書を見ながら、その番号順に作業していけば出来あがるようになっていたので、非常に作業がやり易かったです。
![IMG_20190913_164051.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490861/23c60fa6-9929-7694-d3df-08be5c37b2c0.jpeg)

#動作確認
次に簡単な動作確認をしました。
開発環境は、CS+というルネサスエレクトロニクス製のマイコン共通の統合開発環境を使用します。
Windows 10のパソコンに開発環境をインストールし、前方の赤色LEDを4つ同時に点滅させるサンプルプログラムをビルドすると、ROMに書き込むためのmot形式のファイルが作成されました。
パソコンとマイクロマウスをUSBで接続し、ファイルを書き込みました。
見事に期待通りの動作をしました。ただ、LEDを点滅させただけなので、まだ安心できませんが。
![IMG_20190913_164538.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490861/68b2dde7-cf8d-ebb4-cf0c-2672633415bb.jpeg)

#試走用迷路到着
目標はマイクロマウス競技会に出場することなので、競技会で使用されているのと同じ規格の迷路セットを購入しました。
迷路の大きさは、本番は16X16区画で、試走用は4X4区画です。
購入した迷路は、迷路用ベースと壁、柱のセットです。値段は合計、約5万円です、結構なお値段です。
WEBサイトを色々見てみると、迷路を自作している人達がいましたが、私には真似できないと思い、
思い切って購入しました。届いた物を見て、値段に見合ったしっかりした作りだったので、買って良かったと思いました。
![IMG_20190913_165849.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490861/4a73838f-eb93-1430-e798-5142cf2225af.jpeg)

さあ、やっとQiitaらしく、ソフトウェアを作りまチュー。
【備忘録：Webサイト作成の基礎】HTML5のテンプレート

## はじめに
HTML, CSS, JSを使って静的なWebサイトを作る際、毎回始めに使っているHTMLのテンプレートがあるので、それをまとめてみた。

## HTMLのテンプレート
### ``<head>``

```html:index.html
<!DOCTYPE>
<html lang="ja">
<head>
  <!--基本-->
  <meta charset="utf-8">
  <meta name="description" content="サイトの説明文">
  <meta name="keyword" content="キーワード1, キーワード2, ...">
  <title>hoge hoge</title>
  <!--SEO対策のようなもの？-->
  <meta property="og:type" content="website">
  <meta property="og:title" content="タイトル">
  <meta property="og:description" content="サイトの説明文">
  <meta property="og:url" content="サイトURL">
  <meta property="og:image" content="サイトアイコン画像のパス指定">
  <!--アイコン画像-->
  <link rel="icon" type="shortcut icon" href="サイトアイコン画像のパス指定">
  <!--レスポンシブ対応-->
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
  <!--CSS-->
  <link href="CSSファイルのパス指定" rel="stylesheet" type="text/css">
</head>

<body>
</body>

</html>
```

jsやjQueryの読み込みは、``<body>``タグの最下部でおこなう。
そうすることで、ページの表示速度が多少早くなるらしい。

### ``<body>``

```html:index.html
<body>

  <header></header>

  <main></main>

  <footer></footer>
  
  <!--jQuery読み込み-->
  <script src="jQueryのCDN" type="text/javascript"></script>
  <!--JavaScript-->
  <script src="JSファイルのパス指定" type="text/javascript"></script>
</body>
```

ちなみに、``<main>``タグはinline要素として扱われることがあるので、CSSで``main{display: block}``と指定する癖をつけておくと面倒なことが起きにくい。

## CSSのテンプレート
[こちら](https://qiita.com/c6tower/items/809f485c324c6efd9ed7)を参考に

## 参考サイト
* https://qiita.com/RinoTsuka/items/3b4fb69d980cecddf512
* https://qiita.com/c6tower/items/809f485c324c6efd9ed7
【川原のGo言語&Elixir奮闘記】#1　Hello World

Hello World私だよ。

今日から、Go言語とElixirをマスターするために勉強していくよ。

週に1回ほどで投稿できたらと思うよ。

1日１善みたいな感じで。

今日は特に何もしないけど。

とりあえず作業環境はWindowsとLinuxということで。

####Goのバージョンは`1.12.9`だよ。

この記事は自分の備忘録としても活用するよ。

だから自分の得た知識をここに垂れ流すよ。

今日は思ったより寒かったね。

また来週。
torchvisionのEMNISTダウンロードできない件について

# はじめに
EMNIST（Extended MNIST）というデータセットがあり，それを用いた実験をPytorchで行おうとした際にEMNISTがダウンロードできないというエラーに陥った際の解決方法を紹介します．

# 環境
2つの環境で試し，どちらでもうまくいきました

- OS: MacOS　/　Linux
- python: 3.7.4 / 3.5.1
- torchvision: 0.4.0

# 原因
データセットへのリンクが切れており，Pytorchでインストールする際にエラーが起こっていました．（[こちら](https://github.com/pytorch/vision/issues/1296#issuecomment-529781521)にてその旨が書かれています）

# 実行したこと
`torchvision`のIssueにてEMNIST関連があるかみていたところ数日前に開かれた[issue](https://github.com/pytorch/vision/issues/1296)を見つけました．

単純にurl先が切れているとのことで，新たなリンク先に変更すれば良いとのことでした．

`Pypi`でインストールをしていたため，以下の方法で直接`torchvision.datasets.mnist`を書き換えることによって無事インストールが始まりました．

## 解決方法

単純に`torchvision`パッケージの`datasets/mnist.py`の1行をいじれば良いのですが，インストール方法によってこの場所が異なります．（また，直接パッケージをいじるためあまり良い方法ではないです...）

```
$ vim ~/.local/pyenv/versions/3.7.4/lib/python3.7/site-packages/torchvision/datasets/mnist.py
```
これによって開かれたファイルの230行目あたりに`EMINST`クラスがあります． `def __init__(...)` の
直前に`url`を指定している部分があるので，そこを

```
 url = 'http://www.itl.nist.gov/iaui/vip/cs_links/EMNIST/gzip.zip'
```
に書き換えるだけです．

# 最後に
何度かリンクが切れているらしく，上記のurlでは今後上手くいかない可能性があります．
その際は`torchvision`のIssueにて検索することをオススメします．
VueでのAPI

# 時代はSPA
SinglePageApplication
紙芝居をイメージ。
JavaScript上でページの中身を変えるので
URLもvue-routerなどを使えば変えられるので
そう。サーバーと通信して新たなhtmlやJSPのページを必要としない
1枚のページをころころ変えていくアプリケーション

軽い。便利。

# ページ遷移の方法
vue-routerを使います

```javascript:router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home/'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: qwq
    }
  ]
})
```

componentがページの内容で、これが何枚もある感じ。
1枚ごとにURLを設定して、まるで今までのサーバー通信のアプリケーションのようにふるまえる

# APIの呼び方
```javascript:main.js
//  Ajax通信ライブラリ
import axion from './axios'
```


```javascript:qwq.js
<script>
import ...
export default{
    data: function () {
        return {
            id: '',
            name: [],
            obj: null
        },
    methods: {
        suica: function () {
            console.log('スイカだよ')
        },
        melon: function () {
            console.log('メロンだよ')
        }
        mounted: function () {
            //  リクエストを生成
            const params = {
                'wawa' : this.id,
                'sasa' : this.name
            }
            //  APIたたく
            this.$api
                .post('http://google', JSON.stringfy(params), {
                    headers: {
                        'Content-Type' : 'application/json'
                    }
                })
                .then (response => {
                    this.obj = response.data.responseBody
                }).catch(error => {
                    console.errer(errer)
                }).then(() => {
                })
        }
    }
}
</script>
```

みたいなね
`mounted()`ってfunctionはページ読み込み後、最初に行われるやつ！
今回はそこでapi読んでます
だいたい英語の通りなので詳細な説明は割愛しますが、SpringでAPI呼び出すときと同じ感じですよね

#API側(Spring)

サーバー側でのControllerメソッドを、APIとして扱います。
ようはjavascript側からControllerを呼ぶってことです。

サーバーとの通信がページ遷移のためでなく、何か他のロジックを使うためって感じですね。

```java:ServerController.java
@RestController
@RequestMapping("/hello")
public class ServerController {

    //こういうserviceがあったとする
    @Autowired
    private ServerService service;

    @RequestMapping("/hi")
    public WebApiResponse<Dto> wawa(@RequestBody Wawa wawa) {
        WebApiResponse<Dto> response = new WebApiResponse<Dto>();
        //serviceでなにか処理をする
        Dto dto = service.sasa(wawa);
        response.setResponseBody(dto);
        return response;
    }
}

```

言わずもがなな感じですよね
`WebApiResponse`を使ってやり取りします
Modelもいい感じに自由に設定できるので楽ですね

# で？
例のごとく書きなぐりです。
次第にアップデートしていければ嬉しいです！！
Rubyスクレイピングで超絶楽をする（記事詳細ページ全件取得編）

以前、ある案件で、
検索結果一覧にある全詳細ページの特定のタグ内にある内容が必要になったのですが、
その詳細ページに辿り着く方法が2パターンありました。

①エリアなどの検索条件指定して検索かけるなどして、辿り着く方法
②1ページずつリンクを直打ちして開く方法

たしか、全部で300ページくらいあったので、
スクレイピングして取得する事にしました。

#どうやって全件取得するか？
検索条件を自動で入れて取ってくる方法を考えましたが、
複雑なことを考えるのは面倒だったので、シンプルに考えることにしました。
方法としては、
①本番と同じファイルを用意する。
②詳細ページがまるごと入っているディレクトリを見つける
③その詳細ページがあるディレクトリをスクレイピングして、ファイル名全件取得取得
④取得時にファイル名の前に本番のリンクをくっつける
⑤リンク先一覧として、CSVで吐き出す。

といった感じですかね。

#スクレイピングで使用したソースコード
書いてあることは、上に書いてある内容です。
単純に、特定のディレクトリ内（article/）のファイル名を全件取得して、
本番のリンクを前に繋げてあるだけです。
これによって、本番サイトの全詳細ページへのリンク先一覧が完成します。

```ruby
require 'open-uri'
require 'csv'

# スクレイピング先のURL
url = 'http://www.sample.jp/article/'
dir = []

filenames = Dir.open("article/",&:to_a) - [".", ".."]
filenames.each do |file|
  files = []
  files.push(url+file)
  dir.push(files)
end

# CSV出力と同時にターミナルにも内容を出力
test = CSV.open("article-urls.csv", "w") do |csv|
  dir.each do |row|
    csv << row
  end
end
puts test
```

#吐き出したCSVデータを元に、本番サイトをスクレイピングしよう。
上のソースコードで吐き出したリンク先一覧のCSVを元に、
別のrbファイルで本番サイトをスクレイピングします。

```ruby
require 'open-uri'
require 'nokogiri'
require 'kconv'
require 'csv'


line = []
ps = []
leadDt = []
articleLeadDescTitle = []
CSV.open("data-utf-8.csv", mode = "rt") do |csv|
  line = csv.readlines
end

line.each{ |link|
  for url in link do
    charset = nil
    html = open(url) do |f|
      charset = f.charset
      f.read
    end
   doc = Nokogiri::HTML.parse(html,nil,'utf-8')
   doc.xpath('//div[contains(@id,"mainColumn")]').each do |node|
     data = []
     articleTitle = node.css('h1').inner_text
     articleCatchCopy = node.css('h3').inner_text
     articleLeadTitle = node.css('p.leadComent').inner_text
     articleLeadText = node.css('p.lead').inner_text
      if !node.search('.//dl[contains(@class,"article01")]').nil?
          article01_inner = node.xpath('.//dl[contains(@class,"article01")]').inner_text
      end
      if !node.search('.//dl[contains(@class,"article02")]').nil?
          article02_inner = node.xpath('.//dl[contains(@class,"article02")]').inner_text
      end
      if !node.search('.//dl[contains(@class,"article03")]').nil?
          article03_inner = node.xpath('.//dl[contains(@class,"article03")]').inner_text
      end
     data.push(url)
     data.push(articleTitle.tosjis)
     data.push(articleCatchCopy.tosjis)
     data.push(articleLeadTitle.tosjis)
     data.push(articleLeadText.tosjis)
     data.push(article01_inner.tosjis)
     data.push(article02_inner.tosjis)
     data.push(article03_inner.tosjis)
     ps.push(data)
   end
  end
}

# CSV出力と同時にターミナルにも内容を出力
CSV.open("article-data.csv", "w") do |csv|
  ps.each do |row|
    csv << row
  end
end
```

ほとんどどこかのコピペだと思いますが、
大体こんな感じで全リンク先の特定のタグにある内容を取得出来ます。

スクレイピング時、リンク先一覧の中に本番のページが存在しないリンクが紛れている場合があります。
最初のスクレイピングはあくまで、ローカルにある全ファイル名に本番のリンクをくっつけただけなので、
吐き出した後、サクッとリンク先のページが存在しているかだけチェックしたほうが良いかもしれません。
たしか、存在しないとこは空の行が出来た気がします。

これがCSV化出来たら、重複した記事内容が無いか簡単に調べることも出来そうですね。
【2019年9月版】Cloud FunctionsでGoをデプロイをする際のエラーメッセージが「go: finding ・・・」だった時の対処方法

# Cloud Functions の Go インスタンスでデプロイエラーが発生しましたよ、というお話。

Golangで実装した functions をデプロイしようとして、以下のようなエラーが発生しました。

```
$ gcloud beta functions deploy xxxxxxxxx \
    --project xxxxxxxxxx \
    --entry-point xxxxxxxxx \
    --runtime go111 \
    --trigger-http \
    --memory 128MB
Deploying function (may take a while - up to 2 minutes)...failed.
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: go: finding ....
...
```

当然、以下の記事を参考にビルドのチェックいたしましたが。。。

- [Cloud FunctionsでGoをデプロイをする際のエラーメッセージが「go: finding ・・・」だった時の対処方法](https://qiita.com/shuichiro/items/68d25691fea580eda754)

上記のエラーが止まらないのです。

新規のfunctionsはデプロイを中止し、ソースコードをいったんリバートしまして、既に**デプロイ済みのfunctionsを再度、デプロイしてみた**ところ・・・

またもや**上記のエラーが発生したのです。**

これは困ってしまいました。ちょっと前に上げたfunctionsが、今は上がらなくなっているのです。
しかし、今上がっているfunctionsは問題なく動いています。。。

これは何だろう・・・？と公式ドキュメントを開いてみましたら・・・

[Cloud Functions | The Go Runtime](https://cloud.google.com/functions/docs/concepts/go-runtime)

![The Go Runtime     Cloud Functions Documentation     Google Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335150/6a52e91f-76f9-0585-e460-417d2ba2da2d.png)

Go 1.11.6 ...?

**Go 1.11.6 ...?**

いやいや、この前上げたときは**1.11.5だったでしょうが！！！**
(いくら吠えても仕方ないので今回はちゃんとスクショ貼っておきました。)

・・・というわけで、 1.11.5 から 1.11.6 へのマイグレーションの手順です。

## Go 1.11.5 から 1.11.6 への切り替え

まずは、goの環境を1.11.5から1.11.6に乗せ換えます。こういう時には、[goenv](https://github.com/syndbg/goenv) 助かりますね。

以下のコマンドでサクッと対応完了です。

```
$ goenv install 1.11.6
...
$ goenv global 1.11.6
...
```

環境によっては `GOPATH` や `GOROOT` の変更が必要かと思います。
goenv がない場合は、頑張ってください。。。

## 依存モジュール情報のアップデート

続いて functionsのプロジェクトから `go.mod` と `go.sum` を削除し、goモジュールの再作成をします。

```
$ rm go.mod go.sum

$ go mod init
```

## ビルド確認

以下のコマンドでビルドです。

```
$ go build
```
go のビルドは非常に簡単で助かります。早いし。

## デプロイの再実行

ビルドをすると `go.mod`が更新され、`go.sum`が再生成されます。~~(go.sum、めっちゃ変わってるやん・・・)~~
これでデプロイを行ってみましょう！

```
$ gcloud beta functions deploy xxxxxxxxx \
    --project xxxxxxxxxx \
    --entry-point xxxxxxxxx \
    --runtime go111 \
    --trigger-http \
    --memory 128MB
Deploying function (may take a while - up to 2 minutes)...
...
```

ここでエンドポイントの情報などが表示されれば成功です！

## 最後に

Goのランタイム、~~しれっと~~バージョンアップして文句はないですが、ビルド失敗したときのエラーメッセージが非常に分かりにくいですね。(というか、実際にはエラーメッセージは解決が糸口にもなってない。。。)

手詰まりになったら基本に立ち返って公式サイトを見る、というのも一つの手です。

いろいろ言いたいことはありますが以上です。。。
(・・・こういうのって未必の故意っていうんじゃないのぉ？)
git commit前にaddしたファイルのみrubocopで検査する

# pre-commitを使ってRubocopで検査すると遅い

もともとの`.git/hooks/pre-commit`はこうなっていた。

```shell
#!/bin/sh

bundle exec rubocop -P
if [ "$?" -ne 0 ]; then
	exit 1
fi
```

これによって、コミット前にRubocopを強制実行してルールに外れている場合はコミットさせないようにしているのだけれど、如何せん遅い😡

## 遅い原因

かれこれ6年も運営しているRailsプロジェクトで行うと数分間応答がなくなってしまう。検査対象が全てのファイルになっているからだ👎

## 課題

gitで変更があったファイルだけに対してRubocopを実行すればよい👍

## 対策

### 変更があったファイルだけを取り出す

gitで変更のあったファイルだけを抽出するには、`git diff`を使う。

```shell
git diff --cached --name-only --diff-filter=AMRC
```

#### オプションの説明
`--cached`は、addされたファイルだけを対象にする。
`--name-only`は、変更のあったファイル名だけを取り出す。
`--diff-filter=AMRC`は、Added, Modified, Renamed, Copiedなファイルを対象とする。 

### Rubyのファイルだけを取り出す

現時点だとRuby以外の変更ファイルも抽出されるので、さらにgrepで絞り込む

```shell
git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$'
```

拡張子が`.rb`で終わっているファイルだけに絞り込んだ。

### Rubocopを実行する

絞り込まれた結果に対してRubocopを行う。渡す方法には`xargs`を使う。

```shell
git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$' | xargs bundle exec rubocop -P
```

これで、変更のあったRubyファイルだけを対象にRubocopを実行することに成功した🎉

ということで、`.git/hooks/pre-commit`を修正した。

```shell
#!/bin/sh

git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$' | xargs bundle exec rubocop -P
if [ "$?" -ne 0 ]; then
	exit 1
fi
```

## オマケ

Auto Collectもこれを使うとめっちゃ速い😎

```shell
git diff --cached --name-only --diff-filter=AMRC | grep '\.rb\>$' | xargs bundle exec rubocop -a
```

しかしpre-commitには含めたくないし、いい感じのコマンドにしたいけれど、いいコマンド名を思いつかない…🤔
Python 3 エンジニア認定データ分析試験（β）を合格した感想

# Python 3 エンジニア認定データ分析試験って？
一般社団法人Pythonエンジニア育成推進協会が実施している民間試験です。
9/30まではベータ試験扱いですが、合格者は本認定されるそうです。

以下は公式からの転記です。
- 試験名称：Python 3 エンジニア認定データ分析試験
- 概要：Pythonを使ったデータ分析の基礎や方法を問う試験
- 受験料金：1万円（外税）　学割5千円（外税）
- 問題数：40問（すべて選択問題）
- 合格ライン：正答率70%
- 試験センター：全国のオデッセイコミュニケーションズCBTテストセンター
- 主教材：「Pythonによるあたらしいデータ分析の教科書」（翔泳社）

# 勉強法
実質の勉強時間は8時間程でした。
主教材5章の応用が出題範囲でなかったため、コードを動かすよりも情報を頭に叩き込むというイメージで勉強しました。
実際には主教材を2周読破し、一部付属データのJupyterを動かしました。

# 受けてみた感想
制限時間は60分でした。8割程度の正解で、無事合格しました。
問題を解きながら、ただPythonを使ってデータ分析をするエンジニアではなく、分析目的や結果を周囲へ説明（見える化）できるステキなPythonicになろう！というメッセージを感じました。

エンジニア認定基礎資格と違うと感じたところは、以下の2つです。
・数学の知識（出題範囲に書いてある通り）
・機械学習関連の知識（本だけ100%は網羅できない印象を受けました）

JDLAのG検定のPython版っぽいなーという印象です。
回答終了後にベータ試験なので問題におかしいところがないか指摘するアンケートがありました。

# これから受講される方へ
JDLA G検定を合格している人であれば機械学習関連の知識は問題なく解けると思います。
日頃機械学習に関わらずにPythonを使っている方は主教材の1章と3章を理解しないと落ちる可能性がありそうです。
Pythonをまったく使ったことがない方は、エンジニア認定基礎試験をとってからの受験をおすすめします。。。

# 最後に
教材が実際の業務フローに沿って説明が進むのでかなり勉強になりました。
もっとこうすれば楽にできるんだと思うメソッドも見つけられ、個人的にですが満足しています。

ステキなPythonistaを目指して頑張りましょう！
PowershellでActiveDirectoryユーザーのpwdLastSetを人間の読める値へ変更する

## 変更前

`132128346183950472`だといつか分からない

```
PS C:\Users\administrator.CHASE> Get-ADUser -Identity test10 -Property * | Select-Object -Property SamAccountName, pwdLastSet

SamAccountName         pwdLastSet
--------------         ----------
test10         132128346183950472
```

## 変更後

`datetime`型へ変更している
詳しくはよくわかないです・・

```
PS C:\Users\administrator.CHASE> Get-ADUser -Identity test10 -Property * | Select-Object -Property SamAccountName, @{Name="pwdLastSet";Expression={[datetime]::FromFileTime($_."pwdLastSet")}}

SamAccountName pwdLastSet
-------------- ----------
test10         2019/09/13 16:50:18


PS C:\Users\administrator.CHASE>
```

## ちなみに
`Get-ADUser`コマンドレットには`PasswordLastSet`というプロパティがあるので、これを使えばOK。直近のパスワード変更日時のことですね。

```
PS C:\Users\administrator.CHASE> Get-ADUser -Identity test10 -Property * | Select-Object -Property SamAccountName, @{Nam
e="pwdLastSet";Expression={[datetime]::FromFileTime($_."pwdLastSet")}},PasswordLastSet

SamAccountName pwdLastSet          PasswordLastSet
-------------- ----------          ---------------
test10         2019/09/13 16:50:18 2019/09/13 16:50:18
```
プロパティの列挙

#### 列挙

| 手段                               | 自文可 | 自文不 | 自シ可 | 自シ不 | 親文可 | 親文不 | 親シ可 | 親シ不 |
|----------------------------------|-----|-----|-----|-----|-----|-----|-----|-----|
| for..in                          | ●   | ×   | ×   | ×   | ●   | ×   | ×   | ×   |
| Object.keys                      | ●   | ×   | ×   | ×   | ×   | ×   | ×   | ×   |
| Object.getOwnPropertyNames       | ●   | ●   | ×   | ×   | ×   | ×   | ×   | ×   |
| Object.getOwnPropertyDescriptors | ●   | ●   | ●   | ●   | ×   | ×   | ×   | ×   |
| Reflect.ownKeys()                | ●   | ●   | ●   | ●   | ×   | ×   | ×   | ×   |

#### チェック

| 手段                               | 自文可 | 自文不 | 自シ可 | 自シ不 | 親文可 | 親文不 | 親シ可 | 親シ不 |
|----------------------------------|-----|-----|-----|-----|-----|-----|-----|-----|
| in                               | ●   | ●   | ●   | ●   | ●   | ●   | ●   | ●   |
| obj.hasOwnProperty               | ●   | ●   | ●   | ●   | ×   | ×   | ×   | ×   |
| obj.propertyIsEnumerable         | ●   | ×   | ●   | ×   | ×   | ×   | ×   | ×   |
composer install のエラー　as the wrong version (~~~) installed.  の解決

## まとめ
- composer installは.lockがあるときはそっちを参照する
- php extensionはphpに勝手に入っているライブラリで、phpのバージョンアップで更新できる

---

環境
php: 7.1.19

---

composer install すると

```
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run update to update them.
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - The requested PHP extension ext-simplexml ^7.2 has the wrong version (7.1.19) installed. Install or enable PHP's simplexml extension.
  Problem 2
    - The requested PHP extension ext-json ^1.6 has the wrong version (1.5.0) installed. Install or enable PHP's json extension.
  Problem 3
    - The requested PHP extension ext-zip ^1.15 has the wrong version (1.13.5) installed. Install or enable PHP's zip extension.

```
こんなエラーが出てくる。

## composer installとは
そもそもcomposer installは何をしているのかを調べた。

composer install は[公式ドキュメント](https://getcomposer.org/doc/03-cli.md#install-i)をみて解釈すると

composer.jsonを参照し依存関係を解決しながらvendorディレクトリにパッケージを追加するコマンド。
composer.lockがある場合はそちらを使用する。

つまりlockファイルがあるときはそっちを参照してしまう。

## 一旦の対処法

composer.lockを覗くと

```
    "platform": {
        "php": "^7.1.3",
        "ext-simplexml": "^7.2",
        "ext-json": "^1.6",
        "ext-zip": "^1.15"
    },
```

と書かれている。下三つの記述をエラーメッセージのversionまで下げたらcomposer installできた。
しかしext-simplexml等は今からvendorファイルにインストールするはずなのに、なんでversionが古いと怒られるのか？

グローバルでインストールされているのかと思い、調査した。

### php extentionとは

php extentionとは、phpそれぞれのversionでインストールされているライブラリのこと。勝手にインストールされているものもあればされていないものもある。

``` 
php -i | grep json

json version => 1.5.0
```
確かに自分のphpの設定でext-jsonがversion1.5.0であることが確認できた。
このversionは個別にアップデートするものではなく、phpのバージョンアップに追随して更新されるみたい。

なのでphpのアップデートをしなければならないことがわかった。

## php 7.2.22へ
アップデートしないといけないことがわかったので、phpを7.2.22へ、phpbrew使いました。
インストールに16分かかったんだが、何これ

まあ無事インストールできたのでもっかいcomposer install
...できた、、、、疲れた


### phpbrew 使うとextensionのversion簡単に確認できる
余談ですが、phpbrew使うとコマンドで簡単にextensionのversionを確認することができました。


```
$phpbrew extension

Loaded extensions:
 [*] bcmath       7.2.22      
 [*] bz2          7.2.22      
 [*] calendar     7.2.22      
 [*] ctype        7.2.22      
 [*] curl         7.2.22      
 [*] date         7.2.22      
 [*] dom          20031129    
 [*] fileinfo     1.0.5       
 [*] filter       7.2.22      
 [*] gd           7.2.22      
 [*] hash         1.0         
 [*] iconv        7.2.22      
 [*] json         1.6.0     
```


こんな感じ、extensionの導入も phpbrewコマンド経由で可能、かなり便利だと感じた。

以上
Scout APMを利用してHerokuのR14/R15エラーを解析

## はじめに
こちらのポストは[Scout APMを利用してHerokuのH12エラーを解析](https://qiita.com/ScoutAPM/items/498ce60c4207b73a1056)の続きになってますので、是非そちらも参考にしてください

## R14とR15の違いについて
- **R14 - Memory quota exceeded**

> A dyno requires memory in excess of its quota. If this error occurs, the dyno will page to swap space to continue running, which may cause degraded process performance. The R14 error is calculated by total memory swap, rss and cache.

メモリの使用量がdynoに割り当てられた分を超えた場合に起こります。このエラーが起こった際には、dynoはメモリスワップすることでアプリケーションを動かします。これにより、アプリケーションのパフォーマンスが劇的に遅くなることがあります。

- **R15 - Memory quota vastly exceeded**

> A dyno requires vastly more memory than its quota and is consuming excessive swap space. If this error occurs, the dyno will be killed by the platform. The R15 error is calculated by total memory swap and rss; cache is not included.

メモリの使用量がdynoに割り当てられた分を超え、**スワップスペースもかなり使用している**際に起こります。(具体的には、割り当てられたメインメモリの二倍の量...free, hobby, standard 1xであれば、1GB)
このエラーがおきた際には、herokuによって、プロセスがkillされることになります。

まとめると、どちらもアプリケーションが完全に止められてしまうか、遅くなるかという違いになります。

## Scout APM活用方法
上記エラーが起こった際には、次のようなログが出力されます
![image](https://cdn.buttercms.com/fu9UPHmTDy3Ik3LZFQHA)

このエラーは頻繁に起こる例ではありますが、APMを使わずしてデバックするのはかなり困難です。メモリ問題の解決については、[Scout APM](https://scoutapm.com/?utm_source=qiita&utm_medium=blog&utm_campaign=heroku_r14)が競合他者と比較しても、かなり優っている点になります。

まず始めに、このようなメモリに関する異常はScoutのOverviewページの線グラフにおいて、スパイクを発見することが出来ます。下のような例では、メモリの使用量が、ある時を境にして急激に上昇したことが確認出来ます。さらに下図の左下にも確認出来る、**Memory Bloat Insights**をチェックすると、`ArticlesController#index` が表示されており、そこで精査すべき問題を表示しています。

![image](https://cdn.buttercms.com/ffrqMVYHTUiVIgTDg3A8)

このスパイクが起きた時間のトレースを確認すると、どこのレイヤーで多くのメモリを使用していたかは一目瞭然です。下図の例では**View**のレイヤーになります。さらに、バックトレースから、ペジネーションを行なわず、全レコードを表示していたことが原因だということを特定することができます。


![image](https://cdn.buttercms.com/TcUYaAXSSHC4Yub8Z8KJ)
※ScoutではGithub integrationを提供しておりますので、Scout上で、実際に誰がいつ書いたコードが問題の原因になっているのか確認することができます!

## 最後に
Scoutを活用してメモリの問題を解決したいという場合には、こちらの[リンク](https://book.scoutapm.com/memory-bloat.html)を参考にしていただけると、更に詳細情報が確認できます。

[14日間無料トライアル](https://scoutapm.com/?utm_source=qiita&utm_medium=blog&utm_campaign=heroku_r14)を実施中ですので、この機会に是非ご利用ください！
error pulling image configuration, docker(71) error(35) 

機材：macOS 10.12.x, 16GB memory, docker for mac

```shell-session:macOS
$ docker run -p 8080:8080 -v /Users/administrator/openjij/work:/openjij/work -it kaizenjapan/openjij-ch1-ubuntu /bin/bash 
docker: error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/31/31f8ffbbbf06db1691bd5386f547f553151cbfdd1cfff171e5dcec3eeed4d546/data?verify=1568363392-Y3T1ULnIeo5xF1fchY9TssmnPvY%3D: Service Unavailable.
See 'docker run --help'.
```
# 参考資料(reference)
docker(28) Openjij チュートリアルをdockerで
https://qiita.com/kaizen_nagoya/items/09a52b25d54091c8db6f

Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
# 文書履歴(document history)
ver. 0.01 初稿 20190913
ver. 0.02 参考資料追記 20190914
ver. 0.03 add URL　20240508
### 最後までおよみいただきありがとう4ざいました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Django + SendGrid でメールを送信

## 背景
Djangoサイトでメールを送ろうとしていたのですが、Gmailではなぜかうまく動かなかったので、その代わりにSendGridでメールを送ってみようと思いました。

## 前提条件
* Djangoでプロジェクトを作成済み
* 使用中のDNSホストでCNAMEなどの設定の仕方が分かる

## 手順
### SendGridアカウントの登録
1. SendGridで無料のアカウントを作成する<br>日本のSendGridアカウントを作成すると、審査に２日ぐらいかかる可能性あり。アメリカ版ならすぐに作成可能。ちなみに、この時に入力するメールアドレスはアカウント作成用のものなのでなんでもいい）

2. 認証メールを開く

3. ドメインの認証を行う。<br>英語版ではSendgridのサイトの左側のナビバーにある"Settings"タブを開くとある"Sender Authentication"のページからできます。私はGoogle DomainsをDNSホストとして使っていたのですが、これがプルダウンメニューにあるGoogle Cloudにあたるのか分からなかったので、"Other Hosts"を選んで"Google Domains"と入力しました。Djangoから送信する送信元アドレスに"…@sendgrid.net"でなく、独自のドメインを使いたい場合はYesにチェック。

4. 次の画面では自分のドメイン（"hogehoge.com"）などを入力

5. 最後に出てくるDNS関連情報を自分が使っているDNSホストのページにコピー&ペースト。<br>ここで注意するのが、"DNS NAME"をペーストするときに自分のドメイン（"hogehoge.com"）の部分を削除しておく必要があることです。DNSホストにCNAMEを登録したら数分待ち、Verifyボタンを押して認証しましょう。
6. 5が終わったらAPI Keyを入手しましょう。<br>先ほどの"Settings"タブから"API Keys"を選び、"Create API Keys"でAPI Key作成します。"Restricted Access"を選んで、"Mail Send"の権限を与えます。

### Django側の設定
Sendgrid側の設定が終わったら、次はDjangoの設定をします。今回はsmtpではなく、sendgridのWEB APIを通してメールを送信します。

1. virtualenvに入って、pipでdjango-sendgrid-v5をインストールします。<br>`pip install django-sendgrid-v5`

2. Environment variableにAPI keyを追加。<br>`export SENDGRID_API_KEY="先ほど作ったAPI key"`

3. settings.pyに以下を追加します。<br>`import os
EMAIL_BACKEND = "sendgrid_backend.SendgridBackend"
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
SENDGRID_SANDBOX_MODE_IN_DEBUG= False #DEBUG modeがTrueの場合にサンドボックスモードを起動/停止する設定。
DEFAULT_FROM_EMAIL = 'admin@hogehoge.com'

サンドボックスモードはデフォルトでTrueになっているため、明示的にこれをFalseに設定しないと実際のメールは送られません。
ではテストしてみましょう。

### メールの送信

Djangoのシェルからメールを送ってみます。

`python3 manage.py shell
>>>  from django.core.mail import send_mail
>>>  send_mail('testing', 'my message', 'admin@hogehoge.com', ['宛先@example.com'], fail_silently=False)
1`

これで宛先にメールが届くはずです。
ちなみに私の場合、outlook.comのメール宛に送信したメールはブロックされていました。
さらにGmailの方はSpamフォルダに入っていました。

初めての記事なので、いたらないところもあると思いますが、自分のための備忘録として今回は書かせてもらいました。
Powershellスクリプトで複数引数が必要な外部コマンド実行

powershellでスクリプト書いている際に引数が必要な外部コマンド実行でつまずいたのでメモ書きに

### 環境
windows 10


### 現象
```powershell
& コマンド "-引数 値 -引数2 値"
```
としていたが、この値部分に()が含まれており、`)の使い方が誤っています。`というエラーが発生していた

### 解決策
```powershell
& コマンド -引数 "値" -引数2 "値"
```
に変更。
QualityForwardのAPIを使って更新履歴を取る

[QualityForward](http://bit.ly/2KgiwCh)はテスト管理をクラウドで提供しています。そして、多くのクラウドサービスと同様にAPIを提供しています。現在、下記のデータを取得または新規作成、更新、削除できます。

- プロジェクト
- テストケース
- テストサイクル
- テストフェーズ
- テスト結果
- テストスイート
- テストスイートバージョン
- ユーザ

現在、非公式ながらNode.js用ライブラリ `qualityforward-node` を作っていますが、その使い方の一例として、テストスイートの更新履歴を管理してみます。

## コード例

コードは下記のようになります。テストスイートを取得し、それをCSV化しています。

```js
import * as dotenv from 'dotenv';
const { parse } = require('json2csv');

dotenv.config();
import { QualityForward} from 'qualityforward-node';

(async () => {
  const client = new QualityForward(process.env.API_KEY);
  const testSuites = await client.getTestSuites();
  const csv = parse(testSuites.map(s => s.toJSON()), {});
  console.log(csv);
})();
```

後はこれを定期的に実行するだけです。出力先は適当なGitリポジトリとしています。

```
$ npx ts-node test.ts > /home/user/repo/res.csv
```

cronなどで定期実行していれば、自動的に更新されるでしょう。データ取得時には自動でコミットも追加しておく方が良いでしょう。

## 差分を見る

CSVの差分を見る場合は、次のように行うと分かりやすいです。

```
$ git diff --word-diff-regex="[^,]+" res.csv 
```

そうすると、異なるセルだけが色分けされて表示されます（via [csvを見やすくgit diff (word-diff-regexオプション) - Qiita](https://qiita.com/sanemat/items/04a419e9ca9394fb69eb)）。もちろんCSV用の差分ビューワーを使うのも良いでしょう。

<img width="1032" alt="Screenshot_ 2019-09-13 16.24.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/787fdff3-e0ce-e792-49da-ca045e4616a7.png">


## まとめ

データが誰かによって変更された場合にも、その差分を取っておけば安心です。差分によって設定を戻すこともできますし、いつから変わったのか捕捉も簡単です。APIを使って、適切な運用が行えるようになるでしょう。

[QualityForward](http://bit.ly/2KgiwCh)
【メモ】JQueryを使わず独自UIでSELECTタグを制御する

デザイン的にSELECTタグだとどうしようもない時があるよねえ・・・。

```haml:sample.haml
  %ul#js-langList
    %li{class: ''} EN
    %li{class: ''} JA
    %li{class: ''} ZH
    %li{class: ''} FR
  %select#js-langSelector
    %option{value: 'en'} EN
    %option{value: 'ja'} JA
    %option{value: 'zh'} ZH
    %option{value: 'fr'} FR
```

```javascript:sample.js
  document.getElementById('js-langList').addEventListener('click', function(e){
    document.getElementById('js-langSelector').options[Array.prototype.indexOf.call(e.target.parentNode.querySelectorAll("li"), e.target)].selected = true;
  }, false);
```
js-langSelectorはdisplay:noneして、あとは好きにスタイルを当てて下さいまし。

## 追記
UIの選択要素にCLASS(active)を付与する版

```javascript:sample2.js
  document.getElementById('js-langList').addEventListener('click', function(e){
    var lists =  e.target.parentNode.children;
    for(var i = 0; i < lists.length; i++){
      lists[i].classList.remove('active');
    }
    e.target.classList.add('active');
    document.getElementById('js-langSelector').options[Array.prototype.indexOf.call(e.target.parentNode.querySelectorAll("li"), e.target)].selected = true;
  }, false);

```
OpenEntityManagerInViewInterceptor Spring MVC interceptorの役目

# OpenEntityManagerInViewInterceptorの役目
1. HTTPリクエストが処理始める時、EntityManagerインスタンスを作り、そしてスレッドにつける
2. HTTPリクエストが処理終わる時、前作ったEntityManagerインスタンスを閉める

# どうして必要なの？
例えばEntity Aがあり、プロパティ'type'がEntity Bに設定した。Entity AをEntityManagerが作り、このEntityManagerが遅延読み込みに設定した。このEntityManagerインスタンスはEntity Aを読み込むトランザクションが終わった時、たぶん閉また。あとでEntity Aのプロパティ'type'がViewレイヤにアクセスされる。Entity Bはプロキシインスタンス、ほんのインスタンスが読み込むのはEntity Aを読み込むEntityManagerインスタンスが必要だ。でもViewレイヤで扱うときこのEntityManagerインスタンスもうなくなった。最後エラーになってしまった。

もしOpenEntityManagerInViewInterceptorが設定したら、このEntityManagerインスタンスがViewレイヤにアクセスできる。

# どうやってSpring Bootに設定する？
OpenEntityManagerInViewInterceptorは既定使用する。あるいはプロパティファイル'application.properties'に下のコードを入れ、使用することを宣言する。

```
spring.jpa.open-in-view=true
```
ReactではCSS疑似要素が使えません。

タイトルの通り、Reactで吹き出しを実装する過程で分かったこと

それは・・・


Reactでは、CSSの::beforeや::afterなどの疑似要素がそのまま使えません。

そのため、 疑似要素(Pseudo-elements)が含まれた外部のCSSデザインを使う場合、事前によく検討した方がよさそうです。

＜span＞等で別に要素を書きだし、直前・直後にいれるなり、StateやReduxで操作するなどで対応することは可能です。