OmniAICreator/Qiita-1.07M huggingface dataset:
Rails gem rooを使って、エクセルファイルからデータ保存

# 目的
ユーザーが複数のデータをアプリに投稿したいとき、エクセルファイルを選択するとデータベースに保存できるようにしたい。
# 実装
#### アプリ立ち上げ

```terminal
rails new sample_app -d postgresql
rails db:create
```

rails newで新規アプリを作成、データベースも作成する。
#### コントローラー作成

```terminal
rails g controller users index
```

indexアクションを持つUserコントローラーを作成。
ルーターとビューも一緒に作成される。

#### モデル作成

```terminal
rails g model user name:string email:string
rails db:migrate
```

usersテーブルには、string型のnameとemailのカラムを作成。
#### ビュー

```html:app/views/users/index.html.erb
<h1>ユーザー一覧</h1>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>名前</th>
      <th>Eメール</th>
    </tr>
  </thead>
  <tbody>
    <% @users.each do |user| %>
      <tr>
        <td><%= user.id %></td>
        <td><%= user.name %></td>
        <td><%= user.email %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<%= form_with url: import_users_path, local: true do |form| %>
  <%= form.file_field :file %>
  <%= form.submit %>
<% end %>
```

投稿フォーム生成。ファイル自体を保存するわけではなく、params[:file]を送ったアクション:importにてUserを登録できるようにする。
#### ルーター

```ruby:config/routes.rb
Rails.application.routes.draw do
  resources :users do
    collection do
      post :import
    end
  end
end
```

UserにPostメソッドの:importアクション用のルーティングを追加する。
#### コントローラー

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def import
    User.import(params[:file])
    redirect_to users_url
  end
end
```

indexアクションはscaffoldを使ったときと同じで全レコードを取得し、@usersに代入。
importアクションは、params[:file]を受け取って、usersテーブルのレコードを作成するimportメソッドを使う。モデルには、importメソッドの定義を書く。
#### モデル

```ruby:app/models/user.rb
class User < ApplicationRecord
  def self.import(file)
    xlsx = Roo::Excelx.new(file.tempfile)
    xlsx.each_row_streaming(offset: 1) do |row|
      user = self.new(id: row[0].value, name: row[1].value, email: row[2].value)
      next if self.pluck(:id).include?(user.id)
      user.save
    end
  end
end
```

Userモデルのモデルメソッドなので、def self.import　の形で定義。params[:file].tempfileに送信したファイルのパスが入る。Roo::Excelx.new(file.tempfile)でファイルを読み取り、変数xlsxに代入。each_row_streamingメソッドで読み込んだファイルの行毎に処理を実行。
offsetオプションによって、処理を飛ばす行数を指定できる(一行目の項目欄を飛ばす)。
next if self.pluck(:id).include?(user.id)で同じidがusersテーブルに存在している場合は処理をスキップしている。

gem rooを使えるように準備をする。
#### gem rooを使う準備

```terminal:Gemfile
gem "roo" #追記
```

ターミナルでbundle installする。また、config/application.rbにrequire "roo"を追記

```ruby:config/application.rb
# 省略
require 'rails/all'
require "roo"
# 省略
```

これで、OK。

# 確認
サーバーを立ち上げ "http://localhost:3000/users" にアクセスして画面を確認する。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496707/7c81ad61-bfd3-7191-afc6-6740fc3dfae1.png)
ファイルを選択を押して、次のようなエクセルファイルからデータを登録できる。
![エクセル.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496707/c4702291-abaf-9103-6b97-ea128729a362.png)
登録後、次のように画面が変わっていることを確認する。
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496707/c99f11b8-08e0-388b-1cfd-4162a1f9e4d1.png)

# 参考記事
https://qiita.com/seitarooodayo/items/c9d6955a12ca0b1fd1d4
https://qiita.com/guri3/items/f20487516311b2a3db37
本当に参考になりました！ありがとうございます！

# 後書き
応用して、社員表を一気に登録する機能をアプリに作ってみようと思います。
Ruby on Rails5 速習実践ガイド5.2対応　Chapter2

#Chaptrt2　Railsアプリケーションをのぞいてみよう

**Windows10の環境構築**
実習でHyperVマネージャーにより、仮想環境はすでにあり。
**Ubuntu　18.04.3**をインストール
**rbenv 1.1.2-30-gc879cb0** Gitを使ってGitHubからをインストール。
**Ruby 2.5.1**　インストール
**Rails** インストール
**Node.js** のインストール
>JavaScriptを用いる場合、効率よく配信するためにJavaScriptを圧縮する機能が備わっているが、そのためにJavaScriptランタイムが必要となるためにインストール。

**PostgreSQL** をインストールしセットアップ
PostgreSQLを起動。
　`sudo service postgresql start`

　
　`sudo su postgres -c 'createuser -s {Ubuntuのログインユーザ}'`
　を打つと、以下のエラーが出た。

　`psql: FATAL: role “postgres” does not exist`
　{}無しでUbuntuのログインユーザー名を記載したらすんなり通りました。

scaffoldを使ってscaffold_appという名前で「ユーザー管理アプリケーション」をRailsのコマンドで自動生成させる。
　`rails new scaffold_app -d postgresql`

　`rails new`　コマンドはRailsアプリケーションのひな型を生成。
アプリケーションの名前を`scaffold_app`と指定。
scaffold_appディレクトリと関連ファイルが生成されて、ログ出力される。
この後　bundle installが自動的に実行されて、Railsの実行に必要なgemがインストールされる。
データベースの作成。config/databese.ymlというファイルの定義をもとに。

`bin/rails s db:create`

「rails」ではなく「bin/rails」で、アプリケーションのルートディレクトリ直下のbinディレクトリにあるrailsというスクリプトを呼び出している。Gemfileどおりのgemを利用できる環境上でrailsコマンドを実行できる。
**railsサーバー起動**
　`bin/rails s`

railsは標準のHTTPサーバとしてPumaを採用。

**WEBブラウザでサーバーの起動を確認**
　アドレスバーにhttp://localhost:3000/を入力。

**ユーザー管理機能のひな型を作る**
「ユーザー」に関するscaffoldを自動生成。
　`bin/rails generate scaffold user name:string address:string age:integer`

**ユーザー管理機能に使うテーブルをデータベースに作成。**
　`bin/rails db:migrate`

**ユーザー一覧画面を表示**
　`http://localhost:3000/users`
WEBブラウザへ上のURLを入力してアクセス。

**重要だと思ったポイント**

- ユーザーを管理するために必要な機能「CRUD」が生成されている。
　**「作成(create)」「読み出し(read)」「更新(update)」「削除(delete)」**
- コードの通り道
Railsアプリケーションは、**MVC（モデル・ビュー・コントローラ）**という考え方で構成。
コントローラーが呼ばれる。コントローラーにはリクエストに対する処理が書かれている「アクション」と呼ばれるメソッドが定義（一覧画面にアクセスした際はidnexアクション）されている。
AtCoder 生活　83日目

[前回](https://qiita.com/flandrescarlet237/items/3c15603888c43f7b40f6)

#83日目
今回は茶色diffの問題を2問解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC094|C|◯|32分3秒|
|ABC137|C|◯|52分55秒|

##[ABC094_C](https://atcoder.jp/contests/abc094/tasks/arc095_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll n;
    cin >> n;
    vector<ll> x(n);
    vector<ll> y(n);
    rep(i,n) cin >> x[i];
  	y = x;
    sort(x.begin(),x.end());
    int a = x[n/2 - 1];
    int b = x[n/2];
    rep(i,n){
        if(y[i] <= a) cout << b << endl;
        else cout << a << endl;
    }
}

```

解くのにかかった時間：32分3秒


##[ABC137_C](https://atcoder.jp/contests/abc137/tasks/abc137_c)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll n;
    cin >> n;
    vector<string>  s(n);
    rep(i,n){
        cin >> s[i];
        sort(s[i].begin(),s[i].end());
    }
    sort(s.begin(),s.end());
    ll ans = 0;
    ll cnt = 1;
    rep(i,n-1){
        if(s[i] == s[i+1]) cnt++;
        else {
            ans += cnt*(cnt-1)/2;
            cnt = 1;
        }
    }
    ans += cnt*(cnt-1)/2;
    cout << ans << endl;
}


```

解くのにかかった時間：52分55秒


###最後に
もっと早く解かないと茶色になれない

難易度|かかった平均時間|解けた問題数|
|:-:|---|---|
|C|42分29秒|2問中2問|
vscode...

いままで、ソースといえばemacs、もしくはちょっともっさりでほとんど使っていなかったeclipseだった。

MicroS...この頭２文字だけでも拒否反応を示していたが。。

vscodeをlinux上でdebパッケージインストール。

