OmniAICreator/Qiita-1.07M huggingface dataset:
イベントclose機能を作ってみた(論理削除)

# やりたいこと
ポートフォリオとしてイベント投稿アプリを作成中イベントの開催日が過ぎたイベントの扱いをどうしようかと調べていたら論理削除の存在を知ったのでイベントを論理削除してイベントを閉鎖する機能を自作した。

# 機能要件
実装の前に今回の機能要件をまとめると、

## ① イベントの期日が過ぎたイベントを論理削除する
具体的には、

- イベントカラムにbooleanを持たせる
- 開催日が過ぎたイベントのbooleanの状態でViewの表示を変更する


## ② 論理削除はイベント期日が過ぎたら自動で実行
具体的には、

- イベント開催日が過ぎたらbooleanを変更するメソッドを定義
- そのメソッドをrakeタスクに登録
- rakeタスクを定期実行する


# 実装
それでは実装開始！

## ① イベントの期日が過ぎたイベントを論理削除する


### イベントカラムにbooleanを持たせる

命名は今回はstatusとしてデフォルトをfalseに設定する

```ruby:コンソール
$ rails g migration AddStatusToEvents status:boolean
```

```ruby:
class AddStatusToEvents < ActiveRecord::Migration[6.1]
  def change
    add_column :events, :status, :boolean,  default: false
  end
end
```

```ruby:コンソール
$ rails db:migrate
```

### 開催日が過ぎたイベントのbooleanの状態でViewの表示を変更する

やることは簡単
viewの表示を条件分岐するだけ

```ruby:view
- if @event.status?
  .btn.btn-danger 終了
- else
  .btn.btn-primary 参加する
```

画面で表すとこんな感じ

falseの時(通常時)
![スクリーンショット 2021-09-12 10.32.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/e2eb5dd3-5a3b-e7b2-8e5f-61a878f8bfb7.png)
![スクリーンショット 2021-09-12 10.32.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/e65a5681-822f-7024-26ab-bde52b6aeba4.png)

trueのとき(開催日が過ぎた)
![スクリーンショット 2021-09-12 10.30.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/5d62cc87-fa2c-a4a1-cac4-1eda879aa461.png)
![スクリーンショット 2021-09-12 10.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974719/5b2d0b7e-86ca-0ef3-95e8-7b565fe3d57c.png)

これでイベントの開催日が過ぎたことが一目瞭然！

## ② 論理削除はイベント期日が過ぎたら自動で実行

### イベント開催日が過ぎたらbooleanを変更するメソッドを定義
ここがなんだかんだ一番悩んだ場所
日付の処理をどうするか色々調べた結果以下のような形に
railsはDate.todayで今日の日にちが取れることを初めて知った。

```ruby
 Event.where('start_time < ?', Date.today).where(status: false).update_all(status: true)
```

### そのメソッドをrakeタスクに登録
あとは定期実行するためにrakeタスクに登録

```ruby:ターミナル 
$　rails g task close_event
```

```ruby:lib/tasks/close_event.rake 
namespace :close_event do
  desc "イベント開催日が過ぎたらイベントをcloseする"
  task close_event: :environment do
    Event.where('start_time < ?', Date.today).where(status: false).update(status: true)
  end
end

```

一応ここで動作確認

```ruby:ターミナル 
$　rake close_event:close_event
```

### rakeタスクを定期実行する
定期実行にはwheneverを使う

```ruby:Gemfile
gem 'whenever', require: false
```
```ruby:ターミナル 
$ bundle install
```

設定ファイルをインストール

```ruby:ターミナル 
$ bundle exec wheneverize .

[add] writing `./config/schedule.rb'
[done] wheneverized!
```

設定を書いてrakeタスクが毎朝6時に実行されるようにセット

```ruby:config/schedule.rb
require File.expand_path(File.dirname(__FILE__) + '/environment')
# cronを実行する環境変数
rails_env = ENV['RAILS_ENV'] || :development
# cronを実行する環境変数をセット
set :environment, rails_env
# cronのログの吐き出し場所
set :output, "#{Rails.root}/log/cron.log"

# 時間指定
every 1.day, at: '6am' do 
  rake 'close_event:close_event'
end
```

cronを更新して完成

```ruby:ターミナル 
$ bundle exec whenever --update-crontab 
```


# まとめ
実装する前に機能要件と機能実装の流れを具体的にすることでスムーズに実装することができた。
機能を自作するのは大変だったがとても楽しかった！
Pepper SDK入門(36) LocalizeAndMapでPepper専用地図を得る

#はじめに
PepperはLocalizeAndMapアクションとLocalizeアクションによって周辺環境の地図を作成し、移動しても自分の相対位置を保持します。

```java
//アクションをビルドする
LocalizeAndMap localizeAndMap = LocalizeAndMapBuilder.with(qiContext).build();

//非同期にアクションを実行
localizeAndMap.async().run();

//LocalizeAndMapの実行を保存
private Future<Void> localizationAndMapping;
```

つまりLocalizeが実行されていれば、Pepperを特定の位置に配置して周辺をネズミ花火のように動き回ってもらってもPepperは自分の立ち位置を見失いません🧨
LocalizeAndMapの使い方は以下の通りです↓

```java
//アクションをビルド
LocalizeAndMap localizeAndMap = LocalizeAndMapBuilder.with(qiContext).build();

//Localize状況を取得するためのリスナーを追加
localizeAndMap.addOnStatusChangedListener(localizationStatus -> {
    if (localizationStatus == LocalizationStatus.LOCALIZED) {
        //アクションを停止
        localizingAndMapping.requestCancellation();
        //Localizeアクションが使う地図情報を出力する
        ExplorationMap explorationMap = localizeAndMap.dumpMap();
    }
});

//アクションを実行
localizingAndMapping = localizeAndMap.async().run();
```

#既存の地図をパン生地のように拡張する🥖
周辺環境の地図が既に作成できていれば、新しいLocalizeAndMapによってその地図の拡張が可能になります。ドリルなどは使いません。
Pepperが地図を読み込むのに成功したら、ExplorationMapにデータを追加します。
この機能性はステレオカメラを装備したPepperで、APIレベル7のSDKでビルドされたExplorationMap上でのみ実行されます。
Pepperがステレオカメラを装備していない場合などは、LocalizeAndMapの呼び出しは失敗します。

```java
//アクションをビルド
LocalizeAndMap localizeAndMap = LocalizeAndMapBuilder.with(qiContext)
                                                            .withMap(explorationMap)
                                                            .build();
```

##センサーは超常的な何かを感知しない
位置を特定するには、センサーの情報を用いて環境内のPepperの位置を計算します。
主としてレーザーセンサーを用いるため、見えるのは数メートル先までです。鳥取砂丘などの開かれた環境ではPepperが得られる情報は少なく、一貫性のないものになります。

##人間とか幻獣とかポルターガイストとか全ての動くオブジェクト
周辺環境の地図を作成している間にPepperが検出した障害物は、人間も含みすべて地図上に保存されます。極小規模なストリートビューですね。
人間が多ければ多いほどLocalizeアクションのパフォーマンスが落ちて、地図の結果に影響します。

障害物の検出は、LocalizeAndMapアクションの実行中以外にも継続的に実行されます。
Pepperの障害物検出の能力は、センサー値によって時間と共に上がります。その結果、LocalizeAndMapがスタートする数秒前にPepperの周りにいた人間は障害物などとして地図上に保存されます。
よって周辺環境の地図を作成する前には、Pepperの近くに人間や動くオブジェクトがいない方が望ましいです。15秒ほど待ってからLocalizeAndMapアクションを実行してください。
見えない何かがいそうな場合は、除霊などしないまでも窓を開けて外へ逃すなどしてから実行しましょう！

##アニメーションを読み込む(熟読はしない)
LocalizeAndMapアクションがスタートした時、Pepperはセンサーから情報を集めるために周辺を見回します。
LocalizeAndMapがこのアニメーションを実行できない時、例えば既に実行中の他のアクションがある場合には、LocalizeAndMapはアニメーション失敗のエラーを投げます。椅子取りゲーム方式ですね💺


#あとがき
今回も[PepperSDKforAndroid](https://android.aldebaran.com/sdk/doc/pepper-sdk/ch4_api/movement/reference/localize_and_map.html)を参考に書かせていただきました。
さらに詳しい情報は、[LocalizeAndMapのAPIドキュメント](https://android.aldebaran.com/sdk/doc/javadoc/qisdk/com.aldebaran.qi.sdk.object.actuation/-localize-and-map/index.html)を参照してください。

次回のPepperSDK入門はExplorationMapです。Pepperによる探検は始まりません💰⛏それでは〜
PythonistaのためのC++記法入門: それC++ではどう書くの5 ~条件処理~

[PythonistaのためのC++記法入門: それC++ではどう書くの4](https://qiita.com/nctp/items/399d224bb4043edfbcc8)の続き。今回は短め。

# if文

### Pythonではこう書いた

```python
if a == 10:
    # 処理A
elif a == 100:
    # 処理B
else:
    # 処理C
```

bool値に関しては以下のように書ける
Pythonでは`0`や空文字列`""`、空の`list`なども`False`として扱われる。

```python
flag = True
if flag:
    # 処理

flag = False
if not flag:
    # 処理
