OmniAICreator/Qiita-1.07M huggingface dataset:
Go言語をMacOSにインストールする

Homebrewコマンドを使ってMacOSにGo言語をインストールする方法を説明してきます。
前提としてHomebrewがインストールされていることを想定しています。

# 環境
- MacOS 10.14
- Homebrew 2.1


# インストール方法

## バージョン確認

```bash
$ brew search go

go
go@1.10
go@1.11
go@1.12
```

Goを検索するとインストール可能なバージョンが出力されるので、インストールしたいバージョンを決めましょう。

## インストール
今回は1.12をインストールしてみましょう。

```bash
$ brew install go@1.12
```

## PATHの設定
インストールが終わったら↓のようなメッセージが出てきます。

```
If you need to have go@1.12 first in your PATH run:
  echo 'export PATH="/usr/local/opt/go@1.12/bin:$PATH"' >> ~/.bash_profile
```

このメッセージはインストールしたGoのバイナリのPATHを通すように設定する必要がある、ということを言っています。なので、PATHを通しましょう。
`~/.bash_profile`が乱雑するのは嫌なので上記のメッセージ通りにはやりませんが、手取り早くPATHを通したい方は上記のメッセージ中のコマンドを実行してください。
ついでに`GOPATH`の設定もしてしまいましょう。

```bash
$ vi ~/.bash_profile

export GOPATH="$HOME/go"
GO_BIN="/usr/local/opt/go@1.12/bin"
export PATH="$GO_BIN:$PATH"

$ source ~/.bash_profile
# ^vi^sourceを実行した方が早いかな...
```

## 確認
ちゃんとGoが使えるか確認しましょう。

```bash
$ which go
/usr/local/opt/go@1.12/bin/go

$ go version
go version go1.12.9 darwin/amd64
```

これで終了です :wave:
EDAで扱うpythonの関数メモ

# はじめに
EDA(Explorer Data Analystic)を行う際に扱う関数をメモっとく。
覚えたつもりが全然覚えられてないことにがくぜんとした。。。

# 使用しているライブラリ
import matplotlib.pyplot as plt

# plt.scatter
https://pythondatascience.plavox.info/matplotlib/%E6%95%A3%E5%B8%83%E5%9B%B3

２次元の散布図の描画で使用するメソッド。

```
matplotlib.pyplot.scatter(
	x		x軸の値
	, y		y軸の値
	, s=20		表サイズ
	, c=None	色の値
	, marker='o'	マーカーの形（デフォルトは'〇'＝円）
	, cmap=None	カラーマップ
	, norm=None	正規化を行う場合のNormalizeインスタンスを指定
	, vmin=None	正規化時の最小値
	, vmax=None	正規化時の最大値
	, alpha=None	透明度。0(透明) ～ 1(不透明)
	, linewidths=None	線の太さ
	, verts=None
	, edgecolors=None	線の色
	, hold=None
	, data=None
	, **kwargs
)
※ "=" が記載されている値はデフォルト値
```

# plt.plot
https://pythondatascience.plavox.info/matplotlib/%E6%8A%98%E3%82%8C%E7%B7%9A%E3%82%B0%E3%83%A9%E3%83%95

２次元の折れ線グラフの描画で使用するメソッド。

```
matplotlib.lines.Line2D(
	xdata			X軸の値
	, ydata			Y軸の値
	, linewidth=None	線の太さ
	, linestyle=None	線のスタイル（デフォルトは実線）
	, color=None		線の色
	, marker=None		マーカーの種類
	, markersize=None	マーカーの太さ
	, markeredgewidth=None	マーカーの枠線の太さ
	, markeredgecolor=None	マーカーの枠線の色
	, markerfacecolor=None	マーカーの塗りつぶしの色
	, markerfacecoloralt='none'	マーカーの塗りつぶしの色２
	,fillstyle=None		マーカーの塗りつぶしのスタイル
	, antialiased=None	アンチエイリアス（線を滑らかにする処理）をするかしないか
	, dash_capstyle=None
	, solid_capstyle=None
	, dash_joinstyle=None
	, solid_joinstyle=None
	, pickradius=5
	, drawstyle=None
	, markevery=None
	, **kwargs
)
```
Power BIのブックマーク機能でグラフ操作ボタンをつくる

##はじめに
- Power BIでは、スライサーやドリルUp/Downアイコンでインターラクティブにビジュアルを操作することができますが、一発で設定できるボタンがあると便利です。
- ブックマーク機能とボタンを使い、グラフを所定の状態に設定するボタンをつくってみました :grin:

##ダミーデータ
ダミーデータとして、Date,Category,Numberの列から構成されるテーブルを用意します。
ここでは、DAXによるテーブル式でランダムなデータを作成します。

```ruby:DAX
Data = ADDCOLUMNS(CALENDAR("2015/1/1","2019/9/30"),"Category",UNICHAR(UNICODE("A")+INT(3*rand())),"Number",INT(10*rand()))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/6ee89e66-6204-f449-3e25-27ac1622b2a7.png)

##グラフの作成
1.以下の折れ線グラフを作成します。

- カテゴリごとの合計値のグラフ
- 合計値のグラフ

※X軸に日付の階層をもつDateを割り当てます。

2.テキストボックスを用いて、グラフにコメントをつけます。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/9c4cbf8a-b747-8555-fdcc-f673e72c3e93.png)



##ブックマークとボタンの作成
1.ブックマークを作成します
ここでは、以下のように設定しています。

| ブックマーク名    | データ |ディスプレイ|現在のページ|すべてのビジュアル|選択したビジュアル|
|:----------------:|:------:|:---------:|:---------:|:---------------:|:---------------:|
| 年ごと            |     ✔ |           |            |✔               |                |
| 四半期ごと        |     ✔ |           |            |✔               |                |
| 月ごと        |     ✔ |           |            |✔               |                |
| 全て        |     ✔ |           |            |✔               |                |
| 直近一年        |     ✔ |           |            |✔               |                |
| コメントOn        |      | ✔          |            |✔               |                |
| コメントOff        |      | ✔          |            |✔               |                |

2.ブックマークにフィルタやビジュアルの状態を割りてます。（ビジュアルの状態やフィルタ設定後にブックマークを更新します）
![Bookmarks.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/66b2e6eb-8882-0f31-4e5e-4890bd619a46.gif)

3.ボタンのブックマークを配置し、アクションにブックマークを割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/b2b5d1ae-b873-4b4e-36ff-625c2af7f173.png)

##作成したダッシュボード
![BookmarksDemo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/fa3dabfe-25a4-9012-9c78-d158a5a30aa9.gif)


##参考
- Power BIのブックマーク　https://docs.microsoft.com/ja-jp/power-bi/desktop-bookmarks
- Power BI でボタンの使用　https://docs.microsoft.com/ja-jp/power-bi/desktop-buttons
【社内コミュニケーション】夜の飲み会はやめて昼ランチにしよう

社内コミュニケーションという名目のもと、夜の飲み会が開催されることがある。
断固反対。社内コミュニケーションは昼にやろう。

| | 昼ランチ | | 夜の飲み会 | | 
| --- | :-: | --- | :-: | --- |
| 参加メンバー | ○ | 基本誰でもOK | ✕ | 基本酒が強い人が集まる |
| 仕事の話 | ○ | 業務時間内なので話しやすい | ✕ | 愚痴にまみれる |
| 食事代 | ○ | 1000円前後 | ✕ | 3000〜5000円前後 |
| 制限時間 | ○ | １時間 | ✕ | 終電 or 朝までコース |
PowerShellでエクセルマクロを実行する

PowerShellからExcelのVBAマクロを実行する。


```powershell
:Run-ExcelMacro.ps1
Param(
    [string]$excel_file_name # マクロを実行するエクセルファイル名
    ,[string]$macro_name     # 実行するマクロ名
)

if( [String]::IsNullOrEmpty($excel_file_name) -or 
    [String]::IsNullOrEmpty($macro_name) ) {
    # 空のときは終わり
    Write-Host $excel_file_name is not found! 
    exit 1
}

