OmniAICreator/Qiita-1.07M huggingface dataset:
業務用管理画面の開発・改善案件を受ける際のpros/cons

「社内で業務で使っている管理画面を改善したいんですけどー」的な案件が好きで昔からよく受けているんですが、その中で感じているpros/consを簡単にまとめてみた。
（issueレビュー待ちの時間つぶし）

# pros

## 利用ブラウザを強いることができる

- 社内向けのサービスなので、toC向けのサービスと違って「Chromeを使ってください」的なことを言える
- 今回初めて`Array.prototype.find()`を使ってみたんですが、これ便利ですね。IE氏ね。

## その業種独特の業務内容を知ることができる

- 知らないと良い管理画面なんて作れない
- これがけっこう面白い。学び

## 「作業効率の改善」を目的としていることが多く、効率化大好き人間にはたまらない

- 「コンバージョン率を上げる」「売上を上げる」みたいな目的に比べて達成しやすい
- そしてそもそも現状がダメダメだから依頼がくるのであって、けっこうシンプルな解決法でも簡単に成果が出せる
- ちなみに「作業時間が半分になったら、その分の人件費がそのまま利益となるんですよ」的な話をよくしてます
    - その分の人件費を削れという話ではなく、浮いた時間をもっと建設的な業務に回そうぜというお話

# cons

## **ポートフォリオに載せられない！！！！**

- 「こんなものを作りました！」って言えないのは微妙に辛み。
    - まぁ、ポートフォリオなんて作ってないんですけどね。
- それでも、自分的に「良いものできた！」と思ってても世間のみなさんには使ってもらえないのは悲しみ
【python】virtualenv作成手順メモ

同一サーバー上で、異なるライブラリのバージョンに依存しているプロジェクトを持つことが多かった。そこで、virtualenvを用いて、独立したPython環境を指定できるようにするのが便利なため、その手順のメモ。

## virtualenvのインストール

```
 $ sudo conda install virtualenv
# $ sudo pip install --upgrade virtualenv (pipの場合)
```

## virtualenvの環境の作成

```
 $ virtualenv --system-site-packages targetDirectory # for Python 2.7
 $ virtualenv --system-site-packages -p python3 targetDirectory # for Python 3.n
```

## virtualenv環境のアクティベート

```
 $ source targteDirectory/bin/activate
```

これによって、プロンプトが以下のように切り替わる

```
(targteDirectory)$
```

## virtualenv環境のディアクティベート

```
(targteDirectory)$ deactivate
```
TypeScript 2.5.2 更新点


