OmniAICreator/Qiita-1.07M huggingface dataset:
文字列探索アルゴリズム

#文字列から文字列パターンを探したい。

みなさん、文字列から文字列パターンが存在するかどうかを探したい時ってありますよね。
そんな時にぴったりな３つのアルゴリズムを実装しました。

解説は時間に余裕ができたら追記します。

#まずは、ランダムな文字列を生成するプログラム

```python
import random

def random_str(x, char_list):
    return "".join([random.choice(char_list) for _ in range(x)])

if __name__ == "__main__":
    print(random_str(10, ["a","b","c","d"]))
```


ではここから三つの文字列探索アルゴリズムを紹介します。
#ブルートフォース（ゴリ押し）

``` python
from make_random_str import random_str

string = random_str(10000,["A","B","C","D","E"])

def brute_forth(string, pattern):
    i = 0
    j = 0
    lp = len(pattern)
    ls = len(string)
    ans = []
    while i <= ls-1:
        if string[i] == pattern[j]:
            if j == lp-1:
                ans.append(i-lp+1)
                i +=1
                j = 0
            else:
                i += 1
                j += 1
        else:
            i = i-j+1
            j = 0
    if not ans:
        ans = -1
    return ans

print(brute_forth(string,"ABCDE"))

#以下、正規表現を用いてbrute_forthアルゴが正しい出力を出しているかどうかを確認
import re

L =[]
check = re.finditer(r"ABCDE", string)
for i in check:
    L.append(i.span()[0])
print(L)
```

#KMP法

```python
from make_random_str import random_str

string = random_str(1000000, ["A","B","C","D","E"])

def kmp(string, pattern):
    #最初にいくつずらせば良いかのテーブルをpatternから作成する
    table = [0] * len(pattern)
    j = 0
    for i in range(1, len(pattern)):
        if pattern[i] == pattern[j]:
            table[i] = j
            j += 1
        else:
            j = 0

    ans = []
    s = 0
    t = 0
    while s < len(string):
        if string[s] == pattern[t]:
            if t == len(pattern)-1:
                ans.append(s-t)
                s += 1
                t = 0
            else:
                s += 1
                t += 1
        elif t == 0:
            s += 1
        else:
            t = table[j]
    return ans


print(kmp(string, "ABCEABC"))

#以下、正規表現を用いてbrute_forthアルゴが正しい出力を出しているかどうかを確認
import re

L =[]
check = re.finditer(r"ABCEABC", string)
for i in check:
    L.append(i.span()[0])
print(L)
```

#BM法

```python

from make_random_str import random_str

string = random_str(10000,["A","B","C","D","E"])

def bm(string,pattern):

    lp = len(pattern)
    ls = len(string)

    # 最初にtableを作成する
    #asciiを使うので長さ256のtableを用意
    table = [lp for _ in range(256)]
    for i in range(lp):
        table[ord(pattern[i])] = lp-i-1

    ans = []
    i = lp - 1
    while i < ls:
        j = lp - 1
        while string[i] == pattern[j]:
            if j == 0:
                ans.append(i)
            i -=1
            j -=1
        #maxを取ることを忘れない
        i = i + max(table[ord(string[i])], lp-j)
    if not ans:
        return -1
    return ans

print(bm(string, "ABCDE"))

#以下、正規表現を用いてbrute_forthアルゴが正しい出力を出しているかどうかを確認
import re

L =[]
check = re.finditer(r"ABCDE", string)
for i in check:
    L.append(i.span()[0])
print(L)
```
Re-ducksパターンのSelectorで引数を使う

# 概要

React ReduxのRe-ducksパターンにおいて、Selectorで引数を使う方法です。
サンプルとか見てても引数を使わない簡単な方法での実装例が多く、少し戸惑ったので書いていこうと思います。

どんな時に使うかというと、API等から直接データをStoreに入れてデータを扱いたい場合などに使えるかなと思います。

Selectorでは `reselect`を使う前提で書いていきます。

# 方法
## 毎回 createSelectorする方法
`createSelector`を関数の中に内包して、毎回発行する方法です。
以下のように、`createSelector`で作成したインスタンスを`return`する関数を作ります。

簡単にできますが、毎回createSelectorを呼び出して関数を作成しているので、パフォーマンスが悪そうな感じがします。

```js:reducks/subjects/selectors.js
import { createSelector } from "reselect";

export const getChildSubject = (state, subjectName) => {
  return createSelector(
    (state) => state.subjects,
    (subjects) => {
      if (subjectName in subjects) {
        return subjects[subjectName].value;
      }
    }
  )(state);
}
```

```jsx:components/sample.jsx
import React from 'react';
import { useDispatch, useSelector } from "react-redux";
import { getChildSubject } from "../../reducks/subjects/operations";

const Sample = (props) => {
  const dispatch = useDispatch();
  const selector = useSelector(state => state);

  const childValue = getChildSubject(selector, "subjectName");

  return (
    <div>{childValue}</div>
  )
};

export default Sample;
```

## Memoizeを使用する方法
`lodash.memoize`モジュールを使用することで、引数を`createSelector`内で使用できるようになります。
reselectの利用方法に沿った形になるため、こちらの方が安全にしようできるかなという印象です。

`createSelector`内で`memoize`関数内にfunctionで記述します。
引数は複数設定しても問題ありません。

```console
yarn add lodash.memoize
```

```js:reducks/subjects/selectors.js
import { createSelector } from "reselect";
import memoize from 'lodash.memoize';

export const getChildSubject = createSelector(
  (state) => state.subjects,
  (subjects) => memoize((subjectName) => {
    if (subjectName in subjects) {
      return subjects[subjectName].value;
    }
  })
);
```


```jsx:components/sample.jsx
import React from 'react';
import { useDispatch, useSelector } from "react-redux";
import { getChildSubject } from "../../reducks/subjects/operations";

const Sample = (props) => {
  const dispatch = useDispatch();
  const selector = useSelector(state => state);

  const childSubjectSelector = getChildSubject(selector);
  const childValue = childSubjectSelector("subjectName");

  return (
    <div>{childValue}</div>
  )
};

export default Sample;
```

# 参考
* [GitHub - reduxjs/reselect (Q: How do I create a selector that takes an argument?)](https://github.com/reduxjs/reselect#q-how-do-i-create-a-selector-that-takes-an-argument)
Protégé Desktop (for windows) の文字サイズを大きくする方法。

オントロジーをもう少し触るべく、Protégéをインストールしたのですが、「文字が小さすぎて読めない！（バサバサッ、ハズキルーペ風）」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18010/84d774d6-e924-f50d-00c3-4513e2dac9c8.png)
ということで、設定に手間取ったので、メモ的な記録です。

検索したら、githubに同僚の Melissaが教えてくれたんだぜ by natancox 、みたいな[投稿](https://github.com/protegeproject/protege/issues/752)を見つけたので、そちらをもとにトライ。

>I fixed the issue thanks to my colleague Melissa:
>Find java.exe you installed.

>1. Right click -> Properties
>2. Go to Compatibility tab
>3. Check Override high DPI scaling behavior.
>4. Choose System for "Scaling performed by"

あれ、そのままだ、ということで試行錯誤しているうちに、java.exeならできないが、javaw.exeなら直せることを発見。
まず、インストールフォルダ>jre>binからjavaw.exeをみつけ、右クリック→プロパティをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18010/fd8d0807-82d7-4af4-2585-cb18750c1d3b.png)
互換性タブを選び、「高DPI設定の変更」をクリック。システム（拡張）を選び、OK、OKで閉じる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18010/9bff1054-7a17-aeee-2228-62143c8de7d3.png)
Protégé を再度起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18010/dd860990-b381-defd-1766-1e4775a4a696.png)

「読める、読めるぞぉ！！」こんなことでオントロジー構築をあきらめてはならぬぞぉ。（困っている人の声あまり聞かないから、もしかしたらMac Userが多いのかという気もしている。）ありがとう、Melissa,natacox！ありがとう、ハズキルーペ（関係ない）！！
ProtégéをWindowsで使いたい人の助けになれば！と思います！！
openFrameworksからTelloドローンを操縦する


##はじめに