if(Test-Path $excel_file_name) {
    $excel = New-Object -ComObject Excel.Application
    # Excelを表示しない
    $excel.Visible = $false
    $full_name = Convert-Path $excel_file_name
    $book = $excel.Workbooks.Open($full_name)
    $excel.run($macro_name)
    $book.close()
    $book = $null
    $excel.quit()
    $excel = $null
    [GC]::Collect()

    exit 0
}
```

Excelを非表示にしても、マクロ内のメッセージボックスは表示します。


## Example
シート内のマクロは、シート名を付けて実行する。

```
PS C:\Work>.\Run-ExcelMacro.ps1 Test.xlsm Sheet1.TestMacro
```

## GitHub
https://github.com/digitalMagicbox/Run-ExcelMacro
Talendでちょっと複雑なリスト結合処理のためにtHashInputを使う

ソースはこちら。
https://github.com/kuinaein/talend-complex-merge-example

# やりたいこと
ETLツールTalend Open Studio for Data Integration 7.2.1を使っている。

データベース（テーブル）AとBがある。それぞれカラムとしてID、名称、メールアドレスetcを保持している。Aには連携用にB側のIDも入っているが、連携前の場合は0。

さて、データベースAからBへの一方向同期を行いたい。B側のIDが分かっている場合は当然にそれを使う。分かっていない場合は、まずメールアドレスが一致するもの、次に名称が一致するものを連携対象のレコードとし、そのIDを使う。

元のデータは例えばこんな感じ。

**A**

|id |name          |email            |b_org_id|
|---|--------------|-----------------|--------|
|1  |麻布株式会社        |azabu@nowhere.com|0       |
|2  |株式会社伊藤工務店     |itou@nowhere.com |10002   |
|3  |(株)宇治園芸店      |uji@nowhere.com  |10003   |
|4  |衛門府           |emon@nowhere.gov |0       |
|5  |オスマンエージェンシー（株）|osman@nowhere.com|0       |

**B**

|org_id|name     |email              |
|------|---------|-------------------|
|10001 |麻布株式会社   |azabu@nowhere.com  |
|10002 |株式会社伊藤工務店|itou@nowhere.com   |
|10003 |株式会社宇治園芸店|uji@nowhere.com    |
|10004 |衛門府      |dayomon@nowhere.gov|
|10004 |衛門府      |demonen@nowhere.gov|
|10005 |堀高高等学校   |holy@nowhere.edu   |

（Bで10004が被っているのは誤記ではなくて、実際には「組織」「組織の担当者」と2つテーブルがあるのを簡略化のためにJOINしているから。）


# ペインポイント
2つのテーブルを、結合条件を変えながら何度も結合しなおすというところが難点。

Talendでは循環参照を防ぐため、コンポーネント間の接続が結構制限される。
具体的に言うと、2つのコンポーネントについて、（たとえ間にtReplicate等を挟もうと）その2つから伸びている接続線を2回以上交わらせることができない模様。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207347/5383387c-6dc0-a54b-d488-067cbf5687ba.png)
同じファイルを何度も読みこませたり、tMapでCROSS JOINしてtFilterRowで自力で絞り込むという荒業もできなくはないが。。

# tHashInput/tHashOutputを使う
Talendにはテーブルデータをメモリに保存して何度も再利用できるtHashInput/tHashOutputというコンポーネントがあるのでそれを使う。

ただし、デフォルトでは有効になっていないので、ファイルメニューの「プロジェクトプロパティの編集」で設定を変える必要がある。デザイナー＞パレット設定を開き、右ペインのジョブ＞テクニカル下にある両コンポーネントを有効化する。

tHashOutputで保存したデータを、tHashInputから読み込ませる形になる。tHashInputはどのtHashOutputのデータを読み出すか選択できるもの、スキーマを同期してはくれない。リポジトリでスキーマを定義してしまうことを推奨。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207347/c8f003f2-2b56-a632-25e1-ccbf6720d154.png)

（かなり雑だが、、）出力はこんな感じになる。

||||||
|---|---|---|---|---|
||2|株式会社伊藤工務店|itou@nowhere.com|10002|
||3|(株)宇治園芸店|uji@nowhere.com|10003|
|rejected|5|オスマンエージェンシー（株）|
|by_email|1|||10001|
|by_name|4|||10004|
ModuleNotFoundError: No module named 'boto3’


# 環境

* macOS Catalina 10.15


# エラー内容

`$ sudo pip install boto3`でboto3をインストールしたけど、
いざスクリプトを実行するとエラーが発生した。

``` sh
$ python3 sample.py
Traceback (most recent call last):
  File "sample.py", line 2, in <module>
    import boto3
ModuleNotFoundError: No module named 'boto3'
```

boto3モジュールがないため、エラーが発生しているが、
boto3は先ほどのコマンドでインストールしているはずなので、
モジュールがないというエラーが発生するのは不思議だった。

# 対処法

``` sh
$ sudo pip3 install boto3
```

`pip`でboto3を入れていたが、`pip3`にしなければいけないようだ。
単に`pip`だとPython2.7が実行されていたが、boto3の場合はPython3用の`pip3`をインストールしなければならなかった。

普段Pythonを触らないので、ハマってしまった。

# 参考

* [boto3 module not recognized when script run from file (Mac) - Course: Create a Serverless Portfolio with AWS and ReactJS](https://acloud.guru/forums/serverless-portfolio-with-react/discussion/-KtxumkIth6835Je9R9a/boto3%20module%20not%20recognized%20when%20script%20run%20from%20file%20(Mac))
* [Python - Pythonの「pip」と「pip3」は何が違う？｜teratail](https://teratail.com/questions/46066)
型に厳密なdataclass

シンプルな`dataclasses.dataclass`はアトリビュートの型が定義と異なってもインスタンス化が可能。つまり以下のような例が実行可能。

```python
@dataclasses.dataclass
class NormalDataclass:
    foo: int

NormalDataclass(foo=1.1)  # ok
```

厳密に型をチェックしたい場合は`__post_init__`を定義すれば良い。`__init__`の後に呼ばれるのでここで型チェックをしてみよう。

```python
@dataclasses.dataclass
class StrictDataclass:
    def __post_init__(self):
        for key, val in self.__dataclass_fields__.items():
            member = getattr(self, key)
            assert isinstance(member, val.type), f"Invalid Type of member: {type(member)} != {val.type}"

    foo: int


StrictDataclass(foo=1)  # ok
StrictDataclass(foo=1.2)  # AsertionError: Invalid Type of member: <class 'float'> != <class 'int'>
```

不正な値が入ってきた場合にいち早くassertionを投げてくれるのでデバックがしやすくなるかもしれない。
Next.js SSRのセッション管理

#はじめに
SSR（Server Side Rendering）の場合はセッションを使ってユーザー認証管理は一般的です。
Next.jsもいくつかのセッション管理ツールがありますので、少しまとめてみます。

#next-authとは
The NextAuth library uses Express and Passport, the most commonly used authentication library for Node.js, to provide support for signing in with <b>email</b> and with services like <b>Facebook, Google and Twitter</b>.
NextAuth adds Cross Site Request Forgery (<b>CSRF</b>) tokens and <b>HTTP Only cookies</b>, supports universal rendering and does not require client side JavaScript.

next-auth: https://github.com/iaincollins/next-auth

##インストール
`npm install next-auth`

##クライアント使うサンプル
```react
import React from 'react'
import { NextAuth } from 'next-auth/client'

