OmniAICreator/Qiita-1.07M huggingface dataset:
abc 099

C


メモ化再帰（動的計画法）で解く。

```
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<list>
using namespace std;
using ll = long long;
const int INF = 1e8;
int N;
vector<int>c;
int dp[111111];
int main() {
	cin >> N;
	c.push_back(1);
	for (int i = 6; i <= N; i *= 6) {
		c.push_back(i);
	}
	for (int i = 9; i <= N; i *= 9) {
		c.push_back(i);
	}
	fill(dp, dp + N, INF);
	dp[0] = 0;
	for (int i = 0; i <= N; ++i) {
		for (int j = 0; j < c.size(); ++j) {
			if (i >= c[j]) {
				dp[i] = min(dp[i], dp[i - c[j]] + 1);
			}
		}
	}
	cout << dp[N] << endl;
	return 0;
}
```

https://qiita.com/drken/items/ace3142967c4f01d42e9
このサイトがすごく良かったので同じことを欠いてまとめてみようかと思う

計算量解析

```
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<math.h>
#include<queue>
#include<deque>
#include<stack>
#include<cstdio>
#include<utility>
#include<set>
#include<list>
#include<cmath>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int INF = 1e8;
const int MAX_N = 110000;
int memo[MAX_N];
int rec(int n) {
	if (n == 0)return 0;
	if (memo[n] != -1)return memo[n];

	int res = n;

	for (int pow6 = 1; pow6 <= n; pow6 *= 6)res = min(res, rec(n - pow6) + 1);

	for (int pow9 = 1; pow9 <= n; pow9 *= 9)res = min(res, rec(n - pow9) + 1);

	return memo[n] = res;
}
int main() {
	int N; cin >> N;
	for (int i = 0; i < MAX_N; ++i)memo[i] = -1;
	cout << rec(N) << endl;
	return 0;
}
```

```
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<math.h>
#include<queue>
#include<deque>
#include<stack>
#include<cstdio>
#include<utility>
#include<set>
#include<list>
#include<cmath>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int INF = 1e9;
const int MAX_N = 110000;
int dp[MAX_N];
int main() {
	int N;
	cin >> N;
	for (int i = 0; i < MAX_N; ++i) {
		dp[i] = N;
	}
	dp[0] = 0;
	for (int i = 1; i <= N; ++i) {
		for (int pow6 = 1; pow6 <= i; pow6 *= 6) {
			dp[i] = min(dp[i], dp[i - pow6] + 1);
		}
		for (int pow9 = 1; pow9 <= i; pow9 *= 9) {
			dp[i] = min(dp[i], dp[i - pow9] + 1);
		}
	}
	cout << dp[N] << endl;
}
```
貰うdp

```
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<map>
#include<math.h>
#include<queue>
#include<deque>
#include<stack>
#include<cstdio>
#include<utility>
#include<set>
#include<list>
#include<cmath>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
const int INF = 1e9;
const int MAX_N = 110000;
int dp[MAX_N];
int main() {
	int N;
	cin >> N;
	for (int i = 0; i < MAX_N; ++i) {
		dp[i] = N;
	}
	dp[0] = 0;
	for (int n = 0; n < N; ++n) {
		for (int pow6 = 1; n + pow6 <= N; pow6 *= 6) {
			dp[n + pow6] = min(dp[n + pow6], dp[n] + 1);
		}
		for (int pow9 = 1; n + pow9 <= N; pow9 *= 9) {
			dp[n + pow9] = min(dp[n + pow9], dp[n] + 1);
		}
	}
	cout << dp[N] << endl;
}
```
配るdp
環境構築とプログラミング不要で30秒で作れるスクレイパー

![fast_scraping_low_rate.gif](https://qiita-image-store.s3.amazonaws.com/0/193662/90e48c11-08cc-0deb-0dde-58ead2a62fe3.gif)

#やりかた(mac OS限定)
スクレイピングしたいページをsafariで開く
automatorを起動
automatorのワークフローを新規作成
アクションからインターネットを選択
「Safariの現在のWebページを取得」をダブルクリックで追加
「WebページからリンクURLを取得」をダブルクリックで追加
「URLにフィルタを適用」をダブルクリックで追加し条件に/items/を入力
アクションからテキストを選択
「テキストエディット書類の内容を設定」を追加
実行
「テキストエディット書類の内容を設定」の結果タブにURLが出力される

※gif制作で参考にしたページ
https://qiita.com/hirothings/items/7ed040d017bda13e261a
Mojaveにアップデートしてjekyll動かしたらbad interpreterでたので対応した

## エラーコマンドとメッセージ

```bash
$ jekyll 
-bash: /usr/local/bin/jekyll: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby: bad interpreter: No such file or directory
```

pryなど、Gemで入れた他のツールも動かない。辛い。

## 原因

Macのメジャーアップデートにより、System下のRubyのバージョンが変わったため。

## 必要なコマンド

```bash

# gemの認識するrubyのバージョンのアップデート?
sudo gem update --system

# developerツール入れ直し
xcode-select --install

# Mojave用のCommandLineToolsがheadersを読み込んでくれないため対応
sudo open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
```

## エラー対応のログ

### sudo gem update --systemのあと

以下のようなエラーが出ていた

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

### xcode-select --install のあと

以下のようなエラーが出ていた

```
/Users/hoge/.rbenv/versions/2.5.0/include/ruby-2.5.0/ruby/defines.h:112:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~
1 error generated.
make: *** [ruby_http_parser.o] Error 1

make failed, exit code 2
```

## その他

`pry`とかは `sudo gem update --system`だけで対応できそうです。

## 参考

### gem updateについて

http://www.project-unknown.jp/entry/cocoapods-high-sierra

### 最後の mac_sdk_headers

https://techracho.bpsinc.jp/hachi8833/2018_10_10/62963

## 追記

またエラーでた。

```bash
jekyll
# => /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/dependency.rb:319:in `to_specs': Could not find 'jekyll' (>= 0) among 15 total gem(s) (Gem::LoadError)
```

下にGEM_PATHが変やで!!という1文があり、rbenv下にgemをinstallしていたので、
とりあえず.bash_profileに以下を書いて対応。 
この辺ベストじゃないプラクティスっぽいけど、とりあえず対応完了。

```bash
# hogeはユーザーネームに変えてね
export GEM_PATH="/Users/hoge/.rbenv/versions/versions/2.5.0/lib/ruby/gems/2.5.0/"
```
PHPで欠かせないPSR-2と命名規則の最速チェックリスト

コーディングをしているとき、ある一定のルールが

ないと可読性の低いコードになります。

また、チームで開発するときも好き勝手に変数を決めていると

メンバーに多大な迷惑をかけてしまう恐れがあります。

そこで、今回はコードを書くにあたって心得ておきたい

PSR-2と命名規則についてまとめたいと思います。

##PSR-2

チームで開発するにあたり、コーディング規約に従ったコードを

書くことで、コードを読む際の認識のずれを抑えることができます！

そこで、PHPにはPSR（PHP Standards Recommendations）というPHP標準勧告が

あります。PSRには、PSR-0、PSR-1、PSR-2、PSR-4などの種類が

ありますが、PSR-2がPHPの最もスタンダードなコーディング規約になりつつあります。

PSR-2はPSR-1を拡張したコーディング規約です。

###＜PSR-2最速チェックリスト＞

1.　予約後は小文字で書く

```php
$a = true;
```
---
2.　スペース4つでインデントとする

```php
    public function getValue()
```
---
3.　ファイルの最後に空行を入れる

```php
}

```
---
4.　namespace、use、classの間には空白行を入れる

```php
namespace Aaa¥Bbb;

use Aaa¥Ccc;

class Ddd 