以前から[ProcessingやmicrobitなどからTelloドローンを操作する](https://qiita.com/kikpond15/items/d7d6c21221e4dfb93474)実験をやってきました．
今回はopenFrameworksからTelloを操縦したいと思います．

##アドオンを作ってみた([ofxTello](https://github.com/kikpond15/ofxTello))
Processingの時と同様にUDP通信でコマンドを送って操縦するのですが，毎回コマンドを全て実装するのがめんどくさかったので，コマンドを簡単に実装できるようにaddonを作りました．
addonを作るのが初めてだったのであまり良い設計とは言えませんがとりあえず簡単に使えるようにはなっています．

[ofxTello](https://github.com/kikpond15/ofxTello)
###ofxTello使い方
まずは[ofxTello](https://github.com/kikpond15/ofxTello)を自身のoF環境のaddonsにクローンしてきます．
次にProjectGeneratorでプロジェクトを作成する際に，クローンしてきたofxTelloとofxNetworkをアドオンに追加します．
![スクリーンショット 2020-08-15 17.04.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191122/8a002021-99a1-5344-4111-0ecb111455e7.png)

###コード
プログラムを実行する前に，TelloのWiFiに接続しておいてください．


```c++:ofApp.hpp
#pragma once
#include "ofMain.h"
#include "ofxTello.h"

class ofApp : public ofBaseApp{
	public:
		void setup();
		void update();
		void draw();
        void exit();
		void keyPressed(int key);

    ofxTello tello;
    int distance, angle, speed;
};

```


```c++:ofApp.cpp
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
    distance = 50;
    angle = 45;
    speed = 50;
    tello.connect();
}
//--------------------------------------------------------------
void ofApp::update(){
    tello.receiveUpdate();
    if(tello.getReceiveMessage().length() > 0){
        cout << tello.getReceiveMessage() << endl;
    }
}
//--------------------------------------------------------------
void ofApp::draw(){
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    if(key == 't'){
        tello.takeoff();
    } else if(key == 'l'){
        tello.land();
    } else if(key == 'w'){
        tello.foward(distance);
    } else if(key == 's'){
        tello.back(distance);
    } else if(key == 'a'){
        tello.left(distance);
    } else if(key == 'd'){
        tello.right(distance);
    } else if(key == OF_KEY_UP){
        tello.up(distance);
    } else if(key == OF_KEY_DOWN){
        tello.down(distance);
    } else if(key == OF_KEY_RIGHT){
        tello.cw(angle);
    } else if(key == OF_KEY_LEFT){
        tello.ccw(angle);
    }
}
//--------------------------------------------------------------
void ofApp::exit(){
    tello.close();
}
```
コマンド送信時にTelloからの返信をtello.receiveUpdate()で常に受け取る感じです．
ストリーミング機能はopencvを使った方法で実装出来そうですが，今のところこのアドオンには実装していません．


使いづらい点，わかりづらい点などありましたら，コメントでよろしくお願いします．
Cmder上のvimでcolorschemeをmolokaiに変更した。

## 背景

Windowsのコンソールが使いにくかったのでCmderを使い始めたもののCmderの設定とvimの設定が切り分けられないのが嫌で調べてみた。自前の`.vimrc`で設定しても反映されない。

具体的に言うと、カラースキームをmolokaiにしたかったんだけど、明日には忘れている自信があるので忘備録として。

## 1. molokai.vimのダウンロードと配置

[Molokai Color Scheme for Vim](https://github.com/ueaner/molokai)からダウンロード。

cmderとは別にvimを持ってる場合は`%HOME%`あたりに`.vim`ディレクトリがあるので、中に`colors`ディレクトリを作成して以下のようにダウンロードしたカラースキームファイルを配置。

なかったら`%HOME%`に`.vim`ディレクトリから作るか、任意の場所に作成してvimrcで`runtimepath`の指定すればOK。前者であればパスの指定なしで読み込まれるはず。

```
%HOME%/.vim/colors/molokai.vim
```



## 2. vimrcの場所を確認、編集

`vimrc`を開く。これは`.vim`下にあるものでなく、Cmderの下にあるやつ。

```
vim <path-to-cmder>\vender\git-for-windows\etc\vimrc
```

`<path-to-cmder>`はCmderへのパスなので人による。`Cmder.exe`あるところ。

これを開くといろいろ書いてあるけど、これはCmder側の設定をvimに反映させるためのものなのでいらないものは適宜消して大丈夫。私はCmderの設定とvimの設定を完全に分けたいので全消し。

一番消す必要があるのはこのライン。

```
let g:skip_defaults_vim = 1     " Do not source defaults.vim again (after loading this system vimrc)
```

これのせいで`.vim`ディレクトリ下のカラースキームファイルが読み込めないので消すかコメントアウトすべし。

あとは`colorscheme molokai`と`set t_Co=256`をvimrcに追加すると次にvimを開いたときに反映されるはず！


### 個人的なメモ

全消ししちゃったので個人的に最低限ないと困る設定のメモ。
今は寂しい`vimrc`だけどこれから成長していく予定。

```
" vimrc
syntax on
set number
set tabstop=4
set shiftwidth=4
colorscheme molokai
set t_Co=256
```
Python de 3DCAD ~ Spline Surface ~

pyhonocc-core(OpenCASCADE)でSpline Surfaceを作ります。ついでにSTEPで吐き出します。

## Surface生成コード

コードは[これ](https://gist.github.com/tnakaicode/f7faa6783664d9f6e5c2324d2bb663e1#file-qiita_002-1-py)です。

赤のSurfaceと青のSurfaceは形状自体は同じものですが、場所をgp_Ax3を使って変えています。

![qiita_002-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688859/f0d8e648-05b3-6f8b-efa7-4864ebc26d9a.png)


肝になる部分だけ抜粋します。

```Python
def spl_face(px, py, pz, axs=gp_Ax3()):
    nx, ny = px.shape
    pnt_2d = TColgp_Array2OfPnt(1, nx, 1, ny)
    for row in range(pnt_2d.LowerRow(), pnt_2d.UpperRow() + 1):
        for col in range(pnt_2d.LowerCol(), pnt_2d.UpperCol() + 1):
            i, j = row - 1, col - 1
            pnt = gp_Pnt(px[i, j], py[i, j], pz[i, j])
            pnt_2d.SetValue(row, col, pnt)
            #print (i, j, px[i, j], py[i, j], pz[i, j])

    api = GeomAPI_PointsToBSplineSurface(pnt_2d, 3, 8, GeomAbs_G2, 0.001)
    api.Interpolate(pnt_2d)
    face = BRepBuilderAPI_MakeFace(api.Surface(), 1e-6).Face()
    face.Location(set_loc(gp_Ax3(), axs))
    return face
```

px, py, pzは(n x n)のnp.arrayをnp.meshgridで生成して、適当な曲面のGridデータをpzとして入力します。

あとは、TColgp_Array2OfPntというOpenCASCADEのgp_Pntの2次元配列に代入していき(for loop部分)、GeomAPI_PointsToBSplineSurfaceに食わせます。

GeomAPI_PointsToBSplineSurfaceが実質的なSpline Surfaceを生成する関数ですが、詳しくは[こちら](https://www.opencascade.com/doc/occt-7.4.0/refman/html/class_geom_a_p_i___points_to_b_spline_surface.html#a1b3a73421947912e5d39086c0228729f)を読んでください。

TColgp_Array2OfPntのあとの2つの数値(3,8)はSplineを生成する近似多項式の際の最小次数と最大次数です。  
GeomAbs_G2は滑らかさを定義しています。ほかにもGeomAbs_C0, GeomAbs_C1, GeomAbs_C2, GeomAbs_G1などがあります。G2とういのは2階微分可能ということになります。  
最後の0.001は近似の際の最大誤差で、入力の点群とSurfaceの誤差がこの値を下回るようにSurfaceを生成します。

## 1点だけ異常な値を入れてみる

きれいな点群データを入れても面白くないので、生成したデータに異常値を入れてみます。

コードは[こちら](https://gist.github.com/tnakaicode/f7faa6783664d9f6e5c2324d2bb663e1#file-qiita_002-2-py)です。

データ生成部分だけ抜粋します。

```Python
px = np.linspace(-1, 1, 100) * 100 + 50
py = np.linspace(-1, 1, 200) * 100 - 50
mesh = np.meshgrid(px, py)
data = mesh[0]**2 / 1000 + mesh[1]**2 / 2000
data[100, 50] = 100.0
```

(200 x 100)の2次元arrayの大体真ん中あたり(100,50)を100.0として突出した形状にします。

![qiita_002-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688859/70e21ee1-1e4c-7f50-9f3e-c769a5fe499e.png)

真ん中あたりが異常に飛び上がった形状になります。飛び出した部分に引っ張られて周辺の形状が変形しているのは、Splineを使う以上はどうしても発生します。  
こんな異常な形状でも、(正しいかどうかは別として)生成しきってくれるのがOpenCASCADEの強味でもあります。
jqueryで１ページ内に複数idが存在する時にすべてのid選択する方法

現在railsでポートフォリオを作成しており、ajaxを利用しいいね機能を実装しました。

その際同じ投稿が同じページに表示されてしまうと１ページ内にidが複数存在してしまうため、
いいねをクリックしても１番最初の投稿にしかいいねが反映されないというエラーに直面してしまいました。

解決にかなり時間がかかってしまったので、同じような問題に直面している人の役に立てればと思い記事を書きました！

## idはユニークである必要がある
そもそもidは１ページに１つまでしか存在するべきではないというルールがあるため、普通にidを選択すると１つ目しか選択してくれません。

とは言え複数idが存在してしまうケースはあります。

以下のように設定すれば問題は解決できます。

### [id=xx]とかく

[id=xx]のようにかけばidをすべて抽出できます。

```ruby:qiita.js
$("[id=foo]").html("bar");
```

```ruby:qiita.html
<p id="foo">foo</p>
<p id="foo">foo</p>
```

## まとめ

[id=xx]とかけばすべて選択できます。

参考になれば嬉しいです。
macOS Big Sur（ベータ版）でキー入力をリマップする(windows keyboard用)




https://qiita.com/zizi4n5/items/7974d4751212214dab4e
こちらを見て設定しようとしていたのだけど、windows keyboard対応していなかったので書いた。(&調べた)

Karabiner-elementsがBig Sur対応するのはもうちょいかかるのかな... 

#### 自分の環境
Macbookpro 2019 16inch
Microsoft Natural Ergonomic Keyboard 4000

だけど、おそらく他の最近のmac + win向けkeyboardで問題なく動くはず

# できること
Windows JIS keyboardの　”無変換", "変換","カタカナ/ひらがな" キーを、macの "英数", "かな" にマッピングして、"無変換"を押したらMacの"英数"が押された時の挙動をするし、 "変換,カタカナ/ひらがな"のキーを押したらMacの"かな"が押された時の挙動をするようになる



## 各種キーとそのキーコードについて
一応このあとのコードで記載されている謎の「0x7000000**」はそれぞれこれらのキーを指しています。
興味ない人は下の方までスルーして「やったこと」だけ読んでくだされ

|キー|キーコード（hex）|
|:-:|:-:|
|無変換|0x70000008B|
|変換|0x70000008A|
|カタカナ/ひらがな|0x700000088|
|英数|0x700000091|
|かな カナ|0x700000090|

0x7000000に、キーに対応する1byteを付記すればOK
例)
半角/全角 -> 0x700000035


※参考
 https://developer.apple.com/library/archive/technotes/tn2450/_index.html
 http://www2d.biglobe.ne.jp/~msyk/keyboard/layout/usbkeycode.html


# やったこと

やったことは[先のqiitaの記事](https://qiita.com/zizi4n5/items/7974d4751212214dab4e)に書いてあることとほぼイコール




`~/Library/LaunchAgents` に以下の `com.example.KeyRemapping.plist`を作製

```com.example.KeyRemapping.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.KeyRemapping</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/hidutil</string>
        <string>property</string>
        <string>--set</string>
        <string>{"UserKeyMapping":[
          {
            "HIDKeyboardModifierMappingSrc": 0x70000008B,
            "HIDKeyboardModifierMappingDst": 0x700000091
          },
          {
            "HIDKeyboardModifierMappingSrc": 0x70000008A,
            "HIDKeyboardModifierMappingDst": 0x700000090
         },
         {
            "HIDKeyboardModifierMappingSrc": 0x700000088,
            "HIDKeyboardModifierMappingDst": 0x700000090
         }
        ]}</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

```

これで再起動したらいつもキーが希望通り動くようになるはず。
もしなんか動かないなと言う時は system.logにエラー出たりしてると思うので確認する。


```/var/log/system.log

Aug 15 17:08:51 NariMacBookPro2019 com.apple.xpc.launchd[1] (com.example.KeyRemapping[767]): Service exited with abnormal code: 1

```


それでもわからんという場合はshellで以下みたいな感じのコマンドでも打って、単体でエラーとか出てないか確認して下さい。shellでこのコマンド打てばキーマップがいきなり変わります。
キーのコードは好きなようにいじれば良いっす。

```bash
hidutil property --set '{"UserKeyMapping":[                       
  {
            "HIDKeyboardModifierMappingSrc": 0x70000008B,
            "HIDKeyboardModifierMappingDst": 0x700000091
  },
  {
            "HIDKeyboardModifierMappingSrc": 0x70000008A,
            "HIDKeyboardModifierMappingDst": 0x700000090
  },
  {
            "HIDKeyboardModifierMappingSrc": 0x700000088,
            "HIDKeyboardModifierMappingDst": 0x700000090
  }
]}'
```



# おまけ
そこそこ特殊なアプリをmacに入れてたりするが今んとこBig sur上で動いていないのは Day-oぐらい..かな
VueのコンポーネントにRailsのデータを使った話（SFC利用、Railsの一部にVue使用）

### やったこと
Railsのアプリの一部にVue.jsで作成したコンポーネントを組み込んでいます。今回は、フォームの一部（selectボックス）にVueのコンポーネントを入れ込みました。

selectのoptionはRailsのデータを利用して作成したので、その時のまとめです。

### 動作環境
今回の動作環境は下記のとおりです。

- Rails 5.2.4.2
- Vue.js 3.0.1

### 前提条件
あるお店のデータを新規作成するページ`shops/new`において、shopのカテゴリー（`Category`）を選択するセレクトボックスを設置しました。
この中の`<option>`の中身をVueで動的に生成しました。

（↑上記の内容だけであれば、Railsの機能で十分なのですが、今回はこのフォームの選択内容によって動的に画面を変化させたかったので、selectボックスそのものからVueで作成しています）

### 参考記事
作成にあたり、参考にした記事を掲載します。この記事の内容も、そこから多くを引用させていただきながら作成しています。

- [Rails 5.1 + Vue.js で開発を行う - part2 Ajax で GET しよう！](https://qiita.com/cohki0305/items/a678b0b17c5b496c1de9)
- [【Rails】RailsでDBからデータを読み込み、Vue.jsを通じてブラウザに出力する方法](https://qiita.com/terufumi1122/items/98bd4d1835fabfb700af)

### APIを作成する
Ajax で GET しようと思うと、API を作成して、そこにリクエストを投げて JSON を取得することになるそうです。なので、はじめに API を作成しました。

#### routes
```ruby:config/routes.rb
Rails.application.routes.draw do
  root to: "somepages#index"
 
  resources :shops, only: %i(new)
  namespace :api do
    resources :shops, only: %i(new)
  end
end

```
#### controller
`controllers/api/shops/`ディレクトリを作成し、その中に以下のようなファイルを作成します。

```ruby:controllers/api/shops/new.rb
class Api::ShopsController < ApplicationController
  def new
    @categories = Category.all
    render 'new', formats: 'json', handlers: 'jbuilder'
  end
end
```
### Ajax用のフォーマットの作成
#### Jbuilderの定義
Jbuilderを用いて、Ajaxに使うJsonのデータを作成しました。

```ruby:views/api/shops/new.json.jbuilder
json.array! @categories, :code, :name
```
上記のコードの内容は、こちらの記事をご参照ください。
- [Railsのjbuilderの書き方と便利なイディオムやメソッド](https://qiita.com/ryouzi/items/06cb0d4aa7b6527b3645)

拙著ですが、初心者の方はよろしければこちらもどうぞ＾＾
- [[初心者向け]Railsのコンソールでjbuilderの中身を確認した話](https://qiita.com/tanutanu/items/1dd1ea027dd142e84dc8)

#### 中身の確認
`http://localhost:3000/api/shops/new.json`にアクセスすると、Jbuilderで生成したJsonデータの中身が確認できます。

```
# 下記はサンプルデータです。通常、真っ白いページに出てきます。
[{"code":100, "name":"カテゴリー1"},{"code":200, "name":"カテゴリー2"},{"code":300, "name":"カテゴリー3"}]
```

### AjaxでGETする
Vue で Ajax 通信する際に便利なライブリーである`axios`(アクシオス) をインストールします。Vue.jsでは`axios`を利用することが推奨されています。

```
$ yarn add axios
```
`yarn`以外でのインストール方法は[こちらの公式ドキュメント](https://github.com/axios/axios)をご覧ください。

ページがロードされたときにselectボックスの中身が表示されるようにしたいと思います。
Vueのライフサイクルフックのうち`mounted`を利用します。

```vue:selectForm.vue
<template>
  <div>
    <select name="shop[category_id]" id="shop_category_id">
      <option v-for="cat in categories" :value="cat.code">{{ cat.name }}</option>
    </select>
  </div>
</template>

<script>
// axiosを読み込む
import axios from 'axios';

export default {
  data() {
    return {
      //axiosで取得するデータを入れるため、空でOK
      categories: []
    }
  },
  //mountedでVueインスタンスのDOM作成完了直後に読み込む
  mounted() {
    axios.get('/api/shops/new.json').then(response => (this.categories = response.data))
   // response.dataの中には、Jbuilderで生成したJsonデータが入っているので、
   // それをcategoriesに代入。
  }
}
</script>
```
以上で、フォームが生成できました。（見せられないのが残念）
今回、コンポーネントはこちらのやり方でViewに呼び出しています。

もし、コンポーネントが呼び出せない！という方がいたらこちらを参照ください。
- [Rails, Vue.js で単一ファイルコンポーネントを使用したいときの設定ファイルの書き方](https://teratail.com/questions/280111)
### 感想
まだ少しわからないところがありますが、まずはRailsとVueをつなぐことができてうれしいです。引き続きいろいろなパーツをVueで作れるようになりたいと思います＾＾
GitHubからGemを理解する（RSpec編）

#経緯
プログラミング学習を進める過程で様々なGemを使う。アプリケーションに必要な機能を導入し課題解決を図るツールだが、Gemごとでコーディング規則が異なっており、あやふやに理解しているとツールに溺れかねない。そこでGemの理解を深めることを目指し、GitHub上の元データを覗いてみようと思う。今回はRSpecについて調べてみよう。

#方法
今回はGitHub上の[rspec-rails](https://github.com/rspec/rspec-rails#installation)のページを参考資料にする。主にトップページを上から順繰りと読み進めていき、気になった箇所についてコメントをしていく。

#その１．development環境とtest環境双方で使用できるようにGemを配置する

>Add rspec-rails to both the :development and :test groups of your app’s Gemfile:

>```ruby:Gemfile
>group :development, :test do
>  gem 'rspec-rails', '~> 4.0.1'
>end
>```

>(Adding it to the :development group is not strictly necessary, but without it, >generators and rake tasks must be preceded by RAILS_ENV=test.)

development環境での設定は強制されていないが、設定をしないと本来development環境でも対応可能なテストまでtest環境で行うことになる。他の開発者と干渉せず、過度な迷惑をかけないdevelopment環境だからこそ、そこで対応できるものは進めようということのようである。

#その２．テストの範囲は自身で設定できる

>```terminal
># Default: Run all spec files (i.e., those matching spec/**/*_spec.rb)
>$ bundle exec rspec

># Run all spec files in a single directory (recursively)
>$ bundle exec rspec spec/models

># Run a single spec file
>$ bundle exec rspec spec/controllers/accounts_controller_spec.rb

># Run a single example from a spec file (by line number)
>$ bundle exec rspec spec/controllers/accounts_controller_spec.rb:8
>```

テスト範囲をdirectoryやfile、exampleなどで指定できる。全体の流れをテストするのか、特定の箇所だけテストするのか、対象によって無駄のない検証を心がけよう。

#その３．テストコードは自然言語とプログラミング言語の双方で記述する

>In RSpec, application behavior is described first in (almost) plain English, >then again in test code, like so:

>```ruby
>RSpec.describe 'Post' do           #
>  context 'before publication' do  # (almost) plain English
>    it 'cannot have comments' do   #
>      expect { Post.create.comments.create! }.to >raise_error(ActiveRecord::RecordInvalid)  # test code
>    end
>  end
>end
>```

describeに確認する「機能」、contextに確認する「状況」、itに機能もしくは状況についての「具体的内容」を自然言語で記述する。itに記載したものをベースに具体的な確認内容をプログラミング言語として記述する。こうすることで、人もコンピューターも理解できる記述が完成する。

#終わりに
GitHub上のデータは情報の宝庫である。コードの意図や本質、TIPS等が記述されておりGemへの内容理解が深まった。原典に当ることの大切さを感じる良い機会であった。他のGemについても同様に実践していきたい。
[MySQL]mysqldumpを利用して別の環境にデータを移行する

任意の環境のデータを別の環境に移行してテストしたい、という場面は開発をしているとよく起こるかと思います。

本記事では、このような際にmysqldumpを利用して別の環境へデータを移行する方法を記載します。

# mysqldumpとは

MySQLのバックアップを作成するコマンドです。

mysqldumpで取得したファイル中にはテーブルのDROP文・CREATE文・INSERT文が入っていて、このバックアップを利用することで元のテーブル・データの状態に復元できることが分かります。

# イメージ

mysqldumpで取得したバックアップを別のサーバーに利用することで、データ移行を実現します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97097/c40f9897-1896-dbbf-46eb-34b7e1b44bfb.png)


# データ取得

上記イメージの①②に当たる部分です。

```
mysqldump --single-transaction -h(取得元IP) -u(取得元ユーザー) -p(取得元パスワード) --port=(取得元ポート) (DB名) (テーブル名) > backup.sql
```

Tips:

- 指定したDB内の全てのデータを取得する際には、テーブル名を省略します。
- テーブル名は複数指定できます。
- `--where`を利用して、テーブルに対してWHERE句を指定できます。 例：`--where="user_id = 'abc'"`

# データ取込

上記イメージの③に当たる部分です。

上記で作成した`backup.sql`を利用して、`mysql`コマンドでデータ取込を行います。

```
mysql -h(取込先IP) -u(取込先ユーザー) -p(取込先パスワード) --port=(取込先ポート) (DB名) < backup.sql
```

# 一部のデータのみを取り込みたい場合

すでにあるデータを削除せずに追加で取り込みたい場合は、データ取得時に`-no-create-info`を利用してDROP・CREATE文を発行しないようにします。

```
mysqldump --single-transaction --no-create-info -h(取得元IP) -u(取得元ユーザー) -p(取得元パスワード) --port=(取得元ポート) (DB名) (テーブル名) > backup.sql
```

但し、プライマリキーが衝突する場合等にはエラーが発生し、異常終了します。この際、データは全てロールバックされるので一部のデータだけが取り込まれるということはありません。

# 参考

- [mysqldumpまとめ](https://qiita.com/PlanetMeron/items/3a41e14607a65bc9b60c)
- [MySQLのデータベースをmysqldumpでバックアップ/復元する方法](https://weblabo.oscasierra.net/mysql-mysqldump-01/)
cherry-pickコマンドでコミットを書き換えよう

ソースコードをマージするために、方法が多いです。こちらは普通がmerge、rebaseで利用していますが、もう一つ方法を紹介したいと思います。

仮にmasterやdevはブランチがある。今回、devのコミットからmasterブランチにマージしていきます。

既にmasterブランチのコミット

```
devブランチを作成する前
commit●
devブランチを作成する後
commit❺
```

既にdevブランチのコミット

```
commit❶
commit❷
commit❸
commit❹
```

●　一つコミットをcherry-pickしたい

```
git cherry-pick {コミットID}
```

●　複数の連続したコミットをcherry-pickしたい

```
git cherry-pick {始点となるコミットの１つ前のコミットハッシュ}..{終点となるコミットハッシュ}
```

例１：
・masterブランチにcommit❶をcherry-pickしたい場合

```
・git cherry-pick commit❶
・コンフリクトが発生する場合
➀　コンフリクトを修正
➁　修正したファイルはgit add <paths> または git rm <paths>
➂　git commit
・コンフリクトを対応した後、cherry-pickを終わりのコマンドを実行していきます
git cherry-pick --quit
```
結果、masterブランチのコミットは

```
commit●
commit❺
commit❶
```
です。

例２：
・masterブランチにcommit❶〜commit❹をcherry-pickしたい場合
commit❶もマージしたい場合は、commit❶の１つ前のコミットハッシュからcherry-pickする必要です。今回のコミットはcommit●です。そのため、下記のコマンドがある。

```
・git cherry-pick　commit●..commit❹
コンフリクトが発生すると、例１と同じで対応します。
違い点のは複数コンフリクトがある場合は、次のコミットをcherry-pickするために、
下記ののコマンドを実行します
・git cherry-pick --continue
```
結果は

```
commit●
commit❺
commit❶
commit❷
commit❸
commit❹
```
です。
そして、途中でcherry-pickを辞めたいなら、下記のコマンドです。

```
git cherry-pick --abort
```

以上です。
Macで複数バージョンのRubyを管理する[macOS+rbenv]

# はじめに
Rubyを触ったことがなかったので、今更ながら触ってみようと思い自分のMac上にRubyの環境を構築したという話。
Macには標準でRubyがインストールされているのですが、バージョンが古く、どうせ最新版入れるならPHPのphpenvと同様に
Rubyもrbenvを入れて複数バージョンを切り替えられるようにした方が今後も色々と楽そうと思い立ったので今回の記事にしました。

<br>

# 環境

* MacBook Pro 13 - macOS Mojave 10.14.6

※今回の手順ではbrewコマンドを使用するため事前にHomebrewがインストールされているものとします

<br>

# 目的

Macで複数バージョンのRubyを管理し、それを切り替えて使えるようにする。
(プロジェクトごとにバージョンが違うとか)

<br>

# rbenv導入手順
まずはHomebrewのアップデート

```
$ brew update
```

次にrbenvをインストール

```
$ brew install rbenv
...
Error: Permission denied @ apply2files - /usr/local/lib/node_modules/cordova/node_modules/extglob/lib/.DS_Store
```

私の環境では何やらパーミッションエラーが出ましたが.DS_Storeのものなので無視

最後にrbenvのバージョンを確認

```
$ rbenv --version
rbenv 1.1.2-11-gc46a970
```

これでインストール完了です！
簡単すぎて拍子抜けしちゃいます。
PHPのphpenvを導入した時はもっと面倒くさかった思い出しかない。。。

<br>

# おまけ
rbenvコマンドを引数無しで実行すればヘルプが見れますが、念の為。

```
$ rbenv
Usage: rbenv <command> [<args>]

Some useful rbenv commands are:
   commands    List all available rbenv commands
   local       Set or show the local application-specific Ruby version
   global      Set or show the global Ruby version
   shell       Set or show the shell-specific Ruby version
   install     Install a Ruby version using ruby-build
   uninstall   Uninstall a specific Ruby version
   rehash      Rehash rbenv shims (run this after installing executables)
   version     Show the current Ruby version and its origin
   versions    List installed Ruby versions
   which       Display the full path to an executable
   whence      List all Ruby versions that contain the given executable

See `rbenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/rbenv/rbenv#readme
```

<br>

* インストール可能なRubyバージョンの確認

```
$ rbenv install --list-all
1.8.5-p52
1.8.5-p113
1.8.5-p114
...
```

* 指定したバージョンのRubyをインストール

```
$ rbenv install 2.7.1
Downloading ruby-2.7.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.1.tar.bz2
Installing ruby-2.7.1...
ruby-build: using readline from homebrew
Installed ruby-2.7.1 to /Users/XXXXX/.rbenv/versions/2.7.1
```

* インストール済みRubyバージョンの確認

```
$ rbenv versions
* system (set by /Users/XXXXX/.rbenv/version)
  2.7.1

※systemは元々Macにインストール済みのRuby
```

* 現在使用しているRubyバージョンの確認

```
$ rbenv version
system (set by /Users/XXXXX/.rbenv/version)
```

* カレントディレクトリ以下で使用するRubyのバージョンを指定

```
$ rbenv local 2.7.1
```

* システム全体で利用するRubyバージョンを指定

```
$ruby global 2.7.1
```

各種コマンドやコマンドごとの動作もphpenvと一緒です。
なのでphpenvを使った事がある人なら特に違和感なく使えるかも。
php-fpmアクセスログのおすすめ設定（www.conf）

**LEMP環境＆Laravel** だと、php-fpmのデフォルト設定では、アクセスログに必要な情報が出力されないので、
ログに出力できるパラメータをすべて実際に出力検証し、これはあったほうがいいなというものをまとめました。

## アウトライン
- 環境情報
- デフォルトaccess.logフォーマット
- おすすめaccess.logフォーマット
- 解説
- 番外編

## 環境情報
- Centos7
- php7.4
- Laravel 6.0
- nginx1.16.1
- 対象設定ファイル：www.conf (php-fpm)

## デフォルトのaccess.logフォーマット
以下はデフォルトの設定内容になります。

```:www.conf
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"

※アクセスログフォーマットに設定可能なパラメータの簡易解説
　%C : CPU 使用率
  %d : リクエストの処理にかかった時間
  %e : 環境変数（$ _ENV / $ _SERVER）
  %f : script filename
  %l : content-length of the request (for POST request only)
  %m : request method
  %M : PHPで使用したメモリのピーク
　%n : pool name
  %o : output header
  %p : PID of the child that serviced the request
  %P : PID of the parent of the child that serviced the request
  %q : クエリストリング
  %Q : the '?' character if query string exists
  %r : the request URI (without the query string, see %q and %Q)
  %R : remote IP address
  %s : status (response code)
  %t : server time the request was received
  %T : time the log has been written (the request has finished)
  %u : remote user
```



実際にこの設定で出力される結果はこちら↓
> 192.168.1.1 -  1/Aug/2020:01:01:01 +0000 "GET /index.php" 200 /var/www/html/test.com/public/index.php 1111 12211 30.11%

これだと、ログ調査をする際、以下の問題点があります。

- どの画面にアクセスがあったかわからない　（出力されるパスは全て`/var/www/html/test.com/public/index.php`）
- 複数ホスト管理している場合、どのホストへアクセスされたものかわからない（全部ごっちゃになる）
- リクエスト完了までにかかった時間が「ミリ」単位で見づらい


## おすすめaccess.logフォーマット
そのため、色々試した結果、以下のようにフォーマットに変更しました。

```:www.conf
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{HTTP_HOST}e %{REQUEST_URI}e %q %{seconds}d %{kilo}M %C%% %{HTTP_REFERER}e"
```
このフォーマットで実際に出力される結果はこちら↓
> 192.168.1.1 -  1/Aug/2020:01:01:01 +0000 "GET /index.php" 200 /var/www/html/test.com/public/index.php test.com:443 /test/home  1.111 12211 30.11% https://test.com:443/test/login

以下で解説します。

## 解説
追加・編集したパラメータは以下の5つになります。

| パラメータ | 説明 | 出力例 |
|:-:|:-:|:-:|
| %{HTTP_HOST}e | 現在のリクエストのHost:ヘッダ  | test.com:443  |
| %{REQUEST_URI}e  | ページにアクセスするために指定されたURI  | /test/home  |
| %q  | クエリストリング | a=1  |
| %{seconds}d  | リクエストの処理にかかった時間を秒数で表示  | 1.111  |
| %{HTTP_REFERER}e  | 現在のページに遷移する前にユーザーが閲覧していたページのURL  | https://test.com:443/test/login  |

上でも説明がありましたが、「**%e**」で`$_SERVER変数`の値が取得できるので主にこちらを使用しました。
実際に出力してみた感じですと、使えそうな`$_SERVER変数`は上記ぐらいでしたが、お好みで追加してみてください。

<br>
まとめると、
上記5つのパラメータを追加・編集することで、
どのホスト・画面にアクセスがあったか、リクエスト処理に何**秒**かかったか
さらには、遷移する前の滞在画面までわかるようになりました。

これでサービス運用していくうえで少しは助かるかと思います。
是非参考にしてください:sunny:


##番外編
その他のパラメータで、使えそうだなと思ったけど、実際出力してみて
使えないと判断したパラメータ達です。

| パラメータ | 説明 | 出力例 |
|:-:|:-:|:-:|
| %r | 説明では「the request URI」だが、ユーザーがアクセスしたURIではなかった。  | /index.php  |
| %R  | クライアントIPではなく、nginxサーバーのIPを取ってくるため今回は使えない。<br>IPに関してはnginxの方で取得すればOK。  | 192.168.1.1 |
| %{REMOTE_ADDR}e  | %Rと同じ理由  | 192.168.1.1  |
[Julia] web アプリをJuliaで作る

# 何のメモ？
JuliaでGenieを使ってWebアプリを作ろうと思った際の覚書。
Dockerで実装するとちょっとハマるのでそのことを書ておく。

# どんなときに役立つの？
Dockerで web application for Julia な環境を作る。

# Juliaとは
以前の記事参照：https://qiita.com/risa0320/items/b10e1457b58de64687ce

# Genieとは
Julia の web Framework。
https://genieframework.com/
https://genieframework.github.io/Genie.jl/dev/index.html

# 使った環境
* Docker version 19.03.12
* docker-compose version 1.26.2

# Genie の使い方
## install 
```julia

julia> ] 
pkg> add Genie
julia> using Genie
```

## Genie アプリ作成
プロジェクトをこれで作成するとTemplate一式が作成され、るので便利。

```julia
julia> using Genie
julia> Genie.newapp("app_name")
```

## ルーティング登録
```julia:routing.jl
using Genie
import Genie.Router: route

route("/") do
  "Hellow - Welcome to Genie!"
end
```

## サーバとして起動
ここがDockerでの注意ポイント。
次の項目で説明する。

```julia:start_app.jl
using Genie

Genie.config.run_as_server = true
Genie.AppServer.startup(8000)
```
これで、 http://localhost:8000 もしくは http://127.0.0.1:8000 でブラウザから確認できる。

# Dockerで web app for julia コンテナで実現する
```dockerfile:Dockerfile
FROM julia:1.5

RUN julia -e 'using Pkg; Pkg.add("Genie");' && ¥
  julia -e 'using Genie; Genie.newapp("app_name");'
```

```yaml:docker-compose.yaml
version: '3'
services:
  web_app:
    container_name: web_app
    build: ./
    environment:
      TZ: 'Asia/Tokyo'
    ports:
     - 8000:8000
    volumes:
     - ./:/julia_app
    working_dir: /julia_app
    command: julia start_app.jl
```

```julia:start_app.jl
using Genie
import Genie.Router: route

Genie.config.run_as_server = true

route("/") do
  "Hello - Welcome to Genie!"
end
# docker を使う場合は "0.0.0.0"を指定しないと動作しない！
Genie.AppServer.startup(8000, "0.0.0.0") 
```

# 参考記事
* https://padic-aririri.hatenablog.com/entry/2019/02/17/012723
* https://sireikan.qrunch.io/entries/WjF2QayP5pCdCQ89
初学者向けgithubのコマンド集

# gitのコマンドを忘れないようにするためのメモ
　忘れないようにするためのメモです。
　使っていただければ幸いです。

## gitのログを見やすくする方法
　[参考ページ](https://qiita.com/takasianpride/items/842a785af610025a2030)

## githubにリモートリポジトリを作成した際に行うこと

$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/sample_app.git
$ git push -u origin master



## originとmasterについて
[参考ページ](https://qiita.com/seri1234/items/e651b3e108a695a92809)


## ブランチを途中のコミットまでpushしたい
[参考ページ](https://qiita.com/yagaodekawasu/items/18a2c395722a4f012338)


## 基本コマンド

・修正した内容をコメント付きでコミット
　$ git commit -am "HelloWorldメソッドを変更"
・初回コミットの際
　$ git init
　$ git add -A
　$ git commit -m "Initialize repository"

・herokuにpushするときの手順
　$ git commit -am "Add hello"
　$ git push
　$ heroku create
　$ git push heroku master

・herokuのlog取得方法
　$ heroku logs        　 # 直近のイベントを表示する
　$ heroku logs --tail  　# イベント発生のたびに自動表示する（Ctrl-Cで終了）

・ブランチのチェクアウト
　$ git checkout -b static-pages

・チェックアウトしたブランチでコミットする場合
　$ git add -A
　$ git commit -m "Add a Static Pages controller"
　$ git push -u origin static-pages

・現在のブランチの状況を知る場合

　$ git status
　$ git branch



以上


また、追加で学んだことがありましたら追記して行きます。
便利なコマンドがありましたら、コメントしていただけると嬉しいです。
LinuC 202「OpenLDAPサーバーの設定」を調べた (主にLDAPの概念について)

「2.07.4 OpenLDAPサーバーの設定」の出題内容については以下をご参照ください。
Version 10.0になって少々内容が変更されているようです。

LinuCレベル2 202試験（Version 10.0）出題範囲 | LPI-Japan
https://linuc.org/linuc2/range/202.html

LinuC レベル 1、レベル 2 の出題範囲改定について
https://linuc.org/docs/linuc_ver10.pdf

## この記事のアジェンダ
- LDAPの基本概念を整理
- slapcat, slapadd, slapindexの使い方を紹介
- OpenLDAPのアクセス管理について少し補足

## LDAPの基本概念
たぶんこの手の話題は図で説明したほうがわかりやすい気がするけど、ひとまずテキストベースで整理。
押さえておきたい基本概念は次のとおり。

- ディレクトリ情報ツリー (DIT)
- スキーマ (オブジェクトクラス, OID)
- エントリ, 属性, 識別名 (DN)
- LDIF
- ホワイトページ

以下、詳細です。

+ ディレクトリ情報ツリー (DIT)
  - DIT: Directory Information Tree
  - LDAPはツリー構造でデータを格納している

+ スキーマ
  - オブジェクトクラスや属性を定義
  - エントリに必須な属性、設定可能な属性を定義する属性
  - core, cosine, nis, inetorgpersonスキーマなどがある
    + OID
      - OID: Object IDentifier
      - オブジェクトクラスや属性にはOIDが割り当てられている
      - 例えば、inetOrgPersonオブジェクトクラスにはOID「2.16.840.1.113730.3.2.2」が割り当てられている

<よく見かけるスキーマ>
core.schema: OpenLDAP必須スキーマ
conine.schema: ディレクトリサービスX.500規格で定義されたスキーマ
nis.schema: UNIXのユーザ/グループを扱うためのスキーマ
inetorgperson.schema: アドレス帳を扱うためのスキーマ


+ エントリ
  - LDAPのデータの基本単位
  + 属性
     - 属性タイプと属性値から構成
  + 識別名 (DN)
     - DN: Distinguished Name
     - 各エントリを識別するために一意に割り当てる属性

    DNの例

    ```
    dn: cn=woody,ou=People,dc=xxxx,dc=vs,dc=sakura,dc=ne,dc=jp
    ```

  + LDIF
     - LDIF: LDAP Data Interchange Format
     - LDAPのデータはLDIFという形式で表現できる

    LDIF形式

    ```
    dn: <識別名>
    <属性タイプ>: <属性値>
    <属性タイプ>: <属性値>
    ~
    ~
    <属性タイプ>: <属性値>
    ```

+ ホワイトページ
  - inetorgpersonスキーマで定義されているinetOrgPersonオブジェクトクラスを使って、アドレス帳を実現するのが通例らしい


## slapcat, slapadd, slapindexの使い方

+ slapcat
  - 用途
     - LDAPデータベースの内容をLDIF形式で出力
     - バックアップ作成時とかに使う

  - 使用例
     - 「-n 2」で(2)のデータベースを指定する

```
# slapcat -n 2 > ldapdb.ldif
```

  - 注意点
    - 「-n 2」を指定しないと下記のようなエラーになるはず
    - 「The first database」はセッション数などの情報を扱うモニターDBでslapcatに対応していないためエラーとなる


アンチパターン

```
# slapcat > ldapdb.ldif
5f30e016 The first database does not allow slapcat; using the first available one (2)
```

+ slapadd
  - 用途
     - slapcatで作成したバックアップのリストア時に使う
     - 後述のslapindexと組み合わせで使う

+ slapindex
  - 用途
     - LDAPデータベースのインデックスを再構築する
     - リストアした後にはインデックス再構築が必須となる

  - 使用例

```
# slapadd -l ldapdb.ldif
# slapindex
```

## OpenLDAPのアクセス管理

接続元IP毎のアクセス制御はTCPWrapperやfirewalldで行う。
エントリや属性のアクセス制御はolcAccess属性で設定する。

+ 既存のolcAccess属性の属性値をslapcatコマンドで確認
  - olcDatabase={0}config,cn=configは設定用データベース管理設定
  - ↓の例の場合、全てのエントリは指定したDNユーザのみmanageアクセス*1でき、その他はアクセスできない

```
# slapcat -n 0
dn: olcDatabase={0}config,cn=config
~
~
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=extern
 al,cn=auth" manage by * none
```

*1 アクセスレベルmanageは謎...
https://gihyo.jp/admin/serial/01/ldap/0010

+ olcAccess属性の書式

```
olcAccess: to <アクセス制御対象> by <接続元> <アクセスレベル>
```

- 詳細

<アクセス制御対象>
*: 全てのエントリ
attrs=<属性タイプ>: 指定した属性
dn=<DN>: 指定したDN

<接続元>
*: 全てのユーザ
anonymous: 認証前のユーザ
user: 認証されたユーザ
self: 接続中の認証済ユーザ
dn=<DN>: 指定したDNユーザ

<アクセスレベル>
write: 属性値を変更可能
read: 検索結果を参照可能
search: 検索可能
compare: 比較可能
auth: 認証を受け付けることができる
none: アクセスできない
学習用データをPostgreSQLに取り込むまで（SQL超入門）

## 前提条件
macOS Catalina 10.15.6

## 概要
ゼロからわかるSQL超入門で勉強していた際に記載されていたPostgreSQLのインストール方法ではできなかった際にやったことの記録になります。

## PostgreSQLの導入
### PostgreSQLのインストール
```
# インストール
$ brew install postgresql
```
### DBの保存場所を設定
```
$ vi ~/.bash_profile
```

```~/.bash_profile
export PGDATA=/usr/local/var/postgres
```
.bash_profileに上の内容を追記します。

### PostgreSQLの立ち上げ
```
# PostgreSQLの立ち上げ
$ brew services start postgresql
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql) 
```

### PostgreSQLの操作
#### PostgreSQLのユーザー作成
```
$ createuser ユーザー名 --interactive
Shall the new role be a superuser? (y/n) 
# 新しく作成するユーザーをスーパーユーザーにするか聞かれるので y を選択する。
```
#### PostgreSQLの操作
```
# PostgreSQLにログイン
$ psql -U ユーザー名
postgres=#

# 学習用データの取り込み
postgres=# \i '~/Downloads/zerosql/import_mac.sql'

# 接続しているデータベースのテーブル一覧
postgres=# \d

# PostgreSQLからログアウト
postgres=# \q
```

### PostgreSQLの停止
```
# PostgreSQLの停止
$ brew services stop postgresql
==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql)  
```
GitLab APIからMerge Requestの情報を取得する

<h1>はじめに</h1>
GitLabではREST API が提供されています。
今回はそのAPIを使ってMRの情報を取得するまでを記載いたします。


<a href=https://docs.gitlab.com/ee/api/merge_requests.html>・Merge requests API</a>

<h1>1.gitLabApiを使うためにトークンを作成する</h1>
まずはgitLabApiを使うためにトークンを作成します。

・gitlabの右上のアカウントアイコンSettingsを選択します。
![picture_pc_36d1d13d217d80aa01caebf81660179c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247780/ca2243f2-5065-019f-7efa-fb23549d11e7.png)


・サイドバーからAccess Tokensを選択。
![bbb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247780/c4f3889b-5114-d28e-a5a1-6ed3728159ec.png)


・NameとScopesのapiにチェックを入れます。今回は期限などはないのでExpiers atは入力無しです。Create personal access tokenをクリックします。
![ccc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247780/59cb8d02-dc87-ef65-5e85-985f493739fb.png)


・これでトークンの生成は完了です。
![ddd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247780/df100ab7-ae1d-c9b2-057d-334cd04e22e0.png)


<h1>2.gitLabApiからMR情報を取得</h1>
トークンが完成したので実際にMerge Requestの情報を取得してみましょう。

取得したいプロジェクトIDから先ほど発行したトークンをパラメータに設定することでMRの情報を取得することができます。

```
curl https://" + [GitLabのHost] /api/v4/projects/取得したいMRのProjectID/merge_requests?private_token='発行したトークン'
```


<h1>終わりに</h1>
<a href=https://docs.gitlab.com/ee/api/merge_requests.html>・Merge requests API</a>

上記ドキュメントの `Parameters` で様々な取得条件を設定することができます。
情報を取得して運用の自動化やなど行えるかと思います。
新卒プログラマの学習ログ　〜　其の五　〜

#Kotlinのあれこれ
Android StudioでKotlinを使用しながら、Androidアプリ開発に関して学んでいます。
Javaの基礎知識があればKotlinの学習は必要ないと上司から言われていましたが、全然そんなことないと思っています。(泣)

確かにオブジェクト思考を前提としたプログラミングではありますが、Javaと比較してKotlinは型推定が常識のように行われるためにいきなりライブラリの仕様等を見ると心が折れます。

#高階関数とそれに組み合わさるあれこれ
前回に関数オブジェクトについて書かせていただきました。
関数オブジェクトが本領を発揮するのは、関数の引数として与えたり、返り値として返すことができる点です。

高階関数は関数を引数として受け取って動作する関数です。
今回は関数オブジェクトを引数として渡す方法や、それに書き換えられるラムダ式と絡めて記事を書いてみます。



#早速コードを見てみよう
まずは実際に動作するコードを確認してみましょう。
以下は受け取った文字を出力する関数オブジェクト`charPrint`を高階関数`forEach`に引数で渡しています。
このプログラムの流れがわかる方はこの記事はお役に立てないかもしれません。

```HigherOrderFunction.kt

fun forEach(s: String, x: (Char) -> Unit) {
    for (c in s) {
        x(c)
    }
}

fun charPrint(c: Char): Unit{
    println(c)
}

fun main() {
    val funObject = ::charPrint

    forEach("aiueo", funObject)
}
```

実行結果は以下のようになります。
> ..> a
> ..> i
> ..> u
> ..> e
> ..> o

文字を受けとって表示する関数オブジェクトを引数に受け取って、もう一つの引数の文字列を一文字ずつ表示する関数になっていますね！
`charPrint`のところの`: Unit`は型推論ができるので省略しても大丈夫です。
`: Unit`は戻り値のない関数に記述するのでしたね！
Javaでいうvoidみたいなものですかね。

これは以下のようにも書くことができます。
ラムダ式を使用した記述方法です。

```HigherOrderFunction.kt

fun forEach(s: String, x: (Char) -> Unit) {
    for (c in s) {
        x(c)
    }
}

fun main() {
    forEach("aiueo", {c: Char ->
        println(c)
    })
}
```
これでも同じ実行結果を得ることができます。
さらにラムダ式は引数が一つのときに限り、暗黙の変数itを使用することができます。
なので、mainの部分は以下のように書き換えることができます。

```HigherOrderFunction.kt

fun main() {
//    forEach("aiueo", {c: Char ->
//        println(c)
//    })
    forEach("aiueo", {
        println(it)
    })
}
```
構文糖衣(syntax sugar)も使用すると、以下のように書き換えることができます。

```HigherOrderFunction.kt

fun main() {
//    forEach("aiueo", {c: Char ->
//        println(c)
//    })
    forEach("aiueo"){println(it)}
}
```
Kotlinには書き換える方法が多く、初めて見ると色々な書き方に困惑してしまうと思います。
私も未だによく混乱してしまいます。
仕組みや学ぶ順序を意識して、なぜこの書き方が良いのかという点も含めて理解すると良いと思います。


## 最後に
相変わらずJavaやC言語でなれている人にとってはあまり馴染みのない書き方ですね。
次回はAndroidアプリの開発に関わる記事について書いてみようと思います。



#とりあえず。。。
メモ代わりに書いていますが、これから理解が深まれば書き足していきます。
いつか誰かのお役に立てると嬉しいですね。

# 初学者から一人前まで、、、
ここでは一人前のプログラマの定義を
「おおよそ自力で様々なツールを活用しながら、ある程度思い通りの実装ができること」
とします。

また、人生においてプログラミングに向き合う時間として、現時点で2000時間取り組めればある程度の基盤が備わると仮定しています。
（言語やツールに依存しない思考法や情報収集能力）

プログラミングは大学で学んで来ましたが、特に根詰めてやってきていないので、ノーカウントとして取り組みます。

現在までの学習時間
**およそ450時間**
どんどん更新していきます。
量子化技術メモ

Deep Learning Digital Conference（8/1）で、量子化技術の発表がありましたので、学んだことを以下に記載します。

引用した発表は以下の2件です。
- 最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法（エヌビディア　佐々木様）
- Tensorflow Liteの量子化アーキテクチャ（ax（株）　品部様）

##量子化とは？

量子化
　例）float→Int8

メリット
　高速化、メモリ節約、モデル小型化
　→組み込み機器用

デメリット
　精度低下

対策
　量子化に強いネットワークを利用
　量子化の方法を工夫

量子化の種類
　半精度浮動小数点数量子化　2倍小型化
　　→自動混合演算（後述）
　ダイナックレンジ量子化　　4倍小型化、2～3倍高速化
　　重みだけInt8
　完全整数量子化　　　　　　4倍小型化、3倍以上高速化
　　重みとテンソルをInt8
　　→Post-training Quantization（後述）

##自動混合演算（AMP）

混合精度トレーニング（Mixed Precision Training）
　FP32をFP16に変換。
　メモリ節約、2～8倍速い。
　正確度維持。

自動混合演算（Automatic Mixed Precision、AMP）
　混合精度トレーニングを自動で適用。　

Tensorコア世代が対応。
　Volta（2017）、Turing（2018）、Ampere（2020）。
　→GeForce GTX 1080 Ti（Pascal（2016））は非対応。

有効化
　TensorFlow
　　TF1.14およびTF2以降、オプティマイザのラッパーを利用可。
　　opt = tf.train.experimental.enable_mixed_precision_graph_rewrite(opt)
　　https://www.tensorflow.org/api_docs/python/tf/train/experimental/enable_mixed_precision_graph_rewrite

　PyTorch
　　ネイティブにサポート。
　　https://pytorch.org/docs/stable/amp.html
　　https://pytorch.org/docs/stable/notes/amp_examples.html

参考）A100
　学習
　　混合精度演算がV100（Volta）より2.5倍速い。
　推論
　　疎行列化で2倍速い。

##Post-training Quantization（Tensorflow）
精度
　重み　　Int8
　Bias　　Int32
　Tensor　Int8
　出力　　Int8

量子化ツール
　pbファイルをTensorflowLiteのConvert APIでInt8に量子化
　キャリブレーション用画像が必要
　Quantize Aware Training不要

レイヤー毎
　per-tensor（layer-wise）よりper-axis（channel-wise）の方が精度が高い

## 参照
Deep Learning Digital Conference
https://dllab.connpass.com/event/178714/
https://dldc-2020.dllab.ai/

最新のNVIDIA AmpereアーキテクチャによるNVIDIA A100 TensorコアGPUの特長とその性能を引き出す方法
https://www.slideshare.net/DeepLearningLab/track22-nvidia-amperenvidia-a100-tensorgpu?ref=https://dllab.connpass.com/event/178714/presentation/

Tensorflow Liteの量子化アーキテクチャ
https://www.slideshare.net/HitoshiSHINABE1/tensorflow-lite-237535976?ref=https://dllab.connpass.com/event/178714/presentation/
Sphinxメモ

##経緯
自分自身がSphinxでよく使うもので、少し調べないと出てこないものをまとめました。

###外部のcsvファイルを読み込む

```
.. csv-table:: サンプルデータ
   :file: sample.csv
   :encoding: utf-8
   :header-rows: 1
(一行あける)
```
sample.csvは、Excelで「名前をつけて保存」からファイル形成を「CSV UTF-8(コンマ区切り)(.csv)」で選択して、保存します。最後は、:header-rowsの後、一行開けないと、表示されません。またcsvファイルは、プログラムファイルと同じディレクトリに入れます。

左がExcel画像、右がHTML画像

![スクリーンショット 2020-08-15 16.23.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177825/64e6b303-57b4-fc9c-282d-e4aa77c7aaf6.png)![スクリーンショット 2020-08-15 16.28.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177825/93149674-5a53-b6b6-9988-d10bd09ec5f2.png)


###同じページ内のラベル参照

```
.. _`foo_label`:

===============
foo Methods
....
....
....

=============
ページ先頭の方にある :ref:`foo 説明<foo_label>` を参照。
```
これも、[.. _`foo_label`:]の次の行は開けておきましょう。


###コンストラクタをドキュメントに追加する方法
デフォルトでは、コンストラクタはドキュメントに追加されないです。

conf.pyにて下記の通りに追記しましょう。

```
def skip(app, what, name, obj, would_skip, options):
    if name == "__init__":
        return False
    return would_skip

def setup(app):
    app.connect("autodoc-skip-member", skip)
```

すると、コンストラクタはスキップされません。


##参照
[Sphinxのautodocを使用して、クラスの__init __（self）メソッドを文書化する方法は？](https://www.it-swarm.dev/ja/python/sphinxのautodocを使用して、クラスのinit-（self）メソッドを文書化する方法は？/971302038/)
[1. restructured text の練習](https://msakamoto-sf.github.io/sphinx-rest-exercise1/re-st_syntax/ex-typical1.html#label-sample)
【メモ】WSL2 + Ubuntu のインストール

# まえがき
？？？「すいません、WSL2の導入の仕方って知ってますか？」
？？？「WindowsでUbuntu使いたいすけどー・・・」
ってな感じでよくやり方をきかれます。私は某知恵袋でいうベストアンサーを叩き出せるほどの人間ではないですが、ここ見て！という手引があればいいなと思ったのと、新規でマシン構築した際にいちいち調べるのもあれなので、メモとして手順を書きます。
ちなみに筆者はArch Linux派です（1回目）。

# Windowsを最新版に更新
これは言うまでもないので、やりましょう。
ここが一番時間かかるっていうのはここだけの話。

# WSL2をインストール
正直、Microsoftのヘルプ見たほうが早いかもしれません・・・。
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

## 新規編
まず、Linux 用 Windows サブシステムオプション機能が有効にします。
スタートボタンからPowerShellを開き、以下のコマンドを入力します。

```
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```

次に、WSL2を導入します。
WSL2特有ですが、仮想マシン プラットフォームオプション機能を有効にする必要があるため、またしてもPowerShellで以下の通りに入力しましょう。

```
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

（更新編に続く）

## 更新編
なんかうまく行かない！ってときの更新編（＆新規編の最後の続き）。
MicrosoftのWSL2のサイトへアクセスしましょう。
https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel
「最新の WSL2 Linux カーネル更新プログラム パッケージをダウンロード」をクリックし、ダウンロード＆インストールしましょう。
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/362939c5-721b-4dab-cdfb-6f2a91f9735b.png)

## 念押しの一手
デフォルトのバージョンを2にするため、PowerShellで以下のコマンドを入力します。

```
wsl --set-default-version 2
```

# Microsoft Storeのターン
ここからしばらくはMicrosoft Storeでの作業が続きます。

## Ubuntu 20.04 LTS をインストール
Microsoft StoreでUbuntuと入力してインストールすしましょう。
Ubuntuには数種類のものがありますが、正直お好きな方を選んで構わないと思います。

* Ubuntu   
最新のLTS版がインストールされます。
なお、更新すると、LTSのバージョンもあがります。2年周期なのでそんなにコロコロと更新は来ないですが・・・。  
* Ubuntu xx.04 LTS   
指定されたバージョンのLTS版がインストールされます。  
特定のバージョンの環境が必要な場合はこちらのほうがいいと思います。  

![pic2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/ca9b42d0-9028-dc38-b019-bae3674b26d4.png)

## Windows Terminal をインストール  
Windowsとは思えない画面になると評判のWindows Terminalをインストールしましょう。
やり方はUbuntuと同様、Storeから。
![pic3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/085a4cef-4f5a-003e-2a09-5680c2a81edf.png)

# 実食！
ここからは実際に使っていきます。

## Ubuntuの初期設定
Ubuntuでのユーザ名とパスワードを設定します。
スタートボタン→Ubuntuで下記画面が出てくるのでやりましょう。
![pic4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/df717d86-4f79-9ec1-7017-dce1bd41831a.png)

## Windows Terminalで実行
Windows Terminalを開くと、デフォルトだとPoweShellが出てくるはずです。そこで下三角ボタンを押して切り替えましょう。
![pic5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/2fe62925-480b-31c0-88be-2e605a80ed61.png)
切り替えたらこのように表示されてあとはお好きに使えます。
![pic6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163185/3bce9d5a-40ee-0bca-910a-902ad618bba4.png)

ざっとこんな感じでいけます。
ちなみに筆者はArch Linux派です（2回目）。
ubuntuでパスワードが短すぎて変えられないと出てたときの対処法【passwdコマンド】【ubuntu】

ubuntuでパスワードを変えた。
変える前`●●●●`　⇛　変えたあと`●●●●●●●●●●●`

やっぱり4文字のほうがいいと思って、`●●●●`に戻そうと思った。
変えようと思ったら、`変更`を押せない。( ﾟДﾟ)
`パスワードが短すぎます。`とのこと。
![Screenshot from 2020-08-15 13-14-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641736/235ea745-59ae-18aa-7af5-28ac32f54926.png)

端末で試した。

```
$ sudo passwd -f
```
だめだった (^ ^;)
![Screenshot from 2020-08-15 13-15-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/641736/55a0889b-1e5c-0e0c-102a-fee4c6ee2a14.png)

googleで調べてみた。
`passwd 短いパスワード`

###調べた結果

[Ubuntuで短いパスワードを設定する方法は？](https://qastack.jp/ubuntu/180402/how-to-set-a-short-password-on-ubuntu)

```
$ sudo passwd [ユーザー名]
```

[ユーザー名]をパスワードを変更したいユーザー名に置き変える。

```sh
$ sudo passwd ichiri
[sudo] ichiri のパスワード: #今のパスワードを入力
新しいパスワード: #新しいパスワードを入力
新しいパスワードを再入力してください: #新しいパスワードを再入力(慎重にしてね)
passwd: パスワードは正しく更新されました #成功
$ 
```