export default class extends React.Component {
  static async getInitialProps({req}) {
    return {
      session: await NextAuth.init({req})
    }
  }
  render() {
    if (this.props.session.user) {
      return(
        <div>
          <p>ログイン中です。</p>
        </div>
        )
    } else {
      return(
        <div>
          <p>未ログインです。</p>
        </div>
      )
    }
  }
}
```

##サーバ側
###./pages/authフォルダーにページ作成
- index.js  NextAuth.signinメソッドを実行し、ログイン成功、失敗を判断
- error.js　認証失敗の処理

##重要な３つの設定ファイル
- next-auth.config.js: https://github.com/iaincollins/next-auth/blob/master/example/next-auth.config.js
  セッションの保存時間、DBなどの設定

- next-auth.functions.js：https://github.com/iaincollins/next-auth/blob/master/example/next-auth.functions.js
ログインの処理、セッションに保存するデータなど

- next-auth.providers.js：https://github.com/iaincollins/next-auth/blob/master/example/next-auth.providers.js
Facebook、Twitter、GoogleなどのproviderのクライアントID,シークレットなどの情報を設定
利用しない場合は設定なしでOKです。

参考：https://github.com/iaincollins/next-auth
サンプル：https://github.com/iaincollins/next-auth/blob/master/example/pages/auth/index.js

#passport
passport:http://www.passportjs.org/

#cookie
サンプル：https://github.com/zeit/next.js/tree/canary/examples/with-cookie-auth

#firebase
サンプル：https://github.com/zeit/next.js/tree/canary/examples/with-firebase-authentication

以上
Maya TransformAttributesの値だけをリセットしたい

MayaでRigを組んでいるときに
「Translate, Rotate, Scaleを一気に初期化したい！」というタイミングが何度もありました。
そこで、複数オブジェクトのトランスフォーム値を初期化するMELを書きました。
マーキングメニューに登録して使ってみてください。
https://youtu.be/1IdIZQhr6Jk


```
string $obj[] = `ls -sl`;
for ($objSel in $obj)
{
select $objSel;
setAttr .t 0 0 0;
setAttr .r 0 0 0;
setAttr .s 1 1 1;
}
```




単純なプログラムですが、
以下の方法でリセットが効かなかったり、手順が多いので良い方法とは言えませんでした。

方法1
Modify > Reset Transformations
⇒Rigのカーブだけでなく、対象のジョイントまでリセットされてしまう。
（または、Rig自体がスキンアタッチされている場合はエラーになり、リセットがきかない）

方法2
Channel Boxで0クリアする。
⇒Channel Boxを開いて、TranslateとRotateを選び、0を入力する。
これだけで3ステップを踏んでしまっている。これを1ステップにしたい。

方法3
アニメーションキーで初期状態を入れる。
⇒キーをあらかじめ打っておくと、邪魔になることがある。
また、キーを後から流し込むのも、Rigに変更があれば流し込みが出来ない。
コードレビューをするときの心構えについて

## はじめに
過去、コードレビューが意味するところ、そしてその心構えを教えていただきました。その内容を忘れないようにするため、自分の言葉で書き下しておこうと思います。教えてもらって感じたことも混じっています。

## 意味するところ
* コードの品質向上
以上。レビュー必須とすることで良い品質のコードを保てるものと思います。雑なコードをメンテしないといけないことを考えれば、レビューする時間なんて安いものかと思います。

* 割れ窓理論
「きれい」なコードが並んでいれば、「きれい」に書かれ続けられるものと思います。

* 人の目
人に見られるので、人に説明できるようにコードを書くようになっていくものと思います。

* 間違いの訂正
人はミスをする生き物です。また、本人はミスに気づきにくいものです。

## 心構え
* 自分を棚に上げる
コードレビューの意味するところは「コードの品質向上」です。自分が出来ていなかろうと「良くないもの」はコメントを付けるほうが良いと思います。

* 自分の勉強のためと思う
理解できないコードはレビューできないので、書いた本人や分かる人に質問するようにするといいと思います。「コードの品質向上」を目的としているので教えてもらえるはずです。また、人の技術を盗むチャンスです。習得すれば結果としてチームに貢献できます。

* コードスタイルも見逃さない
~~フォーマッターを使うべきと気づくはず。~~ ~~後に気がついた人が修正するとバージョン管理システムでBlameできなくなる。~~ 「割れ窓理論」だと思いますので。

* 修正内容を全部提示しない
あなたはコピペしたコードを覚えていますか？ある程度考える余地を残すことで良いコードについて覚える可能性が上がるものと思います。

## さいごに
レビューは「コードの品質向上」のためであり、チームでその認識が統一されていれば良いスパイラルを産むものだと思います。もし諍いに気がついたら、ファシリテータやマネージャーに認識の統一をお願いするといいかもしれません。いかなる場合もノーマウント（覚えたての言葉）であるといいと思うのです。
setImageResourceでnullが出て頭を抱えたお話

フラグメントに未来少年コナンのパタパタアニメみたいに、ランダムなポーズのアニメをTimer関数で入れ替える。
これでActivity入れ替えてもずーっとヘッダーでキャラが踊り続けるアニメができるはずだったが・・・
val handler =Handler()
val picAry = arrayOf(R.drawable.pic0,R.drawable.pic2～～)
var rndNum:Int =Math.random *10
timer(name = "patapataTimer", period = 1000) {
handler.post{
anime.setImageResource(picAry[rndNum])
   }
}

だが、最初のActivityじゃ普通に動くのに、別のActivityに飛んだりするとすぐ落ちてしまう。

Runのメッセージをみると
java.lang.NullPointerException:
なんでーい、nullでるやんけー。もう少し読み進んでいくと
void android.widget.ImageView.setImageResource(int)
どうもactivityの切り替えタイミングとTimerのタイミングが悪いときイメージを拾い損ねてnullが出る模様。

で、思い出したのがこの人の投稿
https://qiita.com/TomiGie/items/0545e11e694eac7d88ec

var mp: MediaPlayer? = null

変数を宣言するときに一番後ろに"?"を入れ、null許容型にするというもの
Viewの後ろにも付けられるかな？と入れてみたら・・・

timer(name = "patapataTimer", period = 1000) {
handler.post{
anime?.setImageResource(picAry[picSuu])
   }
}
ＹＥＳ。これで見事 落ちなくなりました。
エンジニアスタンプラリー～フロントエンド編＃4

## 企画主旨
[Frontend Developer Roadmap](https://roadmap.sh/frontend)をひたすら巡回する企画 
詳しくは[こちら](https://qiita.com/tonchan1216/items/8d5f072cf769dfe1bc4f)

## 今回の実施内容
CSSプリプロセッサ
選択しが３つあるようだが、唯一黄色表示になっているSASSを選択。
ロードマップ作成者曰く、「今からLess始める、なんてことしたくないけどね。私なら。」とのこと。

## CSS Pre-processors

#### SASS
yarn経由でSassをインストール。便利ですねえ。

```
"scripts": {
    "watch-css": "sass --watch src/sass/main.scss styles/style.css",
},
```


公式サイト[Sass Basics](https://sass-lang.com/guide)に従って、シートを分割したり、階層構造にしたり、変数使ったりしてみた。
記法はSCSS記法を選択。なんかややこしい。

```scss:main.cscc
@import 'base';
$font-stack: "Open Sans", sans-serif;
$bg-color:#ffffd9;

body {
  width: 600px;
}

header {
  h1 {
    font-size: 40px;
    text-align: center;
    margin: 0;
    padding: 30px 0;
    color: #00539f;
    animation-name: fadeInTitle;
    animation-duration: 3s;
    animation-timing-function: ease-in;
  }

  nav {
    display: flex;
    justify-content: space-around;
    align-items: stretch;
  }

  h2 {
    flex: 1;
    text-align: center;
    background-color: $bg-color;
    margin: 0;
    padding: 20px 0;
  }

  h2:nth-child(2){
    background-color: white;
  }
}
```

## 成果物
デザインを少しだけアップデート。Sass使うと捗ることを実感。
https://tonchan1216.github.io/WDR-frontend/v4/
https://github.com/tonchan1216/WDR-frontend/tree/4.0
二分木の直列化（シリアライズ）と復元

## 概要
直列化（シリアライズ）とは、オブジェクトをバイト列に変換し、メモリやファイル上に保存しやすい状態にすることです。本記事では二分木のデータ構造を文字列にシリアライズし、さらにその文字列から二分木を復元する手法を紹介します。

## 方針
二分木の構造を文字列に変換するにはいくつかの方法が考えられますが、ここでは深さ優先探索(DFS)の先行順巡回(pre-order)の順に各ノードの値を羅列した文字列を生成することにします。

## 例
下記のような二分木をDFSのpre-orderで走査し、`1 2 null null 3 4 null null 5 null null`のような文字列を生成します。のちの復元（デシリアライズ）を容易に行うため、子ノードがnullの場合も明示的に文字列に含めている点に注意してください。

```
    1
   / \
  2   3
     / \
    4   5
```

## 実装例

```python
    def preorder(self, node, arr):
        if node is None:
            # ノードが空の場合もnullとして記録しておく
            arr.append('null')
        elif node is not None:
            arr.append(node.val)
            arr = self.preorder(node.left, arr)
            arr = self.preorder(node.right, arr)
        return arr

    def serialize(self, root):
        # 先行順巡回でリストを生成
        arr = self.preorder(root, [])
        # スペース区切りでリストを文字列化する
        return ' '.join(str(i) for i in arr)

    def deserialize(self, text):
        # 文字列からリストを生成
        arr = text.split()
        return self.rdeserialize(arr)

    # pre-orderの配列から二分木を生成するメソッド
    def rdeserialize(self, arr):
        if len(arr) == 0:
            return None
        if arr[0] == 'null':
            del arr[0]
            return None

        # pre-orderの先頭をrootとして取り出し、部分木を再帰的に生成する
        root = TreeNode(int(arr[0]))
        del arr[0]
        root.left = self.rdeserialize(arr)
        root.right = self.rdeserialize(arr)

        return root
```
R double arrow演算子で「global変数に代入的なこと」を行う

Rで`purrr::map` (または`apply`)で呼び出した関数内で、関数外で（グローバル変数的な意図で）定義した変数に値を代入しようとして若干はまりました。double arrow演算子を用いて解決しましたが、備忘録として残そうと思います。よくよく調べると永続代入ってことで基本的な文法なようですが、全く覚えていなかった＆調べ方が悪かったためすぐに正解にたどり着かなかった。。。

## うまく行かない例
mapを使って（名前付き）リストXに一気に値を代入しようとします。

```r
X <- list()
key <- c("A", "B", "C")

purrr::map(key,
           function(x){
             value <- stringr::str_c("val_", x)
             X[[x]] <- value
           })
