OmniAICreator/Qiita-1.07M huggingface dataset:
Spring BatchでIn-MemoryのJobリポジトリを利用する方法

Spring Batchは、デフォルトでDBベースのJobリポジトリを利用するため、勝手にJob管理用のテーブルが作られます。テーブルのCreate権限がないDBユーザの場合やパフォーマンスが気になる場合、In-Memory Jobリポジトリを利用することが可能です。
但し、In-MemoryのJobリポジトリの場合、再起動などの機能が利用できなくなりますので、使うかどうかは非機能要件次第になります。
>
Note that the in-memory repository is volatile and so does not allow restart between JVM instances. It also cannot guarantee that two job instances with the same parameters are launched simultaneously, and is not suitable for use in a multi-threaded Job, or a locally partitioned Step. So use the database version of the repository wherever you need those features.



##解決方法１
一番簡単な解決方法は、DataSourceのAutoConfigを使用しないことです。

```java
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args).close();
	}
}
```
[Spring Batch 3.0.8.RLEASE API](http://https://docs.spring.io/spring-batch/trunk/apidocs/) Annotation Type EnableBatchProcessingの説明
>
If a user does not provide a DataSource within the context, a Map based JobRepository will be used. 


##解決方法２
DataSourceがAutoConfigの場合でも、JobRepository、JobExplorer、JobLauncherをOverrideすることで、MapベースのJobRepositoryを利用することが可能です。

```java

@Configuration
@EnableBatchProcessing
public class BatchConfig {

	......
    
	/**
	 * in-memoryジョブリポジトリを使用する
	 * 
	 * @return
	 */
	@Bean
	DefaultBatchConfigurer batchConfigurer() {
		return new DefaultBatchConfigurer() {
			
			private JobRepository jobRepository;
			private JobExplorer jobExplorer;
			private JobLauncher jobLauncher;

			{
				MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean();
				try {
					this.jobRepository = jobRepositoryFactory.getObject();
					MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(jobRepositoryFactory);
					this.jobExplorer = jobExplorerFactory.getObject();
					SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
					jobLauncher.setJobRepository(jobRepository);
					jobLauncher.afterPropertiesSet();
					this.jobLauncher = jobLauncher;
					
				} catch (Exception e) {
				}
			}

			@Override
			public JobRepository getJobRepository() {
				return jobRepository;
			}

			@Override
			public JobExplorer getJobExplorer() {
				return jobExplorer;
			}

			@Override
			public JobLauncher getJobLauncher() {
				return jobLauncher;
			}
		};
	}
}
```

メタデータテーブルを生成させないために、`application.properties`を以下のように改修する。

```application.properties
spring.batch.initializer.enabled=false
```

参考資料：
https://blog.ik.am/entries/409
https://qiita.com/blackawa/items/e9eaa254cbe27e257e10
コンテナ脆弱性スキャナClairのクライアント (2017年11月)

KubeCon + CloudNativeCon North America 2017が近づいてきて楽しみですね。

[CloudNativeCon/KubeCon NA 2016](https://www.cncf.io/blog/2016/11/17/cloudnativeconkubecon-2016-wrap/)まではCNCon + KubeConだったのですが、今年春のKubeCon + CNCon EU 2017から順序が逆転しましたね。そんなわけで、Kubernetes以外のコンテナの様子が気になるわけです。

Kubernetes上で実行するコンテナの脆弱性スキャナとしても利用できるClairについて、質問に答える機会があったので、メモしておきます。

## Clair (coreos/clair)

![Clair Logo](https://cloud.githubusercontent.com/assets/343539/21630811/c5081e5c-d202-11e6-92eb-919d5999c77a.png)

Core OSが開発・公開しているコンテナ（イメージ）の脆弱性静的分析ツールのOSS(Apache 2.0 License)でGitHubレポジトリは https://github.com/coreos/clair です。最新版は2.0.1です。

CoreOS(現Core OS Container Linux)に惚れ込んでいた頃、[Docker Meetup Tokyo #6](https://qiita.com/f_nishio/items/cf227a1b1abf63c6a16e)で一緒に登壇していた@spesnovaさんがClairについて話していた記憶があります。

最近だと、行けなかったので、詳細不明だけど、[Kubernetes Meetup Tokyo #7の参加者レポート](https://qiita.com/takky/items/44ca63273706a5ed93ce)を見る限り@mumoshuさんがメンションされていたようです。

が、情報が少ない。

## アーキテクチャ

![](https://cloud.githubusercontent.com/assets/343539/21630809/c1adfbd2-d202-11e6-9dfe-9024139d0a28.png)
via https://github.com/coreos/clair/blob/master/Documentation/running-clair.md

一般的にはコンテナレジストリとの連携が一般的でしょう。

でも、コンテナレジストリなんて運用したくないし、Docker Hub、Google Container Registry (GCR)、Amazon EC2 Container Registry (ECR)、Azure Container Registry (ACR)使っててるだけです、って人が大半だと思われる。

## CI/CDパイプラインの中でやりたい

そんな意見もあるでしょう。

## ローカルにあるこのイメージで確認したいだけなんだ

そんな意見もあるでしょう。

そんなあなたやローカルで実行できるClairクライアントが必要。

### (deprecated) coreos/analyze-local-images (deprecated)

CoreOSから2015年11月にcontribとして現れましたが、緩やかなメンテナンスを経て、2017年5月にdeprecatedに。

>  deprecated tool for interacting with Clair locally

via https://github.com/coreos/analyze-local-images

#### 関連記事
- https://qiita.com/kz-takahashi/items/575c144c5b9f118bc96d

### (deprecated) wemanity-belgium/hyperclair (deprecated)

公式ではないが、2016年1月に出てきて、2-3ヶ月アクティブに改善が続けられるも、その後メンテナンスが止まりました。2017年2月にdeprecatedに。

今ではリードにもこう書かれています。

> DEPRECATED [mv to https://github.com/jgsqware/clairctl] -> A CLI for using Clair with Registry https://github.com/jgsqware/clairctl

via https://github.com/wemanity-belgium/hyperclair

### clairctl (jgsqware/clairctl)

そんなわけで今はclairctl。2016年10月hyperclairから移動される形？で、clairctlが立ち上がる。今に至るまで開発・メンテナンスもされています。

>  Tracking container vulnerabilities with Clair Control for CoreOS Clair

via https://github.com/jgsqware/clairctl

### デモ
デモはhyperclairのままで古い。が、イメージはこんな感じ。

[![asciicast](https://asciinema.org/a/41461.png)](https://asciinema.org/a/41461)

## その他Clairの参考情報

- [Clair Documentations](https://coreos.com/clair/docs/)
- [coreos/clairのIssues](https://github.com/coreos/clair/issues)
- [All posts tagged "Clair" - CoreOS Blog](https://coreos.com/blog/clair)


## CoreOS in CNCon NA 2017

CoreOSはKubeCon + CloudNativeCon North America 2017のスポンサーもしているものの、Tectonic/Quay推しだと想像されるのでなかなかチャンスは少なそうですが、Clairについても聞いてこれたらなと思います。
ブラウザ機能格差への３つの対応概念　まとめ

フロントエンド開発は、つまるところWebブラウザに依存する。
 Webブラウザの大きな問題点として、ブラウザ間の機能格差があり、これへの対処法として３つの考え方があるが、投稿されていなかったので、シンプルにして投稿いたします。
## グレースフル・デグラデーション
1. まずは、対応度の高いブラウザに合わせて作成。
2. その後、対応度の低いブラウザでは、いくぶんか表現を削除。

ブラウザごとに表現を変えても良いという考え方
上限から、減らす考え方
## プログレッシブ・エンハンスメント
1. まずは、対応度の低いブラウザに合わせて作成。
2. その後、対応度の高いブラウザだけリッチな表現を加える。

ブラウザごとに表現を変えても良いという考え方
下限から、足す考え方
## レグレッシブ・エンハンスメント
1. まずは、対応度の高いブラウザに合わせて作成
2. その後、対応度の低いブラウザでは、Polyfillを用いて同等な表現を加える。

ブラウザごとの表現を変えないという考え方
※デメリットとして、Polyfillは、JavaScriptを用いた技術のため、古いブラウザに対して負荷がかかることになる。負荷検証コスト等を踏まえる必要がある。 



※これらは、表現の格差であり、コンテンツ（情報）の格差ではない。

## これらを踏まえて思うこと
フロントエンド開発のブラウザ差異に関しては、これらの情報共有が必要になる。

- 対象端末・ブラウザの範囲
- 対象端末・ブラウザの機能
- 対象端末・ブラウザ間の機能格差（HTML5, CSS3, JavaScriptへの対応度）
- 対応方法（上記３つのいづれか）

  デザインとマークアップを分業していると、いつの間にかグレースフル・デグラデーションになっているのではないか。むむむ。

## 疑問
ベンダープレフィックスでの対応って関係あるのか

参考：[どうする？ブラウザ機能格差の解消 第1回 3つの実装の考え方](https://app.codegrid.net/entry/ways-of-implementation#toc-1)
apt エラーがでたときのRepository設定

公式リポジトリは場所がよく変わるのでエラーが出る。

こちらのページにて描いてあったものがとても良かったので乗せておきます。
https://qiita.com/fkshom/items/53de3a9b9278cd524099


```
sudo sed -i.bak -e "s%http://[^ ]\+%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g" /etc/apt/sources.list
```

日本のミラーサイト
http://www.ubuntulinux.jp/ubuntu/mirrors


```
sudo apt-get clean
sudo apt-get update
```
※必要であれば、`rm -rf /var/lib/apt/lists/*`で、取得済みの情報をクリア。
UniRxでAsyncReactiveCommandを使ったダブルクリックの抑制


###背景
最近AsyncReactiveCommandを知ったので使ってみた

###参考
http://neue.cc/2016/08/03_536.html
https://qiita.com/soi/items/eca0601ad0fc4e401623

##問題
ボタンをダブルクリックされても処理は一回だけに抑制したい！

##ボタンひとつの場合
```Hoge.cs
	[SerializeField] private Button _button;

	void Start(){
		var asyncReactiveCommand = new AsyncReactiveCommand();
		asyncReactiveCommand.Subscribe(_ => Observable.Timer(TimeSpan.FromSeconds(0.5f)).AsUnitObservable());
		asyncReactiveCommand.BindTo(_button);
	}
```
これでクリックされてから0.5秒間 interactable を false にしてくれる！


```HogeHoge.cs
	[SerializeField] private Button _button;

	void Start(){
		_button.BindToOnClick(_ => {
			return Observable.Timer(TimeSpan.FromSeconds(0.5f)).AsUnitObservable();
		});
	}
```
これでも同様に動く便利なショートカット！

##ボタン複数の場合
同じグループのボタンでどれか一つでもクリックされたらそのグループのボタンを押させたくない時！

```Common.cs

public static class Common
{
	private static readonly Dictionary<int, AsyncReactiveCommand> _asyncReactiveCommandDict = new Dictionary<int, AsyncReactiveCommand>();
	
	public static AsyncReactiveCommand GetAsyncReactiveCommand(int groupId)
	{
		if (_asyncReactiveCommandDict.ContainsKey(groupId))
			return _asyncReactiveCommandDict[groupId];

		_asyncReactiveCommandDict.Add(groupId,new AsyncReactiveCommand());
		_asyncReactiveCommandDict[groupId].Subscribe(_ => Observable.Timer(TimeSpan.FromSeconds(0.5f)).AsUnitObservable());
		return _asyncReactiveCommandDict[groupId];
	}
}
```

```SuppressionDoubleClick.cs
public class SuppressionDoubleClick : MonoBehaviour
{
	[SerializeField] private int _groupId;

	void Start()
	{
		Common.GetAsyncReactiveCommand(_groupId).BindTo(GetComponent<Button>());
	}
}
```

こんな感じに定義して抑制したいボタンに SuppressionDoubleClick を設定すればおｋ！
![button.gif](https://qiita-image-store.s3.amazonaws.com/0/59989/f6995f3a-0d8e-1ea8-3c43-2b90cb2fd07a.gif)

思ったより簡単だった
Prophet on Miniconda on Windows10

# 前提条件

- Windows 10 or Mac
- [Miniconda 3](https://conda.io/miniconda.html) の最新安定板

[「極力CUIでゼロからDjango開発環境を構築」](https://qiita.com/ShortArrow/items/19f4fc70764fc225f0e7)と同様の手順を実行して、Powershellまたはターミナルで[Miniconda 3](https://conda.io/miniconda.html)が使用できるようになっていること

# 仮想環境を作成して有効化

```bat
(base) PS> conda create -n prophet-test
(base) PS> conda activate prophet-test
(prophet-test) PS>
```

## Mac ターミナル の場合

```bat
(base) $ conda create -n prophet-test
(base) $ source activate prophet-test
(prophet-test) $
```

::: note warn
<ul>
   <li>Windows では `conda` なのに Mac では `source`</li>
   <li>`prophet-test`は任意の文字列に置き換えできる</li>
   <li>右端の()の中が現在な仮想環境</li>
</ul>
:::

# Prophetをインストール

```batch
(prophet-test)　PS> conda install -c conda-forge fbprophet
```

参考: <https://facebook.github.io/prophet/docs/installation.html>
この１コマンドで関連ライブラリがconda-forgeからインストールされ、最後にProphetがインストールされる。

# ストーリー

pipを使用してpystanやprophetを以下のようにインストールしてみたが、上手く行かなかった。

```bat
(prophet-test)> conda install numpy matplotlib pandas
(prophet-test)> pip install -U pystan
(prophet-test)> pip install -U fbprophet
```

ここで Successful installing という表示は出た。
しかしコーディングを始めると、AttributeError が発生してコードが正常に実行されない。
`pip install -U pystan`を`conda install pystan`に変えてもダメだった。
そこで、<https://facebook.github.io/prophet/> を見ていたらWindowsとLinuxに並んでAnacondaの記述を発見。

>Use conda install gcc to set up gcc. The easiest way to install Prophet is through conda-forge: conda install -c conda-forge fbprophet.

ということは、

```batch
(prophet-test)> conda install numpy matplotlib pandas
(prophet-test)> conda install gcc
(prophet-test)> conda install -c conda-forge fbprophet
(prophet-test)> pip install pystan
(prophet-test)> pip install fbprophet
```

でよさそう。

> The major dependency that Prophet has is pystan. PyStan has its own installation instructions.
https://pystan.readthedocs.io/en/latest/installation_beginner.html

を見るとWin とMacでC言語関連のインストール方法が違うらしい。これによって、Pystanのインストール手順に差が生まれる模様。

**Excelsior!**
【Excel】グループ化した行を一部非表示のままにしておく方法

行の高さを「0.1」に設定する。

これで、グループの詳細データを表示した場合も
行の高さを「0.1」に設定した行は表示されない。

「0」だと駄目でした。
仕組みはよくわからない。
Kotlin - 文法 - メモ

kotlinは便利だけど、便利故に勝手に期待をする -> やっぱりできなかった。 -> どうやるの？
と、深く考えることなしにハマってしまう。
そんな私の備忘録。

# コンストラクタ

#### 下記のクラスにセカンダリを追加する場合、`list: ArrayList<Any>`はデリゲートができない。

```kotlin
class Hoge(var list: List<Any>)
```

結局、プライマリ+α な引数にするという形をとることにした。

```kotlin
class Hoge(val list: List<Any>) {
    constructor(foo:String, bar: ArrayList<Any>) : this(bar) {

        // barzもデリゲートできない
        val barz = ArrayList<Any>()

        // ちなみにセカンダリの引数は自動的にval相当になる（var, valの指定不可）
        // 下記はエラー
        foo = ""

    }
}
```

考えてみたら当たり前のことで異なるコンストラクタの引数を参照できるわけがない。

# when
#### break, continueが使えないので迷った。

- returnするとメソッドを抜けてしまう。
- loopは使えたとしても極力使いたくない。

when句からのexitは空の中括弧で対応した。

```kotlin
val hoge:String = foo
when (hoge) {
    null -> return
    "" -> {}
    "a" -> {return} //nullと同じ挙動
    else -> {
        print(hoge)
    }
}
```
# Properties

IntelliJではresources配下に対して以下のようにしてアクセスができた。

```
~/resources
    /dev
       /example.properties
    /prod
       /example.properties
```
```kotlin
val prop = Properties()
val env = "dev"
prop.load(this::class.java.getResource("/${env}/example.properties").openStream())
```

参照
https://stackoverflow.com/questions/42739807/how-to-read-a-text-file-from-resources-in-kotlin

# Paths

作業ディレクトリの取得方法

```
Paths.get("").toAbsolutePath().toString()
```

# SLF4J
```kotlin
val logger = LoggerFactory.getLogger(this::class.java)
```
Auto_incrementとパーティションでバグった…ＭｙＳＱＬ5.7

#はじめに
多分これは運用上、あんまり起こらない事であることをお伝えします。起こるとしたら以下の条件を満たした場合…だと考えられます。

- ＭｙＳＱＬ5.7であること（他のはいつか検証します）
- auto_increment（仮にidカラムとしましょうか）を指定したカラムを含む複合ＰＫのテーブルである事。
- auto_incrementカラム以外のＰＫカラム(日付で試したのでcreated_dateとします）に対してパーティションが組まれている事。
- 複合ＰＫに含まれるカラム(created_date)の値をupdateすること。

そもそもＰＫの値をupdateするなんて！！っていうのはごもっともな話。あくまで検証中の事故で気付いたので…ご勘弁ください。弁護するなら、パーティションを張るために本来であれば複合ＰＫにしなくても良いカラムをしている場合もあるとは思います…。

#検証準備
以下のテーブルを用意します。

```テーブル
CREATE TABLE `t_log_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `created_date` datetime NOT NULL DEFAULT '1999-01-01 00:00:00',
  PRIMARY KEY (`id`,`created_date`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE  COLUMNS(created_date)
(PARTITION p1711 VALUES LESS THAN ('2017-12-01') ENGINE = InnoDB,
 PARTITION p1712 VALUES LESS THAN ('2018-01-01') ENGINE = InnoDB,
 PARTITION pmaster VALUES LESS THAN (MAXVALUE) ENGINE = InnoDB) */;
```
t-log_testテーブルについて以下のデータを入れます。

```
insert into t_log_test(created_date) VALUES("2017-12-01 10:15");
```
もちろん、正常に入ります。
パーティション的にはp1712に入っているはずです。

#検証実行

```
mysql> select * from t_log_test;
+----+---------------------+
| id | created_date        |
+----+---------------------+
|  1 | 2017-12-01 10:15:00 |
+----+---------------------+
1 row in set (0.00 sec)
```
入ってます。
ここで禁断の…created_dateをupdateします。(通常の運用では作った日付けとかよりもupdated_dateとかの方を更新することにはなると思いますが）

```
mysql> UPDATE t_log_test SET created_date='2017-11-30 10:15:34' where id=1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t_log_test;
+----+---------------------+
| id | created_date        |
+----+---------------------+
|  1 | 2017-11-30 10:15:34 |
+----+---------------------+
1 row in set (0.00 sec)
```
このレコードが「入っていた」p1712を削除します。データはp1711に移動しているはずです。

```
mysql> ALTER TABLE t_log_test DROP PARTITION p1712;
Query OK, 0 rows affected (0.23 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from t_log_test;
+----+---------------------+
| id | created_date        |
+----+---------------------+
|  1 | 2017-11-30 10:15:34 |
+----+---------------------+
1 row in set (0.00 sec)

```
うん消えていない。
もう一度レコードを挿入します。

```
mysql> select LAST_INSERT_ID( );
+-------------------+
| LAST_INSERT_ID( ) |
+-------------------+
|                 1 |
+-------------------+
1 row in set (0.00 sec)

mysql> insert into t_log_test(created_date) VALUES("2017-11-30 12:15:13");
Query OK, 1 row affected (0.04 sec)
```
LAST_INSERT_ID()関数でも見てますが想定ではＩＤが2になるはず。
結果は…

```
mysql> select * from t_log_test;
+----+---------------------+
| id | created_date        |
+----+---------------------+
|  1 | 2017-11-30 10:15:34 |
|  1 | 2017-11-30 12:15:13 |
+----+---------------------+
2 rows in set (0.00 sec)
```
ものの見事にauto_incrementの値が"リセット"されてしまってます。idを外部キーとして扱うシステムならこれで重大な問題につながります。
試しにDELETEで同じことをしてみたのですが再現はしませんでした。
恐らくauto_incrementの管理機能のバグではないかと思うのですが…単なる仕様かもしれません。

そもそも**ＰＫの更新などと言う恐ろしいこと**を実行する人はいないと思うのですが…まぁご参考程度に…。
Processingで画像を表示する

```
float RGB = 255;
float ALPHA = 100;

PImage image;

void setup(){
  size(50,50);
  image = loadImage("whiteBrush.png");
  background(0);

}

void draw(){
  imageMode(CENTER);
  tint(RGB,ALPHA);
  image(image,25,25);
}
```

・画像のときは、fill()の代わりに tint()を使う。
最初の一歩 GitHub上での新規リポジトリをVSCodeに紐付け、ローカルでプログラミングを始める方法。

VSCode上でプログラムを書き、それを記録しておくためGitHub上に保存しておこうとした所、久しぶりすぎてやり方を忘れていたので調べてメモ。

# 前提条件
環境
Windows7
Gitはインストール済み
GitHubのアカウントは作成済み
VSCodeはインストール済み

# 一番簡単な方法（以前触っていたことはあるが完全に忘れている状態）
GitHubへ
https://github.com/masakinihirota
https://github.com/[自分のID]
↓
Repositories（タブボタン）
↓
New（緑色のボタン）
↓
（必須）
[Repository name]
（任意）
Description,Public or Private(現在はPrivateでも無料です),
Initialize this repository with a README,license
↓
「Create repository」（緑色のボタン）
↓
GitHub上でのリポジトリが作成されます。
↓
VSCodeでローカルにリポジトリを展開したい場所を開きcloneコマンドを実行します。
↓
コマンドラインから
`git clone https://github.com/[自分のID]/[Repository name].git`
例
`git clone https://github.com/masakinihirota/React.git`
※「.git」を付けることを忘れずに。
↓
[VSCodeで開いたディレクトリ]/[Repository name]
例
D:\webをVSCodeで開いた場合。
D:\web\React
と展開されます。

確認
README.md等になにか書きます
VSCode上からコミットします。
VSCode上からプッシュします。
成功したらローカルで変更した部分が、github上で更新が反映されていることを確認できると思います。


# まっさらな状態から作る方法
（GitHub上にもローカル上にもGitフォルダ等が全く何もない状態。）

おおまかな手順
github上でまっさらなリポジトリを作っておく。
※README.mdや.gitignore等にチェックを入れないこと
ローカルでリポジトリを作っておき、githubへpushする。

以下詳細な手順

## GitHubページを訪れる
https://github.com/
画面右上にあるSign in[ボタン]を押す。
Username or email address
Password
をそれぞれ入力
Sign in[ボタン]を押す。

## ログイン済みの自分のトップページ
画面右側の中央にある
New repository[緑色のボタン]を押す。

Create a new repositoryページが開く
Repository name
を入力
（緑のチェックマークが出ればok）

Create repository[緑色のボタン]を押す。

GitHub上にリポジトリが作成される。

URLを記録しておく
Quick setup — if you’ve done this kind of thing before
の下にURLが表示される
https://github.com/アカウント名/リポジトリ名.git
SSHでアクセスする場合はこちら
git@github.com:アカウント名/リポジトリ名.git
このURLを記録しておく。

URL例
HTTPS
https://github.com/masakinihirota/test.git
SSH
git@github.com:masakinihirota/test.git

## ローカル側で作業

### エクスプローラー上での作業
エクスプローラーを立ち上げ
レポジトリを置きたい場所にフォルダを新規作成する。
「このフォルダの下にGitHub上に作ったリポジトリが作成される」
（VSCode上から自分の作りたい場所にフォルダを作成できるなら不要）

### VSCode上での作業
VSCodeを立ち上げる
ファイル＞新しいウィンドウで
新しいウィンドウを開く

ファイル＞フォルダを開く
から新規作成したフォルダを選択
もしくは
エクスプローラーからVSCodeへ
作ったフォルダをドラッグ＆ドロップする。

表示＞総合ターミナル
もしくは
Ctrl+`
でターミナルを開き。
（Windows端末）

「URLの部分は各自で設定」
echo "# test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/masakinihirota/test.git
git push -u origin master

SSHでアクセスする場合はこちら
ーーーー未定

作業終了

### 確認作業
ローカル上で
何か適当なファイルを作成or変更して
コミットしてプッシュすると
GitHub上に反映されることを確認する。

プッシュはVSCode左側の上から3番目のGitコマンドアイコンを選び。
その隣に開かれた ソース✓ ↻・・・
この・・・を押すとGitコマンド群が現れ
プッシュを選択すると出来る。

後は自由にプログラミング！

# ローカルにリポジトリが2つ以上ある場合は？
git remoteコマンドがきちんと設定してあれば
VSCodeで、開くリポジトリ毎に自動的に設定の切り替えが行われているようです。

### (おまけ)すでにローカル側にリポジトリがある場合
GitHub上にリポジトリを作成する。
git remoteコマンドでリポジトリを指定
git remote add origin https://github.com/masakinihirota/test.git
git cloneコマンドでリポジトリをローカルマシーンにコピー
git clone https://github.com/masakinihirota/test.git

### すでにGitHub側にリポジトリがある場合
git cloneを使う。
リモートファイルをローカル環境に落とす手順書

# 目的
ログファイル、設定ファイル、DBスキーマなどを落としたい時に利用する

## 手順1 リモートサーバーで叩くコマンド
リモートサーバーのグローバルIPを取得
```$ curl ifconfig.me```

## 手順2 ローカルで叩くコマンド
後はscpコマンドでダウンロード。
落としたいファイルの相対パスはユーザーでログインした場合の**~/**から
```$ scp -r username@remote_server_ip_addr:file_path output_dir/file_name```

## 最後
### **便利！**
Let's Encrypt がある日発行できなくなった

## 概要

* OpenResty の lua-resty-auto-ssl を使ってる (多分 certbot-auto でも同じ)
* 気づいたら以下エラーで証明書の発行がエラーになってた

```
INFO: Using main config file /path/to/resty-auto-ssl/letsencrypt/config
+ Generating account key...
+ Registering account key with ACME server...\


Error registering account key. See message above for more information.
 err: # !! WARNING !! Extra configuration directory /path/to/resty-auto-ssl/letsencrypt/conf.d exists, but no configuration found in it.
  + ERROR: An error occurred while sending post-request to https://acme-v01.api.letsencrypt.org/acme/new-reg (Status 400)

Details:
{
  "type": "urn:acme:error:malformed",
  "detail": "Provided agreement URL [https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf] does not match current agreement URL [https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf]",
  "status": 400
}

...
```

## 原因

* `Details` にある通りデフォルトで指定しているライセンスファイルが今現在指定すべきものと異なるせい

## 解決策

### lua-resty-auto-ssl

* https://github.com/GUI/lua-resty-auto-ssl#advanced-lets-encrypt-configuration にあるように設定ファイルを置く
* `cond.d` 配下に置けば何でも良さそう
* 例

```
$ cat /path/to/resty-auto-ssl/letsencrypt/conf.d/custom.sh
LICENSE="https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"
```

### certbot-auto

* 試してないけど以下でできるかも？
    * https://github.com/certbot/certbot/blob/master/tests/letstest/testdata/sample-config/accounts/acme-staging.api.letsencrypt.org/directory/48d6b9e8d767eccf7e4d877d6ffa81e3/regr.json のようなファイルが `/etc/letsencrypt/accounts/acme-v01.api.letsencrypt.org/directory/**/regr.json` とかにある
    * `agreement` や `terms_of_service` に同様の指定があるのでこれを書き換えればいけるかも
SoapUI Community Edition での Groovy コードの共通化

# SoapUIというテスト自動化ツール
SoapUIというツールがある。
これは、元々SOAPの電文をテストする場合に、WSDLというSOAPの定義を元に簡単にテストケースを自動生成して自動テストできるようにしたツールだが、REST APIのテストにも対応している。
Javaで作られたOSSで、テストケースの合間にGroovyにてコードを書けばGroovyで自動化できることは全てできる。
このツールは、時代の流れによりSwagger対応し、RESTAPIをテストできるようになった。

# 事の発端
SoapUIではテストスイート（TestSuite）とテストケース（TestCase）があり、テストケースをまとめた物がテストスイートである。
このSoapUIを使用して REST APIをテストするにあたり、Groovyで良く書くコードは共通化しない限り　同じコードがテストケースに散在し、このコードが間違っていると全てのテストケースを修正しなくてはならない。
そこでSoapUIでのテストケースでコードを共通化する方法を調べた。

# 最終的なイメージ

Groovyで共通コードをクラスとしてインポートし、使用する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/192988/7a0101f4-aafa-53d2-3cde-5f70a43e4a11.png)

# 手順概要
* Groovyをインストール
* JavaSDKをインストール
* groovyc にて のクラスをコンパイル
* コンパイルしたGroovyのクラスをjar でアーカイブ
* 作成した jar のアーカイブを SoapUIインストールフォルダの bin/ext に配置

こんな簡単な手順でGroovyのコードが共通化できるので、お試しあれ。
Raspberry PiのRaspbianイメージをMacでSDカードにコピーする手順


RaspbianなどRaspberry PiのディスクイメージをMacOSマシンのターミナルでSDカードにコピーする手順。

※ GUIで操作できる[balenaEtcher](https://www.balena.io/etcher/)の方が簡単。
※ ネットが使えて、1台だけインストールするなら[NOOBS](https://www.raspberrypi.org/downloads/noobs/)を使う方が簡単。


## イメージのダウンロード

[Download Raspbian for Raspberry Pi](https://www.raspberrypi.org/downloads/raspbian/)


zipファイルを解凍する。

## イメージのコピー

MacにSDカードを挿すと自動的にマウントするので、それらしいパスを確認してからアンマウントする。


```terminal
$ diskutil list
/dev/disk0 (internal, physical):
…
/dev/disk3 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *16.1 GB    disk3
   1:             Windows_FAT_32 boot                    43.7 MB    disk3s1
   2:                      Linux                         16.0 GB    disk3s2

$ diskutil unmountDisk /dev/disk3
Unmount of all volumes on disk3 was successful
```


`/dev/disk3` の `3` はそのときのディスクのマウント状態によって変わる。

ddコマンドを使ってイメージを書き込む。このとき `/dev/rdisk?` 経由で書き込むとコピーの速度が多少速くなるらしい。

`Ctrl+T` を押すと途中経過を確認できる。

```
$ sudo dd if=./2017-09-07-raspbian-stretch.img of=/dev/rdisk3 bs=16m
293+1 records in
293+1 records out
4916019200 bytes transferred in 372.695589 secs (13190441 bytes/sec)
```

終わったらまた自動マウントされるので、SDを取り出す前にアンマウントする。

```
$ diskutil unmountDisk /dev/disk3
```
Dockerを利用してPHP5.3 / Apache2 のローカル環境を構築する方法

## はじめに
PHP 7.2がそろそろリリースされようとする昨今ですが、まだPHP5.3を利用しているシステムも少なくないと思います。今回はDockerを利用してPHP5.3/Apacheのローカル環境を構築する方法をまとめます。

## なぜ Docker を利用するのか

Docker を利用するメリットは以下です

* 起動が高速
* 他開発者と環境と共有・統一できる
* 調整が簡単

## 前提
* [Docker for Mac](https://www.docker.com/docker-mac) がインストール済み
* [Docker Hub](https://hub.docker.com/) にユーザー登録済み

## 構築手順
方針を簡単にまとめると、Docker で PHP5.3/Apacheのイメージを作成し、それをdocker-composeで起動して利用する方針です。手順は以下にまとめます。

### Docker Image を準備

Ubuntu 12.04 は初期状態で PHP 5.3.10 がインストール可能なのでそれを利用します。以下ファイルを用意します。

```sh:Dockerfile
FROM ubuntu:12.04
MAINTAINER Your Name <your@email.com>

VOLUME ["/var/www"]

# PHP 5.3 + Apache で必要なパッケージをインストール
RUN apt-get -qq update \
    && apt-get install -y -qq --no-install-recommends \
      apache2 \
      libapache2-mod-php5 \
      php5

COPY run /usr/local/bin/run
RUN chmod +x /usr/local/bin/run

EXPOSE 80
CMD ["/usr/local/bin/run"]
```

```sh:run
#!/bin/bash
set -e

# Apacheの環境変数を読み込み、Apache2をフォアグランドで起動。これによりコンテナ起動時にApacheが常時起動になる
source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND
```

イメージをビルドします。タグ名は好きな名前をつけてください。

```sh
$ docker build ./ -t hypermkt/php53-apache
```

### Docker Hub にイメージを push

docker コマンドを利用して先ほど作成したタグ名を指定して、イメージをpushします。

```sh
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: hypermkt
Password:
Login Succeeded

$ docker push hypermkt/php53-apache:latest
```

成功すると以下のようにリポジトリが作成されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/29755/ed8c4052-e624-bd29-2dfa-0c1a990457bb.png)


### docker-compose で コンテナを起動

docker-compose.yml ファイルを用意します。ポイントとしては

* Docker Hub に pushしたイメージを利用する
* 80ポートにアクセスできるようにする
* ホストの直下とコンテナ側のドキュメントルートをマウント

を設定します。

```sh:docker-compose.yml
version: '2'
services:
  web:
    image: hypermkt/php53-apache
    volumes:
      - ./:/var/www
    ports:
      - "80:80"
```

コンテナを起動します。

```sh
$ docker-compose up
```

### 動作確認

確認用にホスト側にphpinfoファイルを用意しておきます。

```php:phpinfo.php
<?php
phpinfo();
```

ブラウザからアクセスすると、phpinfoが確認できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/29755/ae3f6429-a427-3f7a-0be6-490824896588.png)

これで PHP 5.3 + Apache2 環境の構築完了です。

## おわりに

今回は最低限の環境を構築したのみでした。WebサービスとなるとさらにPHPの拡張モジュールが必要だったり、Apahceで設定変更も必要になると思いますので、必要に応じて拡張していくと良いと思います。

## 参考
* [hypermkt/docker\-php53\-apache](https://github.com/hypermkt/docker-php53-apache)
VagrantでWindows7にWindows10を立てる

# Windows 7 (ホストOS)の作業

## Windows 10 の仮想マシンを初期設定
```
> vagrant init Microsoft/EdgeOnWindows10
```

## Vagrantfileの編集

```:Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "Microsoft/EdgeOnWindows10"
  config.vm.guest = :windows
  config.vm.communicator = "winrm"
  config.winrm.username = "user"
  config.winrm.password = "user"
  config.winrm.retry_limit = 30
  config.winrm.retry_delay = 10

  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "public_network"
end
```

## 仮想マシンの起動
```
> vagrant up
```
エラーがいろいろ表示されるが、とりあえず動くはず。

# Windows 10 (仮想OS) の作業
Virtual BoxからWindows 10にアクセスする。

## 日本語化
以下の記事を参考にしてください。
[Windows10を日本語化する](https://qiita.com/o_study_o/items/764a635834911812d714)

## すべてのパブリックネットワークをプライベートネットワークに変更
[コントロールパネル] > [ネットワークと共有センター] > [アクティブなネットワークの表示]に表示されている**すべての**パブリックネットワークをプライベートネットワークに変更する。

ただし、ネットの情報によるとGUIでは変更できないことが多いらしい（自分の環境でもそうだった）。
そんなときでも、以下のサイトの手順により設定変更できる。
[Windows10のネットワーク設定で、プライベートネットワークの設定が出来ません。](
https://answers.microsoft.com/ja-jp/windows/forum/windows_10-networking/windows10%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88/0e5004a8-ca48-422f-84b8-93646373a5cc?auth=1)

## ユーザーの作成
Win RMでアクセスするユーザーを作成する（＝前述の`Vagrantfile`に記載したユーザー）。

-  アカウント：user
-  パスワード：user

## Win RM の設定
Windows PowerShellを管理者権限で実行する。

```
PS> winrm qc
```
確認を求めるプロンプトでは「y」を入力する。

```
PS> winrm set winrm/config/service/auth '@{Basic="True"}'
PS> winrm set winrm/config/service '@{AllowUnencrypted="True"}'
```

## OSのシャットダウン
本来はVagrantで停止したいが、現段階では機能しないのでOSからシャットダウンする。

# Windows 7 (ホストOS)の作業
この段階でこれまでの設定がすべて有効になるので、今後は以下のようなVagrantコマンドが実行可能。

```
> vagrant up
> vagrant reload
> vagrant halt
```
brewで管理しているソフトウェアで何かあった時のトラブルシューティングメモ

昔まで頻繁に使っていたMacのパッケージ管理ツールの`Homebrew`を久しぶりに使ったら`rails new`した時にエラーとか起きたりしたので、メモとして随時更新していこうと思う。

## とりあえずこれ

`brew`を最新に保っておくのがそういった問題を未然に防ぐためにやっぱり重要

```
// brewを掃除する
$ brew cleanup

// 問題検出
$ brew doctor
```

## xcodeを最新にする

```
$ xcode-select --install
```
命名規則について

# はじめに
プログラミングで使用される変数、関数などはこれらの命名規則を利用していることが多い。

- キャメルケース(ローワーキャメルケース)
- パスカルケース(アッパーキャメルケース)
- スネークケース
- チェインケース(またはケバブケース)
- ハンガリアン記法
- 大文字記法

## 注意
- Microsoftでは一般的な名前付け規則として、ハンガリアン記法、スネークケース、チェインケースの使用を非推奨とする案内があります。
- 本ナレッジではサンプルをC#やphpにて記述しておりますが、特別な意味はありません。


# 命名規則

## パスカルケース(アッパーキャメルケース)

```C#:例) get + user
public string GetUser = "変数の値";
```

複合語の頭文字を大文字にする命名規則をパスカルケースといいます。
パスカルケースは商品名に採用されるものもある(例:PlayStation)。

## キャメルケース(ローワーキャメルケース)

```C#:例) get + user
public string getUser = "変数の値";
```

複合語のはじめの単語の頭文字を小文字にし、以降の単語の頭文字を大文字にする命名規則をキャメルケースといいます。

## スネークケース

```php:例) get + user + name
$get_user_name = "変数の値"
```

複合語の区切りに_(アンダースコア)を使う命名規則をスネークケースといいます。

## チェインケース(ケバブケース)

```php:例) get + user + name
$get-user-name = "変数の値"
```

複合語の区切りに-(ハイフォン)を使う命名規則をチェインケースといいます。

## ハンガリアン記法

```c#:例) string型データ(username)を格納する変数
str(String) + username = strusername
```

## 大文字記法

```c#:例) 定数SERVERNAME
public const string SERVERNAME = "サーバの名前"
```


# 個人的な感想
色々ピックアップしたが、3つ以上の単語で構成される複合語を名前として用いるのは最適化しきれていない可能性が高い。

- 異なる処理を1つの処理としてグルーピングしていないか？
- 処理の範囲が広くなりすぎていないか？

整理できるようなら整理したほうがよさそう。

# 参考

https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%A1%E3%83%AB%E3%82%B1%E3%83%BC%E3%82%B9

https://docs.microsoft.com/ja-jp/dotnet/standard/design-guidelines/general-naming-conventions
【備忘録】イベントログ検知→メール送信メモ

# イベントログへのERROR出力をメール通知

## Powershellスクリプトを作成

```Powershell:Sendmail.ps1
# イベントログへのERROR出力でメール通知

## Powershellスクリプトを作成

# SMTPサーバ
$smtp = "xxx.xxx.xxx.xxx"
# Fromアドレス
$from = "xxxxxx@xxxxxx"
# Toアドレス
$to = "yyyyy@yyyyyyy"
# Subject
$subject = "エラー通知"

# SmtpClientクラス
$mlClient = New-Object Net.Mail.SmtpClient($smtp)

# MailMessageクラス
$mailMsg = New-Object Net.Mail.MailMessage($from, $to)
$mailMsg.Subject = $subject
$mailMsg.Body = "イベントログでエラー検知`nイベントID:1000"
$mailMsg.SubjectEncoding = [System.Text.Encoding]::GetEncoding("ISO-2022-JP")
$mailMsg.BodyEncoding = [System.Text.Encoding]::GetEncoding("ISO-2022-JP")

# メール送信
$mlClient.Send($mail)
```

## Powershellをコールするbatを作成

```bat:Sendmail.bat
rem Sendmail.ps1 配置場所に移動
cd /d D:\temp
powershell -NoProfile -ExecutionPolicy Unrestricted .\sendmail.ps1
```

## タスクスケジューラにイベント登録
![event.png](https://qiita-image-store.s3.amazonaws.com/0/146082/32f8986e-1b23-6815-ede9-ca3df71f309b.png)

## イベント発火

`eventcreate /ID 1000 /L Application /SO Cmd /T ERROR /D "Error event"`
apt実行時ipv6アドレスにアクセスさせたくないときの対処

特定の環境だと、
aptやapt-getを実行した際に、リポジトリサーバ（アップデートパッケージのある場所）にIPv6アドレスでアクセスしようとして、めっちゃ遅いときがある。

IPv4でリポジトリサーバを探させたいときは下記のコマンドを実行する。

```
echo 'Acquire::ForceIPv4 "true";' | sudo tee /etc/apt/apt.conf.d/99force-ipv4
```

これでIPｖ４で探してくれる。
gRPCを導入してみて感じたよかったことと遭遇した問題

# 導入
2017年、OrigamiでもgRPCの導入が進みました。
もともと、2年ぐらい前からIDLによる定義とそれを利用したRPCの利用についてはときどき話されていましたが、既存機能をgRPCに置き換えるモチベーションや積極的な理由もあまりなく、HTTPによる通信にものすごく困っていたわけでも無いため、なかなかスタートが切り出せずにいました。
しかし完全新機能の一部をgRPCで作ったところ、それに携わったメンバーからの感触もよく、gRPCの利用範囲を広げて行くことにしました。
OrigamiにおけるgRPC利用はサーバー間通信から始めており、クライアントアプリから直接gRPCアクセスすることは(今の所)行われていません。
またサーバサイドの開発言語もほとんどがGoで書かれており、言語間のインピーダンスミスマッチについての評価はできていません。

# 遭遇した問題
## コミュニケーションコスト、ドキュメンテーションコストが減る
最大の利点はコミュニケーションコスト、ドキュメンテーションコストが減ることだと思います。
Protocol Bufferによる定義があるので、値の型定義についてはとりあえず定義ファイルを見ることですぐにわかります。また生成されたソースコードがあるので、ソース補完が効くのもGo使いにとっては非常にありがたいです。
定数の一部についてもenumで定義できるので、公開された定数についてもあるていどドキュメンテーションされることになります。
ただし値やフィールドの意味や、受け取る値の範囲などは定義できないので適宜コメントやドキュメントに書いて行く必要はあります。proto3からはrequiredやoptionalというものも無くなったので、このあたりもコメントするポイントです。

## テストしやすくなる
HTTP通信であってもGo標準パッケージにある `net/http/httptest` を使うことでテストできていたのですが、gRPCの場合はRPCが見かけ上単なる関数呼び出しになるため、テストが非常にやりやすくなりました。
またパラメータのバインディング処理が無くなったため、コードもすっきりするようになりました。
コーディング規約として、RPCの引数と返り値にScalar Value Typesを用いず、Message Typesを使うことと決めています。

## テスト用CLIアプリが作りやすい
Goの得意領域としてCLIアプリが作りやすいということが良く言われますが、この特性はgRPCと非常に相性が良く、接続元サーバーが出来上がる前からCLIツールを作ることで結合テストが簡単に行えるようになります。
またこのCLIツールでテストデータの作成もSQLでDBに直接突っ込むのでは無く、正しい手順で行えるため、意図せぬ不正データが発生することを防止できます。

# よくなかったこと
## 定義ファイル更新のコンフリクトが起きる可能性がある
Protocol Bufferでの構造体(message)定義では、フィールドの順序を決める必要がありますが、開発タイミングによってはこの順序がコンフリクトする可能性があります。

例えば以下のような検索サービスに対するリクエストメッセージの定義があったとします。
```proto3
message SearchRequest {
  string query = 1;
}
```

ここで検索結果の数を制御するcountというフィールドを追加する要件が生まれたとすると、定義は以下のようになります。

```proto3
message SearchRequest {
  string query = 1;
  int32 count = 2;
} 
```

一方で結果の並び順を制御するorderというフィールドを追加する要件が発生し、その要件を受け取った人はcountの要件を知らないと以下のような定義を書いてしまうと、フィールドの番号が被ってしまいます。

```proto3
message SearchRequest {
  string query = 1;
  string order = 2;
} 
```

これくらいであれば後から話し合って調整することも可能ですが、より複雑なケースでは非常に面倒なことになります(同名のフィールドに別の意味を与えるとか)。

この問題については全体に目を配って早め早めに調整するしか手はないかなと思っています。

## うっかり古い定義が混ざってもすぐに気づけない
新旧の定義が混ざった時にすぐにエラーとなってくれればよいのですが、なんとなく動いてしまうケースも多く、原因にたどり着くのに時間がかかることがありました。
ただこれはgRPC固有の問題ではなくHTTPでも起こり得ます。

## バイナリ通信であるがゆえに起きる諸々
gRPCはバイナリ通信なので、通信経路の途中でログを出すといったことが出来ないというのは地味に辛いです。
それと気軽にcurlで叩いて動かすということが出来ないため、疎通確認が面倒だったりします。
接続確認のためのPING-RPCを定義して、疎通用としていますが、それでもcurlに比べると面倒です。
そのほか普通のHTTPと比べるとやはり周辺ツールの不足というものは感じます。

# gRPCは使う価値があるか
特有の問題点はあるもののJSONやFORMと比べた時、やはりProtocol Buffersによる定義があることは非常に有利に思います。
運用を続けて行くうちにトラブルに遭遇することはあるでしょうが、サーバー間通信についてはgRPCを利用する価値はあると考えています。
C++ Builder > thisを書く派 > this->Height > 検索するときを考慮

```txt:動作環境
C++ Builder XE4
```

### 関連

[thisを書く派？書かない派？](https://qiita.com/askyq/items/bc63c70fb58fac7da794)

### C++ Builderにて

```cpp
this->Height = 400;
```

フォームのHeightなどを変更する時にthisを使っている。

昨日のデバッグ作業時、thisをつけていたため、バグフィックスは10分で済んだ。

thisをつけない場合「Height」で検索することになる。
NormalHeight, defaultHeight, AdjustHeightなど「Height」が含まれる変数などが検索に引っかかると、検索時のノイズになる。
「this->Height」にしておくことで、該当箇所のみを検索候補に挙げることができると考えている。

後ろに空白を付けた「Height 」などで検索するという案もあるかもしれないが、下記の二つ目で検索に失敗する（コーディングルールがそろってない場合など）。

```
Height = 400;
Height=400;
```

### 理由

僕の場合は、コーディング時に将来の検索性を重要視している。
検索性が高いコードは保守作業が楽であり、自分の「未来の時間」を増やすことができると考えている。

http://www.qmss.jp/interss/03/materials/senvita.htm
> セネカ『人生の短さについて』
> ...
> しかし、われわれは短い時間をもっているのではなく、実はその多くを浪費しているのである。
cron で、stderr への出力をログに入れる方法

次のプログラムをcron で実行した時のログの取り方です。

```py3:cron_test.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	cron/cron_test.py
#					Nov/22/2017
#
# ----------------------------------------------------------------
import sys
import datetime
#
# ----------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
time_aa = datetime.datetime.now()
#
print (time_aa)
#
sys.stderr.write("*** 終了 ***\n")
#
# ----------------------------------------------------------------
```

標準出力だけをログに入れる場合

```text
*/2 * * * * /home/uchida/cron/cron_test.py > /tmp/cron_a.log
```

ログ出力

```text:cron_a.log
2017-11-22 08:32:01.268014
```

標準出力と、stderr　をログに入れる場合

```text
*/2 * * * * /home/uchida/cron/cron_test.py > /tmp/cron_b.log 2>&1
```

ログ出力

```text:cron_b.log
*** 開始 ***
*** 終了 ***
2017-11-22 08:27:01.748117
```
【Python】RoboBrowserを使ってナナコの残高を Slack に送る


この記事は[RoboBrowserを使ってWebページにログインしてクローリング - TIL](http://tmg0525.hatenadiary.jp/entry/2017/11/07/022837)の転載です

---

最近、下の本を読んでいる。RoboBrowserと言うものがあるらしいので、使ってみたときのメモ

[Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド- | 加藤 耕太 |本 | 通販 | Amazon](https://www.amazon.co.jp/exec/obidos/ASIN/4774183679/hatena-blog-22/)

なんか、フォームに入力したりするときには Requests で行うのは面倒らしいので、 RoboBrowser を使用するっぽい。

[jmcarp/robobrowser](https://github.com/jmcarp/robobrowser)


## インストール

```
pip install robobrowser
```

RoboBrowserは内部でBeautifulSoupを使用しているため、BeautifulSoup4とRequestsは一緒にインストールされる

## nanacoのサイトにログインし、残高確認をしてみる

RoboBrowserを使ったプログラムの作成で、nanacoのサイトにログインして、残高を表示するプログラムを作ってみた

ソースはGitHubにあげた

[tamago324/post_nanaco_slack: Get nanaco balance info](https://github.com/tamago324/post_nanaco_slack)

### フォームの送信

フォームを送信するには、まず、フォームを取得する。フォームを取得するには`RoboBrowser.get_form()`を使う。引数にformのidを渡すことでフォームを取得できる。

#### ログインのフォームを取得する

```python
>>> from robobrowser import RoboBrowser
>>> browser = RoboBrowser()
>>> browser.open('https://www.nanaco-net.jp/pc/emServlet')
>>> form = browser.get_form(id='login_card')
>>> form
<RoboForm _PageID=SCBS_PCB1001, _DataStoreID=DSBS_PCB1001_Control, _SeqNo=1509980487174_[ACTIVE]_ExecuteThread:__19__for_queue:__weblogic.kernel.Default_(self-tuning)___, _ControlID=BS_PCB1001_Control, _WID=NoWID, _ORGWID=, _WIDManager=, _preProcess=, _TimeOutControl=, _WIDMode=0, _WindowName=, _ReturnPageInfo=, XCID=, SECURITY_CD=, ACT_ACBS_do_LOGIN2=>
```

#### テキストボックスに入力する

テキストボックスの name を指定し、value属性に値を代入する

```python
>>> form['XCID'].value = '1234567891234567'
>>> form['SECURITY_CD'].value = '1234567'
```

#### フォームの送信

送信するときには`RoboBrowser.submit_form()`を使う。引数に値を入力したフォームを渡す。送信後の状態が browser に入っているため、selectなどで要素を取得できる。

```python
>>> browser.submit_form(form)
>>> browser.select('#cardzan > span.time')
[<span class="time">2017年11月05日23時59分時点</span>]
```

あとはごちゃごちゃ取っていく(適当)

---

書いている最中になんかエラーが出た

### エラー内容

```sh
/Users/tamago324/.local/share/virtualenvs/robobrowser-zDYVPytv/lib/python3.6/site-packages/bs4/__init__.py:181: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("html.parser"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.

The code that caused this warning is on line 60 of the file nanaco_zan.py. To get rid of this warning, change code that looks like this:

 BeautifulSoup(YOUR_MARKUP})

to this:

 BeautifulSoup(YOUR_MARKUP, "html.parser")

  markup_type=markup_type))
Traceback (most recent call last):
  File "nanaco_zan.py", line 60, in <module>
    main()
  File "nanaco_zan.py", line 13, in main
    loginedForm = login(browser)
  File "nanaco_zan.py", line 40, in login
    browser['XCID'].value = NANACO_NUM
TypeError: 'RoboBrowser' object is not subscriptable
```

### 解決策

**インスタンス生成時にparserを指定すればいいらしい**

```python
>>> browser = RoboBrowser(parser='html.parser')
```

[python - Robobrowser BeautifulSoup error - Stack Overflow](https://stackoverflow.com/questions/44698274/robobrowser-beautifulsoup-error)
paiza.ioでpython

#概要
paiza.ioでpythonやってみた。
モジュール調べてみた。

#python2の場合

https://paiza.io/projects/ybQ_DOY1GjTPJvN5opY_5g

```
Python: 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609]
scipy: 0.17.0
numpy: 1.11.0
matplotlib: 1.5.1
pandas: 0.20.3
```

#python3の場合

https://paiza.io/projects/TqkE-NmqQzbfPweBsbXlOw

```
Python: 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609]
scipy: 0.17.0
numpy: 1.11.0
matplotlib: 1.5.1
pandas: 0.20.3
```

#サンプルコード

```
import sys
print ('Python: {}'.format(sys.version))
import scipy
print ('scipy: {}'.format(scipy.__version__))
import numpy
print ('numpy: {}'.format(numpy.__version__))
import matplotlib
print ('matplotlib: {}'.format(matplotlib.__version__))
import pandas
print ('pandas: {}'.format(pandas.__version__))
import wave
import time
import random
import os
import json
#import thread
import PIL
import zipfile
import argparse
import math
import uuid
import glob
import csv
import gzip
import collections
import re
import tarfile
import threading
#import Image





```

以上。
MATLAB: acos(44) > 0.0000 + 4.4772i   | Numpy: np.arccos(44) > nan

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

### MATLAB

```
>> acos(44)

ans =

   0.0000 + 4.4772i
```

https://jp.mathworks.com/help/matlab/ref/acos.html?lang=en
>  For real values of x outside the interval [-1,1] and for complex values of x, acos(x) returns complex values. All angles are in radians.

[-1, 1]の外の値なので、複素数を返す。
この複素数の計算が不明。

### Numpy

https://ideone.com/Fwve8H

```py
import numpy as np

res = np.arccos(44)
print(res)
```

```txt:run
nan
```

Numpyの場合はnanを返す。

### TODO

~~[ ] MATLABでのacos()の複素数値の意味~~

自分が扱う問題では[-1, 1]の範囲内になりそうなので調査は保留とする。
MacのショートカットキーとCheatSheet紹介


## 1. ショートカットキーで使うキーの記号について
https://support.apple.com/kb/PH18802?locale=ja_JP&viewlocale=ja_JP

【一部抜粋】
command：⌘ [^1]
[^1]: コマンドキー：スカンジナビア半島で一般的に観光地のマークとして使用されているものらしい。元々Appleのロゴが書かれたりもしてたが、ジョブズが違う記号にしろ、と指示して探してきたものだそう。特に深い意味はなさそう。
control：⌃ [^2]
[^2]: コントロールキー：wikiによると、従来controlキーを押すと、生成されるASCIIの下位5ビット以外がゼロとなり、ASCIIの非表示文字である最初の32文字 (0x00 - 0x1f) を生成、入力できたらしい。排他的論理和が^を使うので、おそらくそれが由来だと思われる。（多分0x1fと排他的論理和をとって否定を取る処理が由来な気がするがソースは検索してもなかったので不明）
option：⌥ [^3]
[^3]: オプションキー：由来は[ここ](https://www.quora.com/Computer-Keyboards/What-is-the-origin-of-the-Macs-option-key-symbol-%E2%8C%A5)に記載の通り、斜線部分が右上/右下と左上の線を繋ぐスイッチを示していて、それを選択するオプションという意味合いらしい。windowsのaltキー相当
shift：⇧ [^4]
[^4]: シフトキー：上にずらす（＝シフトする）が由来らしい。大文字にしたり、数字の所の上側に書いてある記号を入力したりするのに使う。似たようなのにCaps Lock(⇪)があるが、これは用途的にはシフト押しっぱなしで、シフトキーマーク[⇧]を何回も押しているイメージ
escape：⎋ [^5]
[^5]: エスケープキー：丸の中から抜け出すの意味。キーボードの大体左上にあるのでそれも合わせると覚えやすい

## 2. ショートカットキーをすぐに確認できるアプリ
[こちらの記事](https://qiita.com/MMMMMonchi/items/dd72e32fc8e69bcdf411)でも紹介されているが、CheatSheetというアプリを入れておくと、command(⌘)キー長押しでショートカット一覧が表示されるようになる。サクッと確認したい場合には便利。
ダウンロードURL：http://www.cheatsheetapp.com/CheatSheet/

表示されるのは以下のようなものになります。
![ショートカットキー一覧.png](https://qiita-image-store.s3.amazonaws.com/0/188222/eadaefa4-6549-d1e3-12ac-7b9f197b45c9.png "ショートカットキー一覧.png")

## 3. 覚えておくと便利なショートカット
#### (1) スクリーンショット関係
[ここ](http://yoshizo.hatenablog.com/entry/16-ways-to-take-your-macintosh-screen-shot-with-keyboard-shortcuts/)がよくまとまってます。調べて初めて知ったんですが、スペースつけるとウィンドウを指定して撮るとかできるんですね。
#### (2) controlキー＋ファンクション関係(⌃+Fn)
control+F2：メニューを選択状態にする。returnを押して矢印キーで移動するとマウスを触る必要がない
control+F3：Dockを選択状態にする。矢印キーで移動してreturnで該当のアプリを起動できる
その他については、システム環境設定＞キーボード＞ショートカットキーのキーボードを見ると確認が可能
![ショートカットキーの確認.png](https://qiita-image-store.s3.amazonaws.com/0/188222/736d292e-0ded-9536-7f06-9f68284865e9.png "ショートカットキーの確認.png")
## 4. やっておくと便利なこと
特定のアプリにショートカットキーの割り当てをしておくと便利
参考URL：https://qiita.com/hkengo/items/39433881d842578b7ade
JJUG CCC 2017 Fall モブプロ・アンカンファレンス 参加メモ

#日本最大のJavaコミュニティ主催1DAYイベント
[JJUG CCC 2017 Fall](http://www.java-users.jp/ccc2017fall/ "JJUG CCC 2017 Fall") の参加メモです。
[#JJUG_CCC](https://twitter.com/hashtag/jjug_ccc "#JJUG_CCC")
今回は、モブプロとアンカンファレンスという参加型のみだったので
どちらも[マインドマップ](https://www.mindmeister.com/?r=438493 
"マインドマップ")でメモ。
##参加セッション
1. モブプロで実施する Cognitive Service & Bot ハッカソン #1 #2
[#ccc_i1](https://twitter.com/hashtag/ccc_i1 "#ccc_i1") [#ccc_i2](https://twitter.com/hashtag/ccc_i2 "#ccc_i2")

1. アンカンファレンス③
[#アンカンファレンス](https://twitter.com/hashtag/アンカンファレンス "#アンカンファレンス")
テーマ
 1. お仕事の働きがいについて
 2. 勉強会について
 3. ScalaMaturiへのお誘い

## メモ
###1.モブプロで実施する Cognitive Service & Bot ハッカソン #1 #2

マップにメモ。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/0O3R0ohfWl">https://t.co/0O3R0ohfWl</a></p>&mdash; SunFuji_test (@SunFujiTest) <a href="https://twitter.com/SunFujiTest/status/935180876542967809?ref_src=twsrc%5Etfw">2017年11月27日</a></blockquote>

Twitterのはめ込みURLがうまく表示れなくなるケースがあるので下に画像ものせました。
(見づらいので実際のマインドマップをちょくで見るのがよいです)

![コグニティブサービスAPI&モブプロのマップ](https://qiita-image-store.s3.amazonaws.com/0/215413/7c23e081-c8ea-197f-8596-8a0ccc8185b2.png)



マップ(mindmeister.com)で確認する場合
アカウント未作成の場合「[MindMeister](https://www.mindmeister.com/?r=438493 
"MindMeister")」でアカウント作成。
実際のマインドマップ:「[コグニティブサービスAPI&モブプロのマップ](https://www.mindmeister.com/ja/992858422?t=DwbLA4Pe1v "コグニティブサービスAPI&モブプロのマップ")」

###2.アンカンファレンス③
テーマ募集で「お仕事の働きがいについて」を応募して、採用されたので参加。
マップにメモ。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/nBa67gn55R">https://t.co/nBa67gn55R</a></p>&mdash; SunFuji_test (@SunFujiTest) <a href="https://twitter.com/SunFujiTest/status/935180817600360448?ref_src=twsrc%5Etfw">2017年11月27日</a></blockquote>

Twitterのはめ込みURLがうまく表示れなくなるケースがあるので下に画像ものせました。
(見づらいので実際のマインドマップをちょくで見るのがよいです)
![アンカンファレンス③1.お仕事の働きがいについて](https://qiita-image-store.s3.amazonaws.com/0/215413/30e4ffe9-698c-11b2-691a-7ddd08497c15.png)


実際のマインドマップ:「[アンカンファレンス③1.お仕事の働きがいについて](https://www.mindmeister.com/994758022/1 "アンカンファレンス③1.お仕事の働きがいについて")」

##感想
###1.全般
JavaEEのセッションが少なかった、Springのセッションが増えた。

###2. モブプロで実施する Cognitive Service & Bot ハッカソン #1 #2
#### コグニティブサービスAPI
かなり魅力的、導入のしやすさもあって音声解析・翻訳試したい。
自分の動機が、英語が苦手っててところがちょっと残念だけど、各社切磋琢磨／利用者も貢献して、翻訳こんにゃく目指して精度もっとあげたい。
#### モブプログラミング
ペアプロですら未経験だったので、疲れたけど楽しかった。
喋りたい欲。指摘したい欲。なんか言いたい欲。チームに貢献したい欲。
みんなでやったー出来たーって言いたい欲。
いろいろ満たされました。
#### その他
JavaDayTokyo2017のときも感じたけどハンズオンは集客が弱いのかな。
2013年(4年前)のJJUGCCCで、寺田さんのGlassFish4+JavaEE7の
ハンズオンに参加したときはほぼ満杯だったな。
あのころのJavaEEの勢いがほしいところ。

###3.アンカンファレンス③お仕事の働きがいについて
今の会社では働き方改革が一段落ついてきて(方向性が見えた感じ)<br>次は働きがい改革が必要になってくるとおもって応募。
重たいテーマかなーと思いつつ、勉強会とつながっていい感じで進すすみました。
勉強会にはロールモデルになる人いっぱいいていい！
社内メンバーへの勉強会への参加呼びかけ方法に再考が必要になった。

働き方改革すら、ままならないケースは世の中にはまだまだある。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">プロフェッショナル　仕事の流儀「過労死と闘い、命を守る～弁護士・川人博～」<a href="https://t.co/gvEImRIg1c">https://t.co/gvEImRIg1c</a></p>&mdash; SunFuji_test (@SunFujiTest) <a href="https://twitter.com/SunFujiTest/status/935359669043830784?ref_src=twsrc%5Etfw">2017年11月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Golangで書いたweb以外のプログラムをheroku上で動かす

# やったこと
[heroku](https://www.heroku.com/)にGolangで作ったプログラムをデプロイしました。

herokuはwebアプリしかデプロイできないと思っていたのですが、普通のプログラムもheroku上で動かせるというのを知りました。
とりあえず記事にします。

#必要なもの
・Golangで書いたプログラム

・herokuCLI <- これはherokuのチュートリアルでインスコしていると思います

・[godep](https://github.com/tools/godep)

```
go get github.com/tools/godep
```
でインストールできます。
###いきなり余談
heroku コマンドで
<img width="598" alt="エラーメッセージ" src="https://qiita-image-store.s3.amazonaws.com/0/143170/a65b9bfe-5daa-1ad9-cb20-225e2802f9a2.png">
こんなエラーが出たら
[この記事](https://qiita.com/yoshixj/items/9c38d023d49c24d33820)を見て、herokuCLIをアップデートしましょう。

#本番
demoappディレクトリに
`main.go`があるとします。

この時、パッケージはGOPATH以下に存在しないと行けないようです
**1.**

```
$echo 'worker: demoapp' > Procfile
```

と実行してください。workerというプロセス名にすることで、webアプリでないものも動かせるようになります。

**2.**

```
$godep save
```

と実行してください。
これでライブラリなどの依存関係がまとめられます。

**3.**

```
$heroku create --buildpack https://github.com/heroku/heroku-buildpack-go.git
```

と実行してください。
`--buildpack https://github.com/heroku/heroku-buildpack-go.git`
は、godepを使用する限り絶対に付けないといけないオプションです。

**4.**

```
$git init
$git add .
$git commit -m "first commit"
$git push heroku master
```
これを実行すればデプロイ完了です！

****

<img width="1254" alt="herokuの管理画面" src="https://qiita-image-store.s3.amazonaws.com/0/143170/f6c9b38d-1cd2-6181-2455-fb139e35eb09.png">
ダッシュボードのResourcesタブを見ると、workerがあります。
右のペンのボタンを押してトグルをオンにし、confilmを押すと稼働します。
ログは右上のMoreボタンの「View logs」より確認できます〜！！
#エラー
pushする際に

```
fatal: 'hoge' does not appear to be a git repository云々
```
などと出て来た場合は

```
//アプリケーション名はherokuサイトのダッシュボードから確認できます
git remote add heroku https://git.heroku.com/アプリケーション名.git
```
を実行してください。
[https://qiita.com/sayama0402/items/e2c9e65786259dc55e11](https://qiita.com/sayama0402/items/e2c9e65786259dc55e11)
俺が実現したMySQL 5.5 to Auroraマイグレーション

46億のmysqldump愛好家な皆様こんばんわ
ちょっとMySQLデータベースの移行経験ある俺です。ワタシチョットイコウデキル

ついに俺でもわかるシリーズタグの記事が30本目を迎えました。
俺以外の俺達も俺でもわかるシリーズタグをつけて記事書いてくれたこともあり、感謝の24365なエブリデイです。

記念にMySQL 5.5の環境からAuroraへダウンタイムを抑えて移行する方法を書き残します。
今回の例ではオンプレミス環境からAWSをターゲットとしていますが、AWS to AWSも可能です。

詳しく知りたい方は[弊社](http://www.andgate.co.jp)の俺宛に連絡下さい。
ひょっこりノコノコ伺いに行くと思います。

# 過去Auroraへの移行を実現した手段

- [このへん](https://qiita.com/gamisan9999/items/42da32f2ecd449a8d0b8)
- [この記事](https://qiita.com/gamisan9999/items/1113d8b4b88cd4c935c2)

# 今回の構成

こんなかんじです。
データセンターとVPC間はインターネット接続なのでstunnelでトンネルはってます。
VPN Connection/Direct Connectでセキュア, 高速回線引いておいても良いです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/167fdd5d-e045-8880-5069-568cded8ec7d.png)

レプリケーションパターンでふつうに移行するとこんな流れになります

# MySQL 5.5の環境をふつーにAuroraへ持っていく場合

## 事前準備

事前準備においてしんどいのは
MySQL 5.5 on EC2へのデータリストア, MySQL 5.6へのバージョンアップとAuroraへのリストアです。
移行対象のDBクラスタが多いほど辛みが増します。

### 事前複製作業

1.MySQL 5.5環境をターゲット環境に作る
2.ソース環境のMySQL 5.5からmysqldumpを使ってDBをバックアップする
3.バックアップしたDBデータをターゲットのMySQL 5.5環境へリストアする
4.ターゲット環境にAuroraを準備してバックアップしたDBデータをリストアする
5.ターゲット環境のMySQL 5.5をMySQL5.6へバージョンアップする

### 事前レプリケーション作業

6.ターゲット環境のAuroraとMySQL 5.6とレプリケーションする。
7.ターゲット環境のMySQL 5.5環境をMySQL 5.6にバージョンアップする
8.ターゲット環境のMySQL 5.6環境からソース環境のMySQL5.5にレプリはる
9.レプリケーションエラーなく同期できることをチェックする

## 切替当日

10.レプリケーションエラーの有無をチェックする
11.アプリをメンテに入れる
12.レプリケーションを止める
13.アプリエンドポイントを切り替える
14.裏口からアプリ動作チェック、データ整合性チェックする
15.アプリのメンテを解除する
16.ソース環境とターゲット環境のMySQLレプリケーションを停止して、環境を破棄する。
17.最高

# MySQL 5.5からAuroraへの移行にDMSを使う

ちょっと楽するためにData Migration Service(DMS)を使います。
DMSを使った流れは以下の通りになります。

## 事前準備

DMSを使うことでAuroraへのデータリストアをすっ飛ばすことができますいえいいえい

### 事前複製作業

1.MySQL 5.5をターゲット環境に作る
2.ソース環境のMySQL 5.5からmysqldumpを使って移行対象のDBデータ(mysqldump dbname)とDDL(mysqldump --no-data)をバックアップする
3.バックアップしたDBデータをターゲットのMySQL 5.5環境へリストアする
4.ターゲット環境にAuroraを準備してbinlogを有効にする
5.バックアップしたDBのDDLをAuroraにリストアする

### 事前レプリケーション作業

6.ターゲット環境にDMSインスタンスを準備して以下の条件でDMSレプリケーションを実行します
ソース: ターゲット環境のMySQL 5.5
ターゲット: Aurora
レプリケーション方法: フルロード,フルロード後はCDC
※補足: DMSのソースDBをオンプレミス環境のMySQL5.5にすることも可能ですが、レプリケーション異常発生時の切り分けを、DMS依存のものなのか、オンプレミス<->VPCネットワーク障害なのか切り分けしやすくするため、EC2にMySQL5.5環境を作っています。

7.ターゲット環境のMySQL 5.5環境からソース環境のMySQL5.5にレプリはる
8.MySQLレプリケーション/DMSレプリケーション両方エラーなく同期が継続していることをチェックする

## 切替当日

9.レプリケーションエラーの有無をチェックする
10.アプリをメンテに入れる
11.DMSレプリケーションを止める
12.アプリエンドポイントを切り替える
13.裏口からアプリ動作チェック、データ整合性チェックする
14.アプリのメンテを解除する
15.ソース環境とターゲット環境のMySQLレプリケーションを停止して、環境を破棄する。
16.最ッッッ高ッッ！

# DMS利用時の注意点

DMSにはいくつか制約があります。どんな制約があるかはここには書きません(DMSの機能も定期的に更新されていくので)

必ず`移行計画時点でドキュメントをチェック`し、移行対象の環境で制約があてはまらないことを確認してください。
当てはまる場合は回避できるように対応をしてください。

- [MySQL 互換データベースの AWS Database Migration Service のターゲットとしての使用](http://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Target.MySQL.html)
- [移行タスクのトラブルシューティング](http://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Troubleshooting.html)

良い移行ライフを！

完