```
---
5.　クラス、メソッドの開き括弧は次の行に記述

```php
class Foo
{
    public function get()
    {
```
---
6.　ifの開き括弧は同じ行に配置

```php
if ($aaa) {
```
---
7.　クロージャの開き括弧は同じ行に記述（閉じ括弧は最後の行に記述）

```php
$f = function() {
    return 1;
};
```
---
8.　caseで意図的に処理をスルーする場合は「// no break」等の記述が必須

```php
switch ($expr) {
    case 1:
        echo 'A';
        // no break
    case 2:
    case 3:
        echo 'B';
        break;
}
```

以上のようなルールがPSR-2にはあります。

普段からコーディングをするときに注意したいところです。

もっと細かいPSR-2の詳細は[こちら](https://www.php-fig.org/psr/psr-2/)



##命名規則

命名規則とは、変数名をつける際のルールです。

開発組織ごとに命名規則が定められている場合もあり、

そこはうまく対応する必要がありそうです。

しかし、多くの命名規則には共通する点が存在するのでまとめてみたいと

思います。

###＜命名規則を導入するメリット＞

命名規則を使う理由としては

以下が挙げられます。

1. 名前の付け方を考える必要がなくなる
2. コードの可読性を高める
3. 変数からコード内容を理解しやすくする
4. 名前の増殖を抑えられる

です。

これらを導入することでプログラムが大きい時や、開発期間が長い時に

スムーズに対応できます。

###＜命名規則最速チェックリスト＞

・長い名前は付けない
　名前は長くても20文字程度に収まるようにする。

・理解できる名前にする
　短ければ良いというのではなく、意味が通じる名前にする。

・慣例としてあるものはその慣例に従う
　慣例として以下のものが挙げられます。

　1.クラス名は先頭大文字で以降は小文字（単語の区切りは大文字にする）
　2.変数は小文字で始め以降も小文字（単語の区切りは大文字にする）
　3.メソッド名も変数名と同様
　4.定数は全て大文字で表す（単語区切りは"_"を入れる）
　5.識別子の対称性も意識して命名する

命名するポイントとしては、汎用的な名前は避け、具体的な名前をつけると

可読性が上がります。その関数や変数がどのような仕事をするのか常に考えて

命名したいところです。

いずれにせよ、開発メンバーが読みやすいような命名を心がけたいですね！




##参考文献
・[PSR-2 コーディングガイド（日本語）](http://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.html)
・[PSR-1 と PSR-2 を5分でざっくり理解する](https://www.slideshare.net/wterada/psr1-psr2-5)
・[今さら聞けない、変数や関数の命名規則と、まず覚えるべき英単語200](https://oxynotes.com/?p=8679)
AWS勉強 -NATを構築する-

# NATを構築する

プライベートサブネットに配置したサーバーはインターネットから接続できないため安全だ.
しかしインターネットと一切通信できないのとサーバーのアップデートやソフトウェアのインストールの際に不便だ.
この問題を解決するのがNATで,NATは「プライベートサブネット→インターネット」の向きの通信だけを許可する.

## NATの用途と必要性

これから,DBサーバーに「MySQL」というデーターベースソフトをyumコマンドを使用してインストールしてWebサーバーから利用できるようにするのだが,ここで問題が発生する.
DBサーバーはプライベートサブネットにあるためインターネットに接続できないという問題だ.
つまりyumなどのコマンドを使用してもソフトウェアをダウンロードできないのだ.
踏み台サーバーを経由して必要なソフトウェアを１つずつscpコマンドなどでコピーすることもできるが,手間がかかりすぎてしまう.

### NATの仕組み

https://milestone-of-se.nesuke.com/nw-basic/nat/nat-summary/

上記参考に

### NATインスタンスとNATゲートウェイ

AWSでNATを構成する場合,次の２つの方法がある.

①NATインスタンス

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_NAT_Instance.html

②NATゲートウェイ

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html

本書では構築のしやすさからNATゲートウェイを利用する.

### パブリックサブネットとプライベートサブネットをNATゲートウェイで接続する

プライベートサブネットに配置したDBサーバーをNATゲートウェイを経由してインターネットに接続できるようにするために以下のような手順を踏んでいく.

#### NATゲートウェイを配置する

インターネットから接続可能な場所である「パブリックサブネット」に配置して起動する.

#### デフォルトゲートウェイを設定する

NATゲートウェイの準備ができたらプライベートサブネットからインターネット宛のパケットがNATゲートウェイを経由するようにルートテーブルを変更する.

## NATゲートウェイを構築する

### NATゲートウェイを起動する

VPCに移動後,

![スクリーンショット 2018-10-28 16.22.42.png](https://qiita-image-store.s3.amazonaws.com/0/180668/baa63bf3-f6b0-14e1-685a-44b8bf90a267.png)

からの,

![スクリーンショット 2018-10-28 16.31.01.png](https://qiita-image-store.s3.amazonaws.com/0/180668/25108012-6ba1-0d1b-5d5a-9c1c8fc936c1.png)

できた❣️

<img width="1280" alt="スクリーンショット 2018-10-28 16.31.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/180668/921332a8-c2a5-f8a1-e655-b1e4e6707ecb.png">

### ルートテーブルを更新する

![スクリーンショット 2018-10-28 16.51.37.png](https://qiita-image-store.s3.amazonaws.com/0/180668/93ef0cf7-d925-a038-419a-716deabb845b.png)

からの,

<img width="774" alt="スクリーンショット 2018-10-28 23.29.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/180668/2ebfad01-e5d5-3d6c-c82a-b08ecd1a60e5.png">


## NATゲートウェイを通じた疎通確認をする

### curlコマンドで確認する

DBサーバーにSSHでログインして,

```shell
$curl www.nikkeibp.co.jp
```

と入力してwww.nikkeibp.co.jpのトップページを取得してみる.
これで出力されればNATゲートウェイが機能してHTTP通信ができていることが確認できる.

<img width="558" alt="スクリーンショット 2018-10-28 17.07.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/180668/902f820a-9a96-02da-9759-84829f434c28.png">

でけた!

ちなみに,NATゲートウェイは稼働時間と転送バイト単位の両方で課金されるらしいので全く通信していなくても稼働していれば料金がかかってしまうらしい.
なのでNATゲートウェイを使う必要がなくなったら削除するとよい!

### 感想

ほぼ終盤ですね.
あと少し頑張ります!
Tkinterで全画面表示する方法

# コード

## 全画面(全画面)

```python
root.attributes("-fullscreen", True)
```
全画面にする際は、画面を閉じるボタンを追加してください。
でないと、永遠に真っ白な画面が表示されます。
画面を閉じる方法は、「tkinter close」「tkinter exit」「tkinter quit」等でググればでます。

## 全画面(Windowsにおける最大化)

```python
root.attributes("-zoomed", "1")
```

# 参考元
https://code.i-harness.com/ja/q/798da7
http://utisam.hateblo.jp/entry/2013/01/12/212958
kotlinでandroid入門 広告表示 AdMob+Firebase

今回は Firebase を使っての広告の表示

#### build.gradle (Project)

```build.gradle
  ependencies {
      ・
      ・
       classpath 'com.google.gms:google-services:4.0.1'
    }
  
```

google-servicesを追加


#### build.gradle (app)

```build.gradle
    apply plugin: 'com.google.gms.google-services'

    dependencies {
        implementation 'com.google.firebase:firebase-ads:15.0.1'
    }
```
plugin と implementation の２つを追加


#### AndroidManifest.xml
 
```xml
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
```

パーミッションを入れる

#### 画面

activity_main.xml はsdkバージョンと同じ物を使っています


#### MainActivity.kt 


```kotlin
class MainActivity : AppCompatActivity() {
    private val appID = "ca-app-pub-3940256099942544~3347511713"　// テスト用
    private val adUnitId="ca-app-pub-3940256099942544/6300978111"   // テスト用
    private var blAdView : Boolean = false
    private lateinit var adMobView : AdView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        MobileAds.initialize(this, appID)
        adMobView = AdView(this)
        adMobView.adUnitId = adUnitId
        adMobView.adSize = AdSize.BANNER
                val adRequest : AdRequest = AdRequest.Builder()
                    .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
//                    .addTestDevice(adTextDeviceId)
                    .build()
        adMobView.loadAd(adRequest)

        button.setOnClickListener { _ ->
            redisplayAdMob()
        }
    }
    private fun redisplayAdMob() {
        if (blAdView) {
            // 表示時 -> 消す
            adMobView.visibility = AdView.GONE
            admob_layout.removeView(adMobView)
            Log.d("AdMob", "OFF")
            blAdView = false
        } else {
            // 非表示 -> 表示
            admob_layout.addView(adMobView)
            admob_layout.visibility = LinearLayout.VISIBLE
            adMobView.visibility = AdView.VISIBLE
            Log.d("AdMob", "ON")
            blAdView = true
        }
    }
}

```

動作もsdk版と同じ、ボタンで表示／非表示切り替え


#### sdkとの違い

・ライブラリが違う（詳細は Firebase にアプリ登録時に指示されます )
・MobileAds.initialize(this, appID)でFirebase との関連付けを行っている（たぶん）
   このため、アプリIDが必要
   skdの時は 広告ユニットIDだけで良かった

実行すれば、テスト広告の表示/非表示の動作はできますが
このコードでは、Firebase となにもしていません。
テスト用のIDでのテストですから
(Firebaseにアプリ登録もしてませんから)
特定のメールの内容をSlack無料版で複数人に共有したい

[Slack でメールを受信する – Slack](https://get.slack.help/hc/ja/articles/206819278-Slack-%E3%81%A7%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E5%8F%97%E4%BF%A1%E3%81%99%E3%82%8B)

Slackにはメールアプリというとても便利な機能があります。これとGmailのフィルターを使えば特定のメールをSlackのメールアドレスに転送するだけでチャンネルにメールの内容を投稿することができます。

それがあるならこれを使えばいいのでは、という気持ちになりますが、メールアプリは残念ながら有料版でしか使えません。無料アカウントの場合は『転送用のメールアドレスを設定』して個人のslackbotに内容を送る機能だけが使えます。

個人のslackbot宛てに届いたメールはfileとして保存されます。そのfileのURLはそのSlack上のチャンネルに直接貼って直接共有することができるので、少し手間ですがslackbotに届いたfileのURLをチャンネルに手動で貼ることで複数人に共有することができます。自分の観測範囲では添付ファイルなどがあってもいい感じに表示してくれました。

恒常的に発生するなら有料版一択ですが、数件程度ならこれで十分に回ると思うので試してみてください。
Project Euler 問題2 「400万以下のと偶数のフィボナッチ数の和」

## 問題
400万以下のフィボナッチ数のうち、偶数の数字の和を求めよ
> Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

> 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

> By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.


## コード(Python)
```python

def getFibonacchi(max : int, firstNum = 1, secondNum = 2, fibonacchiNums=[1,2]): #一個目の数字と二個目の数字から三個目の数字を求める
  thirdNum = firstNum + secondNum
  if thirdNum > max:
    return fibonacchiNums
  fibonacchiNums.append(thirdNum) 
  return getFibonacchi(max, secondNum, thirdNum, fibonacchiNums)

def getSumOfEvenNumbers(numbers : list): #任意のリストから偶数を抜き出し、和を求める
  evenNums = []
  for number in numbers:
    if number % 2 == 0:
      evenNums.append(number)
  sumOfEvenNums = sum(evenNums)
  return sumOfEvenNums

fibonacchiNums = getFibonacchi(4000000)
sum = getSumOfEvenNumbers(fibonacchiNums)
print(sum)

```


400万以下というとすごい数のフィボナッチ数が出て来そうですが、意外と少ない!

```python
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578]
```
というわけで今回はストレートに再帰関数でやってみました。

ちなみに私も今回知ったのですがPythonではこんな感じに関数の引数の型を他のエンジニアさんに教えることができます(ただし強制力はない)

```python
max : int
numbers : list
```
Gatsby.jsでAdobe Fontsを使う

# 概要 
GatsbyでWebFontを使う方法を調べてみました。
今回はAdobe Fontsを使っていきます（Google Fontsなどは適宜置き換えて読んでください）

# 導入

1. まずはフォントを入れます。
[Adobe Fonts](https://fonts.adobe.com/)で好きなフォントをアクティベートしてプロジェクトに追加します。
下のような画面が出るので、`kitId`をメモする。
<img width="556" alt="Screenshot 2018-10-28 16.11.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/148589/8dd6b7eb-6542-e4a2-134c-27aa2136e515.png">

1. Gatsbyではindex.htmlに直接scriptを貼ることは推奨されていないので、
[webfontloader](https://www.npmjs.com/package/webfontloader)というパッケージを使ってロードします。
まずは、`yarn add webfontloader`。
このフォントをロードしたいコンポーネントで（できればLayout系がいいと思います）

    ```javascript
    componentDidMount(){
      WebFont.load({
        typekit: {
          id: 'xxxxxx'
        }
      });
    }
    ```
これでフォントはロードされます。

1. `gatsby develop`はこれで通るのですが、`gatsby build`はwebpackのビルドの過程で`window is not defined`を吐いて失敗するので、[このページ](https://www.gatsbyjs.org/docs/debugging-html-builds/)の通りに従い、

   ```javascript:gatsby-node.js
   exports.onCreateWebpackConfig = ({ stage, loaders, actions}) => {
     if (stage === 'build-html') {
       actions.setWebpackConfig(
         {
           module: {
             rules: [
               {
                 test: /webfontloader/,
                 use: loaders.null()
               }
             ]
           }
         }
       );   
     }
   }
   ```
を追加すれば無事にビルドが通ります。ちなみに、Reactのコンポーネント内で`window`や`document`を参照している箇所がある場合も同様のビルド失敗をしますが、その時は`window`が定義されているかどうかをチェックする(typeof)処理を書くことでwebpackコンパイル時に落ちないようになります。

# まとめ
[Typography.js](http://kyleamathews.github.io/typography.js/)と合わせて使うと非常に快適にフォントを扱えるのでおすすめです。
Java7〜Java8の新機能

JDK 1.6 (JavaSE6) からの差異
※ぱっと見で使いそうなもの抜粋

【JDK 1.7 (Java 7/ SE7) から】
・整数リテラルに２進数(0b始まり)が使える
・数値リテラルにアンダーバーが使える
・Switch文で case 文字列 が使える
・ダイアモンド演算子＜＞：クラスのインスタンス化時、型引数を省略できる
・try~catchのcatch{}内で、例外の再throwができる
・リソース付try文 (try-with-resources) ：try (型 変数 = 初期化)
・例外のマルチキャッチ：catch(例外A | 例外B)

【JDK1.8 (Java 8/ SE8) から】
・ラムダ式
・finalの省略：実質的にfinalな変数にfinalをつけなくて良い
・メソッド参照：クラス名::メソッド名
・１箇所に同一アノテーション複数指定
・関数型インターフェース
・日付時刻API：パッケージが変わった。DateやCalendarやDateFormat→timeへ※これはかなり違う点

あと色々難しそうなのは、いいや。

>以下サイトを参考にさせていただきました。
[Java新機能（Javaの変更点）](http://www.ne.jp/asahi/hishidama/home/tech/java/uptodate.html)
rsyslogに直接ログを送りつけるモジュール達

## 候補

ruby 実装のrsyslog　クライアントでめぼしいものは以下２つ。

### remote_syslog_logger

https://github.com/papertrail/remote_syslog_logger
ActiveSupportのLoggerを差し替えることができる。Railsを使っていたならこれが一番。

### remote_syslog_sender

https://github.com/reproio/remote_syslog_sender
単体で機能するrsyslogのクライアント。ActiveSupportとか関係なく、単体のRubyスクリプトに組み込むならこちらが良い。

## そもそもなんのためのもの？

rsyslogは普通は、マシンのsyslogから同期をとるような形でログを集約するのがよくある使い方。ところが、syslog自体がCentOSとUbuntuで違うし、rsyslogの設定も個別。極めつけはMacやWindowsで開発するときにはどこにsyslogがあるかも怪しい。

そうなるとOSの機能に任せるのではなく、自前で直接ログを集約したくなる。Windows上で動くツールからでもガシガシログを溜め込みたい。ということで、プログラムから直接ログを集約したいよね。

### 他にもログを集約するツールはありそうだけど

あるだけどいつでもすごい分散データベースを使って分析したいわけじゃぁない。普通のログローテーションができて、それが一つのサーバに集まっているだけでいい。さらに、rsyslogのいいところは、UDPが選べるというところ。ログサーバーとの通信がいまいちでもそれがクライアントを待たせることがない。最悪ログが欠落するんだけど、ログ書き出しのトラブルがサービスを止めるという本末転倒なトラブルを防ぐことができる。これはよい。

ということで、UPDで安上がりに複数サーバからロギングしてもらうには、rsyslogクライアントがいいねって話です。

ちなみに、Rubyじゃなくて、Pythonのrsyslogクライアントもある。
https://csl.name/post/python-syslog-client/

実装そのものはシンプルなので、もはやライブラリとかじゃなくて、単体のスクリプトでもいいのかなって思う。
Google TrendのデータをAPI経由で取得し時系列解析②〜プログラム言語の人気トレンドを国別比較する〜

### Summary
- Google Trendから各キーワードの検索データを取得し、時系列データ分析を行います
- Pytrendsという（非公式の）ライブラリを用いてデータを取得します
- 各検査キーワードの検索トレンドを国別に比較・分析します
- 前回同様にstatsmodelを用いて時系列解析を施して比較してみます
- 参考（前回記事）：
[Google TrendのデータをAPI経由で取得し時系列解析①〜人気プログラム言語のトレンドを考察する〜](https://qiita.com/takubb/items/e5578a8143a4f6b0f7fc)

### 分析ゴール
- 各プログラム言語のキーワード検索傾向に関する国別の違いを把握する
- 対象国は下記とする（言語の影響を排除するため、英語圏に絞りました）
    - 日本
    - U.S
    - イギリス
    - シンガポール
    - オーストラリア
    - カナダ

### 対象データ
- [前回分析時の結果](https://qiita.com/takubb/items/e5578a8143a4f6b0f7fc)を参考に、対象言語を以下として、Google trendから抽出する
    - Python（日本では上昇傾向）
    - JavaScript（日本では横ばい）
    - Java（日本では下降傾向）
- 2014年〜2018年9月末の期間で考察する

### データ取得
- Pytrendsを利用して、Google Trend APIへアクセスし対象データを抽出
- 検索キーワードと対象エリアをそれぞれリストにして、for文を回す

```py
data = pd.DataFrame()
for kw in kw_list:
    df = pd.DataFrame()
    for area in trg_area:
        pytrends.build_payload([kw], timeframe='2014-01-01 2018-09-30', geo=area)
        df_ = pytrends.interest_over_time()
        df = pd.concat([df, df_], axis=1)
    data = pd.concat([data, df], axis=1)
```
- データフレームを整形します（不要な列の削除、カラム名の修正）

```py
data.drop('isPartial', axis=1, inplace=True)
python = data[kw_list[0]]
JavaScript = data[kw_list[1]]
Java = data[kw_list[2]]
python.columns = trg_area
JavaScript.columns = trg_area
Java.columns = trg_area
```

### データの可視化
- まずはシンプルに各プログラミング言語別に国別の検索状況を可視化する

```py
python.plot(figsize=(15, 3), lw=.7)
plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")
plt.title('Python')

JavaScript.plot(figsize=(15, 3), lw=.7)
plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")
plt.title('JavaScript')

Java.plot(figsize=(15, 3), lw=.7)
plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")
plt.title('Java')
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/76983/4e883194-0aa1-17f2-b1fc-dc8e7cd6339b.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76983/c317bb2a-0276-d075-224c-868c17c4daf5.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76983/dc0936e0-1d5b-1d4f-bdde-cec1a4809b54.png)