```

```r
> print(X)
list()
```
map内の関数で普通の代入演算子(<-)を使って代入しても、Xに反映はされない。


# うまく行く例
```r
purrr::map(key,
           function(x){
             value <- stringr::str_c("val_", x)
             X[[x]] <<- value
           })
```
```r
> print(X)
$`A`
[1] "val_A"

$B
[1] "val_B"

$C
[1] "val_C"
```
doubleアロー演算子(<<-)を使えば反映される。

## 用途
複数のファイル群をディクショナリっぽい構造でデータフレームとして読み込んだり（これをやりたかった。普通にfor文を使っても良いのかもしれないですが）

```r
file_list <- c("A", "B", "C")
df <- list()

purrr::map(file_list,
           ~(df[[.]] <<- readr::read_csv(str_c(., ".csv")))
           )
```

map2を使ってkey(リストの名前)とvalue(リストの値)の変換とか

```r
X2 <- list()
purrr::map2(names(X), unlist(X),
           function(key, value){
             X2[[value]] <<- key
           })
```

## 参考
https://cran.r-project.org/doc/manuals/R-intro.html
10.5 Assignments within functions
データフレーム同士の列の中を比較して、一方にしかないない値を取得する

## 動作環境
python３
jupyter lab

関連リンクです。あなたは、「データフレーム同士のカラム名の差分、比較方法」について探していますか？↓
[データフレーム同士のカラム名の差分を取得・比較する方法](https://qiita.com/hatorijobs/items/3b199fb23cb60f8dbc72)

#データフレームの任意の１列に対して、ソート＆ユニークな要素を取得する
まずは、悪い例。飛ばして読んでもいいです。（失敗は成功の母）

```
import numpy as np
import pandas as pd

# サンプルとなるデータフレームを作成
df = pd.DataFrame({ 'A' : [1,2,3,4,5], 'B' : ["aaaa","cccc","dddd","bbbb","cccc"]})

#1列だけを取得したあと、ソートに失敗した悪い例
[in]
print(df['B'].sort_index())

[out]
0    aaaa
1    cccc
2    dddd
3    bbbb　　　←ソート出来ていない！！
4    cccc
Name: B, dtype: object

#↓このままソートできていないままunique()してしまうザコーダ
[in]
print(df['B'].sort_index().unique())

[out]
['aaaa' 'cccc' 'dddd' 'bbbb']　　　←だから、ソート出来てないってば！！

[in]
print("ファッ!?ユニークは出来てるけど、ソートできてないやんけー")

[out]
ファッ!?ユニークは出来てるけど、ソートできてないやんけー
```
以下、成功例。（追記、全体的に修正しました。コメントありがとうございます。）

```
#↓ソートの成功例
[in]
print(df['B'].sort_values())

[out]
0    aaaa
3    bbbb　　　　　　←ソートできてる
1    cccc
4    cccc
2    dddd
Name: B, dtype: object

#↓sort_valuesすると、pandas.core.series.Series型になってしまう
[in]
print(type(df['B'].sort_values()))

[out]
<class 'pandas.core.series.Series'>

#↓続いて、ソートした上で、ユニークなものだけにする
[in]
print(df['B'].sort_values().unique())

[out]
['aaaa' 'bbbb' 'cccc' 'dddd']


#↓unique()すると、numpy.ndarray型になってしまう
[in]
print(type(df['B'].sort_values().unique()))

[out]
<class 'numpy.ndarray'>
```
エラーがでるようなときは、type()で型を確認してコーディングしていきます。

# 【ここからが本題】　データフレーム同士の列の中を比較して、一方にしか存在しない値を確認する
上のやり方を基礎にして、本題を解決します。自分が表示したい内容は、sort_index() と unique()を使って以下のようにして出来ました。

```
# 比較するためのデータフレームを２つ作る
train = pd.DataFrame({ 'A' : [1,2,3,4,5], 'B' : ["aaaa","cccc","dddd","bbbb","fffff"]})
test  = pd.DataFrame({ 'A' : [1,2,3], 'B' : ["aaaa","dddd","cccc"]})

#↓ソートの正解例
[in]
print(train['B'].sort_values().unique())

[out]
['aaaa' 'bbbb' 'cccc' 'dddd' 'fffff']
               
#これができると、↓このように比較できる
[in]
print(train['B'].sort_values().unique())
print(test['B'].sort_values().unique())

[out]
['aaaa' 'bbbb' 'cccc' 'dddd' 'fffff']
['aaaa' 'cccc' 'dddd']
```
こうすれば、testデータは、trainデータと比べて、ddddとffffの値が存在しないことがわかりました。データが1000行あったりした場合に、ユニークな値の確認に使えます。
（なんか、もっと良い確認方法ありそうですねー、でも今はこれでいいや）

#あとがき
データの中身を確認する際などは、これで見やすくなると思います。
もっと見やすいやり方あったら、コメントください。
【gas】gmailの添付ファイルをドライブに保存、更新

## 1. はじめに

ご覧いただきありがとうございます。

今回は業務でメールのPDFを取り出しそのファイルを重複しないように
googleドライブに上げたいと考えgasを使用して実装してみました。

## 2. ソースコード

まずは完成品のソースコードをご覧ください。

```javascript
//定数
var SEARCH_TERM = 'subject:(○○○○) '; //検索条件（件名で検索の場合）
var FOLDER = DriveApp.getFolderById('○○○○'); //保存するフォルダ(Googledrive上のURL”folders/”以下)

//メイン（メールから添付ファイルを取得）
function fetchFile(){
  var myThreads = GmailApp.search(SEARCH_TERM, 0, 30); //条件にマッチしたスレッドを検索して取得(0~30件まで)
  var myMessages = GmailApp.getMessagesForThreads(myThreads); //スレッドからメールを取得し二次元配列で格納
  var attachments = myMessages[0][0].getAttachments(); //添付ファイルを取得
  
  Logger.log(myMessages[0][0].getSubject());  //取得メールの件名表示
  updateFile(attachments)  //ファイル置き換え
}

//フォルダの中に入ってるファイルの名前を取得
function getFileNames(){
  var files = FOLDER.getFiles();
  var fileNames = []
  var count = 0
  
  while (files.hasNext()) {
    fileNames[count] = files.next()
    count++
  }

  return fileNames
}