```

### C++ではこう書く

```cpp
int a;
if (a == 10) {
  // 処理A
}
else if (a == 100) {
  // 処理B
}
else {
  // 処理C
}
```

bool値に関しては以下のように書ける。

```cpp
bool flag = true;
if (flag) {
    # 処理
}

flag = false;
if (!flag) {
    # 処理
}
```

## if文の書き換え

### Pythonではこう書いた

```python
a, b = 10, 20

if a < b:
    answer = a
else:
    answer = b

# 以下のように1行で書ける
answer = a if a < b else b
```

### C++ではこう書く

```cpp
int a(10), b(20);
int answer;

if (a < b) {
  answer = a;
}
else {
  answer = b;
}

// 以下のように1行で書ける
int answer = a < b ? a : b;
```

#### まとめ

| | C++ | Python |
| --- | --- | --- |
| if文 | if (条件1) {<br>&nbsp;&nbsp;処理1;<br>}<br>else if (条件2) {<br>&nbsp;&nbsp;処理2;<br>}<br>else {<br>&nbsp;&nbsp;処理3;<br>} | if 条件1:<br>&nbsp;&nbsp;&nbsp;&nbsp;処理1<br><br>elif 条件2:<br>&nbsp;&nbsp;&nbsp;&nbsp;処理2<br><br>else:<br>&nbsp;&nbsp;&nbsp;&nbsp;処理3 |
| boolean判定(1) | if (boolean){<br>&nbsp;&nbsp;処理<br>} | if boolean:<br>&nbsp;&nbsp;&nbsp;&nbsp;処理 |
| boolean判定(2) | if (!boolean){<br>&nbsp;&nbsp;処理<br>} | if not boolean:<br>&nbsp;&nbsp;&nbsp;&nbsp;処理 |
| 三項演算子 | `型 変数 = 条件式? true時の値 : false時の値` | `変数 = True時の値 if 条件式 else False時の値` |

## and / or 

### Pythonではこう書いた

```python
if a > 0 and b > 100:
    # 処理

if a > 0 or b > 100:
    # 処理

```

### C++ではこう書く

```cpp
if (a > 0 && b > 100) {
  # 処理
}

if (a > 0 || b > 100) {
  # 処理
}
```

[コメント](https://qiita.com/nctp/items/5088cd08354b4300bfc6#comment-44e193bf1f4c31c13bce)をいただきました。C++でも`and` / `or`が使えるとのことです。

# for文

### Pythonではこう書いた

```python
for a in range(0, N, 1):
  # 処理

# 一般的にはこう書くことのほうが多い
for a in range(N):
  # 処理
```

### C++ではこう書く

```cpp
for (int i = 0; i < N; i++) {
  // 処理
}
```

コンテナ型に関しては以下のようにも書ける。
条件式の`配列の要素の型 変数名 : 配列変数`に注意。
配列の要素の型を常に考えないといけない。

```cpp
vector<int> a = {1, 3, 2, 5};
for (int x : a) {
  // 処理
}
```

`auto`を使うと簡単に書ける。
[コメント](https://qiita.com/nctp/items/5088cd08354b4300bfc6#comment-44e193bf1f4c31c13bce)をいただきました。`auto&&`のほうが好ましいとのことです。

```cpp
vector<int> a = {1, 3, 2, 5};
for (auto x : a) {
  // 処理
}
```

イテレータを用いた書き方は別記事にて説明する。


# while文

### Pythonではこう書いた

```python
while i < 10:
    # 処理
    i += 1 
```

### C++ではこう書く

```cpp
int i = 0;
int N = 10;
while (i < N) {
  // 処理
  i++;
}
```
PL/SQLをかじってみた(1)

業務で必要になるかもしれないのでPL/SQLについて学んでみた。
今回は基本となる3つの部と書き方と変数の定義について学んでみたよ。

###使用した環境
Oracle Live SQL

###PL/SQLとは
ＳＱＬを手続き型言語として拡張したプログラミング言語。
まぁ、ＳＱＬの言語＋Cとかの手続き型言語を合体させて便利にさせたもの。
これがあればSQL文とif文やfor文などのプログラムが同時に書ける。
しかも、データベースの中にも入れられちゃう。すごい。

####<strike>4</strike>3つの部があるよ
| 名称    |書き方     | どんなことを書くのか|
|:--------|:---------|:------------------|
| 宣言部   | DECLARE      | ブロック内で使用する変数などを宣言　　  | 
| 実行部   | BEGEIN       | SQLによるデータ操作や手続き処理を記述| 
| 例外処理部| EXECPTION   | ブロック内で発生したエラー（例外）の処理を記述|        

ブロックの最後には必ず「END;」を記述すること。
（手続きが多言語の一つであるCOBOLでいうピリオドみたいな感じかな)

####HelloWorld（プログラムでまず初めに学ぶであろう事柄）
ここでは、基本的な書き方と変数、定数について書いていくよ。

【例文】

```sql
DECLARE
  --変数と定数の宣言 
  str VARCHAR2(30) := 'Hello, world!'; --文字型
  num constant NUMBER default 100; --数値
BEGIN
  --変数と定数の内容を画面に出力
  DBMS_OUTPUT.PUT_LINE(str);
  DBMS_OUTPUT.PUT_LINE(num);
 --変数への代入
  str := 'Good Bye';
  --変数の内容を画面に出力
  DBMS_OUTPUT.PUT_LINE(str);
END;
```
```
Statement processed.
Hello, world!
100
Good Bye
```
できた！！！

ここでは以下のことをしているよ

1. 変数と定数の宣言
1. 変数と定数の内容を画面に出力
1. 変数への代入
1. もう一度変数の内容を画面に出力


#####変数と定数の宣言

変数を宣言する構文はこんな感じかな。

```
1. 変数のみを宣言する
   変数名 データ型;
2. 変数を宣言して初期値を代入する。
   変数名 データ型 := 値;
   変数名 データ型 default 値;
3. 変数を非NULL制約をつけて宣言（必ず代入が必要）
   変数名 データ型 not null := 値;
```

:=とdefaultの違いは初期値とデフォルト値くらいの違いかな？

というよりどっかの格好つけたがりがいろんな種類があった方がよくねと言って作ったとしか

大抵は:=を使えばいいんだと思う。
それと、非NULL制約をつけた場合は

```sql
DECLARE
  --変数宣言 
  str VARCHAR2(30) not null; --文字型
BEGIN
  str := 'HEllo';
  --変数の内容を画面に出力
  DBMS_OUTPUT.PUT_LINE(str);
END;
```
```
ORA-06550: line 3, column 7:
PLS-00218: a variable declared NOT NULL must have an initialization assignment 
```
このように、コンパイルエラーが発生するみたいだね。
（まぁ、変数を空にするなと言われているのに値を入れていない、変数を空にしているんだから当たり前か）

定数を宣言する構文はこんな感じかな。
定数とは値が定まった数と言う名前の通り、必ず初期値が必要なんだ。
宣言だけしたらエラーになるから気を付けてね。

```
   変数名 CONSTANT データ型 := 値;
   変数名 CONSTANT データ型 default 値;
```

それと、定数にした場合はもう値を書き換えられないよ。


```sql
DECLARE
  num constant NUMBER := 100; --定数
BEGIN
  num := 10;
END;
```
```
ORA-06550: line 4, column 3:
PLS-00363: expression 'NUM' cannot be used as an assignment target 
```

このように、コンパイルエラーが発生するみたいだね。
（まぁ、値は定まっているんでと言われているのに値を変えようとしているんだから当たり前か）

#####値の表示と文字の結合

んで、値の表示には

```
DBMS_OUTPUT.PUT_LINE(値とか数式とか);
```
を使うらしい。
値のほかにも数式、変数や定数なども使えるよ。
これは値の確認とかでこれからたくさん使うから**必ず**覚えてね。

あっ、文字列の結合は

```sql
num NUMBER default 100; --数値
DBMS_OUTPUT.PUT_LINE('数値だよ'||num);
```
```
数値だよ100
```

て具合に「||」を使うらしい
（&とか+じゃないんだね。sqlでも確かこうだったから同じだね）

あっ、そうそうデータ型についても話とかなきゃ。
えっと、なになに……あっ、ＳＱＬと同じなのか。じゃぁ、いっか。

よし、終り。
あとは、参考記事を確認すること。

私より1000パー分かりやすいから。


それじゃぁ、以上。
あぁ、お腹空いた。
バーイ


####参考にした記事
[超入門PL/SQL]
(https://atmarkit.itmedia.co.jp/ait/series/5485/ "超入門「PL/SQL」")
[ここからはじめようOracle PL/SQL入門](https://www.oracle.com/technetwork/jp/ondemand/database/db-basic/b-11-plsql-1448399-ja.pdf "Oracle ここからはじめようOracle PL/SQL入門")
【Swift】ストアドプロパティとコンピューテッドプロパティ

# 構造体とは
インスタンスの型になるもの。
Taiyakiの構造体から、中身があんこのたいやきが作られる。
Carの構造体から、日産GTRが作られる。

Swiftでも、UI部品は構造体又はクラスから作られる。

``` swift
struct Taiyaki{
 文
}
```

# プロパティとは
「インスタンスを特徴づける性質や特性」
たい焼きでと例えると、「中の具材」や「値段」

``` swift
// プロパティの宣言
var プロパティ名　= 初期値
// 例
struct Taiyaki{
 var nakami = "あんこ"
 //　省略
}
```

# ストアドプロパティ
プロパティの値が構造体で初期化されていて、
毎回固定の値が保持されているもの。
実際のコードだと以下の通り。

``` swift
var プロパティ名 = 初期値
let プロパティ名 = 初期値