### 時系列データ解析（季節成分分解）
- 周期性があり、解釈しづらいので季節成分分解を施して、トレンドのみで比較する

```py
trend = pd.DataFrame()
for i in range(len(trg_area)):
    res = sm.tsa.seasonal_decompose(python.iloc[:,i])
    trend = pd.concat([trend, res.trend], axis=1)
    
trend.plot(figsize=(15, 3), lw=.7)
plt.legend(bbox_to_anchor=(1.04,1), loc="upper left")
plt.title('python')
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/76983/7670e083-b69f-7a15-316f-e989992a6a74.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76983/0cd534fe-f089-f926-8b6c-f7b9fa09b1d8.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/76983/1d6ca2d2-84eb-0f68-ad24-69219ba727c8.png)

### 分析結果の考察
- Pythonは全ての国において上昇トレンドにある
    - ただし、国によって傾きが異なる為、線形回帰をして、傾きを比較する（次分析テーマ）
- JavaScriptは国によってトレンドが大きく異なる
    - ただし、最大でも週で約10ポイントのぶれなので誤差の可能性もある
- Javaは全ての国において下降トレンドにある
    - Pythonと同様に国によって傾きが異なる
    - 日本とシンガポールは下降が緩やかなのに対して、米国や英国は2015年からの急に下降している

### 最後に
- PythonとJavaは国ごとに傾きが異なっている点が面白い発見でした
- 国や文化によって、新たなプログラミング言語への移り変わりが異なるのかもしれません
- この辺りはグローバルのIT業界知識のある方に分析の観点を頂きながら仮説を出していきたいと思います
- 次回は対象国を増やし、Pythonのトレンドの傾きの変化に着目して分析を続けてみます
react-native run-iosが「Print: Entry, ":CFBundleIdentifier", Does Not Exist」でBUILD FAILEDになった時の対処法

昨日からReactNativeを始め、詰まったのでメモがてらQiitaに書いておきます。
# 環境
- macOS: Sierra
- xcode: Version 8.2.1 (8C1002)
- node: v10.12.0
- react-native-cli: 2.0.1
- react-native: 0.57.4

各々調べて書いてましたが、`react-native info`で楽々調べられます。
# エラー詳細
```
>react-native run-ios
---一部抜粋---
** BUILD FAILED **