//フォルダにあるファイル名が添付ファイル名と同じとき更新
function updateFile(attachments){
  var fileNames = getFileNames()
  for(var i in attachments){
    for(var j in fileNames){
      //ドライブにすでに同じ名前のファイルがあるか？
      if(attachments[i].getName() == fileNames[j]){
        var files = DriveApp.getFilesByName(fileNames[j])
　　　　//重複ファイルを削除
        if (files.hasNext()) {
          var file = files.next()
          file.setTrashed(true)
          Logger.log(file.getName())  //削除したファイル名表示
        }
      }
    }
    FOLDER.createFile(attachments[i]) //ドライブに添付ファイルを保存
  }
}
```

## 3. コード解説・補足
ブロックごとに解説と補足説明していきます。

### 3-1. 定数
```var SEARCH_TERM = 'subject:(○○○○)';```
検索条件の設定です。
今回のプログラムでは欲しいPDFの添付されているメールは同じ件名で送られてくるため
件名で検索しています。
**'○○○○'**の部分は部分的な検索なので、例えば給料明細のお知らせが
「○○月の給与明細」という件名で送られてくる場合'subject:(月の給与明細)'と指定しておけば
きちんと取得できると思います。

```var FOLDER = DriveApp.getFolderById('○○○○');```
の**'○○○○'**の部分は保存したいフォルダを開いた状態のfolders/以下の文字列になります。

【参考画像】
<img width="374" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486705/b7f05116-424a-d349-84ad-a7c9b322ce16.png">

### 3-2. メイン
メインについて参考サイトのものを改変させて使っております。
改変したのはメールの読み出し部分で、参考サイトのものだと30件分の中に複数検索条件に
適合するメールがあった場合、複数読み込むことになっているのですが、今回は更新していきたいので、
最新のものだけ使用するように**myMessages[0][0]**と指定しています。

### 3-3. フォルダの中に入ってるファイルの名前を取得
ここについては名前通りなのですが、最初に指定したフォルダに入っている
ファイル名をすべて取得して返却します。

### 3-4. フォルダにあるファイル名が添付ファイル名と同じとき更新
3-3で取得したファイル名と添付ファイルのファイル名を比較して、
重複したファイルがある場合、そのファイルを削除して添付ファイルを保存します。

## 4. 参考文献
- [Google Apps ScriptでGmailの添付ファイルをGoogleドライブに保存する]
(https://tonari-it.com/gas-gmail-attachment-drive/)

- [GoogleAppsScriptでファイル一覧の取得(Googleドライブ)]
(http://www.googleappsscript.info/2017-07-27/drive_list_folder.html)

## 5. おわりに
本当は取得したPDFをエクセルに変換してgoogleドライブに保存までしたかったのですが、
PDFに書いてある表が相性が悪いのか変換の精度が悪く、PDFXchangeeditorで手動変換に
落ち着きました。
どなたかお詳しい方、何か知恵がありましたらコメントしていただけると嬉しいです！

最後に記事をお読みいただきありがとうございました。
[Git] Gitのmergeでvimdiffを利用する

# 目的

pullしたときにコンフリクトが発生したときなどvimdiffを利用してコンフリクトを解消する

# 手順

#### 1. 使いどころ

例えば以下のようにgit pullが失敗して手動でmergeする必要がでてきたときに利用します

```
$ git pull
～
Auto-merging aaa
CONFLICT (content): Merge conflict in aaa
Automatic merge failed; fix conflicts and then commit the result.
```

#### 2. vimdiffをmergeツールとして利用するよう設定する

以下のようにglobalコンフィグに入れておく

```
$ git config --global merge.tool vimdiff
$ git config --global merge.conflictstyle diff3
$ git config --global mergetool.prompt false
```

入力せずともgit mergetoolの中でmerge toolに何を使うかきかれるのでvimiffとしておけばよい。

#### 3. vimdiffを開く
    
```
$ git mergetool
```

このコマンドを入力すると以下のようなvimdiffの画面が開く

```
╔═══════╦══════╦════════╗
║ LOCAL ║ BASE ║ REMOTE ║
╠═══════╩══════╩════════╣
║                       ║
║        MERGED         ║
║                       ║
╚═══════════════════════╝
```

| ウィンドウ | 役割 |
| --- | --- |
| LOCAL | 現在のワーキングツリー上のファイル |
| BASE | 共通の先祖ファイル。変更前はどのようなファイルだったか |
| REMOTE | ワーキングツリーへマージしようとしているファイル |
| MERGED | 最終的にレポジトリの中で保存されるファイル |

#### 4. vimdiffの使い方

##### ウィンドウ間の移動

各ウィンドウ間は [ctrl]+w → hjklで移動できる(h:left, j:down, k:up, l:right)。
※hjklの代わりにカーソルでもOK

##### マージ方法

MERGEDウィンドウに移るとコンフリクト部分が色付きで表示されている

<<<<<<<<から>>>>>>>>の間がコンフリクト箇所

```
<<<<<<< HEAD
localfile
||||||| merged common ancestors
ancestor
=======
remotefile
>>>>>>> ap8990as3eipsaldjff669197e1sdkfasasdf1131d
```

コンフリクト箇所にカーソルを合わせたら、LOCAL,BASE,REMOTEどれを採用するかきめて以下のコマンドで反映させる。

| 採用対象 | 反映コマンド |
| --- | --- |
| LOCAL | :diffg L |
| BASE | :diffg B |
| REMOTE | :diffg R |
| その他 | 手動で編集 |

##### マージ処理の終了

編集が完了したらwindowを閉じる。
`:xa`で終了することで、MERGEDウィンドウの編集内容を保存しつつ全ウィンドウ一括で閉じることができる。
~~MERGEDウィンドウにカーソルがあたっているなら、:wで保存して、:qaで全ウィンドウ一括で閉じる。
(:wqaで一気に閉じることも可能だが、この場合LOCAL,BASE,REMOTEのファイルも全て保存され、レポジトリの中にuntrackedファイルが増えてしまう)~~

```
:xa
```
##### 作業中に発生したuntrackedファイルの削除

vimdiffでのmerge処理完了後、コンフリクトが発生していたローカルファイルは拡張子.orig付きの別名で保存されている。
これらvimdiffにより保存されたバックアップファイルはレポジトリには不要なのでgit cleanを利用し削除する。
※誤って新規作成したファイルを一緒に削除してしまわないよう注意が必要

```
$ git clean -n
$ git clean -f
```

git cleanはstagedされていないファイルを削除する。-n はドライランオプション。
もし、特定のファイルだけ削除したい場合はファイルパスを指定する。

```
$ git clean -n %untracked_file_path%
$ git clean -f %untracked_file_path%
```
bash使用時にインストールしたRuby(rbenv)のバージョンが、zsh導入後反映されない

## 何が起こったか
bashを使用していた時にインストールしたruby(rbenv)が、zsh導入後に反映されなかった。

### 環境

- MacBook Pro (13-inch, 2018)
- macOS Mojave 10.14.6
- Homebrew 2.1.11
- rbenv 1.1.2
- zsh 

## 試したこと
```
# rbenvでインストールしたバージョンの確認
$ rbenv versions
  system
* 2.6.3 (set by /Users/tatsuya/code/instant_tween/.ruby-version)

# システム全体で使用する
$ rbenv global 2.6.3

# 設定の更新
$ rbenv rehash

# バージョンの確認
$ ruby -v           
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
```

**バージョンが切り替わらない。。**


## 環境変数が適切に通ってないのが原因だった！
使用しているRubyの環境変数を確認。

```
$ which ruby
/usr/bin/ruby
```

これがrbenvだと、`/Users/ユーザー名/.rbenv/shims/ruby`が正しいらしいので、
.zshrc を編集。

```
$ vim ~/.zshrc
```

`eval "$(rbenv init -)"`
を.zshrcに追記する。

設定を更新

```
$ source .zshrc
```

最後に、Rubyのバージョンが変わっているか確認

```
$ which ruby        
/Users/ユーザー名/.rbenv/shims/ruby

$ ruby -v            
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

```

無事Rubyのバージョンが変わったので、設定終了！

## 参考にした記事

以下の記事を参考にさせていただきました。ありがとうございました。

[rbenv利用時にruby -vで古いバージョンのRubyが呼ばれる場合の対処](https://easyramble.com/rbenv-ruby-version-trouble.html)
Liferayのバッチの作成

#はじめに
定期的に実行するバッチ処理はシステムよくあります。
Javaのスケジューラのライブラリとしてquartzは有名です。
quartz：http://www.quartz-scheduler.org/

LiferayのスケジューラもQuaryzを採用しております。

Liferayの中でやり方を簡単にまとめます。

#QuartzのCron設定フォーマット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/922df8bc-8f18-a499-9bd1-be2ca4b9fbd0.png)

出典：http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html


#QuartzのCron設定サンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/618d3f7d-4123-ef80-7b94-d70d1b6066b8.png)

出典：http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html

#Liferayのバッチ実装必要なメソッド
- activate：OSGiモジュール起動処理
- deactivate：OSGiモジュール停止処理
- receive:ビジネスロジック

#サンプル
```TestBatch.java
package com.test.batch;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.messaging.MessageListenerException;
import com.liferay.portal.kernel.scheduler.SchedulerEngineHelper;
import com.liferay.portal.kernel.scheduler.SchedulerEntryImpl;
import com.liferay.portal.kernel.scheduler.TimeUnit;
import com.liferay.portal.kernel.scheduler.Trigger;
import com.liferay.portal.kernel.scheduler.TriggerFactoryUtil;

import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;

@Component(immediate = true, property = {
}, service =TestBatch.class)
public class TestBatch implements MessageListener {

	private static Log _log = LogFactoryUtil.getLog(TestBatch.class);

	// バッチ起動間隔
	private static int INTERVAL_TIME = 15;

	@Override
	public void receive(Message message) throws MessageListenerException {
		
		_log.info("バッチ 開始");
		
		// do something
		
		_log.info("バッチ 終了");
	}
	
	@Activate
	@Modified
	protected void activate() {
		String batchClassName = this.getClass().getName();
        // トリガーの設定
		Trigger trigger = TriggerFactoryUtil.createTrigger(batchClassName, batchClassName, INTERVAL_TIME, TimeUnit.MINUTE);
		SchedulerEntryImpl schedulerEntryImpl = new SchedulerEntryImpl(batchClassName, trigger);

		_schedulerEngineHelper.register(this, schedulerEntryImpl, DestinationNames.SCHEDULER_DISPATCH);

		_log.info("Batch is activated.");
	}

	@Deactivate
	protected void deactivate() {
		_schedulerEngineHelper.unregister(this);
	}

	@Reference(unbind = "-")
	private volatile SchedulerEngineHelper _schedulerEngineHelper;

}