こんにちは[@vvakame](https://twitter.com/vvakame)です。
今回は薄味更新という感じですね。

[TypeScript 2.5.2](https://blogs.msdn.microsoft.com/typescript/2017/08/31/announcing-typescript-2-5/)がアナウンスされましたね。

[What's new in TypeScriptも更新](https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#typescript-25)されているようです。

わかめさんも久々に[PR送った](https://github.com/Microsoft/TypeScript/pull/17394)りしました。

## 変更点まとめ

* try-catchの例外のキャプチャが省略できるようになった [Optional catch binding](https://github.com/Microsoft/TypeScript/issues/17467)
	* `try { ... } catch { ... }` がvalidに(es仕様に準拠
* jsに対してコメントによる型注釈・キャストのサポートを追加 [Assertion/cast JSDoc syntax in checkJs mode](https://github.com/Microsoft/TypeScript/issues/5158)
* より賢いpackage解決 [For duplicate source files of the same package, make one redirect to the other](https://github.com/Microsoft/TypeScript/pull/16274)
	* package.jsonのnameとversionを見るようになった
* 参照先packageがsymlinkだった場合realpathではなく指定したパスにファイルが存在するように振る舞う [Add "preserveSymlinks" option](https://github.com/Microsoft/TypeScript/pull/16661)
	* Node.jsの--preserve-symlinksと一緒
* 関数の切り出しとメソッドの切り出しのリファクタリングの追加 [Refactoring to extract functions & methods](https://github.com/Microsoft/TypeScript/pull/16960)
* JSDocスタイルの型注釈を書いてしまった時にTypeScriptの型注釈に変換するQuick Fixの追加 [correct references to types of properties](https://github.com/Microsoft/TypeScript/pull/17250)
* ある型のプロパティの型の参照はインデックスアクセスの形式しか許されていないが、ドットアクセスで書いてしまった時に変換するQuick Fixの追加 [correct uses of JSDoc types to TypeScript types](https://github.com/Microsoft/TypeScript/pull/17462)

## try-catchの例外のキャプチャが省略できるようになった

[今Stage3のやつ](https://tc39.github.io/proposal-optional-catch-binding/)

```ts
try {
  JSON.parse("あかんやつ");
} catch {
  console.error("あかんかった…");
}
```

## jsに対してコメントによる型注釈・キャストのサポートを追加

わかめさんは余り興味ないやつですね

```js
// @ts-check

const a = /** @type {string[]} */ ([]);
a.push("a");
// error TS2345: Argument of type '1' is not assignable to parameter of type 'string'.
a.push(1);
```

## より賢いpackage解決

Nodeモジュールとしてnode_modules配下に同じパッケージ同じバージョンへの参照がある場合、複数回処理せず過去に処理済みのものへのリダイレクトとして扱われるようになる。
これによりメモリ効率や処理速度の向上とprivateなフィールドについて期待通り互換性のあるものとして扱われるようになる。

## 参照先packageがsymlinkだった場合realpathではなく指定したパスにファイルが存在するように振る舞う

Node.jsの同名のオプションと同じふるまいなので[そっち見てくれ](https://nodejs.org/api/cli.html#cli_preserve_symlinks) だそうです。
Webpackの `resolve.symlinks` と真偽値が逆なので注意な！らしいです。

## 関数の切り出しとメソッドの切り出しのリファクタリングの追加

そのまんまです。[公式](https://blogs.msdn.microsoft.com/typescript/2017/08/31/announcing-typescript-2-5/)のgif動画見てもらえばいいと思います。

この機能は次のVSCodeのアップデートで使えるようになるそうな。

[PR](https://github.com/Microsoft/TypeScript/pull/16960)のdescriptionにRyanが画像作って貼ってるんだけど雑な矢印が描かれていて味がある。

## JSDocスタイルの型注釈を書いてしまった時にTypeScriptの型注釈に変換するQuick Fixの追加

```ts
let foo: *;
let bar: number?;
```

こういうのを書くと

```ts
let foo: any;
let bar: number | null; // or number | null | undefined;
```

に修正できます。

## ある型のプロパティの型の参照はインデックスアクセスの形式しか許されていないが、ドットアクセスで書いてしまった時に変換するQuick Fixの追加

長い。

```ts
interface Foo {
    value: string;
}

let fooValue: Foo.value;
```

こういうコードを書くとエラーになる。

```ts
interface Foo {
    value: string;
}

let fooValue: Foo["value"];
```

Quick fixを適用するとこうなる。
EC2 SGのインバウンド・アウトバウンドに説明の項目が追加されてるー

# IP見ただけでどこのIPかなんて把握できるか:japanese_goblin:
これはうちのシステムのあるSGのインバウンドルールです。
IPは白塗りしています。
<img width="1103" alt="c63fe2e4-b30f-1d38-8198-4b93e85a4bf5.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/3c337a84-efbe-8f05-30f6-bf311bb56a8b.png">

昨日までは説明の項目はなく画像の通りでした。
SSHを6IPから許容していますが、一体これがどこのIP誰のIPかさっぱりわかりませんでした。
オフィスのIPが変わったときもどのIPと入れ替えたらいいかわからず、さらに追加する始末です。


# 説明の項目ができたので説明を記述できる:blush:
<img width="1119" alt="6e890515-bff9-74af-56eb-6a5f12da1c84.png" src="https://qiita-image-store.s3.amazonaws.com/0/147005/23050852-6554-62d3-bc7a-ee51f2e4cbe4.png">

これによって無駄なルールを削除したり、
変更の際に一発でわかるようになったりします。

# 遅すぎる改良
まあでも文句言っても仕方ないんです。
Amazonサンキュー:v:

# 注意
現在以下の文字しか使えないらしい。
```256 characters from the following set: a-zA-Z0-9. _-:/()#,@[]+=&;{}!$*```
プレースホルダーの例に日本語入ってるのに！！！
静的サイトにおけるAzure BLOB Storageの各BLOBの選択について

ストレージサービスのAzure Storageでは、BLOB、テーブル、キュー、ファイルという4種類のストレージが提供されています。
そして、BLOBストレージ(Azure BLOB Storage)には以下の3種類があります。

* ブロック BLOB
    * `ドキュメント、ビデオ、画像、バックアップ、およびその他の非構造化テキストまたはバイナリ データのストリーミングと保存に利用します` (公式サイトより引用)
* ページ BLOB
    * `データ ディスクは Azure Storage にページ BLOB として格納される固定形式の VHD であり、永続データを格納するために仮想マシンで使用されます。` (公式サイトより引用)
    * 上記説明より、Azure Virtual Machines のデータ ディスク
* BLOB の追加
    * `追加 BLOB は、ブロック BLOB のようなブロックから成りますが、追加操作に最適化されています。 同じ BLOB に対して複数の VM から情報を記録するような用途に使用されます。` (公式サイトより引用)

上記説明から、静的サイトのファイルは `ブロック BLOB` で格納すれば良いと考えて、 `Azure Portal` から確認用のファイルを `ブロック BLOB` でアップロードしていました。
しかし、動作確認後に FTP クライアント(Mac なら Cyberduck)からサイトページをアップロードすると、ファイルは `BLOB の追加` でアップされてしまいます。
`Azure Portal` から1つ1つファイルをアップロードするという運用は普通しないため、 `BLOB の追加` でアップロードするのが今のところ正しいようです。

## 参考情報

* [Azure Storage Blob の価格 | Microsoft Azure](https://azure.microsoft.com/ja-jp/pricing/details/storage/blobs/)
* [Azure BLOB、Azure ファイル、または Azure データ ディスクを使用するタイミングの判断](https://msdn.microsoft.com/ja-jp/library/azure/dn790517.aspx)
* [Azure Storage の概要 | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-introduction)
Carthage使っててXcode9[beta]でストアにあげるとビルドが無効と言われるよ

https://t.co/S0q7gUxgOV

問題となるのはこれ
https://forums.developer.apple.com/thread/81893

Carthage側の対応がfixするまでは一旦cocoapods側の方を使うなどして回避しましょう。
Promise.all()という選択肢

# はじめに

「AWS-SDK for Node」を利用してよくAWSのサービスを利用しているのですが、基本的にPromiseを使ってリクエストを投げてます。そんなとき配列を一行ごとにPromiseで処理しなければならん事案が発生したので、そういや「Promise.all()」とかあったなーと思いつつ、教えてもらったりしたので備忘録的に残しておく(すんごい今更だろうけど)

## やりたいこと

```data.json
[
  {"id": "aaa", "value": "1234"},
  {"id": "bbb", "value": "3456"},
  {"id": "ccc", "value": "5678"}
]
```
上記のようなJSON配列を1行ごとにDynamoDBにPUTしていきたかった。


## 実際に書いてみた

```js:main.js
const AWS = require("aws-sdk");
const co = require("co");
const dynamodb = new AWS.DynamoDB.DocumentClient({
  region: "ap-northeast-1"
});
const dynamoPutData = require("./dynamo_put_data")

co(function *(){
  data = [
    {"id": "aaa", "value": "1234"},
    {"id": "bbb", "value": "3456"},
    {"id": "ccc", "value": "5678"}
  ];
  Object.keys(data).foreach((key) => {
    const item = data[key];
    return yield dynamoPutData.putDynamoDB(dynamodb, item);
  });
}).then(() => {
  console.log("success");
}).catch((err) => {
  console.log(err);
});
```

```js:dynamo_put_data
class dynamoPutData {
  /**
   * @param {DocumentClient} dynamoDB
   * @param item
   * @returns {Promise}
   */
  static putDynamoDB(dynamoDB, item) {
    return new Promise((resolve, reject) => {

      console.log("put");

      const params = {
        TableName: "foobar-json",
        Item: item
      };
      console.log(params);
      return dynamoDB.put(params, (err, data) => {
        if (err) {
          console.log(err);
          return reject(err);
        } else {
          console.log(data);
          return resolve(data);
        }
      });
    });
  }
}
```

まぁこんな書き方したら間違いなく怒られる
だってforeachの中でpromiseを返そうとしているから
シンタックスエラーとかがエラー文に並ぶのではないかな

## そんなあなたにPromise.all()ですよ

Promise.all()を使って書くとこうなる

```js:main.js
const AWS = require("aws-sdk");
const co = require("co");
const dynamodb = new AWS.DynamoDB.DocumentClient({
  region: "ap-northeast-1"
});

co(function *(){
  data = [
    {"id": "aaa", "value": "1234"},
    {"id": "bbb", "value": "3456"},
    {"id": "ccc", "value": "5678"}
  ];
  // Promiseの処理を配列に格納
  const promises = Object.keys(data).map((key) => {
    const item = data[key];
    return dynamoPutData.putDynamoDB(dynamodb, item);
  });
  // promisesを実行
  return yield Promise.all(promises);
}).then(() => {
  console.log("success");
}).catch((err) => {
  console.log(err);
});
```
あらかじめpromisesにPromiseの配列を用意しておいて、Promise.all()で実行させることによって、promisesの処理を実行し、すべての処理が終わるまで次の処理を待ってくれます
これでJSON配列をPromiseで処理させることができました

# まとめ

やりたいとこはこれで叶ったわけですが、非同期で処理をしているので、扱うデータによってはこれでは問題が発生してしまうことがあります。たとえば、時系列順での扱いがすごく重要なデータの場合などなど。ちゃんと時系列順に処理が完了しているかは保証がないですからね･･･そういうときにはひと工夫が必要ですね

ではまた！
Synthetic Response への画像埋め込みと日本語対応

Fastly では Synthetic Response 機能を用いることで、オリジンに依存することなくエッジサーバーよりレスポンスを返すことができます。オリジンレスのアプリケーション開発や、オリジンダウン時のエラーページ生成に活用できます。

#1. 基本的なSynthetic Response

Fastly ドキュメントの [Creating the custom response カスタムレスポンスの作成](https://docs.fastly.com/guides/basic-configuration/creating-error-pages-with-custom-responses#creating-the-custom-response) にあるとおり、Synthetic Response の作成はカンタン。

上記ドキュメントにしたがって、Fastly コントロールパネルの設定画面にて、HTMLのソースを入力し、条件を設定してください。オリジンレスのページが生成できます。

**図1. Create a synthetic response でのレスポンス指定**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89952/d24bff65-a498-545f-e213-83c3b0500600.png)

#2. 画像埋め込み

テキストのみの無味乾燥なレスポンスでは、サイトの中でそのページだけが、デザイン的に浮いてしまいます。画像ファイルを埋め込むことで、他のページと統一感のあるデザインにアップグレードしてみましょう。

画像ファイルの URL を HTML（例： &lt;img src="/images/logo.png"&gt;）や CSS（例： background-image: url("/images/bg.png")）に指定すれば、埋め込み完了！

...といいたいところですが、画像の配信もオリジンレスにしなくて大丈夫ですか？オリジンダウン時にページは配信できても、埋め込まれた画像ファイルが配信不可となり、画像が表示されません。

**図2. オリジンダウンで「壊れた」画像**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89952/a96d2ed8-afa3-05c0-fa41-072eea297291.png)

#3. Data URI で埋め込み画像をオリジンレス化

[Data URI スキーム](https://ja.wikipedia.org/wiki/Data_URI_scheme) を用いると、別ファイルを参照する代わりに、BASE64でエンコードした画像をインラインで埋め込むことが可能です。

###CSS 埋め込み例

```
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAKCAYAAACT+/8OAAAAEklEQVR42mP8z8AARAjAOFgFABmeE/cGzVQmAAAAAElFTkSuQmCC);
```

###HTML 埋め込み例

```
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAKCAYAAACT+/8OAAAAEklEQVR42mP8z8AARAjAOFgFABmeE/cGzVQmAAAAAElFTkSuQmCC">
```

変換用ツールはオンラインで多数提供されていますが、ここでは2つ紹介しておきます。

* [Data URI Scheme 変換](https://hamayapp.appspot.com/static/data_uri_conv.html)
* [data: URI Generator](https://dopiaza.org/tools/datauri/index.php)

#4. Synthetic Responseのサイズ制限

Synthetic Responseのサイズには 64キロバイト の上限が設定されています。コントロールパネルにて、それをより大きい文字列を指定すると、超過部分を切り捨てた上で設定へ反映されます。

このサイズ制限に触れる場合には、複数の Synthetic Response に分割することで回避可能です。VCL ファイルそのものにも Fastly ではサイズ制限を設定しているため、分割による対応にも上限があります。ご注意ください。

※**『日本語対応』『数値文字参照による日本語対応』**は、Synthetic Response で Unicode (UTF-8) に対応したため、削除しました。Synthetic Response内で、UTF-8 にて日本語を直接記述することができます。[Unicode in VCL](https://www.fastly.com/blog/unicode-in-vcl) (英文) をぜひご一読ください。
rails: before_actionとは

\*scivolaさんよりいただいたコメントを参考に冒頭箇所一部編集しました。

#before_actionとは
<a href="http://guides.rubyonrails.org/action_controller_overview.html#filters" target="_blank">Action Controller Overview</a>によると`before_action`はフィルタリングとして定義されている。

>_if you set a filter on ApplicationController, it will be run on every controller in your application._
>_~~コントローラー上に（`before_action`を始めとした）フィルタリングを含めればアプリケーション起動時に毎回作動してくれる。~~_
>_`ApplicationController`に定義することによってアクション実行前に全てのコントローラーにフィルターがかかる。（scivola）_

##使用例
実装例の主な例としてユーザー認証などがそれに当たる:

```
class ApplicationController < ActionController::Base
  before_action :require_login
 
  private
 
  def require_login
    unless logged_in?
      flash[:error] = "You must be logged in to access this section"
      redirect_to new_login_url # halts request cycle
    end
  end
end
```
コントローラーに新たに`before_action`を追加することによって`require_login`が~~アプリケーション起動時~~（すでに定義されている各アクションの実行前）に作動してくれる。全てのユーザーから登録しているユーザーだけを**フィルタリング**している。

##onlyとexcept
しかし上のように表記してしまうと全てのページ移動においてユーザー認証を要する実装になってしまうので例えば新規会員登録したいユーザーにすら認証が入ってきてしまうというダブルバインディングな構造になってしまう。

>_For obvious reasons (the user wouldn't be able to log in in the first place!), not all controllers or actions should require this. You can prevent this filter from running before particular actions with skip_before_action:

```
class LoginsController < ApplicationController
  skip_before_action :require_login, only: [:new, :create]
end
```

対策として新規登録といったページではユーザー認証を任意的になくすことができる。`only: [:new, :create]`がそれに当たる。

>_The :only option is used to skip this filter only for these actions, and there is also an :except option which works the other way._
>_`only`と`except`は特定のフィルタリングをスキップさせたいときに使用する。_

#まとめ
まとめると`before_action`の役割は以下の通り:

- コントローラーに入れておけば~~アプリケーション起動時~~（すでに定義されているアクションが実行される前）に自動で作動してくれるフィルタリング。アクションの中身が重複していて且つ仕様頻度が高い場合は`before_action`として定義しておいたほうが効率よくコードの見栄えが良くなる。

- `only`や`except`を使えばより柔軟な実装も可能。
MySQLから特定のテーブルをダンプ、リストアするバッチファイル

MySQLから特定のテーブルのdump、restoreをしたいと思い、batファイルを作りました。
自分用にメモ。

##初期設定
以下変数を設定する。
binPath=XXXX　#MYSQL\binのパス
dbName=XXXX　#データベース名
tmpFile=target_　#dump対象のテーブル一覧を出力するファイル名の接頭辞

##使い方
1. batファイルを開く
2. モードを選択してください（dump:1 restore:2）:　どちらかを選択
3. **（dumpの場合）**ダンプを取りたいテーブル名を指定<br>※例えば「m_」と入力すると文字列「m_」が含まれるすべてのテーブル、ビューが対象となる。<br>batファイルと同じ場所に、対象テーブル一覧を記載したファイル（target_XXX.txt）とdump（dump_XXX.sql）が作成される。
4. **（restoreの場合）**「dump_」以降のダンプファイル名を入力してください（拡張子入力不要）

```bat:mysqldump&restore.bat
@ECHO OFF

REM 遅延環境変数を有効化
SETLOCAL enabledelayedexpansion

REM 各種設定
SET binPath=XXXX
SET filePath=%~dp0
SET dbName=XXXX
SET tmpFile=target_
SET tables=

REM モード選択
SET /P mode="モードを選択してください（dump:1 restore:2）: "

IF "%mode%" EQU "1" (
    ECHO mode:dump
    
    :DUMP
    SET /P tableName="テーブル名を入力してください: "

    REM カレントディレクトリをMySQL\binへ変更
    cd %binPath%

    REM バックアップ対象を抽出
    mysql -u root -h localhost -N information_schema -e "SELECT table_name FROM information_schema.tables WHERE table_schema = '%dbName%' AND table_name LIKE '%%!tableName!%%'" > %filePath%%tmpFile%!tableName!.txt

    FOR /F %%a IN (%filePath%%tmpFile%!tableName!.txt) DO (
      IF "!tables!" EQU "" (
        SET tables=%%a
      ) ELSE (
        SET tables=!tables! %%a
      )
    )

    mysqldump -u root -h localhost %dbName% !tables! > %filePath%dump_!tableName!.sql

    ECHO dump作成完了しました

    SET /P contDump="続けてdumpしますか？(y/n): "
    IF "!contDump!" EQU "y" (
        GOTO DUMP
    ) ELSE (
        GOTO END
    )

) ELSE IF "%mode%" EQU "2" (
    ECHO mode:restore
    
    :RESTORE
    SET /P dumpFile="「dump_」以降のダンプファイル名を入力してください（拡張子入力不要）:"
    
    ECHO restore start...
    mysql -u root -D %dbName% < %filePath%dump_!dumpFile!.sql
    ECHO restore end
    
    SET /P contRest="続けてrestoreしますか？(y/n): "
    IF "!contRest!" EQU "y" (
        GOTO RESTORE
    )
)

:END
ENDLOCAL

```
シェルとgitで残業コミットを調べる

#環境
Mac：10.12.5
bash：3.2.57

#はじめに

1月の残業時間を10時間以内（1日30分以内）にすることを目標にしています。
そこで月の終わりに以下を行うことにしました。

・出勤簿を確認して残業が発生している日を洗い出す。
・残業時間に何をしていたか確認する。
　・チャットツールで自分の発言履歴を調べる。
　・git logで作業内容を調べる。
・その要因を特定して事前に防ぐフローに変更する。

この「git logで作業内容を調べる」方法の改善策として作成したシェルスクリプトのまとめです。

#先にまとめ

```sh
# 引数チェック
if [ "$1" == "" ]; then
        echo "引数に何日前からのチェックを開始するか指定してください\n例）sh checkOvertime.sh 30"
        exit 1
fi

# チェック開始日を表示
DATE=$(date -v -"$1"d "+%Y/%m/%d")
echo "$(git config user.name) の $DATE 以降の残業コミット一覧\n"

for (( i = "$1"; i >= 0; i-- )); do
        DATE=$(date -v -"$i"d "+%Y/%m/%d")
        LOG=$(git log --pretty=format:"%h %ad %s" --date=format:'%H:%M' --since="$DATE 19:30:00" --until="$DATE 23:59:59" --author="$(git config user.name)" | sort -k2)

        # 残業コミットがないなら次の日へ
        if [[ $LOG == "" ]]; then
                continue
        fi

        # 日にちと残業コミットを表示
        echo "[$DATE]"
        echo "$LOG\n"
done
```

```
# 調べたいリポジトリに移動
# sh ~/checkOvertime.sh 30 を実行した結果

panti310 の 2017/08/02 以降の残業コミット一覧

[2017/08/04(金)]
0bcbeceb1c5 22:28 コミットメッセージが表示されます
1b4d4eddfed 22:55 コミットメッセージが表示されます
fa245590885 22:56 コミットメッセージが表示されます
b9123d98df2 22:56 コミットメッセージが表示されます

[2017/08/24(木)]
60f3975eca2 19:57 コミットメッセージが表示されます

[2017/08/29(火)]
51007bd88c1 19:42 コミットメッセージが表示されます

[2017/08/30(水)]
6a722556eec 19:43 コミットメッセージが表示されます
```
※author名とコミットメッセージは適当に伏せています。

4日はチャットツールを合わせて見ると19時からレビュー会があったようです。さらに、その後修正&デバッグ依頼を行っているので、 完全にカツカツでスケジューリングミスです。また、コミットを見る限り修正内容は大したものではないので、レビュー会自体の進行の不手際が大きそうです。

24日、29日、30日は「あともうちょっと」でズルズル残ってしまったパターンですね。その日に必須ではないけど依頼されたからやって帰ったという感じです。



#解説
###git log フォーマットを指定する
--pretty と --date を合わせてフォーマットを指定しています。

▽Qiita - git logのフォーマットを指定する
http://qiita.com/harukasan/items/9149542584385e8dea75

▽Qiita - 任意の日付フォーマットでgit logを表示する
http://qiita.com/tomlla/items/219cea9dd071c8a9e147


###git log 日付けで絞り込む
--since と --until で残業時間でのコミットを絞り込んでいます。
時間帯は19:30:00 ~ 23:59:59の設定にしているので、適宜変更してくださいmm

▽Qiita - git log よく使うオプションまとめ
http://qiita.com/take4s5i/items/15d8648405f4e7ea3039#%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%AE%E7%B5%9E%E3%82%8A%E8%BE%BC%E3%81%BF


#さいごに
あと5時間削ることができれば目標の10時間以内達成です！
来月頑張るぞ！

追記：改良版を掲載しました。
[ワンライナーで残業コミットを調べる](https://qiita.com/panti310/items/1516b8c5e4213380151e)
rebaseをかけても正しくコミットの時間を検出できるので、rebase派の人は上記参照くださいmm
social.frameworkがiOS11から使えなくなる件



social.frameworkを使用してtwitterやfacebookのボタンを設定しているところはシェアができなくなります。

depracatedで後ほど使えなくなるという訳ではなく、iOS11端末かつtwitterもfacebookアプリもインストールされていない場合に全く動かなくなります。（設定画面にtwitterやfacebookの設定がなくなったのが原因？）

ただ、twitter、facebookのアプリが入れてあれば投稿は可能です。
（twitterのアプリの場合は投稿する前に設定画面で登録してください画面が出てしまいました。facebookはアプリが入って入れば特に問題なく投稿可能でした。）

対処法としては

 - twitter.kitなど他のSDKを入れる(iOS9以上)
 - twitterやfacebookのアプリがない（social.frameworkが使えない）場合はそれ用に処理を入れる。
 - iOS11以降は非表示にしたり、webで投稿するようにする

などで対処します。
XCode9で「new branch」をする方法


XCode8まではsource controllからnew branchを選択して新しくブランチを作っていたがXCode9からはやり方が変更

Option + 2で Source Control Navigatorを開く。

そして、Branchesから派生させたいブランチを右クリックしてNew Branch from hogehoge　で作成可能。
Linux ディストリ別 初期環境構築

# Debian Ubuntu
```sh
apt update && apt install -y sudo git curl
newuser="hoge"; adduser --home "/home/$newuser" $newuser && adduser $newuser sudo && su $newuser
```

# Fedora RHEL CentOS {Scientific,Oracle,Amazon}Linux
```sh
yum install -y sudo git passwd
echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers
newuser="hoge"; adduser -d "/home/$newuser" $newuser && passwd $newuser && usermod -aG wheel $newuser && su $newuser
```

# ArchLinux OpenSUSE Gentoo
```sh
# ArchLinux
pacman -Syy && pacman -S --noconfirm git sudo
# OpenSUSE
zypper install -y git sudo
# Gentoo
emerge-webrsync && emerge sudo git curl
```

```sh
echo "%wheel ALL=(ALL) ALL" >> /etc/sudoers
newuser="hoge"; useradd -m -G wheel $newuser && passwd $newuser && su $newuser
```

# FreeBSD
```sh
pkg install -y sudo curl git bash gnuls
echo "%wheel ALL=(ALL) ALL" >> /usr/local/etc/sudoers
set newuser="hoge"; echo $newuser"::::::::bash:" | adduser -f /dev/stdin -G wheel && passwd $newuser && su $newuser
```



# 以上を考慮したパッケージマネージャー選択ShellScript
```sh
execable(){ [[ -x "$(command -v $1)" ]] || [[ "$(command -v $1)" != "" ]] ; }
if   execable brew  ; then manager="brew install"
elif execable yum   ; then manager="sudo yum install -y"
elif execable apt   ; then manager="sudo apt install -y"
elif execable pacman; then manager="sudo pacman -S --noconfirm" # ArchLinux
elif execable zypper; then manager="sudo zypper install -y" # OpenSUSE
elif execable pkg   ; then manager="sudo pkg install -y" # FreeBSD
elif execable emerge; then manager="sudo emerge" # Gentoo
else echo "no package manager"; exit 1
fi
manager(){ $manager $@ ; }
```


<hr>
use `visudo`
Rendering a display field of model formset with django-tables2

# Overview

Djangoでtables2 を使いながらformを作りたい時の方法。
完全にHiddenで良いならばこちらにHow Toが書いてあるが、
Input自体はHiddenながら、データを表示しておきたい時の方法を作ってみた。

https://github.com/bradleyayers/django-tables2/issues/418

```
class DisplayHiddenInputColumn(tables2.Column):                                         
    def __init__(self, *args, **kwargs):                                                
        super(DisplayHiddenInputColumn, self).__init__(*args, **kwargs)                 
                                                                                        
    def render(self, value):                                                            
        return mark_safe(                                                               
            '<input type="hidden" name="{}" value="{}" />{}'.format(                    
                self.accessor, value, value)) 

```

tr/td の display none を消してhidden input の後に値を付けてやるだけ。
Originalだと、name が verbose_name になっているが、データの参照具合を考えるとname = accessor の方が便利だった。

formset と違うので複数のフィールドで適用すると

form1 = [ 1, 2, 3 ]
form2 = [a, b, c]

みたいに、 [1, a], [2, b], [3, c] のようになってくれないが、
dict ではないのでzip 処理でくっつけてしまえばいいんじゃなかろうか。
Google Cloud VisionのOCR結果を用いた検索可能pdfの作成

Google Cloud VisionのOCR結果(jsonファイル)にはテキストの読取結果とともに画像内での文字の座標が含まれている。

gcv2hocrは、このjsonファイルをhocr形式に変換する。

https://github.com/dinosauria123/gcv2hocr

hocrファイルと元の画像ファイルをhocr-pdf(hocr toolsに含まれる)で処理すると検索可能なpdfが得られる。

https://github.com/tmbdev/hocr-tools

この方法で戦前・戦中期の日本のカメラ広告を電子化し、下記で公開している。

http://japanese-ww2-camera-ad.tk

縦書き、横書き、旧かな、旧漢字が混在した広告もある程度読み取ることができる。市販のOCRソフトウエアと比較しても読取精度は高いと感じる。

活字ばかりでなく、広告中のロゴタイプも読み取れることがある。

右行頭の横書きでは、語順が逆転する。

複数のスキャン画像から一つの検索可能なpdfを作成するためのシェルスクリプトの例を下記に示す。

```
a=1
while [ $a -le 32 ]
do
    if [ $a -le 9 ] ; then
	   number="00"$a
	fi

    if [ $a -ge 10 -a $a -le 99 ] ; then
	   number="0"$a
	fi

    if [ $a -ge 100 ] ; then
	   number=$a
	fi

    echo "Google OCR page$number.jpg"
    sh ./gcvocr.sh page$number.jpg [Your API Key]

    echo "Convert page$number.hocr"
    ./gcv2hocr page$number.jpg.json page$number.hocr

    a=`expr $a + 1`
done

echo "Generating out.pdf"
python hocr-pdf ./ > out0.pdf

echo "Reducing pdf size"
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/default -dNOPAUSE -dQUIET -dBATCH -sOutputFile=out.pdf out0.pdf
```

gcvocr.shは画像をGoogle Cloud Visionにアップロードし、jsonファイルを得るためのシェルスクリプト。
pdf作成後にghostscriptを用いてファイルサイズを縮小している。
RustでFFT (3)自作クレートchfftの紹介


# 概要
FFTを実装し、チューニングを施していた所、要素数によってはFFTW3やrustfftより速くなったため、クレートとした。

# 使い方
Cargo.tomlにnumクレート及びchfftクレートを追加する。

```toml:Cargo.toml
[dependencies]
num = "*"
chfft = "*"
```

サンプルコードは次の通り。

```rust
extern crate chfft;
extern crate num;
use num::Complex;
use chfft::CFft1D;

fn main() {
    let input = [Complex::new(2.0, 0.0), Complex::new(1.0, 1.0),
                 Complex::new(0.0, 3.0), Complex::new(2.0, 4.0)];

    let mut fft = CFft1D::<f64>::with_len(input.len());

    let output = fft.forward(&input);

    println!("the transform of {:?} is {:?}", input, output);
}
```

その他backwardメソッドや、スケーリング処理を同時に行うメソッドを用意している。
ただし、現状では1次元の複素数FFTしか実装されていない。

# パフォーマンス計測結果

## 測定環境
MacBook Pro (Retina, 13-inch, Mid 2014)
Processor 2.6GHz Intel Core i5 (Haswell)
Memory 8GB 1600MHz DDR3

RUSTFLAGS='-C target-cpu=native'
rustc 1.19.0 (0ade33941 2017-07-17)

FFTW3の計測はfftwクレートを使用

## 測定内容
順方向に変換した結果を逆変換する処理を1,000回実施。
総所要時間を2,000で除したものを結果とした。

## 測定結果
単位はns(ナノ秒)

| 要素数 | chfft | FFTW3 | rustfft |
|---|---|---|---|
| 2 | 39 | 40 | 65 |
| 4 | 46 | 47 | 69 |
| 8  | 68 | 67 | 79 |
| 16 | 97 | 107 | 129 |
| 32 | 191 | 214 | 331 |
| 64 | 363 | 513 | 620 |
| 128 | 782  | 1,084 | 1,277 |
| 256 | 1,649 | 2,451 | 2,183 |
| 512 | 3,732 | 5,963 | 5,989 |
| 1,024 | 7,948 | 13,469 | 10,802 |
| 2,048 | 19,286 | 30,287 | 29,665 |
| 4,096 | 64,376 | 79,114 | 60,930 |
| 8,192 | 157,663 | 188,274 | 150,720 |

これより大きい要素数となると、L3キャッシュに乗らなくなる事から非常に遅くなる。
マルチスレッド化、及びロジックの切り替えを行い、高速化を測る必要がある。

# ソースコード
githubの次のページを参照
https://github.com/chalharu/chfft
phpで色々な種類のファイルを配列にした

phpでファイル操作を行うことが多かったので
ファイルによっての配列作成の違いをまとめました。


##ファイルの作成

適当にファイルを作ります。
テスト用として .txt .csv .json の3つのファイルを作ります。

```test.txt
aaa@aaa.com
bbb@bbb.com
ccc@ccc.com
```

```test.csv
aaa@aaa.com,bbb@bbb.com,ccc@ccc.com,
```

```test.json
{"0":"aaa@aaa.com","1":"bbb@bbb.com","2":"ccc@ccc.com"}
```



##配列の作成

```array.php
<?php

  #test.txt 読み込み
  $str = file_get_contents('./test.txt');
  $arr = explode("\n", $str, -1);
  var_dump($arr);

  #test.csv 読み込み
  $str = file_get_contents('./test.csv');
  $arr = explode(",", $str, -1);
  var_dump($arr);

  #test.json 読み込み
  $str = file_get_contents('./test.json');
  $arr = json_decode($str, true);
  var_dump($arr);
```

##出力結果

```
array(3) {
  [0]=>
  string(11) "aaa@aaa.com"
  [1]=>
  string(11) "bbb@bbb.com"
  [2]=>
  string(11) "ccc@ccc.com"
}
array(3) {
  [0]=>
  string(11) "aaa@aaa.com"
  [1]=>
  string(11) "bbb@bbb.com"
  [2]=>
  string(11) "ccc@ccc.com"
}
array(3) {
  [0]=>
  string(11) "aaa@aaa.com"
  [1]=>
  string(11) "bbb@bbb.com"
  [2]=>
  string(11) "ccc@ccc.com"
}
```

##まとめ


ファイルの形式によって配列の作り方は違う。
しかし、基本的には下記の関数を使えば配列は作れる。

```
file_get_contents : ファイルを読み込んで文字列として返す
explode : 文字列を区切り文字で分割して配列にする
json_decode : jsonファイル読み込んでデコードする
```

今回の場合ではexplodeの第３引数に-1を設定して
配列の最後に空文字の値が入らないようにしたり、json_decodeの第2引数をtrueにして
objectではなく配列を作成するようにしています。

公式リファレンスに引数の詳しいことが載っています。

> http://php.net/manual/ja/function.file-get-contents.php
> http://php.net/manual/ja/function.explode.php
> http://php.net/manual/ja/function.json-decode.php


##おまけ

.phpファイルを読み込む

```test.php
<?php
  $arr = [
    'aaa@aaa.com',
    'bbb@bbb.com',
    'ccc@ccc.com'
  ];
```

```array.php
  #test.php 読み込み
  require('./test.php');
  var_dump($arr);
```

出力結果 : 

```
array(3) {
  [0]=>
  string(11) "aaa@aaa.com"
  [1]=>
  string(11) "bbb@bbb.com"
  [2]=>
  string(11) "ccc@ccc.com"
}
```
vimでテンプレートを使う

# 追記
今はmattnさんが作成している vim-sonictemplate を使ったほうがテンプレートを複数用意して選べるので良いと思います。
https://github.com/mattn/vim-sonictemplate

# 概要
vimにだいぶ慣れてきたので、カスタマイズしたくなってきた。
その過程で得た知識の理解を深めるためにまとめた。

#動機
visual studioやandroid studioではプロジェクトを作るときにテンプレートを入力した状態にしてくれる。
これをvimでもやりたかった。
htmlやtexを書くとき、いつも同じ内容をはじめに入力していることに気づいたため、それを自動化したかった。

#template
まず、テンプレートを用意する。
今回はhtml, texのテンプレートを用意した。
テンプレートは$VIMの下に新たにtemplateディレクトリを作ってその下に入れた。
```tex templete: $VIM/template/t.tex
\documentclass{jarticle}
\usepackage{graphicx}
\title{}
\author{}
\begin{document}
\maketitle
\section{}
\section{}
\section{}
\begin{thebibliography}{99}
    \bibitem{book1}
    \bibitem{book2}
\end{thebibliography}
\end{document}
```

```html template: $VIM/template/t.html
<!DOCTYPE html>
<html>
  <head>
    <mata charset="utf-8">
    <link rel="stylesheet" href="style.css" type="text/css" charset="utf-8">
    <title></title>
  </head>
  <body>
  </body>
</html>
```

#vimrc
次に上で作ったテンプレートをファイルを新たに作成したときのみ、挿入するように設定する。
```vimrc: $VIM/vimrc
augroup templateGroup
  autocmd!
  autocmd BufNewFile *.html :0r $VIM/template/t.html
  autocmd BufNewFile *.tex :0r $VIM/template/t.tex
augroup END
```
autocmdはvimrcが複数回読み込まれたときに、上書きされずに追加されていくのでautocmd!で再度読み込み時にいったんautocmdの設定を削除しています。
また、autogroupを設定することでautocmd!で再読み込み時に他のantocmdの設定が知らないうちに削除されないようにしています。pluginでautocmdを使っていた場合に影響が出ないようにするためにしたほうがよいと思っています。

BufNewFileは存在しないファイルの編集を開始したときを意味しています。ここを変えることで後ろのコマンドの実行タイミングが変わります。
例えば、QuitePreにすると:quiteを使ったときに実行されるようになるのでここでコンパイルやテストを行う外部コマンドを実行するように指定するというようなことが考えられます。
詳しくはvimのドキュメントに書かれています。

次はvimにデフォルトである補完の設定をしたいです。
目標はkaoriyaさんのスパルタンVIMです。
AndroidStudioのGUIからActivityを作るとapp/build.gradleがずれる問題

# 概要
app/build.gradleのdependencies内で以下のようにコメントがある状態で、
![スクリーンショット 2017-08-31 23.26.35.png](https://qiita-image-store.s3.amazonaws.com/0/33071/4d4db85a-6b85-f33e-912f-e11846ea0876.png)

```New > Activtiy > EmptyActivity```　のようにGUIからActivityやFragmentを生成すると、
![スクリーンショット 2017-08-31 23.17.26.png](https://qiita-image-store.s3.amazonaws.com/0/33071/a8ff8ab7-f1c3-50b5-7a2f-a1a97f292243.png)

並びがおかしくなる。:innocent:
![スクリーンショット 2017-08-31 23.27.45.png](https://qiita-image-store.s3.amazonaws.com/0/33071/f58bb404-c5bc-5f9f-2cc6-7381580a2895.png)

もちろんこのままではエラーが出る。
```
Error:(48, 0) Could not get unknown property 'compile' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
```

# 対応
1年ほど前にIssue化されて解決していない問題のよう。
https://issuetracker.google.com/issues/37076867

EmptyActivityレベルなら地道に作ったほうが速そうですが、
どうしてもテンプレートを使いたい場合は、dependencies内にコメントを書かないようにしたり、```git checkout app/build.gradle```などでこの箇所のみ戻すしかなさそう。:dizzy_face:

参考
https://stackoverflow.com/questions/42984981/gradle-indentation-issue-in-android-studio-2-3/42985170#42985170
https://stackoverflow.com/questions/42995487/gradle-file-is-edited-on-creating-new-activity-fragment
Linux形式のパスをWindows形式のパスに変換してクリップボードにコピーする方法

# 背景

`ghq`と`peco`を組み合わせて使うようになって、Windowsエクスプローラーのマウス操作が億劫になりました。とは言え、まだまだシェル力が足りないのでエクスプローラーを併用するのですが、ディレクトリのパス形式がLinuxとWindowsで違うために目的のディレクトリをすぐ開けなくてちょっと困っていました。(´・ω・`)

## 使用環境

* Windows 10
    * bash（Git for Windows 同梱のもの）

# やったこと

そこで、以下のようなことをやってみました。

* `bash`のカレントディレクトリパスをWindows形式に変換
* Windows標準のクリップボードにコピーするツール`clip`に上記パス情報を渡す

あとは、エクスプローラーや好みのファイラーにパスを貼り付けて移動できます。

## `bash`のカレントディレクトリパスをWindows形式に変換

### cygpathでやってみた

```bash
# 日本語を含むパスで文字化けします
$ cygpath -w `pwd` | tr -d '\n' | clip
```

はじめは、上記のように`cygpath`ツール（Git for Windowsに同梱）を使った方法を試したのですが、残念ながら`clip`ツールがShift-JIS形式の文字列しか扱えないため日本語を含むパスで文字化けしてしまいます。それじゃあパイプのどこかで`iconv`使って文字コードを`UTF-8`から`Shift-JIS`に変換してみよう！と思ってやってみたのですが以下のようになりました。

* `cygpath`で変換したWindows形式のパスに対して`iconv`で変換を試みたが、「:」や「\」が含まれていて変換できない
* `iconv`で変換した文字列を`cygpath`に渡してみたが、なんだか化けた文字列が返ってきた

### 素直に`sed`に入門した

はい、素直に正規表現使って変換することにしました。本当にすみませんでした(´・ω・`)

```bash
pwd | tr -d '\n' | iconv -f UTF-8 -t SJIS | sed -e 's/\//\\/g' -e 's/\(^\\.\)/\1:/' -e 's/\(^\\\)//' | clip
```

きっと半年後ぐらいに自分で見直して、「いったいこれは何をやっているんだ・・・！( ･`ω･´)」ってなると思うので簡単に処理をメモします。（ここは本当に自分用です。低レベルです。すみません、すみません。。）

* `pwd`でカレントディレクトリ（Linux形式）を取得
* `tr`で末尾の改行コード除去
* `iconv`で`UTF-8`から`Shift-JIS`に文字コード変換（後述の`clip`ツールに渡すための準備）
* `sed`で`/`を`\`に置換したり、冒頭の`\(任意の文字)`の後に`:`入れたり、冒頭の`\(任意の文字)`の`\`消したり
* `clip`ツールに渡してクリップボードへ

`sed`さんは本当に素晴らしいですね。

# 参考

とても助けていただいた記事の皆様です。ありがとうございますm(_ _)m

* [【iconv】文字コードを変換して出力する](http://itpro.nikkeibp.co.jp/article/COLUMN/20131209/523510/)
* [sedでこういう時はどう書く?](http://qiita.com/hirohiro77/items/7fe2f68781c41777e507)
* [cygpath の便利なオプション](http://takuya-1st.hatenablog.jp/entry/20110910/1315644196)
* [シェルスクリプトのみでMacとWindowsのファイルパスを相互変換する方法(Macユーザ向け)](http://qiita.com/odacoh/items/14844b79f7fcf5bef97e)
Word用のVBA テキストファイルからテキストボックスを吐き出すマクロ

10年ほど前に書いた多数のテキストボックスを吐き出すVBAマクロです。
全国の大学一覧を地図上に置きたくて作りました。
このマクロを持つワードドキュメントと同じフォルダに置いた"chartdata1.txt"ファイルの1行ずつのテキストボックスを最後の行まで吐き出します。
A4縦のレイアウトでつまみやすいようにずらしながらテキストボックスを配置するように作っています。
大量にテキストボックスが必要なときに参考にしてみて下さい。

~~~VBA:CommandButton1_Click()
Private Sub CommandButton1_Click()
    Dim i, j, y As Integer
    Dim strTxt As String
    Dim strInRec As String
    Open ActiveDocument.Path & Application.PathSeparator & "chartdata1.txt" For Input As #1
    strTxt = ""
    i = 1
    y = 100
    Do While Not EOF(1)
        i = i + 1
        Line Input #1, strInRec
'        Debug.Print i, strInRec
        strTxt = strInRec
        ActiveDocument.Shapes.AddTextbox(msoTextOrientationHorizontal, 10 + 20 * Int((i) Mod 14), y + 10 * i, _
        150, 20).Select
        Selection.ShapeRange.TextFrame.TextRange.Select
        Selection.Collapse
        Selection.TypeText Text:=strTxt
    Loop
Close #1
End Sub
~~~
## **動作見本**
![WordVBA01.png](https://qiita-image-store.s3.amazonaws.com/0/147091/33cd91b9-c063-c3c4-c7a8-3c41b63afc81.png)
[Ruby] 配列が値のハッシュで存在しないキーへ配列前提のアクセス

一発ネタです

```rb
@hash = something.group_by do
  # ...
end
```

これ↑をこう↓すると

```rb
@hash[:not_exist_key] << 'something'
# => NoMethodError: undefined method `<<' for nil:NilClass
```

こう↑なるので、こう↓

```rb
@hash = something.group_by do
  # ...
end.tap do |h|
  h.default_proc = Proc.new do |hash, key|
    hash[key] = []
  end
end
```
[クイズ]javascriptと仲良くなるための一歩　第４５話「this参照４」

#問題

```js
var x = 1;
var obj3 = {
           x:3,
           doit3: function(){ console.log("method is called." + x); }
          }
obj3.doit3(); //=> ?
```

:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:
:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:

#答え

```js
var x = 1;
var obj3 = {
           x:3,
           doit3: function(){ console.log("method is called." + x); }
          }
obj3.doit3(); //=> method is called.1
```
悪魔のツール「すこすこ砲」の中身

# はじめに
今回はなんJに投下され、拡散し有名となった、YouTube低評価ツール「すこすこ砲」について大雑把に解説しようと思います。
この記事では、CUI版の一つである[この](https://github.com/AnKoushinist/suko-suko-button)repoを参考にします。

**8/31前後にYouTubeのレイアウトが変更されたため、現行のコードは動作しません。**
**悪用防止のため、ここで紹介されているrepoを含め、ソースコードは公開されないことになっていますが、**
**開発者達が修正をしているので暖かく見守ってあげて下さい。**

# 使い方
まず初めに、使い方を簡単に説明しましょう。
すこすこ砲をダウンロードして展開し、コマンドプロンプトを起動。そして以下のように入力します。

```
SukoSukoCui.exe [メールアドレス] [パスワード] [YouTubeにおけるチャンネルID]
```
YouTubeにおけるチャンネルIDは、[こちらのチャンネル](https://www.youtube.com/channel/UCaminwG9MTO4sLYeC3s6udA)を例にとると、`UCaminwG9MTO4sLYeC3s6udA`となります。
コマンド指定もでき、以下のようなものがあります。

- `--first-10` 最初の10個のみを対象にする
- `--suko N` 最初のN個の動画を対象にする
- `--para N` N並列で実行する

# すこすこ砲の動作
## [WebDriverで並行数分のChromeを起動](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L78)
WebDriverで制御できるのはウィンドウごとらしく、タブの制御は現時点では不可能とのこと。
以下、ウィンドウ名は`スレッド0`...`スレッドN-1`(プログラム内と同じ名前)とします。

## ログイン
これは並列してログイン処理をしません。(一つづつ順番にログインをします。)

https://accounts.google.com/ServiceLogin にアクセスしてから、
### [新ログイン画面の場合](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L211-L218)
1. ID`identifierId`にメールアドレスを入力
2. ID`identifierNext`をクリック
3. パスワード欄が出るまで待機
4. ID`password`にメールアドレスを入力
5. ID`passwordNext`をクリック

### [旧ログイン画面の場合](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L200-L207)
1. ID`Email`にメールアドレスを入力
2. ID`next`をクリック
3. パスワード欄が出るまで待機
4. ID`Passwd`にメールアドレスを入力
5. ID`signIn`をクリック

という動作でログインをします。

## [再ログイン](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L229-L241)
これから先の動作で、たまにログインがされていないことがあります。
これを解決するため、「ログイン」ボタンをクリックするだけの処理があります。
「再ログインをする」等の表記があった場合は、「ログイン」ボタンをクリックするだけと考えて下さい。

## [動画の探索](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L153-L169)
実行してみると分かりますが、**APIは叩いていません。**
**使いません。**

さあどうするのかと言いますと、
**チャンネルの投稿動画をウェブページから探します。**
 
**探します。**
この発想は無かった。
### 動作
以下のようにして探索をします。(スレッド0のみを使用します。)

0. ログインしていない場合は再ログイン
1. 「もっと読み込む」をクリック
2. 2が出来なくなるまで繰り返す
3. `watch?v=~~~`の`~~~`部分を全部探す

## [すこる](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L93-L138)[(低評価する)](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L171-L191)

### その前に...
一個前のステップで探索した動画は、全スレッドに**均等**に振り分けられます。(動画数によっては少し偏りますが)
### [すこる](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L171-L191)

0. ログインしていない場合は再ログイン
1. (`[動画ID]すこ！ ([完了動画数]/[全動画数])`と表示する)
2. 低評価ボタンが押されているか確認する<br>押されていれば、5へ<br>(確認しないと、低評価を外してしまいます。)
3. 低評価を押す
4. 次の動画へ

## [正常終了時](https://github.com/AnKoushinist/suko-suko-button/blob/master/cui/Program.cs#L133)
`(ChromeDriver).Dispose()`を呼び出して全スレッドのChromeを閉じます。

# 最後に
「すこすこ砲」の「すこ」とは、「**低評価**」を意味します。「逆すこ」は、「高評価」となります。
かなり原始的な方法にも見えますが、動画あたり数秒しか開かずに低評価を押せるのは気軽で速いですね。
その短さが故、再生数にカウントされないため、収益化していても相手の収益になることは無いそうです。
よく話題に出る、高評価率は[ここ](http://ytranking.net/channel/2379/)から見ることができます。~~いかになんJ民やTwitterユーザー達の勢力が大きいかが見て取れます。~~

ここまでご覧いただきありがとうございました。
公開鍵、秘密鍵でssh接続トラブル


`$vagrant up`

した際に以下のようにssh接続が失敗してしまう現象を解決する方法。

```
    default: SSH auth method: private key
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
    default: Warning: Connection reset. Retrying...
    default: Warning: Connection aborted. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
    default: Warning: Authentication failure. Retrying...
```

#原因

自身のローカル上にある**秘密鍵**と設定したいサーバー上にある**公開鍵**が**一致しなかった**ため、接続に失敗してしまうことが原因である。
秘密鍵、公開鍵の仕組みが分からない方は、[こちら](http://knowledge.sakura.ad.jp/beginner/3543/)


特に今回は、自分自身で公開鍵や秘密鍵を設定したところ、**設定したいサーバー上に公開鍵を書き込み忘れていた**ため、その設定方法を載せようと思う。

#解決方法

①もし公開鍵、秘密鍵を作成していない場合は[作成](http://qiita.com/abgata20000/items/161c49583f531afedda7)。


②作成した公開鍵情報をコピー。

`$ cat id_rsa.pub`

もしくは

`$ vi id_rsa/pub`

で中身が見れる。

ssh-rsaの最初から最後まですべてをコピー。


③設定したいサーバー上にあるauthorized_key(人によってはauthorized_keys)に書き込みを行う。なければ作成。

まずは設定したいサーバーに接続。windowsの場合はPowerShell、Macの場合はターミナルで実行。


`$ ssh アカウント名`

ログイン完了したら、.sshディレクトリへ移動

`$ cd /home/ユーザーアカウント/.ssh`

先ほどコピーした公開鍵をvimを使ってauthorized_key(もしくはauthorized_keys)に追加。なければ作成。

`$ vi /home/ユーザーアカウント/.ssh/authorized_key(もしくはauthorized_keys)`

すでにある場合はそのキーの最後に追加するのでもよい。

最後に秘密鍵のパーミッションを変更

`$ chmod 700 ~/.ssh`
`$ chmod 600 ~/.ssh/authorized_key(もしくはauthorized_keys)`

以上でsshログイン可能になる。

再起動して出来ているか、みてみよう。

`$ vagrant reload`


#参考文献
・[絵で見てわかるWebアプリ開発の仕組み](https://www.amazon.co.jp/%E7%B5%B5%E3%81%A7%E8%A6%8B%E3%81%A6%E3%82%8F%E3%81%8B%E3%82%8BWeb%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF-%E6%9D%BE%E6%9D%91%E6%85%8E-ebook/dp/B0142S78NM)
Macでファイル名に拡張子を表示させる


##Finderを開く
##Finderの環境設定を開く
<img width="437" alt="スクリーンショット 2017-09-01 0.09.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/140528/dda08b0b-97ab-1c0a-5993-17e8504c7dba.png">

##全てのファイル名拡張子を表示にマーク
<img width="365" alt="スクリーンショット 2017-09-01 0.09.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/140528/d3cd291d-deab-8f2d-e51a-fe1785e20a07.png">  
<img width="362" alt="スクリーンショット 2017-09-01 0.09.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/140528/0ba947f5-f661-3b4f-aa26-d11bf1a299fd.png">

以上
例の黒い画面に慣れるための準備 実行編

# Let's 黒い画面
[前回のやつ](http://qiita.com/blue2gou/items/b58aa3057a58d1f3641f)
まずは黒い画面を開いてみます。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/199415/21680852-b85a-7719-9c74-d42824e64b47.png)
### 黒い画面（黒いとは言っていない）

# とりあえず設定
vimの設定とかして・・・
あとは何やろうかなぁ。目標持たないとね。
ホストOSのと連携出来るようにしよう。眠い！
AngularJSのBinding（?,&）の使い方について書いてみた

###バインディング
AngularJSのバインディングの種類は色々ありますが
今回は"="などと比べて理解しにくい"?"と"&"について書いてみたいと思います。

###?について
私はバインディングに"?"のという記号が存在するのを半年以上も知りませんでした笑
実際にどのような働きをするかというと、"?"があるとコンポーネントの読み込みが終わった後にバインディングをしてくれます。
以下のコードは"?"が付いている時と付いていない時の挙動が分かるように書いています。

```questionController.html
<question-component param1="'hogehoge'" param2="'hogehoge'"></question-component>
```

```questionComponent.js
angular.module('myApp')
  .component('questionComponent', questionComponent);

class questionComponentClass {
  constructor() {
    this.param1 = "fugafuga" //この2行で値を変更している
    this.param2 = "fugafuga"
  }
}

questionComponentClass.$inject = [];

var questionComponent = {
  controller: questionComponentClass,
  templateUrl: 'component/questionComponent.html',
  binding: {
    param1: '<',
    param2: '<?' //こちらは?がついている
  }
}
```

```questionComponent.html
?が付いていないと{{$ctrl.param1}}になります。
?が付いていると{{$ctrl.param2}}になります。
```

実際に実行すると以下のように表示されます。

```html
?が付いていないとhogehogeになります。
?が付いているとfugafugaになります。
```

###&について
次に"&"について書いてみます。バインディングを"&"にするとそのバインディングは関数として扱われます。
以下のコードはバインディングが"&"の時の書き方です。

```andComponentClass.js
angular.module('myApp')
  .component('andComponent', andComponent);

class andComponentClass {
  constructor() {}

  and(value) {
    andFunction({value: result}); //オブジェクトで定義
  }

}

andComponentClass.$inject = [];

var andComponent = {
  controller: andComponentClass,
  templateUrl: 'component/andComponentClass.html',
  binding: {
    andFunction: '&'
  }
}
```

```andController.html
<and-component and-function="$ctrl.smple(value)"></and-component> //引数にキー名を記入
```

ポイントなのはandController.html内で呼び出すときに**バインディング名=andController.html内の関数(キー名)**
になる事とコンポーネントでは**一度ラップ**してバインディングを呼ぶ点です。

他のバインディングと違い、かなりクセが強いので理解するのが難しいですが、呼び出す時を意識すれば
扱えるようになると思います。
Python3とiPhoneで簡単なゲームを作ってみる

[Pythonista](http://omz-software.com/pythonista/)というiOSアプリをご存知でしょうか？

## Pythonistaとは？

PythonistaはiPhone/iPadで動くPython環境で、以下の機能を備えています。

* Python2.7, Python3.5
* IDEによるコード補間、エラー箇所の表示
* デバッガ搭載、エラー時のスタックトレース、変数値を見ることができる
* スタイルチェッカー、pyflakeなどのLinterを標準搭載
* Python標準ライブラリに加え、2Dゲーム開発、UI、GPS、テキストスピーチ、Objective CのAPI呼び出し等のPythonistaモジュールを同梱している
* また、Flask, numpy, Pandas等の有名なオープンソースライブラリも同梱している
* ゲームプログラミングに必要なテクスチャやサウンドデータを使うことができる
* ある方法を使えば、UNIXコマンド、git、pipも使うことができる

という、Pythonista(Pythonプログラマ)にとっては電車の中でもトイレでもどこでもコーディングできる素晴らしい環境と言えます。

今回は、PythonistaとiPhoneのソフトウェアキーボードだけで簡単なゲームを作ってみました。

## 作ったゲーム

Flappy bird風の横スクロールアクションゲーム

作成時間：電車の中で5時間程

![FlappyAlien.gif](https://qiita-image-store.s3.amazonaws.com/0/44173/fdb18eef-0f25-77d5-dba8-1cbdd3698edb.gif)

ソースコード：https://github.com/yukinarit/flappy_alien/blob/master/flappy_alien.py
(Pythonistaにコピペするだけで動作します)

## 環境構築

AppStoreからPythonistaと検索してインストールしましょう。

必須ではありませんが、筆者は[StaSh](https://github.com/ywangd/stash)を使って、iPhone上にシェル環境とgitを使えるようにしてコーディングしました。StaShのインストールはこのページ(http://qiita.com/kido-akira/items/8fbe7783245e3b7d3bac) が参考になりそうです。

<img width="300" alt="asset.png" src="https://qiita-image-store.s3.amazonaws.com/0/44173/6a1b7fd1-2996-6711-06e0-b26306b751d8.png">
StaShのgitを使ってtypoを修正してgithubにプッシュしている様子

## コードの解説

Pythonistaモジュールのscene, ui, soundパッケージを使って作りました。

* sceneパッケージ
  - Scene ... ゲームの画面。敵の生成、衝突判定、UI操作はここに実装しました。
  - SpriteNode ... エイリアン、ブロック、背景画像を描画する
  - LabelNodeクラス ... 文字描画に使用した
  - Action ... エイリアンの落下、ブロック、背景画像の左スクロール
* uiパッケージ
  - デバッグ情報を描画するのに使用
* soundパッケージ
  - タップしたときにSEを鳴らすの使用

サウンド、画像リソースはPythonistaに予め入っているものを使いました。

<img width="300" alt="asset-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/44173/5f5653cd-5d55-9b57-8cd5-a949c5faf105.png">

## 終わりに

このようにPythonistaを使うと簡単にゲームを作ることができます。個人的には子供へのプログラミング教材として大きな可能性を感じています。
JMockitを使ってプロパティファイルを開発用と本番用でスイッチをした

初めてJMockitを触って色々と試したので備忘も兼ねて出来たことのメモ
・Java1.8
・EclipseOxygen(4.7.0)
・jmockit-1.33

テストクラス

```
import static org.junit.Assert.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import org.junit.Test;
import mockit.Invocation;
import mockit.Mock;
import mockit.MockUp;

public class PackagesTest {

	/**
	 * 何もMockらない場合
	 */
	@Test
	public void test_getData() {
		assertEquals("some_id"			,Packages.getData("id"));
		assertEquals("some_password"	,Packages.getData("password"));
	}

	/**
	 * テスト用にプロパティファイルをスイッチする場合、loadかinputstreamの返り値をいじればよい？
	 */
	@Test
	public void test_getData_MockPath() {
		new MockUp<Properties>() {
			@Mock
			public void load(Invocation inv,InputStream inputStream) {
				InputStream inputStream2;
				try {
					inputStream2 = new FileInputStream("sample - コピー.properties");
					inv.proceed(inputStream2);
					inputStream2.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		assertEquals("test_id"			,Packages.getData("id"));
		assertEquals("test_password"	,Packages.getData("password"));
	}

	/**
	 * テストユニットのコード上にそのままリテラル値でMockUpした方がレビューの負担は少ない？
	 */
	@Test
	public void test_getData_MockProperty() {
		new MockUp<Properties>() {
			@Mock
			public String getProperty(Invocation inv,String value) {
				switch (value){
				case "id":
					return "mock_string";
				default:
					return inv.proceed(value);
				}
			}
		};
		assertEquals("mock_string"		,Packages.getData("id"));
		assertEquals("some_password"	,Packages.getData("password"));
	}
}
```

メインクラス

```
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;

public class Packages{

	public static void main(String[] args){
		System.out.println(getData("id"));
		System.out.println(getData("password"));
	}

	public static String getData(String arg) {
		String file = "sample.properties";
		String value = new String();
		Properties properties = new Properties();

		try {
			InputStream inputStream = new FileInputStream(file);
			properties.load(inputStream);
			inputStream.close();

			value = properties.getProperty(arg);

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return value;
	}
}
```
AV1 specification を読む (Annex B スーパーフレーム) 

#AV1 specification 日本語訳

具体的な用途は謎ですが。

----

#Annex B: スーパーフレーム

##B.1 概要

AV1では、複数の符号化フレームを1つのチャンクにまとめる「スーパーフレーム」をサポートしています。

このスーパーフレームのインデックスは、チャンクの34bytesまでに格納されます。
中に含まれるフレームは、このスーパーフレームインデックスを解釈することで特定できます。

スーパーフレームのシンタックスはを B.2 節で示し、 シンタックス要素の意味を B.3 節で説明します。
スーパーフレームのパース方法を B.4 節で説明します。

##B.2 スーパーフレームシンタックス

```C++
superframe(sz)
{
	for (i=0; i<NumFrames; i++)
	{
		frame(frame_sizes[i])
	}
	superframe_index(sz)
}
```

##B.2.1 スーパーフレームインデックス

```C++
superframe_index(sz)
{
	frameSizeSum = 0
	superframe_header()
	for (i=0; i<NumFrames-1; i++)
	{
		frame_sizes[i]							f(SzBytes)
		framesSizeSum += frame_size[i]
	}
	frame_size[i] = sz - SzIndex - frameSizeSum
	superframe_header()
}
```

##B.2.2 スーパーフレームヘッダ

```C++
superframe_header()
{
	superframe_marker					f(3)
	bytes_per_framesize_minus_1			f(2)
	frames_in_superframe_minus_1		f(3)
}
```

##B.3 スーパーフレームセマンティクス

###sz

スーパーフレームのバイト数を指定します。
外部から与えられます。

###frame_sizes[i]

このスーパーフレーム内のフレーム番号 i（0開始）のフレームのバイト数を指定します。

###superframe_marker

0b110 の固定ビット列で、スーパーフレームがそんざいするかどうかを検出するためにあります。

###bytes_per_framesize_minus_1

フレームサイズを符号化するために必要なバイト数を指定します。

```C++
SzBytes = bytes_per_framesize_minus_1 + 1
```

###frames_in_superframe_minus_1

このスーパーフレーム内のフレーム数を指定します。

```C++
NumFrames = frames_in_superframe_minus_1 + 1
```

注意：
スーパーフレームにはNumFrame==1で1フレームだけが含まれてもかまいません。

##B.4 スーパーフレームパーシング

スーパーフレームの使用は選択可能で、1つのチャンクには1つのフレームあるいはスーパーフレームが含まれます。

デコーダは、スーパーフレームの存在意を以下のように検出します。

 1. チャンクの最終バイトをパース氏、superframe_marker==0b110 であることをチェックします。
 2. superframe_indexの合計サイズ SzIndex = 2 + (NumFrames-1)*SzBytes
 3. superframe_indexの最初のバイトが、最後のバイトと一致することをチェックします。

1,3 の両方のチェックが成功したら、そのチャンクにはスーパーフレームが含まれると判断され、スーパーフレーム内の各フレームが順番にデコード処理に渡されます。

そうではなければ、そのチャンクにはスーパーフレームが含まれず、チャンク全体をデコード処理に渡します。

注意：
符号化フレームの最終バイトには superframe_marker が含まれてはいけないという規定があるために、この処理はうまく動きます
AV1 specification を読む (Annex A レベル) 

#AV1 specification 日本語訳

----

#Annex A: レベル

##A.1 概要

レベルはビットストリームをデコードするために必要な能力の制限を規定します。

この規格では、いまのところ1つのレベルだけがあります。
このレベルをレベル1と呼びます。

レベル1は、おおまかに 1080P 60fps 20Mbps ストリームのワーストケースとしてビットストリームを制限し、以下の誠也宇があります。

 * Width <= 1920
 * Height <= 1080
 * 1秒当たりのフレーム数は60以下（出力フレームと非出力フレームの両方を含みます）
 * イントラフレームのビット数は、100,000,000/60 以下
 * インターフレームのビット数は、50,000,000/60 以下
 * イントラフレーム内での read_bool 呼び出しは、2*100,000,000/60 回以下 
 * インターフレーム内での read_bool 呼び出しは、2*50,000,000/60 回以下
AV1 specification を読む (テーブル) 

#AV1 specification 日本語訳

テーブルは原典を参照してください・・・。
解説はあとで書きます。

----

#10. 追加の表

本章では、規格の本文になじまない表が含まれています。

##10.1 スキャンテーブル

```C++
defaultScan4x4[16]
colScan4x4[16]
rowScan4x4[16]
defaultScan8x8[64]
colScan8x8[64]
rowScan8x8[64]
defaultScan16x16[256]
colScan16x16[256]
rowScan16x16[256]
defaultScan32x32[1024]
```

##10.2 変換テーブル

```C++
bWidthLog2Lookup[BLOCK_SIZES]
bHeightLog2Lookup[BLOCK_SIZES]
num4x4BlocksWideLookup[BLOCK_SIZES]
num4x4BlocksHiehLookup[BLOCK_SIZES]
miWidthLog2Lookup[BLOCK_SIZES]
num8x8BlocksWideLookup[BLOCK_SIZES]
miHieghtLog2Lookup[BLOCK_SIZES]
num8x8BlocksHighLookup[BLOCK_SIZES]
sizeGroupLookup[BLOCK_SIZES]
txModeToBiggestTxSize[BLOCK_SIZES]
subsizeLookup[PARTITION_TYPES][BLOCK_SIZES]
coefBand4x4[16]
coefBans8x8Plus[1024]
energyClass[12]
mode2TxfmMap[MB_MODE_COUNT]
```

##10.3 パレート確率テーブル

```C++
paretoTable[128][8]
```

##10.4 固定確率テーブル

```C++
kPartitionProbs[PARTITION_CONTEXTS][PARTITION_TYPES-1]
kfyModeProbs[INTRA_MODES][INTRA_MODES][INTRA_MODES-1]
```

##10.5 デフォルト確率テーブル

```C++
defaultPartitionProbs[PARTITION_CONTEXTS][PARTITION_TYPES-1]
defaultSegmentationTreeProb[MAX_SEGMENTS-1]
defaultSegmentationPredProbs[3]
defaultYModeProbs[BLOCK_SIZE_GROUPS][INTRA_MODES-1]
defaultUvMmodeProbs[INTRA_MODES][INTRAMOES-1]
defaultSkipProb[SKIP_CONTEXTS]
defaultIsInterProb[IN_INTER_CONTEXTS]
defaultCompModeProb[COMP_MODE_CONTEXTS]
defaultCompRefprob[REF_CONTEXTS]
defualtSimgleFefProb[REF_CONTEXTS][2]
defaultMvSignProb[2]
defaultMvBitsProb[2][MV_OFFSET_BITS]
defaultMvClass0BitProb[2]
defaultTxProbs[TX_SIZES][TX_SIZES_CONTEXTS][TX_SIZE-1]
defaultInterModeProbs[INTER_MODE_CONTEXTS][INTER_MODES-1]
defaultInterpFilterProbs[INTERP_FILTER_CONTEXTS]
defaultMvJointProbs[3]
defaultMvClassProbs[2][MV_CLASSES-1]
defaultMvClass0FrProbs[2][CLASS0_SIZE][3]
defaultMvClass0HpProb[2]
defaultMvFrProbs[2][3]
defaultMvHpProb[2]
defaultCoefProbs[TX_SIZES][BLOCK_TYPES][REF_TYPES][COEF_BANDS][PREV_COEF_CONTEXTS][UNCONSTRAINED_NODES]
default
```