OmniAICreator/Qiita-1.07M huggingface dataset:
API呼ぶ【コール編】

##API呼ぶ

以下4つのパートに分かれています。(〇〇編は適当につけましたゆるして)
[API呼ぶ【準備編】](https://qiita.com/RO018/private/0335375a22ba51d15661)
[API呼ぶ【コア編】](https://qiita.com/RO018/private/19a9f1740e0dffbb7844)
[API呼ぶ【ハンドリング編】](https://qiita.com/RO018/private/609ce3dcb3079d44b69a)
API呼ぶ【コール編】

##コール編
前回までで、Facadeを呼べばAPI関連の処理まとめてやってくれるように作れました
じゃあFacade呼ぼう

```service.java
package service;

import exception.NantokaApiBadResultException;
import exception.NantokaApiUnknownException;
import facade.Facade;
import model.RequestBody;
import model.RequestDto;
import model.ResponseBody;
import model.ResponseDto;

public class Service {
	
	/** APIFacade */
	private static Facade facade = new Facade();
	
	public static void main(String[] args) {
		System.out.println(service(""));
	}

	public static String service(String str) {
		
		// ロジック
		
		RequestBody body = new RequestBody();
		body.setId("28");
		body.setName("なんとかさん");
		body.setInfo("おなかすきました");
		
		RequestDto request = new RequestDto();
		request.setRequest(body);
		
		try {
			// API実行
			ResponseDto response = facade.nantokaApiFacade(request);
			ResponseBody responseBody = response.getBody();
			return responseBody.getInfo() + responseBody.getComment();
			
		} catch (NantokaApiUnknownException e) {
			return e.getMessage();
			
		} catch (NantokaApiBadResultException e) {
			return e.getMessage();
		}
	}
}
```

エラーがシンプルでいいですね
FacadeでExceptionでくくったものと、処理結果がnullの場合を一つのエラーにまとめることができています
あとは結果が正常じゃない場合のエラーをとっています
結果の種類に応じて処理分けたかったら、Exceptionを増やして分岐させていけば対応できますね

##まとめ
★Client(コア層)はただたんにAPIたたくだけ
★Facade(ハンドリング層)でExceptionを好きなように吐かせる
★Service(コール層)で、分岐した時の処理を実装

なかなか綺麗なんじゃないでしょうか！
API呼ぶ【ハンドリング編】

##API呼ぶ

以下4つのパートに分かれています。(〇〇編は適当につけましたゆるして)
[API呼ぶ【準備編】](https://qiita.com/RO018/private/0335375a22ba51d15661)
[API呼ぶ【コア編】](https://qiita.com/RO018/private/19a9f1740e0dffbb7844)
API呼ぶ【ハンドリング編】
[API呼ぶ【コール編】](https://qiita.com/RO018/private/1c9f4e603cd15b95acea)

##ハンドリング編
コア層で実際にAPIをたたいたので、
今回の階層では出てきたエラーをハンドリングします

ここでいうエラーとは、Exceptionだけでなく
処理結果が不正である場合も含まれます


```Facade.java
package facade;

import client.Client;
import exception.NantokaApiBadResultException;
import exception.NantokaApiUnknownException;
import model.RequestDto;
import model.ResponseDto;

public class Facade {
	
	/** 処理結果コード正常 */
	private static final String SUCCESS = "0";
	
	/** APIクライアント */
	private Client client = new Client();

	/**
	 * APIを実行した結果を取得する
	 * 
	 * @param request リクエストDTO
	 * @return レスポンスDTO
	 * @throws NantokaApiUnknownException 通信エラーや結果が存在しなっかった場合
	 * @throws NantokaApiBadResultException 処理結果不正の場合
	 */
	public ResponseDto nantokaApiFacade(RequestDto request)
			throws NantokaApiUnknownException, NantokaApiBadResultException {

		ResponseDto response = new ResponseDto();

		try {
			response = client.nantokaApiClient(request);

		} catch (Exception e) {
			// 通信系エラーの場合
			throw new NantokaApiUnknownException(e.getMessage());
		}

		if (response == null) {
			throw new NantokaApiUnknownException("なんも返ってこなかったよ");
		}
		
		if (!SUCCESS.equals(response.getResultCode())) {
			throw new NantokaApiBadResultException("処理結果不正");
		}

		return response;
	}
}
```

通信エラー系のExceptionの場合も、処理結果がなぜかnullだった場合も、
同じく`UnknownException`で返すようにしてみました

まぁこっちの気持ちとしてはなんかよくわかんないエラーなので、まとめたいよね
あと処理結果が不正の場合も、こっちからしたらエラーみたいなものなのでExceptionとして返しました


ここまでで、APIを呼ぶ機能は完成したと言えます
あとはこいつを呼び出すだけなので、次回実際に使ってみましょう
API呼ぶ【コア編】

##API呼ぶ

以下4つのパートに分かれています。(〇〇編は適当につけましたゆるして)
[API呼ぶ【準備編】](https://qiita.com/RO018/private/0335375a22ba51d15661)
API呼ぶ【コア編】
[API呼ぶ【ハンドリング編】](https://qiita.com/RO018/private/609ce3dcb3079d44b69a)
[API呼ぶ【コール編】](https://qiita.com/RO018/private/1c9f4e603cd15b95acea)

##コア編
実際にAPIにPOST送信をなげる、コアとなる部分を実装します

```client.java
package client;

import javax.xml.ws.http.HTTPException;

import json.JsonUtil;
import model.RequestDto;
import model.ResponseDto;

public class Client {
	
	/**
	 * APIを実行する
	 * 
	 * @param request リクエストDTO
	 * @return レスポンスDTO
	 */
	public ResponseDto nantokaApiClient(RequestDto request) {
		
		String requestJson = JsonUtil.requestDtoToJson(request);
		
		String response = post(requestJson, "http://nantoka.com");
		
		return JsonUtil.responseJsonToDto(response);
	}
	
	/**
	 * POST処理
	 * 
	 * @param requestJson Json変換したリクエスト
	 * @param uri 送信先URI
	 * @return レスポンスJson
	 * @throws 通信エラー系
	 */
	private final String post(String requestJson, String uri) {
		
		try {
			// なんかPOST用のライブラリのやつ
			return "ClientBuilder.newClient().path(uri).request().post(requestJson);";
		} catch (HTTPException e) {
			throw e;
		}
	}
}
```

postメソッド内部の実際の`ClientBuilder`のライブラリは今回は省略しました
ハンドリングはもっと表面部分の階層の処理でやりたいため、
今回みたいなコア層では通信系Exceptionをすべてそのままスローするようにしています


やってることはリクエストを投げてレスポンスを受け取る、ただそれだけですね
外部のメソッドを通信して使ってるだけです
通信の際にはJson形式に直して送り、戻ってきたJson結果をDTOに直して返してます
LDAP認証入門

# はじめに
LDAPサーバを管理しているとクライアント側からLDAP認証開始時に質問を受けることがよくある。LDAPがニッチのためか、話が嚙み合わないことが多い。そこで、意思疎通が可能になる程度の内容でLDAP認証について簡単にまとめおく。

# LDAPとは
そもそもLDAPとはLightweight Directory Access Protoclの略省で「ディレクトリサーバ」へアクセスするためのプロトコルである。

LDAPの目的としては情報を整理して管理するためのものであり以下のような特徴をもつ

- ツリー構造

- 読み取りが高速

- 基本的な属性があらかじめ定義されてる（電話番号、パスワードなど）


LDAPは上記で示したように本来は認証に特化したものではない。しかし、LDAPが持っている機能のなかに認証を実施してくれる操作がある。そのため、LDAP認証は認証操作という一部の機能を利用しているだけにすぎない。

LDAPの詳細については今回のメインテーマではないため、別サイトを参照していただきたい。

# LDAP認証ってなにもの？
LDAP認証とは具体的には*LDAP Bind*という認証を実施してくれる操作があり、それを利用している。

*LDAP Bind*のポイントとしては、KEYとして*DN*を使い、Passwordによって認証している。クライアント側にOK・NGの認証結果（コード）を返す。
LDAP認証を利用すれば、クライアント側（アプリケーション）としてはパスワードを自分で比較することはしなくて済むようになるため、安全に簡単に認証を扱えることになる。

ちなみ*DN*とはDistinguished Nameの略（識別名）でツリー構造の中で一意となるLDAPのKEYになるものである。

# LDAP認証のからくり
アプリケーションのログイン画面で入力するIDは通常DNでなくアプリケーションで使うIDである。そのため、LDAP認証を実施するためには入力されたIDからDNを生成する必要がある。この変換がLDAP認証の肝になる。変換方法に統一的なプロトコルはなくクライアント側に任されるが、おおむね以下のような方法で実現している。

### 検索を組み合わた方法

ログイン画面で入力されたIDを利用してLDAPサーバを検索してDN生成する。この方法の大まかな流れは以下になる。

1. *LDAP Search*を利用してIDの紐づくDNをLDAPサーバから検索して取得する

1. 取得したDNを用いて、*LDAP Bind* で認証操作を実施する


ポイントしては*LDAP Search*を使って検索するところになるだろう。この操作のイメージをつけることが重要になる。
アプリケーションのLDAP認証の設定情報にはこの*LDAP Serach*のための設定情報が必要になる。検索のイメージがないとどのように値を設定してよいかわからず、悩むことになるだろう。

例えば、*Tomcat*の`server.xml`にあるLDAP認証の設定は以下となる。

```
<Realm className="org.apache.catalina.realm.JNDIRealm"
  connectionName="CN=USERNAME,DC=example,DC=com"
  connectionPassword="Passwordxxxx"
  connectionURL="ldap://xxx.example.com"
  authentication="simple"
  userBase="DC=example,DC=com"
  userSearch="(uid={0})"
  userSubtree="true"
　・・・
```
`connectionName`はLDAPを検索するためのユーザのDNとなる。これはクライアント（アプリケーション）にログインするものではない。`connectionPassword`は検索ユーザのためのパスワードになる。検索するユーザも基本的はLDAPサーバに認証されて、そのあと検索操作を実行する。一般的には*ReadOnly*程度の権限しかないようなユーザを利用することになる。
`userBase`は検索するツリー構造の起点となる。これは*LDAP Search*に必要なプロパティである。`UserSearch`はIDを紐づける検索条件になる。この条件に当てはまるユーザを検索してDNを生成することになる。そのため、DNの中にIDが入っていなくてもよいことになる。`userSubtree`は起点より配下も見に行ってよいかの確認となる。

このように設定において*LDAP Search*の知識が必要になってくる。そのため、必要があれば*LDAP Search*特に検索条件の作り方などについては調べてほしい。

上記では*Tomcat*を例に出したが、多くのアプリケーションがこの方法を採用している。

### 置換を使った方法

こちらの方法をとっているクライアントは少ないが、`DN=CN={0},O=yy,C=xx` などのようにIDを置換するだけでDNを組み立てる方法もある。

この方法の場合は*LDAP Search*の設定情報がいらないため、シンプルな設定になる。しかし、ツリーの場所を固定しているため複雑なツリー構造の場合に対応できない。ただし、認証のみためにLDAPサーバを構築するのであれば、すべてのDNを同一階層に置けばよいので、このようなことも可能になる。

#おわりに

LDAP認証を利用する際には、IDからどのようにDNを作り出しているかがポイントになる。特に検索を組み合わせたパターンの場合、LDAPになじみがない人にとってはイメージできず、設定の意味が全く理解できなかったのでないかと思われる。この記事で少しでもイメージがつき、設定がスムーズにできるようになってもらえれば幸いである。
iPad ProでHHKBを快適に使うための方法

## 概要
**この記事はHHKB Professional 2 US配列（有線接続）を想定しています。**

HHKBの打鍵感に慣れてしまうと、PCやMacだけでなくiPadでも使いたくなってしまいます。
この記事では、iPad ProでHHKBを快適に使うための方法を紹介します。

## 用意するもの

- iPad Pro (iPadOS 13.2.3)
- HHKB Professional 2 US配列（有線接続）
    - 筆者はType-Sを使用
- [エレコム USBケーブル Type C (USB C to mini B) 0.5m](https://www.amazon.co.jp/gp/product/B0197AP76U/)
- [KAUMO USB 変換コネクタ (mini-Bオス / mini-Bメス 横L型 右向き) ](https://www.amazon.co.jp/gp/product/B06W9K27DC/)
    - この記事では右向きを推奨します

## 詳細

### 接続

これらを組み合わせることで以下の写真のような接続ができます。

![21333B06-52A9-4EEF-8DED-460B383C8577.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245363/916b03d3-c121-1023-eb93-8f96e84397d8.jpeg)

一般的なmini BケーブルはHHKBに対して縦向きに差し込むことになり、iPadを画像のように置いたときに干渉してしまいます。

![B70FDE5D-E4A3-4CA4-9236-45D9172DA073.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245363/f562b7e8-5919-b5d8-4590-7d3bc0742258.jpeg)

そこに、横L型 右向きの変換コネクタを入れるとこのように干渉することなく、スッキリと配線することができます。

![D72D0494-E23F-4DA9-894F-9BE8A9AD12D8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245363/6a947a45-fe52-dfda-2185-7bd657f53292.jpeg)

### HHKBの設定

HHKBのDIPスイッチは2のみをONにします。つまり、Macintoshモードです。

![D349B330-9347-4A19-BC52-EBC9ABE18D25.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245363/46571ccb-f15c-9839-ba1e-7dcc46a7c2e0.jpeg)

### iPadOSの設定

HHKBをiPadに接続すると、「設定>一般>キーボード」に「ハードウェアキーボード」という項目が表示されるようになります。私は以下の画像のような設定で使っています。

<img width="952" alt="95318573-F76A-497C-88B7-07DBEAD68A42.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245363/e5154936-cfe6-1372-6ff4-2c0700056a1b.jpeg">

また、キーリピートは「設定>アクセシビリティ>キーボード>キーのリピート」で設定できます。
私は以下の画像のような設定をしています。「キーのリピート間隔」、「リピート入力認識までの時間」は設定可能な最短の秒数です。

<img width="952" alt="0AC48641-B5F0-4B2C-A4A3-0796442CBEB3.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245363/e3d3221e-6a5d-85cc-409c-fa32d433e879.jpeg">

## 難点

macOSで使うときはKarabiner-Elementsで左右のCmdキーの空打ちで英数/かな入力の切り替えをしていますが、iPadOSではそれができません。現状はCaps Lockで切り替えていますが、FnキーとTabキーの2つのキーを押す手間と、一発で意図した入力モードにならない(Caps Lockを押すごとに英数とかな入力が切り替わる)ため不便です。それを除けば快適に使えています。
memo jsでrequireする時.defaultが必要になる場合がある

この場合 `require('object').default` でないと取れない

```javascript
export　default = object;
```


これなら `require('object')` で取れる

```javascript
module.exports = object;
```


es6の `import ... from ...` でやれば `exports.default` でも `.default` なしで取れるからそっち使おう！
Type scriptについて学んだことメモ


## 目次
1. Type scriptとは
2. Type scriptの基本

## 今回の学習のゴール
- Type scriptとは何か、何ができるかを知る
- 実際の使い方について知る

## 1. Type scriptとは

> TypeScript はマイクロソフトによって開発され、メンテナンスされているフリーでオープンソースのプログラミング言語である。TypeScriptはJavaScriptに対して、省略も可能な静的型付けとクラスベースオブジェクト指向を加えた厳密なスーパーセットとなっている。

> TypeScriptはクライアントサイド、あるいはサーバサイド (Node.js) で実行されるJavaScriptアプリケーションの開発に利用できる。
[TypeScript - Wikipedia](https://ja.wikipedia.org/wiki/TypeScript)

- JavaScriptに型をつけた言語
- TypeScriptのコードはJavaScriptにコンパイルされて実行される
- クラスベースオブジェクト指向については[Node.js, JavaScript学習まとめ](https://qiita.com/katu_/items/64c74b1a1abe1e596c8d)を参照

**→ JavaScriptではデータの型を指定する必要がないが、TypeScriptは型を厳密に扱う言語であるため、コードの品質と理解容易性を高めることができる**

## 2. Type scriptの基本

- Node.jsがインストールされていることが前提条件
- Type scriptをインストール

```console
$ npm install --save-dev typescript
```
- TypeScriptのファイルを作成
    - 変数に型を指定する

```test.ts
let message: string = 'Hello';
console.log(message);
```
- `tsc`コマンドでコンパイラしてnodeを実行

```console
$ tsc test.ts
$ node test.ts
```
- 実行結果

```console
Hello
```

### 基本的な型

- 真偽値

```typescript
let isDone: boolean = false;
```
- 数値

```typescript
let decimal: number = 6;
```
- 文字列

```typescript
let color: string = "blue";
```
- 配列

```typescript
let list: number[] = [1, 2, 3];
```
- タプル
    - タプル型は値の型がわかっている配列を記述したいときに使用

```typescript
let x: [string, number];    // タプル型を宣言

// 初期値
x = ["hello", 10];    // OK
x = [10, "hello"];    // Error
```
- 列挙型
    - 性質が似た複数のものを列挙する時にenum使用

```typescript
enum Color {Red, Green, Blue}    // Red=0, Green=1, Blue=2
let colorName: string = Color[1];

console.log(colorName);    // Greenが出力される

// 以下のように列挙型の値を手動で設定することもできる
enum Color {Red = 1, Green = 2, Blue = 4}    // Red=1, Green=2, Blue=4
enum Color {Red = 1, Green, Blue}    // Red=1, Green=2, Blue=3
```
- Any
    - アプリケーションの作成時に型のわからない変数を記述する必要がある場合に使用
    - どんな型とも相互変換可能（実質TypeScriptの型システムを無視することである）

```typescript
let list: any[] = [1, true, "free"];
```

- Null

```typescript
let n: null = null;
```
- Undefined

```typescript
let u: undefined = undefined;
```

※ [JavaScript の null と undefined の違い](https://qiita.com/katu_/items/a7a0087e615264d609b4)
nullは明示的に設定しなければ存在しない値のこと
undefinedは値の内容が存在しないときに暗黙的に設定される値のこと

### 使用例

- 関数
  - 引数にstring型を追加

```typescript:greeter.ts
function greeter(person: string) {
    return "Hello, " + person;
}

const user = "Nakamura";
document.body.innerHTML = greeter(user);    // document.body要素の内容を置き換え(innerHTMLプロパティ: 要素内のHTMLのマークアップを取得したり設定したりできる)
```

- インターフェース

```typescript:greeter.ts
interface person {     // personというインターフェースを定義 personはプロパティを持ったオブジェクト
  firstName: string;    // プロパティに型を持たせる
  lastName: string;
};

const user1:person = {
  firstName: "Tanaka",    // OK
  lastName: "Sato"        // OK
};

const user2:person = {
  firstName: "Tanaka",    // OK
  lastName: 3             // Error
};
```

## 参照
- [Documentation · TypeScript](https://www.typescriptlang.org/docs/home.html)
- [Why TypeScript？ - GitHub](https://github.com/yohamta/typescript-book-jp/blob/master/docs/why-typescript.md)
- [TypeScriptの型入門](https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a)
[vscode] settings.json

```terminal:settings.json
{
    // ==== html ===========================================================
    "html.format.extraLiners": "", // headとbody要素の調節
    "html.format.preserveNewLines": false, // 指定タグ間にスペースを入れない
    "html.format.indentInnerHtml": true, // headとbodyをインデントする 
    // ==== javascript =====================================================
    "[javascript]": {
        "editor.tabSize": 2,
        "editor.autoIndent": true,
    },
    // ==== python ==========================================================
    "[python]": {
        "editor.tabSize": 4
    },
    "python.venvFolders": [
        ".pyenv",
        ".local/share/virtualenvs"
    ],
    // ==== window ==========================================================
    "window.zoomLevel": 1,
    // ==== editor ==========================================================
    "editor.fontFamily": "'Migu 1M', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'",
    "editor.fontSize": 17,
    "editor.formatOnSave": true,
    "editor.insertSpaces": true, // インデントに使用する文字を自動判定
    "editor.tabSize": 2,
    "editor.minimap.enabled": false,
    "editor.hover.enabled": false, // 説明ヒントを非表示
    "editor.wordWrap": "on", // 端で折り返す
    // ==== debug ===========================================================
    "debug.console.fontSize": 18,
    "debug.openDebug": "neverOpen", // デバッグ時サイドバーを開かない
}
```
コボる?

#はじめに
初めて記事書くので皆々様お手柔らかにお願いします。
最近、仕事で官公庁系システムに携わっています。
そこで出会ったのがCOBOL！
情処の試験からこの前消えましたね笑
現在はなんやかんや格闘してますので、この機会に紹介してみようかと思います。

##COBOLの全体構成
COBOLプログラムの全体構造を説明していこうと思います。
プログラムは全体で4つに分かれて構成されています。

・見出し部
・環境部
・データ部
・手続き部

各部の中でさらに節と段落に分かれ、構成されています。
それぞれの部で役割が明確になっていて、ソースの可読性が高いと一般的に言われています。
ただ他の言語での実装に慣れている人からすると
「やりづらいなぁ」とか「こういう実装できんの!?てなる部分もあるかもしれません。」
ということで各部の説明をしていこうかと思います。

###見出し部
プログラムのメンテナンス情報を設定する場所になります。
プログラム名や作成者等々を設定しますが、プログラム名以外は廃項目となるらしいので
プログラム名だけ設定すれば問題ないです。
プログラム名を設定するうえで注意する必要があるので、説明します。

1.設定必須
2.見出し部の一番始めに設定
3.日本語ダメ絶対
4.重複禁止

1~3についてはエラーを吐くので気付けると思います。
ただ4に関しては注意して実装してください。
同一のプログラム名を設定してコンパイルした場合、上書きして既存プログラムのオブジェクトを
ぶち壊すことがあります。

###環境部
コンピュータ名や利用ファイル名等、実行に必要な環境を記述する場所になります。
環境部は「構成節」「入出力節」の2つの節の分かれています。

・構成節
ソース作成マシン名や実行マシン名を設定します。
・入出力節
ｲﾝﾌﾟｯﾄ、ｱｳﾄﾌﾟｯﾄﾌｧｲﾙ名を設定します。

入出力がないプログラムであれば入出力節は省略可能です。
構成節は設定しなくても特に差支えありません。
(自分が見た諸先輩方のソースには書いているプログラムはなかったです。)

###データ部

プログラムを構築していく上で事前準備をしていくところです。
ここでは入出力ファイルのレイアウトやデータ項目(変数)等々プログラム内で扱うすべてのデータを
定義する必要があります。
プログラムを実装時に「あっ変数定義してないわ。まぁここでしか使わないから直前で定義しよ」
ってことが出来ないわけです。
(筆者は良くやりがち、本当によくない)
節は全部で5つあります。

ファイル節
作業場所節
連絡節
通信節
レポート節

ここでは詳しい部分は割愛します。まぁここで変数を全部定義するんだなって感じです。

###手続き部

COBOLプログラムで一番最後に記述する部分です。
ここではプログラムが行う処理内容を記述していきます。
手続き部は他の部と異なり規定の節や段落は存在しないです。
プログラムの作成者が執拗に応じて作成していくことになります。

#終わりに
なんやかんや書いているうちに長くなりましたのでこの辺にしたいと思います。
「COBOLプログラムの構成ってこんななんやー」ってわかってもらえれば幸いです。
(わからんぞ!って方、後はご自分で...)
まぁCOBOLに触れる機会自体少ないと思いますが笑

それでは。
【プリザンター】拡張SQL機能を使って自動連番を実装するよ！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/ca19263b-ad17-1993-2cf1-39f2ac1a2653.png" width=30%>

おはようございます！

今回の記事ではプリザンターの拡張SQL機能を使ってテーブルに連番を振っていこうと思います。

# 参考サイト
[プリザンター システム機能:拡張SQL](https://github.com/Implem/Implem.Pleasanter/wiki/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%A9%9F%E8%83%BD%EF%BC%9A%E6%8B%A1%E5%BC%B5SQL)

[プリザンター 拡張SQL書き方の例](https://github.com/Implem/Implem.Pleasanter/blob/master/Implem.Pleasanter/App_Data/Parameters/ExtendedSqls/Sample.json.txt)

[Pleasanter ユーザーマニュアル-拡張SQL](https://pleasanter.net/fs/publishes/422350/edit)

# 自動連番のイメージ
現在、プリザンターのレコードは以下のように3つ存在しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/8f6a2993-75e5-1023-97d7-6d4555acbf2e.png" width=40%>

レコードの一つを覗いてみると・・・

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/bb8c60c1-64d2-2455-62ae-521f3280f900.png" width=40%>

赤枠で囲まれている自動連番という項目がありますね。

作り方は「テーブルの管理」→エディタで作成できます。

（あまりイメージが湧かない方は公式ページを参照しましょう！）
[Pleasanter ユーザーマニュアル テーブルの管理](https://pleasanter.net/fs/publishes/422252)

 

こちらの番号がテーブル作成時に自動で振られていくというイメージになります。

# 拡張SQLの実装
それでは拡張SQLの実装をしていきます。

拡張SQLを書く上で大切なのはまず自動連番を実装したいテーブルのサイトIdとフォームの列名（データベースの列名）です。

まずはSQL Server Management Studioを開き、それぞれの列名を確認します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/be68e89f-74df-ff01-0017-e28a74f8e87e.png" width=40%>
<br>
今回連番を振りたいSiteIdは「62」、フォームの列名は「ClassA」ということが分かりますね！

 

連番を振るSQLは以下になります。

```SQL:自動連番.sql
UPDATE Results SET ClassA = 
(SELECT MAX(ClassA) FROM Results WHERE SiteId = 62) + 1
WHERE ResultId = {{Id}};
```
※{{Id}}はレコードのIDに置換されます。

また、今回は記録テーブルで連番を実装するのでWhere句にResultIdを設定していますが、期限付きテーブルの際はIssueIdで設定を行ってください。

次に上記に掲載した「プリザンター 拡張SQL書き方の例」に倣ってjsonファイルを作成していきます。

```json:自動連番.json
﻿{
    "Description": "Sample",
    "SiteIdList": [62],
    "IdList": null,
    "OnCreating": false,
    "OnCreated": true,
    "OnUpdating": false,
    "OnUpdated": false,
    "OnDeleting": false,
    "OnDeleted": false,
    "OnBulkDeleting": false,
    "OnBulkDeleted": false,
    "OnImporting": false,
    "OnImported": false,
    "OnSelectingWhere": false,
    "CommandText": "UPDATE Results SET ClassA = (SELECT MAX(ClassA) FROM Results WHERE SiteId = 62) + 1 WHERE ResultId = {{Id}};"
}
```

"SiteId"は「62」に設定し、新しくテーブルを作成したときに連番を振りたいので"OnCreated"を「true」としています。

拡張SQLは"CommandText"欄にコピーしてください。

 

作成したjsonファイルは\pleasanter\App_Data\Parameters\ExtendedSqlsに置いてください。

 

それでは、新しくレコードを作ってみましょう！！

先ほどまでに3つのレコードを作っているので次に作られるレコードには「4」が振られればOKです！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538249/173cec81-95ca-5daa-6233-60575fb5fe23.png" width=40%>

無事に「4」が振られました！

# おわりに
ということで、プリザンターの拡張SQL機能を使って自動連番を実装する方法を書きました！

 

拡張SQLは凄く便利な機能なのでぜひ利用してみてください！

ではでは！
Ubuntu 18.04 LTS でpgpool-IIを使ってPostgreSQLをキャッシュする

僕は筑波大学学園祭実行委員情報メディアシステム局のインフラ担当を務めました。
学園祭なのでもちろんのこと[企画検索システム](https://www.sohosai.com/map)が制作されましたが（学園祭プログラマー Advent Calendar 2019 18日目の@siy1121が記事を書いています）、ソフトウェアのデーターベースの設計が好ましくなく、レスポンスが非常に遅くなってしまいました。
データーベースの設計を途中で変更するのはなかなか難しいのでインフラ側で解決しました。
その際利用したpgpool-IIの使い方と説明です。

ネットにはpgpool-IIの使い方はCentOSしかないので、Ubuntuでの運用の仕方を書きます。

# pgpool-IIとは
pgpoolはPostgreSQLとクライアントの間で稼働するミドルウェアです。コネクションプーリングやロードバランスなどの機能を持たせることができます。今回はインメモリキャッシュ機能を使っていきます。
詳細は[こちらのサイト](https://pgpool.net/mediawiki/jp/index.php/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8)をみていただくのがいいのかなと。
<img width="960" alt="簡易的な説明図.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/eec787a1-c1bf-b563-84fb-0ef7976a25f2.png">

# インメモリキャッシュとは
学園祭の[企画検索システム](https://www.sohosai.com/map)を例に説明します。
たとえば、あるタグがついている企画の一覧をデーターベースが返すとき、同じタグを検索したら毎回返す結果は同じはずです。「食べ物」で検索をかけた場合は常に同じ結果が帰ってくるはずです。
つまり、以前問い合わされたことのあるSQL文がまた問い合わせられたら、結果を最初の段階でキャッシュしておき、そのキャッシュを返答すれば無駄のない処理となります。
ここで問題なのは、INSERT文などでデーターベースの内容が書き換わったときです。
その際はpgpool-IIは対象のテーブルのキャッシュを自動的に全て消去します。
つまり、pgpool-IIを再起動することなく自動的にPostgreSQLとのデータに不整合がないように調整してくれます。
学園祭当日になって（ありえないが、）食べ物を出店する企画が増え、INSERT文で企画を追加したとしても、pgpool-IIは自動的に対象のテーブルに対するキャッシュを消去し最新のデータを返します。
なお、このキャッシュ機能は最近はソフトウェア側でこの処理をすることが増えてきたそうです。



# 導入


```sh
echo "deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main" | sudo tee -a /etc/apt/sources.list.d/pgdg.list
curl -s https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
sudo apt update
sudo apt upgrade
sudo apt install pgpool2
```

参考：http://nodoka.org/postgresql-11-pgpool2-ubuntu-18-04/

# 設定
今回、ソフトウェア（企画検索システム）は何も設定しなくてもいいように、PostgreSQLとpgpoolのポート番号をいじります。

PostgreSQLの設定ファイルはバージョンによって設定ファイルの場所が違うので注意。

それぞれ、以下の設定項目を見つけて編集します。


```conf:/etc/postgresql/11/main/postgresql.conf
port = 60001                            # PostgreSQLのポート番号　好きに設定する
```


```conf:/etc/pgpool2/pgpool.conf
port = 5432                        # pgpoolのポート番号 ソフトウェアはここにアクセスする

backend_port0 = 60001              #PostgreSQLで設定したポート番号

memory_cache_enabled = on          #キャッシュを有効化します。
```

設定を有効化するためにはそれぞれの再起動が必要です。

```shell
systemctl restart postgresql
systemctl restart pgpool2
```

もし `systemctl restart pgpool2` が失敗する場合はいったんサーバーを再起動してください。


導入は以上です。キャッシュが使えるメモリの量など細かい設定もできます。それはググってください

# 結果
pgpool-IIを導入する前に検索にかかる時間が48.95秒（！？？？？）だったものが・・・
![委員会開催企画2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/c16a9bed-a2f0-4929-1d47-53e8a05c06b3.png)

45.12ミリ秒の検索時間になりました！やったね！！
![委員会開催企画2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510882/13fef326-b51e-fe1f-e6c9-9b2bf2da6fc5.png)
rails db:resetとrails db:migrate:resetの違い

##rails db:reset
- データベースを全て削除
- `schema.rb`に書かれている内容を元にデータベースを作成
- `seeds.rb`に書かれているサンプルデータを読み込む

##rails db:migrate:reset
- データベースを全て削除
- マイグレーションファイルを古い順に全て実行

自分は基本的にこちらを利用します。
注意点として、`seed.rb`の読み込みは行わないので、`rails db:seed`を手動で実行する必要があります。
サイトに某ほとけ風な何かを呼び出すjQueryプラグイン・hotoke.jsを作った

ご存知の方は知っている某ドラマで現れる、「ほとけ」風ななにかを自分のサイト内に呼び寄せるjQueryプラグインを作成しました。

## デモ
実装サンプルはこちらになります。ページを開いてから数秒後に登場します。
<a href="http://webdrawer.net/sample/js/hotoke/index.html" target="_blank">hotoke.jsのサンプルページ</a>

## 使い方
以下のファイルを表示させたいページに読み込みます。

- hotoke.css
- jQuery（今回はバージョン2.2.4を使用して作成しました。他のバージョンで動くかは未検証です。）
- hotoke.js

```html
<link rel="stylesheet" href="hotoke.css">
<script src="jquery-2.2.4.js"></script>
<script src="hotoke.js"></script>
```

ファイルを読み込むパスはそれぞれ変更してください。
そして使用したいページで以下を記述します。

```html
<script>
$(function(){
  $('body').hotoke();
});
</script>
```

これで実行されます。

## カスタマイズ方法

### オプション

オプションが2つあり、

- timeStart　ほとけ呼びかけるまでの時間を指定（ミリ秒）
- hotokeImgPath　ほとけの画像へのパス（読み込むHTMLからのパス）

```html
<script>
$(function(){
  $('body').hotoke({
    timeStart : 3000,
    hotokeImgPath : '../../hotoke.png'
  });
});
</script>
```

デフォルトでは3000ミリ秒でほとけが呼びかけ始めます。画像はそのHTMLと同階層のhotoke.pngを読み込みます。

### セリフの変更
最初の呼びかけと、その後のセリフの編集はhotoke.jsを編集します。hotoke.jsの以下の部分を編集してください。ファイルの上部にあります。

```javascript
//最初の呼び出し文言
var hotokeShout = [
  'ヨ○ヒコー',
  'ヨ○ヒコよー'
];

//ほとけ降臨後の文言
var hotokeWords = [
  'ここにセリフを入れることができます。',
  'セリフ2',
  'セリフ3'
];
```

ここに文言を追加・編集することで表示されるセリフが変わります。最後の項目以外は文末にカンマが必要です。

### 見た目の変更
hotoke.cssを編集してください。ちなみに、最初の呼び出し文言は文字数によって、降臨後の文言は画像の幅によって吹き出しのサイズが変わりますがCSSで変更可能です。


### 画像の変更
hotoke.pngを差し替えてください。デモの画像はフリー素材を組み合わせただけなので、あなただけのほとけを降臨させてください。
RailプロジェクトをGitHubで管理する時にやること

Railsプロジェクトを複数人で管理をする時に最初にやることをまとめました。

##READMEを編集
各種ツールのバージョンや設定方法等を記載しましょう。
ツールの宣伝を書くこともあります。

##.gitignoreの編集
git管理対象外とするファイル、ディレクトリを設定します。
[gitignore.io](https://www.gitignore.io/)を利用すると、言語等に合わせてそれっぽい.gitignoreファイルが手に入ります。あとは必要に応じてカスタマイズしましょう。

##database.ymlを複製
`database.yml`を複製し、`database.yml.default`などの名前をつけます。
また`.gitignore`に`database.yml`を追加し、git管理から外しましょう。

各開発者は、`database.yml.default`の情報に、ローカルPCのパスワードなどを追加して、オリジナルの`database.yml`を作成します。

`.env`ファイルを扱う場合も同じで、環境によって影響がでるファイルは、オリジナルを別名で保存し、そちらをgitで管理するようにしましょう。
DropdownButtonで選択されたテキストのスタイルをドロップダウンの開閉によって変える

[DropdownButton](https://api.flutter.dev/flutter/material/DropdownButton-class.html)を使うときに、選択されたテキストのスタイルをドロップダウンが開いた状態と閉じた状態とで変えたい場合、`selectedItemBuilder`と`items`を使い分けると実現できます。

```dart
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final String text = "Flutter";
  
  List<String> _items = ["A", "B", "C"];
  String _selectedItem = "A";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: DropdownButton<String>(
          value: _selectedItem,
          onChanged: (String newValue) {
            setState(() {
              _selectedItem = newValue;
            });
          },
          selectedItemBuilder: (context) {
            return _items.map((String item) {
              return Text(
                item,
                style: TextStyle(color: Colors.pink),
              );
            }).toList();
          },
          items: _items.map((String item) {
            return DropdownMenuItem(
              value: item,
              child: Text(
                item,
                style: item == _selectedItem
                    ? TextStyle(fontWeight: FontWeight.bold)
                    : TextStyle(fontWeight: FontWeight.normal),
              ),
            );
          }).toList(),
        ),
      ),
    );
  }
}
```

↓ `selectedItemBuilder`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87546/82a785e1-7940-0ad5-2097-9f3b677e7de7.png)

↓ `items`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87546/9ec3a3f2-78e1-7ccd-5df1-ec9fb81ac91b.png)

[dropdown.dart](https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/dropdown.dart#L1257)を見ると、enabledで`selectedItemBuilder`がnullの場合は`List<Widget>.from(widget.items)`が使われることがわかります。

```dart:[flutter/lib/src/material/dropdown.dart#L1257]
// The width of the button and the menu are defined by the widest
// item and the width of the hint.
List<Widget> items;
if (_enabled) {
  items = widget.selectedItemBuilder == null
    ? List<Widget>.from(widget.items)
    : widget.selectedItemBuilder(context);
} else {
  items = widget.selectedItemBuilder == null
    ? <Widget>[]
    : widget.selectedItemBuilder(context);
}
```

https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/dropdown.dart#L1257
jetson nanoと3つの公式SDカードイメージ

# Jetson Nano Developer Kit SD Card Image
Jetson Download Center やGetting Started With Jetson Nano Developer Kit にリンクされている。
https://developer.nvidia.com/embedded/downloads
名前のとおりだが、Jetson Nanoの開発用にチューニングされている。
初回起動時にubuntuのinstallがはじまる。


# jetcard
Jetson Nano Developer Kit SD Card ImageをベースにJupyter LabサーバーやPyTorchやTensorFlowなどがプリインストールされている。AIプログラミング用にチューニングされている。githubで[公開](https://github.com/NVIDIA-AI-IOT/jetcard)されており、ダウンロード先はGoogleDrive。公式なのに、なんでGoogleDriveなのかわかりません？


# NVIDIA DLI Jetson Nano SD Card Image 
[jetson nano講座](https://courses.nvidia.com/courses/course-v1%3ADLI%2BC-RX-02%2BV1-JA/)で配布される、学習用のイメージ。また、DLIはDeep Learning Instituteの略である。
Jetson Nano Developer Kit SD Card ImageをベースにJupyter Labサーバーなどがプリインストールされている。
https://developer.download.nvidia.com/training/nano/dlinano-ja-v1-0-0_image_20GB.zip

# jetcardとNVIDIA DLI Jetson Nano SD Card Image
初回起動時にはubuntuはインストール済みであるが、ネットワーク、ユーザ設定など行う必要がある。

共にヘッドレスモードモードが使える。以下のように構成する。
![headless_dev-mode_animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514297/48d89d53-9d9e-d1cc-2dc0-e19655a17ac4.gif)

Jupyter LabのIPアドレスは[192.168.55.1:8888](http://192.168.55.1:8888/login)である。ただし、firefoxでは設定が必要らしく、宗教上の理由でfirefoxしか使えない人以外はChromeを使用するのが安牌。
jetcardの初期パスワードは`jetson`である。
NVIDIA DLI Jetson Nano SD Card Imageの初期パスワードは`dlinano`である。


# まとめ
Jetson Nano Developer Kit SD Card Imageとjetcardのどちらかという選択肢になりそうです。どちらを選んでも、後から設定が必要になりそうなので好みの問題なのかなという感じ。僕はjetcardを選びました。
QGISで地図PDFを簡単に出力するプラグイン「EZPrinter」をつくりました

## はじめに
QGISの基本機能としてのPDF出力は、範囲や縮尺の指定が微妙に使いにくいです。
レイアウト機能を使って少し手間をかければ、かなり綺麗な地図も作成出来ますが、QGISで表示している地図をサクッと紙などに出力したい時のためにプラグインを作りました。

## EZPrinter

[EZPrinter/GitHub](https://github.com/Kanahiro/EZPrinter)
制作期間：３週間くらい

### 使用例
![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/e0643430-5b18-4bf0-9c82-3e5cc0c822f4.gif)


### 使い方
* 用紙サイズを選択します
* 縮尺を選択します
* 印刷したい領域を選択します
* ダイアログがポップアップするので、タイトルやサブテキスト、スケールバーをカスタムします。
* Export PDFでお好きな場所に出力

### 作図例
旭川市駅前エリア、A4、1/2500
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/725aecf5-289a-5d3a-bc3d-5334753de35d.png)

### 参考サイト
[QGIS3.x系向けプラグイン作成手順や各種処理の実装方法について](https://qiita.com/Kanahiro/items/205d1128dcdaf3ad9506)
[QGIS Python API documentation project](https://qgis.org/pyqgis/master/index.html)
draw.io をコマンドラインで実行して、画像ファイルをエクスポートする

## draw.io をコマンドラインで使いたい
ダイアグラムを作成するのに便利な [draw.io](https://www.draw.io/) ですが、画像ファイルのエクスポートをコマンドラインで実行できたら、ドキュメントのビルドなんかに使えて便利だろうなと思い調べてみました。

## drawio-desktop のインストール
オンライン番が有名な [draw.io](https://www.draw.io/) ですが、コマンドラインで実行するにはローカル環境にインストールする必要があります。まずは、[drawio-desktop のリリースページ](https://github.com/jgraph/drawio-desktop/releases) からダウンロードしてインストールしてください。

> 補足
> 少し前までは、下記URLにデスクトップ版のインストーラがあったのですが、いつの間にかリンクが消えてますね。
> https://about.draw.io/integrations/#integrations_offline
> Githubでは引き続き公開されているので、Githubのリリースページからダウンロードしましょう。
> https://github.com/jgraph/drawio-desktop/releases

## エイリアスの登録
次に、コマンドラインで使いやすいようにエイリアスを登録します。
実行ファイルのパスは、異なることがあるので、自分の環境でインストール先を確認してください。

__macOS__

```
alias draw.io=/Applications/draw.io.app/Contents/MacOS/draw.io
```

`.bash_profile` とかに保存しておくと、毎回入力する必要がなくて便利です。

__Windows__

```
doskey draw.io="C:\Program Files\draw.io\draw.io.exe" $*
```

`doskey` とか言うコマンド、初めて知りました。

## コマンドラインでの実行
コマンドラインで実行する準備が整ったので、早速試してみましょう。

```
draw.io --help
```

下記のような、ヘルプページが表示されるはずです。

```
Usage: draw.io [options] [input file/folder]

Options:
  -V, --version                      output the version number
  -c, --create                       creates a new empty file if no file is passed
  -k, --check                        does not overwrite existing files
  -x, --export                       export the input file/folder based on the given options
  -r, --recursive                    for a folder input, recursively convert all files in sub-folders also
  -o, --output <output file/folder>  specify the output file/folder. If omitted, the input file name is used for output with the specified format as extension
  -f, --format <format>              if output file name extension is specified, this option is ignored (file type is determined from output extension, possible export formats are pdf, png, jpg, svg, vsdx) (default: "pdf")
  -q, --quality <quality>            output image quality for JPEG (default: 90)
  -t, --transparent                  set transparent background for PNG
  -e, --embed-diagram                includes a copy of the diagram (for PNG format only)
  -b, --border <border>              sets the border width around the diagram (default: 0)
  -s, --scale <scale>                scales the diagram size
  --width <width>                    fits the generated image/pdf into the specified width, preserves aspect ratio.
  --height <height>                  fits the generated image/pdf into the specified height, preserves aspect ratio.
  --crop                             crops PDF to diagram size
  -a, --all-pages                    export all pages (for PDF format only)
  -p, --page-index <pageIndex>       selects a specific page, if not specified and the format is an image, the first page is selected
  -g, --page-range <from>..<to>      selects a page range (for PDF format only)
  -h, --help                         output usage information
```

## 画像ファイルをエクスポート
画像ファイルをエクスポートするには、次のように実行します。

```
draw.io -xf svg -o diagram.svg diagram.drawio
```

フォルダごとまとめてエクスポートすることも可能なようです。

```
draw.io -xrf png -o output/ input/
```

ドキュメント生成ツールと組み合わせれば、色々と応用がききそうです。
本番機で油断してPSOD出しちゃった

#はじめに
現在Qiitaにて「本番環境でやらかしちゃった人 Advent Calendar 2019」(https://qiita.com/advent-calendar/2019/yarakashi-production )が開催中です．私も毎日記事を読ましていただき，勉強をさせていただいています．

さて，私は本番環境...ではなくその一歩前の本番機の構築時に大きな失敗をしてしまった経験があります．当カレンダーに書くほど私が文才があるわけではないので，こっそりと投稿させていただきます．

#概要
どんな環境を構築していたかというと，仮想基盤(PoweredgeにてESXi)です．
導入する環境がVLAN が設定されており，最終的にホストのManagement Network にVLAN IDを設定する必要がありました．しかし，近くにVLAN 対応のスイッチがなく，まぁ最後に設定入れればいいかと思い設定していました．
※この油断が原因で大変な思いをして，結局スイッチ借りてきてVLAN の設定をしました．
環境の概要については https://qiita.com/ydetectiveu007/items/32790e9eece199a7a81a を参照してください．

とにかく，VLAN の設定がなにもされていないスイッチを使い，ESXiの設定をしていました．
設定自体は以下を設定しました．

- iDRAC
- ESXiホスト
- ネットワーク
- ストレージ
- OMSA

ここで，ネットワークの設定でVMKernel という仮想マシン以外で使用するネットワークの設定（例えば，ESXi ホスト自身へのアクセス，ストレージへのアクセス，vMotionなど）をしていました．簡単に書くと以下のような形です．

|vmk|	IPアドレス|	備考|
|:------------------------:|:------------|:------------|
|vmk0|  192.168.0.1| Management Networkアクセス用．VLAN IDを設定する必要がある|	
|vmk1|	192.168.1.1|ストレージアクセス用|
|vmk2|	192.168.2.1|ストレージアクセス用|
|vmk3|	192.168.3.1|ストレージアクセス用|
|vmk4|	192.168.4.1|ストレージアクセス用|
|vmk5|  192.168.5.1|vMotion用|

このようにESXi のWeb UIを使ってvmkを設定し，最後にDCUIでvmk0 にVLAN を設定しました．
すると...

#なにが起きたか
<b>なんとホストのIPアドレスが本来ストレージアクセス用に設定したvmk1 のIPアドレスである 192.168.1.1 に変更されてしまいました．</b>

#その後の展開
IPアドレスが何の予告もなく勝手に変更されてしまい，とにかくパニックになりました．（しかも本当に最後の最後だったので，ショックも大きかった）
何とか元の設定に戻そうとしてIPアドレスを変えようとしたり，Management Network に割り当てられているネットワークアダプターも変わってしまっていたので，それを戻そうとしました．しかし，以下のようなメッセージが出力されて元に戻ることはありませんでした．
※搬入直前でスケジュールに余裕がなかったこと，もう終わりだという安堵感からこの状態に陥ったこともありちゃんとしたオペレーションは覚えていませんでした．

```:出力されたメッセージたち
Enable Management Network: Error
Setting ip/ipv6 configuration failed: Unable to Set: Sysinfo error:
Address already in useSee VMkernel log for details.

Network Adapters: Warning
One or more of the selected adapters are already used for other connections.

Unable to Set: Sysinfo error: Network
unreachableSee VMkernel log for details
```

上記のようなメッセージ（特に一番上のメッセージ）は何回も出てきました．
多分，あなたが設定しようとしているIPアドレス（192.168.0.1）はほかのvmkで既に使われているため設定できないよ．というニュアンスだと思います．

#結果どうなったか
何回かネットワークの設定を戻そうと必死にもがいていると，ついにやつが現れました．
ESXi 界のブルースクリーンことPSOD (Purple Screen of Death: https://kb.vmware.com/s/article/2150124) です．
うわさには聞いていましたが，鮮やかな紫色でした．そして，これを自分が操作している本番機の目の前で見ることになるとは夢にも思いませんでした．

#どう対応したか
<b>再起動です．</b>どうにもならなくなった時の再起動，やはり最強です．再起動したおかげで，IPアドレスは変わったままでしたが，何とか無事に起動しました．
（本番環境でなくてよかった...）

#最終的には
どのようにオペレーションしたのか詳しく覚えていませんが，IPアドレスを元に戻すことに成功しました．そして，スイッチを借りてきてVLAN を作成し，無事に設計通りのパラメータにすることができました．
（実はもうひと悶着ありましたが）

#なぜこのようなことが起きたか
詳しくはググってもよくわかりませんでしたが，<b?ESXi が接続性を可能な限り確保する仕様になっている</b>からであると推測します．
今回VLAN を設定したことにより，スイッチにVLANが設定されておらず，ホストのIPアドレスに接続できなくなってしまうので，それではまずいとESXiが判断し，ほかの接続できるvmkのIPアドレスを自動的にホスト自身のIPアドレスに変更してしまったのではないかと推測しています．

上記仕様を知らなかったこと，それ以上に本番環境と同じ，もしくは近い環境の構築を怠った自分の油断というか怠惰が原因であると考えています．

今後は検証や構築の際，本番環境と同じ環境を構築するよう心がけます．
（でないと思わぬ製品の仕様で今回のように痛い目に遭ってしまう...）

#今回学んだこと
いろいろ学びました．
- ESXiでVLANを設定するときは最初にVLAN の環境を構築しておくこと（最後に痛い目見る）
- PSODになったら再起動すること
- iDRACにクラッシュした際の情報が保存されている（後から気づいた）
- ★環境構築は本番に可能な限り近い環境を用意するよう努力すること（一番大事）

以上です．このような事例はググっても特に出てこなかったので，こんなミスするのは私くらいのようなものらしいですが，本記事の内容がどなたかの助けになれば幸いです．
Notionのデータベースでフィルタとソートをする

[アルプ株式会社](https://thealp.co.jp/)でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2019](https://qiita.com/advent-calendar/2019/notion) 14日目のエントリです。
13日目は[Notionでデータベースを作る](https://qiita.com/pictiny/items/dba21dd5d226ac5b6849)でした。

# View
13日目の[Notionでデータベースを作る](https://qiita.com/pictiny/items/dba21dd5d226ac5b6849)では、データベースの表示設定を保存できる**View**を紹介しました。
**View**に保存できる表示の設定にフィルタとソートがあります。

## フィルタ
データベースの右上の`Filter`からメニューを開き、条件を入力できます。
フィルタを設定すると、条件に一致したデータだけを表示することができます。

<img width="522" alt="フィルタ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/deef6add-a800-4ab1-c64d-d16a3aeedd66.png">

使える条件は**プロパティ**の種類によって異なります。
複数の条件を組み合わせる場合には、AND条件かOR条件を選択します。

## ソート
データベースの右上の`Sort`からメニューを開き、条件を入力できます。
ソートを設定するとデータの並びが整理されます。

<img width="413" alt="ソート" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/26d8706f-eb5a-5864-999d-e293618b529e.png">

ソートのキーになる**プロパティ**と昇順か降順を選択して設定します。
フィルタと同じく複数のソート条件を追加でき、上にある条件の優先順位が高くソートされます。
追加したソート条件はドラッグ・アンド・ドロップでも並び替えることができます。

# まとめ
公式ドキュメントは[Filter](https://www.notion.so/Intro-to-databases-fd8cd2d212f74c50954c11086d85997e#6593c3c178e0462897586a2ccb2b1f3a)や[Sort](https://www.notion.so/Intro-to-databases-fd8cd2d212f74c50954c11086d85997e#ab89ca64a96640b0bc09182522af8083)にありますので、そちらもご覧ください。
clound9にPHP、Laravelの環境構築をする

# はじめに
PHP、Laravelを学習するために環境構築の備忘録として記載

# 環境
AWS Cloud9

# インストール
PHP 7.2
Laravel 5.5

# 1.PHPのセットアップ
#####リポジトリのインストール

```:
$ sudo yum -y install http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

<中略>
Installed:
  remi-release.noarch 0:6.10-1.el6.remi                                                                                                                                                                                                        

Complete!
```
#####PHP 7.2と必要なパッケージをインストールする

```
$ sudo yum -y install php72 php72-cli php72-common php72-devel php72-gd php72-intl php72-mbstring php72-mysqlnd php72-pdo php72-pecl-mcrypt php72-opcache php72-pecl-apcu php72-pecl-imagick php72-pecl-memcached php72-php-pecl-redis php72-php-pecl-xdebug php72-xml

<中略>
  policycoreutils-python.x86_64 0:2.1.12-5.25.amzn1        python27-IPy.noarch 0:0.75-1.6.6.amzn1                   scl-utils.x86_64 0:20120229-1.el6                                        selinux-policy.noarch 0:3.10.0-98.26.amzn1        
  setools-libs.x86_64 0:3.3.7-34.23.amzn1                  setools-libs-python.x86_64 0:3.3.7-34.23.amzn1           tcl.x86_64 1:8.5.7-6.9.amzn1                                            

Complete!
```

#####デフォルトでPHP 7.2を使えるように設定する
cloud9には最初から古いバージョンのPHPがあるため先ほどインストールしたPHP 7.2をデフォルトで使えるようにする

```
$ sudo alternatives --set php /usr/bin/php-7.2
```

#####バージョンを確認し、7.2.*がインストールされているのかを確認する

```
$ php -v
PHP 7.2.24 (cli) (built: Oct 31 2019 18:03:13) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.24, Copyright (c) 1999-2018, by Zend Technologies
```

# 2.composerのインストール

#####Laravelをインストールするためには、composerというパッケージ管理ツールを利用する必要がある

```
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
```
##### composerの確認

```
$ composer about
Composer - Dependency Manager for PHP
Composer is a dependency manager tracking local dependencies of your projects and libraries.
See https://getcomposer.org/ for more information.
```

#####※Your environment is running out of quota. Please make some free space.という警告
もし上記のような警告がCloud9の右上に出てきたら下記コマンドでメモリを開放すると解決するかもしれない

```
$ sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
```
# 3.Laravelプロジェクトを作成する
home(environment)で

```
$ composer create-project laravel/laravel ./プロジェクト名(任意) "5.5.*" --prefer-dist
```

※ `"5.5.*"` と指定することで5.5の中での最大のバージョンがインストールされる。

以上
スマホでVPN接続してサーバーの電源OFF/ON

サーバーにVPN接続、サーバーの電源OFF/ONを、全てスマホ（Android）でやりました。
というだけの事です。
滅多にやらないので、手順の備忘です。

##事情
休日にサーバーの電源をOFF/ONしなければならない時があります。
（建屋の電源の工事とか検査とか）

##働き方改革
そもそも、サーバーがオンプレミスなのが悪いのですが、
休日に仕事場には行きたくありません。
なので家からVPN接続して操作するのですが、
外出中に対応しなければならない時があります。
家族で出かけているのに、仕事でPCを持ち歩くのは、時代に逆行しています、家族に何か言われそうです。

なので、スマホで全て操作してみました。

##電源OFF
UTMメーカー謹製のスマホアプリでVPN接続
[ConnectBot](https://connectbot.org/)でサーバーにSSH接続
su - 成り上がり
shutdown -h now

##電源ON
UTMメーカー謹製のスマホアプリでVPN接続
サーバーのリモートマネージメント機能
（サーバーが起動していなくても、電源ON/OFF出来る機能）
で、サーバーの電源ON。

##結果
ログインパスワードのセットが、スマホだとイライラしますが、
出先の美味しいものを調べるふりをすれば、何をしているか家族にバレません。
平和が一番です。
プロキシ環境でpip install

# 概要
プロキシ環境でpip installするとき、コマンド忘れてググることがたまにあるので自分用にメモします。


## 方法
インストール対象がhoge、ユーザーがusername、パスワードがpassword
プロキシがfoo、ポート番号が8080の場合

```
pip install hoge --proxy=http://username:password@foo.proxy.local:8080
```


複数のライブラリをインストールするとき、上記の"--proxy=~"を毎回打つのめんどくさいので、
初めに以下のコマンドを打って、

```
set HTTP_PROXY=http://username:password@foo.proxy.local:8080
set HTTPS_PROXY=http://username:password@foo.proxy.local:8080
```

そのあと普通に、以下で所望のライブラリをインストールしてもOK

```
pip install hoge
```

以上
自分用 Ruby on Rails 初歩メモ

# Rubyの要注意基本文法
* 文字列(String) とシンボル(Symbol) の違いに注意<br>
https://qiita.com/Kta-M/items/53a13ef60e14fcb41193
* 文字列内の変数展開は ‘#{hoge}’ 表記

# 名前付きルートの使い方
1. 対象のルーティングの末尾に ‘as HOGE’ を追記
2. View で対象のルーティングに遷移するリンクのURLにて’HOGE_path’ と指定
3. もし、対象のルーティングにパラメータを渡す際は、 ‘HOGE_path(x)’ の表記になる。

# インスタンス変数とローカル変数
`@hoge` : インスタンス変数、ビューに渡せない
`hoge` : ローカル変数、ビューに渡せる

# コントローラの基本7アクション
* new	データを新規作成する
* create	データを追加（保存）する
* index	データの一覧を表示する
* show	データの内容（詳細）を表示する
* edit	データを更新するためのフォームを作成する
* update	データを更新する
* destroy	データを削除する

# View で利用するタグについて
`<%　%>` では、タグ内の結果が画面に表示されずに処理される。
`<%=　%>` では、タグ内の結果が画面に表示される。

# form_for における POST, PATCHの判定
form_forにおけるsubmit時のメソッドについて、特にPOST, PATCHから適切なものが指定される。
これは、コントローラから渡されたオブジェクトがEmptyかNotEmptyかによってActiveRecordのnew_record?メソッドは自動で判別してくれているため。

# redirect_to と render　の違い
* redirect_to は、指定ルーティングに対してHTTPリクエストを投げる。そのため、コントローラ内の処理も実行される。

* render は、他のアクションに対応するVierw を呼び出す。
View の描写のみを行うため、HTTPリクエストを送ったり、コントローラ内の処理は実行しない。
初学者に「覚える必要はない」という言葉がけは危険

###プログラミング塾に通っています
こんにちは。
　まーこです。

　10月から塾で学ぶプログラミングを始めました。（今までは個人勉強で学習していましたが、成長がないので塾に通うことになりました。）
　そこで、学ぶなかで、新しい概念や用語や態度に出会うのですが、そこでの考察をメモします。
　元々、ファインアーティストとして活動していたため、文章に感覚的な部分があります。
　プログラマーのように、ロジカルに書くことができないのですが、努力いたしますのでよろしくお願いします。

###「覚える必要はない」というけれども
　覚える必要がないと経験者の方はおっしゃるのですが、これ**初心者の人にとって意味を取り間違える危険性**がある気がしています。

###「暗記ではなく理解しなさい」というけれども

　**「理解するって何を理解するの・・・？」**
　
　これが私が感じでいた勉強での出来事です。
　初学の人にとっては何を理解すればいいか分からないのではないかと思います。ましてや理解する内容はどれが理解するべき事項なのか分からない。。。
　そのため、私は自分が何を分かっていなくて、何につまづいているか分析すれば理解できていないところが理解できるのでは？？？と思って、ググってググってググって・・・。

###「分からなければググりなさい」というけれども
　
　**ググる先にまた分からないことがあって、ググってググって・・・・帰ってこれなくなってしまったんですよね笑**
　理解するつもりが余計に新しい知識を得て、メタレベルでは理解が深まって行くのですが、先生が期待する表層の”理解すべき内容”に辿りつけなかったんですよね笑
　それなら一発で答えを言ってほしい・・・なんて思ったりしていました。

*（先生の気持ちとしては自分で調べる力をつけてほしいとのことでしたが、初学者には効率が悪すぎると思います。。。日常でスマホを使い検索しているのが習慣化されているはずなので、現代人にとっては検索する能力は弱くないスキルだと思うのですよね。ただ、検索した先の決断能力は別。でもこの能力、全てを一度勉強した後、自然に身についてくる能力では？そんな気がします。）←完全愚痴*

###覚える必要はあるのでは？
　覚える必要はある気がします。
　**「何を覚えるのか」**が実は経験者の方は伝えたいのではないかというのが私の推測です。

###では、何を覚えさせたいのか
　**このコマンドが「何ができる」を把握（覚え）させたい**

　2ヶ月半プログラミングの塾に通ってやっとここに行き着きました。2ヶ月半もかかりました。
　実はこの間2人の先生から教わっています。**「ふーん」**程度でよいということだそうです。
 *（理解と言われると「なるほど！」だと思うじゃないですか！！！？）←完全愚痴*

###しかし、暗記は最強なのではないか
　最終的には暗記は最強なような気がしています。せっかちの人は特に。生産性はすごく上がる気がします。毎度毎度調べるの面倒です。
　そこで、頭文字だけ暗記すればよいEmmetを導入しました。これがまた便利！！
　そしてvscodeエディタの推測でコードを表示してくれる機能。これがまた便利！！その他、記憶の補助となる拡張ツールを入れました。

###「覚えてもよい」
　覚えるのは決して悪いことではない気がします。コードを描き速さが上がると勉強のモチベーションが上がりますし。
　これは個人の能力や性格によるのかもしれません。私はせっかちだし、飽きっぽいし、面倒くさがりなので、覚えた方が効率がよかったです。
　覚えて量をこなすなかで、なんとなく分かってきた時間の方が、量をこなさず、理解に費やすためにググったりコードを見直していた時間と比べるととても有意義でした。

　もし、「覚える必要はない」という一般化されたプログラミング学習お作法言葉にひっかかりを感じている方は、どうか試してみてください。

　学習メモをここまでご覧頂きましてありがとうございました！
Swift勉強日記　〜Part 1〜

#はじめに
やっとmacを手に入れたのでSwiftの勉強を始めました。
HackingWithSwiftのProject１を進めるにあたって今後のためにメモしておきたいと思ったことを綴ります。

#コマンドのCheat Sheet
・Cmd + R : Simulatorの起動
・Cmd + . : Simulatorの終了
・Cmd + L : Libraryの表示

#用語集
FileManager.default : ファイル操作をするために必要なデータタイプ。
Bundle : コンパイルされたプログラムや全ての要素を含むディレクトリである。
UITableViewController : スクロールや選択できる複数行のデータを表示できる。

#データファイルの追加方法
データファイルを左側のNavigation AreaにDrag＆Dropする。
<img width="1440" alt="スクリーンショット 2019-12-14 0.41.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501835/3c8cb52d-612e-31a2-4136-9df56d6b157c.png">


と以下の図のような画面が出現する。
<img width="730" alt="スクリーンショット 2019-12-14 0.31.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501835/8f821121-7c3e-b107-3a09-2c69af199c06.png">

この際
・Copy items if needed
・Create groups
という項目がチェックされているか確認すること

#ファイル名の取得方法
pathで取得したディレクトリ内のファイル名を全て取得する。

```Swift
let path = Bundle.main.resourcePath!
let contents = FileManager.default.contentsOfDirectory(atPath: path)
```

#列の表示方法
TableViewにおいて表示する列の数を設定する

```Swift
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return //ここに表に表示させたい列の数
}
```

#UITableViewControllerへの変更方法
まず

```Swift
class ViewController: UIViewController 
```
を

```Swift
class ViewController: UITableViewController 
```
に変更する。

次にMain.storyboard内において、デフォルトで設定されている View Controller Scene を Table View Controller に変更する。
<img width="1440" alt="スクリーンショット 2019-12-14 1.26.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501835/355a7a7d-42ec-4b99-7a47-d1e8b537170a.png">

#Navigation Controllerとは？
Table View Controller を Navigation Controller に Embed In すると、iPhoneの設定上部で見られる画面遷移のための Navigation Bar が表示される。
<img width="414" alt="IMG_A41E31204DB4-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501835/dfdba5b2-a68b-ca9b-d4bd-2dd451a217fc.jpeg">





参考Webサイト
https://www.hackingwithswift.com/100
強化学習３６　githubのコミットを削除する

中学から大学生までのAI初学者を対象にしています。

chokozainerはgithubをファイル置き場兼公開に使用しています。
ファイル置き場としてはいいのですが、公開用となると、今までのbugfixなどが大量に残っているので、いろいろと問題があります。
まるごとダウンロードしようとすると、全く不要な古いファイルまでのダウンロードされてしまうのです。

そこで、一番最近の状態を残して、過去の全コミットを消去する方法を探しました。
該当するフォルダに移動して、
コンソールで以下のようになります。

```bash

git checkout --orphan tmp
git commit -m "Initial Commit"
git checkout -B master
git branch -d tmp

git push origin +master
```
detached HEADになった後にめっちゃcommitしてしまった、、

##発生した状況と手順
開発中、同じブランチの以前の状態に戻りたくなり
`git reflog`→`git checkout <commit id>`で過去の状態に戻った
↓
エラーメッセージっぽいものが出ていたけど、無視してそのまま10回くらいcommitを重ねた
↓
GitHubにPushができなくなってしまった

##detached HEADとは
現在の地点が、ブランチから切り離されてしまっている状態。
ターミナルのプロンプトに現在のブランチ名を表示させているのですが、気がつくとブランチ名ではなく`d8d36db9f649a163b097`のようなSHA1が表示されちゃってました。

##何がまずいのか
どのブランチにも属していないので、PUSHができません。
あと、うまいことやらないと行った変更が全て消えてしまいます。

##うまくいった対処法
新規ブランチを作成し、

```terminal
$ git branch tmp
```

元いたブランチに移動し、

```terminal
$ git checkout create-header
```

作成したブランチを取り込む

```terminal
$ git merge tmp
```

コミット履歴に、マージをした記録が残ってしまいますが、個人的にはオッケーです。
無事解決できてよかった。

##うまくいかなかった対処法
現在のブランチのSHA1を取得

```terminal
$ git rev-parse HEAD
d8d36db9f649a163b097
```

SHA1からブランチを取得

```terminal
$ git name-rev d8d36db9f649a163b097
d8d36db9f649a163b097 master
```

現在`master`ブランチが指すコミットにいることがわかったので、移動

```terminal
$ git checkout master
```

私の場合`git name-rev d8d36db9f649a163b097`をしてもブランチ名が取得できなかったので、この方法ではうまく行きませんでした。
過去のコミットに戻る、という動作をした場合、この方法は使えないのかもしれません。

逆にdetached HEADになった直後はこの方法で修正できそうです。

##今後に向けて
過去のバージョンに戻りたい時には、`git checkout <commit ID>`ではなく`git reset --hard [commit id]`を使う！

##参考
[gitのHEADがブランチから外れてしまう現象とその直し方](https://nishiohirokazu.hatenadiary.org/entry/20110513/1305290792)
[detached HEAD から脱出する方法を git の内部構造から探る](https://qiita.com/Kuniwak/items/4e5d55d6888e5f6411fe)
ドメインを取得する時に考えておくべき事

# はじめに
ドメインを取得する時に気にしておくべき事を考えました。
取得したドメインの管理をしている中で思ったことを残しておこうと思います。

## 対象読者
- ドメインを取得しようと考えている方
- ドメインの管理者
- 知的財産の管理者

## ドメインとはなにか
そもそもドメインとは何でしょうか？
今回対象にしているドメインとは以下のようなものです。

- example.com
- google.com
- yahoo.co.jp

Webブラウザのアドレスバーに表示されたり、メールアドレスで使われているあれのことです。

# そのドメインは本当に必要ですか
結論から書きます。
**そのドメイン本当に必要ですか？**
これがこの記事で伝えたい事です。
多くのドメイン取得はそれ自体が大変ではありません。維持管理が大変なのです。

# 取得の時に考える事
- ドメイン名
- 取得時期
- 取得費用

用途に応じた名前でドメインを取りますよね。
使用開始したい時期に間に合わせる必要がありますし、対外的にサービス名称やブランドを発表する前に取得する必要があるでしょう。
1年あたりの金額はそれほど大きくない事がほとんですが取得費用が必要になります。社内で必要な手続きを行いましょう。

# 手放す時に考える事
取得したドメインを利用していたサービスが終了した。今後使用しないという場合は廃止（解約）を検討します。

## 手放すリスク
一度利用したドメインを手放す場合は第三者に悪用されないかに気をつける必要があります。
元のサイトを停止しても、SNSや他のサイトからのリンクは残り続けます。
自社サイトからのリンクは削除が可能でしょうが、自社公式アカウント以外のtwitter投稿が削除されることはないでしょうし、他のサイトからのリンクも修正されないことも多いでしょう。

リンク切れだけなら問題は大きくありません。
問題はドメインが悪用された場合に起こります。

- ライバル企業の宣伝に利用される
- 詐欺サイトに利用される

同業他社の宣伝に利用されたり、自社ブランドと見せかけてニセ商品の販売をされたりすることで自社ブランドを毀損する恐れがあります。


## 維持するコスト
悪用を防ぐためには自社で保有し続ける事になります。その場合のコストは何でしょうか？

- ドメインの登録・維持そのものにかかる費用
- ドメインを管理し続ける費用

年間で数千円とはいえ、長期間維持すればそれなりの金額になります。
また、取得したドメインの更新を続ける管理者のコストもドメイン数が増えてくれば無視できなくなります。
ドメイン取得時に利用する業者は、取得費用よりも管理費用を意識して選定したほうが良いでしょう。

#まとめ
無闇にドメインを取得せず保有しているドメインのサブドメインでサービスを始めることはできないかを検討しましょう。
ただしその場合でも、第三者に取得されないようにドメイン取得だけしておくという考え方もあるかもしれません。
悪用を防ぐことに加えて、ヒットしたサービスが社名になった場合など持っておくと安心できる場面もありえます。
取得はしても利用しなければ手放す際のリスクは限定的と言えるでしょう。