OmniAICreator/Qiita-1.07M huggingface dataset:
Reactコンポーネントの動的スタイル更新

# React.jsでレスポンシブデザインを
React.jsにはコンポーネントという概念が存在します。
複数の仮想DOMをコンポーネントで管理することにより、
オブジェクト指向ライクな設計が可能となります。

しかし、ここで問題があって...
仮想DOMを扱うReact.jsではとてもCSSを扱いづらい。
動的にスタイルを変更しようとすればどうしようとよく迷う。

というわけでReactコンポーネントの動的スタイル更新方法を
共有したいと思います。

## State更新でコンポーネントを再描画

まず、仮想DOMの描画処理をMain.jsに記述します。

```react:Main.js
import React,  { Component } from 'react';
import ReactDOM from 'react-dom';
import {ContentBody} from './ContentBody';

class Main extends Component {
    render() {
        return (
            <ContentBody />
        );
    }
}

ReactDOM.render (
    <Main />,
    document.getElementById("root")
);

export default Main;
```

次に、Windowのサイズが変更された場合にスタイルを動的に変更するプログラムを書いていきます。

```react:ContentBody.js

import React, { Component } from 'react';

let initWindowSize = {};
let initButtonStyles = {};

export class ContentBody extends Component {
    constructor(props) {
        super(props);
        //Stateにはスタイル用にオブジェクトを保持しておく
        this.state = {
            stylesSendButton: {}
        }
    }
    getInitWindowSize(){
        let width = window.innerWidth
        let height = window.innerHeight; 
        initWindowSize = {
            width: width,
            height: height
        }
        initButtonStyles = {
            background: "#f2f2f3",
            border: "none",
            position: "absolute",
            float: "left",
            left: width*0.8,
            bottom: height*0.01,
            outline: 0,
            display: "block",
            width: width*0.225+"px",
            height: width*0.225+"px"
        }
        //特定のスタイルの更新をStateの更新によって行う
        this.setState({stylesSendButton: initButtonSize});
    }
    getWindowSize(){
        let width = window.innerWidth
        let height = window.innerHeight;
        let window_size = {
            width: width,
            height: height
        }
        return window_size;
    }
    ChangeSizeStyles(windowSize){
        let stylesSendButtonChange = {
            background: "#f2f2f3",
            border: "none",
            position: "absolute",
            float: "left",
            left: windowSize.width*0.8,
            bottom: windowSize.height*0.01,
            outline: 0,
            display: "block",
            width: windowSize.width*0.225+"px",
            height: windowSize.width*0.225+"px"
        }
        this.setState({stylesSendButton: stylesSendButtonChange});
    }
    //windowサイズの変更検知のイベントハンドラを設定
    componentWillMount () {
        window.addEventListener('load', () =>{
            this.getInitWindowSize();
        });
        window.addEventListener('resize', () => {
            let window_csize = this.getWindowSize();
            this.ChangeSizeStyles(window_csize);
        });
    }
    render() {
        return (
            <div>
　　　　　　　     //StyleをStateで管理できるように設定
                <button id="button" style={this.state.stylesSendButton} />
            </div>
        );
    }
}

```

以上です。
こっちのほうがスタイルの変更が容易だよとか、
その他、指摘などあればコメントよろしくお願いします。
CookieやWebStorageでのnullの振る舞い

うっかり間違えたけど、その間違えが後々響くことがあるので備忘録として記載。

# 起きた問題
特定の変数がnullであった際に後続の処理を行わない実装をしていたが、意図せず判定に引っかからず処理が実行されてしまうパターンが発生していた。

```javascript
function hoge(value) {
  // value には値がはいるかnullかのどちらか
  if (!value) {
    return false;
  }
  /* 後続の処理 */
}
```
# 原因
valueの値は、別のAPIで取得した戻り値（何かしらの値 or null）をCookie、LocalStorageへ保存している。
当たり前なのだが、、APIで取得した値がnullで、それをCookieやLocalStorageへ保存した後に取得できる値はobjectではなくstringとなってしまう。

```javascript
let value_1 = null;
console.log(typeof value_1); // object
if (!value_1) {
  console.log('ここの条件に入る');
}
// 「ここの条件に入る」が出力される

let value_2 = 'null'; // CookieやlocalStorageから取得すると文字列として扱われる
console.log(typeof value_2); // string
if (!value_2) {
  console.log('ここの条件に入る');
}
// 「ここの条件に入る」が出力されない（文字列なので上記の判定分だと引っかからない）
```

nullはnullだと思いこみから発生した問題。
TypeScriptにすれば恩恵がうけれたかな、と思いつつも、今後同じことを繰り返さないよう気をつける。
Mirage soloとUnityでVR開発

#はじめに

3日前にVRゴーグル初体験した初心者です。
今回は既存の情報でうまくいってない人向けに作りました。
アプリの中身の作り方には一切触れていませんので、ビルドが出来ない等で困っている方の参考になればと思います。

#環境
Windows10 Home 64bit
Unity 2018.2.11f1 Personal
Android OS 8.0 (Oreo)

#必要なもの
・Mirage Solo
https://www.lenovo.com/jp/ja/vr-smartdevices/augmented-reality/lenovo-mirage-solo/c/mirage-solo
・Unity
https://unity3d.com/jp/get-unity/download/archive?_ga=2.105431431.540089069.1529304098-1012543397.1513824749
・JDK
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
・Android Studio
https://developer.android.com/studio/?hl=ja
・Google VR SDK
https://github.com/googlevr/gvr-unity-sdk/releases
Unity,JDK,Android SDK

Mirage Soloは用意してください。
Unity, JDK, Android Studioはインストールを完了させておいてください。
Google VR SDKはダウンロードしておいてください。

#１、Mirage SoloのUSBデバッグを有効化
設定 > 全ての設定 > システム > 端末情報 > ビルド番号
ビルド番号を7回押して開発者モードをONにしてください。

設定 > 全ての設定 > デバッグ > USBデバッグ

USBデバッグをONにしてください。

#２、Android SDKのインストール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/7990f6da-ddd4-b81a-abb1-c35b64327e30.png)

Configure > SDK Manager

![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/dfa5dddf-0051-0daa-20de-118c062e395e.png)

Android 8.0 (Oreo)にチェックを付けてApplyをクリックしてください。

#３、Unityの設定

ダウンロードしてある、GoogleVRForUnity_1.170.0.unitypackageをimportしてください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/c4b00b83-e657-f5bd-89d2-24bf452ac779.png)

`Edit > Preferences > External Tools`

AndroidのSDK,JDKに記入
SDK: `C:/Users/[user name]/AppData/Local/Android/Sdk`
JDK: `C:\Program Files\Java\jdk1.8.0_191`

[user name]はユーザー名を入れてください

![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/c47f7420-394a-2c1c-57ce-7d2a4039ec16.png)


`File > Build Setting > Player Settings`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/e3c2806c-512e-a543-6e03-060383076e02.png)

######Other Setting
Package Nameを[com.company.package]のように適当な名前に書き換えてください。
Minimum API Level, Target API LevelをAndroid 8.0 'Oreo' (API level 26)に変更してください。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/b2203727-c875-8116-8129-71d7fd45cb2a.png)

######XR Settings

Virtual Reality Supportedにチェックを入れてください。
Virtual Reality SDKsにDaydreamを追加してください。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/287072/6b7255a0-9d92-3534-7b66-d666c0891246.png)

`File > Bulid Setting`

Build SystemをInternalに変更してください。

#４、Build & Run
USBデバッグが有効化されているMirage SoloをPCとUSB接続してください。

Unityで File > Build Setting のAdd Open ScenesをクリックしてScenesを追加します。
Build And Runをクリックしてください。

Buildが終了したらMirage SoloでBuildしたアプリが起動します。

お疲れ様でした。

#５、エラーの対処

原因：Mirage SoloのOSアップデート
対応するSDKのインストールをしてください。
Unity: File > Build Setting > Player Settings > Other Settings
APIを対応するバージョンに変更してください。

原因：JDKのアップデート
Edit > Preferences > External Tools
JDKのパスを変更してください。

#参考にした情報
https://qiita.com/monchi/items/8d9a6d1dd8f4b8606a61
https://qiita.com/JackMasaki/items/a322fd29e4034431d032

ぜひこちらも参考にしてください。
MariaDBをExcelから操る

Excelでデータ管理してて、それをDBに更新したいという場合、
手っ取り早く直接接続しちゃえってことでメモです。

#MariaDB をExcelから扱う

MariaDBを使ってますが、これまでは、MySqlのドライバで代用できてましたが、MariaDB用ドライバもすでにでてきてますね。元はMySqlでしたが分岐してから結構時間経過したので両者の差異もでてきたかもしれませんので、MariaDB用があるならそれを使わないとですね。
https://downloads.mariadb.org/connector-odbc/

ここからstableリリースのものを基本はダウンロードします。