```

#ポイントとなるトリガーの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/08885eac-ae6c-78f0-dcc1-234a9b52a471.png)
TriggerFactoryUtilクラスに用意されていますので、簡単に作成できます。


CronTrigger: http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
参考記事：https://portal.liferay.dev/docs/7-1/tutorials/-/knowledge_base/t/message-listeners

以上
Linux基礎(ファイルシステムのマウントとアンマウント)

#ファイルシステムのマウント
パーティションにファイルシステムを作成した後、<strong>マウント</strong>を行う必要がる。このマウントとは、パーティションとあるディレクトリを関連づけること。マウントしたファイルシステムが結合されるディレクトリが<strong>マウントポイント</strong>と呼ばれる。このマウントにより、そのパーティションにファイルやディレクトリを作成したり、利用することができるようになる。

- <strong>ファイルシステムのマウント</strong>

![スクリーンショット 2019-09-27 21.16.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374557/a5805e8b-4b7e-d642-a282-4f8d2af9e1f2.png)

恒常的なマウントを行うためには、以下の2つの作業を行う必要がある。

1. <strong>/etc/fstab</strong>ファイルの編集
2. <strong>mount</strong>コマンドの実行、または再起動(init6)の実行

※/etc/fstabファイルの編集を行わずにmountコマンドだけを実行した場合、再起動後に無効になる。

#/etc/fstabファイル
/etc/fstabファイルの書式は以下の通り。以下の書式例では、①はUUIDとして表示されているが、新たに追加する設定は、以下の書式の記述によりマウントすることは可能。

- <strong>/etc/fstabファイルの書式</strong>

![スクリーンショット 2019-09-27 21.41.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374557/e0b2c5d4-9a85-3af6-4dd9-2ed5b48670e3.png)

|項番|フィールド|設定内容|
|---|---|---|
|①|マウントするデバイスファイル名|マウントするデバイスファイル名またはボリュームラベルを指定|
|②|マウントポイント|マウントポイントとなるディレクトリの絶対パスを指定|
|③|ファイルシステムの種類|①のファイルシステムの指定。下表1を参照|
|④|マウントオプション|①のマウントオプション指定。※下表2を参照|
|⑤|dump|dumpコマンドによるバックアップ対象となるかどうかを指定<br>0：バックアップする必要がない<br>1：バックアップする必要がある|
|⑥|fsck|システム起動時にfsckコマンドでチェックを行う時の順序を指定<br>0：fsckコマンドでファイルシステムをチェックしない<br>1：ルートファイルシステム(/)に指定する数値<br>2以上：その他のファイルシステムに指定する数値|

- 表1- ファイルシステムの種類

|ファイルシステム|説明|
|---|---|
|ext2|Linuxの標準ファイルシステム|
|ext3|ext2の機能拡張版(現在の主流)|
|ext4|ext2の機能拡張版(現在の主流)|
|reiserfs|高速なジャーナリングファイルシステム|
|xfs|SGI開発によるジャーナリングファイルシステム|
|jfs|IBM開発によるジャーナリングファイルシステム|
|iso9660|CD-ROMのファイルシステム|
|msdos|MS-DOSのファイルシステム|

- 表2- マウントオプションの種類

|オプション|説明|
|---|---|
|async|ファイルシステムの入出力を非同期で実行|
|auto|mount -a コマンドの実行時にマウントする|
|noauto|mount -a コマンドの実行にマウントしない|
|defaults|デフォルトのオプションを設定(async, auto, dev, exec, nouser, rw, suid)|
|exec|バイナリの実行を許可|
|noexec|バイナリの実行を禁止|
|ro|読み取り専用モードでマウント|
|rw|読み書き可能モードでマウント|
|unhide|隠しファイルも表示|
|suid|SUIDとSGIDの有効化|
|user|一般ユーザーにマウントを許可する|
|users|一般ユーザーにマウントを許可し、マウントを実行していないユーザーにアンマウントを許可|
|nouser|一般ユーザーのマウントを許可しない|

#mountコマンド
/etc/fstabファイルの変更を行った後、<strong>mount</strong>コマンドを実行するか再起動(init 6)する必要がある。

mount [オプション] デバイス名

|オプション|説明|
|---|---|
|-a|/etc/fstabファイルに記述されているファイルシステムを全てマウント(noautoは除く)|
|-o|マウントオプションの指定|
|-t ファイルシステム|ファイルシステムの種類を指定|

```shell
# /dev/sda6のファイルシステムを、/home3ディレクトリにマウント
$ mount /dev/sda6 /home3
```

現在マウントされているファイルシステムをアンマウントするためには、<strong>unmount</strong>コマンドを使用する。

unmount [オプション] デバイス名/マウントポイント

|オプション|説明|
|---|---|
|-a|/etc/mtabファイルに記述されているファイルシステムを全てアンマウント|
|-t|引数に指定したファイルシステム形式のファイルシステムのみをアンマウント|

```shell
# /dev/sda6がマウントされている/home3ディレクトリをアンマウント
$ unmount /dev/sda6 /home3
```

※/etc/mtabファイルはmountコマンドやunmountコマンドがしようしているファイルであり、ユーザーが手動変更できないファイル。
SwiftでCの構造体をキャストしてUNIXドメインソケットを使う方法


SwiftでもCのシステムコールを呼ぶことができるのでうまく使えば、UNIXドメインソケットを使ったSwiftとCのライブラリ間のスレッド通信を行うことができる。

## Cでの操作方法

C言語でUNIXドメインソケットを使う場合にはsockaddr_un構造体をsockaddrにキャストしてbindやconnectに渡す必要がある。

``` C
int sock = socket(AF_UNIX, SOCK_STREAM, 0);

struct sockaddr_un addr;

strcpy(addr.sun_path, "/tmp/hogehoge");

addr.sun_family = AF_UNIX;

bind(sock, (struct sockaddr *)&addr, sizeof(addr));
```

## Swiftでの操作方法

Swiftで同様にキャストを行なう必要があるが、```let sockAddrUn = sockAddr as sockaddr_un```のようなキャストはできない。
Swiftの場合は、

**sockaddr_un構造体　→　UnsafeRawPointer化　→　assumingMemoryBoundを使ってsockaddr構造体に変換** 

のようなステップを踏む必要がある。

具体的には、次のように書く

``` Swift
let sock = socket(AF_UNIX, SOCK_STREAM, 0)

let sockPath = "/tmp/hogehoge"

var sockAddrUn = sockaddr_un()
sockAddrUn.sun_family = sa_family_t(AF_UNIX)
sockPath.withCString { path in
    Darwin.memcpy(&(sockAddrUn.sun_path), path, Int(strlen(path)))
}

let rawPtr = UnsafeRawPointer(&sockAddrUn)
let sockAddrPtr = rawPtr.assumingMemoryBound(to: sockaddr.self)

Darwin.bind(sock, sockAddrPtr, socklen_t(MemoryLayout<sockaddr_un>.stride))
```

## こんな書き方は絶対ダメ

因みに最初に構造体のキャスト方法がわからず変数を二つ用意してmemcpyをするという荒技を行なっていた。

``` Swift
let sock = socket(AF_UNIX, SOCK_STREAM, 0)

let sockPath = "/tmp/hogehoge"

var sockAddrUn = sockaddr_un()
sockAddrUn.sun_family = sa_family_t(AF_UNIX)
sockPath.withCString { path in
    Darwin.memcpy(&(sockAddrUn.sun_path), path, Int(strlen(path)))
}

var sockAddr = sockaddr()
Darwin.memcpy(&sockAddr, &sockAddrUn, MemoryLayout<sockaddr_un>.stride)

Darwin.bind(sock, &sockAddr, socklen_t(MemoryLayout<sockaddr_un>.stride))
```

sockaddr_unの分だけコピーしてbindにsockaddr_unの長さを渡すのでビルドは通るし、動きはするがReleaseビルドで最適化設定がされるとsockaddrからはみ出た分のデータが消えてしまい、bindがEAFNOSUPPORTエラーを返すようになる。

A構造体　→ UnsafeRawPointer → assumingMemoryBoundでB構造体　でキャストするようにしましょう。
【powershell】正規表現にマッチした箇所を色付きで強調表示する

## 2020/05/03 更新
[ANSI エスケープシークエンスを使う方法](https://qiita.com/AWtnb/items/d61df5df70d242faa441) でもっとシンプルに実装できました。

## 作ったもの

![202004292000501.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501098/00ff61cc-9da6-e8ab-47b5-7e86524b0d35.png)
コンソールエミュレータは [Cmder](https://cmder.net) が好きです。

## 環境
```
PS > $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.18362.145
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.145
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
```

## コード
```powershell
function Write-StringHighlight {
    <#
    .SYNOPSIS
    文字列内の指定箇所を強調表示する
    ・パイプライン経由での入力にのみ対応
    .PARAMETER pattern
    検索パターン
    .PARAMETER case
    指定時は大文字小文字を区別
    .PARAMETER color
    強調箇所の色
    .PARAMETER plainColor
    強調しない箇所の色
    .PARAMETER continuous
    指定時は出力後に改行しない
    #>
    param (
        [string]$pattern = ".",
        [switch]$case,
        [ValidateSet("White", "Black", "Blue", "DarkBlue", "Green", "DarkGreen", "Cyan", "DarkCyan", "Red", "DarkRed", "Magenta", "DarkMagenta", "Yellow", "DarkYellow", "Gray", "DarkGray")][string]$color = "Yellow",
        [ValidateSet("White", "Black", "Blue", "DarkBlue", "Green", "DarkGreen", "Cyan", "DarkCyan", "Red", "DarkRed", "Magenta", "DarkMagenta", "Yellow", "DarkYellow", "Gray", "DarkGray")][string]$plainColor = "Gray",
        [switch]$continuous
    )

    $capture = "(?<pre>.*?)(?<main>{0})(?<post>.*)" -f $pattern
    if ($case) {
        $r = [regex]$capture
    }
    else {
        $r = [regex]"(?i)$capture"
    }

    $loopFlag = $true
    if ($pattern.Substring(0,1) -eq "^") {
        $loopFlag = $false
    }

    foreach ($i in $input) {
        Do {
            if (-not $r.IsMatch($i)) {
                break
            }
            $m = $r.Matches($i)
            Write-Host $m[0].Groups["pre"].Value -ForegroundColor $plainColor -NoNewline
            Write-Host $m[0].Groups["main"].Value -ForegroundColor Black -BackgroundColor $color -NoNewline
            $i = $m[0].Groups["post"].Value
        } while ($loopFlag)
        Write-Host $i -ForegroundColor $plainColor -NoNewline:$continuous
    }
}