快適というか、この補完度がたまらない。。たまに、おせっかいなところもあるが。
といって、あのeclipse的なもっさり感はなく。サクサク。


おせっかい感とまだ新車の高機能車に乗ったばっかりなので
いろいろいじっているとこ。
JavaScriptをすこーし勉強してみたので書き留める④

最低限の知識一応あるけど、復習も兼ねて書いてみることにするの巻その④

## 関数宣言と関数式（超ざっくり）
- 関数式
    - 実行が関数式に到達された時に作成される。その後から使用できる。
    - if文外で変数宣言⇨if文内で関数式を使用して代入する⇨あとで使える
- 関数宣言
    - スクリプト/コードブロック全体で使用できる。
    - 関数宣言は関数式より早く使えるようになる
    - ブロック外だと使えない


## アロー関数
アロー関数で書くと...

```
let func = (arg1, arg2, ...argN) => expression
```

同じのを関数式で書くと...

```
let func = function(arg1, arg2, ...argN) {
  return expression;
}
```

使ってみよう！こんな感じ。

```
let sum = (a, b) => a + b;

/* アロー関数は次よりも短い形式です:

let sum = function(a, b) {
  return a + b;
};
*/

alert( sum(1, 2) ); // 3
```

引数一つならかっこ省略でもっと短く。

```
// 次と同じです
// let double = function(n) { return n * 2 }
let double = n => n * 2;

alert( double(3) ); // 6
```

引数なしならかっこは必須。

```
let sayHi = () => alert("Hello!");

sayHi();
```

アロー関数は引数式と同じように使用できる。

```
let age = prompt("What is your age?", 18);

let welcome = (age < 18) ?
  () => alert('Hello') :
  () => alert("Greetings!");

welcome(); // ok now
```

複数行のアロー関数

```
let sum = (a, b) => {  // 波括弧を使って複数行の関数を書けます
  let result = a + b;
  return result; // 波括弧を使った場合、結果を得るには return を使います
};

alert( sum(1, 2) ); // 3
```

------------

雑になってしまった....
ちゃんと書けるようになって理解したら書き直そうかね。
頭脳労働のムダ（無駄）

皆さんは、毎日の頭脳労働の中で次の様な状態に陥った事は無いでしょうか？ 

1. 集中力が無くなり、思考が停滞する。
2. 作業を進めるための情報が少なく、遣り方が見えない。
3. 何かに躊躇していて、重大な事でなくとも決定できない。
4. 段取りが抜けていて、次の作業へ直ぐに移れない。 
5. 思考がループしていて抜け出せない。 
6. 今出来ない一寸、横に退けていよう。 

ここに載せた様なことが**頭脳労働**のムダです。 

の頭脳労働のムダを**是正する方法**についてご紹介します。

##二人一組での作業 
常識的、論理的に考えると、一つの仕事を二人で担当する事は、大変な非効率と考えられますが、頭脳労働者（＝知識労働者：状況に応じて異なる意思決定と行動が取れる労働者のこと／ピーター・ドラッカー（経営学者））にとっては、必ずしもそうでは有りません。

皆さんも経験があると思いますが、人に話す（声を出して考える）と自分の考えが意外にも、すらすらとまとまる事はありませんか？

また話すことによって人から自分の論理の矛盾を指摘された事は有りませんか？

頭脳労働者が二人で仕事をすると、思考錯誤や思考ループ等のムダを排除でき、結果的には、二人分以上の生産性を出す事が可能です。

さらに自身の理解度も判り、その時点での不足知識を浮き彫りにも出来ますので、品質に対するムラも排除できます。ソフトウェア製造において採用されるアジャイル開発のプラク ティスであるペア・プログラミングでも同様なことが言えます。 

##タイムボックス（決められた時間での作業）
従来の仕事の仕方は、なるべく良い結果を得る為に、熟慮を重ねて漏れの無い様にと考え時間に対して最大限（ある種無制限に近い）に使用するといった考え方が主流でした。(正解主義に通じる）

作業者の行動基準は、何らかの作業の一区切りを作業単位として考えています。頭脳労働にこの考え方を適用するとエンドレスになる危険性があります。それは作業が一区切り着くまでは作業完了と見なされないからです。

また、人夫々によって完了に至る時間がまちまちである為に、頭脳労働をチームで実施する場合は、この考え方が計画を大幅に狂わせる原因の一つとなります。

時間は有限なリソースであると言う考えに立って、一定の時間内で作業を完了させると言う意識変革が作業者に求められます。
これは別の表現をすれば作業者は常に時間を守る為に意思決定を迫られるという事です。今判っている事による結果出しをすすめる適応主義になるということです。

ソフトウェア製造において採用されるアジャイル開発のプラクティスであるイテレーショ ン・スプリント等でも同様なことが言えます。

簡単に説明してきましたが、頭脳労働そのもの自体を『見える化』してムダとりをするのではありませんが、二人一組の作業スタイルやタイムボックスという時間枠を採用する事 で頭脳労働の改善を進めることが可能なのです。  

この活動を従来の上下関係で実施するのでは効果よりも『やらされ感』による弊害が出 ますので注意いただきたいです。  

**『二人一組での作業スタイル』**と**『タイムボックス（決められた時間での作業）』**は様々な頭脳労働の現場で適用できることが分かっており、私も日々の実務の中でも実施しております。

ぜひ、皆さんの現場でもチャレンジしていただきたいとお勧めします。
Kinx Tips - UTF8 文字列のフォーマッティング

# Kinx Tips - UTF8 文字列のフォーマッティング

## はじめに

**「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。Kinx で実装したちょっとした小技を紹介。

* 参考
    * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
        * 個別記事へのリンクは全てここに集約してあります。
    * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
        * Pull Request 等お待ちしております。  

そう、ちょっとした小技。

## UTF8 文字列のフォーマッティングの問題

### C 言語の printf

UTF8 はバイト数と文字幅が一致しないので、"%-20s" とかしても微妙に揃いませんよね。半角カナも試しに使ってみましょう。

```c
#include <stdio.h>

int main()
{
    struct fruits {
        char *name;
        int price;
    } fruits[] = {
        { .name = "りんご", .price = 230 },
        { .name = "みかん(1袋)", .price = 450 },
        { .name = "ｸﾞﾚｰﾌﾟﾌﾙｰﾂ", .price = 120 },
    };
    printf("01234567890123456789\n");
    for (int i = 0; i < sizeof(fruits)/sizeof(fruits[0]); ++i) {
        printf("%-20s ... %3d 円\n", fruits[i].name, fruits[i].price);
    }
    return 0;
}
```

結果はこうなります。

```
01234567890123456789
りんご            ... 230 円
みかん(1袋)      ... 450 円
ｸﾞﾚｰﾌﾟﾌﾙｰﾂ ... 120 円
```

基本的にバイト数なので、日本語 3 バイトであれば 3 消費します。したがって幅が縮みます。

### Ruby の sprintf

C と同じかと思いきや、違います。

```ruby
fruits = [
    ["りんご", 230],
    ["みかん(1袋)", 450],
    ["ｸﾞﾚｰﾌﾟﾌﾙｰﾂ", 120],
]

puts "01234567890123456789"
fruits.each {|name, price|
    puts sprintf("%-20s ... %3d 円", name, price)
}
```

結果はこうなりました。

```
01234567890123456789
りんご                  ... 230 円
みかん(1袋)              ... 450 円
ｸﾞﾚｰﾌﾟﾌﾙｰﾂ           ... 120 円
```

バイト数ではなく文字数です。日本語も（何バイトであろうと） 1 文字で 1 消費します。なので、表示幅が増えます。文字数なので、半角カナだと実は一致します。

### Kinx のフォーマッタ

Kinx では UTF8 の文字幅を確認してフォーマット文字列の数値部分を自動調整します。表示幅として機能します。

```javascript
var fruits = [
    ["りんご", 230],
    ["みかん(1袋)", 450],
    ["ｸﾞﾚｰﾌﾟﾌﾙｰﾂ", 120],
];

System.println("01234567890123456789");
fruits.each(&(e) => {
    System.println("%-20s ... %3d 円" % e[0] % e[1]);
});
```

結果はこうなります。

```
01234567890123456789
りんご               ... 230 円
みかん(1袋)          ... 450 円
ｸﾞﾚｰﾌﾟﾌﾙｰﾂ           ... 120 円
```

Qiita のコードブロックでは等幅で表示されていない感じなので微妙ですが、等幅フォントで見れば縦ラインはきちんと揃っています。東アジア文字幅(East Asian Width)に従って調整するので概ねうまく動くはず [^1]。

[^1]: 「[ここ](http://www.unicode.org/reports/tr11/#Recommendations)」に従うと、東アジアの従来文字コードの文脈では Ambiguous Unicode characters は fullwidth 推奨ということでそちらに倒してます。でないと乱れる。

多くの人が期待する動作は **コレ** ではないでしょうか。

## おわりに

なかなか忙しくて記事が書けないとき用に、こういった小ネタもストックしておこう。

ではまた、次回。
Windows Subsystem for Linuxが表示されない

#WSLついて
WSL(Windows Subsystem for Linux)とは、Linuxのバイナリ実行ファイルをWindows 10およびWindows Server上でネイティブ実行するための互換レイヤーのこと。
Windows上でLinux環境を利用するために、「Windows Subsystem for Linux」を有効化する必要がある。

#事象
Windowsの機能を表示し、Wから始まる項目を探してみても「Windows Subsystem for Linux」が見つからない・・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594264/720415a8-28a5-b634-a89b-fd215bf1324f.png)


原因を調べたら、32bitだと表示されないとのこと。
自分のPCは64bitのため、関係なし。


#原因

Windows10のバージョンが2004のため、どうやら名称が翻訳されたらしい。
「Linux用Windowsサブシステム」を有効化することで解決した！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594264/5041a8cb-8504-7dea-cf05-4069ff811214.png)
Pandasでバージョンにより微妙に異なる動作