Windowsで最近は64bit Windowsがほとんどですので、win64.msiとおもいきや、Excelが標準だと32bitがインストールされているっぽいので、win32.msiをインストールする必要があるようです。
両方いれといても大丈夫ですが。


そしてインストールです！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/84965/352fdcf3-cf4d-3540-420e-2b3b11adeac6.png)

[Typical]で大丈夫そうです。


#ODBC設定

##Windows10にODBCをセットアップする。
上記は、MariaDB接続のために用意したODBCドライバーのインストールです。こんどはそのドライバをWindowsが扱えるように登録します。
コントロールパネルが最新のWindows10では、表示されないので、
「設定」から検索で「odbc」と入力すると候補がでます。
Excelが上記書いた通り、通常は32ビットバージョンがインストールされているので、
ODBCデータソースのセットアップ(32ビット)を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/84965/d41bbb5f-a482-6eca-94f5-c25694d35fbe.png)


ユーザDSNに追加します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/84965/d5024dc2-0789-9e29-14ce-7bb457e89c4d.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/84965/889d49ed-8f67-ea21-e415-9dc3766eb290.png)

接続設定は適当に、サーバーに合わせて名前付けてくださいね。
NAME:には、プロジェクト名なんかいいとおもいます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/84965/2ff2e110-a1c7-9faa-8d79-fe917a7c94c3.png)

Charasetはutf8mb4ですね。日本語扱うなら。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/84965/b4f859cb-bdf6-484a-5918-795fe690a64e.png)

このくらいでOK

あとは、サーバー独自に設定画面がでてくるのでそれに合わせてください。
プロンプトにも西木野真姫を表示しよう！