# Alias
Set-Alias "hilight" Write-StringHighLight
```

個人的には `$profile` に書いておいて各種コマンドレット内で使いまわしています。

## 仕組み
自動変数 `$input` でパイプラインからの入力を受け取って各要素を処理しています。
アルゴリズムというほどでもありませんが、正規表現の名前付きキャプチャ（[参考記事](https://qiita.com/jnchito/items/cceb669cb06fc044f411)）で文字列をマッチ箇所とその前後に分割し、ループを繰り返しながら後方へとマッチ箇所を探索します。事前に `^` の有無を判定しているのはループのたびに先頭部分にマッチしてしまうからです。

`Write-Host` による出力ですので、パイプ処理の途中でのフィルタ的な使い方はできません。あくまで検索結果を視覚的に確認するために作成したコマンドレットです。

<font color="SlateGray">エイリアスの _hilight_ は [秀丸エディタ](https://hide.maruo.co.jp/software/hidemaru.html) の設定リスペクトです。</font>
IX2106の設定1

# はじめに
転職して通信系の会社に入ったので、実用と勉強を兼ねてノリと勢いでIX2106を購入した。
備忘録で色々残していく。
手探りなのでプロからの指摘があると嬉しい。

# ルータの起動と接続
USBシリアルコンバータを購入して、`ルーター⇔付属コンソールケーブル⇔コンバータ⇔PC`のように接続！
※USB⇔RS-232C変換ケーブルは、Prolific社のPL2303が使われているものは避けたほうがよいかも。
　できなくはないけど面倒らしい。win以外でも面倒かは不明。
　[Windows10でPL2303を無理やり動かす](https://ehbtj.com/info/pl2303-windows10/)


電源ケーブルを指してスイッチオン！

TeraTermをインストールして、図のように、シリアル接続を選択して「OK」！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226319/3cac3672-9e71-ed6a-ddc9-ced4603fdf7e.png)

# 初期コンフィグの削除手順

### 1.コンフィグレーションモードで「erase startup-config」コマンドを実行し、スタートアップコンフィグを削除。

```
Router# enable-config [Enter]
Router(config)# erase startup-config [Enter]
Are you sure you want to erase the startup-configuration? (Yes or [No]): y [Enter]
Router(config)#
```

### 2.オペレーションモードに戻り、「default-console command-line」コマンドを実行。

```
Router(config)# exit [Enter]
Router# default-console command-line [Enter]
Router#
```

### 3.本装置を再起動

```
Router# reload [Enter]
% Warning: current running-configuration is not saved yet.
Notice: The router will be RELOADED. This is to ensure that
        the peripheral devices are properly initialized.
Are you sure you want to reload the router? (Yes or [No]): y [Enter]
```
### Appendix1.初期コンフィグの内容

```
timezone +09 00
logging buffered 131072
logging subsystem all warn
logging timestamp datetime
ip ufs-cache enable
ip dhcp enable
ip access-list web-http-acl permit ip src any dest 192.168.1.254/32
http-server ip access-list web-http-acl
http-server ip enable
ip dhcp profile web-dhcp-gigaethernet1.0
  dns-server 192.168.1.254
device GigaEthernet0
device GigaEthernet1
interface GigaEthernet0.0
  no ip address
  shutdown
interface GigaEthernet1.0
  ip address 192.168.1.254/24
  ip dhcp binding web-dhcp-gigaethernet1.0
  no shutdown
interface Loopback0.0
  no ip address
interface Null0.0
  no ip address
web-console system information
  o lan1 GigaEthernet1.0
```

### 4.基本設定
※追記_2019/10/07
PPPoE、DHCP、おまじないなど諸々設定する。（PPPoEは動いてない。。。）
※追記_2020/04/26
auひかりはPPPoEで認証しておらず、貸し出されるHGWのMacアドレス+特殊なパケットで認証してるらしい。
独自のルータで直接つなぐことはできない。。

```
!
hostname XXXX
timezone +09 00
!
username XXXX password hash XXXX administrator
!
!
ip ufs-cache enable
ip route default GigaEthernet0.1
ip dhcp enable
!
proxy-dns ip enable
!
telnet-server ip enable
!
http-server ip enable
!
ppp profile ppp_profile
  authentication myname XXXX
  authentication password XXXX password-1
!
ip dhcp profile dhcp_profile1
  assignable-range 192.168.100.10 192.168.100.20
  default-gateway 192.168.100.254
  dns-server 192.168.100.254
!
device GigaEthernet0
!
device GigaEthernet1
!
interface GigaEthernet0.0
  no ip address
  no shutdown
!
interface GigaEthernet1.0
  ip address 192.168.100.254/24
  ip dhcp binding dhcp_profile1
  no shutdown
!
interface GigaEthernet0.1
  encapsulation pppoe
  auto-connect
  ppp binding ppp_profile
  ip address ipcp
  ip tcp adjust-mss auto
  ip napt enable
  no shutdown
!
interface Loopback0.0
  no ip address
!
interface Null0.0
  no ip address
```


# 参考
[NEC：「UNIVERGE IX2105、IX2106、IX2207」初期コンフィグの削除手順](https://jpn.nec.com/univerge/ix/Info/default-console.html)
Sileo対応のリポジトリ作成方法

# Sileoのリポジトリ作成方法

はじめまして、Sugiutaと言います。今回初投稿させていただく内容ですが、JailbreakされたiPhone向けのTweakを配布するためのリポジトリ作成方法を解説させていただきます。

## はじめに

今回はgithubでリポジトリを作成していきたいと思います。githubにて○○.github.io (○○は自分の名前等)というリポジトリを作成してください。この形で作成しないとSileoやCydiaに反映されないので注意してください。

## 開発環境

- iOS端末(JailBreak済み)
- MacBook M1
- Githubリポジトリ

## リポジトリ作成方法

リポジトリを作成するにおいて必要なファイルが6つあるので紹介させていただきます。

### Release

1つ目はReleaseというファイルです。ここにはリポジトリの情報を書いていきます。書き方としては以下をご参照ください。

```text:Release
Origin: // リポジトリ名
Label: // 開発者名
Suite: stable
Version: 1.0
Codename: // 開発者名(別名称)
Architectures: iphoneos-arm iphoneos-arm64
Components: main
Description: // リポジトリ情報
```

### CydiaIcon.png

2つ目はCydiaIcon.pngです。こちらはリポジトリ欄に表示するアイコン画像の事です。正方形の画像を使用してください。

### deb(Packages.gz等)

残りの3つですが、ここからはターミナルを使ってファイルを作成していきます。

```shell:Packages
cd /var/mobile/Repo
dpkg-scanpackages -m ./debs > Packages
bzip2 Packages
```

以上の動作を問題なく行うと2つのファイルが作成されているはずです。(Packages,Packages.bz2)

## githubリポジトリに入れる。

以上の動作を行うと5つのファイル(フォルダ)が出来上がるはずです。

- Release
- CydiaIcon.png
- debs(フォルダ)
- Packages
- Packages.bz2

この出来上がった5つをgithubリポジトリに入れてみましょう。以上でリポジトリの作成は完了です。Sileo,Cydiaに登録してみてください。

## まとめ

これでリポジトリを作成することはできたと思います。一応例として僕のリポジトリを置いておくので参考にしてみてください。

https://github.com/sugiuta/repo/
メモ「Automate the Boring stuff -chapter3 Functions」

#def Statements with Parameters
**Deduplication makes your programs shorter, easier to read, and easier to update.**

```
import random
 def getAnswer(answerNumber):
     if answerNumber == 1:
           return 'It is certain'
       elif answerNumber == 2:
           return 'It is decidedly so'
       elif answerNumber == 3:
           return 'Yes'
       elif answerNumber == 4:
           return 'Reply hazy try again'
       elif answerNumber == 5:
           return 'Ask again later'
       elif answerNumber == 6:
           return 'Concentrate and ask again'
       elif answerNumber == 7:
           return 'My reply is no'
       elif answerNumber == 8:
           return 'Outlook not so good'
       elif answerNumber == 9:
           return 'Very doubtful'

