OmniAICreator/Qiita-1.07M huggingface dataset:
複数のPDFファイルを結合する方法

たまに使うけど忘れてしまうので備忘録として。

# 基本情報

* 執筆：2018/10/01
* OS:Windows10

# tl;dr

PDFBoxをコマンドラインで利用できるツールで可能。

```
java -jar pdfbox-app-2.0.11.jar PDFMerger 結合元_1.pdf 結合元_2.pdf 結合元_3.pdf 結合結果.pdf
```

※java、jarファイル、結合元ファイルの場所によりファイルパスは適宜変更の必要があります。
※jarファイルはバージョンによりファイル名が異なるので注意してください。

# jarファイルのDL先

以下のサイトからCommand line toolsのpre-built PDFBox standalone binaryをダウンロード
https://pdfbox.apache.org/download.cgi

# 結合以外の機能

時間があったらまとめる予定。以下のページが参考になります。
https://www.itcowork.co.jp/blog/?p=3043


弊社ではエンジニアを募集中です。こちらも見て頂けると嬉しいです。
https://www.nittsu-infosys.com/recruit/2019/index.html
Nuxt.js開発環境をDockerで構築

### 実行環境
```
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14
BuildVersion:   18A391
```
```
$ docker --version
Docker version 18.06.1-ce, build e68fc7a
```
```
$ docker-compose --version
docker-compose version 1.22.0, build f46880f
```

### Dockerfile, docker-compose.yml, Makefile 作成
- https://github.com/f-sugar/nuxt-docker

``` Dockerfile:Dockerfile
FROM node:8.11.3-alpine

WORKDIR /app

RUN apk update && \
    apk add git && \
    npm install -g npm && \
    npm install -g vue-cli

ENV HOST 0.0.0.0
EXPOSE 3000
```

``` yml:docker-compose.yml
version: '3'

services:
  nuxt:
    build: .
    tty: true
    command: yarn dev
    volumes:
      - .:/app
    ports:
      - "3000:3000"
```

``` Makefile:Makefile
.PHONY: build install sh run down

build:
	docker-compose build

install:
	docker-compose run --rm nuxt yarn

sh:
	docker-compose run --rm nuxt sh

run:
	docker-compose up

down:
	docker-compose down
```

### ビルド
```
$ make build
```

### アプリケーション作成
```
$ docker-compose run --rm nuxt npx create-nuxt-app
```

### 実行
```
$ make run
```
gitのエイリアスを作るときに使ったtips - mac

gitでよく使うコマンドをエイリアスにしたかったので、その時に、色々方法があるんだろうけど自分流で、他のは調べずにw 作ってみました。シェルスクリプトで。条件は、引数が使えること。ちなみに私の環境はmacです。unixのコマンドを使っていきます。

まずはbash_profileにエイリアスを書いていきます。

```
vi ~/.bash_profile

```

例えば下記のようにエイリアスを書いたとします

```
function tes(){
git add . -A
git commit -m "commmon commit"
git push $1 $2
}
```

んで、ファイルを更新

```
source ~/.bash_profile
```

んで、下記のようにコマンドを打つと、`git push origin master`で、やってくれます。

```
$ tes origin master
```

シェルスクリプトは引数名を作れないので$1 $2とかのようになってしまいます。
termextractからsudachiのユーザ辞書を作ってみた


こちらの記事のsudachi版です。
[termextractを使って保持データから専門用語を抽出しmecabのユーザ辞書を作成する][1]
[1]:https://qiita.com/ldap2017/items/88fc6a48793c135c314e


```環境
macOS High Sierra 10.13
Python 3.6.5
mecab of 0.996
sudachi-0.1.1-SNAPSHOT
```