The following build commands failed:


CompileC /Users/xxxxxxxx/react-native/hello_world/ios/build/Build/Intermediates/React.build/Debug-iphonesimulator/React.build/Objects-normal/x86_64/RCTShadowView+Internal.o Views/RCTShadowView+Internal.m normal x86_64 objective-c com.apple.compilers.llvm.clang.1_0.compiler

(1 failure)


Installing build/Build/Products/Debug-iphonesimulator/hello_world.app

An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=2):

Failed to install the requested application

An application bundle was not found at the provided path.

Provide a valid path to the desired application bundle.

Print: Entry, ":CFBundleIdentifier", Does Not Exist

Command failed: /usr/libexec/PlistBuddy -c Print:CFBundleIdentifier build/Build/Products/Debug-iphonesimulator/hello_world.app/Info.plist

Print: Entry, ":CFBundleIdentifier", Does Not Exist


Error: Command failed: /usr/libexec/PlistBuddy -c Print:CFBundleIdentifier build/Build/Products/Debug-iphonesimulator/hello_world.app/Info.plist

Print: Entry, ":CFBundleIdentifier", Does Not Exist

    at checkExecSyncError (child_process.js:611:11)
    at Object.execFileSync (child_process.js:629:13)
    at Promise.then (/Users/xxxxxxxx/react-native/hello_world/node_modules/react-native/local-cli/runIOS/runIOS.js:208:5)
``` 

# 解決方法
macOSとxcodeをアップグレードしたらいけました。
macOS: `Sierra`→`High Sierra`
xcode: `Version 8.2.1 (8C1002)`→`Version 10.0 (10A255)`

# 見た記事

[React Nativeでinit直後の`Print: Entry, ":CFBundleIdentifier", Does Not Exist`を直した](https://qiita.com/gki/items/ad5bb0af398bfea438ff)
→自分の場合`ios/build/Build/Products/Debug-iphonesimulator/`配下に諸々ファイルが作成されていた。

[React NativeでiOS実行時に"CFBundleIdentifier Does Not Exist"となってしまう場合の対処](https://qiita.com/iwamatsu0430/items/ba3c5d14e4b525c80e23)
→これ試して見ましたが、解決せず・・・

[Can't see iOS 11 simulators in OpenSim #37](https://github.com/luosheng/OpenSim/issues/37)
→これを見て解決にいたりました。`xcrun simctl list devices`でほぼ全端末が`(unavailable, runtime profile not found)`になるのでおかしいなと思って`unavailable, runtime profile not found`で検索してこれに辿りつきました。`xcrun simctl list -j devices`の方が個人的に見やすいと思いました。

# 役に立つコマンド
```
# 利用できるデバイスを確認する
xcrun simctl list devices

# 利用できるデバイスをjson形式で確認する
xcrun simctl list -j devices

# デバイスを指定してシミュレーターを起動する
react-native run-ios --simulator="iPhone X"
```

# 最後に
本質的な問題解決にはなっておりませんが、メモがてら残しておきます。何かツッコミ等ありましたら、コメント頂けますと幸いです:bow:
Python anaconda



anacondaをインストール

```
$ pyenv install anaconda3-5.2.0
```

anacondaのバージョン等を確認

```
$ pyenv versions

* system (set by /Users/   /.pyenv/version)
  anaconda3-5.2.0
```

systemの状態だとanacondaを指定できていない
つまり、もともと入っていたpython2.7 or python3.6 がpythonとpython3に指定されている

ここでanaconda3-5.2.0を以下のコマンドで指定する

```
$ pyenv global anaconda3-5.2.0
```

もう一度バージョン確認すると

```
$ pyenv versions

system
* anaconda3-5.2.0 (set by /Users/   /.pyenv/version)
```

これではpython3系が使われることになっているのでpython2系を使う場合は

```
$ pyenv global system
```

をうてばよい
AWS SDK Golang×SESでのメール送信 using SendBulkTemplatedEmail

# はじめに
AWS SDK GolangとSESで、SESのテンプレートを使いつつ一括メール送信する設定をしたので記録として残しておきます。

# Go×SESでメール送信
まずは以下の記事を参考に、プログラム上で設定したメッセージ文言でメール送信できることを確認しました。
この時点ではテンプレートは使用していません。

[AWS SDKを使ってGolangからSES経由でメールを送る](https://blog.mmmcorp.co.jp/blog/2017/07/28/golang-ses/)

# メールテンプレート対応

SESテンプレートを登録し、メール送信時のSESのAPIとしてsendMailではなくSendBulkTemplatedEmailを呼び出すようにしていきます。

## SESにテンプレート登録
SESテンプレートは[Amazon SES API を使用してパーソナライズされた E メールを送信する](
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-personalized-email-api.html)の手順に従って登録しました。
上記手順に記載されているのと全く同じテンプレートを登録してみました。

## SendTemplateEmailを使うようコードを編集

[SES-APIのドキュメント](https://docs.aws.amazon.com/sdk-for-go/api/service/ses/)を見つつ編集。

```go
package main

import (
	"errors"
	"log"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ses"
)

func main() {
	from := "from@example.jp"
	template := "MyTemplate"
	defaultTemplateData := "{ \"name\":\"\", \"favoriteanimal\":\"\" }"

	// メール送信先
	destinations := []*ses.BulkEmailDestination{
		{
			Destination: &ses.Destination{
				ToAddresses: aws.StringSlice([]string{"to1@example.jp"}),
			},
			ReplacementTemplateData: aws.String("{ \"name\":\"太郎\", \"favoriteanimal\":\"ペンギン\" }"),
		},
		{
			Destination: &ses.Destination{
				ToAddresses: aws.StringSlice([]string{"to2@example.jp"}),
			},
			ReplacementTemplateData: aws.String("{ \"name\":\"次郎\", \"favoriteanimal\":\"あひる\" }"),
		},
	}

	err := SendEmail(from, template, destinations, defaultTemplateData)
	if err != nil {
		log.Println("mail sending error")
	}
	log.Println("mail was sent!")
}