// 使用例
struct Taiyaki{
 // ストアプロパティ-初期値が設定されている
 var nakami = "クリーム"
 func sayNakami() {
  print("中身は" + nakami + "です")
 }
}
```

# コンピューテッドプロパティ
ストアプロパティは初期値が設定されていて、
その値をもとにメソッドで使用していた。

それに対して、コンピューテッドプロパティには、以下の特性がある。

- 初期値を持たない
- 呼び出されたタイミングで処理を行い、必ず結果を返す

実際にコードを見るとわかりやすい

``` swift
// 書き方
var プロパティ名: 型名{
 文
 return 値
}
// 例文
struct Vtuber{
 // これは初期値があるので、ストアプロパティ
 var nakami = "あんこ"
 // ここからがコンピューテッドプロパティ
 var sayNakami:String {
  result = print("中身は" + nakami + "です") // 初期値を使用せずに、変数を使用している
 }
}
```

# ストアドプロパティとコンピューテッドプロパティの違い
２つの構文での違いは以下の通りになる。

|                | ストアドプロパティ | コンピューテッドプロパティ | 
| -------------- | ------------------ | -------------------------- | 
| 変数、定数     | varまたはlet       | varのみ                    | 
| 型名の省略     | 可能               | 不可                       | 
| 波括弧{}の有無 | なし               | あり                       | 
| 戻り値         | 不要               | 必須                       | 

## 変数と定数
コンピューテッドプロパティの宣言では定数を指定できない。
定数を指定すると、中身の変更ができなくなるため。

``` swift
 // letだと、変数nakamiが変更できなくなる
 var sayNakami:String {
  result = print("中身は" + nakami + "です") // 初期値を使用せずに、変数を使用している
 }
```

## 型名の省略 
ストアドプロパティは変数の初期化の際、型を自動で認識してくれる。
対して、コンピューテッドプロパティは初期値がないので、
宣言時に明示的に型を指定する必要がある

``` swift
 // ストアドプロパティ-変数を定義しているので、型を自動で認識する
 var nakami = "あんこ"

 // コンピューテッドプロパティ-初期値がないので、明示的に型を指定する必要がある
 var sayNakami:String {
  result = print("中身は" + nakami + "です")
 }

```

# コンピューテッドプロパティとメソッドとの違い
上記で記載したコードはメソッドでも同様のことが実現できる。

``` swift
// メソッドの場合
func sayNakami() -> Int{
 result = print("中身は" + nakami + "です")
}
```

ただし、コンピューテッドプロパティには大きな違いがある。

- 引数を受け取ることができない
- 戻り値が必ずある。

## 引数を受け取ることができない
メソッドには ```func sayNakami("あんこ":String)``` のように引数を設定できたが、
コンピューテッドプロパティではできない

## 戻り値が必ずある。
コンピューテッドプロパティは必ず、```return```で戻り値を指定しなければならない
なお、中身１行だけの場合、省略できる

``` swift
// 省略可能なケース
 var nakami = "あんこ"
 var sayNakami:String {
  print("中身は" + nakami + "です") //中身が１行のみのため、returnが省略できる
 }

// 省略不可能なケース
 var nakami = "あんこ"
 var sayNakami:String {
  文
  return print("中身は" + nakami + "です") //中身が2行のみのため、明示的にreturnを記述
 }
```


# まとめ
- ストアドプロパティは初期値をもつもの（値を保持する）
- コンピューテッドは初期値を持たず、読み出されたタイミングで計算する（計算する）
Fundamental Statistics for Data Science (Part 02)

continuation from [Fundamental Statistics for Data Science (Part 01)](https://qiita.com/qualitia_cdev/items/ad872ebbcd408e613218).


###### 5) Mean
Mean is also famous as average in mathematics, which can be obtained by summing all the observations and divided by the number of data points.

Let us think that a random variable has the following data. N is the number of data points. 

X = { x<sub>1</sub>, x<sub>2</sub>, x<sub>3</sub>, . . . , x<sub>N</sub> }

We can calculate the mean using the following equation.
![mean.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579376/df7dda72-28dc-6132-d4a9-0e636e420b99.jpeg)


```mean.py
import numpy as np

x = np.array([1,2,3,4,5,6])
x_mean = np.mean(x)

print(x_mean)
```

###### 6) Variance
Variance refers to a spread between numbers in a data set. More pointedly, variance measures how far each number in the set is from the mean value in the dataset. When we calculated the sample variance, we can use it to approximate the population variance.

![variance.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579376/619966d2-1f6f-4183-d458-13db09a74ef1.jpeg)

```var.py
import numpy as np
x = np.array([1,4,3,6])
x_variance = np.var(x)

print(x_variance)
```

###### 7) Standard Deviation
Standard deviation measures the distribution of a dataset relative to its mean.
We can calculate it by the square root of the variance.
Standard deviation is usually favored over the variance since it has the same unit as the data points, implying we can interpret it more easily.

```std.py
import numpy as np
x = np.array([1,4,3,6])
x_std = np.std(x)

print(x_std)

```

Let's continue from part 03

*本記事は @qualitia_cdevの中の一人、@nuwanさんが書いてくれました。
*This article is written by @nuwan a member of @qualitia_cdev.
coc.vimで'[coc.nvim] build/index.js not found, please install dependencies and compile coc.nvim by: yarn install'と言われた

# 突然のエラー

```
[coc.nvim] build/index.js not found, please install dependencies and compile coc.nvim by: yarn install
```

* Macをアップデートしたから?
* deinでプラグインアップデートしたから?

正直どれが原因かわからなかったけど、なんとかエラーでなくした記録が誰かのお役にたてばと(備忘録も兼ねて)

# vim8でdeinを使っている
* deinの機構として、プラグインはgithubからcloneしてるだけです
* なのでそのディレクトリを見つけて git pull したら最新のがおちてくるから解決するんじゃないかという仮説

```
cd ~/.cache/debin/repos/github.com/neoclide/coc.nvim
git pull origin master
```

## 結果
* 変わらず
* ヒントはすでにログに書かれているのにねえ・・・

# そのディレクトリでyarn installしてみる(先にこっちやろうぜ)

```
cd ~/.cache/debin/repos/github.com/neoclide/coc.nvim
yarn install
```

## 結果
* 変わらず
* まじで?!

# うーん、困った
* 詰んだかと見せかけて・・・
* 基本に立ち返って、coc.vimのコマンドを打ってみる

```
: call coc#util#install()
```

## 結果
* なおった!!

# 結論として
1. dein側でプラグインアップデート
1. 上が機能していなさそうであれば、直接git pull
1. call coc#util#install()　
1. おそらく上記コマンドだけでよい(yarn installは上記コマンドがやってくれる)
コミット前にテストを実行しよう　~husky ver7~ 

# はじめに
コミットする前にテストを実行させるための設定をします。[husky](https://www.npmjs.com/package/husky)を使うことで簡単に設定ができます。huskyは、ver4から6に上がった際に仕様が大きく変わっているため、改めてインストール手順をまとました。

* [huskyのドキュメント](https://typicode.github.io/husky/#/?id=automatic-recommended)

## 開発環境

* husky : 7.0.2
* node : v14.17.6 

## インストール

* jestのコマンドの設定とjestはインストール済みです。[jestのインストール方法](https://qiita.com/YSasago/items/6f23055c971a091f9993)


まずはnpmを使ってhuskyをインストールします。

```sh
$ npm install --save-dev husky
```

package.jsonのscriptsにprepareコマンドを追加します。

```json:package.json
 "scripts": {
    "test": "jest",
    "build": "babel src -d dist",
    "start": "babel -w src -d dist",
    "prepare": "husky install"
  }
```

prepareコマンドを実行します。実行すると、```.husky```フォルダが作成されます。

```sh
$ npm run prepare
```

コミット直前に```npm test```を実行したいので、Git hooksを追加します。下記のコマンドを実行すると、.huskyフォルダに```precomit```のファイルが作成されます。コマンドを修正したい場合は、```precomit```ファイルに記載されているコマンドを修正します。

```sh
$ npx husky add .husky/pre-commit "npm test"
husky - created .husky/pre-commit
```
## 実行結果

huskyの設定ができたので、実行してみます。

```sh
$ git add . 
$ git commit -m "husky install"

....

Test Suites: 1 skipped, 4 passed, 4 of 5 total
Tests:       1 skipped, 107 passed, 108 total
Snapshots:   0 total
Time:        21.261 s
```
無事コミット直前にtestが実行されていることが確認できました。

https://qiita.com/YSasago/items/6f23055c971a091f9993
pythonでブロックで実行時間をログに残る

# 背景
* pythonでDB query実行時間などを残りたい
* いつでもend - startで時間を計算することが面倒

## 普通のやり方

```python
    time_sta = time.perf_counter() 
    time.sleep(2)
    time_end = time.perf_counter() 
    print(time_end - time_sta)