#はじめに

Pandasは超便利なライブラリではあるが、バージョンが変わると、以前動作していたものが動作しなくなったりすることがある。今回は、0.24⇒1.0にした時のケースとして2点あげる。

# その① ixが使えねー。

まずは、0.24で。'a'と'b'という列からなるデータフレームを作成し、ixで列を指定してみよう。

```0.24
>>>a = pd.DataFrame([[1,2],[3,4]], index=[1,2], columns=['a', 'b'])
>>> a.ix[:, ['a','b']]
   a  b
1  1  2
2  3  4
```
普通に使える。
次に、1.0で。

```1.0
>>> a.ix[:, ['a','b']]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\generic.py", l

ine 5273, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'ix'

```
使えねー。
しかし焦ることはない。
ixの代わりにlocを使えばいいのだ。

# その② locで存在しない列を指定するとエラー。

今度はそのまま、'c'という存在しない列を指定してみよう。
0.24の場合。

```0.24
>>> a.loc[:, ['a','c']]
   a   c
1  1 NaN
2  3 NaN

```

列を自動的に作成し、'NaN'で埋めてくれるようだ。気が利きすぎ？

次1.0で。

```1.0
>>> a.loc[:, ['a','c']]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\indexing.py",
line 1760, in __getitem__
    return self._getitem_tuple(key)
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\indexing.py",
line 1287, in _getitem_tuple
    retval = getattr(retval, self.name)._getitem_axis(key, axis=i)
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\indexing.py",
line 1952, in _getitem_axis
    return self._getitem_iterable(key, axis=axis)
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\indexing.py",
line 1593, in _getitem_iterable
    keyarr, indexer = self._get_listlike_indexer(key, axis, raise_missing=False)
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\indexing.py",
line 1550, in _get_listlike_indexer
    self._validate_read_indexer(
  File "C:\ProgramData\Anaconda3\envs\padnas1\lib\site-packages\pandas\core\indexing.py",
line 1652, in _validate_read_indexer
    raise KeyError(
KeyError: 'Passing list-likes to .loc or [] with any missing labels is no longer supported

, see https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#deprecate-loc-

reindex-listlike'

```

キーエラーが発生。これはこれで厳密でよいかもしれない。
対応としては、事前に列にそのキーが存在しているか調べた方がよさそうだ。

#最後に
今回、たまたま見つかった2例を紹介したが、他にも細かいところで多々動作が変わっていると思われるので、以下などにより、網羅的に変更点を確認した方がよいだろう。
https://pandas.pydata.org/docs/whatsnew/v1.0.0.html
multiprocessingでサブプロセスのログをメインプロセスから出力する

サブプロセスのログをメインプロセスから出力したい時がある。
multiprocessingの`get_logger()`とloggingの`QueueHandler/QueueListener`を使うときれいに実装できたのでメモ。

## 実装例

```python
import logging
import multiprocessing
from logging.handlers import QueueHandler, QueueListener


# サブプロセスで動く関数
def process(i):
    logger = multiprocessing.get_logger()
    logger.warning(f"num {i}")


def main():
    manager = multiprocessing.Manager()

    # queue作成
    queue = manager.Queue()

    # loggerの設定
    logger = multiprocessing.get_logger()
    logger.setLevel("WARN")
    logger.addHandler(QueueHandler(queue))  # queueに出力するようにする

    console_handler = logging.StreamHandler()
    console_handler.setFormatter(logging.Formatter("%(processName)s %(message)s"))
    listener = QueueListener(queue, console_handler)  # queueを見るようにする
    listener.start()

    # サブプロセス起動
    logger.warning("start!")

    with multiprocessing.Pool(processes=2) as pool:
        results = [pool.apply_async(process, args=(i,)) for i in range(4)]
        for result in results:
            result.wait()

    logger.warning("finish!")

    listener.stop()


if __name__ == "__main__":
    main()
```

## 仕組み

メインのlogger（`multiprocessing.get_logger()`）に`QueueHandler`を設定してログの出力先をqueueにし、`QueueListener`を使ってqueueのログを標準出力に流している。
お絵かきできるSNSを作りたい！10

お絵かきできるSNSを作りたい後半戦、１つ前に戻すを作っていきます。

筆跡が分るようにjsonで座標を逐一保存しようかとも考えたのですが、管理が大変そうだったので１ストローク毎にcanvasの中身をスクリーンショットを撮る感じにしました。

まず、対処のボタンにイベントを追加します。

```html:
<a href="#" class="btn" onclick="doPrevCanvas();">１つ前に戻す</a>
```

ローカルストレージを用意し、レイヤー1とレイヤー2をそれぞれ１ストローク毎に保存していきます。

```javascript:
// ストレージの初期化
var myStorage = localStorage;

function initLocalStorage(){
	myStorage.setItem("__layer", JSON.stringify([]));
	myStorage.setItem("__layer2", JSON.stringify([]));
}

function setLocalStoreage(){
	var png = $("#canvas")[0].toDataURL();
	var logs = JSON.parse(myStorage.getItem("__layer"));
	setTimeout(function(){
		logs.unshift({png});
		myStorage.setItem("__layer", JSON.stringify(logs));
	}, 0);
	var png2 = $("#canvas2")[0].toDataURL();
	var logs2 = JSON.parse(myStorage.getItem("__layer2"));
	setTimeout(function(){
		logs2.unshift({png2});
		myStorage.setItem("__layer2", JSON.stringify(logs2));
	}, 0);
}

function doPrevCanvas(){
	var logs = JSON.parse(myStorage.getItem("__layer"));
	if(logs.length > 0){
		logs.shift();
		setTimeout(function(){
			myStorage.setItem("__layer", JSON.stringify(logs));
			ct.clearRect(0, 0, $("#canvas").width(), $("#canvas").height());
			if (logs.length == 0) {
				draw("canvas",logs["png"]);
			} else {
				draw("canvas",logs[0]["png"]);
			}
		}, 0);
	}
	var logs2 = JSON.parse(myStorage.getItem("__layer2"));
	if(logs2.length > 0){
		logs2.shift();
		setTimeout(function(){
			myStorage.setItem("__layer2", JSON.stringify(logs2));
			ct2.clearRect(0, 0, $("#canvas2").width(), $("#canvas2").height());
			if (logs2.length == 0) {
				draw("canvas2",logs2["png2"]);
			} else {
				draw("canvas2",logs2[0]["png2"]);
			}
		}, 0);
	}
}

function draw(target,src) {
	var img = new Image();
	img.src = src;
	img.onload = function() {
		if (target == "canvas"){
			ct.drawImage(img, 0, 0);
		} else {
			ct2.drawImage(img, 0, 0);
		}
	}
}
```

あとは初期化の中でローカルストレージの用意し、線の書き終わりにレイヤー１と２の情報を保存します。

次回は小技（ショートカットの実装）を予定しています。
また気が向いたときにお会いしましょう。