func SendEmail(from string, template string, destinations []*ses.BulkEmailDestination, defaultTemplateData string) error {
	sess := session.Must(session.NewSession())
	svc := ses.New(sess)
	input := &ses.SendBulkTemplatedEmailInput{
		DefaultTemplateData: aws.String(defaultTemplateData),
		Destinations:        destinations,
		Source:              aws.String(from),
		Template:            aws.String(template),
	}
	_, err := svc.SendBulkTemplatedEmail(input)
	if err != nil {
		return errors.New(err.Error())
	}
	return nil
}
```

これでテンプレートを使ってメール送信できました。

このコードでは送付先のアドレスやテンプレート内で動的に変える値を直接記述していますが、実際には”// メール送信先”とコメントを入れているあたりで、DBから取得した値をそれぞれに設定することになるイメージです。

# However
テンプレートの日本語記載がメールにおいて文字化けする、という問題が未解決なので、解決したら追記します。
リモートワークに対する見解と避けるべき行為_第二篇



[現場でリモートワークを実践する方向けの「リモートワークで避けたいこと 2 つ」
](https://qiita.com/ymatsukawa/items/37836b905c94c0eee3d4)

から約 1 年半、もう少し実務に寄せられないかと思い、書く。上の記事を第一篇としておく。

# 私なりのリモートワークに対する見解

リモートワークをすると「自由になれる」「柔軟性を持たせられる」と思っていないだろうか。

具体的に「何が自由になる」だろうか。

具体的に「何に柔軟性を持たせられる」だろうか。

私が思うに **「働く場所の制約」がゆるくなるだけ** だと思っている。

ただそれだけ。

**「仕事をする概念がガラリと変わった」なんて誰も言ってない。**

(ここには書ききれないので省くが、むしろシビアに「仕事っぷり」を見られる)

こういう思惑の上で、リモートワークで避けるべき行為を挙げようと思う。

# リモートワークで避けるべき行為

## 1. 文章だけでやり取りする

文章は **伝達手段の一つ** であることを思い出そう。

伝達手段は他にも、テレビ会議・音声通話、言うなれば電話もある。

**文章伝達が「上手くいっていない」 と思った時点で切替えるべきだ。**

----

よくあるチャット風景を見てみよう。

```
Mr.Z [13:38]
@you
先日の定例で A 様から頂いた要望を元に、仕様パターンを洗い出しました。
問い合わせ必要だと思う箇所があるので、
今日の 15:00 までに見てほしいです。
http://example.com/issue/1000

you [13:39]
確認します。

you [14:02]
@Mr.Z
コメントに回答しました。
先方と認識(意図)がずれていると思います。
回答含め、いくつか質問したので確認お願いしたいです。
http://example.com/issue/1000/comment/1

Mr.Z [14:21]
@you
確認しました。すみません、質問 B の件ですが「...」という解釈で良いでしょうか

you [14:30]
「解釈的」には正しいんですが。。
うーん。。
```

1時間のやりとりが発生し、さらに伸びそう。「まずい」と思うべきだ。

言うなれば `you` は `14:02` 時点で伝達手段を切り替えた方が良い。

```
you [14:02]
@Mr.Z
コメントに回答しました。
先方と認識(意図)がずれてるかもしれないです。
回答含め、いくつか質問したので確認お願いしたいです。
http://example.com/issue/1000/comment/1

↓

you [14:02]
@Mr.Z
テレビ会議ですり合わせしたいです。ご都合よいタイミングで。

