OmniAICreator/Qiita-1.07M huggingface dataset:
Python×業務効率化 使用してみたツールまとめ

#はじめに
現場にいながらPythonなどで細々としたツール開発をしているk_mayo_beamです。
この記事では自分が試してみたパッケージをまとめてみます。
他にこんなのもあるよーっていう方がおりましたら、コメント等で教えてくれたらうれしいです。
#Excelに関する業務
現場でダントツに多いExcel業務です。
##Openpyxl
PythonでExcelファイルの操作ができるパッケージです。
機能的にはExcelVBAでできることの8割ってところでしょうか（体感）。
**多数のExcelファイルに同様の変更をするなどの業務を自動化できます。**
結合セルに罫線が引かれているファイルは読み込むと罫線が壊れてしまう既知の問題があり、**日本流の複雑な帳票作成には相性が悪い**のが欠点です。
##pandas
データ分析に特化したDataframeという型を提供するパッケージです。
ExcelファイルやCSV形式での大量のデータを集計、分析、グラフ化することができます。
**今のところExcelデータの抽出やフォーマット修正などの自動化**に使用することが多いです。
後述のPyinstallerでexe化するのが大変で、**配布がめんどくさい**です。
##win32com
仕組みはよく理解していないですが、WindowsのアプリをPythonから触ることができるツールです。
とりわけ、ExcelをPythonから起動し、マクロを実行するのに使用しています。
**既存のマクロを使う業務を複数つなげる**ことができるので、意外に使えます。
また、本家Excelを起動するので、ファイルや表示が壊れるなんてことが少ないのも特徴で、帳票作成の自動化はこれで開発しています。
当然、**Windows以外や本家Excelがインストールされていない環境では使用できない**でしょう。
#PDFに関する業務
PDFをマージしてみたり、分割してみたり、書いてあることをまとめたり。。。
なんか作業的な業務が多いけど、自動化が面倒なPDFに関する業務です。
##PyPDF2
PDFの内容に関係のない、分割やマージといった機能を提供するパッケージです。
基本的に**分割とマージ**に使って、自動化の一部を担うことが多いです。
一応、文字を挿入したり、画像を差し込んでみたりもできるらしいです。
##PDFminer
PDFを文字列化する機能を提供するパッケージです。
PDFを文字列化して、リネームに使用したりします。
**OCR機能ではないので、画像部分を文字列化することはできません。**

#最後に
2018/9/8段階では、ExcelとPDFについて使用したものをまとめています。
個別の具体的な事例は追って記事にできたらいいなぁと思っています。
また何か見つけたら更新しますね。
SQLZOO 「SUM and COUNT」 回答集

###＜2020/08/15 追記＞
現在、SQLの学習をSQLZOOで開始するのはあまりお勧めできません。
別のサービスの活用をご検討ください。

---


SQLZOOの「SUM and COUNT」の回答集です。

---

1 . Total world population

```
SELECT SUM(population)
FROM world
```
>そのまま

2 . List of continents

```
SELECT DISTINCT continent 
FROM world
```
>DISTINCTでユニーク化


3 . GDP of Africa

```
SELECT SUM(gdp) 
FROM world
WHERE continent = 'Africa'
```

4 . Count the big countries

```
SELECT COUNT(name) 
FROM world
WHERE area >= 1000000
```
>

5 . Baltic states population

```
SELECT SUM(population)
FROM world
WHERE name IN ('Estonia', 'Latvia', 'Lithuania')
```
>

6 . Counting the countries of each continent

```
SELECT continent, COUNT(name)
FROM world
GROUP BY continent
```
>continentごとに集計する、という指定のために「GROUP BY」が必要です。

7 . Counting big countries in each continent

```
SELECT continent, COUNT(name)
FROM world
WHERE population >= 10000000
GROUP BY continent
```
>WHERE句とGROUP BY句の順番に注意しましょう。

8 . 

```
SELECT continent
FROM world
GROUP BY continent
 HAVING SUM(population) >= 100000000
```
>HAVING句は集計した後の結果で結果が絞られます。
>WHERE句は集計する前の値で結果を絞るので、この場合は不適当。
>書く順序に違和感があるかも知れませんが、GROUP BY句のあとにHAVING句が読み込まれます。
SQLZOO「SELECT within SELECT Tutorial」 回答集

###＜2020/08/15 追記＞
現在、SQLの学習をSQLZOOで開始するのはあまりお勧めできません。
別のサービスの活用をご検討ください。

---