#手順
手順１と２は上記の記事を見てください。
[手順３.sudachi形式のユーザ辞書を作成](#3sudachi形式のユーザ辞書を作成)
[手順４.バイナリ辞書の作成](#4バイナリ辞書の作成)
[手順５.設定ファイルの修正](#5設定ファイルの修正)
[手順６.テスト](#6テスト)


#3.sudachi形式のユーザ辞書を作成
mecab形式で作ったテキストファイルから複合語のユーザ辞書を作成します。


````termextract.py
#sudachiのユーザ辞書の作成
import termextract.mecab
import termextract.core
import collections


# ファイルを読み込む
input_text = open("input_mecab.txt", "r", encoding="utf-8").read()

#アウトプットするファイルを指定
f = open("sudachi_dic.csv", mode='w')

#bag-of-wordsする
frequency = termextract.mecab.cmp_noun_dict(input_text)
#LR(単名詞の左右の連接情報)を生成
LR = termextract.core.score_lr(frequency,
         ignore_words=termextract.mecab.IGNORE_WORDS,
         lr_mode=1, average_rate=1
     )
#重要度が高い順に並べ替えて出力
term_imp = termextract.core.term_importance(frequency, LR)

data_collection = collections.Counter(term_imp)

for cmp_noun, value in data_collection.most_common():
    dic_noun = termextract.core.modify_agglutinative_lang(cmp_noun)
    line = u"%s,5146,5146,8000,%s,名詞,普通名詞,一般,*,*,*,,%s,*,*,*,*,*" % (dic_noun,dic_noun,dic_noun)
    #公式に名詞類の登録であれば、"5000 ～ 9000" を推奨とありましたので8000としました
    f.write(line + "\n")
    
f.close()
````

#4.バイナリ辞書の作成
作成した辞書をバイナリ化します。targetディレクトリ内にある`target/sudachi-XX.jar`を使って変換できます。

````ターミナル
$java -cp Sudachi/target/sudachi-0.1.1-SNAPSHOT.jar \
com.worksap.nlp.sudachi.dictionary.UserDictionaryBuilder \
system_core.dic \ #Sudachi のシステム辞書
./sudachi_dic.csv \ #ユーザ辞書ソースファイル名
./sudachi_user.dic #出力するバイナリ辞書ファイル名
````


#5.設定ファイルの修正
同じくtarget内にある`sudachi.json`を修正してユーザ辞書を利用可能にします。なお、ユーザ辞書は複数利用することも可能らしいです。複数利用したい場合はリスト形式でカンマ区切りで記述します。

````sudachi.json
{
    "systemDict" : "system_core.dic",
    "userDict" : ["sudachi_user.dic"], ←ユーザ辞書を追加
    "inputTextPlugin" : [
        { "class" : "com.worksap.nlp.sudachi.DefaultInputTextPlugin" },
        { "class" : "com.worksap.nlp.sudachi.ProlongedSoundMarkInputTextPlugin",
          "prolongedSoundMarks": ["ー", "-", "⁓", "〜", "〰"],
          "replacementSymbol": "ー"}
    ],
    ....
````

#6.テスト
ユーザ辞書は実行時にjsonファイルを指定して実行することで利用できます。

````ターミナル
java -jar sudachi-0.1.1-SNAPSHOT.jar -r sudachi.json 
````

#おわりに
本当はユーザ辞書を作ってSudachiのPython版SudachiPyで利用したかったのですが、まだSudachiPyはユーザ辞書に対応していないようでした。。残念。。（2018.10.01現在）


###参考サイト
https://github.com/WorksApplications/Sudachi/blob/develop/docs/user_dict.md
【jQuery】指定したid属性の要素へHTMLタグを追加する


# タグを追加する

```.js
$('#idとか').append('HTMLタグ');
```

# 実装例
ここでは例として画像タグをjqueryで追加します。

```js
$('#img_div').append('<img id="img" src="https://*********.jpg">');
```

上記を実行すると

```html
<div id="img_div"></div>
```

↓

```html
<div id="img_div"><img id="img" src="https://*********.jpg"></div>
```

id `img_div` にimgタグが追加される
DSP/RTB/SSPについて

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/19729221-05f3-fb01-3311-f77b89616b2c.png)


DSP/RTBオーディエンスターゲティング入門を読んだまとめ。
DSP/RTBだけといわず広告システムについて体系的に記されていたので小分け。
DSP、SSP、RTBについて。

##総論
「枠」から「人」への大きなパラダイムシフトを理解する

## DSPとは
- デマンドサイドプラットフォーム
- 広告主が、メディア枠を買うための機構
- 広告主が、対象の**オーディエンス**や**メディア枠のジャンル**、**配信時間**などを元に希望に近い**メディア枠**を**入札**する

## SSPとは
- サプライサイドプラットフォーム
- メディアが、メディア枠に表示する広告主からのクリエイティブを**選定**するための機構
- メディアが、複数広告主からの対象メディア枠の入札と、メディアへ来訪したユーザー情報やメディア枠の情報などを分析して**クリエイティブ**を**入札**(**応札**)する

どちらも選定、入札自体はシステムが自動で行う
人間は手持ちのクリエイティブまたはメディア枠の配信設定をするだけ。

##RTBとは
- リアルタイムビッティング
- 広告主がDSPによって入札したメディア枠の入札状況と、メディアがSSPによって入札したクリエイティブの入札状況を瞬時に判断し、落札させる機構
- 落札で決まるのは1配信(以降**インプレッション**と呼ぶ)でクリエイティブの表示1000回当たりの料金(**インプレッション単価**またの名を**CPM**)


一瞬で決まるオークション、または上場株の取引のようなイメージ
RTBは競売人

##1インプレッション決定時のフロー
1. ユーザーがメディア枠の存在するメディアへアクセスする
2. メディア枠を読み込みSSPに広告リクエスト(ユーザー情報)が飛ぶ
3. SSPから複数のDSPにリクエストが飛ぶ(以降**ビットリクエスト**と呼ぶ)
4. 複数のDSPがビットリクエストを分析し、メディア枠の入札する金額を決定する(以降**ビットレスポンス**と呼ぶ)
5. SSPがビットレスポンスを分析し、いずれかのクリエイティブを入札する
6. RTBがそれぞれの入札状況を判断し落札する
7. 落札結果をSSPが受け取り、メディアに落札結果の広告配信タグを返す
8. 広告配信タグがDSPからクリエイティブを取得してメディアにHTMLコードを配信する
9. HTMLコードを元に画像サーバーにリクエストが飛ぶ
10. 広告画像を返し、メディアに広告が表示される

### ビットリクエストに含まれるもの
- ユーザーID(クッキー)
- IPアドレス
- ブラウザ・OS情報
- クリエイティブの掲載先(メディア)ドメイン
- メディア枠ページのあるカテゴリ(コンテンツカテゴリ)
- 広告枠ID
- 広告サイズ
- 広告主の情報(業種など)

### ビットレスポンスに含まれるもの
- 入札金額
- クリエイティブの広告タグ
- 落札後の通知URL

このようにシステムが分析できるようになる事で、人力でメディアがメディア枠に合うクリエイティブを求めて営業するのと比べて、最適化されたオーディエンスが介在するようになるので、「枠」の限界を超え(精度・コスト・量が比にならない)「人」への配信が成立していく。

また、広告主は売買部分がシステム化されたことで、どのような広告を出すべきかに集中することができる。ここで広告運用の仕方が重要になってくる。
効果の高い運用をするには適切な運用指針を設定する必要があり、変化に応じた適切な運用指針を設定するには運用後のデータを適切に活用する必要がある。

ここでDMPが重要になってくる
[DMP入門まとめ](https://qiita.com/dich1/items/f25bac558f5c2340a98d)

一方、RTBの機能によって、クリエイティブやメディア枠の価値も明確になり、その明確さを活用して更に無駄のない配分を行おうとする。その際に登場してくる機構がアドエクスチェンジになる。
[Ad Exchange/Data Exchangeについて](https://qiita.com/dich1/items/a684e0304ed6c69a700e)

## 書籍情報
横山 隆治, 菅原 健一, 楳田 良輝　DSP/RTBオーディエンスターゲティング入門
https://amzn.to/2xUJEQ5

## 雑感
SSP入門はないのか。タイトル的に揃っていない感が気になる
nycのカバレッジにwebpackでビルドしたソースが含まれるのを阻止する

# 概要
自分のライブラリのカバレッジがとても低く、何故なんだろうと思っていて調べたのですが、webpack側で作ったソースが含まれていたのが原因でした。
今回はその対応するために結構苦労したのでメモしておきます。

## webpackのソースが含まれている時のカバレッジ(間違い)
<img width="567" alt="スクリーンショット 2018-10-01 17.33.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/264910/5cdeb93f-f6d8-8dcf-6086-9f94a9ff0092.png">

## 自分のソースのみのカバレッジ(正しい)
<img width="474" alt="スクリーンショット 2018-10-01 17.34.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/264910/dd8f0c74-7b9c-1b9f-8020-ee13fb5d4cfe.png">


# webpackでソースマップの出力をする

`devtool: 'inline-source-map'`って所です。この設定を有効化することによってビルドファイルの中にソースマップを含めることができます。
この設定をしないとnyc側で元のソースを辿って正しいカバレッジを取得することができません。注意しましょう。

```javascript
var nodeExternals = require('webpack-node-externals');

module.exports = {
  mode: 'development',
  externals: [nodeExternals()],
  target: 'node',
  devtool: 'inline-source-map',
  entry: './src/main.js',
  output: {
    library: 'nomlish',
    libraryTarget: 'umd'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-env',
              ]
            }
          }
        ]
      }
    ]
  }
};

```

# nycでビルド先ファイルを除外する
[公式ドキュメント](https://www.npmjs.com/package/nyc#excluding-files)
package.jsonにnycの設定を記述し、ビルドファイルのカバレッジを計測しないようにします。ビルドファイルのパスを記述します。
私のソースの場合src/main.jsが自分で書いたソースなのでそれ以外は見る必要がありません。

```javascript
  "nyc": {
    "exclude":["dist"]
  },
```
↓の画像ではwebpack→bootstrap、webpack→universalModuleDefinitionがカバレッジに含まれていますがこのソースがdist配下に存在するからですね。
<img width="567" alt="スクリーンショット 2018-10-01 17.33.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/264910/5cdeb93f-f6d8-8dcf-6086-9f94a9ff0092.png">

# あとがき
[ava公式のカバレッジ取得についての記述](https://github.com/avajs/ava-docs/blob/master/ja_JP/docs/recipes/code-coverage.md#es2015%E3%81%AE%E3%82%AB%E3%83%90%E3%83%AC%E3%83%83%E3%82%B8)
[nyc公式のカバレッジ取得についての記述](https://github.com/istanbuljs/nyc#source-map-support-for-pre-instrumented-codebases)
テストにはavaを使用していたのですが、どちらの公式ドキュメントにもwebpackとの併用ケースがなくこの対応だけにかなり苦労しました。
特殊なケースなのかもしれませんがやはりググっても記事は少なく、こういう時に公式ドキュメントから紐解いて問題を解決する能力が必要なんだなと実感しました。
GR-LYCHEEを組み立てよう

GR-LYCHEEは買ったままでも使用可能ですが、コネクタを半田付けすることで拡張が可能です。
主にはArduinoコネクタと、USBホストです。

今回は、サーボコネクタと、Segger　J-Linkのコネクタも取り付けます。

はじめに1.27mm　2x5　10Pinのコネクタを半田付けします。
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/48cbfde4-219d-3d87-decc-22aed9a12a59.jpeg)

背面に飛び出しすぎると、カメラのフラットケーブルを傷つけます。
(傷つけました）
半田付け後は、カプトンテープなりで保護すべきです。
DAPLinkがあるので、binファイルをアップロードすることでこのコネクタは半田付けしないでもOKです。
DAPLinkはLPC11U35FHI33により、binファイルをドライブにコピーペーストすることでファームを書き込めます。
e2Studioから直接書き込みたい場合は、このコネクタを半田付けし、Seggerを使用してファームを書き込むことになります。

J-LINK EDU MINI DigiKey 2,413円です。
https://www.digikey.jp/product-detail/ja/segger-microcontroller-systems/8.08.91-J-LINK-EDU-MINI/899-1061-ND/7387472

これは使えるか不明
LPC-Link2　秋月電子　2,800円です。（CMSIS-DAP）
http://akizukidenshi.com/catalog/g/gM-06706/

次にサーボ用のコネクタを半田付けします。
2.54mm　６Pinです。
秋月等で1本　35円です。
ピンヘッダ　１×４０　（４０Ｐ）
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/47cd1fa0-fa3b-66ac-3ba5-cc835597a101.jpeg)

次に、付属のソケットを半田付けします。
![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/eef7c024-633a-e442-80d5-3a3c68de5983.jpeg)

最後にUSBコネクタを半田付けします。
![Last.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/772c3c4b-5a13-2968-1863-fcb1656fbdf8.jpeg)
background-imageはanimationやtransitionで動かせない

CSSの`background-image`プロパティはanimationやtransitionを使って動かせません。

- [3.3. Image Sources: the background-image property | CSS Backgrounds and Borders Module Level 3 - W3C Candidate Recommendation, 17 October 2017](https://www.w3.org/TR/css-backgrounds-3/#the-background-image)
- [background-imageはアニメーション出来ない(問題と解決のコード付き)
](https://qiita.com/kubosho_/items/2b0486a0712e9b546614)
- [background-imageをtransitionさせる](https://www.blackmage.site/web/background-image-transition)

しかし、アニメーションで動かせないと聞くとかえって動かしたくなりませんか？特にホバーするとふわりとグラデーションするボタンとか作りたくないですか？（謎の圧）

まずはこちらをご覧ください。
<p data-height="265" data-theme-id="0" data-slug-hash="XxbRLL" data-default-tab="css,result" data-user="h_kudo" data-pen-title="Button with Gradient Effect" class="codepen">See the Pen <a href="https://codepen.io/h_kudo/pen/XxbRLL/">Button with Gradient Effect</a> by Hibiki Kudo (<a href="https://codepen.io/h_kudo">@h_kudo</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
ホバーすると背景がグラデーションするものの、仕様通り`transition-duration`プロパティが無視されアニメーション効果がついてくれません。

そこで`opacity`プロパティと擬似要素を使ってふわりと背景が遷移するアニメーションを表現します。
<p data-height="265" data-theme-id="0" data-slug-hash="ZqGKEr" data-default-tab="css,result" data-user="h_kudo" data-pen-title="Button with Animated Gradient Effect" class="codepen">See the Pen <a href="https://codepen.io/h_kudo/pen/ZqGKEr/">Button with Animated Gradient Effect</a> by Hibiki Kudo (<a href="https://codepen.io/h_kudo">@h_kudo</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
コードはこちら

```html:button.html
<button type="button" class="button"><span class="button__inner">Hover me</span></button>
```
```css:style.css
.button {
  position: relative;
  display: inline-block;
  overflow: hidden;
  width: auto;
  min-width: 120px;
  height: 50px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background-color: #da0641;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.2);
}
.button::after {
  position: absolute;
  z-index: 0;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  content: "";
  transition-duration: .3s;
  opacity: 0;
  background-image: linear-gradient(135deg, #f2d50f 0%, #da0641 100%);
}
.button:hover {
  cursor: pointer;
}
.button:hover::after {
  opacity: 1;
}
.button__inner {
  font-size: 20px;
  position: relative;
  z-index: 2;
  display: flex;
  min-width: 120px;
  height: 100%;
  padding: 0 15px;
  text-decoration: none;
  color: #fff;
  justify-content: center;
  align-items: center;
}
```
この小技で少し遊び心を感じるふわっとグラデーションするボタンが実装できました。
ThinkPad X230にUbuntu 18.04.1 LTS (Bionic Beaver)をインストールする

X230、いいですよね。最新のUbuntuであるUbuntu 18.04.1 LTS (Bionic Beaver)でもサクサク動きます。
![x230.jpg](https://qiita-image-store.s3.amazonaws.com/0/68213/5c0ca58a-8158-8bba-0ead-e261c181032e.jpeg)

## インストール
https://askubuntu.com/questions/789998/16-04-new-installation-gives-grub-efi-amd64-signed-failed-installation-target
この記事の通り、通常のインストール用パーティションに加え200MBのパーティションを作成しFAT32でフォーマットし、 `/boot/efi` にマウントします。

## Boot repair
しかし、これだけだと起動時にF12を押して出てくるboot menuからubuntuを選んでも起動しません。そこで、インストールに使ったUSBメモリを挿してF12を押しながら起動してUSBメモリを選び、Try UbuntuからUbuntuを起動します。
そしてネットに接続後、Terminalを起動、

```
sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair && boot-repair
```
を実行し、 `Recommended repair` を押します。あとは指示に従ってください。
https://help.ubuntu.com/community/Boot-Repair

## GRUB（Bootメニュー）が出てこなかったらこれも試してみてください
https://itsfoss.com/no-grub-windows-linux/
Gradleの同期でgradle project sync failed. basic functionality will not work properlyエラー

【原因】
JDKのバージョンが古い。

【対応】
以下のサイトを参考に最新のJDKをインストールしたパスをAndroid Studioに指定する。
https://www.thehackeruniversity.com/2018/01/20/fix-gradle-sync-failed-error-android-studio/
pandas で html の table の読み書き

html ファイルの作成

```py:html_create.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	html_create.py
#
#					Oct/01/2018
# ------------------------------------------------------------------
import sys
import pandas as pd
#
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
df = pd.DataFrame([
		["t1271","千葉",93416,"2003-11-5"],
		["t1272","勝浦",47573,"2003-6-14"],
		["t1273","市原",28451,"2003-9-25"],
		["t1274","流山",39842,"2003-8-28"],
		["t1275","八千代",27896,"2003-8-8"],
		["t1276","我孫子",13175,"2003-1-15"],
		["t1277","鴨川",85234,"2003-10-21"]])

print(df)
#
path="./cities.html"
#
df.to_html(path,header=None,index=None)
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

html ファイルの読み込み

```py:html_read.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	html_read.py
#
#					Oct/01/2018
# ------------------------------------------------------------------
import sys
import pandas as pd
#
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_html = "./cities.html"
#
df=pd.read_html(file_html,header=None,encoding='utf8')
print(df[0])
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

html ファイル

```html:cities.html
<table border="1" class="dataframe">
  <tbody>
    <tr>
      <td>t1271</td>
      <td>千葉</td>
      <td>93416</td>
      <td>2003-11-5</td>
    </tr>
    <tr>
      <td>t1272</td>
      <td>勝浦</td>
      <td>47573</td>
      <td>2003-6-14</td>
    </tr>
    <tr>
      <td>t1273</td>
      <td>市原</td>
      <td>28451</td>
      <td>2003-9-25</td>
    </tr>
    <tr>
      <td>t1274</td>
      <td>流山</td>
      <td>39842</td>
      <td>2003-8-28</td>
    </tr>
    <tr>
      <td>t1275</td>
      <td>八千代</td>
      <td>27896</td>
      <td>2003-8-8</td>
    </tr>
    <tr>
      <td>t1276</td>
      <td>我孫子</td>
      <td>13175</td>
      <td>2003-1-15</td>
    </tr>
    <tr>
      <td>t1277</td>
      <td>鴨川</td>
      <td>85234</td>
      <td>2003-10-21</td>
    </tr>
  </tbody>
</table>
```
XVim2をXCodeのバージョン毎に導入する

# 利用するXcodeを確認、指定する
```
xcode-select -p

//過去バージョンに入れる場合 9.2を利用する
sudo xcode-select -s /Applications/Xcode9.2.app/Contents/Developer
```

# Xvim2をインストールする

```
git clone https://github.com/XVimProject/XVim2.git
cd XVim2
make

//update_xcode_pluginsをインストールしていない場合インストール
sudo gem install update_xcode_plugins

update_xcode_plugins --unsign
```

# 動作しない場合
```

cd ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/
ls
//過去のXVimを一度削除し、改めてmakeすると動いた
rm -rf XVim2.xcplugin
```
トランザクション分離レベルまとめ

# トランザクションの分離
DBMSは個々のトランザクションついて分離性を維持する制御を行う。

## SQLの同時実行の、副作用
DBMSにおいて、同時処理を行うことで発生する副作用として、
代表的なものに以下の3つがある。

### 1.ダーティーリード
コミットされていない未確定の変更を、読み込めてしまう副作用のことを、`ダーティーリード`と呼ぶ。こうして読み取ってしまった未確定の情報をもとにして、別の処理を行ってしまうため、非常に危険。

### 2.反復不能読み取り
SELECT文の実行後、データの更新(UPDATE)が行われると、次回SELECTした際にクエリ実行結果が異なってしまう副作用。データ整合性が崩れる原因となる。

### 3.ファントムリード
2回のSELECT文の間に、INSERT文で行を追加されると、2回の検索結果が変わってしまうという副作用。
1回目の検索結果の行数に依存するような処理を行う場合、問題となることがある。

## トランザクションの分離
上記3つの副作用は、トランザクションによって解決することが可能。
DBMSは個々のトランザクションついて分離性を維持する制御を行うため、内部で`ロック(lock)`と呼ばれる仕組みを使う。
自分のトランザクションがコミットまたはロールバックで終了すると、ロックが解除され、他の人のトランザクションがその行を読み書き可能になる。

## 分離レベル
一般的なトランザクション分離レベル
(下に行くほど処理速度は高速だが、危険度は高い。)

|分離レベル|ダーティーリード|反復不能読み取り|ファントムリード|
|--------|-----------|-------------|----------|
|READ UNCOMMITTED|恐れあり|恐れあり|恐れあり|
|READ COMMITTED|発生しない|恐れあり|恐れあり|
|REPEATABLE READ|発生しない|発生しない|恐れあり|
|SERIALIZABLE|発生しない|発生しない|発生しない|


## トランザクション分離レベルの指定
```SQL
SET TRANSACTION ISOLATION LEVEL 分離レベル名
SET CURRENT ISOLATION 分離レベル名
```

## 参考
参考図書 : [スッキリわかるSQL入門](http://amzn.asia/d/diFEu7A)
CLI プログラム引数の ~ の扱い

CLI プログラムに `~` を引数として渡すと、何もせずとも受け取ったプログラムでホームディレクトリのパス（`$HOME` 相当）に展開されます。この仕様を知らなくてハマりました。

### 再現手順

以下のプログラムをコンパイルします。

```tilda.c
#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("%s\n", argv[1]);
    return 0;
}
```

以下のようにコンパイルします。

```shell-session
$ clan tilda.c
```

以下のように実行します。

```shell-session
$ ./a.out ~
/Users/ogata
```

引数を `~` ではなく `"~"` または `'~'` にすることでホームディレクトリに展開されなくなります。

```shell-session
$ ./a.out "~"
~
```

### 再現環境

少なくとも以下の環境で同じ動作になります。

- macOS 10.13.6
- Ubuntu 18.04
- FreeBSD 9.1-RELEASE-p24

### 補足

これは C 言語に限った話ではありません。例えば以下の Haskell でも同様の動作になります。

```tilda.hs
import System.Environment

main = getArgs >>= putStrLn . head
```

Python でも同様です。

```tilda.py
#!/usr/bin/python

import sys

print sys.argv[1]
```

Ruby でも同様です。

```tilda.rb
#!/usr/bin/ruby

puts ARGV[0]
```

Perl でも同様です。

```tilda.pl
#!/usr/bin/perl

print $ARGV[0];
```

プログラム言語や OS というよりは、シェル（本環境では bash）の「チルダ展開」の仕様のようです。シェルの展開に関しては[シェルの展開順序に気をつけよう - Qiita](https://qiita.com/emasaka/items/a59335c74220b3641639) が詳しいです。
Deep learning env.

##Anaconda
[download](https://www.anaconda.com/download/#linux)

`bash Anaconda3-5.2.0-Linux-x86_64.sh`

[reference](https://pythondatascience.plavox.info/python%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/anaconda-ubuntu-linux)

[How to use VScode](https://beachside.hatenablog.com/entry/2017/12/25/000000)

##Pytorch
[reference](https://pytorch.org/get-started/locally/)
`conda install pytorch torchvision cuda92 -c pytorch`
iOSスクショ検出

下記リンクを参考にしたがビルドが通らなかったので修正したものがこれ


```swift4:ViewController.swift

override func viewDidLoad() {
    super.viewDidLoad()
....
NotificationCenter.default.addObserver(
self, 
selector : #selector(userDidTakeScreenshot), 
name: UIApplication.userDidTakeScreenshotNotification, 
object: nil
)
....
}

@objc func userDidTakeScreenshot(notification : Notification) {
        // 何かする
        print("no screenshot")
}`
CUDA on Ubuntu 16.04

#CUDA 10.0

[Download (deb)](https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1604&target_type=deblocal)

`sudo dpkg -i cuda-repo-ubuntu1604-10-0-local-10.0.130-410.48_1.0-1_amd64.deb`
`sudo apt-key add /var/cuda-repo-10-0-local-10.0.130-410.48/7fa2af80.pub`
`sudo apt-get update`
`sudo apt-get install cuda`

###cuDNN 7.3.1 cuda10
[official](https://developer.nvidia.com/cudnn)
[wget](https://qiita.com/yukoba/items/3692f1cb677b2383c983)
`tar xzf cudnn-10.0-linux-x64-v7.3.1.20.tgz`
`sudo cp -a cuda/lib64/* /usr/local/lib/`
`sudo cp -a cuda/include/* /usr/local/include/`
`sudo ldconfig`



#CUDA 9.2

##driver 
`sudo add-apt-repository ppa:graphics-drivers/ppa`
`sudo apt-get update`
`sudo apt-get install nvidia-396 nvidia-modprobe`


[reference](https://medium.com/@zhanwenchen/install-cuda-9-2-and-cudnn-7-1-for-tensorflow-pytorch-gpu-on-ubuntu-16-04-1822ab4b2421)

##CUDA9.2
[Download](https://developer.nvidia.com/cuda-92-download-archive)
`sudo dpkg -i cuda-repo-ubuntu1604-9-2-local_9.2.148-1_amd64.deb`
`sudo apt-key add /var/cuda-repo-9-2-local/7fa2af80.pub`
`sudo apt-get update`
`sudo apt-get install cuda`


###cuDNN 7.3.1 cuda9.2
[official](https://developer.nvidia.com/cudnn)
[wget](https://qiita.com/yukoba/items/3692f1cb677b2383c983)
`tar xzf cudnn-9.2-linux-x64-v7.3.1.20.tgz`
`sudo cp -a cuda/lib64/* /usr/local/lib/`
`sudo cp -a cuda/include/* /usr/local/include/`
`sudo ldconfig`


---

###nvidia driver 410 -cuda9.2
`sudo apt remove nvidia-*`
`sudo apt update`
`sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub`
`sudo bash -c 'echo "deb
http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 /" > /etc/apt/sources.list.d/cuda.list'`
`sudo apt update`
`sudo apt install nvidia-410`
[reference](https://askubuntu.com/questions/1077061/how-do-i-install-nvidia-and-cuda-drivers-into-ubuntu)
Ubuntu 16.04 setup


#nvidia driver 375
`sudo apt-get install nvidia-375`
`sudo service lightdm restart`
[reference](https://qiita.com/Reizouko/items/c5826dbcc113321fbbcd)



##日本語入力
- 不完全な〜〜〜のダイアログが表示されるのでインストール
- 設定->テキスト入力-> 次のソースへ切り替え
　半角全角キーを押す
- 設定->言語サポート
　すべて適用

##デュアルブート　-grub
`sudo fdisk -l`
`sudo blkid /dev/sda`
/dev/sda: PTUUID="dff0173d" PTTYPE="dos"
`sudo gedit /etc/grub.d/40_custom`

以下、記載して保存

```
menuentry “Microsoft Windows 10” {
search –fs-uuid –no-floppy –set=root dff0173d
chainloader (${root})/efi/Microsoft/Boot/bootmgfw.efi
}
```

`sudo update-grub`
[reference](https://qiita.com/pg_pyro/items/3f928ec04c192884c0ed)
gcloudで特定のGCEインスタンスの外部IPを確認する

# はじめに
とあるスクリプトで、 `curl inet-ip.info` を実行してGCE インスタンスの
外部 IP を取得していたのですが、9月の末頃 inet-ip.info がダウンしていたようで…

IP 取得できずバッチが失敗する状態が数日続きました。
※ 10/1 に確認した際は復旧してました

そこで、外部のサービスに頼らず `gcloud` コマンドで外部IPの
取得をしてみようと思った次第です。


# gcloud での外部IP取得方法
最初はこんなのを考えました。長い…

```bash

gcloud compute instances list --filter="name='インスタンス名'" --format json | jq -r '.[].networkInterfaces[].accessConfigs[].natIP'
```

でも `jq` なくても出来るはずだよね？と思ってもう少し調べた所 
下のコマンドで取れました。やっぱり長い…つーか、jsonパース方法変わっただけやん。

```bash

gcloud compute instances list --filter="name='インスタンス名'" --format="value(networkInterfaces[].accessConfigs[0].natIP)"
```

# 終わりに
IP調べるのに結構長いコマンドが必要なんですね。
フィルター芸を覚えればもっといろいろな情報引き出せそう。

# 20190904追記
ちょっとフィルターやってみました。
Dataprocのノード情報を取得してテーブル表示する、的な。

```bash:実行コマンド

gcloud dataproc clusters describe クラスタ名 \
    --region=リージョン \
    --format="multi( \
        config:format='table[box]( \
            softwareConfig.imageVersion, \
            gceClusterConfig.zoneUri.basename() \
            )', \
        config:format='table[box]( \
            masterConfig.numInstances:label=NUM_MASTER, \
            masterConfig.machineTypeUri.basename():label=MASTER_TYPE, \
            workerConfig.numInstances:label=NUM_WOKER, \
            workerConfig.machineTypeUri.basename():label=WOKER_TYPE \
            )', \
        config:format='table[box]( \
            secondaryWorkerConfig.numInstances:label=NUM_PREEMPT, \
            secondaryWorkerConfig.machineTypeUri.basename():label=PREEMPT_TYPE \
            )' \
        )"
```
```terminal:出力
+---------------+-------------------+
| IMAGE_VERSION |      ZONE_URI     |
+---------------+-------------------+
| 1.3.16-deb9   | asia-northeast1-c |
+---------------+-------------------+
+------------+---------------+-----------+---------------+
| NUM_MASTER |  MASTER_TYPE  | NUM_WOKER |   WOKER_TYPE  |
+------------+---------------+-----------+---------------+
| 1          | n1-standard-4 | 3         | n1-standard-4 |
+------------+---------------+-----------+---------------+
+-------------+--------------+
| NUM_PREEMPT | PREEMPT_TYPE |
+-------------+--------------+
|             |              |
+-------------+--------------+
```

参考にしたもの
https://cloud.google.com/sdk/gcloud/reference/topic/formats
https://cloud.google.com/blog/products/gcp/filtering-and-formatting-fun-with
https://cloudplatform-jp.googleblog.com/2016/06/gcloud.html
JavaScriptのコールバックがわからなすぎるので理解する

#コールバックとはなんぞや

##コールバックパターン
* プログラミング技法
* 呼んでほしい関数やオブジェクトをわたしておき、必要に応じてそれらを呼んでもらう技法
* 呼ぶ側と呼ばれる側の依存性が反転する：依存性の反転
    * いつもの依存性：（呼ぶ側）関数実行 -> （呼ばれる側）イベント発生
    * 依存性反転：（呼ぶ側）イベント発生 -> （呼ばれる側）関数呼び出し
* 歴史的にJavaScriptでは多用される
    * クライアントサイドJavaScriptは基本的にGUIだから
        * GUIはイベントドリブンと相性が良い
        * イベントドリブンはまさにコールバックパターンであるから
    * クライアントサイドJavaScriptはマルチスレッドができないから
        * コールバックと非同期処理を組み合わせると並列処理を実現できる
    * JavaScriptに **関数宣言式** と**クロージャ**があるから
* どんな言語でもある

# JavaScriptとコールバック

##関数オブジェクトを渡す

```js
function func0() {
	var x = Math.ceil(Math.random()*2);
	if (x==1) {
		func1(func2);
	} else {
		func1(func3);
	}
}

function func1(callback) {
	console.log('計算終了です.');
	callback();
}

function func2(){
	console.log('Aです');
}

function func3(){
	console.log('Bです');
}

func0();
```

##引数を渡す

###方法1 関数と引数をわたす
```js
function func1(f, arg1){
	console.log('func1');
	f(arg1);
	console.log('完了')
}

function func2(x){
	console.log(x);
}

func1(func2, 'ほげ');
```

###方法2 引数をとる関数を渡す
```js
function func1(f){
	console.log('func1');
	f();
	console.log('完了')
}

function func2(arg1){
	return function() {
		console.log(arg1);
	}
}

func1(func2('ほげ'));
```

###無名関数を渡す
```js
function func1(f) {
  console.log('func1');
  f();
  console.log('完了')
}

func1(function () {
  console.log('ほげ');
});
```

##非同期処理
###とれない
```js
function func1() {
  console.log('func1')
  setTimeout(function () {
    return 'Hello!!';
  }, 1000);
}

var value = func1();
console.log(value);
console.log('完了')
```

###こうする
```js
function func1(callback) {
  console.log('func1')
  setTimeout(function () {
      callback('Hello!!');
      console.log('完了');
    },3000);  
}

func1(
  function (arg1) {
    console.log(arg1);
  }
);
```

###Ajaxなんかで取得するとき
```js
function func1(callback) {
  console.log('func1')
  $.ajax('/path/to/api')
    .done(function (data) {
      callback(data);
      console.log('完了');
    });
}

func1(function (data) {
  console.log(data);
});
```

#参考にしたURL
https://beginners-hp.com/javascript/callback.html
http://d.hatena.ne.jp/kitokitoki/20121125/p1
https://qiita.com/htanjo/items/360144cab96943050ab2
pandas で PostgreSQL の読み書き

## Arch Linux で必要なライブラリーのインストール

```bash
sudo pacman -S python-sqlalchemy
```

## データベースの作成

```py:postgre_create.py
#! /usr/bin/python
#
#	postgre_create.py
#
#					Mar/05/2023
# ------------------------------------------------------------------
import sys
import pandas as pd
#
from sqlalchemy import create_engine
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
df = pd.DataFrame([
		["t1271","千葉",58471,"2003-9-25"],
		["t1272","勝浦",49523,"2003-3-16"],
		["t1273","市原",27461,"2003-6-21"],
		["t1274","流山",39872,"2003-8-27"],
		["t1275","八千代",21576,"2003-11-5"],
		["t1276","我孫子",53271,"2003-1-12"],
		["t1277","鴨川",81326,"2003-5-22"],
		["t1278","銚子",95142,"2003-10-18"]])

#print(df)
#
engine = create_engine('postgresql://scott:tiger123@127.0.0.1/city')
#
#
df.to_sql(name='cities',con=engine,if_exists='replace',index=None)
#
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## データベースの読み込み

```py:postgre_read.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	postgre_read.py
#
#					Oct/01/2018
# ------------------------------------------------------------------
import sys
import pandas as pd
#
from sqlalchemy import create_engine
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
engine = create_engine('postgresql://scott:tiger123@127.0.0.1/city')
#
df=pd.read_sql_query('SELECT * FROM cities', con=engine)
print(df)
#
df.to_csv("tmp001.csv",header=None,index=None)
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行結果

```text
$ ./postgre_read.py 
*** 開始 ***
       0    1      2           3
0  t1271   千葉  58471   2003-9-25
1  t1272   勝浦  49523   2003-3-16
2  t1273   市原  27461   2003-6-21
3  t1274   流山  39872   2003-8-27
4  t1275  八千代  21576   2003-11-5
5  t1276  我孫子  53271   2003-1-12
6  t1277   鴨川  81326   2003-5-22
7  t1278   銚子  95142  2003-10-18
*** 終了 ***
```

## 確認したバージョン

```text
$ python
Python 3.12.3 (main, Apr 10 2024, 05:33:47) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
>>> pandas.__version__
'2.1.4'
```
X, XS, XR, XS Max 対応(ノッチがあるかどうかを判別する方法)

# 環境

Xcode 10
Swift 4.2

# 対応方法

本当はもっとちゃんとチェックする方法があればいいのですが、思いつかなかったので、一旦`safeAreaInset.top`の高さで判断します。

```swift
final class Const {
    static let hasNotch: Bool = {
        // 今の所safeAreaInset.topが44以上なぐらいしか判断材料がないのでこれで判断
        return Const.safeAreaTopInset >= 44
    }()
}

if Const.hasNotch {
  // X, XS, XR, XS Maxの時の処理
} else {
  // それ以外の端末
}
```

# 言い訳

X, XS, XR, XS Max意外の端末の場合はStatusBarの高さが20~40(電話,テザリング時)なので、44以上にはならんだろってことで44以上を指定しています。いつ壊れてもおかしくないですが、わかりやすいのでいいかなと。
端末名で指定する方法だと今後のアプデに耐えれないので、上記の方法ならAppleさんが想像を超えて来ない限り大丈夫そうかなと。
Docker for MacでインストールしたKubernetesクラスタを初期化する方法

# インストール手順
インストールは難しくないです。この辺りを参考にインストールと起動をしてください。
[Docker for Mac with Kubernetes](https://qiita.com/taishin/items/920d62a641c9cd58f289)

# 本題の初期化方法
##### 1. Dockerアプリからpreferencesを開き、一番右の[Reset]を選択します
##### 2. [Reset Kubernetes cluster]を押します
##### 3. 1分ほど待ちます

![貼り付けた画像_2018_10_01_16_36.png](https://qiita-image-store.s3.amazonaws.com/0/75573/ab4ba04c-e670-6e82-aa4c-aa14c6e78bd0.png)

##### 4. 初期化されました

```bash:kubectl
$ kubectl get pods --all-namespaces
NAMESPACE     NAME                                         READY     STATUS    RESTARTS   AGE
docker        compose-67fd76c887-swvc9                     1/1       Running   0          10m
docker        compose-api-96bfcdd5f-f6hwr                  1/1       Running   0          10m
kube-system   etcd-docker-for-desktop                      1/1       Running   0          9m
kube-system   kube-apiserver-docker-for-desktop            1/1       Running   0          10m
kube-system   kube-controller-manager-docker-for-desktop   1/1       Running   0          10m
kube-system   kube-dns-86f4d74b45-dg7qw                    3/3       Running   0          10m
kube-system   kube-proxy-gm8wq                             1/1       Running   0          10m
kube-system   kube-scheduler-docker-for-desktop            1/1       Running   0          9m
```

なんども作り直して色々試しましょう
🍺今日から使いたいLGTM

[![LGTM](http://www.lgtm.in/p/0el8JXyzn)](http://www.lgtm.in/i/0el8JXyzn)

```markdown:markdown.md

[![LGTM](http://www.lgtm.in/p/0el8JXyzn)](http://www.lgtm.in/i/0el8JXyzn)
```
[![LGTM](http://www.lgtm.in/p/kwHD8Bjoq)](http://www.lgtm.in/i/kwHD8Bjoq)

```markdown:markdown.md

[![LGTM](http://www.lgtm.in/p/kwHD8Bjoq)](http://www.lgtm.in/i/kwHD8Bjoq)
```


LGTMの嬉しさが25倍になる

http://www.lgtm.in/
このサイトにいろいろな画像があっておもしろい
Firebase Realtime DBでインクリメントする方法


トランザクションを使うことでインクリメントを実現することができます。

```
// サンプルモデル counterをインクリメントする
class Hoge {
    var counter: Long? = null
}

// インクリメント実装例
fun incrementExample() {
    val ref = realtimeDatabase.getReference("hoge")
    ref.runTransaction(object : Transaction.Handler {
        override fun onComplete(p0: DatabaseError?, p1: Boolean, p2: DataSnapshot?) {
            if (p0 == null) {
                info { "Transaction success:${p2?.toString()}" }
            } else {
                error { p0 }
            }
        }

        override fun doTransaction(p0: MutableData): Transaction.Result {
            val hoge = p0.getValue(Hoge::class.java)
                    ?: Hoge().apply { counter = 0 }
            hoge.counter = (hoge.counter ?: 0) + 1
            p0.value = hoge
            return Transaction.success(p0)
        }
    })
}
```

トランザクション内で値の取得&更新を行います。
実行中に別の端末などから書き込みがある場合はトランザクションが一度失敗し再試行されます。
試行回数には上限があるらしいので絶対とは言えませんが、更新頻度次第ではかなり有用なインクリメント方法です。

参考
https://firebase.google.com/docs/database/android/read-and-write#save_data_as_transactions
pandas で MariaDB の読み書き

## データベースの作成

```mariadb_create.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	mariadb_create.py
#
#					Oct/01/2018
# ------------------------------------------------------------------
import sys
import pandas as pd
#
import mysql.connector
from sqlalchemy import create_engine
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
df = pd.DataFrame([
		["t1271","千葉",51476,"2003-9-25"],
		["t1272","勝浦",42573,"2003-3-16"],
		["t1273","市原",28471,"2003-6-21"],
		["t1274","流山",36872,"2003-8-27"],
		["t1275","八千代",24176,"2003-11-5"],
		["t1276","我孫子",13276,"2003-1-12"],
		["t1277","鴨川",91346,"2003-5-22"],
		["t1278","銚子",87192,"2003-12-18"]])

#print(df)
#
engine = create_engine('mysql+mysqlconnector://scott:tiger123@127.0.0.1/city')
#
#
df.to_sql(name='cities',con=engine,if_exists='replace',index=None)
#
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## データベースの読み込み

```py:mariadb_read.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	mariadb_read.py
#
#					Oct/01/2018
# ------------------------------------------------------------------
import sys
import pandas as pd
#
from sqlalchemy import create_engine
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
engine = create_engine('mysql+mysqlconnector://scott:tiger123@127.0.0.1/city')
#
df=pd.read_sql_query('SELECT * FROM cities', con=engine)
print(df)
#
df.to_csv("tmp001.csv",header=None,index=None)
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

## 確認したバージョン

```text
$ python
Python 3.10.9 (main, Dec 19 2022, 17:35:49) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas
>>> pandas.__version__
'1.5.3'
```
本番障害発生時の基本的な立ち振る舞い

障害対応はスピードが大事。非常に大事。
ここでは具体的にやる事ではなくて、大枠の考え方をまとめています。

# 原則
- 対応しているメンバーに迷惑がかからないようにする
- 自身がやらなければならない事をやる
- 自身ができることを考えてやる

# 考える事
## 自身がやらなければならない事がある場合
他の人と作業が被る可能性がある場合は宣言/表明してから、迅速且つ正確に、失敗した場合のリスクやその対応策があるかどうかなどを天秤にかけながら行う。

## 対応に必要なメンバーが障害に気づいていない可能性がある場合
該当するメンバーに連絡する。

## 自身にできるかもしれない事を考える
- 悪影響を与える可能性を考慮し、慎重に行動する。
- 他の人と被る事が予想される場合は宣言/表明する。
- やってはいけない可能性が想定される場合はわかる人に必ず確認をしてから行う。
 - 対応しているメンバーに質問する事はそれ自体が負担になり得るので、大した事でなければ聞かないようにする。
 - 大した事でないならやらないようにする(確認がとれないので結果としてこの選択になる)。
-  特にやれる事がないように思える状況でも邪魔にならずにできる事を考える。
 - パフォーマンス監視ツールをみる (状況把握の一環)
 -  本番の挙動を確認する (状況把握の一環だが、「今はアクセスしないで！」という状況も発生し得るので自身の頭で随時判断する。)
 -  対応メンバーの状況を追って把握する (自身の次の一手を考えるのに必要)

# 本当に自身に何もできる事がないと判断した場合
ここは上記の "特にやれる事がないように思える状況でも邪魔にならずにできる事" まで読んでも、それでもまだ他に優先度が高い通常業務があると思える場合に考える事。

- 通常業務を遂行しながら、障害対応に関する依頼を待機する。
 -  通常業務を遂行する場合でも障害対応に悪影響にならないかを考慮し、悪影響になりそうな事は避ける
 - チャット一つにしても、無駄な情報が流れる事で対応を行うメンバーが情報を把握しづらくなる可能性を考慮する。
 -  対応しているメンバーに対して依頼したい事がある場合は、後回しにできないのか考える。
エンジニア（社会人）の勉強方法 By　まつもとゆきひろ（Rubyの生みの親）

　先日、サポーターズCoLabさんが主催するまつもとゆきひろさんの講演に行ってきました。


<b>テーマは【勉強法】です</b>。

他にも出席した方が同じような記事を書いてると思いますので、ここでは特に重要だと思ったことや印象に残った内容をメモとして（Matzさんから共有の許可もいただけたので）、私の補足も入れながら残したいと思います。



<h1>【概念の理解】</h1>
<p>物事を抽象化して考える。
抽象化するとは、対象の詳細に踏み込まず、背景知識を活用して類似性や共通部分を見出し、
対象を理解する。

しかし、抽象化は完璧ではない。詳細に踏み込まないため、個々の誤差から起因する失敗（『アーキテクチャ宇宙飛行士』）が生じる。

それを<font color="green">【抽象化の漏れ】</font>と言う。</p>


<h1>【学生と社会人の勉強方法の違い】</h1>
<p>学生のテストは仮に５教科あって各教科１００点満点だとすれば、総合点が５００点になる。数学が得意な学生がいて、数学の点数が９０点。しかし英語が苦手なため、英語の点数は３０点。その時に、総合点を伸ばすのに注力すべき科目は伸びしろが１０点しかない数学ではなく、７０点の伸びしろがある英語にするのが合理的。</p>
<p>しかし、社会人の場合はそうはいかない。何故なら、<b><font color="red">社会に出たら満点がない</font></b>からです。<br>
世の中には沢山の職種や業務があり、人はそれぞれにあった仕事に就きます。<br>
社会人が勉強する場合は、仕事に直結する場合が多い（そうでない場合もありますが、とりあえずここではそれを前提として話を進めます）。<br>
時間が限られてる中、勉強するものを絞る必要がある。<br>
満点が存在する学生は点数を伸ばすために苦手克服したほうが良いが、社会人はそもそも満点がないので得意なものを伸ばしたほうが点数が高くなる。<br>

若手も年寄りもみんな学校教育に引きづられているから、苦手を潰す戦略を取りがち。<br>
それは合理的じゃない。<br>

<b><font color="blue">例）...プログラミングがとても得意だけどプログラミング以外は苦手な人がいるとする。その人に、プログラマーではなく事務員をやらせるのは合理的か？</font></b><br>
（プログラマーの中にも面倒な事務処理を楽するためにうまく工夫する人もいるとは思いますが…）。<br>
学生はテストで良い成績を残すためには、暗記をする必要がある（記憶作業が重要）。<br>
社会人は知識のインデックスを把握しておくだけで良い。詳細が必要なら、ググれば良いです。<br>
<b><font color="red">インターネットに接続できない職場？？そんな職場辞めたらいいのでは？</font></b><br>
（客先での常駐業務になる場合、セキュリティーを理由にインターネットに接続できないところもあります。私も実際に客先常駐を経験していますが、把握できないほど色んな人が出入りしている中でセキュリティーって…（笑）接続してダメなところを分からないエンジニアはいないし、現場入場でセキュリティー教育を施す。インターネットを活用して業務に励んでもらった方が生産性が上がる）。</p><br>


<h1>勉強できない職場はやめるべき？</h1>
<p>上記でも述べたように私達エンジニアが勉強するときは業務に直結する場合が多いです。勉強する＝スキルが上がる＝生産性が上がる。

<blockquote>プライベートの時間は大事にすべき!</blockquote>

会社にとっても利益になるもので、勉強をするなら職場で積極的にすべき。
（業後や休みに勉強をするのも良いですが、<font color="red">私たちは働くために生きているのではない。生きるために、充実したプライベートを過ごすために働いている</font>）。
<blockquote>Matzさん「仕事の時間を勉強に使いたいよね。生産性を高めて仕事の間に勉強する。
自分の改善のために時間を投資することをゆるさないところは多分あなたのことを尊重していない。そんな会社は滅びたほうがいいよね。」</blockquote>
職場は学校ではない。勉強は他でやれ！という様な理解がない職場なら辞めるべき。
（実際エンジニアでけでなく、医者や法律のプロフェッショナルだって常に勉強している）。
</p>


<h1>内省</h1>

<p>自分について真剣に考える。
好きなこと、得意なこと、苦手なこと。
住む場所、働く場所、勉強する場所。
相手は自分を尊重してくれる人か？
<blockquote><i>尊敬と尊重は違う。尊敬は人格的な部分も含まれるが、尊重は相手をないがしろにしないこと。<i></blockquote>
</p>

<h1>エンジニアとして</h1>
<h2>基礎おさえる</h2>
<p>コンピューターサイエンス、アルゴリズム、コンピューターアーキテクチャなどをしっかりおさえる。
</p>

<h2>英語をやる</h2>
<p>英語が出来ると１８億人とコミュニケーションが取れる。
語学にも段階があって、人によってどの段階を目指すのか変わる。
<blockquote><i>多くの技術的な情報は英語で発信され、その１～２年後になってから日本に輸入される。
だから、英語ができると日本においてタイムマシン経営ができる＝他社より有利になる。<i></blockquote>
最低限読めるようになろう。

<blockquote><i>英語に才能は要らない。とにかく場数を踏むこと。
</i></blockquote></p>

<h2>コンフォートゾーンを出る</h2>
<p>居心地の良い空間にいると成長しない。
普段やらないようなことをするために一歩踏み出す。
変化を恐れない訓練をしよう。
</p>

<h2>人を見下さない</h2>
<p>人を見下すと会話ができなくなる。
自分のことも見下さない。
（電話対応のときや、あんまり知らないことに対する失敗をするときに見下す奴が出てきますが、こいつは馬鹿なのか？頭おかしいんじゃないか？と本当に疑問に思ってしまいます。
彼らはなんで人を見下すんでしょうね？）
</p>


<h1>ブラック企業の撲滅方法</h1>
<p>Q&Aにて、ブラック企業に就職してしまった人はどうすれば良いのか？との質問にMatzさんの答えは、
<blockquote>辞めたらいいです。辞めた後に入社した企業がまたブラック企業なら、また辞めれば良いんです。皆がやめないから、ブラック企業が延命するんです。</blockquote></p>



<h1>最後に</h1>
<p>ほかにも多数のキーワードがありますが、私は上記のキーワードをピックアップさせていただきました。Matzさん、ありがとうございました。
</p>
PythonやJavaScriptにアクセス修飾子がない理由を考えてみた

# はじめに
* 先日、ソースコードレビューを受けた際に「pythonにはアクセス修飾子の概念はないよ」と言われました。
* 「JavaとかRubyにはあったよなー」とか思いつつ、**「Pythonにはどうしてないんだろう」**と感じたため記事を書いてみました。
* Pythonの他にJavaScriptにもないので、そのあたりを解明していきたいと思います！

# 想定読者
* アクセス修飾子が何かわからない。
* アクセス修飾子って聞いたことがあるけど、なんだっけ。
* アクセス修飾子って聞くだけでワクワクする。

という方は、対象としていますのでベテランの方はスルーしちゃってください！！！
（「ここ違うよ」とかレビューやコメントはお待ちしております。）

# そもそも、アクセス修飾子ってなに？
* クラスやメンバからの参照可能な範囲の定義。
* 「お前は使ってもいいよ」「お前は使ってはダメだよ」っていうものを定義します。
* ちょっと、よくわからないので実際の例を見ていきます。

## 代表的なアクセス修飾子のまとめ
* アクセス修飾子には代表的なものが3種類あります。
* `public`と`protected`と`private`です。

| 種類 | 利用目的 |
| ---- | ---- |
| public | 制限無く公開したい |
| protected | 基本的に外部からは隠蔽するが、サブクラスやパッケージ内からのみ利用させたい |
| private | 基本的に外部からは隠蔽し、クラス内からのみ利用させたい |

## アクセス修飾子を図示
* 言葉だけだと、わかりづらかったので図式化。
* 建物で考えてみると、publicが公園。protectedが会社。privateが自宅ってところでしょうか。
* 公園は、誰でも入れる。会社は、社員じゃないと入れない。自宅は、自分だけ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/106459/42f0004a-351d-607e-8b3d-dd715f23b403.png)


## 言語間の差異
* 主要な言語ごとにアクセス修飾子の有無を調べてみました。
* アクセス修飾子がない言語は、基本的にルールベースでアクセス修飾子を表現しています。

| 言語 | アクセス修飾子の有無 | 備考 | 
| ---------- | ---- | ---- | 
| Python | なし | クラスに_などつけて見分ける | 
| JavaScript | なし | クラス_などつけて見分ける |  
| TypeScript | あり | public, protected, private | 
| Java | あり | public, protected, private | 
| PHP | あり | public, protected, private | 
| Ruby | あり | public, protected, private | 
| Golang | なし | lowerCamelCaseとUpperCamelCaseで見分ける | 

### 各言語のprivateの定義方法
#### Python
```python:sample.py
_private_method():
 print('プライベート')
```

#### JavaScript
```js:sample.js
_privateMethod: function() {
 console.log('プライベート');
}
```

#### TypeScript
```typescript:sample.ts
private privateMethod(): void {
  console.log('プライベート');
}
```

#### Java
```java:sample.java
private void privateMethod() {
  System.out.println( "プライベート" );
}
```

#### PHP
```php:sample.php
private function privateMethod(){
  echo "プライベート";
}
```

#### Ruby
```ruby:sample.rb
private
def private_method()
  print("プライベート")
end
```

#### Golang
```golang:sample.go
func privateMethod()
  fmt.Printf("プライベート")
}
```


# アクセス修飾子がない理由（仮説）
* アクセス修飾子を持っていない理由を調べてみましたが、回答を見つけることができませんでした。
（どなたかわかればリンクやコメントください。）
* なので、私の仮説を書いてみたいと思います。

## 仮説①：歴史が浅い言語には存在しない（関係なし）
* 最初、歴史的経緯でアクセス修飾子が不要になったのかなと思いましたが、全く関係なさそうです。
* [意外と若い、プログラム言語の誕生日と年齢。](https://qiita.com/Nekonecode/items/841c9dda9ba1a3014635)を見た所、pythonやJavaScriptもそこまで誕生が古くないです。

## 仮説②：シンプル化するため
* wikipediaを見ると、[Python](https://ja.wikipedia.org/wiki/Python)も[Golang](https://ja.wikipedia.org/wiki/Go_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E))も**シンプル**とか**軽量**といった言葉が使われています。

* 誤解を恐れずに書くとしたら、 **アクセス修飾子がなくてもアプリや動作するものが作れる** ということだと思います。

## 仮説③：大規模アプリ開発を前提としていないため
* PythonもGolangも大規模アプリ開発には、他の言語と比べて向いていない気がしています。
* **大規模開発**つまり、**複数人**、**大人数**で開発することがないため**ルールベース**（_やケース）でも問題ないということなのかなと思います。

## 仮説④：JavaScriptにアクセス修飾子がない理由は、TypeScriptがあるため
* JavaScriptが生まれた当初は、必要なかったんだと思いますが、大規模開発にも使われるようになってきて必須になりました。
* ただ、Typescriptという代替手段があるため、JavaScriptには実装されてないのではないでしょうか。


# 【結論】アクセス修飾子はどんな言語であっても利用すべき
* 基本的にアクセス修飾子は使うべきで、PythonやGolangに存在しないのは、言語自体をシンプル化する目的でしかなく、使わなくていい理由にはならない。
* プログラミング初心者や一人開発だとつい、疎かになってしまいがちですがこの機会に覚えて中級エンジニアの仲間入りをしちゃいましょう。
volumioでのいろいろな設定

volumio2 + RaspberryPi2 + 液晶ＴＶで簡易音楽プレーヤーを作りました。そのときに行った設定の方法を書いておきます。

#sshを有効にする
http://volumio.local/DEV を開いて ssh enable を押すだけ。
volumio.local（デフォルト）の部分は、自分の設定による。

#sambaを有効にする
標準で有効になっているみたい。windowsのエクスプローラで￥￥（ＩＰアドレス）で行ける。または￥￥volumio.local。エクスプローラのネットワークに表示されるようにするには，WorkgroupをＰＣと同じにするといいみたい。

```/etc/samba/smb.conf
[global]
workgroup = HOGEHOGE
```

smbd, nmbdが起動していないなら、sshでログインして、次のコマンドを打つ。

```shell:sambastart.sh
sudo service nmbd restart
sudo service smbd restart
```
#画面制御
volumioは，標準ではＨＤＭＩにＧＵＩを出力しない。そこで，タッチスクリーン表示用プラグインを導入する。途中で止まる場合は，ページを開き直して再挑戦。１００％で終わってもリセットしてもＧＵＩが立ち上がらない場合はchrome-browserが入っていないかもしれない。そのときはsshとかで次のようにする。

```
sudo apt-get install chrome-browser
```

/opt/volumiokiosk.sh　っていうのがあった。そのなかでchromeはキオスクモードで立ち上がるようになっている。内容は次のとおり。

```shell:volumiokiosk.sh
#!/bin/bash
xset +dpms
xset s blank
xset 0 0 120
openbox-session &
while true; do
  /usr/bin/chromium-browser \
    --no-touch-pinch \
    --kiosk \
    --no-first-run \
    --disable-3d-apis \
    --disable-breakpad \
    --disable-crash-reporter \
    --disable-infobars \
    --disable-session-crashed-bubble \
    --disable-translate \
    --user-data-dir='/data/volumiokiosk' --no-sandbox  http://localhost:3000
done
```
次のように書き換えた。

```shell:
xset -dpms
#xset s blank
#xset 0 0 120
```

xsetの参考資料：http://www.atmarkit.co.jp/flinux/rensai/linuxtips/285offx.html
fish shellで `echo {0..255}` は `seq` を使う

ただの備忘録。

# 何やりたかったの？

[LAN内で使われているIPアドレスを調べる6つの方法(Linux/Windows) | 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2015/05/lan%E5%86%85%E3%81%A7%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8Bip%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E8%AA%BF%E3%81%B9%E3%82%8B6%E3%81%A4%E3%81%AE%E6%96%B9%E6%B3%95linuxwindows/#1-1ping_arp)

```shell-session
$ echo 192.168.0.{1..254} | xargs -P256 -n1 ping -s1 -c1 -W1 | grep ttl
```

つまり

192.168.0.x に所属する IPアドレスにpingを送り、返答の合ったものを一覧表示する。 

これをするに辺り、 `{1..254}` の展開ができず、 `ping: cannot resolve 192.168.1.{1..254}: Unknown host` と怒られてた。

# どう書くの？

こうでした。

```shell-session
$ echo 192.168.1.(seq 1 254) | xargs -P256 -n1 ping -s1 -c1 -W1 | grep ttl
```

# 参考資料

* [How to iterate for loop with limiting sequence in fish shell - Stack Overflow](https://stackoverflow.com/questions/36146817/how-to-iterate-for-loop-with-limiting-sequence-in-fish-shell)

# 別の解法

* [fishでも{1..9}を展開したい！ - Qiita](https://qiita.com/ryotako/items/70827643a20fa60b2547)
Anaconda環境で作成したPythonプログラムをexe化した話。

#Anaconda環境で作成したPythonプログラムをexe化した話。

##環境
* Win7 Pro
* Anaconda 5.2(Python 3.6 Version)
* Python 3.6.5

##なぜexe化したかったのか
波形解析をPythonで楽にできることを知り、Python TUEEEEしてた。
しかし、Pythonスクリプトをそのまま実行するためにはPythonがインストールされている環境でないとダメと知る。
ならば実行形式にしてやればいいじゃん←イマココ

##exe化するには
Pyinstallerなるものを使ったら幸せになれるらしい。

##Pyinstallerをインストールする
[Anaconda環境にpipでパッケージをインストールする](https://qiita.com/mckeeeen/items/d4cbe4a16a102157f40c)を参考にさせていただいて、Pyinstallerをインストールしようとする。

プロキシにひっかかった……。

[proxyかんでる社内環境でpip/anacondaを動かすときに注意事項。](https://qiita.com/dev4kj/items/af6c0fea17adef514ba8)を参考にさせていただいて、プロキシを通過しPyinstallerをインストール！

##いざ、exe化へ


exe化したいPythonスクリプトはこんなの。

```python:wave.py
from scipy.optimize import curve_fit
import seaborn as sns

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

filepath = input('please input file path.')
filename = pd.read_csv(filepath, encoding="SHIFT-JIS")
listT = []
listV = []
listT = filename['time']
listV = filename['value']

type = input('please input type.\n1:curve\r2:average')
if type == '1':
    res = np.polyfit(listT,listV,10)
    y2 = np.poly1d(res)(listT)
    plt.figure(figsize=(20,10))
    plt.plot(listT,listV,label='ori')
    plt.plot(listT,y2,label='curve_fit')
else:
    num = 10000
    b = np.ones(num)/num
    y2 = np.convolve(listV, b, mode='same')
    plt.figure(figsize=(20,10))
    plt.plot(listT,listV, label='ori')
    plt.plot(listT,y2, label='ave')

plt.legend()
plt.show()

input()
```
###pyinstaller wave.pyを実行。

結果

```shell:
Recursion error : maximum recursion depth exceeded
```

再帰回数が多いらしい。
pyinstaller wave.py実行時に生成されるwave.specを[pyinstaller creating EXE RuntimeError: maximum recursion depth exceeded while calling a Python object](https://stackoverflow.com/questions/38977929/pyinstaller-creating-exe-runtimeerror-maximum-recursion-depth-exceeded-while-ca)を参考にさせていただいて、変更する。

###pyinstaller wave.specを実行。

結果

```shell:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83 in position 128: invalid start byte
```

読み込みファイルをUTF-8で保存し直しても解決ならず……。
teratailで質問([python3のpyinstallerを使用したexe化について](https://teratail.com/questions/148542))する。


c:\users\user\anaconda3\lib\site-packages\PyInstaller\compat.py の370行目

```python
out = out.decode(encoding)
↓ 変更
out = out.decode(encoding, errors='ignore')
```

###pyinstaller wave.specを再度実行。

結果 **できた！ブラボー！！！！**


やったね、たえちゃん。pythonスクリプトがexe化できたよ！！

##追記
exe化できたにはできたが実行開始までが糞重い。(我慢できないくらい。時間は計ってない。)
cx_Freezeなるものの方がなにやら早いらしい。
cx_Freezeも調べてみないとなあ。
AppleScriptで全てのアプリを終了 - MAC 



# script editorを開く

<img width="676" alt="Screen Shot 2018-10-01 at 15.37.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/04b05a20-a6d5-04f9-a92b-fab78533a909.png">

# new document

<img width="715" alt="Screen Shot 2018-10-01 at 15.40.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/bb75d540-daf4-e6a2-0bf7-960ddb73c3b0.png">

# 実装

<img width="698" alt="Screen Shot 2018-10-01 at 15.40.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/2dead28f-eb3b-195b-04b4-36cce50a72a8.png">

```
tell application "System Events" to set quitapps to name of every application process whose visible is true and name is not "Finder"
repeat with closeall in quitapps
quit application closeall
end repeat
```


# 保存された

<img width="697" alt="Screen Shot 2018-10-01 at 15.40.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/940eac7b-b226-1a73-4741-42e6e80770d5.png">

# 使う

クリックすると実行される

<img width="1364" alt="Screen Shot 2018-10-01 at 15.40.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/135794/6a71ab33-ae35-e731-6352-436645bc5dc9.png">