先方と認識(意図)がずれてるかもしれないです。
コメントにひとまず回答と質問をしました。
http://example.com/issue/1000/comment/1
```

## 2. リモートを言い訳に何かと「出来ないのでは」と考えている

あなたがリモート開発で特別に与えられたのは **「場所」だけ。**

逆を言えば、**「場所以外に制約・影響を受けない」と他の人から思われている。**

こういう自覚がないと現実的な話、きちんと仕事できるのか、と思われてしまう。

結果を出せているかどうか => 否、という観点から、具体的な例を挙げてみる。

### 言い訳1. どうやって進めれば良いか分からなくなったどうしよう

**Ans. リモート先を巻き込め**

「俺詰まってます。。まずいっす。。」を発信することからだ。

リモートワークだからって、自分だけで解決しろと誰が言った？

### 言い訳2. 今日予定のタスク終わったけど、開発メンバーに報告してよいものか

**Ans. なんでもいいから、 報連相しろ**

チャット・メール・電話、他に手段は使っただろうか。

リモートワークだからって、報連相しなくて良いと誰が言った？

### 言い訳3. 設計をしてみたけど、合意形成しなくてよいものか

**Ans. なんでもいいから、合意形成や確認をしろ**

チャット・メール・電話、他に手段は使っただろうか。

リモートワークだからって、確認を取らなくて良いと誰が言った？

### 言い訳4. リモート先が忙しいかもしれない から、相談しづらい

**Ans. 聞け。聞けることに憶測を立てるな**

憶測で仕事をして良いと誰が言った？

リモートワークだからって、人の忙しさを汲み取れるエスパーになれと誰が言った？

## 3. リモートワークが閉塞環境にあることに気づいていない

管理者向けへの話。

(管理者 = プロジェクトリーダーのような、進捗を管理しつつ、開発者をサポートする立場の人 を想定する)

### リモートワークは閉塞環境にある

「同じゴールに向かっている人間が『その場』に一人」

「連絡を取り合う場所がチャットスペース」

開放的と言えるだろうか。むしろ閉塞だろう。

そのせいか、**開発者の思考は自分の中だけで回り始める。閉塞は自己判断を生みやすい。**

なので管理者は **「リモートワークには閉塞が発生する」ことを認知した上で、対策を講じる** 必要がある。

ニッチなことはやめておき、どの現場でも必要だろうと思うことを挙げておく。

* **定常的に結果を出せているかを見る**
  * 閉じられた環境で、人は自分で完結する傾向がある
  * => WIP でもソース差分のプルリクエストを日次的に依頼する
  * => 仕様書の改訂はドラフト版でもレビュー依頼する
* **手詰まりを起こしていないかを知る**
  * 閉じられた環境で、人は自分が正常なのか異常なのか判断がつかなくなる
  * => 15分以上手詰まりを起こしたら「アラート」として上げてもらう
  * => チャットなら管理者だけ、取り決めたら開発者全員にでもいい
* **支援してくれる人への橋渡しをしてあげる**
  * 閉じられた環境で、人は目の前のことで手一杯になる
  * 管理者が全体を見て誰が何をできるか、できたか、把握する
  * => 管理者が他の開発者へ代わりに発信受信し、開発者間の情報橋渡しをする

# 最後に

繰り返しになりますが、私個人の見解では

リモートワークで得られるものすなわち **「働く場所の制約」がゆるくなることだけ** です。

## ところで、あなた何者

地方SI企業で 5年近くリモートワークをやっている者です。リモートワーク以外の経験も勿論あり(１年ぐらい)

それ以外は語ることはありません。

## 冒頭の見解について他に書く予定はあるか

書こうと思いますが、未定。気が向いたら。
gitについて

#はじめに
会社でGitlabを使っていましたが、自分がしっかり理解をしていないまま"pull"や"push"をしていましたが、さすがに理解しないとまずいということでメモ代わりにQiitaに掲載します。
対象は僕のメモ書きが参考になる人です。(；一_一)
↓とりあえず言語理解しよう....超簡単に説明していますのでちゃんと知りたいひとはggr

#参考資料

https://tracpath.com/bootcamp/learning_git_firststep.html

#gitとは
難しくいうと、分散型バージョン管理システム。
簡単にいうと、バージョン管理システム（マルチ用）

#作業フロー
リポジトリをクローンを作成しプルしてマージ、コミットしてプッシュする。
(スタバの注文かよ....)
でもこれを読んだらわかるようになります。

#repository(リポジトリ)
リポジトリ＝共同ファイル
ローカルリポジトリとリモートリポジトリの二つがあります。
ローカルリポジトリ＝自分のＰＣに作成したファイル=共有リポジトリ
リモートリポジトリ＝離れたところにあるファイル
![7353_01_s.gif](https://qiita-image-store.s3.amazonaws.com/0/263673/208315a1-52e1-840b-4d5c-e3774ed66aff.gif)

#clone(クローン)
クローン＝コピー
リモートリポジトリをコピーしてもの＝ローカルリポジトリ

#commit(コミット)
新規作成したファイルや編集したファイルをリモートリポジトリに保存することを意味します。

#push(プッシュ)
共有リポジトリに編集したファイルを反映させることを意味します。

#pull(プル)
他のメンバーが追加した機能や修正したファイルを自分の作業ディレクトリに取り込むことを意味します。

#merge(マージ)
プルしたデータが統合されることを意味します。

#余談
###merge request(マージ　リクエスト)
pushした時無言でやるとコンフリクトを起こしてしまう為、"マージしてください"とお願いすることを意味します。

###conflict(コンフリクト)
1つのファイルを別々のユーザーが編集した後、マージを行うと発生する競合をコンフリクトという。
どっちの編集を優先した方がいいのかわからなくなってしまうのでコンフリクトという形で報告してくれます。（優秀ですね.....）




========================================================
こんな形で自分メモをしていきます。
編集、変更については、
間違いに自分で気づいたときや他のユーザーが指摘した（自分が納得、理解した時のみ）場合に行います。
[書籍感想]エンジニアリング組織論への招待

[エンジニアリング組織論への招待](https://gihyo.jp/book/2018/978-4-7741-9605-3) を読んだ感想です。

これまではアジャイルな体制や開発の実務経験がなく、ブログ等で方法論を読んでどのようにして実際に運用すればよいのかイメージできませんでした。「不確実性のマネージメント」、「不安に向き合う」という考え方からアジャイルがやりたい事が分かった気がします。

## 考え方の転換を迫られる Chapter1 思考のリファクタリング

頭から読み進めた時に、書籍のタイトルから推測した書きたいことが詰められていると感じた内容でした。開発を円滑に進めるために日々悩んでいる事に具体的な回答はないものの、自分のとらえ方を見直す機会にります。

最後のカレー作りの寓話は あるある 過ぎでした。

> パーティに来るみんなのためにカレーを作りましょう。そう言って、ボブとエバは2人でカレーを作り始めた。
ボブは「どんなカレーにするかは僕が決める。カレーの代金は僕が出すから。エバは料理が得意だから僕が支持するようにカレーを作ってくれよ」と言った。
エバは了解し、材料とレシピを来るのを待った。
ボブはどんなカレーにするか悩んだ。料理が得意ではないのでレシピを書くのに時間がかかった。
エバは、とりあえずライスは必要だろうと考え、お米を炊き始めた。そして、ボブがようやく書き上げたレシピを見て、こう言った。「このレシピは正確じゃない。香辛料の分量を決めてもらわないとカレーはできないわ」
ボブは香辛料の分量がどんな味になるのかわからなかったが、パーティーは近いので「適当に決めてくれよ」と言い捨てた。
しばらくして、ボブはパーティーの客から「ライスはターメリックライスじゃないと嫌だ」と言われたことを思い出した。
そしてエバに「ライスはターメリックライスにしてくれ」と頼んだ。エバは「もうライスは炊いてしまった。ターメリックライスにするならもっと早く言ってよ」と怒り始めた。
ボブは「ターメリックライスじゃないとダメだ」といった。
エバはライスの炊きなおしになるが、仕方なくボブの提案を受けれた。
パーティー目前になってもライスは炊けない。それにカレーはターメリックライスよりも白ご飯に合うように作ったから、味のバランスもめちゃくちゃだ。
それを知ってボブは激怒し、「パーティに間に合わなければ、カレーを作る意味がないじゃないか！それでも料理人なのか！」と言い捨てた。
エバはその言葉に怒りを覚えて、「あなたがターメリックライスにしろって言い出したり、レシピを作るのが遅かったから遅れたの」と抗弁した。
味の整っていないカレーと雰囲気の悪くなった2人を見て、パーティは興ざめに終わった。

仕様を出してくれない発注者と、納期は不変なので見切りで開発に着手せざるを得ない開発者。お互いに悪気はなく、自分の責任範囲を全うして良かれと思ったが、望まない結果になってしまう辛い結果です。もう半歩相手側に寄り、状況を伺うだけで改善できると思ったり、思わなかったりします。

## 伝え方を何とかしたい Chapter2 メンタリングの技術

伝言ゲームで例えられるように、伝わる情報に介在する人が多い程に不正確になり少しずつ内容が変化していきます。それは1対1の場合でも話し手の言いたいことは半分程度しか伝わりません。しかし、発信者の心がけで改善できるものと信じています。

話し手が意図していることが伝わないのは、本書でもなどか出てくる「情報の非対称性」があり、話し手が理解していることと聞き手が理解している程度が違うので、それを無視して話し手が話したいことを話してしまうと、聞き手には全然伝わりません。「氷山の一角」に例えると、話し手が話したいことは海面から出ている部分だけど、それを理解する前提として海中に巨大な氷があります。互いに海中の氷に気づいていないので、沈没事故を起こしてしまいます。

## カレー作りを成功させたい Chapte3 アジャイルなチームの原理

アジャイルの考え方を理解できた(と思われる)「不確実性」が出てきました。

受託開発を行っている立場としては、案件が開始された時点でお客様とは立場の違いから抱えている「不確実性」がずれています。

- お客様は開発したものがエンドユーザに受け入れられられるか分からない「目的不確実性」
- 開発者はスケジュール通りに進行するのかが分からない「方法不確実性」

ウォーターフォールは「方法不確実性」と「要件定義」という言葉で「目的不確実性」を半分だけ対処します。半分だけなのは、要件定義でエンドユーザに受け入れられる内容を検討するものの、結果がフィードバックされるまでの時間がアジャイルと比較して長いためだと理解しました。

アジャイルでは、「目的不確実性」と「方法不確実性」に加えて、正しく伝わっていないかもしれない「通信不確実性」に対処しながらプロジェクトを進めていきます。

これまでアジャイルの記事を読んでも自分の中に「すとん」と落ちなかったのは、方法が書かれたものばかりを読んでいたために、その背景にある考え方にまで至らず、モヤモヤした状態が続き開発を進めるイメージをつかめませんでした。

## プロジェクトの進め方 Chapter4 学習するチームと不確実性マネージメント

見積を行うときには不安の量を「バッファ」として計上しています。一つ一つの作業でみればそれ程ではないものの、全体として積み上げると過大と感じることもあります。

気がかりではありつつもバッファの妥当性を検証することがありませんでした。「予定と実績の管理」と考えると及び腰になりがちであり、早く終わることに越したことはからでした。それでは「方法不確実性」と向かっていないので、方法に関心しつつも、耳が痛い内容でした。

## 考え方を組織に適用する Chapter5 技術組織の力学とアーキテクチャ

リリースを積み上げていくと、その時のやむを得ない事情などで技術的負債が積みあがってしまいます。技術的負債が積みあがると属人的になりがちだし、負債を返済するための期間を確保するのも大変です。これまでは感覚だけで大変さや必要性を説明してもなかなか理解してもらえず、技術的負債を数値化するのは気づきませんした。

組織に適用するには再現性や客観性が大事ですからね。

論文はこれかな。 [Technical Debt: From Metaphor to Theory and Practice](https://ieeexplore.ieee.org/document/6336722)　[後で読む]
【入門】RSpec on Ruby on Rails

### RSpecとは

###参考リンク
[Rails RSpecの導入](https://qiita.com/shizuma/items/8221544601aa3d0770d2)
[基本的な構文・機能のまとめ](https://qiita.com/jnchito/items/42193d066bd61c740612)
[Ruby on Rails、RSpecを使ってコントローラのテストを書いてみる(アウトラインを書く)](https://blog.naichilab.com/entry/2016/01/19/011514#%E3%82%A2%E3%82%A6%E3%83%88%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%92%E6%9B%B8%E3%81%8F)
[subject/expectの使い方](https://qiita.com/mm36/items/453d71d48dd8f462344c)
[Rspecの悪い/良い書き方](https://qiita.com/isuke/items/c98f76892d4fec2ac8bf)
[swift備忘録]Xcodeのプロジェクトファイルで、異なるswiftのバージョンを使う。

Xcodeアップデート時、cocoapodなどが最新のswiftバージョンに対応しておらず、エラーとなる時があります。
そんな時に、その部分のターゲットのみ、コンパイラのswiftバージョンを変える方法。

1.　バージョンを変えたいターゲットを選択。
2.　 Build Settings > Swift Language Versionへ移動
3.　 デフォルトはXcodeのバージョンに対応した最新のswiftバージョンになっています。(今回はSwift4.2)
 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/95908/3e7890c9-4b74-da3f-52d0-6d9a834e345f.png)

4.　 ここをcocoapodsに対応したバージョンに変える。(今回はSwift4.0に変更。)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95908/3ce4f801-429a-04a1-930c-b3b0e7867a21.png)


以上です！簡単に対応する事ができました！
はじめに_「すごいErlangゆかいに学ぼう！」_#01

# この記事の概要
Erlangの書籍「すごいErlangゆかいに学ぼう！」の勉強メモです
Mac向けです

# インストール
brewを入れている場合

```bash
$ brew install erlang
```

.bash_profileに次を追記

```
export PATH=$PATH:/usr/local/erlang/bin
export Erlang_HOME=/usr/local/erlang
```

# シェル立ち上げと終了
インストール後

```bash
$ erl
```

閉じるのは Control + G のあと、q

# ヘルプ
listsモジュールのヘルプ

```bash
$ erl -man lists
```



四則計算など

```erlang
%% 加算
1 + 1. %% => 2
%% 減算
1 - 1. %% => 0
%% 乗算
3 * 4. %% => 12
%% 割算
4 / 3. %% => 1.3333333333333333
%% 割算
4 div 3. %% => 1
%% 剰余
5 rem 3. %% => 2