```

# 対策
* rubyのブロックように実装して便利になると思う
* pythonではrubyのblockのような予約語がない

## 実装してみる

```python
from contextlib import contextmanager 
import time 
import sys 

@contextmanager 
def time_count(function_name: str): 
    time_sta = time.perf_counter() 
    yield 
    time_end = time.perf_counter() 
    print(f"{function_name}の実行時間: {time_end - time_sta}") 

def get_tenant_info(): 
    with time_count2(sys._getframe().f_code.co_name): 
        time.sleep(2)     

get_tenant_info() # -> get_tenant_infoの実行時間: 2.0020375240128487     
```

## メリット
* ブロックで実行時間をログに残って、実装方法を固定できる 
* ソードコードの量が少なくなって、バグもない
【勉強用】仮想化３種についてまとめてみた

どうも、エンジニアのハマベです。
仮想化の概念の理解って難しいな、と思ったので、まとめてみることにしました。

### 仮想化とは？
イメージとしては、大きなサーバー(PC本体)の中に小さな仮想のサーバーをつくり、そのなかで作業できるようにする。といった感じ。

- メリット
  - 本物のサーバー同様に扱えるし、テストに必要な環境などを自由に作成できる
  - １台のPCに複数の環境を作ることが出来る

まとめると、一つのハードウェアに必要な環境を集約できる、ということがメリットになる。環境ごとにハードウェアを用意すると、リソースをめいいっぱい使い切るのは難しいし運用も煩雑になってしまう。そこを解消できるのが、仮想化技術だ。

参考サイト：
https://pfs.nifcloud.com/navi/beginner/virtualization.htm

### 仮想化3種類

#### ホストOS型
ホストOS(PC本体)の中に仮想化ソフトウェアをインストールし、その中にゲストOS(仮想PC)を作成する方式。
他２種に比べ、簡単に任意のOSで作成できるので、**個人的な開発には向いている。**

- メリット
  - 仮想化ソフトウェアが比較的扱いやすい
  - ホストOSで実行中のアプリと並行して利用できる

- デメリット
  - 他２種とくらべて動作が遅め
  - ホストOSに負荷がかかると、動作が重くなってしまう

イメージ画像
![hostOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209814/1ffdd1b8-27bd-b5e1-5f75-c4c4d514bb90.png)


- 主なソフトウェア
  - VirtualBox (Windows／Mac)
  - WorkstationPlayer (Windows) 

参考：
https://qiita.com/Pentas/items/5f558deeddcfef814b3e

#### ハイパーバイザー型
ホストOS型と違い、仮想化ソフトウェアを挟まず、直接ゲストOSをインストールする方式。
windows(10以降)の場合、「Hyper-V」というドライバが標準で入っており、使いやすい。本番環境(複数人での開発)向き。

- メリット
  - ホスト型に比べ、ハードウェアを直接制御するため、速度が速い

- デメリット
  - 専用のドライバが必要で、ホスト型より少し難易度が高い

![hyper.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209814/a977e345-7ab4-9f17-3f4f-31cb9736c53a.png)

- 主なソフトウェア
 - Hyper-V
 - vSphereHypervisor
 - KVM

参考：
https://thinkit.co.jp/story/2012/10/17/3722

#### コンテナ型
他２種と異なり、ゲストOSをホストOS上にインストールしない。
「コンテナ」と呼ばれる仮想空間を作り、その中にアプリを構築する。コンテナはホストOSを使用して動作しているため、ゲストOSは必要ない。

- メリット
 - 起動が速く、処理が軽量で済む
 - 比較的簡単に、環境をコピーできる
 - コンテナの環境を合わせれば、どのサーバーでも確実にアプリが動作する 

- デメリット
 - カーネル(OSの中核)を共有するため、個別に変更できない
 - コンテナ環境のベースとなるOSと異なるのシステムは動かせない
 - 学習コストが比較的高め(新しい技術なので、情報がすくなめ)
 
![contena.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1209814/44fe5c53-76eb-7609-1487-608f705df1b3.png)

- 主なソフトウェア
  - Docker (正確にはオープンソース型プラットフォーム)
  - Kubernetes (コンテナを管理するソフト？個別に調べた方がよさそう)

参考：
https://licensecounter.jp/engineer-voice/blog/articles/20191101_post_31.html

https://pfs.nifcloud.com/navi/tech/container_virtualization.htm


いかがだったでしょうか。
多分まだまだツッコミどころは多いと思われますが、ご指摘いただけると、とても嬉しいです。かなり喜びます。

以上、ご覧いただきありがとうございました。
プログラミング初心者でもJavaは習得できる？おすすめの学習法

##そもそもJavaとは
Javaは1995年に登場して以来、数あるプログラミング言語でも最も人気が高く、国内外問わず使用人口も多い言語です。

OSに依存しないマルチプラットフォームな言語で汎用性が高く、なんでも作れてしまいます。

その分Javaは需要も高いです。

##Javaでできること
Javaは次のようにさまざまなことができます。

- 業務用アプリ開発
- Android向けのアプリ開発
- Webサイト構築
- 組み込み系の開発
- 大規模なシステム開発

Javaを習得しておくことで、さまざまな開発の仕事が可能となります。

## Javaはプログラミング初心者に不向きなの？

まだまだ人気が高いJavaですが、プログラミング初心者にはおすすめできない言語とよく言われています。

理由は次のとおりです。

- 何でもできるけど、その分覚えることが広範囲に渡る
- 構文が複雑で理解しずらい

初心者がいきなりJavaの学習をすると、覚えることが多すぎたり、エラーが解決できずに途中で挫折してしまう可能性が高いです。

Javaは複雑ですが一度覚えてしまえば、他の言語もスムーズに理解しやすいといった大きなメリットもあります。

実体験ですが、初心者でも根気よく勉強すれば、簡単なWebサービスくらいなら作れるようになります。

## Javaを習得するために必要なスキル

Javaを習得するには、ざっくり次のスキルが必要です。

- Javaの基本
- IDE（統合開発環境）
- データベース（MySQL、PostgreSQL）
- フレームワーク

まずはJavaの開発でよく使われるIDE（開発環境）であるEclipseを導入して、Javaが実行できる環境を整えることです。

ある程度規模の大きな開発になると、データベースとの連携やフレームワークの使用も必須となります。

## 初心者がJavaを学習するのにおすすめの教材

プログラミングが学べる動画サイトで、Javaがどんなものか？実際に手を動かして確認してみましょう。

次のサービスでは無料の範囲でもJavaの基本がある程度学べます。

- [ドットインストール](https://dotinstall.com/)
- [Progate](https://dotinstall.com/)

ある程度コツがつかめたら、書籍でじっくりと学習することをおすすめします。

書籍は次の2冊がおすすめです。

- [スッキリわかるJava入門 第2版](https://www.amazon.co.jp/dp/B00MIM1KFC/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
- [新わかりやすいJava オブジェクト指向徹底解説](https://www.amazon.co.jp/dp/B07K97ZWYG/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

参考書で学習するコツとして、参考書の内容を全て理解するのは膨大な時間が必要です。

まずは全てを理解しようとせず、参考書のプログラムを実際に手を動かして確認して慣れていくことが大切です。

## そもそもプログラミング自体がよくわからない場合は…

ここまで駆け足で紹介しましたが、そもそも、

- プログラムが動く仕組みがよくわからない……。
- プログラミングの基礎の基礎を知っておきたい。

という方はプログラムが動く仕組みや、動かし方を初歩の初歩から解説している書籍を読んでみることをおすすめします。

プログラミング初心者におすすめの書籍については、こちらの記事で紹介しています。

[【プログラミング初心者向け】これだけは読んでおくべきおすすめ本7冊](https://www.furikatu.com/recommended-programming-books/)

## 最後に

プログラミング初心者が、Javaを習得するための方法について紹介しました。

Javaは覚える範囲が広く難易度は高いですが、人気が高く需要もあるので習得すれば有利になることは間違いありません。
証明書のドメイン名をCommonNameで設定するとエラー

オライリーのReal World Http 第2のハンズオンを進めていて、opensslコマンドで自己(オレオレ)証明書を作ってSSL化するところで躓いた。
https://www.oreilly.co.jp/books/9784873119038/

### 記事の目的、用途
備忘録。同じく証明書の知識が浅いまま、同テキストに立ち向かう人のヒントになれば。

# 問題
サーバー側の証明書を作成するにあたって(テキストではserver.crt)、ドメイン名を設定する必要がある。
ドメイン名の設定方法は従来CommonNameで設定していたが、RFC2818により非推奨となった。

テキスト中で使用しているgolangのライブラリでもこれに対応しており下記のエラーが出る

```
x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0	
```

ネットを調べているとブラウザChromeやwebサーバーのNginxでもCommonNameでドメイン名を設定した証明書は同様のエラーを出すらしい
[参考]
[GoogleChromeの場合](https://www.ipentec.com/document/windows-chrime-error-net-err-cert-common-name-invalid-using-ssl-certificate-signed-with-local-ca)
[Nginxの場合](https://yuru-infra-se.hatenablog.com/entry/2021/07/18/032526)→golangのライブラリと同じエラーメッセージ

# 解決策
もともとマルチドメイン証明書の設定のために用いていたSAN(Subject Alternative Name)を使用する。
openssl x509で証明書を作るときに-extfileで指定する設定ファイルにSANの項目を追加する。

テキスト中のコマンド例

```
openssl x509 -req -days 365 -in server.csr -sha256 -out server.crt -CA ca.crt CAkey  ca,key -CAcreateserial -extfile /etc/ssl/openssl.cnf -extensions Server
```

設定ファイルに追加する項目

```
subjectAltName = DNS:ドメイン名１, DNS:ドメイン名2
```

テキストの場合、localhostの証明書を作るので下記のようになる

```
subjectAltName = DNS:localhost
```

テキストの場合、-extensionsで設定を切り替えるため、ServerやCAなどの項目ごとに設定を分けて書いている。
今回は、サーバー証明書のドメイン名をSAN指定すれば良いので、Serverの設定値に追加する。

```
[Server]
basicConstraints=CA:FALSE
keyUsage=digitalSignature,dataEncipherment
extendedKeyUsage=serverAuth
subjectAltName = DNS:localhost
```

### 追記
client側で証明書要求(.csr)を作成するときに、CommonNameに何らかの値を入力していると、httpsリクエスト時にエラー。何も入力しないこと。

```
x509: certificate signed by unknown authority (possibly because of "x509: invalid signature: parent certificate cannot sign this kind of certificate" while trying to verify candidate authority certificate "hogehoge")
```


# 参考
[マルチドメイン証明書とは](https://qiita.com/testnin2/items/0fb2211dffae2ffaec7a)
[設定ファイルにSANの項目を追加する参考](https://qiita.com/nis_nagaid_1984/items/b8f87d41ea108d47af61)
VSCode 半角スペース表示 JSON（所要時間１分）

VSCodeで半角スペースを見えるようにする（所要時間１分）
薄い・で表示されるようになる

#VSCodeのターミナルで
* ``` code c:\Users\{PCのユーザ名}\AppData\Roaming\Code\User\settings.json```
* ```"editor.renderWhitespace": "all",```を追記（１行目でよい）
 
__終了__





##もしくは（非ターミナルから）
* VSCode上の左下の歯車をクリック
* 「Settings」の項目をひらく
* 検索窓に「json」と入力
* ヒットした「Edit in settings.json」をどれでもいいのでクリック
* ```"editor.renderWhitespace": "all",```を追記
【Salesforce】Batch Apexのテスト実行時のエラー

# Batch Apex の実行時に発生するエラーについて
Batch Apexのテストクラスを実行して下記のようなエラーを目にした方はいないでしょうか？
　
原文：
System.UnexpectedException: No more than one executeBatch can be called from within a test method.
Please make sure the iterable returned from your start method matches the batch size, resulting in one executeBatch invocation.

和訳：
System.UnexpectedException：テストメソッド内から呼び出すことができるexecuteBatchは1つだけです。
startメソッドから返されるiterableがバッチサイズと一致していることを確認してください。その結果、executeBatchが1回呼び出されます。


エラー文では若干遠回しな言い方をしていますが、要は・・・
　・Startメソッドで取得したレコードが多くてバッチサイズ超えてるよ。
　・バッチサイズ超えてるから２回目のexecuteが動いてるよ
　・executeが2回以上動いているからエラーにしたよ。
という話です。


#解決方法
下記のような形でテストの時のみStartメソッドで取得するレコードを、バッチサイズ以下の数値になるように
分岐させるだけでOkです。

```
        if (Test.isRunningTest()){
            query = 'SELECT Id , FROM User WHERE Account AND LIMIT [指定したバッチサイズ以下の数値]';
        } else {
            query = 'SELECT Id , FROM User WHERE Account AND LIMIT 50000';
        }