SQLZOOの[「SELECT within SELECT Tutorial」](https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial)の回答集です。
前回の[「SELECT from Nobel Tutorial」](https://qiita.com/TakahiroNAMBU/items/df954450b75b28c5853d)の続編です。

---
1. Bigger than Russia

```
SELECT name FROM world
  WHERE population >
     (SELECT population FROM world
      WHERE name='Russia')
```
>国名を変えるだけ

2 . Richer than UK

```
SELECT name
FROM world
WHERE continent ='Europe'
  AND gdp/population >
     (SELECT gdp/population FROM world
      WHERE name='United Kingdom')
```
>


3 . Neighbours of Argentina and Australia

```
SELECT name, continent
FROM world
WHERE continent IN
    (SELECT continent
     FROM world
     WHERE name IN ('Argentina', 'Australia'))
ORDER BY name
```
>

4 . Between Canada and Poland

```
SELECT name, population
FROM world
WHERE population >
    (SELECT population
     FROM world
     WHERE name = 'Canada')
    AND
      population <
        (SELECT population
         FROM world
         WHERE name = 'Poland')
```
>BETWEEN句だと失敗しました。~~（できるはずですよね..？）~~BETWEEN句だとA以上B以下で、A,Bを含む形になってしまうためNG。


5 . Percentages of Germany

```
SELECT name, CONCAT(ROUND(population/
    (SELECT population
     FROM world
     WHERE name = 'Germany')
   *100, 0),'%')
FROM world
WHERE continent = 'Europe'
```
>多重構造でややこしいのですが、個別に見ていきましょう。
>>ROUND(数値,0)
→数値を小数点以下第一位で四捨五入する

>>CONCAT(a,b)
→aとbを繋げて「ab」と表示。今回の場合はROUNDした数値に%をつける形。

6 . Bigger than every country in Europe

```
SELECT name
FROM world
WHERE gdp > ALL
    (SELECT gdp
     FROM world
     WHERE continent = 'Europe' AND gdp > 0)
```
>ALLで特定数値との比較なくすべてを抽出
>NULL値を除く処理も加えている。

7 . Largest in each continent

```
SELECT continent, name, area FROM world x
  WHERE area >= ALL
    (SELECT area FROM world y
        WHERE y.continent=x.continent
          AND area > 0)
```
>クエリのテーブルをx、サブクエリのテーブルをyとして
y.continent=x.continentで両テーブルの一致を探している。

8 . First country of each continent (alphabetically)

```
SELECT continent, min(name)
FROM world
GROUP BY continent
```
>文字列カラムに対してmin()を使うと、アルファベット順に最初のもの、となります。

9 . Difficult Questions That Utilize Techniques Not Covered In Prior Sections

```
SELECT name, continent
FROM world x 
WHERE population/3 >= ALL
(SELECT population
FROM world y
WHERE y.continent=x.continent
AND x.name != y.name)
```

---
###続きはこちら

[SQLZOO 「SUM and COUNT」 回答集](https://qiita.com/TakahiroNAMBU/items/8efc21051b907993b3e4)
node.js でc++ライブラリを動かすまで

##  準備

- まずはnode.jsをインストール
- node.jsの拡張モジュールnode-gypをインストール

```
　　　　npm install node-gyp　
```

- nativeのライブラリを読み込むためのモジュール `node-ffi`をインストール

```
npm install node-ffi
```
## ソースコード

### C++

```C++

#ifdef __cplusplus
extern "C" {
#endif
  int my_func1(int x){
  cout << "here is my_func1 in C++\n";
  return x * 2;
  }
}

#ifdef __cplusplus
extern "C" {
#endif
void my_func2(const char* x1){

    cout << "here is my_func2 in C++\n";

    string x1_conv = string(x1);
    string x2 = "+ C++(str2)";
    string x3 = x1_conv + x2;
    cout << x3 << "\n";

    }
}

#ifdef __cplusplus
extern "C" {
#endif
char* my_func3(const char* x1){

    cout << "here is my_func3 in C++\n";

    const char* x2 = "+ C++(str3)";
    size_t x1_len = strlen(x1) + 1;
    size_t x2_len = strlen(x2) + 1;
    char* x3;
    x3 = (char *)malloc(x1_len + x2_len);
    sprintf(x3, "%s %s\n", x1, x2);

    return x3;
}
}

typedef struct tag_my_struct{
    int x;
    int y;
    char* s;

}my_struct;

#ifdef __cplusplus
extern "C" {
#endif
void my_func4(my_struct* ms){

    cout << "here is my_func4 in C++\n";
    cout << "x: " << ms->x << '\n';
    cout << "y: " << ms->y << '\n';
    cout << "s: " << ms->s << '\n';
    cout << "s add:" << ms->s << '\n';
    printf("C++ ms add: %p\n", ms);
    printf("C++ s add:%p\n", ms->s);
}
}
```

### Node.js

```node.js
var ffi = require('ffi')
var ref = require('ref')
var Struct = require('ref-struct')

// 構造体の定義
var my_struct = Struct({
  'x': ref.types.int,
  'y': ref.types.int,
  's': ref.refType(ref.types.char)
})

// 構造体の型を格納
var ptr_my_struct = ref.refType(my_struct);

// 構造体のポインタの型を格納
var ptr_str = ref.refType(ref.types.char);

// ffi.Libraryでライブラリ内関数の宣言
var libfactorial = ffi.Library('./c++/cmake-build-debug/libmyTest', {
  'my_func1': [ "int", [ "int" ] ],
  'my_func2': [ "void", [ "string" ] ],
  'my_func3': [ "string", [ ptr_str ] ],
  'my_func4': [ "void", [ ptr_my_struct ] ]
})

if (process.argv.length < 3) {
  console.log('Arguments: ' + process.argv[0] + ' ' + process.argv[1] + ' <max>')
  process.exit()
}

// ライブラリ内へ渡す関数の引数定義
var str2 = 'Node.js(str2)'
var str3 = 'Node.js(str3)'

// 文字列はstring型宣言ではなく、Bufferオブジェクトを渡すことでもアドレス参照される
var str3_buf = Buffer.from(str3, "utf8")

// 構造体のインスタンス
var my_struct_val = new my_struct;

// 構造体内の文字列のBuffer定義
var str4 = 'Node.js(str4)'
var str4_buf = Buffer.from(str4, "utf8")

// 構造体内の変数に値を格納
my_struct_val.x = 1000
my_struct_val.y = 2000
my_struct_val.s = str4_buf

var output1 = libfactorial.my_func1(parseInt(process.argv[2]))
console.log('Node.js output1: ' + output1)

var output2 = libfactorial.my_func2(str2)

var output3 = libfactorial.my_func3(str3_buf)
console.log('Node.js output3: ' + output3)

var output4 = libfactorial.my_func4(my_struct_val.ref())
console.log(my_struct_val.ref())
console.log('my_struct_val.s add' + ref.address(my_struct_val.s).toString(16));

```
BigQuery GIS Alpha program を試してみた　~ 登録からGeoVizの地図表示まで ~

# はじめに
　Googleが提供する強力なデータ分析環境であるBigQueryが、空間情報処理（GIS）関数のアルファテストが開始されましたので試してみました。

# Betaに移行されました！
2018年9月10日にBeta版に移行されたようです。
BigQueryを利用可能な人は誰でもGIS関数が利用可能です

ドキュメントも公開されました
https://cloud.google.com/bigquery/docs/gis-intro?hl=JA

# Alpha版の利用までの流れ（現在は必要ありません！）
 1. Googleのクラウド環境（Google Cloud Platform）に利用登録する
 2. [ブログ記事](https://cloud.google.com/blog/products/gcp/bridging-the-gap-between-data-and-insights)にあるテスト登録リンクを探す
  - https://cloud.google.com/blog/products/gcp/bridging-the-gap-between-data-and-insights
  - 下記の文の最後にリンクがあります。<br />
 > BigQuery GIS and BigQuery Geo Viz are in public alpha now. To request access to both, please fill out this <font color="red"><b>form</b></font>.  
 3. フォームに必要事項を記入する
 4. 登録完了待つ(私は4日かかった）

# 登録メールが来たら
　「BigQuery GIS Alpha program」というタイトルのメールが、google.comの個人アカウントから送られて来ました。

- bq-gis-feedback グループに参加しましょう（必要に応じて職場の同僚も）
    - GIS関数とGeoVizのクイックスタートガイドがあるよ
    - 困ったことを調べたり、要望を書き込んだりしましょう
- BigQuery のGIS関数と GUIツールのGeo Viz の利用登録も完了

# 動作チェック
実際に空間関数が動くことを試してみましょう。
## Geo Vis で地物を表示
### 1. Geo Vis にアクセス 
   https://bigquerygeoviz.appspot.com/
<img src="https://qiita-image-store.s3.amazonaws.com/0/53918/6078b24a-3925-f003-8564-ba39bde43a04.png" height=200px />

### 2. アカウントの登録
ログオンするGoogleアカウントを選択します。GCPの登録したアカウントを選んでください。
<img src="https://qiita-image-store.s3.amazonaws.com/0/53918/3c2639e5-8115-a2d4-b235-e3d994e6c1b2.png" height=80px />

### 3. SQLの実行
#### 3.1 設定
SQLを実行するには、SQLの記述の他に、クラウド環境の設定が2つ必要です。

 - Project ID <br /> GCPのプロジェクトを選択します。<br />（GCPは1アカウントで複数のプロジェクトに登録可能なため）
 
 - Prosessing location <br />クラウドの場所の選択 ( US・UK・asia-notheast など）<br /> AWSのリージョンの選択と同じです。

#### 3.2 SQLの作成

　BigQueryのGIS関数で処理可能な型は、GEOGRAPHY型。対応している測地系は世界測地系（WGS84:SRID=4326)です。

```sql:tsuzuki_mamoru.sql
SELECT 
 '都筑まもる君' AS point_name 
, st_geogfromtext( 'POINT(139.57899 35.549542)') AS geog;
```
SQLがかけたら「Run」ボタンを押下します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/53918/957e97c7-4cc6-377f-bd16-e6bbe8e38b3d.png" width=300px />

### 4.実行結果の地図表示
　地図に表示したい地物が出力されている列名（カラム名）を指定すると。実行結果が地図表示されます。

<img src="https://qiita-image-store.s3.amazonaws.com/0/53918/0489be68-1187-b88c-1c64-ef70165bda5c.png" width=300px />
　Define columnsをクリックしたあとに、プルダウンメニューから列名を選択してください。例では「geog」がGeometry columnに該当します。

# まとめ
　BigQueryのGIS関数の利用申請から、Geo Visを用いた動作検証を行いました。
　はまった箇所としては、どこから登録申請をすればいいのか分からなかったこところです。alphaテストが終了しGeneral Availabilityになれば一切必要無い手続きです。
　あと半年もすれば、数兆行のGISデータを誰もが簡単に取り扱える時代が到来します。
nodejs8 on Google App Engineにアクセス制御を導入する

nodejs8 runtimeのGoogle App Engineなんですが、
python27などのruntimeと違って、app.yamlへのhandlerへのadimn……によるアクセス制御が対応していないので実は設定できません。

なら、nodejs8のruntieを使用した時にGoogle App Engineでどうやって認証をするのか？というと、
[Identity-Aware Proxy](https://cloud.google.com/iap/docs/gcloud-enablement-howto?hl=ja)を使ってアクセス制御を設定してあげる感じになります！

Google App Engineは適当なサービスが動いているという前提で、Identity-Aware Proxyの設定の仕方を！

# IAPの有効
といっても設定は簡単です。
GAEをデプロイ済みであれば下の画面のように表示されるので、IAPを有効にしてあげます！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/7c30f1ac-a162-86ac-3edf-dafe05993f62.png)

# 情報パネルからアクセス可能ユーザの追加！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/44b5ae27-3019-4cf7-b939-0cd40bb48520.png)

「IAP-Secured Web App Use」の権限をアクセスさせたいユーザに追加してあげます。
そうすると、対象のサービスにアクセスした際にGoogle認証の制御が入るようになり、設定したユーザしかアクセスできないようになります。

## 設定する際の補足

 - 情報パネルにも書いてあるのですが、オーナー権限を持っていてもアクセスできません。
 - オーナー権限は権限の設定ができるようになるだけです。
 - IAP-Secured Web App Useの権限があればアクセスできるようになります。
 - ただ！　反映が結構遅いので、後述の確認作業をしようとしても……反映されてないことが
 - そういう時は近所でも10kmぐらい走って時間を潰しましょう

# アクセスしてみる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/eed9fc62-1adc-6469-a255-e06cac0f3013.png)

アクセスしてみると、こんな感じで聞かれるので、ログインしてみましょう

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/d294594a-398a-ddba-38ff-f1bf272b604b.png)

ログインが突破できるとこんな感じで、画面が表示されます！

# 認証失敗の場合

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235100/a25d6c05-6cc1-08bc-d591-1827ff7133ab.png)

もうちょっと綺麗な画面が欲しい:frowning2:
マテリアルデザインガイドラインからStepperが消えた理由を考える

結論のない、完全に自分用のメモ。
2018年９月初旬の情報なので、いずれ何の役にも立たない情報になるでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74571/b91332f7-50c9-3550-deed-19888dcf9534.png)

もともと https://www.google.com/design/spec/components/steppers.html にあったのが、material.io以降のタイミングかどこかで、闇に葬られてしまった。
（追記: [ここ](https://material.io/archive/guidelines/components/steppers.html#)にあった）

* とくに「代替コンポーネントはこれだ」って情報もない
* Flutterでは[公式ライブラリ?](https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/stepper.dart)が現存している模様
* Backdropの説明のところで「stepperとあわせてつかうのもよし」みたいなのは残っている

:thinking: :thinking: :thinking:  なんでStepperってコンポーネントの説明は消えたんだろう・・・ :thinking: :thinking: :thinking:


## 予想１：Backdropのサブみたいな位置づけになった？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74571/9e30f569-4e47-74aa-d018-b91a97f9a803.png)

Backdropの説明には明確にStepperが登場している。

この程度であれば、ぶっちゃけライブラリに頼らなくても実装できるだろう。
もともと存在していたStepperは、そもそもパターンが多かったし、アニメーションとかもあったり無かったりしていて、１つのコンポーネントとして語るには複雑性が高すぎたのではないか？

## 予想２：ほとんど使われていなかった割に、複雑性が高い（＝コスパのよくない）コンポーネントだった？

マテリアルデザインは、おそらく

* デザインが容易（属人化しないためのspec策定、シンプルなルール）
* 実装が容易（表現手段が単純、標準ライブラリによる手厚いサポート）

という部分にもかなり重きをおいていると個人的には思っている。（対 🍎フラットデザイン）

そういう観点でいくと、Stepperは

* horizontal/vertialがある
* ふるまいのパターンが複数ある
    * 完了時の見せ方はグレーアウト系？アクセントカラー？
    * 前のステップに戻る方法は、stepのタップ？明示的にボタン置く？

のように、「使わなくてもViewPagerIndicatorあたりで十分！」ってケースでも使いたくなってしまうような曖昧性があったのではないかと予想。

## 予想3: 既存のコンポーネントとどう組み合わせるかを考えると、ライブラリ化できなかった？

たとえばAndroidで仮にStepperを実装するとしたら、何をつかうだろう？

* FragmentAdapter的なものを受け取って、外回りをなんらかのアダプタViewにする？
* 単純にLinearLayoutで全体をつくってしまって、開閉状態とか選択状態とかを状態でもつ？

などなど、これといった最強の方法が思いつかない。現に、サードパーティのライブラリもいくつかあるが、実現方式はいろいろだ。

[material design components](https://github.com/material-components)として公式に配布するには、[ボトムシートのとき](https://developers-jp.googleblog.com/2016/03/android-support-library-232.html)みたいに、単一的な実装が求められるが、Stepperにはそれができなかったんじゃないか？という予想。


## 結論

よくわからん。

わかったら追記する。
MacOSの＋ボタンを取り戻し、かつ自分好みにするお話

# tl;dr

- **最大化ボタンの挙動をYosemite以前の動きに戻したい**
- FullScreenER(SIMBL Plugin)を元にSwiftで書き直したものを作ってリリースした

# 前置き
Yosemiteを覚えているだろうか。もう4年も前のことになる。
**あのときから我々はウィンドウの最大化ボタンを押す際にOptionKeyを押しっぱなしにしなくてはならないこと**を強いられてきました。

<img width="128" alt="102144D3-7BD3-4A84-A9F3-4508A331BF12.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/7161/0b75f5fb-7d27-c4fe-fef8-1dbbf268988c.jpeg">
This is Shit💩(個人の感想です😜)

<img width="128" alt="23A8A5B5-CF31-4142-B095-4EF268DF043D.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/7161/1165db64-5f9d-b609-52f4-8a4a0ff8c6d0.jpeg">
It's great! 👍(個人の感想です💩)

今回のお話は、フルスクリーンボタンを従来の＋ボタンの動きに取り戻すお話です。

# FullScreenERとは
FullScreenERはウィンドウの最大化ボタンの動きを従来の動きに戻し、Optionキー及びウィンドウ右側にあるフルスクリーンボタンを押すことで新旧2つの動作をウィンドウに与えるためのSIMBLプラグインです。

非常に使い勝手が良いのでずっと愛用してきたんですが、ウィンドウ最大化時にアニメーションが適用されることと、ウィンドウ右端になる最大化ボタンが個人的には気に入らず、これまでソースを変更して使ってきました。

そして時は流れ…Swiftがリリースされ早4年、そろそろSwiftを使ったSIMBLプラグインの作り方を学ぼうかなというタイミングでもあったので、FullScreenERを元にSwiftで同様の動きをするプラグインを作ることにしました。


# WelcomeBack GreenPlusButton

というわけで、ある程度動作確認も完了したのでリリースしたいと思います。

とりあえず配布バイナリから。 
[https://github.com/salexkidd/WelcomeBackGreenPlusButton/releases/tag/1.3](https://github.com/salexkidd/WelcomeBackGreenPlusButton/releases/tag/1.3)

[ソースはこちら](https://github.com/salexkidd/WelcomeBackGreenPlusButton)


## インストール方法
- [MySIMBL](https://github.com/w0lfschild/mySIMBL)をインストールする(多分SIPモードにする必要あり)
- 上記のURLからダウンロードしたプラグインを放り込む
- 再起動/ログオフ または アプリケーションを再起動する

以上で適用されます。


## 問題点と注意点

- このソフトウェアはBSDライセンスとしてリリースしています。
- 気をつけて作ってはいるものの、まだバグがあるかもしれません。
- FullScreenERの作者に新たなリポジトリとして出して良いか聞いてはいるものの、変わる可能性もあるので公開中止になる場合もあります
- バグ等があればコメント欄か、[@salexkidd](https://twitter.com/salexkidd) までご連絡ください


XcodeやkeynoteなどのAppleが作ったソフトウェアの場合以下のようなエラーとともに適応されない場合があります。

```
Error loading /Library/Application Support/SIMBL/Plugins/WelcomeBackGreenPlusButton.bundle/Contents/MacOS/WelcomeBackGreenPlusButton:  dlopen(/Library/Application Support/SIMBL/Plugins/WelcomeBackGreenPlusButton.bundle/Contents/MacOS/WelcomeBackGreenPlusButton, 265): no suitable image found.  Did find:
	/Library/Application Support/SIMBL/Plugins/WelcomeBackGreenPlusButton.bundle/Contents/MacOS/WelcomeBackGreenPlusButton: code signature in (/Library/Application Support/SIMBL/Plugins/WelcomeBackGreenPlusButton.bundle/Contents/MacOS/WelcomeBackGreenPlusButton) not valid for use in process using Library Validation: mapping process and mapped file (non-platform) have different Team IDs
	/Library/Application Support/SIMBL/Plugins/WelcomeBackGreenPlusButton.bundle/Contents/MacOS/WelcomeBackGreenPlusButton: stat() failed with errno=1
```
【Aidemy】ブロックチェーン基礎のコードの整理 ①

ブロックチェーン基礎を学習している中で詰まってしまったので、
コードの内容の整理として記録

内容はブロックチェーン基礎　1.2.3 ジェネシスブロック

```python
 
import time

class Blockchain:
    def __init__(self):
        self.chain = []
        self.current_transactions = []
        self.transaction_index = 0
        self.create_block(nonce="hoge", previous_hash="00000")
        
    # ジェネシスブロックを作成する関数を完成させてください
    def create_block(self, nonce, previous_hash):
        block = {
            'index' :  len(self.chain),
            'timestamp' : time.time(),
            'transactions' : self.current_transactions,
            'nonce' : nonce,
            'previous_hash' : previous_hash,
        }        
        # ブロックの追加をします
        self.chain.append(block)
        return block
    
    
blockchain = Blockchain()
print(blockchain.chain)
```

上から順番に整理していく

```
import time
```

timestampにて、ブロックが生成された時間を受け取る必要があるため必要なモジュール

```
blockchain = Blockchain()
```

この部分でクラスのインスタンスオブジェクトを生成しており、その内容が以下

```
class Blockchain:
    def __init__(self):
        self.chain = []
        self.current_transactions = []
        self.transaction_index = 0
        self.create_block(nonce="hoge", previous_hash="00000")
```
self.chain：リスト化
current_transactions：このブロック内での取引データ
transaction_index = 0：初期値を0と指定
self.create_block(nonce="hoge", previous_hash="00000")：この関数は別に定義

```
    def create_block(self, nonce, previous_hash):
        block = {
            'index' :  len(self.chain),
            'timestamp' : time.time(),
            'transactions' : self.current_transactions,
            'nonce' : nonce,
            'previous_hash' : previous_hash,
        }        
        self.chain.append(block)
        return block
```

関数create_block(nonce="hoge", previous_hash="00000")の詳細
blockの内部は辞書化されており、　
・'index' :  len(self.chain)　→　繰り返すことで要素が１ずつ増えていくので、index番号と一致
・'timestamp' : time.time(),　→　作成された時間を受け取る
・'transactions' : self.current_transactions,　→今回は定義なし
・'nonce' : nonce,　→引数１の値が代入される
・'previous_hash' : previous_hash,　→　引数２の値が代入される

self.chain.append(block)　→リストであるchainの末尾に辞書であるblockが追加される
create_block(self, nonce, previous_hash)にblockを戻り値として返す
→なぜ？
→おそらく次章で使用するから？（一旦保留）

以下が出力結果

```
[{'index': 0, 
  'timestamp': 1536389268.5988321, 
  'transactions': [], 
  'nonce': 'hoge', 
  'previous_hash': '00000'}]
```

出力内容の整理
変数bloclchainの.chianなので、リストが出力される
・ジェネシスブロックなのでindexは0
・transactions': []なので、今回は取引されたデータはなし
・nonce値は「特に指定がない」という意（？）のhoge
・previous_hash': '00000'は、直前のブロックがないので00000としている（？）
MySQL4のujis(EUC-JP)なDBをMySQL5.6 UTF8なDBにインポートするためにやったこと。


古いXOOPS2.0.x.JPで作られたWebサイトのDBなんかだと MySQL4 で文字コードはujis（EUC-JP)なんてことが結構あります。

そんなDBデータをMySQL5.6でUTF8な環境に移行させようとするとまぁ色々問題でてきてそのままだとインポートできません。

とあるサイトのDBデータを移行するために色々やったことを参考までに書いておきます。

# 文字コードぐちゃぐちゃ

DBデータに結構文字化けしたデータが入ってることあります^^;

こいつをなんとかしないと、インポートこけちゃうのでまず文字コードをなんとかします。

今回試したのは次の手順

1. MySQL4のphpMyAdminでshit-jisでエクスポート
2. 秀丸エディタで開く
3. 文字コードおかしなところを検知してジャンプできるので、文字化けを手修正
4. 名前をつけて保存でUTF8にして保存。
 
![utf8.png](https://qiita-image-store.s3.amazonaws.com/0/9845/89cb77a1-2fe0-b1ca-6270-3b2382aa794b.png "utf8.png")

3番目の手順で文字化けを手動修正するときは、どうせ文字化けしてよめないんだから【文字化けデータ】とかなんでもいいので置き換えちゃうという割り切りも必用です。

# TYPE= を ENGINE= へ一括置換

```TYPE=```は廃止されてるので ```ENGINE=``` に一括置換します。


# MySQLの仕様が変わってエラーになる構文を修正

これはインポートにトライしながら見つかった構文エラーを一つ一つ修正しました。
今回移行したデータで発生したのは下記2点

## Incorrect index name


```
  UNIQUE KEY `` (`desc_form`)
```

こんなのがあったんですが、不要と判断して削除。
XOOPSのformmailモジュールの formmail_idテーブルの定義にありました。

## Too big precision 14 specified for column 'dtstamp'. Maximum is 6.


```
`dtstamp` timestamp(14) NOT NULL,
```

こんな定義。これはXOOPSのpiCalモジュールの定義で発見。全部timestamp(6)に置換しました。

ここまできてやっとインポート成功です。

ちなみにこのWebサイトでのDBデータではシリアライズされたデータもあったので　[EUC-JPでserializeされた文字列をUTF-8でunserializeする。 - Qiita](https://qiita.com/RyujiAMANO/items/c7cdbb8f4f95641fd72e) に書いた変換もこのあと行いました。
Play の BodyParser を組み合わせる

Play では次のようにリクエストボディにアクセスします。

```scala
def save = Action { request: Request[AnyContent] =>
  val body: AnyContent = request.body
  // 
```

デフォルトでは上記のように `request.body` は `AnyContent` 型です。
`Content-Type` ヘッダの値によって適切な型として parse されます。たとえば `Content-Type` が `application/json` であれば JSON として parse され、`request.body.asJson` で JSON が取り出せます。

今回はパースされたボディと共に、生のリクエストボディにアクセスしたいと思いました。

Play では `BodyParser[A]` が HTTP リクエストボディを解釈します。
[その定義](https://github.com/playframework/playframework/blob/2.6.18/framework/src/play/src/main/scala/play/api/mvc/Action.scala#L124) を見るとわかるように `RequestHeader => Accumulator[ByteString, Either[Result, A]]` を継承しています。

```scala
trait BodyParser[+A] extends (RequestHeader => Accumulator[ByteString, Either[Result, A]]) {
```
`Accumulator` は akka-stream の `Sink` のようなもので、ここではリクエストボディのバイト列（いくつかに分かれているかもしれない）を受け取って最終的に `Either[Result, A]` を返します。

最初に考えたのは、生のボディを渡してくれる BodyParser を使っておいて、 Action の中で `ByteString` から目的の型へパースする方法。しかし、ByteString から目的の型へパースするのは BodyParser の役割そのものであり、そこは BodyParser を使いまわしたいと思い直しました。

つぎに考えたのは `BodyParser[A] => BodyParser[(A, ByteString)]` という関数をつくる方法。これはこれで動きそうなのですが、ByteString はメモリ上に乗ることになるので、リクエストボディが長いときに使ってしまうとメモリがあふれる危険があります。

リクエストボディが長いときにはディスクに書いてほしいものです。まさにそれをしてくれるのが [raw BodyParser](https://github.com/playframework/playframework/blob/2.6.18/framework/src/play/src/main/scala/play/api/mvc/BodyParsers.scala#L530) です。
任意の BodyParser と raw BodyParser を組み合わせるとやりたいことが実現できそうです。

実際には任意の BodyParser 2つを組み合わせる形で実装してみました(at #rpscala 勉強会)。できたのが↓です。

https://gist.github.com/tkawachi/9f89782d665d37b21bc983863dc03e35

`と` というメソッドを生やしたので `bodyParsers.json と bodyParsers.raw` といった形で BodyParser を合成できます。JSON としてパースつつ、生のリクエストボディにアクセスできます。

実装上のポイントとして `Broadcast[ByteString](2, eagerCancel = false)` で `eagerCancel` を false にしている点が挙げられます。これは２つの BodyParser にそれぞれ生のリクエストボディを流し込む中継ポイントです。eagerCancel を true にした場合、どちらかの BodyParser がエラーとなった場合（たとえば JSON を期待する BodyParser が JSON ではない文字列を読み込んだ場合）に、即座に中継ポイントがキャンセルされ、もう一方の BodyParser もその時点で終了します。効率は良いのですが、結果の合成の結果、エラーを起こした方ではない BodyParser の出力結果が優先されることがあります。そうなると直感的ではないエラーがリクエスト元に返されることになるため、ここでは eagerCancel を false にしています。一方がエラーになってももう一方はパース処理を続けるため、効率は悪いのですがエラーがわかりにくいという問題は起きません。（両方の BodyParser がエラーになった場合には最初の BodyParser が出したエラーが出力となります。）
【Python Janome】形態素解析3行コード

```python
from janome.tokenizer import Tokenizer
t = Tokenizer()
tokens = t.tokenize("形態素解析対象文")

# 出力
for token in tokens:
    print(token)
```

品詞で限定する場合

```python
def extract_words(text):
    tokens = t.tokenize(text)
    return [token.base_form for token in tokens
            if token.part_of_speech.split(',')[0] in [u'名詞', u'動詞']]
```
ADBでkill-serverできないときは

ある時から、ADBを実行すると応答しなくなるようになりました。

たとえば、

```
$ adb start-server

```

や

```
$ adb devices
List of devices attached

```

のあと、待機状態のまま応答しなくなります。

そして`kill-server`も同様に応答がなくなり使えません。

このような場合の対処としては、`lsof`で5037番ポートでLISTENしているプロセスをkillしてADBを落としてやりましょう。

```
$ sudo lsof -i | grep 5037
adb        4864    user    6u  IPv4 0xbc565019343e37eb      0t0    TCP localhost:5037->localhost:64155 (CLOSE_WAIT)
adb        4864    user    8u  IPv4 0xbc565019363c87eb      0t0    TCP localhost:5037 (LISTEN)
adb        5918    user    3u  IPv4 0xbc565019363eaaab      0t0    TCP localhost:50581->localhost:5037 (ESTABLISHED)
adb        7411    user    3u  IPv4 0xbc56501936384aab      0t0    TCP localhost:51923->localhost:5037 (ESTABLISHED)
adb        7790    user    3u  IPv4 0xbc5650192d8de7eb      0t0    TCP localhost:52002->localhost:5037 (ESTABLISHED)
adb        8190    user    3u  IPv4 0xbc565019365007eb      0t0    TCP localhost:52385->localhost:5037 (ESTABLISHED)
```

```
$ sudo kill 4864
```

`kill-server`できないときの奥の手ということで。

## 参考

https://stackoverflow.com/questions/17851480/adb-not-responding-you-can-wait-more-or-kill-adb-exe-windows-8
Django 1.9 から 2.1 に上げる時の備忘録

#Django 1.9 で作成されたアプリを 2.1.1 対応した際の手順を備忘録として、また同じことをやろうとしてる人への参考として残します。

###1. urls.py の設定を変更します

参照：[https://docs.djangoproject.com/ja/2.1/topics/auth/default/#all-authentication-views](https://docs.djangoproject.com/ja/2.1/topics/auth/default/#all-authentication-views)

urlpatterns=[] の中 url(r'^$', app.views.home, name='home') の url を re_path に置き換えます。
次にログイン・アウトビューが django.contrib.auth.viewsの login と logout メソッド から django.contrib.auth.views の LoginView と LogoutView クラスに変更になっているためここも変更します。
変更後の urls.py はこんな感じです。

```python:urls.py
urlpatterns = [
    # Examples:
    re_path(r'^$', app.views.home, name='home'),
    re_path(r'^contact$', app.views.contact, name='contact'),
    re_path(r'^about', app.views.about, name='about'),
    re_path(r'^login/$',
        auth_views.LoginView.as_view(template_name="app/login.html"), name="login"),
    re_path(r'^logout$',
        auth_views.LogoutView.as_view(next_page='/'), name='logout'),

    # Uncomment the admin/doc line below to enable admin documentation:
    # re_path(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    # re_path(r'^admin/', include(admin.site.urls)),
]
```
ちなみに、Logout 後のリダイレクトをトップページにしています。
適宜 next_page='/' の所を変更して下さい。
（settings.py に LOGOUT_REDIRECT_URL など設定しておくと良いかも）

###2. settings.py の MIDDLEWARE_CLASSES を MIDDLEWARE に変更します。
参照：[https://docs.djangoproject.com/ja/2.1/topics/http/middleware/#activating-middleware](https://docs.djangoproject.com/ja/2.1/topics/http/middleware/#activating-middleware)

単純に MIDDLEWARE_CLASSES を MIDDLEWARE に変更するだけです。
（ここはDjanog1.10以上なら既に変更されていると思います）
更に、'django.contrib.auth.middleware.SessionAuthenticationMiddleware' を削除します。

変更後の settings.py はこんな感じです。

```Python:settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```
###3. あとがき
余りやる事は無いかもしれませんが、情報を探すのに手間取ったため纏めておきました。
また、解決に至るまでに [stack overflow](https://stackoverflow.com/) の回答も参考にさせて頂きました事、ここに御礼申し上げます。
JenkinsでC++/VB.netをビルド/デプロイするときに役立つコマンド集

# はじめに
Jenkinsを使ってC++/VB.netを扱う場合、MSBuildプラグインなどC++/VB.net用のプラグインを利用すると思いますが、会社や環境によってプラグインの追加を制限されていると思います。そんな時に使えるバッチコマンドをメモとして残したいと思います。
今後、随時追加していきたいと思います。

# 前提
- Jenkinsが稼働しているマシンのOS: Windows Server (Linuxではない)
- ビルド環境でJenkinsが稼働している
- 上記にVisual Studioをインストール済み
- ビルド環境と開発環境(デプロイ先)は別マシン

# コマンド一覧
## 0.コマンドの使い方を調べる「<コマンド> /?」
例えば、「dir /?」と実行するとdirの使い方が表示されます。
コマンドについてわからないことがあれば、すぐにググって調べるのもいいですが、まずは「/?」で使い方を確認してみましょう。

## 1.ビルドできるようにPATHを通す「set PATH=%PATH%;<通したいパス>」
Visual StudioでC++やVB.netをビルドする場合、MSBuild.exeやLC.exeを利用してビルドしています。
従って、バッチからビルドするにはMSBuild/LC.exeのフォルダのパスを環境変数PATHに設定して利用することになりますが、Visual Studioをインストールしただけでは環境変数に設定されません。システム環境変数にこれらのパスを設定してよいならそれでよいのですが、サーバの環境変数をルール上変更できない場合もあると思います。その場合は「set PATH=%PATH%;<MSBuild.exeのフォルダパス>;<LC.exeのフォルダパス」をバッチファイルに埋め込んでパスをバッチ内でパスを通すようにしましょう。

## 2.exeのパスを調べる「where <調べたいexe>」
上記でパスを通すにはMSBuild.exeのパスを当然ですが知っていないと通せません。
コマンドの実行ファイルがどこにあるかを調べるためにwhereコマンドを使います。
Visual Studioの開発者用のコマンドプロンプトを開き、「where MSBuild」と入力するとMSBuild.exeフォルダのフルパスが表示されます。

## 3.ビルド環境と開発環境をつなぐ「net use <開発環境のネットワークパス> <パスワード> /USER:<ユーザのドメイン>\ユーザ名」
通常、別のマシンのフォルダを参照するにはエクスプローラ上で「\\<接続したいホスト名\~~~」の形で参照させますが、バッチから「\\接続したいホスト名」と入力しても接続できません。
そこで 別マシンにファイルのコピーなどを実行する前にnet useコマンドを使って別マシンを接続しておく必要があります。

## 4.デプロイ時にrobocopyを使う場合はerrorlevelの設定を忘れずに
ビルド実行しビルド成果物である.exeや.dllを開発環境へデプロイするときにrobocopyを利用する場合に少し注意が必要です。
通常のバッチコマンドでは「成功時:0」「エラー有：0以外」です。jenkinsのビルド成功/失敗もこのerrorlevelで判断しています。
しかし、robocopyコマンドが成功した場合もerrorlevelが0以外になる場合があるため、注意が必要です。
robocopyではerrorlevelが0～4がコマンド成功、5以上がコマンド失敗になっています。
jenkinsのバッチで最後にrobocopyを実行する場合、errorlevelで場合分けして最終的なバッチの戻り値とする必要があります。
Above the fold（ファーストビュー）に含まれる CSS をインライン化してパフォーマンスの改善を図る

# 概要
HTML 内に外部 CSS が指定されていた場合、その CSS ファイルをダウンロードし記述されているルールセット[^1]のすべてを解釈するまで、ブラウザはレンダリングをブロックします。
本稿では、 Above the fold の構築に必要なルールセットをインライン化し、その他のルールセットを非同期で処理することで最適化をしてみます。

>Above the fold の構築に必要なルールセットを `Critical CSS` と呼ぶことが多いようです。
そのため、本稿でも `Critical CSS` と呼ぶことにします。

本稿では、 CSS の最適化を順を追って説明します。
近い内に、 `HTML Critical Webpack Plugin` を使って、本稿の内容を自動的に行う方法もまとめようと思います。

# 最適化の方法
概要でも述べたように今回は、 `Critical CSS` をインライン化して最適化を図ります。

## 最適化する
下記のような HTML があるとします。
今回は `Above the fold` の部分がスクロールしなくても見える部分で、`Below the fold` の部分がスクロールしないと見えない部分とさせてください。

```html:index.html
<html>
  <head>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="red">
      Above the fold
    </div>
    <div class="blue">
      Below the fold
    </div>
  </body>
</html>
```

また、 読み込まれている style.css の中身は下記だとします。

```css:style.css
.red { color: red; }
.blue { color: blue; }
.green { color: green; }
.yellow { color: yellow; }
```

この場合、下記のようにして、 最適化します。

```html:index.html
<html>
  <head>
    <style>
      .red { color: red; }
    </style>
    <link href="main.css" rel="preload" as="style">
  </head>
  <body>
    <div class="red">
      Above the fold
    </div>
    <div class="blue">
      Below the fold
    </div>
  </body>
</html>
```
まず、 `Critical CSS` を `<heade>` 要素内に `<style>` 要素内に移動します。
次に、 `<link href="main.css" rel="preload" as="style">`[^2] とすることで、 `style.css` を非同期で読み込みます。

# まとめ
Above the fold（ファーストビュー）に含まれる CSS をインライン化についてまとめました。
実際の業務などでは、`Critical CSS` の抽出を手動でするのは現実的ではないので、近い内に webpack を使って最適化されたファイルを自動的に生成する方法をまとめようと思います。

# 参考
[CSS の配信を最適化する | PageSpeed Insights | Google Developers](https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery)
[Preload](https://www.w3.org/TR/preload/)
[rel="preload" によるコンテンツの先読み - HTML: HyperText Markup Language | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Preloading_content)


[^1]: セレクタと宣言ブロックをあわせたものです。 `h1 {color: red;}` 左記のコードで言うと `h1` がセレクタ、 `{color: red;}` が宣言ブロックです。
[^2]: 対応ブラウザに注意してください。[loadCSS](https://github.com/filamentgroup/loadCSS) を使うことをおすすめします。
AnsibleでZabbixエージェントをインストールする

AnsibleでCentOSまたはUbuntuにZabbixエージェントをインストールする手順です。

### Ansible Roleの取得
requirements.ymlに以下を追加します。

```requirements.yml
- src: shomatan.zabbix-agent
```

`ansible-galaxy`コマンドでRoleを取得します。

```
ansible-galaxy install -p roles -r requirements.yml
```

### 設定項目一覧

| キー                      | デフォルト値                        | 説明|
|:-------------------------|:----------------------------------|:---------------------------|
| zabbix_agent_version     | 3.2                               | Zabbixエージェントのバージョン |
| zabbix_agent_server_host | 127.0.0.1                         | Zabbixサーバとアクティブチェック用サーバのホストまたはIPアドレス。|
| zabbix_agent_ListenPort  | 10050                             | サーバからの接続をリッスンするポート番号 |
| zabbix_agent_ListenIP    | 0.0.0.0                           | エージェントがリッスンする必要のあるカンマで区切られたIPアドレスのリスト |
| zabbix_agent_Hostname    | "{{ ansible_fqdn }}"              | 一意で、大文字小文字を区別するホスト名。アクティブチェックに必要 |
| zabbix_agent_LogFile     | /var/log/zabbix/zabbix_agentd.log | ログファイルのパス |

### Inventoryファイルの作成
inventory.ymlを以下の内容で作成します。`zabbix.agent.host`部分をインストール対象のサーバに変更します。

```inventory.yml
all:
  hosts:
    zabbix.agent.host:
```

### Playbookの作成

install.ymlを以下の内容で作成します。`zabbix.server.host`部分をZabbixサーバのホスト名に変更します。

```install.yml
- hosts: all
  become: true
  roles:
    - shomatan.zabbix-agent
  vars:
    zabbix_agent_server_host: zabbix.server.host
```

### Playbookの実行

```bash
ansible-playbook -i inventory.yml install.yml
```

### Firewallの設定
`zabbix_agent_ListenPort`で指定したポートをOpenします。
クロスサイトスクリプティング(XSS)メモ@rails

# XSS とは

## 概要
他人のWebサイトに悪意あるスクリプトを埋め込むことで、訪問者のクッキー情報を抜き取ったり、個人情報の不正搾取を行うこと。

悪意あるスクリプトを埋め込むためには、サイト上に入力フォームがある必要があり、この入力フォームに「悪意あるスクリプト(javascript)」を埋め込むことになる。例えば、

```example.js
<script type=”text/javascript”>
  alert(“ピヨピヨ”);
</script>
```

このように、入力フォームに「javascript」を埋め込む事が、クロスサイトスクリプティング（XSS）の基本的な手法になる。
以上が基本的なXSSの手法になるが、具体的にどういった脅威があるのか。

## 脅威例

「セッションハイジャック」：訪問者のクッキー（cookie）情報を抜き取ること。結果不正ログインなどを招いてしまう。

例えばECサイトでセッションハイジャックが行われてしまうと、クレジットカード情報など重要な顧客情報が盗まれてしまい、不正に買い物などが行えてしまう。
また広告システムなどのBtoBシステムでも、不正に他社アカウントを乗っ取りログインすることで数値を書き換えるなどができてしまい、大きな被害が出てしまう。

# 対策（rails）

XSSは、ユーザー入力がHTMLのタグやJavascriptとして認識されてしまうことで発生してしまうので、ここへの対策を打っていく事になる。

rails では、このユーザ入力をXSSが起こらないように出力してくれている。

```example.rb
<%= @user.name %>
```

という出力において、自動的に以下のとおりに変換してくれている。

- < を &lt;
- > を &gt;
- & を &amp;
- " を &quot;
- ' を &#39;

ただこの場所で`html.safe`というメソッドを使っていると、XSSが起きてしまう。
これは`html.safe`というメソッドが、「エスケープ処理をしない」ようにするメソッドのため。

同様に<%= raw @user.name %>も、<%== @user.name %>も、エスケープしないようになるので注意が必要。

また、ユーザ入力値を元に、そのままHTMLを組み立てたりすると、XSSが発生する可能性があるので、注意が必要。

```example.js
// Bad
document.getElementById("hoge").innerHTML = user_name
document.write(user_name)
// Safe (with jQuery)
$("$hoge").text(user_name)
```
gcloud アカウント変更

google cloud でアカウントを変更して操作する場合、下記のスクリプトで変更できる。

```:macの場合
gcloud config set account xxxxxxxxxxxxxxx@gmail.com
rm ~/.appcfg_oauth2_tokens
rm ~/.appcfg_nag
```


例えば、
```goapp deploy```

のアカウントを変更する場合とか。


# goapp deployエラー

### どこかのファイルでビルドエラーになる場合

```
Error 500: --- begin server output ---
<h3>Server Error</h3><p>A server error has occurred.</p>
--- end server output ---
error while running appcfg.py: exit status 1
```

`goapp build`ではエラーにならない場合でも、`goapp deploy`時にサーバーでエラーになる。
TrueSTUDIO


2018/1/19　TrueSTUDIO for STM32 と名前が変わったTrueSTUDIO

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/1e3ae344-a640-b4c9-3c83-88e4b885fe7d.png)

[TrueSTUDIO for STM32 9\.0\.0 released](http://blog.atollic.com/truestudio-for-stm32-9-released)

画面ちょっとしたのDownload Nowを押す
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/1e023f7f-1c7c-c88e-5ae4-0cddf7c2e850.png)

もしくは以下のページから
[Windows archive \- Atollic \- ST](https://atollic.com/resources/download/windows/windows-archive/?submissionGuid=b0d99c4a-df32-4ff3-8f79-2c5c0678989d)

Latest versionをダウンロード

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/f0b75b06-cd15-dd75-32aa-ff82d7f1ef99.png)
CoIDE






[CoIDE \- Free IDE for ARM Cortex\-M Design](http://www.coocox.org/software/coide.php)


GNU Arm Embedded Toolchain
[GNU Arm Embedded Toolchain in Launchpad](https://launchpad.net/gcc-arm-embedded/)


GCC
[GNU Arm Embedded Toolchain \| Downloads – Arm Developer](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/f2ac9d21-7372-b55c-c146-dff346be8f83.png)


Macの場合には以下のように小さなウィンドウですが勘で先へ進めます。


![image](https://qiita-image-store.s3.amazonaws.com/0/49910/78216a43-6d81-8687-9cb7-3b72aa57a529.png)

本来は以下のようなウィンドウらしいので、タブでBrowseボタンにフォーカスをあててEnterキーを押します。
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/8d325353-b0f3-d34e-a5a0-41ddd40189a1.png)

無事にフォルダーの参照画面が出ました！

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/e2730fde-6fdf-c0e0-d206-d38f95933d02.png)
Vagrant入門 Ubuntu環境作成

## はじめに
Vagrantを使ってみたメモです。
色々試したいときに自分のPCの環境を汚したくないので、仮想マシンを立てました。

## 公式のBoxからVagrantfileを作成する
ダウンロードして来て使ったりするのもあるけど基本公式の物を使えばいいらしい

以下のコマンドを実行するとvagrantfileが作成されます。
このファイルにいろいろな設定を書いていきます。

以下の vagrant ~ というコマンドもvagrantファイルが存在するディレクトリで実行する必要があります。

```bash

vagrant init bento/ubuntu-18.04
```

## Vagrantを起動する
このコマンドを実行した際に、Boxがみつからない場合は、Boxをダウンドロードしてくれる

```bash
vagrant up
```

## SSHで仮想環境に接続する

```bash
vagrant ssh
```

## 仮想マシンにログインしたら、パッケージをアップデートする

```bash
 sudo apt-get update
```

## Vagrantを停止させる

```
vagrant halt
```

## Provisioning
Vagrant up した後に自動的に実行される一連の処理
ここでrubyなどをインストールする処理を記述することで簡単に環境を構築することができる。

Provisioningを行うには以下の二つの方法がある

### 命令を一行で書きたい場合
:inline を使う

```
Config.vm.provision :shell :inline => “echo hello world”
```

仮想マシンが立ち上がった後に”echo hello world”が実行された
これは"hello world"を出力しているだけなので実用的ではないが、Provisioningについて理解するには役に立つ

### 別ファイルにコマンドを書いてそれを読み込んで実行する
以下の記述をvagrantfileに追加する

```vagrantfile

config.vm.provision :shell :path => “provision.sh”
```

```provision.sh
sudo yum -y install http
sudo service http start
sudo chkconfig httpd on
```

仮想マシンを立ち上げた状態でprovisionだけを実行するコマンド

```
vagrant provision
```

## その他のコマンド

### VM(仮想マシン)が起動しているかを確認する(Vagrantfileがあるフォルダで行う)

```
vagrant status
```
### VM(仮想マシン)の一覧を表示
こっちの方が便利

```
$ vagrant global-status 
```

### VMを一時停止させる

```
vagrant suspend
```
### suspendからの復帰

```
vagrant resume
```
### VM(仮想マシン)を破棄する

```
vagrant destroy
```

## 最後に
次は、dockerと一緒に使ったりしてみたい（よく知らんけど）
とりあえず、UbuntuのVMを構築したりしてたらわくわくしますね
Windowsで外部プログラムに任意の文字列をパラメータで渡す方法

# 概要

たとえば、Javaで外部プログラムを起動するには

```Java
ProcessBuilder processBuilder = new ProcessBuilder("MyProg.exe", "param1", "param2");
Process process = processBuilder.start();
```

とすれば Windows 以外では問題なく起動できます。 ですが、Windows の場合、パラメーターに空白が含まれていたり「"」が含まれていたりすると思ったとおりに動作しません。
この問題は、Java だけでなく C, Perl なんかでも同じです。
(Cygwin だと、そこで閉じている限り大丈夫っぽい。C# はそもそも、パラメータが１つしかない。でも、main に渡される引数は複数個なんですが...)

とりあえず、ここでは、とにかく、

* あるプログラムから、べつのプログラムにコマンドラインパラメータで文字列を渡したい
* 渡す元プログラム上の文字列と、先のプログラム上の文字列が、とにかく一致していてほしい

というケースを考えます。

# 各言語(起動する側)ごとの対処方法

## Java

```Java
public static Process runProcess(String... cmdArray) {
    ArrayList<String> cmdList = new ArrayList<String>();
    for (String cmd : cmdArray) {
      cmdList.add(transForWinCmd(cmd));
    }
    ProcessBuilder processBuilder = new ProcessBuilder(cmdList);
    return processBuilder.start();
}

private static String transForWinCmd(String arg) {
    // 末尾の \ のエスケープ (必須)
    arg = arg.replaceAll("(\\\\+)(\"|$)", "$1$1$2");
    // " を \" に変換 (必須)
    arg = arg.replaceAll("\"", "\\\\\"");
    // 対象プロセスが Java7, 8 の場合はこれも
    // (他の場合、いらないが、あっても問題はなさそう)
    arg = arg.replaceAll("(\\\\+)([?*]+)(\\\\)", "$1$1\"$2\"$3");
    arg = arg.replaceAll("(\\\\+)([?*]+)(\\\\)", "$1$1\"$2\"$3");
    // " で囲って終わり
    return "\"" + arg + "\"";
}
```

## Perl

Perl では、system 関数に、(コマンド, param1, ..., paramN) のように配列で渡せば OK という仕様だけど、Windows では完璧でないので、以下のようにする。

```Perl
use Encode;

sub systemEx {
  my @args = map {
        local $_ = $_;
        # 末尾の \ のエスケープ (必須)
        s/(\\+)("|$)/$1$1$2/g;
        # " を \" に変換 (必須)
        s/"/\\"/g;
        # 対象プロセスが Java7, 8 の場合はこれも
        s/(\\+)([?*]+)(\\)/$1$1"$2"$3/g;
        s/(\\+)([?*]+)(\\)/$1$1"$2"$3/g;
        # SJIS に変換 (日本語環境の場合はこれが必要)
        if (Encode::is_utf8($_)) { $_ = Encode::encode("MS932", $_); }
        # " で囲む
        "\"$_\"";
    } @_;
  system(@args);
}
```

# どこに問題があるのか？

OS のバグ？ のように感じますが、Windows のプロセス起動 API である CreateProcess は、プロセスおよびそのパラメータを示すものは、文字列の配列ではなく、文字列１つだけです。
Linux のように、パラメータが複数あるインターフェースはアプリケーション側ということになりますが、大抵、コンパイラー付属の標準ライブラリーをみんな使います。
ということで、問題は、標準ライブラリーにあると思われます。

Cの標準ライブラリにプロセスを起動する関数がありますが、この関数の実装が不十分なんじゃないかと思います。
(Java も Perl も、C言語で実装されているので、同じ問題が発生するということです)

ちなみに、１つのコマンドライン文字列を分離する規則は
https://msdn.microsoft.com/ja-jp/library/a1y7w461.aspx
にある通り、複雑ですが、ちゃんとした規則が公開されています。


# その他...

起動対象が Ruby の場合や mingw で作られたものの場合は、別の対処が必要です。
あと、Windows の bat プログラムに渡す場合も...
（ここで書いた対処に加え、bat独自のエスケープもあって、かなり難易度が高いです）
形態素解析：韓国語：その1：mecab-koをインストール

韓国語を形態素解析したいけど、
何がいいかなと探していたところ、mecab韓国語版を見つけました。
というのはもう2年前の話なのだが、それはさておいて。


# mecab-koとは
mecabを韓国語の形態素解析用に多少コードを改変しているようです。

Bitbucketにて公開されています。
https://bitbucket.org/eunjeon/mecab-ko/src/master/

何をどう改変したのかはコミットログを見て、、、も、私は分かりません:sweat:
（README読む限りでは、空白文字の扱いが違うっぽい）

# インストール
ひとまずMacbook Airにインストールします。
- mecab-ko本体をインストール
- 韓国語用辞書をインストール
 
## mecab-ko本体をインストール
Macであれば、homebrewであっさりインストールできます。
といってもREADMEにソースコンパイルの手順書いてるので、
Linuxへのインストールも苦ではないです。

```shell-session
$ brew install mecab-ko
==> Downloading https://bitbucket.org/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz
==> Downloading from https://bbuseruploads.s3.amazonaws.com/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz?Signature=Db
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/mecab-ko/0.996-ko-0.9.2 --sysconfdir=/usr/local/etc
==> make install
🍺  /usr/local/Cellar/mecab-ko/0.996-ko-0.9.2: 21 files, 4.3MB, built in 1 minute 15 seconds
```

## 韓国語用の辞書をインストール
mecab-ko-dicという名前で、Bitbucketで配布されています。
https://bitbucket.org/eunjeon/mecab-ko-dic/

インストール手順は2パターン記載があります。
automakeのバージョンが1.11でない場合、
autogen.shを実行する手順であればちゃんとインストールできそう。

```shell-session
$ wget https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.1.1-20180720.tar.gz
$ tar zxfv mecab-ko-dic-2.1.1-20180720.tar.gz 
$ cd mecab-ko-dic-2.1.1-20180720
$ ./autogen.sh
$ ./configure 
$ make
$ make install
```

これで下記ディレクトリに辞書がインストールされます。

```shell-session
$ ls /usr/local/lib/mecab/dic/mecab-ko-dic/
char.bin	left-id.def	model.bin	rewrite.def	sys.dic
dicrc		matrix.bin	pos-id.def	right-id.def	unk.dic
```

# mecab-koを使う
mecabコマンドで起動できます。
韓国プロ野球（KBO）のニュースの見出しを形態素解析してみます。

ニュース記事：
https://www.koreabaseball.com/News/Preview/View.aspx?bdSe=38482

記事見出し「승리 목마른 소사, 한화 상대로 9승 도전」

```shell
$ mecab
승리 목마른 소사, 한화 상대로 9승 도전
승리	NNG,행위,F,승리,*,*,*,*
목마른	VA+ETM,*,T,목마른,Inflect,VA,ETM,목마르/VA/*+ᆫ/ETM/*
소사	NNG,*,F,소사,*,*,*,*
,	SC,*,*,*,*,*,*,*
한화	NNG,*,F,한화,*,*,*,*
상대	NNG,*,F,상대,*,*,*,*
로	JKB,*,F,로,*,*,*,*
9	SN,*,*,*,*,*,*,*
승	NNBC,*,T,승,*,*,*,*
도전	NNG,*,T,도전,*,*,*,*
EOS
```

とりあえず形態素解析できましたが、、
なるほどハングル読めないからよく分からん。

（続く）
Node.js ファイルの読み込み

##　ファイルの読み込みを行う

```javascript

'use strict';
const fs = require('fs');
const readline = require('readline');
const rs = fs.ReadStream('./popu-pre.csv');
const rl = readline.createInterface({'input': rs, 'output': {} });
rl.on('line', (lineString) => {
    console.log(lineString);
});
rl.resume();
```


```javascript

Const fs = require(‘fs’);
Const deadline = require(‘deadline’);
```

Node.jsに用意されたモジュールを呼び出す
Node.jsにおけるモジュールとなるオブジェクトの呼び出し

### fs (FileSystem)
ファイルを扱うためのモジュール

### readline
ファイルを一行ずつ読み込むためのモジュール

```javascript

const rs = fs.ReadStream('./popu-pref.csv');
const rl = readline.createInterface({ 'input': rs, 'output': {} });

```

popu-pref.csvファイルからファイルの読み込みを行うStreamを作成し、さらにそれをreadlineオブジェクトのinputとして設定し、rlオブジェクトを作成している

## Stream??
Node.jsでは出入力が発生する処理をほとんどStreamという形で扱う
Streamとは、非同期情報を取り扱うための概念で、情報自体ではなく情報の流れに注目する

Node.jsでStreamを扱う際には、Streamに対してイベントを監視し、イベントが発生した際に呼び出される関数を設定することによって情報を利用する

**イベント駆動型プログラミング**
あらかじめイベントが発生した時に実行される関数を設定しておいて、起こったイベントに応じて処理を行うこと

```javascript

const rl = readline.createInterface({ 'input': rs, 'output': {} });
```

rlというオブジェクトもStreamのインターフェースを持っている

利用する際には以下のようなコードになる

```javascript

rl.on('line', (lineString) => {
    console.log(lineString);
});
rl.resume( );
```
rlオブジェクトでlineというイベントが発生したタイミングで、コンソールに引数lineStringの内容が出力される。

resumeメソッドの呼び出しはストリームに情報を流し始める処理


>オブジェクトの振る舞いを作ることのできる関数が設定されたプロパティのことをメソッドと呼ぶ

## まとめ
Streamの概念がまだよくわからない、なんとなく書いてるだけな感覚があるので詳しい人教えてください、、、

とりあえずもっとたくさん書いてみよう
Rspec changeでnilから何らかの値に変化することをテストする

テストの前後で値がnilから何らかの値に変化することを確認したい。だけど具体的な値はわからない（スタブするのも面倒）という場合には以下のように書ける。

```ruby
    describe '#set_token' do
      subject { user.set_token }

      it 'tokenに値が設定されること' do
        expect { subject }.to change(user, :token).from(nil).to(String)
      end
    end
```
続・Amazon Linux WorkSpaces US イメージでシステムの起動時に日本語入力を有効化する

前回の記事「[Amazon Linux WorkSpaces US イメージでシステムの起動時に日本語入力を有効化する](https://qiita.com/mosop/items/5cec4c64966bbd7c57ee)」では、既定でインストールされている ibus-kkc をインプットメソッドに指定しました。

残念ながら、私の環境では ibus-kkc で "・" (中点/中黒) をダイレクトに入力することができないことが分かりました。日本語の文章を書くときにこれは不便です。

kkc のシンプルな感じが気に入っていたので残念ですが、古株の ibus-mozc に乗り換えることにします。

## Mozc をビルド・インストール

手頃なパッケージがなかったので、自前でビルドしました。

Mozc のビルドには結構癖があって、詳しく説明しようとすると、それだけで 1 つの記事になりそうです。今回はインストール手順だけ書くことにします。

1. [RPM パッケージ](https://github.com/albuild/mozc/releases/download/v0.2.1/albuild-ibus-mozc-0.2.1-0.amzn2.x86_64.rpm)をダウンロード[^2]

1. パッケージをインストール

    ```
    sudo yum -y install albuild-ibus-mozc-0.2.1-0.amzn2.x86_64.rpm
    ```

## 日本語入力 (iBus) を設定する

Mozc をインストールできたので、iBus を設定していきます。

1. `~/.bashrc` に環境変数の設定を追加する

    ```
    export XMODIFIERS=”@im=ibus”
    export GTK_IM_MODULE=”ibus”
    export QT_IM_MODULE=”xim”
    ```

1. Startup Applications に iBus デーモンの起動コマンドを追加する<br/>コマンド: `ibus-daemon -drx`<br/>![ibusdaemon.png](https://qiita-image-store.s3.amazonaws.com/0/63688/e5b46676-1781-5ab7-08cb-4f19040214e9.png)

1. ログアウト & ログイン

1. ターミナルから `ibus-setup` コマンドを実行して、 iBus の Preferences を開く

1. Input Method に "Japanese - Mozc" を追加する

    ![スクリーンショット 2018-09-07 4.53.06.png](https://qiita-image-store.s3.amazonaws.com/0/63688/e66a01a7-af53-2fae-514c-748e3843b535.png)

無事に Mozc で日本語入力できるようになりました:tada:

![Slice.png](https://qiita-image-store.s3.amazonaws.com/0/63688/264e055b-a8b4-b741-07d9-b20977ae4966.png)

[^2]: バイナリをインストールするのが怖いという方はご自分でビルド可能です。詳しくは [README](https://github.com/albuild/mozc) を参照。
Amazon Linux WorkSpaces に Docker をインストールする

Amazon WorkSpaces (Amazon Linux 2) に Docker を入れたので、備忘録を残しておきます。

## インストール

```
sudo yum install -y docker
```

## ログインユーザーに Docker の使用を許可

```
sudo gpasswd -a $USER docker
```

## システム起動時に Docker を起動

```
sudo systemctl enable docker
```

## DNS を Google Public DNS に設定

既定では、WorkSpaces の DNS 設定が VPC のネットワーク上のアドレスを指しているため、 Docker コンテナ内から到達できない DNS へのリクエストが発生し、名前解決がタイムアウトします。このため、既定の DNS として Google Public DNS を手動で設定することにします。

また、外部 DNS を指定する場合、内部ホストの名前解決は意味を持たないので、ホスト名の検索を無効化します。[^1]

以下の内容のファイルを /etc/docker/daemon.json に保存します。

```:/etc/docker/daemon.json
{
  "dns": ["8.8.8.8", "8.8.4.4"],
  "dns-search": ["."]
}
```

## Docker を起動

```
sudo systemctl start docker
```

## 動作確認

ログインしなおして、動作確認をしてみます。

```
docker run --rm amazonlinux:2 curl -s https://github.com/status
```

出力:

```
GitHub lives! (2018-09-07 21:59:54 -0700) (1)
```

できました:tada:

## 参考

* [Amazon Linux2にDockerをインストールする](https://qiita.com/reoring/items/0d1f556064d363f0ccb8)

[^1]: 既定で ap-northeast-1.compute.internal (東京リージョンの場合) が検索されるよう設定されています。
VRのコンテンツ総まとめ！！

VRコンテンツをちゃんとまとめるメモ。
随時更新！

個人的メモですが、みなにも役立つものに！！
そして、もっと体験しないと。


＝＝やった＝＝
■VR　ZONE
・マリオカート
・釣り
・急流下り
・羽チャリ

■ハシラス
・ハッピーオシャレタイム
・アーバンコースター
　https://hashilus.com/content/urbancoaster/
・アーバンスタンプラリー
　https://hashilus.com/content/urbanstamprally/
・トーヤラケット
　https://twitter.com/hashilus/status/1038309089367928833

■同期作品
・アビスダイバー
・360°ワニワニパニック
・ホラー
・ルンバの中の人
・#VTuber #体験

＝＝やってみたい＝＝
■甲子園VR
http://www.koshien-rekishikan.com/event/virtual/

■VR　ZONE
https://vrzone-pic.com/shinjuku/activity/galagafever.html
高階型の型パラメータを持つDDDリポジトリをDIできるようにする

[DDDリポジトリを楽に実装するライブラリ](https://qiita.com/j5ik2o/items/5f29e2ec22a5eac2a186)で紹介した[scala-ddd-base](https://github.com/j5ik2o/scala-ddd-base)を使って実装したリポジトリを[airframe](https://wvlet.org/airframe)を使ってDIする事例を簡単に紹介します。

リポジトリの実装は前回の記事のとおりです。UserAccountRepositoryは高階型の型パラメータM[_]を必要とします。　この例では、Task[A]のタイプエイリアスとしてBySlick[A]を宣言し、ファクトリメソッドで実装を生成できるようにしています。

```scala
object UserAccountRepository {
  type BySlick[A] = Task[A]
  def bySkinny: UserAccountRepository[BySkinny] = new UserAccountRepositoryBySkinny
｝

class UserAccountRepositoryBySkinny
  extends UserAccountRepository[BySkinny]
  ... 
```

airframe　0．64から高階型でもバインディングを設定できる[^1]ので、以下のように型に対するインスタンスを指定します。

```scala
val design = newDesign.bind[UserAccountRepository[BySkinny]].toInstance(UserAccountRepository.bySkinny)
```

インスタンスを得る方法はこれまでどおり型を指定するだけです。

```scala
val resultFuture = design.withSession{ session =>
  val repository = session.build[UserAccountRepository[BySkinny]]
  (for {
    _ <- repository.store(userAccount)
    result <- repository.resolveById(userAccount.id)
  } yield result).run(AutoSession).runAsync
}
```

実際に動作するコードは[こちら](https://github.com/j5ik2o/scala-ddd-base/blob/master/example/src/test/scala/com/github/j5ik2o/dddbase/example/repository/airframe/AirframeSpec.scala)です

タイプエイリアスとか高階型を利用するなら、airframeの方が便利そうです。Tagless Finalをやる方は、まず間違いなくこの機能を使いたくなるはずです…。

[^1]: 要望を提案したら対応してもらいました！ https://github.com/wvlet/airframe/pull/244
laravelで論理削除を無効にしてloadする

laravelでloadした時に、取得する側の論理削除を無効にしてデータを取得する方法をまとめています。
laravelのバージョンは5.1です。


usersとpostsが1対Nであるとします。
usersテーブルで論理削除されていてもユーザーの情報を取得したい場合には以下のように記述します。

```php
$posts = App\Post::all();
$posts->load(['user' => function($query) {
    $query->withTrashed();
});
```

論理削除したデータも取得する場合は`withTrashed()`を使います。
loadで検索条件を追加する場合は、キーにモデル名、値はクエリインスタンスを受け取る「クロージャ」となる配列を記述し、クロージャ内に検索条件を記述します。

以下を参考にさせていただきました。
https://stackoverflow.com/questions/21995670/how-to-use-withtrashed-when-im-querying-using-eager-loading
オフラインリアルタイムどう書くE27の参考問題

オフラインでリアルタイムに「どう書く」をやるイベント : 
https://yhpg.doorkeeper.jp/events/79705
を、2018年10月6日に、神田秋葉原界隈でやります。

で。4年半ぶりに、参考問題を出しました。
「灯りと鏡」という問題で、詳細は
http://nabetani.sakura.ne.jp/hena/orde27ligmir/
です。

当日出す問題の難易度と分量はこれを目安に考えると良いと思います。

何分で解けたとかいう情報を付てくだされば、本番用の問題の参考にしたいと思います。

実装ができた方はこちらのコメント欄からリンクを張っていただくと見つけやすくて助かります。