## 概要
Bashやzshではコマンドプロンプトをカスタマイズすることができるらしい。
自分はFishユーザで長らく無理だと思っていたけど[ここを見て](http://fish.rubikitch.com/fish_prompt/)できるらしいということを知った。
できるならやるしかない！と思い立ってまきちゃんを表示してみたのだった！


## 从廿_廿从
西木野真姫がどういうキャラクターなのかは [ここ](https://dic.pixiv.net/a/西木野真姫)や[ここ](www.lovelive-anime.jp/otonokizaka/member/member06.html)を見ればわかるはず。
ラブライブのキャラには公式、非公式問わずいくつかの顔文字がある。 `从廿_廿从`は西木野真姫を表す。
言われてみればそういう気がする

## fish_prompt
fishのプロンプトの改造は `fish_prompt`という関数を定義してその中で表示したい情報を記述していくだけでいいらしい。 从廿_廿从 < これなら簡単ね


## 最終的に
```bash
function current_branch
  echo (set_color white) 'on'(set_color green)(__fish_git_prompt)
end

function fish_prompt
  echo (set_color yellow) (prompt_pwd)(current_branch) (set_color red -o)'从廿_廿从'(set_color normal) '< '
end
```
最終的にはこうなった。
何やってるかを解説してくと

```bash

function current_branch
  echo (set_color white) 'on'(set_color green)(__fish_git_prompt)
end
```
ここではコマンドプロンプトに表示するカレントディレクトリのgitのブランチ名を表示する関数
`set_color`で色を指定している
ここで大切なことは `__fish_git_prompt`を使うと大体の問題は解決するということ。
git管理外かの判定を自分でやるのは大変なのだ！


```bash

function fish_prompt
  echo (set_color yellow) (prompt_pwd)(current_branch) (set_color red -o)'从廿_廿从'(set_color normal) '< '
end
```
そして表示するのはこっち
よく見ると `从廿_廿从`がいる。かわいい。
ターミナルは対話型なのでまきちゃんにお願いするとやってくれるところがとてもいい

満足した
<img width="155" alt="スクリーンショット 2018-10-26 10.44.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/189219/0cbca160-a280-1678-a7bf-8031d8c220e2.png">
Learn Regular Expression from Corey

正規表現で悩んでいるときに先生が勧めてくれたYouTube動画がすごく良かったので自分なりに内容をまとめました。

動画: [Regular Expressions (Regex) Tutorial: How to Match Any Pattern of Text](https://youtu.be/sa-TUpSx1JA)
# Meta Characters (Need to be escaped)
`.[{()/^$|?*+`

If I want to search "Finxter.com", the way is `Finxter\.com`

If I want to search "Ha HaHa" with word boundary (`\bHa`), the The matches are "Ha Ha".

If I want to search numbers(321-555-4321 and 123.555.1234), the way is `\d\d\d.\d\d\d.\d\d\d\d` or `\d\d\d[-.]\d\d\d[-.]\d\d\d\d`.

# TEL number example
1. 321-555-4321
2. 123.555.1234
3. 123*555*1234
4. 800-555-4321
5. 5. 900-555-4321

```    
\d\d\d.\d\d\d.\d\d\d\d
\d\d\d[-.]\d\d\d[-.]\d\d\d\d
[89]00[-.]\d\d\d[-.]\d\d\d\d
[1-5]
[a-fA-F]
[^a-g]
```

# Word example
1. cat
2. mat
3. pat
4. bat

- `[^b]at`: Get 1-3.


# Meta Characters
- **\.**: Any Character Except New Line
- **\d**: Digit (0-9) 
- **\D**: Not a Digit (0-9) 
- **\w**: Word Character (a-z, A-Z, 0-9, _)
- **\W**: Not a Word Character 
- **\s**: Whitespace (space, tab, newline), 
- **\S**: Not Whitespace (space, tab, newline),
- **\b**: Word Boundary 
- **\B**: Not a Word Boundary 
- **^**: Beginning of a String 
- **$**: End of a String
- **[]**: Matches Characters in brackets 
- **[^ ]**: Matches Characters NOT in brackets 
- **|**: Either Or
- **()**: Group


# Quantifiers:
- **\*(asterisk)**  - 0 or more
- **\+** - 1 or more
- **?** - 0 or one
- **{3}** - Exact Number
- **{3,4}** - Range of Numbers (Min, Max)

# Name example
1. Mr. Schafer
2. Mr Smith
3. Ms Davis
4. Mrs. Robonson
5. Mr. T

- `Mr\.?` : Get 1, 2, 4, 5
- `Mr\.?\s[A-Z]`: Get 1, 2, 5
- `Mr\.?\s[A-Z]\w+`: Get 1, 2
- `Mr\.?\s[A-Z]\w*`: Get 1, 2, 5
- `M(r|s|rs)\.?\s[A-Z]\w*`: Get all 1-5

# Email example
1. CoreyMSchafer@gmail.com
2. corey.schafer@university.edu
3. corey-321-schafer@my-work.net

- `[a-zA-Z]+@[a-zA-Z]+\.com`: Get 1
- `[a-zA-Z.]+@[a-zA-Z]+\.(com|edu)`: Get 1, 2
- `[a-zA-Z0-9.-]+@[a-zA-Z-]+\.(com|edu|net)`: Get all 1-3
- `[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+`: Get all 1-3

# URL example
1. https://www.google.com
2. http://coreyms.com
3. https://youtube.com
4. https://www.nasa.gov

- `https?://(www\.)?(\w+)(\.\w+)`: Get all 1-4
- Replace with `Group 1: $1`. The result is...

    Group 1: www. 
    Group 1: 
    Group 1: 
    Group 1: www.

Replace with `Group 2: $2`. The result is...

    Group 2: google 
    Group 2: coreyms
    Group 2: youtube
    Group 2: nasa
    
Replace with `Group 3: $3`. The result is...

    Group 3: .com 
    Group 3: .com
    Group 3: .com
    Group 3: .gov


Replace with `$2$3`. The result is...

    google.com
    coreyms.com
    youtube.com
    nasa.gov
Redash v5 にアップグレードすると「dashboards.tags does not exist」エラーが発生する現象の対応

Redash を v5 にアップグレードしようとした際に、以下のエラーが発生しました。
どうやら以前のバージョンには無い dashboard.tags というカラムに依存したコードがある模様。

```
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column dashboards.tags does not exist
LINE 1: ...ived, dashboards.is_draft AS dashboards_is_draft, dashboards...
                                                             ^
```

## v4 -> v5 の順でアップグレードする

既にいくつか報告が上がっていました。
一旦 v4 までアップグレードしてから、再度 v5 にアップグレードすれば良さそうです。
v4 の AMI があれば早いのですが、見当たらなかったので upgrade スクリプトをいじることにします。

https://discuss.redash.io/t/upgrade-from-3-0-0-b3134-to-v5/2384
https://discuss.redash.io/t/solved-how-to-upgrade-from-3-0-x-to-5-0-x/2426

まず、bin/upgrade をコピーします。

```
$ sudo cp bin/upgrade bin/upgrade_v4
```

`upgrade_v4` を編集し、v4 系をダウンロードするようにします。

```python
def get_release(channel):
    if channel == 'ci':
        return get_latest_release_from_ci()

    response = requests.get('https://version.redash.io/api/releases?channel={}'.format(channel))
    release = response.json()[0]

    # 追記
    release['version'] = '4.0.1'
    release['download_url'] = 'https://s3.amazonaws.com/redash-releases/redash.4.0.1.b4038.tar.gz'
```

で、v4、v5　と順番にアップグレードすれば OK でした。

```
$ sudo bin/upgrade_v4
$ sudo bin/upgrade
```
monaca

# monaca
https://monaca.io

https://ja.monaca.io

>Monacaは20万人以上のWeb技術者に選ばれたモバイルアプリ開発環境です

>HTML5でiOS & Android 向けのアプリを同時開発

monacaが「モバイルアプリ開発環境」で「HTML5でiOS & Android 向けのアプリを同時開発」できることは書いている。何のための道具であるか、なぜmonacaという名前なのかを書いていない。。

Monaca Localkit 
https://ja.monaca.io/localkit.html
Monaca CI 
https://ja.monaca.io/ci.html

Monaca デバッガー
https://ja.monaca.io/debugger.html


[*Monaca*] Monaca概要
https://qiita.com/cigalecigales/items/51b7041fa141595b9996

Monaca 環境構築はじめるよー
https://qiita.com/shintaro_kubuki/items/0be2f13cac5889dd6bc8

monacaのローカル開発環境構築
https://qiita.com/sakkuntyo/items/0aa312f164cb5b68bc8b


monacaにてアプリ開発を行う上で考察すること
https://qiita.com/sei_0419/items/eb8aadcb64e8d56a05f4

monacaでスマホアプリを作ろう #1
https://qiita.com/furu8ma/items/42b8c96ed11c7ed22bfe

Monaca の PWA 対応について
https://qiita.com/keeey/items/82ad55a7614135df74df

個人学習メモ#14　MonacaのInAppBrowserプラグイン
https://qiita.com/earth_MY/items/e0724b84ce707a4e593c

# back

monacaにて「background image」の挙動
https://qiita.com/sei_0419/items/a48ae15e16f9f389abf5


monaca backend
https://qiita.com/sei_0419/items/1fe56b94b61e9fa1d1e1

MonacaバックエンドマネジメントAPIについて
https://qiita.com/keeey/items/4eefaf7a37edf41ae686


# android

monaca android8.0に対応
https://qiita.com/sei_0419/items/73c595164ce7c780c950

2018 年 8 月以降の Android アプリの申請について
https://qiita.com/keeey/items/d295bbd7bd95f6b7dc89

# 文書履歴(document history)
ver. 0.01 初稿 20181026
ver. 0.02 文書履歴 20190608
ver. 0.03 URL追記　20230302

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
[メモ]imageをbuildしてからlocalで作ったregistryにpushするまでのコマンド


```console
// imageをbuild. -tでリポジトリ名/イメージ名:タグを指定
$ docker image build -t ch04/todoweb:latest .

// tagでタグにregistryのホスト:ポートを指定
$ docker image tag ch04/todoweb:latest localhost:5000/ch04/todoweb:latest

// ホスト:ポートを追加した名前を指定してpushすることで該当ホストのregistryにpush出来る
$ docker image push localhost:5000/ch04/todoweb:latest
```
※registry用のコンテナは予めdockerHubから落として用意しておく
[UiPath]switch文でcaseを"文字列"で分岐するときの注意

初投稿。UiPathを用いた開発を始めました。早速つまづいたので、取り急ぎ。

# 結論
UiPathのswitch文においてcaseを文字列で指定したいとき、**「判定させたい文字列をダブルクォート」しちゃダメ🙅**。

# 試してみた
## テストシーケンス
メール送信に必要な情報が含まれたExcelファイルをDataTableで読み込み、メールを作成する。
Excelファイルには"Key"列と"Value"列を設け、予めデータを入力しておく。
"Key"列の文字列をもとに送信先・件名等を個別の変数に格納して、最後にメールを作成する。

### シーケンスイメージ
関係ないけど、イメージ出力が便利。
"Key"列の判定をswitch文で実装し、caseとして判定するための文字列を**ダブルクォートして**入れてみる。
![Sequence.jpg](https://qiita-image-store.s3.amazonaws.com/0/36038/388b8628-02f7-2b2e-c13d-a765830ffcbf.jpeg)

### Excelファイルイメージ
![mailtemplate.png](https://qiita-image-store.s3.amazonaws.com/0/36038/a70fc792-7d2a-3015-5aef-bf97850ade19.png)


(以下TBD)
大量のリファラの中から違法サイトを見つけ出す

```python
import pandas as pd

data_frame = pd.read_table("REFERER.txt", header=None)
data_frame2 = pd.read_csv("illegal.csv", header=None)

[
  [
    # 一致した行の必要な情報を表示
    print(referer[1]+","+referer[2]+","+referer[3]+","+referer[4]+","+illegal[1])
    for illegal in data_frame2.itertuples() if illegal[1] in referer[4] # URLの部分一致
  ]
    for referer in data_frame.itertuples()
]
```
php-master-changes 2018-10-25

今日は ext/json のファイル整理、不要変数の除去、opcache の最適化での型推論まわりのバグの修正があった！

# 2018-10-25
## petk: Remove ext/json parser files generated by bison
- https://github.com/php/php-src/commit/22c249347e6b0e3e42aeb1b4e1ca11d6ef4b67b5
- ext/json のパーサジェネレータからの生成となるファイルをリポジトリから削除
- 昨日の [phpdbg での対応](https://qiita.com/sj-i/items/8245d9c2d61eacf17155#petk-remove-phpdbg-parser-files-generated-by-bison)と同様

## weltling: Remove unused var
- https://github.com/php/php-src/commit/40808ac41e8ca90f8f8bfa760b9f09a3f06925aa
- [get_headers()](http://php.net/manual/ja/function.get-headers.php) 実装内の不要変数を削除

## nikic: Improve "narrowing" error message
- https://github.com/php/php-src/commit/e7153e8a2f5ea6e2b2d2b5afe558deebf518f04a
- [7.1~]
- ext/opcache のエラーメッセージを詳細化
- PHP 7.1 で入った[静的単一代入](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E5%8D%98%E4%B8%80%E4%BB%A3%E5%85%A5)による最適化での型推論処理で、narrowing を処理しようとすると無限ループが発生するというバグ回避のため、[単にエラーとする対応](https://github.com/php/php-src/commit/4948da178a1e2e0da4bab76fb4b0ff1948ec8d99)が入っていた
- 参考: [Static Optimization in PHP 7](http://biagiocosenza.com/papers/PopovCC17.pdf)

## nikic: Fixed bug [#77058](https://bugs.php.net/bug.php?id=77058)
- https://github.com/php/php-src/commit/f1ceec5533c5ee0e1de7867d629f336f1353f4b3
- [7.1~]
- ext/opcache の型推論処理のバグにより、変数の値が勝手に書き換えられる問題の修正

## nikic: Don't optimize function if inference failed
- https://github.com/php/php-src/commit/b9431ef4d5c07c19cd141fdb430e3fd763db257c
- [7.3~]
- ext/opcache の関数の最適化を型推論失敗時は行わないよう修正
- 先に解析して次に最適化、のうちの解析結果の方を潰して分岐に入らないようにしてる的な奴なのかな
OS mojaveにアップデートしたら git コマンド使えなくなった時の対処法

# mojave git エラー（多くの人はこれ
多くの人はこちらのエラーが出ているようなのでこちらの場合はこのコマンドで対応してください

xcode-select --install

```
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

# mojaveアップデートでターミナルに恐ろしいエラーが。
ターミナル起動したらエラーでるようになり、linuxOS標準コマンド以外が利用できなくなった

```terminal
xcodebuild[1091:18006] [MT] DVTPlugInLoading: Failed to load code for plug-in 
com.apple.dt.IDE.DVTKitDFRSupport (/Applications/Xcode.app/Contents/PlugIns/DVTKitDFRSupport.ideplugin),
 error = Error Domain=NSCocoaErrorDomain Code=3588 
"dlopen(/Applications/Xcode.app/Contents/PlugIns/DVTKitDFRSupport.ideplugin/Contents/
MacOS/DVTKitDFRSupport, 265): Symbol not found: _OBJC_IVAR_$_NSTextViewIvars.sharedData

....
中略

 in /Applications/Xcode.app/Contents/Developer/usr/bin/../../../SharedFrameworks/DVTKit.framework/Versions/A/DVTKit, NSBundlePath=/Applications/Xcode.app/Contents/PlugIns/DVTKitDFRSupport.ideplugin, NSLocalizedDescription=The bundle “DVTKitDFRSupport” couldn’t be loaded.}}}
** INTERNAL ERROR: Uncaught exception **
Uncaught Exception: Error getting value for key 'initializationClass' of extension 'Xcode.DVTKitDFRSupport.Initializer' in plug-in 'com.apple.dt.IDE.DVTKitDFRSupport'
Stack:
  0   __exceptionPreprocess (in CoreFoundation)
  1   objc_exception_throw (in libobjc.A.dylib)
  2   -[DVTExtension valueForKey:error:] (in DVTFoundation)
  3   _IDEInitializeOnePlugInAndPrerequisites (in IDEFoundation)
  4   _IDEInitializePlugIns (in IDEFoundation)
  5   IDEInitialize (in IDEFoundation)
  6   -[Xcode3CommandLineBuildTool run] (in Xcode3Core)
  7  0x000000010c8f5202 (in xcodebuild)
  8   start (in libdyld.dylib)

```


## 原因はXcodeのバージョンが低いこと
app storeでアップデートしましょう

![image.png](https://qiita-image-store.s3.amazonaws.com/0/69647/325c2665-1617-afa9-8a42-c271353f9f45.png)


### 次にこのコマンドでライセンスを有効化
```
sudo xcodebuild -license accept
```


これで無事つかえるようになりました
ピアボーナスサービスHeyTaco!風のSlackbotを簡単に作る

[HeyTaco!](https://www.heytaco.chat/)というステキなピアボーナスサービスがあって無料期間で試しに使っていたのですが、チームで有料化の合意が取れなかったので残念ながら利用を停止しました。しかし「感謝のタコスを送り合う」という文化がチームに残ったので、HeyTaco!風にタコスに反応するSlackbotを設定してみました。

Slackの管理画面の[ワークスペースのカスタマイズ > Slackbot](https://allin.slack.com/customize/slackbot)を開いて、

![slack_bot_allin_short.png](https://qiita-image-store.s3.amazonaws.com/0/62293/47c5fe13-a3da-dea0-762d-d979bac684b4.png)

「When someone says」をタコスのアイコン(:taco:)にして、「Slackbot responds」にもタコスのアイコンを設定するだけです。（ここでは1個から5個までのタコスのどれかが返るようにしています）

![slackbot_heytaco_1.png](https://qiita-image-store.s3.amazonaws.com/0/62293/d835fb0b-d900-7242-507d-8de48f9a0a90.png)

誰かがタコスのアイコンを含んだ発言をすると、Slackbotが反応します。

私のチームではタコスだけでなく餃子のアイコンも同様に使う文化になったので、餃子も入れています。

![slack_bot_allin_long.png](https://qiita-image-store.s3.amazonaws.com/0/62293/b274d568-19b8-67dc-50db-64baca6bc669.png)

ついでに他のアイコンも混ぜておきました。

![slackbot_heytaco.png](https://qiita-image-store.s3.amazonaws.com/0/62293/ac5c79a9-04de-97a8-0574-5adab51c7263.png)

試しに何度か呼んでみると、こんな風になります。
AzureDevOpsログイン

AzureADとAzureDevOpsを連携して、ユーザーをAzureADで作成したあとのユーザー認証の方法を説明します。
AzureADでユーザーを作成して、ユーザー、パスワードが作成済みの状態です。

# AzureDevOpsでの設定

1. ブラウザでサイトを開く
https://xxxxx.visualstudio.com
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/bd668040-089b-18dc-418c-88658fbe6e36.png)

2. ユーザーIDを入力する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/bffb7f45-b36c-b883-2c60-28caca54ddc0.png)

3. パスワードを入力する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/9886268e-76b3-acba-4888-d476d9e8276f.png)

4. パスワードを更新する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/3b235974-c322-5048-2d88-b0a18dc2e1eb.png)

5. 確認画面、次へをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/17c69c18-0ab4-4150-0586-3bdd4f4e4fd3.png)


6. 認証用のメールを登録するので、次へをクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/003d1ebc-2854-6f21-fada-ade385d51784.png)


7. 使っているメールアドレスを入力する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/3c6d065e-257e-9f3a-45a4-8de35ca52349.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/4ff10a5a-5b11-dd13-b286-7177b4036bc5.png)


8. メールに認証用のコードが届くので入力する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/6bea06b2-baa9-e35d-4f6c-70672dd223d8.png)


9. 確認画面が表示されたら、完了をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/f5c68e96-4d68-0646-8aa2-95fa78dd67f7.png)


10. AzureDevOpsの画面が開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/47172/fc65dcf5-4755-beac-d582-aa22ae486015.png)
Ubuntuで非対話式でadduserを実行

homeディレクトリ作成やログインスクリプトをいい感じに設定してくれるadduserを、大量ユーザ作成時等に、bashスクリプトで対話式部分をスキップして自動化する方法が見当たらなかったので自分で作った。
なんどか同じような事をしている気がするので、ベース部分だけ備忘目的で記事にします。
（adduserとuseradd、どちらがどっちかいつも忘れる…）

# <i class="fa fa-forward" style="font-size:1em;">これで出来た</i> 

```bash
users=("nishi higashi minami kita")
for username in $users; do
# 対話式でメールアカウントとか聞かれないように-gecos ""指定
# パスワードは後でchpasswdで設定するのでdisable
adduser --disabled-password --gecos "" "$username"

# 非対話でパスワード設定（初期パスワードをユーザ名と同じにする）
echo "${username}:${username}" | chpasswd

# sudo 権限付与
gpasswd -a "$username" sudo
done
```

特にaptで何かインストールしないといけないとかもありません。
パスワード初期値はユーザ名と同値にしてますがベースということでご容赦ください。
adduserとuseraddは、Redhat系とDebian系で挙動が全然違うようなので注意。
Go言語環境構築メモ

# Go言語導入
[Golangの特徴](https://aqua-engineer.com/post-590/ "Golangの特徴")
[Go言語入門 1回 （パッケージ編)A Tour Of Go](https://aqua-engineer.com/post-597/ "Go言語入門 1回 （パッケージ編)A Tour Of Go")
[Go言語入門 2回 （関数,変数編)A Tour Of Go)A Tour Of Go](https://aqua-engineer.com/post-613/ "Go言語入門 2回 （関数,変数編)A Tour Of Go")
[Go言語入門 3回 (for文などの基本記述編)A Tour Of Go](https://aqua-engineer.com/post-627/"Go言語入門 3回 (for文などの基本記述編)A Tour Of Go")
[Go言語入門 4回 (ポインター編)A Tour Of Go](https://aqua-engineer.com/post-640/"Go言語入門 4回 (ポインター編)A Tour Of Go)
[Go言語入門 5回 (Array,slices,Map)A Tour Of Go](https://aqua-engineer.com/post-642/"Go言語入門 5回 (Array,slices,Map)A Tour Of Go)
### Goのインストール
```
brew install go
```

###  動作確認用コード（hello world 出力）
```golang:helloworld.go
package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}
```

### コンパイル
```
go build helloworld.go
```
コンパイル後に実行用ファイルが生成される

### 実行
```
./helloworld.go
```
TypeScript で型定義ファイル( d.ts )がないときの対処法

## はじめに

例えば npm からインストールした `foobar`モジュールの型定義がないとき

```ts
import foobar from 'foobar'
```

のようにモジュールをインポートすると、

```sh
Could not find a declaration file for module 'foobar'.
Try npm install @types/foobar if it exists or add a new declaration (.d.ts) file containing declare module 'foobar';
```

とコンパイルエラーが発生します。

大まかに分けると3対処法があります。

- `@types` からインストールする
- 型定義ファイル( `d.ts` )を自作する
- `require` でモジュール読み込み

## 1. `@types` からインストールする

型定義ファイルが提供されているか試します。
TypeScript コンパイラの指示通り `@types` からのインストールを試します。

```sh
# npm
npm install --save @types/foobar
# yarn
yarn add @types/foobar
```

無事インストール出来たら解決です。  
もし型定義が提供されておらず、 `error An unexpected error occurred: "https://registry.yarnpkg.com/@types%2ffoobar: Not found".` と表示された場合、

- 型定義ファイル( `foobar.d.ts` )を自分で実装

もしくは

- `require` でモジュール読み込み

をします。

## 2. 型定義ファイル( `d.ts` )を自作する

`src/@types` ディレクトリを作成します。
`foobar.d.ts` を `@types` 下に作成します。

※ `tsconfig.json` の `typeRoots` のデフォルト設定が `@types` ディレクトリになっています。
※ 型定義ファイルの保存場所を変える場合、`tsconfig.json` を設定します。

```json
{
  "compilerOptions": {
    "typeRoots" : [".d.tsを入れるディレクトリのパス"]
  }
}
```


型定義ファイル( `.d.ts` ) の実装についてはこちらが参考になりました。
**[TypeScript の型定義ファイルと仲良くなろう](http://developer.hatenastaff.com/entry/2016/06/27/140931)**


## 3. `require` でモジュールを読み込む

型定義ファイル( `d.ts` )を書くのが面倒な時の対処法です。
`require` でモジュールを読み込みます。

```ts
const foobar = require('foobar')
```

暗黙的に `any` 型になるので、型定義ファイル `d.ts` が見つからないエラーは消えます。


ただし `TSLint` の設定によっては `[tslint] require statement not part of an import statement (no-var-requires)` という警告がでます。
`// tslint:disable-next-line:no-var-requires` とコメントで `require('foobar')` についてだけ警告を無効にします。

```ts
// tslint:disable-next-line:no-var-requires
const foobar = require('foobar')
```

この状態では `foobar` が `any` 型になり、型チェックも賢い補完も行われません。
自分の使う API を型付けして置くと良さそうです。

```ts
interface IFooBar {
  bazMethod(qux: string): string;
  fuga(hoge: number): boolean
}
// tslint:disable-next-line:no-var-requires
const foobar = require('foobar') as IFooBar;
```


読んでいただきありがとうございました❗
プログラミングコードは、他の人とのコミュニケーション手段だ 。


# プログラマはコミュニケーションが苦手？

あなたはもしかしたら、プログラミングは好きだけれど、他の人とのコミュニケーションや、日本語を書くことは苦手なエンジニアだったりしないだろうか。

# プログラミングの名言

「コードというものは、たまたまインタプリタが実行できるだけ」
「本質的には他の人に対するメッセージであり、コミュニケーション手段だ」

というような意味の言葉を、どこかの本で読んだ記憶がある。

出展は忘れてしまった。

# ユーリカ！

僕はこの言葉がすごく腑に落ちた。

たとえば、コードを書く時の作法として「コードは他の人が読みやすいように書きなさい」と言われる。
実行できるプログラムがまずあって、それが読みやすければ、ちょっとプラスだというような。

だけど逆だ。

プログラミングというのは、そもそも人へのコミュニケーションがメインであり、インタプリタが実行できることの方が、オプショナルなのだ。

## ひとりでコードを書くときはどうなのかって？

君はコードを読まずにコードを書くなんていうことが出来るのだろうか。目隠し将棋ができるタイプだろうか。

自分でコードを書いて、それを一切読まないなんていうことがあるんだろうか。マジシャンか。

ここでいう他の人というのは、コードを書いている真っ最中の自分や、コードを書いてから1ヶ月経った時の、未来の自分も含まれる。

# プログラミングと日本語を書くことの共通点

僕は日頃、プログラミングとは全く関係なく、ブログを書くのが好きだ。
Qiitaに記事を書くのも好きだ。

- プログラミングをすること
- ブログに記事を書くこと
- GithubのDescriptionを分かりやすく書くこと
- Pivotal Tracker に要件定義をまとめること

これは全て、根本の部分で共通していると感じる。

どれも全て、他の人や、自分自身とコミュニケーションするための手段だからだ。自己表現の手段だからだ。

だからプログラミングが出来るということは、非プログラミング言語(たとえば日本語)で自己表現ができるということでもあると思う。

逆に、非プログラミング言語をうまく扱えないのであれば、プログラミング言語を扱うことも、うまくいかなかったり、独りよがりなものになりがちなんじゃないだろうか。
(インタプリタぐらいであれば騙せるかもしれないけれど、複雑なアプリケーションは作れないかもしれない)

# 言いたいこと

- プログラミング言語を使うことと、日本語などの非プログラミング言語を使うことは、本質的には同じことだ。ただ表現の種類が違うだけだ。
- この共通点を感じ取ることさえできれば、プログラミングも、非プログラミングも、どちらも好きになれだろうし、上手になれたりするかもしれない。
- プログラミングすることは国語的文章を書くことだし、国語的文章を書くことはプログラミングすることだ。人と話すこともプログラミングだし、プログラミングは人や自分との対話だ。そこに大きな違いはない。

# 案

- コードリーディングをする時「これは、Aさんから俺へのメッセージだ」というような目線で見てみよう。コードに性格は現れる。
- コードベースについて、他の人と対話してみよう。コードが「人の考え」から生まれたものだと実感できるかもしれない。
- Qiitaに記事を書いてみよう。分かりやすい記事を書くのには、根本的な表現力が試される。
- 日本語でブログを書いたり、日記をつけたりしてみよう。システムエンジニアの仕事や、チーム論などについて書いてみても面白いかもしれない。やりたくなければ、もちろん、やらなくても良いけれど。

## Wi-fi環境の良いスターバックスで、抹茶のティーラテを飲みながら

MacBookのキーボードを叩いたりして、恍惚の瞬間を感じられるかどうか、試してみよう。

脳が手指という外部デバイスを通して、コードやテキストをアウトプットしていく。
それを目が、ゲームと同じぐらい細かなフレームレートで、次々と脳にフィードバックしていき、複雑な反射が起こる、その連続した、偉大な瞬間。

それが分かれば、自分や人とコミュニケートしている時間の全てが、美しいと感じられるかもしれない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/c966ff71-d6a2-e70b-d415-d33c12423973.png)


# 物事の観察力を磨く方法

どうすれば、異なる物事同士の、本質が似通っていることに、気づきやすくなるだろう。

物事に対する根本的な観察力を高めるためには、瞑想、マインドフルネスのトレーニングがおすすめだ。
(練習をせずにゲームがうまくなるスポーツ選手がいるだろうか？)

[瞑想するエンジニア ( by 稲浦悠馬 Yuma Inaura ) —GoogleやFacebookもやっている「マインドフルネス」のススメ— - Qiita](https://qiita.com/YumaInaura/items/f1a55b0b342954224207)

(まあきっと、君はやらないだろうけれど)
(もし興味があれば、ほんの、1秒だけ自分の呼吸を感じ取ってみよう)

# あわせて読みたい？


- [いいこと言ってそうな名言を集めたサイトを作った「プログラミングはセックスのようなもの。ひとつのミスに人生を捧げてサポートしなければならない」 - Qiita](https://qiita.com/jabba/items/0d4e730be7f23c21c6f9)
 - 名言はプログラミングを助く。








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
PowerShellでファイル一覧出力

シンプルなファイル一覧出力
--
カレントディレクトリ配下のファイル一覧を再帰的にテキスト出力します。ディレクトリのみの行は除外しています。
_PowerShell Core 6.1でもこの程度ならコードの修正も必要ないですね。_

```powershell:sample.ps1
$dateTime = Get-Date -Format "yyyyMMdd_hhmmss"
$fileName = "fileList_" + $dateTime.ToString() + ".txt"
ls -Recurse | %{
    if($_.Mode -ne "d-----"){
        $_.FullName | Out-File -FilePath $fileName -Encoding "UTF8" -Append -Width 260
    }
}

```

以下は実行結果の例です。

```text:fileList_20181026_072227.txt
C:\Users\sample\hoge\main.py
C:\Users\sample\hoge\sub.py
C:\Users\sample\hoge\pic.png
C:\Users\sample\hoge\.vscode\launch.json
C:\Users\sample\hoge\.vscode\settings.json
C:\Users\sample\hoge\.vscode\tasks.json
```
なろうリーダー(仮) 2日目: 画面構成検討

# なにやってるの？
- Webサイト[「小説家になろう」](https://syosetu.com/)の小説をダウンロードするAndroidアプリづくり。
- アプリの作り、UIをイマドキにしたい。

# 画面設計
[要件定義](https://qiita.com/nomunomu5678/items/bda958b67cf5e427358e)に引き続き、画面設計を行う。
ということで、まずは画面遷移図を作成する。

# 画面遷移図(状態遷移図)作成に利用するツール
ド定番ですが、~~JUDE竹~~astah*で作成したいと思いま。。。！？

**2018年9月26日をもちましてastah* communityの提供を終了いたしました。**
http://astah.change-vision.com/ja/product/astah-community.html

**…マジですか？**、そうですか。orz
# ということで、代替ツール探し。
- @kazuaki90997さんの[画面遷移図の作成方法ついてのまとめ](https://qiita.com/kazuaki90997/items/8a5673d0b120bb1354f6) にツールが紹介されていたので参考にしました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/306047/8ce58d9e-9905-8770-459a-24576eef5335.png)

- draw.ioがやけに評判がいいので使ってみることにしました。

# できた画面遷移図 (powered by draw.io)
![Untitled Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/306047/be5cf11b-05a4-866c-f1b6-7ffb8cde0aeb.png)
## draw.ioについて
- PowerPointやGoogle Slideで書くよりは断然書きやすい。
- 複数の矢印が重なる部分については、やっぱり多少ズレが生じてしまう。
- Google Driveなどのオンラインに直接保存できる点は使いやすい。
- フリーツールとしては破格の出来と思います。

## 内容面
- 定期的なバックグラウンド実行は(5.0 Lollipop以降では) `AlarmManager`ではなく`JobScheduler`を使うらしい(再起動時に再登録する必要がなくなる？)
- メニューは`ViewPager`よりも`NavigationDrawer`の方が、利用しやすそう。
- `Fragment`が多い為、`MainActivity`で`implements ***Fragment.Callbak`とかやってたらスパゲティが絡まりそう…どうしよ。。。

# 今後の進め方
- どこから実装するかは決めておりませんが、実装に着手したいと思います。
PythonをVScode上で実行できるようにする方法

今回は**Python**のスクリプトを**VScode**で書ける、VScodeのスコープ内で動かせるようにする方法を書きます。
毎度メモ程度ですみません。

# 手順
1.　**Python**のインストール

　**Anaconda**というdistributionをダウンロードしてしまうのが簡単です。以下のサイトからダウンロードできます。

https://www.anaconda.com/download/

詳しいインストール法はすでに多くの人が紹介ているので割愛します。最新版をお勧めします。

**※ GCP環境を使う予定があり、かつクライアントライブラリを使う可能性がある方はお勧めしません！クライアントライブラリインストール時にAnacondaのプリインストールパッケージとの競合で、クライアントライブラリが正常にインストールできません。(2019.07.09現在)**

2.　**VScode**のインストール

　これも簡単です。以下の公式サイトからインストールできます。

https://code.visualstudio.com/

3.　**VScode**上でパッケージのインストール
　**VScode**を開いて**拡張機能**というところがあるので、そこをクリックして以下のパッケージをダウンロードしてください。
　検索をかけることで見つかります。

- **Python**　（似たのが多いので注意）
- **Japanese Language Pack for Visual Studio Code** （表示を日本語にしたい人）

~~※**再読み込みしないとアクティブにならないので、必ず再読み込みをしてください。**~~
(2019.01 ver. 1.31により再読み込みは必要なくなりました。2019.03.03現在)

これをするだけで、**Python**が**VScode**で動きます。

ありがとうございました。
【Java】問題No.1

## 問題1
* Javaのデータ型には大きく分けて二通りあります。  
1つはプリミティブ型(基本データ型)、もう1つは参照型です。  
では、プリミティブ型には、どのような種類の型があるでしょうか？  
すべて記載してください。  
※ヒント：全部で8種類

## 解答1

【基本データ型】  

| No | 型      | 初期値   | サイズ |
|:---|:--------|:--------|:-------|
|  1 | boolean | false   | ? Byte |
|  2 | char    | ¥u0000  | 2 Byte |
|  3 | byte    | 0       | 1 Byte |
|  4 | short   | 0       | 2 Byte |
|  5 | int     | 0       | 4 Byte |
|  6 | long    | 0L      | 8 Byte |
|  7 | float   | 0.0f    | 4 Byte |
|  8 | double  | 0.0d    | 8 Byte |
※1Byte = 8bit
Rails コールバックについて　その2

コールバックの続き

## コールバックの実行となるトリガ
`データベースに影響を与える処理` と　 保存時じゃなくてもトリガとなる `valid?` 

- create
- create!
- destroy
- destroy!
- destroy_all
- save
- save!
- save(validate: false) • toggle!
- touch
- update_attribute
- update
- update!
- valid?

データベースから、レコードを読み込むたびに呼び出される `after_find` では、下記がトリガとなる

- all
- first
- find
- find_by
- find_by_*
- find_by_*!
- find_by_sql
- last

## 関連モデルのコールバック
親子関係のモデル経由でコールバックを実行することができる

```ruby:user.rb
class User < ApplicationRecord
has_many :posts , dependent: :destroy

end
```
```ruby:post.rb
class Post < ApplicationRecord

  def log_destroy_action
    puts 'Userが消えたよ！'
  end
end

>> user = User.first
=> #<User id: 1>
>> user.posts.create!
=> #<Post id: 1, user_id: 1>
>> user.destroy
Userが消えたよ！
=> #<User id: 1>
```

## :if や :unlessでオプションをつけられる
バリデーションでよく使う 

```ruby:user.rb
class User < ApplicationRecord
  before_save :user_search, if: :user_exists?
end
```

## コールバックclassを作れる
Active Recordはコールバックメソッドをカプセル化したクラスを作成できる(Railsガイドより引用)

```ruby:
class PictureFileCallbacks
  def after_destroy(picture_file)
    if File.exist?(picture_file.filepath) File.delete(picture_file.filepath)
      File.delete(picture_file.filepath)
    end
  end
end
```

クラス内で宣言することにより、コールバックメソッドはモデルオブジェクトをパラメーターとして受け取れるようになる
=> これでモデル内で使用可能

```ruby
class PictureFile < ApplicationRecord after_destroy PictureFileCallbacks.new
  after_destroy PictureFileCallbacks.new
end
```
コールバックをインスタンスメソッドとして宣言したため、 `PictureFileCallbacks オブジェクト` を新しくインスタンス化する必要があった
コールバックをクラスメソッドとして宣言する方がいいパターンも...

```ruby
class PictureFileCallbacks
  def self.after_destroy(picture_file)
    if File.exist?(picture_file.filepath) File.delete(picture_file.filepath)
      File.delete(picture_file.filepath)
    end
  end
end
```
クラスメソッドなら、インスタンス化は不要ですね♪

## トランザクションコールバック
データベースのトランザクションが完了したときにトリガされるコールバック
Active Record のモデルから、データベーストランザクションの一部に含まれていない外部のシステムとやりとりを行ないたい場合に使用する

- after_commit
- after_rollback

※　データベースの変更のcommit、rollbackが完了するまでトリガされない
RubyでC言語のHello, World

最近Rubyを学び始めて思いついた超くだらないネタです。。既出かは調べていないです。

```ruby:ruby
def int(n)
end

def main(v, &f)
    begin
        f.call
    rescue LocalJumpError
    end
end

void = 0

### C言語のコード

#include <stdio.h>

int main(void) {
    printf("hello, world!\n");
    return 0;
}

###
```

ブロックについて学んでいて、(意味は全く異なりますが)ほぼC言語のコードに近いものを書けることに気づいて書いてみた次第です。。
本当は`LocalJumpError`の例外処理はゴリ押しせず何かしら別な手段(`lambda`にキャストとか?...`lambda`だとエラーにならない...みたいな記事を見たのですがエラーになったりしてよくわかりませんでした...)で対処したかったのですが、まぁ面倒だし今回はこれでいいかとあきらめちゃいました(苦笑)

おやじギャグみたいなもんだと思ってくれれば幸いですw

#### 10/26 追記

アドバイスを受け`rescue`を使わない形を考えてみました

```ruby:ruby
lambda {

def int(n)
end

def main(v, &f)
    f.call
# rescue LocalJumpError
end

void = 0

### C言語のコード

#include <stdio.h>

int main(void) {
    printf("hello, world!\n");
    return 0;
}

###

}.call
```

バージョンが`2.4.1`以前だとトップレベルで値を返すことができないみたいでした[^1]ので、`lambda {...}.call`で囲んでみました

[^1]: 自分の環境は`ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-msys]`でした
ktorのHttpClientで配列のJSONをパースする

APIレスポンスのJSONのトップレベルが配列の場合(例: `[{'hoge':'huga'}...]`)の、ktorのHttpClientの書き方です。

githubを検索したら見つかりました。

https://github.com/bulwinkel/experiment-ktor-serialization/blob/master/src/main/kotlin/com/bulwinkel/experiments/main.kt

```main.kt
    val gistSerializer = Gist.serializer()
    val li: KSerializer<List<Gist>> = ArrayListSerializer(gistSerializer)

    val client = HttpClient {
        install(JsonFeature) {
            serializer = KotlinxSerializer().apply {
                setMapper(List::class as KClass<List<Gist>>, li)
                setMapper(Gist::class, gistSerializer)
            }
        }
    }
```
第39話 収束級数

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第39話です。

```math
4\pi^2−\sum_{n=1}^\infty\frac{16}{n^2(n+1)^2(n+2)^2}=39
```

これは次の式を変形したものです。

```math
\sum_{n=1}^\infty\frac{1}{n^2(n+1)^2(n+2)^2}=\frac{4\pi^2-39}{16}
```

これも根気よく計算することでこの値になります。
解くには次の式と第6話で出てきた式を使います

```math
\frac{1}{n(n+a)}=\frac{1}{a}\left(\frac{1}{n}-\frac{1}{n+a}\right)
```

計算していきますが、長いので盛大に省略していきます。

```math
\left(\frac{1}{n(n+1)(n+2)}\right)^2=\left(\frac{1}{2}(\frac{1}{n}-\frac{2}{n+1}+\frac{1}{n+2})\right)^2\\
=\frac{1}{4}\left(\frac{1}{n^2}+\frac{4}{(n+1)^2}+\frac{1}{(n+2)^2}-3(\frac{1}{n}-\frac{1}{n+2}) \right)
```

この式をΣに入れていきます。

```math
\frac{1}{4}\sum_{n=1}^{\infty} \left(\frac{1}{n^2}+\frac{4}{(n+1)^2}+\frac{1}{(n+2)^2}-3(\frac{1}{n}-\frac{1}{n+2}) \right)\\
=\frac{1}{4}\left(\frac{\pi^2}{6}+4(\frac{\pi^2}{6}-1)+(\frac{\pi^2}{6}-1-\frac{1}{4})-3(1+\frac{1}{2}) \right)\\
=\frac{1}{4}(\pi-\frac{39}{4})
```

ということで冒頭の式が出てきました。
定期的にLinuxコマンドを実行し、日付時刻付きで画面とファイルに結果を出力する。

* 定期的にコマンドを実行したい
* コマンド結果をリアルタイムで確認したい
* 結果はファイルにも出力したい
* 実行時間を出力したい
* なるべく簡単に行いたい
という要件

```bash
watch -d 'echo `date` `ls` | tee -a result.log'
```

`watch`コマンドは、定期的にコマンドを実行します。
`-d`オプションは画面出力時に差分を強調します。なくても大丈夫です。

`tee`コマンドは、入力を画面とファイルに出力します。
`-a`オプションがファイルへの追記となります。

ちなみに`watch`コマンドの結果自体をファイル出力してしまうと、
エスケープなど`watch`コマンドが出力する不要なものがファイルに含まれてしまいます

```bash:NG例
watch -d echo `date` `ls` | tee -a result.log
```
ずんだ問題まとめ

* [ずんだの縦読み問題 Ruby編 - Qiita](https://qiita.com/tbpgr/items/90abccf8297be0e42f8c)
* [ずんだの1桁足し算問題 Ruby編 - Qiita](https://qiita.com/tbpgr/items/6c75930566dda97bb5b6)
* [ずんだの表見出し++問題 Ruby 編 - Qiita](https://qiita.com/tbpgr/items/427d35f981cd9675efb9)
* [ずんだのMARQUEE問題 - Qiita](https://qiita.com/tbpgr/items/5765ff5bcb418ae6c30e)
* [ずんだのハロウィン問題 Ruby編 - Qiita](https://qiita.com/tbpgr/items/1f2ed0e14e5d94775963)
* [（ずんだの）合成数列の和 Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/composite-number)
* [（ずんだの）シクシク素数列 Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/4949prime-series)
* [ずんだの菱形アルファベット問題 - Qiita](https://qiita.com/tbpgr/items/0567699ba083158804ac)
* [ずんだのさくらんぼ計算問題 Ruby編 - Qiita](https://qiita.com/tbpgr/items/368edd0a39074ba9be04)
* [ずんだのポップル錯視問題 Ruby 編 - Qiita](https://qiita.com/tbpgr/items/7530fda4725384c897c6)
* [ずんだの二桁の整数の桁入れ替えと合計と剰余問題 Ruby編](https://qiita.com/tbpgr/items/c50e872bd33e37c7379e)
* [「ずんだの進次郎構文だからこそずんだの進次郎構文なのです」問題 Ruby編 - Qiita](https://qiita.com/tbpgr/items/c5a8935a40af7580c605)
* [ずんだの波打つ進捗問題 Ruby 編 - Qiita](https://qiita.com/tbpgr/items/33501ed3d23a3f53c196)
バッチファイルを初めて少し勉強したのでメモ


バッチファイルを少しだけ勉強したので、メモ

```test1.bat
@echo off
先頭に常に記述


set test = ryuji
変数「test」に「ryuji」という文字列を格納する


echo test
変数「test」の中身を表示する


if exist test.bat (
    mkdir ryujii1
 ) else (
    mkdir ryuji2
 )
もし、「test.bat」というファイルが存在していれば、
「ryuji1」というディレクトリを作成し、存在していなければ、「ryuji2」というディレクトリを作成する

```

実行方法

まず上記のファイルを作成して任意の場所に保存。
コマンドプロンプトを起動して、

```コマンドプロンプト

cd 「ディレクトリ」

test1.bat

```

で実行可能。
[Windows]Goでデスクトップの壁紙を変更する

# 目的
Goを使ってWindows端末のデスクトップ壁紙を変更してみます。

DLLの読み込みと実行をGoで試してみたかったのでやってみました。

# 壁紙の変更方法

Windowsの場合、壁紙変更は`user32.dll`の`SystemParametersInfo`を呼び出すことで変更できます。また、Goは`syscall.LoadDLL`でDLLをロードし、`DLL.FindProc`でDLL内のプロシージャを取得、`Proc.Call`で実行できます。

```golang
package main

import (
	"syscall"
	"unsafe"
)

func main() {
	user32, _ := syscall.LoadDLL("user32.dll")
	defer user32.Release()
	systemParametersInfoW, _ := user32.FindProc("SystemParametersInfoW")
	path, _ := syscall.UTF16PtrFromString(`C:\Users\v\Pictures\example.png`)
	systemParametersInfoW.Call(0x0014, 0, uintptr(unsafe.Pointer(path)), 0x02)
}

```


# 参考
https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-systemparametersinfow
C++ の方が C よりも速い例

だいたい、同じ趣旨のコードを書いたら C++ の方が速いと私は思っている。

例えば。`std::sort` は `qsort` よりも速いことが多い。

たくさんの整数を 1の位の値で整列するというコードを例に。

# C言語のソースコード

まずは C99 で。

```C:C99
// clang -std=c99 -O2 qsort.cpp
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

double get_tick()
{
  struct timespec t;
  clock_gettime(CLOCK_REALTIME, &t);
  return t.tv_sec + t.tv_nsec*1e-9;
}

typedef int target_type;

void prepare( target_type * data, size_t len )
{
  for( size_t i=0 ; i<len ; ++i ){
    data[i] = (target_type)i;
  }
}

int compare( void const * a, void const * b )
{
  return (*(target_type*)a)%10 - (*(target_type*)b)%10;
}

int main(void)
{
  const size_t N = 1024 * 1024 * M;
  target_type * data = malloc(N * sizeof(target_type));
  prepare( data, N );
  double tick = - get_tick();
  qsort( data, N, sizeof(target_type), compare );
  tick += get_tick();
  printf( "%.6f\n", tick );
  free( data );
  return 1;
}
```

# C++ のソースコード

続いて同じ趣旨の計算を C++11 で。

```c++:C++11
// clang++ -std=c++11 -O2 stdsort.cpp
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <memory>

double get_tick()
{
  timespec t;
  clock_gettime(CLOCK_REALTIME, &t);
  return t.tv_sec + t.tv_nsec*1e-9;
}

using target_type = int;

void prepare( target_type * data, size_t len )
{
  for( size_t i=0 ; i<len ; ++i ){
    data[i] = static_cast<target_type>(i);
  }
}

int main()
{
  const size_t N = 1024 * 1024 * M;
  std::unique_ptr<target_type[]> data( new target_type[N] );
  prepare( data.get(), N );
  double tick = - get_tick();
  std::sort( data.get(), data.get()+N, 
             [](target_type a, target_type b)->bool{ return a%10<b%10; } );
  tick += get_tick();
  std::printf( "%.6f\n", tick );
  return 1;
}
```

これを、M の値を変えながら手元のマシンで実行すると、下表のようになった：

|M|C言語(qsort)|C++(std::sort)|
|--:|--:|--:|
|1|0.014700|0.007676|
|2|0.034709|0.015732|
|4|0.061273|0.031011|
|8|0.127590|0.061935|
|16|0.242823|0.126991|
|32|0.451090|0.260800|
|64|1.077482|0.550410|

ご覧のとおり、 `std::sort` の方が倍ぐらい速い。
たぶん、比較関数が inline 展開されるかどうかの違いだと思う。
ecs-cli 1.6.0が鬼門なので1.7.0以上にしないと無呼吸人生を迎えるハメになる話

俺です。

無呼吸してますか？

未だにecs-cli 1.6.0を使ってる情弱の俺たちはマッハで1.7.0以上にあげましょう。

なぜならv3形式のcomposeファイルを作成した場合,`ecs-cli compose`で指定する`docker-compose.yml`を環境変数でサクッと環境を切り替えたいという欲望を叶えることができないからです。

https://github.com/aws/amazon-ecs-cli/blob/master/CHANGELOG.md

```
## 1.7.0
* Feature - Add support for container health check (#472)
* Feature - Add support for devices (#508)
* Bug - Fix error in ps command (#522)
* Bug - Fix error using ENV variables with docker compose v3 (#537)←めっちゃこれが合致
```

# 定義ファイル

- docker-compose.yml

ecs-cli 1.6.0で以下のようなcomposeパラメータを作ってecs-cliを実行すると、
環境変数をセットしてくれません。

```
version: '3'
services:
 api:
    image: ${API_ECR}
    ports:
      - "80:80"
    command: sl
    env_file:
      - .ecs.${SERVICE_ENVIRONMENT}.env
    logging:
      driver: "awslogs"
      options:
        awslogs-group: "${SERVICE_ENVIRONMENT}/stdout"
        awslogs-stream-prefix: "api"
        awslogs-region: "ap-northeast-1"
```

- ecs-params.yml

ただしecs-params.ymlの環境変数は読むという...

```
version: 3
task_definition:
  ecs_network_mode: awsvpc
  task_execution_role: app
  task_size:
    cpu_limit: 1024
    mem_limit: 2GB
  services:
    rails:
      essential: true
run_params:
  network_configuration:
    awsvpc_configuration:
      subnets:
        - ${SECRETSMANAGER_ECS_SUBNET_AZ1}
        - ${SECRETSMANAGER_ECS_SUBNET_AZ2}
      security_groups:
        - ${SECRETSMANAGER_SECURITY_GROUP1}
      assign_public_ip: DISABLED
```

まず使ってる道具のCHANGELOG読めよハゲという話でした。
おわり。
xcodeで新しくプロジェクトを立ち上げる方法・おまけでLaunchの次の画面を他のものに変更する方法

# 新規プロジェクト作成

  - Xcodeにてcreate project
  - githubと連携するために，チェック項目にチェック
  - githubにてリポジトリ作成．以下連携
    1. プロジェクトのディレクトリで``git remote add origin git@github.com:[繋げたいリポジトリ]``
    2. ``git add -A``
    3. ``git commit -m 'first commit'``
    4. ``git push origin master``
    
# Launchの次に表示される画面をCalendarVCに設定

1. main.storyboardのVCのis_initial_VCのチェックを外す
2. Calendar.storyboardのVCのis_initial_VCをチェック
3. これでいける！と思ったけど，launch画面の次は真っ黒画面
4. 調べると，デフォルトはlaunch -> mainみたいだったので変更が必要
5. 以下の関数を次のように書き換える

```swift:appDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.window = UIWindow(frame: UIScreen.main.bounds)
        
        let storyboard = UIStoryboard(name: "Calendar", bundle: nil)
        
        let initialViewController = storyboard.instantiateViewController(withIdentifier: "CalendarVC")
        
        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()

        return true
    }
```
【Unity】モデルを空に飛ばす（UFO）

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Xcode version 10.0(10A255)
⭐️Unity 2018.2.13f1
⭐️iPhone7 IOS11.4.1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1055482930758217729


UFOを飛ばす。
<img width="375" alt="IMG_0048.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/bcdc3d32-21c2-156f-8eee-76ec63cf825c.png">


<img width="375" alt="IMG_0049.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/5666225c-15ca-8075-a6cc-3dd13433beb8.png">
【Unity】uGUIボタンを使用する

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Xcode version 10.0(10A255)
⭐️Unity 2018.2.13f1
⭐️iPhone7 IOS11.4.1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1055482490381451264


「投げる」ボタン押すと、キューブが出てくる。
床に落ちる。たくさん積み上がると、キューブが落ちる。

<img width="375" alt="IMG_0055.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/2cadb0aa-0d56-1ecc-eb42-50cec319d38a.png">
34歳になったので、「プログラマ35歳定年説」について考えてみた

# 34歳になったので、「プログラマ35歳定年説」について考えてみた
これは、あくまで個人的な見解であり、公式見解、および、他人の意見を否定するものではありません。

## 概要： プログラマ35歳定年説
「プログラマ35歳定年説」とは、読んで字のごとく、「プログラマは35歳で定年を迎える」というものです。

社会人をプログラマで過ごしてきましたので、数日前に34歳になったし、35歳という定年（笑）を迎える前に、一度それについて考えてみようと思います。

## まず
これは **嘘** です。
// 言い方かもしれませんが、「本当ではない」といったほうが確かかもしれません。
私が働いている場所でも、プログラマで35歳以上の人は多く存在します。

大抵の人は分かっていると思いますが、安心してください。

## 出会い
私がこの言葉と出会ったのは、社会人となる前、会社の団体説明会で言われました。
「プログラマは35歳で定年を迎えますが、他の道を提示します」
そんな言葉をその会社では謳っていました。

当たり前のように語られていたその内容に、学生の私はそれを信じていました。
// 就職した先ですぐに嘘だと言われましたが・・・

## なぜ、風説があがったのか
この風説が上がってしまった理由を、Wikipediaや他の記事を読みつつ、自分で考えて（ぱくって）みました。

* 新しい技術を勉強するのが辛い
* 激務 **も** あるので、体力的に辛い
* プログラマではなく管理者になる
* 単価が高くなり売れなくなる
* プログラマって辛いと悟る

### 新しい技術を勉強するのが辛い
これについては、プログラミングが好きであれば、まず大丈夫でしょう。
新しい技術、素晴らしい技術も好きでないのであれば、知ることが辛くなってしまいます。

しかし、単純記憶となれば、若い人よりも低くなるのは事実です。
ですが、今までの知識がそれを大きく補ってくれるはずです。

### 激務 **も** あるので、体力的に辛い
これは、個人的なモノと私は考えます。
50歳近くにして、平然（？）として徹夜や休出している人もいれば、30歳前にして21時帰りが辛いと言っている人もいます。
// 実際に見ています。

まぁ、日本のプログラマの労働時間はおかしい気がしますが・・・
// 21時が早いとか頭おかしい！
// デスマは大抵、上流過程の人間のせい！！
// （あくまで個人的な見解であり、公式見解、および、他人の意見を否定するものではありません）

### プログラマではなく管理者になる
これは基本的に、上からの命令となりますので、どうしようもないかもしれません。
単価が高くなりますし、知識も付いてきますので、どうしても上流過程や管理をすることが多くなってきてしまいます。

### 単価が高くなる、もしくは、年齢により売れなくなる
これはSES契約、や、フリーランス、言ってしまえば派遣の話です。
単価が高い、もしくは、年齢が高くなると派遣先が嫌がります。

案件の中には年齢制限が付くものもあります。

同じ能力（履歴や面接判断）であれば単価は安いほうが良いですし、年齢は低いほうが良いです。
単価は当たり前ですが、年齢について、年が上の人間ほど「扱いづらい」というレッテルが張られてしまいます。
例えば、30歳がリーダで35歳が来ると、やりづらいと思われてしまうのです。

ただ、「同じ能力」というのがキモで、その人自体が魅力的（知識があったり、経歴があったり）であれば上記の限りではありません。

### プログラマって辛いと悟る
新しい技術をスイスイと手に入れている若手、きらきらしている若手を見ていると辛いなと思ってしまうこともあるかもしれません。

これは自身の考え方なので、どうとでもなります。

## 35歳定年説は嘘だけど
大抵の会社では、その人を技術者ではなく管理者にしようとしてきます。
また、派遣では年齢制限が出てきます。

上記より、私は、他の職種のより「プログラマ」職種としての寿命は短いと考えています。
私自身の経験からすると、中小企業で、かつ、自社アプリを開発しているところは長年プログラマで居られるのでは？と考えます。

### 自分の話
昔、新人のころに居た上司は私に以下のように言いました。
// 言葉は微妙に違っていますが、大体同じはずです

25歳まで、プログラミングというものを勉強し、どんなプログラミングでも扱えるようになりなさい。
28歳まで、リーダというものを勉強し、人の導き方を知りなさい。
35歳まで、管理者というものを勉強し、人を動かせるようになりなさい。

私は、これを今でも実践しており、プログラマから少しずつ離れていってます。
// PMOとかなってみたいなぁ～

### SES契約
SES契約では、45歳になったらほぼ契約が取れないのでは？と考えています。
SESがメインの会社は40～45歳くらいになった社員をどう扱おうとしているか疑問に思うこともあります。

## まとめ
上級プログラマ以外の定年は40～45歳くらいかと考えます。
// 上級プログラマとは、上記にある理由を覆せる人たちという意味で使ってます。

35歳以降は、若者よりある知識を使い、かつ、どん欲に知識を得ていくことで、35歳定年はなくなることでしょう。
※ ただし、SESがメインな会社除く

それ以外の方は、上流工程、および、管理職となり、プログラマから離れることになると考えます。
そんな時はプログラマにしがみつくことなく、割り切ったほうが良いでしょう！

## 参考
* [プログラマ定年説 Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E#%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E5%AE%9A%E5%B9%B4%E8%AA%AC)
* [プログラマー３５歳定年説が嘘なのはもうわかっているけど一応考えてみた](https://axia.co.jp/2017-07-07)
* [そろそろ「プログラマー35歳定年説」を徹底論破しとくか](http://lafrenze.hatenablog.com/entry/2015/03/02/175231)
* [プログラマー35歳定年説について思う事](http://www.premium-tsubu-hero.net/salariedworker/age35-retirement)
* [エンジニアの定年は？「35歳定年説」の実態とキャリアアップのヒント](https://tech-camp.in/note/careerchange/30204/)
Chromebook の Linuxアプリに AWS CLI をインストール

参考：[Linux に AWS Command Line Interface をインストールします](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/awscli-install-linux.html)


```bash:rootに
sudo su -
```


```bash:pipインストール
curl -O https://bootstrap.pypa.io/get-pip.py
python3 get-pip.py
pip --version
```

```bash:AWS_CLIインストール
pip install awscli --upgrade 
aws --version
```

```bash:configure
exit # rootから通常ユーザに変更
aws configure
```

```bash:jqも
sudo su -
apt-get install jq
jq --version
```