%% 計算の優先順位
(100 + 121) * 1000. %% => 221000

%% 進数
2#01010101101. %% => 685
```
Javascriptで配列・オブジェクトの配列のソート


よく使うのでメモ。JavascriptのバージョンはES2015。
次のような配列やオブジェクトの配列（連想配列の配列）があった場合、

```javascript
//普通の配列
var array = [5,3,7];

//オブジェクトの配列
var objArray = [
    {'name':'apple','price':300},
    {'name':'orange','price':200},
    {'name':'banana','price':100}
];
```


#1　配列のソート
###関数
```javascript
/**
* @function Array.prototype.sortArray　配列をソートする
*/
if(!Array.prototype.sortArray){
    Object.defineProperty(Array.prototype, 'sortArray', {
        configurable: false,
        enumerable: false,
        writable: false,
        /**
        * @string order ソートの順序 ('asc' or 'desc')
        */
        value: function(order) {
            switch(order){
                case 'asc':  //昇順
                    this.sort((a,b) => a-b);
                    break;
                case 'desc':  //降順
                    this.sort((a,b) => b-a);
                    break;
                default:  //昇順・降順の指定がない場合は降順でソート
                    this.sort((a,b) => b-a);
                    break;
            }
            return this;
        }
    });
}
```

###処理→出力
```javascript
var array = [5,3,7];

console.log(array.sortArray('desc')); //降順でソート
```

###結果
```javascript
[ 7, 5, 3 ]
```


#2　オブジェクトの配列のソート
###関数
キーから値を取得し、バリデーションを追加しただけで、基本的に配列のソートと同じ。

```javascript
/**
* @function Array.prototype.sortObjArray　オブジェクトの配列をソートする
*/
if(!Array.prototype.sortObjArray){
    Object.defineProperty(Array.prototype, 'sortObjArray', {
        configurable: false,
        enumerable: false,
        writable: false,
        /**
        * @string key ソートに用いるオブジェクトのキー
        * @string order　ソートの順序 ('asc' or 'desc')
        */
        value: function(key,order) {
            //オブジェクトの配列であるか確認
            if(Object.prototype.toString.call(this[0])!=='[object Object]'){
                console.log('TypeError: Other than an array of object was passed.');
                return false;
            }
            switch(order){
                case 'asc':  //昇順
                    this.sort((a,b) => a[key]-b[key]);
                    break;
                case 'desc':  //降順
                    this.sort((a,b) => b[key]-a[key]);
                    break;
                default:  //昇順・降順の指定がない場合は降順でソート
                    this.sort((a,b) => b[key]-a[key]);
                    break;
            }
            return this;
        }
    });
}
```

###処理→出力
```javascript
var objArray = [
    {'name':'apple','price':300},
    {'name':'orange','price':200},
    {'name':'banana','price':100}
];

console.log(objArray.sortObjArray('price','asc')); //昇順でソート
```

###結果
```javascript
[ { name: 'banana', price: 100 },
  { name: 'orange', price: 200 },
  { name: 'apple', price: 300 } ]
```
プログラマ向けポータブルソフトのまとめ

NAVERにまとめた。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">プログラマ向けポータブルソフトのまとめ - NAVER まとめ <a href="https://t.co/e6HIMQO3aT">https://t.co/e6HIMQO3aT</a></p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1056412167535120384?ref_src=twsrc%5Etfw">2018年10月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
rails test やrails db:migrate:resetが上手くできない時の解決策。

#問題
`rails test`をすると`bin/rails db:migrate RAILS_ENV=test`が表示されたので、指示通りコンソールに打つとすると今度は`development.sqlite3`が使えなくなった。

`development.sqlite3`と`test.sqlite3`をうまく共存？させる方法を探してみた。

#解決までの流れ
上手くmigrationが出来なかったのかなと思い`rails db:migration:resetをやってみるも

```
$ rails db:migrate:reset
Couldn't drop database 'db/development.sqlite3'
rails aborted!
Errno::EACCES: Permission denied @ unlink_internal - C:/Users/siron/siro_app/db/development.sqlite3
bin/rails:4:in `<main>'
Tasks: TOP => db:drop:_unsafe
(See full trace by running task with --trace)
```

上手くdropができなかったみたいなのでunsafeな方法であるが強制的にdropしてみる。


```
$ rails db:drop:_unsafe
```

上手くdrop出来たので次に`database.yml`の内容でデータベースを作成していつも通りmigrationをする。

```
$ rails db:create:all

$ rails db:migrate 
```

この流れでdevelopment.sqlite3が有効になるが

```
$ rails t
```
と入力すると

```
Migrations are pending. To resolve this issue, run:
bin/rails db:migrate RAILS_ENV=test
```

相変わらずこのような表示が出てくるのでtest.sqlite3は有効化されていないらしい。
なので表示通りにtest.sqlite3もmigrationする

```
$ rails db:migrate RAILS_ENV=test
== 20181027102656 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0042s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0332s
== 20181027102656 CreateUsers: migrated (0.0385s) =============================

== 20181028035604 AddPasswordDigestToUsers: migrating =========================
-- add_column(:users, :password_digest, :string)
   -> 0.0075s
== 20181028035604 AddPasswordDigestToUsers: migrated (0.0177s) ================
```

この一連の流れでmigrationしたらdevelopment.sqlite3とtest.sqlite3どちらも有効化され、データ作成・テスト共にうまくいった。

#お願い
当方プログラミング初心者な為、この記事を見て違和感を感じる表現や間違った解決方法がありましたらご指摘願いたいです。


#参考にした記事
https://qiita.com/parsetree/items/e9b08c6b11f762b949de
enebular の InfoType を ES2015 で書く

InfoType の作成にチャレンジしようと、下記ドキュメントを参考に、`infomotion-tool` を実行してみました。

- Creating an InfoType<br>
  https://docs.enebular.com/ja/infomotion/infomotiontool

# ES5 のテンプレート
出力された `plugin.js` には、下記のような、古き良き prototype を使用したクラス宣言が書かれています。

```js:plugin.js
function DataLogger(settings, options) {
  :
}
DataLogger.prototype.addData = function(data) {
  :
}

DataLogger.prototype.render = function() {
  :
}

DataLogger.prototype.clearData = function() {
  :
}

DataLogger.prototype.resize = function(options) {
  :
}

DataLogger.prototype.getEl = function() {
  :
}

/*
 * Register to use in infomotion
**/
EnebularIntelligence.register('Data-Logger', DataLogger);

module.exports = DataLogger;
```

それぞれのメソッドの意味は、下記公式 API リファレンスを。

- API Reference<br>
  https://docs.enebular.com/ja/infomotion/APIReference.html

# ES2015 のテンプレート

長いものには巻かれる派なので、これを ES2015 のクラス構文に直しました。
必要なメソッドは決まっているので、そう難しくはないですね。

```js:plugin.js
export default class DataLogger {
  constructor(settings, options) {
    :
  }
  addData(data) {
    :
  }

  clearData() {
    :
  }

  resize(options) {
    :
  }

  getEl() {
    :
  }
}

/*
 * Register to use in infomotion
**/
EnebularIntelligence.register('Data-Logger', DataLogger);
```

しかし、上の ES2015 構文のままだと `eit package` コマンドが通りません。

```sh:パッケージング失敗
$ eit package .