次：[お絵かきできるSNSを作りたい！11](https://qiita.com/cardcapt/items/9e3f8093677985821892)
最初：[お絵かきできるSNSを作りたい！](https://qiita.com/cardcapt/items/d15fedf80d336f6b4bb9)
ウィンドウを半透明化できる「Afloat」をmacOS Catalina、macOS Mojaveでも使えるようにする

## はじめに
Afloatとは、指定したウィンドウを透過させることができるMacのプラグインです。
また、最前面にウィンドウを固定する機能もあるため、
デザインデータと半透明にしたブラウザと重ね合わせてスタイルを調整することができます。

macOSのアップグレードにより、macOS Sierra辺りから使えなくなったと思っていたのですが、
AfloatXという後継が出たと知り試したところ普通にAfloatも使えるようになっていました。

初めてAfloatを知ったという方も、これを機に是非お試しください。

ピクセルパーフェクトが求められる利用シーンでは精度、作業効率ともに今までの比ではないかと思います。

自分の場合は最初マージンなど目視でざっくりコーディングし、微調整はAfloatを使って丁寧に仕上げるようにしています。
これをすることでデザイナーさんからの細かい戻しも少なく済み、コーディングの作業効率はもちろんプロジェクト全体の進行もスムーズになります。

![nogi_cap_02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69826/eeb6227e-249b-bb9e-0604-0466450bdb90.gif)

## Macのプラグインマネージャーをインストール
Macのプラグインマネージャー「[MacForge](https://www.macenhance.com/macforge)」を下記からダウンロードし、アプリをインストールします。
Afloatを使えるようにする設定が必要なため、アプリは一旦インストールだけ済ませておきます。

1. [MacForge](https://www.macenhance.com/macforge)からアプリをダウンロード
2. 解凍したらアプリケーションフォルダに移動（任意）

## Afloatを使えるようにする設定①
MacForgeのREADMEに`Loading plugins into some applications may require Library Validation is disabled` と書かれており、
ライブラリの検証を無効にする必要があるようです。
ターミナルで下記のコマンドを実行します。

```
sudo defaults write /Library/Preferences/com.apple.security.libraryvalidation.plist DisableLibraryValidation -bool true
```

## Afloatを使えるようにする設定②

1.　PCを再起動し、アップルマークが出る前に`Command+R`を長押し。アップルマークが出たら離す
macOS 復元システム画面が表示されるので、メニューバー「ユーティリティー」からターミナルを立ち上げ、下記を実行。

```
csrutil enable --without fs --without nvram --without debug
```

2.　PCを再起動しMacForgeを立ち上げ、左上の検索から「Afloat」と検索。
3.　`Afloat`と`AfloatX`が出てくるので、`Afloat`のGETボタンをクリック。
4.　左メニューのManageにAfloatが追加され、チェックが付いている事を確認。

※AfloatXは後継のようですが、ショートカットが無いのでAfloatのほうが使い勝手が良さそうです。

## 動作の確認

半透明にしたいアプリを立ち上げ、
`Command + Control + マウスホイール上下（タッチパッドの場合は２本指で上下）`で透過できれば成功です。

Chromeの場合メニューバーのウィンドウに「Keep Afloat」などの下記の項目が表示されていれば正常にインストールされています。

<img width="746" alt="スクリーンショット 2020-07-04 17.47.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69826/89bcc6ca-d72c-d85b-b748-b118d10e56c6.png">

## 便利なショートカット

**常に最前面に固定＆解除**
`Command + Control + A`

**透明度の変更**
`Command + Control + マウスホイール上下（タッチパッドの場合２本指で上下）`
`Command + Control + 0 or 1`

### アプリが急に落ちる時の対処法
MacForgeを起動した状態でアプリを立ち上げると、
アプリが落ちてしまう時があるようです。
Afloatの動作確認ができたらMacForgeは終了しておくと良さそうです。
※MacForgeを終了してもAfloatは機能します。

## Afloatを無効にするには
Manegeからチェックを外してもAfloatが有効になったまま動作してしまいます。
立ち上げていたアプリのウィンドウを終了すれば次回以降Afloatは無効になります。
【競技プログラミング】重心分解を25行で書く方法

#はじめに
重心分解は25行程度でかけます
(わかりやすい様にコメント付加してたら30行程度になってしまいました)
ポイントは重心分解によって出来る木をBFSでなくDFSで潜ることです！！！

```cpp:Centroid_Decomposition.cpp
constexpr int MAX_SZ=1<<20;
array<vector<int>,MAX_SZ>g;//元の木の隣接リスト
array<int,MAX_SZ>used;//重心が確定したか
vector<int>v;//重心分解後の木のDFS順の列
array<vector<int>,MAX_SZ>ch;//重心分解後の木の親子関係
int s;//重心分解後の木の根
int dfs(int n,int p,int sz,int root){
    constexpr int inf=MAX_SZ*2;
    if(used[n])return 0;
    bool b=1;
    int res=1;
    for(auto e:g[n]){
        if(p==e)continue;
        auto t=dfs(e,n,sz,root);
        res+=t;
        if(t>sz/2)b=0;
    }
    if(!b||sz-res>sz/2)return res;//重心で無いなら部分木のサイズを返す

    //重心を登録
    if(root!=-1)ch[root].emplace_back(n);
    else s=n;
    v.push_back(n);
    used[n]=1;

    //重心分解後の木で自身の子となる重心を探す
    //dfs(e,n,inf,n)では部分木のサイズを求めてる
    //(szをinfにすると当然重心が見つからないため部分木のサイズが返る)
    for(auto e:g[n])dfs(e,n,dfs(e,n,inf,n),n);
    
    //重心はすでに見つかったためinf=MAX_SZ*2を返す
    return inf;
}
```

# 使用方法

グラフを `g` に隣接リスト表示で初期化したのち `dfs(0,-1,(頂点サイズ),-1);` を呼び出します。
vには重心分解後の木をdfsした結果が入ります(なくてもいいかも)
chには、重心分解後の木における子供が入ります
sは重心分解後の木の根が入ります
dfsの挙動は見たままです。は?(質問がある方は[twitter](https://twitter.com/hotmanww)まで)

# verify

[Ciel the Commander -codeforces](https://codeforces.com/problemset/problem/321/C)
[回答例](https://wandbox.org/permlink/GXdoKD4JbIB5pPSb)
VMwareのUbuntu仮想マシンでWebcam (USBカメラ)が使えない時の対応

ある日突然VMwareの仮想マシン(Ubuntu)でWebカメラが使えなくなってしまい、その対応で難儀したので、備忘として書いておく。
「VM」→「設定」で仮想マシンの設定の中のUSBコントローラを変えてみる。
今回はUSB2.0から3.1に変えたら、使えるようになった。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/1c1ea7d5-d038-ab45-33a8-507e45a4ce7a.png)

Windowsの仮想マシンは普通に使えるので、OSが原因かと思ったらVMwareだった(^^);
同じような悩みがあった人はたくさんいるようだ。

【参考リンク】
[Webcam not working on Ubuntu 16.04 with vmware](https://askubuntu.com/questions/864399/webcam-not-working-on-ubuntu-16-04-with-vmware)
【Vue.js 】 単一ファイルコンポーネント

# はじめに
開発規模が大きければ大きいほど、ソースコードも煩雑になっていく。そのため、機能ごとにファイルを切り分け、```モジュール化```することで保守性や再利用性を高めていく。

モジュール・・・機能ごとにクラスや関数を１つのファイルにまとめたもの

## 単一ファイルコンポーネントとは
単一ファイルコンポーネントとは、Vue独自のフォーマットでコンポーネントの定義方法の１つ。アプリケーションのコンポーネント構築に特化したモジュール管理を行うことができる。
Vueのコンポーネント（モジュール）を単独のファイル（拡張子が```.vue```となる）として作成する機能。この単一ファイルコンポーネントは```<template>``` ```<script>``` ```<style>```の3つのブロックで構成される。

```component.vue
<template>
<!-- テンプレートブロック -->
</template>
<script>
// scriptブロック
</script>
<style>
// styleブロック
</style>
```
## ビルド
単一ファイルコンポーネントはVue独自のものなので、そのままブラウザに反映させても動作しない。ブラウザが解釈できるようにファイルを```ビルド（変換）```してあげる必要がある。
```Vue CLI```を利用することで、単一ファイルコンポーネントを使用するためのビルド環境を楽に構築することができる。
※Vue CLIを使用するにはNode.jsのダウンロードが必要になる。

→ [Vue CLI 公式ドキュメント](https://cli.vuejs.org/)
→ [Node.js 公式サイト](https://nodejs.org/ja/)


### template

templateタグ内にはHTMLでテンプレートを記述していく。
```ルート要素が１つ```になるように記述していく。

```sample.vue
<template>
  <div>
    <h1>タイトル</h1>
    <p>テキストテキストテキスト</p>
  </div>
</template>
```

### script
scriptタグ内にはjavascriptを記述していく。（設定次第でtypescriptも使用可能）
Vueのtemplateオプション以外のオプションオブジェクトをここに記述することができる。
コンポーネントを必要な場所で```import```（読み込み）できるように```export```しておく。

→ [importとexportについてはこちら](http://...)


```sample.vue
<script>
export default {
// オプションオブジェクトを記述
}
</script>
```

### style
styleタグ内にはコンポーネントのCSSを記述していく。（設定次第でsassなどのスタイル言語も使用可能）
スタイルにスコープをつけて記述することもできる。
→ [スコープ付きCSSについてはこちら](https://qiita.com/smkhkc/items/c031caaa83d5a9105c6c)

```sample.vue
<style>
// ここにCSSを記述していく
</style>
```
Anaconda Promptを使わずにPythonコマンドを実行する場合のエラー

#はじめに

掲題のエラーについて対応した時のチップス。

# 環境
- Windows10
- Anaconda
- Python3.7

#現象
Anaconda でconda activate 等をせずにDOSプロンプト上で直接 Anacondaの仮想環境のptyhonを実行した場合に以下のエラーが発生した。

```error
During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "common/utils/create_project_schema.py", line 5, in <module>
    import numpy as np
  File "c:\ProgramData\Anaconda3\envs\hogehoge\lib\site-packages\numpy\__init__.py", line 142, in <module>
    from . import core
  File "c:\ProgramData\Anaconda3\envs\hogehoge\lib\site-packages\numpy\core\__init__.py", line 50, in <module>
    raise ImportError(msg)
ImportError:

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.

We have compiled some common reasons and troubleshooting tips at:

    https://numpy.org/devdocs/user/troubleshooting-importerror.html

Please note and check the following:

  * The Python version is: Python3.7 from "c:\ProgramData\Anaconda3\envs\hogehoge\python.exe"
  * The NumPy version is: "1.18.5"

and make sure that they are the versions you expect.
Please carefully study the documentation linked above for further help.

Original error was: DLL load failed: 指定されたモジュールが見つかりません。
```

# 原因と対応
AnacondaプロンプトとMS DOSプロンプトの環境変数PATHの違いをよーくみてみると原因は、以下パスの不足だった。

```
C:\ProgramData\Anaconda3\envs\<仮想環境名>\Library\bin
```

上をシステム環境変数に設定することで解決。Python3.6では発生しなかったり、Anacondaのインストールの仕方によって変わってくる可能性はあるが、ご参考まで。
TeXWorksのコンパイルについて

コンパイルしたいtexファイルがある場所にて，コマンドプロンプトで
　ptex2pdf –l コンパイルしたいファイル.tex
としてコンパイルできるか確認したが、コンパイルできず下記のようなエラーコードがでた。

> 「This is ptex2pdf[.lua] version 20200307.0.
> Processing report_format.tex
> Invalid PATH setting found. Please ensure that cmd.exe can be found.
>
> ptex2pdf processing of report_format.tex failed.」

なにがいけないのかわからないので、一から教えていただきたいです。よろしくお願いします。
Homebrew をインストールしたはずなのにbash: brew: command not foundになる。


###環境
aws: cloud9
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
Rails 6.0.2.1

##install時のwarning
install時にWarning: /home/linuxbrew/.linuxbrew/bin is not in your PATH.)パスがないと怒られました。
brewコマンドを叩いてみても、 「-bash: brew: コマンドが見つかりません」となります。

```
loning into '/home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-core'...
remote: Enumerating objects: 387, done.
remote: Counting objects: 100% (387/387), done.
remote: Compressing objects: 100% (210/210), done.
remote: Total 895969 (delta 244), reused 283 (delta 177), pack-reused 895582
Receiving objects: 100% (895969/895969), 323.15 MiB | 25.72 MiB/s, done.
Resolving deltas: 100% (614005/614005), done.
Tapped 2 commands and 5124 formulae (5,397 files, 356.7MB).
Already up-to-date.
Warning: /home/linuxbrew/.linuxbrew/bin is not in your PATH.======問題の部分=====
==> Installation successful!

==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics
No analytics data has been sent yet (or will be during this `install` run).

==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations

==> Next steps:
- Run `brew help` to get started
- Further documentation: 
    https://docs.brew.sh
- Install the Homebrew dependencies if you have sudo access:
  Debian, Ubuntu, etc.
    sudo apt-get install build-essential
  Fedora, Red Hat, CentOS, etc.
    sudo yum groupinstall 'Development Tools'
  See https://docs.brew.sh/linux for more information.
- Configure Homebrew in your /home/ec2-user/.bash_profile by running
    echo 'eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)' >> /home/ec2-user/.bash_profile
- Add Homebrew to your PATH
    eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
- We recommend that you install GCC by running:
    brew install gcc

```

そこで下記のコマンドを実行することで使えるようになります。

```
echo 'export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH"' >>  ~/.bashrc
source ~/.bashrc
```
Sapper ( Svelte ) の Lint / Prettier の設定を 📝

## はじめに

Sapper プロジェクト作るたびに Lint の設定に時間を取られるのでメモしておきます。
（個人的なメモレベルなので変なところあったら教えてもらえると助かります！）

## ESLint

### Install

```terminal
$ npm install \
  eslint \
  eslint-plugin-import \
  eslint-plugin-node \
  eslint-plugin-promise \
  eslint-plugin-standard \
  eslint-plugin-svelte3 \
  --save-dev
```

### Settings

- `.eslintrc.js`
- `.eslintignore`

```javascript:.eslintrc.js
module.exports = {
  parserOptions: {
    ecmaVersion: 2019,
    sourceType: 'module'
  },
  env: {
    es6: true,
    browser: true,
    node: true
  },
  extends: [
    'eslint:recommended'
  ],
  plugins: [
    'svelte3'
  ],
  ignorePatterns: [
    'public/build/'
  ],
  overrides: [
    {
      files: ['**/*.svelte'],
      processor: 'svelte3/svelte3'
    }
  ],
  rules: {
    'no-var': 'error'
  },
  settings: {
    // Nothing
  }
}
```

```text:.eslintignore
/node_modules/
/__sapper__/
/src/node_modules/@sapper/
/cypress/
```

### Usage

- `package.json`

```json:package.json
"scripts": {
  "lint": "eslint . --ext .js,.svelte --fix",
},
```

```terminal
$ npm run lint
```

## Prettier

### Install

```terminal
$ npm i --save-dev prettier-plugin-svelte prettier
```

### Settings

- `.prettierrc`

```text:.prettierrc
{
  "svelteSortOrder" : "styles-scripts-markup",
  "svelteStrictMode": true,
  "svelteBracketNewLine": true,
  "svelteAllowShorthand": false,

  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 120,
  "tabWidth": 2
}
```

### Usage

- `package.json`

```json:package.json
"scripts": {
  "format": "prettier --write --svelte-sort-order scripts-markup-styles ./**/*.svelte",
},
```

```terminal
$ npm run format
```



## まとめ

Svelte や Sapper めっちゃ早くて快適だからもっと流行ってほしいものです。
あと、 Lint まわりは公式で入ってほしいななんて……。
Pythonのprint関数で文字を表のように出力する方法

#Pythonのprint関数で文字を表のように出力する方法


##はじめに

問題集などでよく見る(N M)と数字が与えられて、
出力結果をN行×M列の何らかの文字列で求められる際の解法。

例）星取表、九九の掛け算表など


##求めるもの
```
& + + + +
+ & + + +
+ + & + +
+ + + & +
+ + + + &

```


##入力
```
N M
```


##コードと解説
```
import numpy as np

#(N M)= (5 5)の形で入力があると仮定する
n, m = input().split()
n, m = int(n), int(m)

#N行M列の二次元配列を作成する(今回は全て0の配列とした)
hyou = np.zeros((n,m))

#星取表などで表示する文字列が複数ある場合は、「その部分の配列の数字」を1,2,3...と場合分けして入れ替えていく
#今回は行と列の数字が同じ際に1を入れるだけのシンプルなやつ

for i in range(n):
   
    for j in range(m):
        
        if i == j:
            hyou[i][j] = 1


#行の終わりの要素示す数値(二次元配列の列の最後の要素の添え字)
x =  m -1
             
for i in range(n):
 
#出力する行が終わりかどうかはj＝＝xかどうかで判定する
#終わりでない場合はend=" "で空白スペース出力、終わりの場合はprint関数そのままで改行する
#数字ごとに出力する文字を替えていく
   
    for j in range(m):
        
        if hyou[i][j] == 0 and j != x:
            print("+", end = " ")
        
        elif hyou[i][j] == 1 and j != x:
            print("&", end = " ")
            
        if hyou[i][j] == 0 and j == x:
            print("+")
        
        elif hyou[i][j] == 1 and j == x:
            print("&" )           
```

##最後に

単純だけど意外と忘れがちな気がしたのでメモっておきます
'%02d' % 2 のパーセントとは？

# '%02d' % 2 

ruby で 数字の 2 を '02' と記述したい時、`'%02d' % 2` のような構文を書きますよね。
引数に対して 0埋めをおこなってstringで返すという方法ですが、こちらの % とか 02 とか d って一体なんなんでしょうか？

## % って何？
ruby では % という記法に様々な意味があります。

1. 剰余を表す「%」 `例: 5 % 3 => 2`
2. Stringクラスの「%」演算子 `例: "%02d" % 2 => "02"`
3. リテラル記法の「%」演算子 `例: %w(dog cat monkey) => ["dog", "cat", "monkey"]`
4. コマンドラインへの入力を示す `例: %x[ DATE ] => "2020年 6月24日 水曜日 09時31分57秒 JST\n"`

上記のような種類があります。
参考: [Rubyで使われる記号の意味（正規表現の複雑な記号は除く）](https://docs.ruby-lang.org/ja/latest/doc/symref.html#per)

先に示した、`'%02d' % 2` という構文は、上記の例でいうと `2. Stringクラスの「%」演算子` にあたりますね！

## 02 とか d って一体なんなんでしょうか？

d は引数の型を示す**「指示子」**の中の一つです。
d は 10進数の整数 (Decimal number) を表しています。
指示子は他にも、文字列を表すものや浮動小数点を表すもの、指数表現を表すものなどがあります。

02 は 0 と 2 に分解することができ、それぞれ**「フラグ」**と**「幅」**を示しています。
**「フラグ」**にもいくつか種類があるのですが、 0 は余白を 0で埋めるという意味になります。
**「幅」**はそのまま、出力時の長さを指定します。

これらをまとめると、`'%02d' % 2` という記法は、

`'%0(余白は0で埋めてくださいね〜)2(出力時の長さは2ですよ)d(引数を10進数の整数で表してくださいね' %(Stringクラスの%演算子ですよ〜) 2(引数は2ですよ！)`

という意味が込められている事になります。

## おわりに

引数は配列で渡す事もできますので、
**「10進数で表している色コードを16進数の色コードに変換したいよ」**という時には、
`'%02x%02x%02x' % [255, 255, 255] => "ffffff"` と書く事ができます！
Slack通知のメンション先をグループにしたらSlackから通知先をカスタマイズできて便利でした

## Slackのグループ機能ってご存知ですか？
僕は知りませんでした。

グループ機能は、たとえば `@engineer`とメンションすると 
エンジニアの`@Aさん`と`@Bさん`に通知が飛ぶような機能です。

[ユーザーグループを作成する | Slack](https://slack.com/intl/ja-jp/help/articles/212906697-%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)

## Slack通知のメンションをグループにしたら便利だった

弊社プロダクトでは、ユーザーの会員登録時に、Slackへ通知を送っています。
通知には個人宛のメンションをつけていて、頻繁に変更されるわけではないのでハードコーディングしてました。
リリースサイクルも早いので、この運用でも問題ないのですが、将来的にこれを続けるのは面倒です。

そこで、グループにメンションするようにしました。

そうすれば、通知先をSlackのグループ設定からカスタマイズできます。

### メリット

- エンジニアじゃなくても通知先を変更できる
- 通知先をすぐに変えられる


## グループへのメンションのつけ方はちょっとムズカシイ

普通に`@engineer`ではできないので注意です。

以下のように書きます。

```
<!subteam^ID>
```
ID(user group id)はAPIから取得できました。
API実行にはアクセストークンを発行する必要があります。

https://api.slack.com/methods/usergroups.list


以下を参考に実装しました。


https://api.slack.com/reference/surfaces/formatting#mentioning-users

以上、参考になりましたら幸いです。
Docker toolbox on windows で Dドライブに移動する

# 記事を書いた経緯
普段から``Windows``を使っている人にとっては**何だよそれ**だったので．
そもそも``Linux``に慣れてないというのもあって，
``Linux``でのマウント方法をググったり，
``d:``とか``cd /d d:``とかやって勝手に苦戦していました．

# 結論
特別マウント作業などはいらず，これだけ．
**最初から割り当てられている**

```
$ cd /d
```

# 補足
下記のコマンドでなんのドライブが使えるか確認してください．
データ格納用のドライブが``Eドライブ``とかの人もいるので．
（自分は諸事情により``C:\Program Files``配下に``Docker-Toolbox``をインストールしていないので，皆さんと少し表示が違うと思います．）

```
$ mount
C:/Users/ユーザ名/AppData/Local/Temp on /tmp type ntfs (binary,noacl,posix=0,usertemp)
C:/Users/ユーザ名/AppData/Local/Programs/Git on / type ntfs (binary,noacl,auto)
C:/Users/ユーザ名/AppData/Local/Programs/Git/usr/bin on /bin type ntfs (binary,noacl,auto)
C: on /c type ntfs (binary,noacl,posix=0,user,noumount,auto)
D: on /d type ntfs (binary,noacl,posix=0,user,noumount,auto)
```
JSで配列の検索と削除のメモ

よく使う機会あったので備忘メモ
配列のobjectでID一致したらそこを削除するメモ

###一致データを削除サンプル

``` ts
datas = [{id:1,content:"AAA"},{id:2,content:"BBB"},{id:3,content:"CCC"}];

deleteData (id) {
  const result = this.datas.findIndex(
    (item) => item.id === id
  );
  if (-1 < result) {
    this.datas.splice(result, 1);
  }
}
```

###参考サイト
ES6でよく使う、配列の中身を操作・検索する関数
https://qiita.com/pentla/items/a87383903a30d7baa282#findindex
JavaScript - 配列の要素を削除する
https://murashun.jp/blog/20191110-18.html#chapter-3
Nuxt.jsでページごとにレイアウトを変える設定方法

Nuxt.jsでは、ページごとにレイアウトを変えることが可能です。

- このページには、Footer無し
- LPページだけ違ったレイアウトにする

と言ったページごとにレイアウトを変える設定方法についてまとめました。

## レイアウトはlayoutsディレクトリでおこなう
Nuxt.jsのプロジェクトにはlayoutsディレクトリがあり、レイアウトの設定をおこなうことができます。
共通のレイアウトは`default.vue`、異なるレイアウトを適用したい場合は、新たにvueファイルを追加します。
今回はヘッダー無しのレイアウトをデモ的に作りたいので、`no-header.vue`ファイルを作成しました。

```
├─ layouts
│  ├─ default.vue
│  └─ no-header.vue

```

`default.vue`には、各ページに共通するヘッダーコンポーネントを読み込みます。

```vue:defaul.vue
<template>
  <div>
    <Header />
    <nuxt />
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Header from '@/components/Header.vue'

export default Vue.extend({
  components: {
    Header
  }
})
</script>

```
`no-header.vue`は、ヘッダーを表示させないので、ヘッダーコンポーネントは読み込まないようにします。

```vue:no-header.vue
<template>
  <div>
     <nuxt />
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({})
</script>

```

## ページごとに使いたいレイアウトを設定する

レイアウトを設定できたので、各ページで使いたいレイアウトを設定します。
特に設定しない場合は`default.vue`のレイアウトが適用されます。
今回は、ヘッダーを表示させたくないページに設定をします。

```vue
<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  layout: 'no-header'
})
</script>

```
layoutプロパティで適用させたいレイアウトを設定することで、`no-header.vue`のレイアウトが適用されます。

![nuxt_layout.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/d55cf9e1-2aa3-d452-00b7-e421322176a2.gif)

## 最後に
今回は、Nuxt.jsでページごとにレイアウトを変える設定についてまとめました。
LPページだけ違ったレイアウトにすることも容易なので、かなり便利です。
可変長引数をとるメソッドを作ってみる

# 可変長引数とは
関数に渡す引数の要素数が決まっておらず複数になり得る引数のこと
つまり可変長、１つかもしれないし、2つかもしれないし、3つかもしれない。

# 定義してみる
```scala
def variableLength(strings: String*): Unit = {
  strings.foreach(println)
}
```

引数の最後に`*`をつけることによって可変長引数を受け取れることができる。

実行してみる

```scala
variableLength("aaa") // "aaa"
variableLength("aaa", "bbb") // "aaa" "bbb"
```
このように要素数の異なる引数を受け付けて実行することができる。

# Seqはどうなるの
Seqは受け付けることができるのかということになるのだが、以下のようにすることによって可能になる。

```scala
val seq = Seq("aaa", "bbb")

variableLength(seq: _*) // "aaa" "bbb"
```
#まとめ
可変長引数について知見を得たので書いてみました。
未だ使用する場面に遭遇していませんが、どこかしらで使う場面が出た時が楽しみです。
typescriptの導入 + classについてのメモ

###TypeScriptのインストール
```
npm install typescript
```
###typescriptの実行
.tsファイルを.jsファイルにコンパイルし、作成された.jsファイルを実行する。

```
tsc ファイル名.ts
node ファイル名.js
```

###typescriptでclassの練習

```practice.ts

//クラスを作成
class Animal {

    //プロパティ  名前:型
    name: string;
    age: number;  //intではない

    //コンストラクタはインスタンスに引数を持たせる場合に必要    
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

}

//インスタンスを作成
var cat = new Animal("Cat", 7);
console.log(cat.name); //Cat
console.log(cat.age); //7


//コンストラクタは省略が可能
class Animal_no_constructor {

    name: string = "Dog";
    age: number = 3;

}

//コンストラクタを省略した場合は、インスタンスに値を持たせることが出来ない
var dog = new Animal_no_constructor();
//プロパティを出力
console.log(dog.name); //Dog
console.log(dog.age); //3


//メソッドの使い方
class Human {

    name: string;
    score: number;

    constructor(name: string, score: number) {
        this.name = name;
        this.score = score;
    }

    judge() {

        var message: string;

        if (this.score > 50) {
            message = this.name + "は合格";
        } else {
            message = this.name + "は不合格";
        }

        console.log(message);

    }

}

var takeshi = new Human("Takeshi", 100);
takeshi.judge(); //Takeshiは合格

var taro = new Human("Taro", 45);
taro.judge(); //Taroは不合格


//継承
class Oya {

    name: string;

    constructor(name: string) {
        this.name = name;
    }

    hello() {
        console.log("こんちわー");
    }

}

class Kodomo extends Oya {

    constructor(name: string) {
        //Oyaのthis.nameを受け継ぐ
        super(name);
        this.name = name;
    }
    
    say() {
        //親クラスOyaのhelloメソッド
        super.hello();
        console.log("あの" + this.name + "!?");
    }

}

var yoshida = new Kodomo("yoshida");
yoshida.say(); //こんちわー あのyoshida!?


//デフォルト引数
class Menu {

    item_number: number;

    constructor(item_number: number = 0) {
        this.item_number = item_number;
    }

    say_item_name() {
        var array = ["ラーメン", "うどん", "蕎麦"];
        console.log(array[this.item_number]);
    }

}

var soba = new Menu(2);
soba.say_item_name(); //蕎麦

var wasureta = new Menu();
wasureta.say_item_name(); //ラーメン(引数がないので自動で0に)

```
Alibaba Cloudのossutilの使い方まとめ

Alibaba CloudのObject Strage Service（OSS)（※注）ではossutilというクライアントアプリが利用できます．
そんなに頻繁にセットアップすることがなくて，使うときにいつも調べてるのでまとめることにしました

（※注）AWSでいうS3みたいなサービス

# ossutilのダウンロード

> クイックスタート - ユーティリティ| Alibaba Cloud ドキュメントセンター
> https://jp.alibabacloud.com/help/doc-detail/50452.htm

からローカルのプラットフォーム用のバイナリをダウンロードする

CentOS用だとこんな感じ

```(console)
$ wget "http://gosspublic.alicdn.com/ossutil/1.4.2/ossutil64?spm=a21mg.p38356.a3.3.67682cd7ojregb" -O ossutil64

実行権限与えた後にパス通るディレクトリに移動しておく

$ chmod +x ossutil64
$ mv ossutil64 /usr/local/bin
```

# ossutilを利用するユーザーの作成とアクセスキーとシークレットキーの生成
 
Alibaba CloudのWebコンソールから，Resource Access Management（RAM）サービスにアクセスして，既存ユーザまたは新規ユーザに対してAccessKeyの発行を行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310137/5aabf386-eebd-caf1-873a-05f0157b6959.png)

※新規ユーザーを作成する場合「プログラムによるアクセス」にチェックを入れてユーザーを作ると，アクセスキーが予め作成された状態でユーザーが作成されるようです．

ユーザーを作成したらOSSへのアクセスについて権限付与してください．

# ossutilにアクセスキーとシークレットキーの設定を行う

ここではCentOS向けのossutil64について設定方法を記載します．
あらかじめアクセスする対象のバケットがあるリージョンのエンドポイントURLとアクセスキー，およびシークレットキーを調べておきます．

```(console)
$ ossutil config
(中略)
Please enter language(CH/EN, default is:EN, the configuration will go into effect after the command successfully executed):EN
Please enter accessKeyID:（アクセスキー）
Please enter accessKeySecret:（シークレットキー）
Please enter stsToken:（空欄のままEnter）
Please enter endpoint:ap-northeast-1（東京リージョンの場合）
```

これにより，設定ファイルが~/.ossutilconfigに保存されます

下記のようにアクセスする対象のバケットがあるリージョンのエンドポイントURLとアクセスキー，およびシークレットキーを設定することもできます

```(console)
$ ossutil64 config -e (バケットのエンドポイント)　-i （アクセスキー） -k （シークレットキー）
```



# ローカルからファイルのアップロードを行う

ローカルのhoge.txt をtestbucket/text/hoge.txtにアップロードします

```(console)
$ ossutil64 cp hoge.txt oss://testbucket/text/hoge.txt
```

ディレクトリをアップロードする場合には，--recursiveオプションを追加します

```(console)
$ ossutil64 cp hoge/ oss://testbucket/ --recursive
```

# バケット内のファイル一覧を取得する

```(console)
$ ossutil64 ls oss://testbucket
```
Macのdocker上に構築したmysqlに、ホストマシンからlocalhost:3306でつながらないよ！

###docker上にmysqlイメージをデフォルト(localhost:3306)で構築したのに、ホストマシンのコンソールからつながらないよ！ぴえん！ってなっている人はホスト名を127.0.0.1で試してみてください。

```Docker:Dockerfile
FROM mysql:8.0

ENV TZ=UTC \
  MYSQL_DATABASE=laravel_local \
  MYSQL_USER=phper \
  MYSQL_PASSWORD=secret \
  MYSQL_ROOT_PASSWORD=secret

COPY ./my.cnf /etc/my.cnf
```

`$ mysql -u phper -psecret`
> ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

こんな風に、何もしてないのにつながらないの！なんで！
それは、 **-h オプションを省略しているから**です。

### つながるよ
```console

$ mysql -u phper -psecret -h 127.0.0.1
mysql> 

```
### つながらないよ
```console

$ mysql -u phper -psecret
> ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)


```

-h オプションを抜くと、デフォルトでmysql clientはlocalhost:3306を見に行きます。
dockerの127.0.0.1とlocalhostは異なる扱いなので気をつけてね！
NEUTRINO用簡単バッチファイル(RunNeuY9.bat)

--------------------------------------------------------------------------------
2020/09/15 version 1.6 / 2020/09/04 version 1.5

RunNeuY9
Download
https://drive.google.com/file/d/1tVEDQtYPqWVLDNkmhANm6iRDombz-IZs/view?usp=sharing
https://mega.nz/file/kXR3nIDT#UBTLtfBylkuewTTQEc0qC6Ci8BchJi9ocMJKQ5X28OM

#概要
NEUTORINOに入ってる Run.bat を使いやすく変更したものです。
Run.bat の中に書き込みしなくても、ファイルを指定したり、声を変えたりフォルマントを変えたり出来ます。

#インストール
Run.bat のあるフォルダにコピーしてください。

#使い方
RunNeuY9.bat をダブルクリックで起動して下さい。musicxml に関連付けても動作すると思います（多分）。
初回起動後は、musicxml をRunNeuY9 の画面にドラッグして下さい。これがこのツールのファイル指定方法です。
あとは、２を押せばwavファイル作成し、再生されます。再生するのは syn.wav の方です。
wavファイルは、NEUTRINOのフォルダと、musicxmlのフォルダ両方に作成されます。
一応、syn.wavだけ、nsf.wavだけ作成も出来るようになっています。
ファイル名には、ある程度設定、例えばピッチシフト1.0なら「ps1.0」が含まれます。どういう設定で作成されたファイルか確認しやすいです。また、設定が異なるなら、このツールを複数起動して同時にwavファイル作成させることも出来ました（出来ない時もあるっぽい）。

メニューから声やフォルマントを変更出来ます。変更後の設定はファイルに保存・読み込み出来ます。
終了時に現在の設定を自動保存し、次回その設定を自動読み込みします。

※nsf.wavはなぜか私の環境だとエラーになって作成されません…

#バグ・要望・感想など
どこに書いてもらってもOKです。
Twiter @4mota ( https://twitter.com/4mota ) / E-mail yomox9@gmail.com / 創作物発表ブログ https://draft.blogger.com/blog/posts/767170535128297111?hl=ja&tab=jj

#履歴
2020/09/04 : ver1.5
2020/09/14 : ver1.6 fix Fix Dont load option file when start

#クレジット
RunNeuY9 2020 yomox9 CC BY 4.0
---------------------------------------------------------------------


#以下は古いバージョン
#初版


RunNeuY9.bat https://mega.nz/file/QSwC0aTD#EWJXGnKAcab6EO9rJ3c_5OKqbZIoX9sQQBazv1R4wjw

#概要：
NEUTRINO の Run.bat を使いやすくしました。
声、ピッチ、フォルマント、スレッド数をメニューから変えられます。

#インストール方法：
NEUTRINO のインストールフォルダ ( Run.bat がある ) にコピー。

#使用方法：
・ダブルクリックで起動（メニューで読み込む musicxml ファイルを指定出来ます）
・musicxml をドラッグする
・musicxml ファイルに関連付けして musicxml ファイルをダブルクリック
・送るにショートカットを作成しても、動くかも。。。。

#クレジット：
RunNeuY9.bat 2020 First publish. 2020 yomox9 some rights reserved. CC BY 4.0
jsonのPHP、JSでのエンコードとか

## php
fetchall(PDO::FETCH_ASSOC) —  結果セットに 返された際のカラム名で添字を付けた**配列**を返す。
json_decode  — JSON形式の文字列を**オブジェクトもしくは連想配列に変換**する
json_encode — 値をJSON形式にして返す


## JSON
JSON.parse — JSON形式で書かれた文字列をJavaScriptの**JSONオブジェクトに変換**する
JSON.stringfy — JSONオブジェクトを**文字列に変換**する
wordpress学習(2020/06/26)

###Akismet
Akismetはスパムコメントを自動的に専用のスパムフォルダへ振り分けてくれるプラグイン。
標準でインストールされている。
Akismetを有効化し、アカウント設定を行う。
PERSONAL　Name Your Priceをクリックしたあと、右側の金額のバーを0円になるまで左にスライド。
そのあと、メールアドレスと名前とwordpressのURLを入力して3つのチェックを入れてcontinueをクリック。
入力したメールアドレスに数字コードが届くのでそれを入力して完了すると、次にAPIキーが届く。
wordpress管理画面にもどり、Akismetの設定のManually enter an API keyからAPIキーを入力kismetはスパムコメントを自動的に専用のスパムフォルダへ振り分けてくれるプラグイン。
標準でインストールされている。
Akismetを有効化し、アカウント設定を行う。
PERSONAL　Name Your Priceをクリックしたあと、右側の金額のバーを0円になるまで左にスライド。
そのあと、メールアドレスと名前とwordpressのURLを入力して3つのチェックを入れてcontinueをクリック。
入力したメールアドレスに数字コードが届くのでそれを入力して完了すると、次にAPIキーが届く。
wordpress管理画面にもどり、Akismetの設定のManually enter an API keyからAPIキーを入力して完了。

###コンタクトフォーム
コンタクトフォームを固定ページで作成。
文書のページ属性のテンプレートでお問い合わせTPLを使うと簡単にコンタクトフォームができる。
URLスラッグをcontactに。

###サイドバーのプロフィール欄
固定ページで画像とテキストでプロフィールを作成する。
そのあと全体をHTML表示してからコピー。
外観のウィジェットを開き、サイドバーにカスタムHTMLを追加。
カスタムHTMLのタイトルを入力し、内容にコピーしたHTMLを張り付けて完成。

###蛍光マーカー
gutenbergで蛍光マーカーを引く場合、ブロックの追加でフォーマットのクラシックを使うとクラシックエディタで蛍光マーカーを引くことができる。
今回この方法ではエディタが上手く機能しなかったのでプラグインを追加。
プラグインのMarker-Animationを使うことで太字にする欄と同じ場所に蛍光マーカーのアイコンが追加される。
アニメーションもつけることができる。

###文字サイズ
文字サイズは大きさを変更したいブロックやテキストを選択して右のブロックのテキスト設定で変更できる。

###引用
引用した部分には引用タグを使う。

###表
+のブロックの追加からフォーマットの表を追加できる。

###post type switcher
固定ページか投稿かの投稿タイプを変更できるようになるプラグイン。

###CSSの追加
カスタマイズのCSSの追加からCSSを書くことで新しいCSSを使うことができる。

###SEOで必須ページ
固定ページでSEOで必須のプロフィール、コンタクトフォーム、プライバシーポリシーがある。

###SEO記事投稿
添付する画像にはすべてタイトルと代替テキストの入力する。
Linux(ubuntu)を知らない人がWindows上でLinuxコマンドを実行する方法【Rとpythonの動作確認まで】


#この記事の目的

- Windowsユーザー向けだよ(Win10):smile:
- Linux(ubuntu)とかわからなくても大丈夫だよ:smile:
- とりあえず動かせるところまで紹介するよ:smile:



#記事を書くまでの経緯

新しいライブラリが出た時にgithub見に行ったらチュートリアルに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/611aeaba-109f-1c94-2f79-e1f7dedf6312.png)
画像元：[StarGAN-Voice-Conversion](https://github.com/liusongxiang/StarGAN-Voice-Conversion)

**sudo**,**~.sh**,**wget**
とかlinux系のコマンドが出てきて今までは
**「Linux環境:innocent:...VirtualBoxたてるか:innocent:...でも重いから嫌い:innocent:...ぐぬぬ:innocent:...」**
ってなってたんですが、
windowsでも簡単に試したいと思って調べてたら、
windowsでもubuntuが動かせるみたいなので紹介。

#step-1 Windows Subsystem for Linux(WSL)の有効化

win10では標準の機能としてLinux環境をwindows上で実行することができます。
使ってみた感じHyper-VやVirtualBoxよりも使いやすいので使いやすさを味わってみてほしい:relaxed:

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/71b587ce-76e2-f24a-6468-4663c05d617d.png)

![02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/cf9dfb3e-a8e6-e0f0-adfb-8461805a54ad.png)

※Windows Subsystem for Linuxにチェックを付ける



#step-2 Ubuntuをダウンロード

今回は18.04LTSを使いますが、各自のやりたいことによって選んでください。
2020/06/26時点では20.04までダウンロードできる。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/7cf92942-2f16-1131-1e14-3b4a3b6250eb.png)


![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/9b0cc365-bc2b-325d-1042-a8ed67eb07cb.png)

インストールした後起動し、IDとpassを設定
passはデフォルトでは表示もされなければ、打ち込んでも*記号が出てきたりもしないので打ち間違いのないように。


#step-3 Ubuntuコマンドを打ち込む(アップデートとRの追加)


バージョン確認

```sh
cat /etc/lsb-release
```

![05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e4e8b777-b5c2-fe80-f00b-939cb04129c1.png)

アップデート

```sh
sudo apt update
```

Rのダウンロード先を追加


```sh
echo 'deb https://cran.rstudio.com/bin/linux/ubuntu bionic-cran35/' | sudo tee -a /etc/apt/sources.list
```

エディタで追加されていることの確認


```sh

sudo nano /etc/apt/sources.list
```


![06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/009efe55-b508-af73-25e8-2c048403ab77.png)

「Ctrl + X」でnanoを抜ける

key追加

```sh
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
```

コマンドに問題なければ

```
gpg: Total number processed: 1
gpg:               imported: 1
```

が返ってくると思う


最後に


```sh
sudo apt install r-base
sudo apt update
```



#step-4 pythonとRが起動できるかだけ確認する

pythonはデフォルトのままでpython3と打ち込むと開く
Rもpythonも抜けるときは「Ctrl + Z」

![07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/79556ce2-bc95-2064-1523-3f05ba959deb.png)

RやPython側から「パッケージが入ってない」と言われたら上記のように起動した後
install.packagesなりpip installなりを実行する。


#以上

これで今後Linux環境が必要な時に試せる
やったぜ

#メモ：フォルダ移動が面倒な時

フォルダを移動するときに
cmdと同じく
cd ~~~~
で移ってもいいけど、使いたいフォルダのアドレスに「bash」と打ち込めばらくちん


![des.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/a48fca54-d50d-6a5d-481c-9407ac9d696d.gif)




#参考記事

[Windows Subsystem for Linux (WSL1) をインストールしてみよう！](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)
[【WSL入門】第1回　Windows 10標準Linux環境WSLを始めよう](https://www.atmarkit.co.jp/ait/articles/1903/18/news031.html)
[最新のRをUbuntuにインストール](https://qiita.com/JeJeNeNo/items/43fc95c4710c668e86a2)
Pipenvのlockingが遅すぎる

# tl;dr
`Pipfile.lock`が無限に終わらない人向け強行手段
また，依存関係を厳密に管理しなくても良いよという人が対象

# 環境変数の定義
```
$ export PIPENV_SKIP_LOCK=true
```
これを叩けば`Pipfile.lock`は生成されない．
毎回打つのはだるいので，`~/.bashrc`に書き込めばよし．

# おわり
完成！！初めてReact.jsでWebサイト作った！！

# とりあえず完成！
つまずいた点たくさんありました．．．
ハマったポイントを記事にしたのはまだ1つだけですが，今後作ってきます

一通り完成したので報告致します．＜－－急にかしこまる
https://shinnosuke7031.github.io/react-test/

意識したのは，ページ遷移しないで表示内容を変えること！

デザインはまだまだですが．．．

ぜひアドバイスとかいただけると幸いです