r = random.randint(1, 9)
fortune = getAnswer(r)
print(fortune)

Note that since you can pass return values as an argument to another function call, you could shorten these three lines:

r = random.randint(1, 9)
fortune = get answer(r)
print(fortune)

to this single equivalent line:

print(getAnswer(random.randint(1, 9)))
```

##The None Value

##Keyword Arguments and print()

#Local and Global Scope

I learned how local and global scope is different and could imagine how return function can be used.

**A variable that exists in a local scope is called a local variable, while a variable that exists in the global scope is called a global variable.**

`Local Variables Cannot Be Used in the Global Scope`

`Local Scopes Cannot Use Variables in Other Local Scopes`

`Global Variables Can Be Read from a Local Scope`

`Local and Global Variables with the Same Name`

`The global Statement`

#Exception Handling

#A Short Program: Guess the Number

```
# This is a guess the number game.
import random
secretNumber = random.randint(1, 20)
print('I am thinking of a number between 1 and 20.')

# Ask the player to guess 6 times.
for guessesTaken in range(1, 7):
    print('Take a guess.')
    guess = int(input())

    if guess < secretNumber:
        print('Your guess is too low.')
    elif guess > secretNumber:
        print('Your guess is too high.')
    else:
        break    # This condition is the correct guess!

if guess == secretNumber:
    print('Good job! You guessed my number in ' + str(guessesTaken) + ' guesses!')
else:
    print('Nope. The number I was thinking of was ' + str(secretNumber))
```

#Short Practice: the Collatz Sequence

```
'''
If number is even, then collatz() should print number // 2 and return this value.
If number is odd, then collatz() should print and return 3 * number + 1.
'''
def collatz(number):
    if number % 2 == 0:
        return number // 2
    elif number % 2 == 1:
        return 3 * number + 1
'''
Lets the user type in an integer and that keeps calling collatz() on that number 
until the function returns the value 1. 
'''
print('Enter number:')
try:
    info = int(input())
    while info != 1:
        info = collatz(info)
        print(info)
except ValueError:
    print('You must enter integer')
```
WSL2までの道のり

#WSL2をインストールまでの道のり
WSL2は、
- 通常のWSL1をインストール
- Hyper-Vの設定
- windows insider programに登録しウインドウズのアップデート、
と地味に時間がかかる

#wslのインストール
wsl2のインストールが目標なので
powershellで下の2文を入れていく

```
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```

再起動をする。

Microsoft Store を開き、好きなLinux ディストリビューションを選ぶ
![2019-09-27 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453473/1168f4bf-473c-dd4d-eb9f-3c649c3fe555.png)

今回は Ubuntu-18.04 を入れた
これでwslは起動する、次はwsl2だ

#Hyper-V
windows 10 homeはそもそもHyper-Vを使えない、残念、でもhomeでも使えるようになるかも？

###Hyper-Vを使えるか状態を確かめよう
コマンドプロンプト(cmd)にsysteminfoと打ち込む

```
ホスト名:　～～～
OS名: ～～～

～～～なんやらかんやら

Hyper-V の要件:         VM モニター モード拡張機能: はい
                        ファームウェアで仮想化が有効になっています: いいえ
                        第 2 レベルのアドレス変換: はい
                        データ実行防止が使用できます: はい
```

となっているとwindowsの設定とBIOS設定をいじらねばならない

```

Hyper-V の要件:         ハイパーバイザーが検出されました。Hyper-V に必要な機能は表示されません。
```
となっている場合は何もしなくてよい

###Hyper-Vの有効化ーーwindows側


windowsのスタートボタンの横にいる「ここに入力して検索」さんに"OptionalFeatures.exe"と打ち
”windowsの機能”を開ける
そこのHyper-Vのチェックボックスにチェックする

![2019-09-27 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453473/05697243-ad9a-a7bd-079f-96b55eb0df83.png)


###Hyper-Vの有効化ーーBIOS側
ｐｃを再起動させＢＩＯＳ画面に入る、マザーボードのメーカーにより入るときに押すキーが違う
ASUSはdeleteキー
ASUSではCPU設定から Intel Virtualization Technologyを有効にすればよい、どこも同じ感じでしょうきっと

これでHyper-Vはおわり


#windows insider programに登録
windows insider programに登録しないとwsl2が動くwindowsのバージョンwindows insider previewがもらえない
[windows insider program](https://insider.windows.com/ja-jp/)
登録し、設定の更新とセキュリティにwindows insider programタブがある、それらを言われたままこなす。
そうするとwindows update にwindows insider　previewに更新できますよ、と言われる
更新ーーーーーーーーー
長い

#WSL →WSL2
WSLをWSL2にする

```
wsl --set-version {Distro} 2
```

{Distro}をWSLのディストリビューションの名前にする。
例えば

```
wsl --set-version Ubuntu-18.04 2
```
とする。
WSLの名前が知りたいときは  

```
wsl -l -v
```


これでWSL2が使えるようになる。

#確認
さっきと同じように

```
wsl -l -v
```
と打つと


![2019-09-27 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453473/fd610922-124a-4c16-8aa3-eec42a99e457.png)

となれば成功

##参考
[Hyper-Vで仮想マシンをたてるまでの手順](https://qiita.com/Kobecow/items/3e20fd5a195dfff39606)
[Windows 10 用 windows Subsystem for Linux インストールガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)
[WSL 2 のインストール手順](https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-install)
[MobaXtermを使いBash On Windowsで簡単にX11を使う](https://qiita.com/nullsnet/items/716c40fba707c3aafc1a)
浮動小数点演算の罠

# 浮動小数点
浮動小数演算には様々な罠があります
その中でも特徴的な罠として結合法則が成り立たないというものがあります
つまり、浮動小数点演算においては

```math
(a+b)+c \neq a+(b+c)
```

です。
これは、大きな値と小さな値を足す時に顕著で、小さな値の情報が落ちてしまいます。
簡単な例でコレを実感してみましょう

## バーゼル問題
```math
\sum_{n=1}^{\infty} \frac{1}{n^2}=\frac{\pi^2}{6}
```

これはバーゼル問題と呼ばれる有名な問題で、オイラーによって解かれました。
個人的には三角波のフーリエ展開を用いて計算する手法が一番わかり易い気がします。

## バーゼル問題の計算
この無限和を有限で打ち切って計算して円周率を計算してみることにします。
どれくらいの速度で収束するのでしょうか？
足していく値が$\mathcal{O}(n^{-2})$であるので、直感的には$\mathcal{O}(n^{-1})$ぐらいで真の値に収束する気がします。（少し手を動かすと証明も出来ます。）
つまり$n$まで計算すれば$\frac{1}{n}$ぐらいの精度で計算できるわけです。
では実際にコレを用いて単精度浮動少数で円周率を計算してみましょう
Haskellでちょろっと書いてみると

```Haskell
Prelude> (\t->sqrt(t*6))$ foldr (+) 0.0 (take 10000000 (map(\x->1/x/x) [1..]))::Float
3.1415925
```

ちゃんと円周率が計算できたようです。ではfoldrをfoldlに変えてみます。

```Haskell
Prelude> (\t->sqrt(t*6))$ foldl (+) 0.0 (take 10000000 (map(\x->1/x/x) [1..]))::Float
3.1413934
```

大幅に精度が落ちてしまいました。$10^7$まで足したのに、$10^4$ぐらいの誤差が出ています。わざわざ計算コストをかけて計算したのに非常にもったいない！

## 積み残し誤差

なぜこのような差が生まれてしまったのでしょうか？
foldrは右から、foldlは左からリストを足し合わせる関数です。
foldlは大きな数字から足し合わせ、foldrは小さな数字から足し合わせることになります。
つまり、foldlでは小さな数字を大きな数字に順次足し合わせることになります。すると小さな数字の情報が次々と欠落してしまい、大きな誤差が生じてしまうのです。
これを積み残し誤差と呼び、同じくらいのスケールの数が足されるように足す順番を工夫することが一般に必要です。

## おわりに
浮動小数点演算にはこの他にも様々な罠があります。浮動小数を扱うときはこういった罠に気をつけていきましょう！