${plugin_dir}/plugin.js
export default class DataLogger {
^
ParseError: 'import' and 'export' may appear only with 'sourceType: module'
```

なので、babel でトランスパイルします。

# Babel の導入
まず必要なツールをインストールします。

```sh:babelの導入
$ npm i @babel/core @babel/cli @babel/preset-env --save-dev
```

.babelrc も作ります。

```json:.babelrc
{
  "presets": ["@babel/preset-env"]
}
```

`plugin.js` という名称のファイルは、`eit package` の実行時に ES5 構文で書いてある必要があります、
なので、ES2015 構文のファイルを `plugin.es` にリネームし、以降はこの `plugin.es` を編集します。

```sh:
mv plugin.js plugin.es
```

結果、ファイル構成はこのようになります。

```sh:ファイル構成
$ tree -a --dirsfirst -L 1
${plugin_dir}
├── node_modules
├── .babelrc
├── datasource.json
├── package.json
├── package-lock.json
├── plugin.css
├── plugin.es
├── plugin.json
└── README.md
```

babel によるトランスパイルと `eit` のパッケージングをまとめてやってしまいたいので、npm で実行するスクリプトに下記のコマンドを追記します。

```json:package.json/scripts
  "scripts": {
    "build": "babel plugin.es -o plugin.js && eit package .",
    :
  },
```

今後は、`plugin.es` を編集したら、トランスパイルとパッケージングを `npm run build` で一気に実行できます。

# おまけ
ちなみに、`eit create` 実行時にテンプレートを指定した際に記載される `d3` の require  は、import 構文に置き換えられます。

```js:require_d3
var d3 = require('d3');
```

```js:Import_d3
import * as d3 from 'd3';
```

それでは、よき enebular & ES201x ライフを。
テンキーを有効活用しよう - Dresskeyのすすめ

## 前置き

皆さん、テンキーって使っていますか？

会社からA4ワイドのテンキー付きノートパソコンを支給されるも、自分を含め皆テンキーは使用していませんでした。

- キーボードの上の方にも数字キーあるのにわざわざテンキーまで指運ぶのはめんどくさい。
- NumLockで数字入力とカーソル入力のどちらかに動作が変わるので、いまがどっちのモードなのか分からん。
　（だいたい期待しているモードじゃない方。）

この無用の長物なのに結構な場所をとっている憎いあンちくしょうを有効活用してやろうじゃないか、
というのが今回の趣旨になります。


## Dresskeyとは

テンキーに他のキーを割り当てることができるWindows用のツールです。

配布元などはこちら。
http://ahk.wktk.so/

*AutoHotkeyみたいなもの？*
-> はい。

- AutoHotkeyとのざっくりと違いは次の通りです。
    - 設定がGUIで簡単にできること。
    - テンキー専用であること。
    - NumLockのON/OFFどちらでも同じ動作をする。（一部のキーはダメなようです。私は0キーがどちらかの状態でしか動作しませんでした。）

*AutoHotkeyでいいじゃん。*
-> はい。AutoHotkeyを既に使っている方には必要ないと思います。

というもの、Dresskeyは実はAutoHotKeyを使いやすいようにラッピングしたソフトのため、実体はAutoHotKeyです。
AutoHotKeyの、自分で設定ファイル作成してスクリプト書いてあげないと起動さえできなかったり、キーの割り当てを調べたりするメンドくささを、もっと簡単にしようとした親切なものがDresskeyです。

AutoHotKeyを利用したことのない人に気軽におすすめできるものです。


## Dresskeyの使い方

1. 配布元のダウンロードページからzipファイルをダウンロードして、展開ください。
2. Dresskey.exeを実行するとタスクバーに常駐するので、アイコンをクリックして設定画面を表示してください。
（プログラムを実行したのにヘルプが表示されるというややこしいことはありません！）
3. 設定画面にはテンキーのキーごとの入力欄がありますので、割り当てたいキーにキー設定を入力してください。
   キー設定の記述方法はAutoHotKeyと同じです。
4. 設定ができたら「セーブ」してください。設定画面が閉じて設定が有効になります。
5. Dresskeyを気に入ったら、Windowsのスタートアップに設定して自動で起動されるようにしてください。


## おすすめのキー設定

キー設定の記述方法はAutoHotKeyのため、ちょっとわかりにくいです。
おすすめのキー設定を記述しますのでコピペしてください。

### タスクバーにピン止めしたプログラムを起動or最小化と復帰
`#1` `#2` `#3` `#4` `#5` `#6` `#7` `#8` `#9` `#0`
Windowsキー + 数字キー の組み合わせでタスクバーにピン止めしたプログラムを起動できます。
数字キーはタスクバーのアイコンの左から順に1～0を指定します。
私は1にテキストエディタ、2にエクスプローラ、3にメーラークライアントを並べて、必要な時にサクッと起動/すぐに最小化できるようにしています。


### 仮想デスクトップの切り替え
`^#{Right}`
`^#{Left}`

Ctrlキー + Windowsキー + 右矢印 or 左矢印キーで、Windows10の仮想デスクトップを切り替えできます。


### マウスホイール
`WheelUp`
`WheelDown`

ページのスクロールをキー操作でも。
私は極力マウスに手を伸ばすのが面倒なので、だいぶ楽になります。
PageUpキーやPageDownキーだと移動量が多く、矢印キーだと移動量が少ないんですよね。


## 最後に

私はDresskeyの関係者ではなく、単にDresskeyに助けられた一人です。

なお私はしばらくDresskeyを使用した後、変換キーとかひらがな/カタカナキーとかもいじりたいという欲が湧いてきたために今ではAutoHotKeyに切り替えています。
WSL Ubuntuにてプロキシ越しのapt-getに失敗した場合

# 問題
会社PCにてWSLよりapt-getした際に失敗する


# 解決方法
## apt設定ファイルに記載する
$ sudo vi /etc/apt/apt.conf
※ ファイルが無い場合は作成して記載すれば良い

## /etc/apt/apt.confに記載する内容

Acquire::ftp::proxy "ftp://192.168.0.1:8080/";
Acquire::http::proxy "http://192.168.0.1:8080/";
Acquire::https::proxy "https://192.168.0.1:8080/";

# 結果
OK！

$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Get:2 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB]
Get:3 http://archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
Get:4 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages [187 kB]
Get:5 http://archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
Get:6 http://security.ubuntu.com/ubuntu bionic-security/main Translation-en [72.7 kB]
.......
Androidで(Excel)グラフを作成

#入力
![s3.JPG](https://qiita-image-store.s3.amazonaws.com/0/296847/d4ae421a-43d6-a40e-e2d6-cab08b12a10f.jpeg)

#結果

![グラフ効果図.gif](https://qiita-image-store.s3.amazonaws.com/0/296847/bc654dc1-e301-7ce5-022c-ffd59a2bdaf7.gif)


#取り込み方法

###下記のPKGをそのまま取り込む
package com.yanheng.drawgraph.graph

### xmlをに追加
※：今回はボタンを押下したら描画開始するイメージです。

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="グラフ生成する"
        android:layout_margin="30dp"
        />

    <com.yanheng.drawgraph.graph.DrawViewDemo
        android:id="@+id/draw_view"
        android:layout_margin="50dp"
        android:layout_width="300dp"
        android:layout_height="200dp"
        android:background="#2260A8FF"
        />

###ボタン押下後処理

    private void setGraph() {
        createSettingData();
        createGraphData();
        DrawViewDemo drawViewDemo = (DrawViewDemo) findViewById(R.id.draw_view);
        drawViewDemo.setGraphSettingData(graphSettingData);
        drawViewDemo.setGraph1(graphMail);
        drawViewDemo.setGraph2(graphFemail);
        drawViewDemo.invalidate();
    }

* X軸、Y軸の設定

        private void createSettingData() {
        graphSettingData = new GraphSettingData();
        graphSettingData.title = "身長グラフ";
        graphSettingData.graphNmae1="男の子";
        graphSettingData.graphNmae2="女の子";

        graphSettingData.axisDataX.maxScale = 18f;
        graphSettingData.axisDataX.minScale = 10f;
        graphSettingData.axisDataX.scaleValue = 1f;
        graphSettingData.axisDataX.scaleTitle = "年齢(歳)";

        graphSettingData.axisDataY.maxScale = 180f;
        graphSettingData.axisDataY.minScale = 120f;
        graphSettingData.axisDataY.scaleValue = 10f;
        graphSettingData.axisDataY.scaleTitle = "身長(cm)";
        }

* グラフ評価の設定上記データを使用する

        private void createGraphData(){
        graphMail.put(10f, 138.9f);
        graphMail.put(11f, 145f);
        graphMail.put(12f, 152.4f);
        graphMail.put(13f, 159.5f);
        graphMail.put(14f, 165.1f);
        graphMail.put(15f, 168.4f);
        graphMail.put(16f, 169.8f);
        graphMail.put(17f, 170.7f);

        graphFemail.put(10f, 140.1f);
        graphFemail.put(11f, 146.7f);
        graphFemail.put(12f, 151.9f);
        graphFemail.put(13f, 155f);
        graphFemail.put(14f, 156.5f);
        graphFemail.put(15f, 157.2f);
        graphFemail.put(16f, 157.6f);
        graphFemail.put(17f, 158f);
        }

* 描画更新

        drawViewDemo.invalidate();


#[ソースコード](https://github.com/YanHengGo/android/tree/master/02_drawGraph) いいねも忘れずに
JSONのインターフェイスをWebで自動生成する

![ダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/244632/1f39f366-d7b0-ae84-e0c3-ee319e92f0f1.png)
メモ書き的ななにか。

quicktypeというWebアプリにJSONを食わせると、様々な言語のインターフェイスを自動生成してくれるのでおすすめです。
画像は[最寄り駅クソAPI](https://github.com/TinyKitten/StationAPI)のレスポンスデータを食わせた奴。

[https://app.quicktype.io/](https://app.quicktype.io/)