```

#最後に
上の例に限らずテストクラスの時のみ運用とは異なった処理をする必要がある場合に
Test.isRunningTest()は有用なので是非使ってみてください。
ただしテスト実行時に分岐のfalse側のカバー率は担保できないため、
カバー率が担保できないほど多用しないようにしましょう。
【HTML/CSS】画像の表示位置（上下左右中央）を完璧に制御する

# 概要
画像の表示位置をコントロールするCSSの実装について、雑に記載します。
（今後の自分の備忘録も兼ねて。）

# HTML/CSS

```html
<div class="contents">
  <img class="image" width="128" height="128" src="image.png" />
</div>
```

```css
.contents {
  width: 100%;
  height: 100vh;
  background-color: darkgray;
}

.image {
  /* ここに画像の表示位置をコントロールするCSSを書く */
}
```

CSSが何も当たっていない時の表示はこんな感じで、画像が左上に表示されます。
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/e74a51ed-58e6-af00-706e-d2174aa2fb77.png)


## 左中央

```css
.image {
  top: 0;
  bottom: 0;
  margin: auto 0;
  position: absolute;
}
```

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/e5bd9df4-7485-e1a3-411e-804c270466d6.png)

## 左下

```css
.image {
  bottom: 0;
  position: absolute;
}
```

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/9749d170-5cd2-ffc8-32cf-ffe4ab6d4e32.png)

## 下中央

```css
.image {
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0 auto;
  position: absolute;
}
```

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/f41248c6-52e5-6692-026f-3aa78086481b.png)

## 右下

```css
.image {
  bottom: 0;
  right: 0;
  position: absolute;
}
```

![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/9371cd62-2831-fe74-69a6-7eaeaa0a5ec2.png)


## 右中央

```css
.image {
  top: 0;
  bottom: 0;
  right: 0;
  margin: auto 0;
  position: absolute;
}
```

![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/8702b5b0-d75e-58e3-581a-344b7cb47251.png)

## 右上

```css
.image {
  right: 0;
  position: absolute;
}
```

![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/a19a9681-e30a-d0e0-da81-103ee8ec3c82.png)

## 上中央

```css
.image {
  left: 0;
  right: 0;
  margin: 0 auto;
  position: absolute;
}
```

![8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/ea404928-f80a-7365-60cb-48b2c579b98f.png)

## 画面中央

```css
.image {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  position: absolute;
}
```

![9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122485/76c64caa-e4fc-f551-9359-10919e072116.png)
【RSpec】結合テストを実施した際に出たchromedriverに関するエラーの解消方法


#対象者

* chromedriverに関するエラーが発生している方
* RSpe結合テストを実施中の方
* JavaScriptのテストが不要な方
* GoogleChromeを使用中の方


#目的

* エラーを解消してRSpecテストを実行できるようにする

#実際の手順と実例
###1.前提

* RSpecテスト実装
* Ruby 2.6.3
* Rails 5.2.5
* Gemfileは下記の通り

````Gemfile.
:
:
group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  gem 'webdrivers'
  gem 'rspec-rails'
  gem 'factory_bot_rails'
  gem 'faker'
end
:
:
````

###2.現状（エラー内容）

下記のようなエラーが出ています。
調べてたところによると、chromedriver-helperというgemがないことが問題みたいです。

![スクリーンショット 2021-09-09 15.28.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1681213/9cad1b9e-3033-0f87-0858-f3bcc0dc88ee.png)

しかし、chromedriver-helperのサポートはgemは2019年3月31日に終了しています。

webdriversというgemへ移行してくださいとのことですが、
下記の記事を参考にさせて頂いた際にうまく行かなかったので、
渋々chromedriver-helperをアプリケーションにインストールすることにしました。


###3.Chromedriverをインストールして解決する方法

1. Chromedriverのインストール
1. rails_helper.rbの修正

上記２点を実行していきます。


####1. Chromedriverのインストール

まず手始めにGoogleChromeをupdateしていきます。

````Terminal.
$ sudo yum -y update
$ sudo yum -y install google-chrome-stable
$ sudo yum -y install libX11 GConf2 fontconfig libOSMesa google-noto-cjk-fonts
$ google-chrome --version
````

その後下記のコマンドでChromedriverをインストールしていきます。

````Terminal.
sudo yum -y install unzip
curl -O -L https://chromedriver.storage.googleapis.com/85.0.4183.38/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin
rm chromedriver_linux64.zip
chromedriver -v
````

最後のコマンドを実行するとChromedriverのバージョンが表示されます。バージョンは下記のサイトで確認できます。

https://chromedriver.chromium.org/downloads


ここまで実行したら再度、テストを実行します。
実行後は更に下記のようなエラーがでました。

```Terminal.
Selenium::WebDriver::Error::UnknownError:
            unknown error: Chrome failed to start: exited abnormally.
              (unknown error: DevToolsActivePort file doesn't exist)
              (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
```

####2. rails_helper.rbの修正

`````rails_helper.rb
RSpec.configure do |config|
:
:
:
 config.include FactoryBot::Syntax::Methods
   config.before(:each) do |example|
     if example.metadata[:type] == :system
       if example.metadata[:js]
         driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
       else
         driven_by :rack_test
       end
     end
   end
  # Capybara.javascript_driver = :selenium
end

`````

上記を追加したらRSpecテストが正常に動作しました。下記の記事を参考にさせて頂いております。

https://qiita.com/chiaki-kjwr/items/b1ad5be3ede9e15c865d





#参考にさせて頂いた記事

* [Selenium::WebDriver::Error::UnknownError:の対処法（seleniumではなくrackを指定してテストを走らせる）](https://qiita.com/chiaki-kjwr/items/b1ad5be3ede9e15c865d)
* [サポートが終了したchromedriver-helperからwebdrivers gemに移行する手順](https://qiita.com/jnchito/items/f9c3be449fd164176efa)
* [WSL2 環境で RSpec (Capybara) で「Webdrivers::BrowserNotFound: Failed to find Chrome binary.」エラーが出るとき](https://obel.hatenablog.jp/entry/20210112/1610437485)
* [ChromeDriver - WebDriver for Chrome - Downloads](https://chromedriver.chromium.org/downloads)
osを作る その16

#概要

osを作る。
setjmpで、カーネルモード、ユーザーモードを行ったり来たりする、システムコールを実装した。

#サンプルコード


```

#include <setjmp.h>

static jmp_buf kernel_context;
static jmp_buf user_context;
static int mode = 0;

void task1() {
	Serial.print("task1  ");
	Serial.println(millis());
}

void task2() {
	Serial.print("task2  ");
	Serial.println(millis());
}

void task3() {
	Serial.print("task3  ");
	Serial.println(millis());
}

void system_call() {
	if (setjmp(user_context))
	{

	}
	else
	{
		longjmp(kernel_context, 1);
	}
}

void setup() {
	Serial.begin(9600);
	if (setjmp(kernel_context))
	{
		if (mode == 1)
		{
			task1();
		}
		if (mode == 2)
		{
			task2();
		}
		if (mode == 3)
		{
			task3();
		}
		longjmp(user_context, 1);
	}
	else
	{

	}
}

void loop() {
	mode = 1;
	system_call();
	mode = 2;
	system_call();
	mode = 3;
	system_call();
	delay(800);
}





```

以上。
ポータルユーザ問い合わせ時，Chatterグループへの自動投稿実装方法

ちょっと整理したい中身です。

[ポータルユーザ問い合わせ時，Chatterグループへの自動投稿実装方法](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000CgY9o)


別案：Chatter投稿アクションではなくカスタム通知アクションを使う

ゲストユーザの場合、Chatter投稿アクションができない、とサポート回答ありました。ポータルユーザでも似たような制限があるのかもしれません。
カスタム通知アクションであればゲストユーザでも実行でき、プロセスビルダーで作成できます。
右上のベルマークに通知がくるやつです。モバイルにプッシュ通知もできます。

一応やり方を書いておきます。
　設定→カスタム通知　でカスタム通知を新規作成。チャネルは全部チェック。
　設定→通知の配信設定→作成したカスタム通知を編集　でiOS、Androidにチェック。
　設定→公開グループ　で新規作成し、通知したいユーザグループを作成。
あとはプロセスビルダーでカスタム通知アクションを選び、グループAPI名を指定できます。
非モバイルユーザへの通知には必要に応じてメールアラートアクションを別途作成する必要あります。
デメリットはChatterではないので公開記録としては残りませんし、通知したいグループメンバーをユーザ側ではなくシステム管理者が管理していく必要があります。

**パターン1**
のフロー実行者を変える方法も検討してみたのですが、レコードトリガフローでは方法が見つかりませんでした。

https://help.salesforce.com/s/articleView?id=release-notes.rn_forcecom_flow_fbuilder_scheduled_paths.htm&type=5&release=230

 

**パターン2**
Otsubo Keijiさんの方法でできるかもしれません。

Chatterアクションのヘルプにあるように表示を"allUsers"に指定する必要があるようです。

https://help.salesforce.com/s/articleView?id=sf.flow_ref_elements_actions_chatter.htm&type=5

私はコミュニティIDの設定方法がよくわからず、別案で妥協してしまいました。

Chatter投稿できる方法があれば是非知りたいです。

 

**IdeaExchangeにも挙がっていてUpvoteしました。**

https://trailblazer.salesforce.com/ideaView?id=08730000000keDRAAY
Vue.js + Electron の環境構築

# 前提

Node.jsはすでにインストールされていることとする

# 「vue/cli」のインストール

```
npm install -g @vue/cli
```

# プロジェクトの作成

```
vue create sample_project
```

# vue-cli-plugin-electron-builder の追加

```
cd sample_project
vue add electron-builder

# uiライブラリを追加
vue add vuetify

# store機能の利用に使用
npm install vuex --save
```

# 起動

```
npm run electron:serve
```

# ビルド

```
npm run electron:build
```

dist_electron配下にビルドファイルが生成される
Cloud9のデフォルトのインデント値設定方法

# はじめに
プログラミング初学者の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。
Cloud9のインデントのデフォルト値の変更方法の共有です。

# 設定
1. 設定の歯車マーク
1. Code Editer (Ace)
1. Soft tabsに任意の数値を設定

以上です！

![Screen Shot 2021-09-16 at 6.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/9588dbb3-6cf5-0e8b-0cfa-8fdbf1dcb461.png)

# おわりに
お読みいただきありがとうございました！
（Qiita10周年おめでとうございます🎉）
Raspberry Pi の集団使用に NFS は有効だろうか

#ここまでのあらすじ
次のテクニックの活用により、Raspberry Pi 4Bをベクトルタイルサーバに使うアイディアを急速に実装しつつあるところです。

-　ストレージ速度問題の克服のため、普通にext4でフォーマットしたHDDを接続する
-　HTTP/2を使用する（ベクトルタイルのアクセスパターンだと、速度がかなり向上）
-　前項のために、Let's EncryptでSSL証明書をとる
-　前項のために、ドメイン optgeo.org を獲得運用する
-　サーバはいわゆる自宅サーバ方式とし、動的 DNS に近い運用を Route 53 で追求することにする
-　監視メッセージは Slack に投げる

このあらすじの中で、外から見た IP アドレスのモニタリングと　DNS レコードの動的更新は未実装ですが、ベクトルタイルサーバとしては概ね安定してきていると思います。

Unixらしい使い方をすることに躊躇しない、というアプローチをとったのが奏功しているように主観的には思っています。

##運用デモ

https://x.optgeo.org/hrlulc/

#直面している課題
ベクトルタイルサーバを維持しつつ、新たなベクトルタイルを生産していきたいと思っています。

ホストと生産は機体を分けたほうが良いはずなので、複数の Raspberry Pi 4B を集団使用することになります。

現在のところ、機体ごとに持たせているプロジェクトが違うという形になっていますが、これは非効率的です。そもそも、Raspberry Pi を immutable infrastructure のように使うというのが当初コンセプトでした。

そこで、ネットワーク・ストレージの使用について考慮することになります。

##NFS使用の可能性についての初期的検討

1. Raspberry Pi で NFS は使えるようです。
1. NFS の速度は大体 10MB/s 程度になるようです。
1. 通常、Raspberry Pi の SD カードストレージの速度は 50MB/s オーダーなのだそうです。
1. NFSのバージョンを適切に選べば、sqliteのデータを置いても問題ないという情報があります。mbtilesファイルはsqliteのファイルなので、このことは考慮するべきと思っています。ただし、実際には、どのストレージに何を置くのか、というのは back pressure に関して考察した経験によって決めると思います。そうすると、mbtiles は少しでも速い方のストレージに置くのかもしれません。むしろ、ソースデータの一時置き場とかに NFS ストレージは有効かなと思います。

ということで、手隙の時間で試してみようと思っています。
LaTeX で定義しておくと便利な数式コマンド


# はじめに
皆さんは論文執筆の際にLaTeX使われていますか？
使われている方、いいですねー。
私も大学にいたときにはLaTeXでかっこよく決めていたものです。
（もうかなり前の話だけど…）
そんなあなたに、定義しておくと数式作成のときに便利なコマンド集をお送りします。
役に立たないかもしれませんが、ご参考にどうぞ。

# コマンド集

1. 微分記号$\frac{\rm d}{\rm dx}$

```
\newcommand{\dd}[2]{\frac{{\rm d} #1}{{\rm d}#2}}
```

2. 偏微分記号$\frac{\partial }{\partial x}$

```
 \newcommand{\pp}[2]{\frac{\partial #1}{\partial #2}}
```

3. 括弧()

```
\newcommand{\lr}[1]{\left(#1\right)}
```

4.かぎ括弧[]

```
\newcommand{\LR}[1]{\left[#1\right]}
```

5. 複数の変数を表示する場合

```
\newcommand{\vars}[2]{#1_{1},#1_{2},\cdots,#1_{#2}}
``` 

6. 複数の変数を微分記号付きで表示する場合

```
\newcommand{\rd}{{\rm d}}
\newcommand{\dvars}[2]{\rd #1_{1}\rd #1_{2}\cdots\rd #1_{#2}}
```
リリースノートとは何か、何を書くのか - Markdownフォーマット付

## リリースノートとは

https://en.wikipedia.org/wiki/Release_notes

> （翻訳）
リリースノートとは、ソフトウェア製品やハードウェア製品と一緒に配布される文書のことで、製品がまだ開発やテストの状態（ベータリリースなど）のときに配布されることもある。 すでに顧客に使用されている製品の場合は、アップデートがリリースされたときにリリースノートが顧客に届けられる。また、リリースノートの別の略語として、Changelog or Release logs, Software changes, Revision history Updates あるいは README fileがある。

### 日本語では
 
https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%8E%E3%83%BC%E3%83%88

> リリースノートは、ソフトウェア製品の個別のリリースバージョンに関する **機能強化、仕様変更、不具合修正などを、エンドユーザーや製品購入者に対して提示することを目的とする。**

> リリースノートは個別のリリース内容について簡潔に記載されるものであって、**仕様書やマニュアルの役割を担うものではない。**

一般的なフォーマットは以下とのこと。

```markdown:Format
## ヘッダー 
- 資料名称、製品名、リリース番号、リリース日、リリースノート番号、リリースノート作成日など
## 概要
- 製品や変更点に関する簡潔な説明
## 目的 
- リリースノートの提供目的に関する簡潔な説明
## 更新事項の説明
- リリースにともなう更新事項（機能強化や不具合修正など）に関する簡潔な説明
## 再現手順 
- 不具合の発生条件や手順
## 解決方法 
- 機能強化や不具合修正の方法に関する簡潔な説明
## エンドユーザーへの影響 
- エンドユーザーがとるべき特別な対処や、他機能に与える影響など
## サポートへの影響 
- ソフトウェア管理プロセスに与える影響など
## 備考 
- ソフトウェアやハードウェアのインストール、バージョンアップ、製品資料の更新などに関する説明
## 免責事項や契約内容

```
https://e-words.jp/w/%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%8E%E3%83%BC%E3%83%88.html

> リリースノートとは、新しいソフトウェア（の版）を発行する際に同時に公表される、以前の版からの変更点や利用上の注意点などをまとめた文書。

> ソフトウェアの種類によって内容は異なるが、前の版からの改良点や新機能の情報、修正した不具合や既知の（未解決の）問題点の情報、動作環境や対応機器・ソフトウェア・データ形式、使用上注意すべき事項などで構成されることが多い。

> **基本的には既存の利用者向けに変更点を簡潔に伝達するために作成されるもので、ソフトウェア自体の機能や仕様、操作法、使用条件、免責事項などを網羅的に詳細に説明するための文書ではない。**

## 一般的なサンプル

https://support.apple.com/en-us/HT211808

https://docs.microsoft.com/ja-jp/windows/release-health/release-information

https://experienceleague.adobe.com/docs/experience-manager-65/release-notes/release-notes.html?lang=ja-JP


### かわいいサンプル

https://note.com/harco7/n/n3ae7e1448f49

https://www.gizmodo.jp/2020/02/slack-update.html

#### その中身：

![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/864c1063-f44d-c9f2-f3e3-f2a11fbedbed.png)

#### すっこここ

https://www.itmedia.co.jp/news/articles/2109/22/news117.html


## 良いリリースノートの書き方

https://simonwillison.net/2022/Jan/31/release-notes/


## まとめ

リリースノートは、大まかな共通フォーマットはあるものの、最終的には提供者に委ねられている。リリースノートに何を書くべきか、マニュアルや仕様書との違いの意味などをあらためて考えて良さそう。

以上参考になればさいわいです。
UNVT に関する考察 2021-09

# UNVTとは何を指すのか
## プログラム？
どちらかというと、そうではないように思います。プロのカートグラファーは自分のプログラム作成能力の限界を知っており、プロのプログラマーがいかに優秀であるかを知っています。
他方で、プロのカートグラファーは、必要な時には自分でプログラムを書くことを躊躇しません。ただ、プログラムを書かないで進められる方がベターであることを知っています。
ちなみに、この考え方は、ややUnixフィロソフィーに通じるところがあるような気がします。
## ツールの組み合わせ？
この理解は、最も現実に近いと思います。UNVTのTは、ToolkitのTです。Toolkitとは道具箱のことです。プロのウェブ・カートグラファーの道具箱になりたい、とUNVTは思っています。
センスのあるツールの組み合わせであることをUNVTは志向すると思います。
プロの道具箱であるだけに、ツールの選定には妥協がありません。このため、ツールの入れ替わりはよくあるべきだと思います。プロは仕事の本質を変えませんが、仕事のやり方は常に改善します。
## ワークフロー？
確かに、UNVTは特定のワークフローを伴って使われます。また、特に大規模な基本図データを取り扱う際に、問題の適切な分割統治や、ワンストリームでTippecanoeにデータを流す、といった特定のテクニックをよく使います。また、試作・計測・試作・計測・試作・計測...を繰り返せ、という教えをUNVTは伴うことも多いです。また、並行処理のループをひっくり返すことによる速度の劇的な向上、といったソフトアプローチをUNVTは好む傾向があります。
他方で、ツールに妥協しないだけにツールの入れ替わりをためらわないのと同じで、仕事に妥協をしない以上、ワークフローについても常に入れ替わりや改善があります。

# UNVTを使うためには何が必要か
## ハード
ハードは与えられるものになる場合が多いです。ハードの性能をどのようにして最大限に発揮するか、というアプローチで問題に向き合う場合が多いでしょう。多くの場合、ベクトルタイル生産における最大のボトルネックはディスクIOです。選べるならば早いストレージを持つべきです。
また、タイル生産は並行性を活用できることが多いです。
## ソフト
ソフトについては、ポータビリティを重んじます。なぜならば、与えられたハードを最大限に生かせる環境は多様である場合が多く、どのような環境でも動かせることが望ましいです。
なお、Unixはポータビリティを重んじます。また、具体的に、最近はIntelでもARMでも問題なく動くような形になることはありがたいと思うところです。
## データ
データは、選ぶものまたは与えられるものです。どのようなデータに対してもベクトルタイルを生産できることが望ましいと思います。
最近は、変わり種のソースデータとして、ラスタデータやポイントクラウドデータなども扱っています。このようなデータにも、ベクトルタイルの恩恵を受けるチャンスがあるとみています。
## スキル
プロのカートグラファーにとって、最も身に近いものというのはスキルであるように思います。転任、転居、出向、転職をしたとしても、必ずスキルは本人の身についてくるものです。UNVTはスキルという観点を大切にします。
難しい言葉を使うとすれば、ケイパビリティ（capability）とも描写できるかもしれません。
実際に手を動かして検証する、というアプローチは、スキル/ケイパビリティによく効きます。

[CJCSI 5123.01H](https://www.jcs.mil/Portals/36/Documents/Library/Instructions/CJCSI%205123.01H.pdf?ver=2018-10-26-163922-137)によれば、ケイパビリティとは、the ability to complete a task or execute a course of action under specified conditions and level of performance という意味なのだそうです。
AXUIElementを操作するために


#はじめに


macで他のアプリのウィンドウを移動させるアプリケーションを作りたいと思い、色々と調べたところ

https://qiita.com/Kyome/items/b51d3c78d44e44a94921

の記事が参考になりました。

しかし実装中、上記の記事の制限事項の回避をしていなかったため、`AXUIElement`を操作する`AXUIElementCopyAttributeValue`や`AXUIElementSetAttributeValue`を使うための権限がアプリに付与されておらず、うまくオブジェクトの情報を取得できずにはまってしまいました。

そこで忘れないうちに、制限を回避するためのアクセシビリティの権限をアプリに付与する方法を残しておくことにしました。

#解決方法
## 1. SandBoxをオフにする

Xcodeで自動生成される`アプリ名.entitlements`ファイルのApp sandboxをNOに変更する
![entitlements.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417405/f5c6f234-3bab-f5f6-defa-bba1fdbdfbd8.png)
アクセシビリティの API はApp SandBox環境では叩けないようなので、SandBoxの設定を外します。


## 2. アクセシビリティの権限を付与する

以下のコードを挿入する。

```
let options: NSDictionary = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as String : true]
let accessEnabled = AXIsProcessTrustedWithOptions(options)
if !accessEnabled {
    print("Access Not Enabled")
}
```

`AXIsProcessTrustedWithOptions`でアプリにアクセシビリティの権限があるかどうか確認し、ない場合は権限を与えるかどうかのダイアログが表示されるので、システム環境設定で許可を与えます。


#おわりに
わかる人にとっては簡単なことでも、知識がないと苦労しますね。
今回初めてまともなアプリを制作してますが、ちゃんとしたエンジニアへの道はまだまだ先が長そうです。
ISO配列？UK配列？MacBookProでWindows(JIS配列)キーボードを利用するには

## 実現したいこと

* ISO配列？UK配列？MacBookProでWindows(JIS配列)キーボードを接続し問題なく日本語入力する。
* [半角/全角]キー, [無変換]キー, [変換]キー, [カタカナひらがな]キーを利用する。

## 対応方法

### macのキーボード設定を変更する

* 「£」の入力よりも「#」の入力が多い場合は、次の通りに「システム環境設定...」> 「キーボード」> 「入力ソース」でイギリス配列キーボードを削除し、英語配列キーボードにする
![スクリーンショット 2021-09-16 3.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49795/79dc028c-53e7-80c3-6efb-8f50721f2661.png)

### Karabiner-Elementsをインストールする

```
brew install karabiner-elements
```

* インストール後はガイダンスに沿って「システム設定」と「セキュリティとプライバシーの設定」を実施する。

### Karabiner-Elementsでキー設定を行います

![スクリーンショット 2021-09-16 3.58.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49795/8a1aaa60-3ed3-2341-cdd9-34868ec8051c.png)

![スクリーンショット 2021-09-16 3.58.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49795/e950e183-e733-1816-7092-5792445f5668.png)

![スクリーンショット 2021-09-16 3.57.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49795/ee54a678-a7d3-cd48-40bb-802014210c42.png)

## macのキーボード設定を変更する

* 情報源の欄に記載しているWebPageを要確認してください

![スクリーンショット 2021-09-16 4.10.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49795/8db6a7ef-17e4-0ec3-7aa1-0b77f903f52a.png)


## 情報源

* https://lifelikewriter.com/mac-winkeyboard/
* https://colo-ri.jp/develop/2019/01/macos-ej-ime.html
* https://support.apple.com/ja-jp/HT201794
* https://qiita.com/mzuk/items/9e0c8ee7e849d86a794f

## 注意点

* 中古SHOPで陳列されている中で一番値段が安くUS配列のMacBookProだと思い購入し、自宅で確認したらISO配列？UK配列？だったようです ..... orz ..... 初めて触った... こういう事がないようにキーボード配列をよく確認して機材を購入したほうがいいです ...

## 使用したキーボード

* MacBookPro ISO配列(イギリス)...?? UK配列??
* FILCO Majestouch 2 HAKUA Tenkeyless
  * 茶軸・テンキーレス・かなあり・マットホワイトFKBN91M/JMW2
  * https://www.diatec.co.jp/products/det.php?prod_c=2755
railsチュートリアル第４章 ユーザークラス

####ユーザークラス

```rb
class User
  attr_accessor :name, :email

  def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
  end

end
    
```

```rb
  attr_accessor :name, :email
```
ユーザー名とメールアドレス（属性: attribute）に対応するアクセサー（accessor） をそれぞれ作成
アクセサーを作成すると、そのデータを取り出すメソッド（getter）と、データに代入するメソッド（setter）をそれぞれ定義
インスタンス変数は常に@記号で始まり、まだ定義されていなければ値がnil

initializeは、Rubyの特殊なメソッドです。これは User.newを実行すると自動的に呼び出されるメソッド

```rb
 def initialize(attributes = {})
    @name  = attributes[:name]
    @email = attributes[:email]
 end
```
attributes変数は空のハッシュをデフォルトの値として持つため、名前やメールアドレスのないユーザーを作ることができます

```rb
def formatted_email
    "#{@name} <#{@email}>"
end
```
このメソッドは、文字列の式展開を利用して、@nameと@emailに割り当てられた値をユーザーのメールアドレスとして構成

requireして、自作したクラスを試しに使ってみましょう。

```rb
>> require './example_user'
=> true
>> example = User.new
=> #<User:0x00007f410082a2b0 @name=nil, @email=nil>
>> example.name
=> nil
>> example.name = "Example User"
=> "Example User"
>> example.email = "user@example.com"
=> "user@example.com"
>> example.formatted_email
=> "Example User <user@example.com>"
```
```require './example_user'``` requireのパスにある’.’は、Unixの “カレントディレクトリ”
’./example_user’というパスは、カレントディレクトリからの相対パスでexample_userファイルを探すように指示
```example = User.new``` 次のコードでは空のexample_userを作成します

####演習
1.クラスを作成

```rb
class User
  attr_accessor :first_name, :last_name,  :email

  def initialize(attributes = {})
    @first_name  = attributes[:first_name]
    @last_name = attributes[:last_name]
    @email = attributes[:email]
  end
  
  def full_name
    "#{@first_name} #{@last_name}"
  end
  
  def formatted_email
    "full_name  <#{@email}>"
  end
  
  def alphabetical_name
    "#{@last_name}, #{@first_name}"
  end
  
end
```

2.```alphabetitcal_name```メソッドを作成

```rb
def alphabetical_name
    "#{@last_name}, #{@first_name}"
end
```

3.```full_name.split```と```alphabetical_name.split(', ').reverse```の結果を確認

```rb
>> user.full_name.split
=> ["Michael", "Hartl"]
>> user.alphabetical_name.split(', ').reverse                              
=> ["Michael", "Hartl"]
```
同じになった。
railsチュートリアル第４章 コントロールクラス

####コントロールクラス
クラスや継承を勉強してきた。

```rb
lass StaticPagesController < ApplicationController

  def home
  end

  def help
  end

  def about
  end
end
```
#####クラス階層を調べよう。

```rb
>> controller.class
=> StaticPagesController
>> controller.class.superclass
=> ApplicationController
>> controller.class.superclass.superclass
=> ActionController::Base
>> controller.class.superclass.superclass.superclass
=> ActionController::Metal
>> controller.class.superclass.superclass.superclass.superclass
=> AbstractController::Base
>> controller.class.superclass.superclass.superclass.superclass.superclass
=> Object
```


```Object ```
↑
```AbstractController::Base```
↑
```ActionController::Metal```
↑
```ActionController::Base```
↑
```ApplicationController```
↑
```StaticPagesController```
という風になっている。

```rb
>> controller.home
=> nil
```
。Railsのアクションには戻り値がありません

####演習
toy_appを消していたから解けなかった。
VSCode の設定のこと、トラブルの事、

:::note
環境：Windows10
:::

#

自動整形用の書式設定、しかも個人の環境なのでグローバルに設定する事にしたよ。

VSCodeの設定、色々解決しないといけない問題が出るわ出るわ、まいっちんぐよ。

- C#フォーマットが思い通りにならない。
- Vimを入れると Ctrl+x 等のコピペが出来なくなる。

諸々解決していきましょう。

## C#自動整形 (Shift+Alt+F)
使用してる物
<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47947/f4b371c7-cb19-8631-d578-5d27bd80adc9.png">
Format On Save は切っておきます。(お好みで)
<img width=50% src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47947/6b82739d-7f9b-52fd-5ecc-b5f44d913cd9.png>

Roslyn を有効にする

> Omnisharp: Enable Roslyn Analyzers
Enables support for roslyn analyzers, code fixes and rulesets.

Roslynは、素晴らしい物だ。
サイトの説明を読めば自信をもって有効にできるね。

https://www.buildinsider.net/enterprise/roslyn/01



突然困った事が発生した。以下のようなフォーマットにされてまった事。

```c#
var base = DynamicPiyoPiyo
                .getHOGE(HOGE)
                .HOGE()
                .HOGE();
```

もうねパラメータの英語ドキュメントの説明分もなくてさ、どれを変えればいいか分かんなかったよね。

`$HOME/.omnisharp/omnisharp.json`を作成したりして試した。
以下のどれかの項目だと思ったんだけど、違くて...

    "NewLinesForBracesInTypes": true,
    "NewLinesForBracesInMethods": true,
    "NewLinesForBracesInProperties": true,
    "NewLinesForBracesInAccessors": true,
    "NewLinesForBracesInAnonymousMethods": true,
    "NewLinesForBracesInControlBlocks": true,
    "NewLinesForBracesInAnonymousTypes": true,
    "NewLinesForBracesInObjectCollectionArrayInitializers": true,
    "NewLinesForBracesInLambdaExpressionBody": true,
    "NewLineForElse": true,
    "NewLineForCatch": true,
    "NewLineForFinally": true,
    "NewLineForMembersInObjectInit": true,
    "NewLineForMembersInAnonymousTypes": true,
    "NewLineForClausesInQuery": true

それで結局どうしたかっていうと、
Extention C# のデフォルトで問題なかったです。
訳が分からないんだけど、何で最初のような改行されたのか、Prettierが機能してたのかもしれない。

一応 Prettier は settings.jsonから外しました。
ぐだぐだしてたら治ってしまったので実際の所どうなのかわからなかったけど。
settings.json

```json
{
    "editor.defaultFormatter": "esbenp.prettier-vscode",
    "[csharp]": {
        "editor.defaultFormatter": "ms-dotnettools.csharp"
    }
}
```


ここが怪しい。「EditorFormattingSettings」ってことは上記で試した omnisharp.json の設定反映されてなかったんじゃないのとも思うが。
<img width=50% src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47947/148ee64f-a54a-70ef-1f5d-4537314a7bb0.png>


## Vim拡張の有効時も通常のショートカットが使いたい

インサートモードにしてもコピー、切り取り、貼り付けのショートカット（Ctrl+[c, x, p]）ができなかった。
**何故かってショートカットが重複してるから。**
「Ctrl + a」も使えない。
こりゃ、winとvimキーバインドは両方どっちも使いたいよ？でもどっちを取る？

ここへきて、なるほど windows と vim の相性の悪さよ。
やっぱMacでいいんじゃないかって思えてきたよ。
Windowsにコマンドキーが無いのが悪い。
Windowsキーがあるじゃないか…
それなー

とりあえず以下

```
"vim.handleKeys": {～～で設定できるらしい
```

↓ 助かった！

https://tc.hatenablog.com/entry/2016/11/29/225724

# 突然のトラブル

* 拡張機能 C# フォーマットが出来ません
    * Ans.　今回の場合フォルダ名を変更したことで solutionファイルが見つからなくなってた模様。C#ファイルをダブルクリックして開いた時にVSCode上に slnファイルを選択するドロップダウンメニューが出てきていたので選択したら正常に戻った。
    * やったこと、設定の変更
        * settings.jsonのeditor.defaultFormatter 部分を削除して再起動したり、Omnisharp:Enable Roslyn AnalがOFFになってたのでONにして再起動とか、
        * Roslyn 実は不要？なのか分からなくなった。