OmniAICreator/Qiita-1.07M huggingface dataset:
numpy の save と load で dict を扱う

## はじめに

numpy の配列を保存して読み込む．`numpy.save` と `numpy.load` 事が足りそうだ．

ここでは，dict型のデータを扱う．

### 目的

numpy でデータを保存する．データの作成条件等を dict型で保存したい．

## 実験
### 失敗するコード
動きそうだがうまくいかないコード

```
import numpy as np

a = {'A':1, 'B':2, 'c':3}
np.save('test.npy', a)
b = np.load('test.npy')
print(b['B'])
```
### エラー箇所

+ `np.load` で `ValueError`
+ `b['B']` で `IndexError`

### 配列`a`の確認

`a`は dict型

```
a, type(a)
# ({'A': 1, 'B': 2, 'c': 3}, dict)
```

### `allow_pickle` パラメータ
`numpy.save`と`numpy.load`では，必要であれば，Pythonのモジュールであるpickleを使用して配列情報を保存する．

|関数|省略|初期値|
|:--|:--|:--|
|`numpy.save`| 可 |`True` |
|`numpy.load`| 可 |`False`|

[numpy.load](https://numpy.org/devdocs/reference/generated/numpy.load.html) によると，version 1.16.3 に`allow_pickle = False`が標準になったらしい．

> allow_pickle: bool, optional<br>
> Changed in version 1.16.3: Made default False in response to CVE-2019-6446.

改良したコード

```
b = np.load('test.npy', allow_pickle=True)
```

### numpy オブジェクトと辞書

`b['B']`で'IndexError'
`b`は dict型っぽく見えるが，実は object 型．

```
b = np.load('test.npy', allow_pickle=True)
b
# array({'A': 1, 'B': 2, 'c': 3}, dtype=object)
```

改良コード.

[numpy.ndarray.item](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.item.html)
`item`を使って値を取り出す．

```
d = b.item()
d['B']
# 2
```

## まとめ

動作するコード

```
a = np.array({'A':1, 'B':2, 'c':3})
np.save('test.npy', a)
b = np.load('test.npy', allow_pickle=True)
d = b.item()
print(d['B'])
# 2
```

## 参考

+ [np.loadとnp.save関数でファイルの永続化方法](https://deepage.net/features/numpy-loadsave.html)
Vue CLIでプロジェクトを作成&起動する方法

# 概要

@vue/cliで新規にプロジェクトを作成し起動する方法を記載する。

# 手順

## プロジェクトの作成
コマンドプロンプトで以下のコマンドを入力する。

```
$ vue create [プロジェクト名]
例：vue create sample_project
```

その後、以下のようなpresetの選択肢が表示されるため選択する。
`Default`か`Manually select features(自分で細かく設定する)`かが選べるが今回は`Default`を選択

```
Vue CLI v4.5.12
? Please pick a preset: (Use arrow keys)
> Default ([Vue 2] babel, eslint)
  Default (Vue 3 Preview) ([Vue 3] babel, eslint)
  Manually select features
```

上記選択後、プロジェクトの作成が行われるのでしばらく待つと以下のような表示になる。
**これが表示されたらプロジェクトの作成は完了**

```
// 省略

success Saved lockfile.
Done in 9.48s.
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project sample_project.
👉  Get started with the following commands:

 $ cd sample_project
 $ yarn serve
```

## プロジェクトの起動
cdコマンドでプロジェクト配下に移動し、`yarn serve`でプロジェクトを起動する。

```
$ cd sample_project
$ yarn serve
```

その後、以下のような表示になったらプロジェクトの起動は成功

```
$ yarn serve
yarn run v1.22.0
$ vue-cli-service serve
 INFO  Starting development server...
98% after emitting CopyPlugin

 DONE  Compiled successfully in 2329ms                                                                                                                                      23:07:11


  App running at:
  - Local:   http://localhost:8080/
  - Network: http://192.168.0.9:8080/

  Note that the development build is not optimized.
  To create a production build, run yarn build.
```

## ページにアクセス
上記の`Local:`または`Network:`に表示されているURLをブラウザに入力してみると、以下のようなページが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598427/233718b9-5ce1-9230-80d0-b1c5535fbdd6.png)
華VBAフォルダサイズファイル数サブフォルダ数

Private Sub CommandButton1_Click()
    'Call getFolderSize
    'Call GetFileCount
    Dim subfolderscount As Integer
    
    subfolderscount = GetSubFolserCount("C:\Users\huawe\OneDrive\デスクトップ\週間作業報告書")
    If subfolderscount <> 0 Then
        GetFileCountSaiki
    End If
    
    
    
End Sub


'フォルダサイズ取得
Public Sub getFolderSize()
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    ''C:\Workフォルダ内の全ファイルの合計サイズを表示します
    MsgBox fso.GetFolder("C:\Drivers").Size / 1024 / 1024 / 1024
    Set fso = Nothing

End Sub

'ファイル数取得 :再帰あり
Public Sub GetFileCountSaiki()
   '--- 含まれるフォルダ数を知りたいフォルダのパス ---'
    Dim folderPath As String
    'folderPath = "C:\Drivers"
    folderPath = "C:\Users\huawe\OneDrive\デスクトップ\週間作業報告書"
    '--- サブフォルダパス一覧を格納する変数 ---'
    Dim subFolders() As String
    subFolders = GetFolderPath(folderPath)
    '--- ファイルシステムオブジェクト ---'
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    '--- ファイル数を格納する変数 ---'
    Dim n As Long
    n = fso.GetFolder(folderPath).Files.Count
    '--- サブフォルダ内のファイル数を加算 ---'
    Dim tmp As Variant
    For Each tmp In subFolders
        n = n + fso.GetFolder(tmp).Files.Count
    Next tmp
    MsgBox "ファイル数:" & n & "   " & "子フォルダ数：" & UBound(subFolders)
    
End Sub



'--- サブフォルダを再帰的に取得する関数 ---'
Public Function GetFolderPath(folderPath As String) As String()
    '--- ファイルシステムオブジェクト ---'
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    '--- フォルダ数を格納する変数 ---'
    Dim n As Variant
    n = fso.GetFolder(folderPath).subFolders.Count
    If (0 < n) Then
        '--- フォルダパスを格納する配列 ---'
        Dim str() As String
        ReDim str(1 To n)
        '--- フォルダパスを格納 ---'
        Dim i As Long
        Dim j As Long
        Dim m As Long
        i = 1
        Dim strTmp() As String
        'フォルダパスを指定してすべてのサブフォルダを取得
        Dim f As Object
        For Each f In fso.GetFolder(folderPath).subFolders
            str(i) = f.Path
            strTmp = GetFolderPath(str(i))  '再帰的呼び出し
            If (Not IsEmptyArray(strTmp)) Then
                m = UBound(strTmp, 1)
            Else
                m = 0
            End If
            'サブフォルダ内にさらにフォルダがあればその分だけ配列を拡張
            n = UBound(str, 1)
            ReDim Preserve str(1 To n + m)
            For j = 1 To m
                str(i + j) = strTmp(j)
            Next j
            i = i + m + 1
        Next f
    End If
    GetFolderPath = str
End Function

'サブフォルダ数
Public Function GetSubFolserCount(folderPath As String) As Integer
    '--- ファイルシステムオブジェクト ---'
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    '--- フォルダ数を格納する変数 ---'
    Dim n As Integer
    n = fso.GetFolder(folderPath).subFolders.Count
    GetSubFolserCount = n
    
End Function
    

'--- 配列が空かどうかを判定する関数 ---'
Public Function IsEmptyArray(arrayTmp As Variant) As Boolean
On Error GoTo ERROR_
    If (0 < UBound(arrayTmp, 1)) Then
        IsEmptyArray = False
    End If
    Exit Function
ERROR_:
    IsEmptyArray = True
End Function
2分ヒープの配列による実装でのノードindex

# 2分ヒープ
2分ヒープは2分木を利用したデータ構造の一つで、プライオリティキューを効率的に実現する。
2分ヒープでは2分木をポインタで表現するのではなく、2分木のノードに番号を付けて配列でもつように実装されることがよくある。


# 配列での実装する際のノードの番号付け
2分木の各ノードに対して、図のように番号を振る。
![binarytree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321747/d640f994-e836-9af8-053c-8757748177bd.png)

この時、自身のノードに対して子番号と親番号は以下のようになるが、これの説明。

1. 左の子: $2n$　右の子: $2n + 1$ 
1. 親 : $floor(\frac{n}{2})$

[1.の説明]
2分木の深さ$d$におけるノード数は$2^d (d=0, 1, 2,...)$であり、深さ$d$以下の全ノード数は

```math
2^0 + 2^1 + … + 2^d = \frac{(1 - 2^(d+1))}{(1-2)} = 2^(d+1) - 1
```
となる。そのため、各深さ$d$における一番左のノードのindexは$(2^d-1)+1 = 2^d$であり、
この一番左のノード$2^d$に対する、左の子は$2^(d+1)=2*2^d$、右の子は$2*2^d + 1$で1.が成り立つ。

深さ$d$の左から$i-1$番目のノード$n-1$に対して1.が成立すると仮定する。
深さ$d$の左から$i$番目のノード$n$に対する左の子の番号は、左から$i-1$番目のノードの右の子の次なので
$(2(n-1) + 1) + 1 = 2n$となって1.がノード$n$に対しても成立する。
よって帰納的に任意の深さ$d$の全ノードに対して1.が成立する。

[2.の説明]
深さdの一番左のノードに対しては、ノード番号が$2^d$で親は$2^(d-1)$なので2.が成り立つ。
また、その次のノードの親は同じ親で、$floor(\frac{2^d + 1}{2}) = floor(2^(d-1) + 0.5)=2^(d-1)$なので2.が成り立つ。

深さ$d$の左から$2i-1$番目のノードに対して2.が成り立つと仮定する。
左から$2i+1$番目のノード$n$に対する親番号は左から$2i-1$番目の親の次であるので、
$floor(\frac{n-2}{2}) + 1 = floor(\frac{n-2}{2} + 1) = floor(\frac{n}{2})$
となって2.が成り立つ。
同様に左から$2i$番目のノードに対して2.が成り立つと仮定すると、左から$2i+2$番目のノード$n$に対しても2.が成り立つ。
よって帰納的に任意の深さ$d$の全ノードに対して2.が成立する。


# 0始まりのノード番号を付ける場合
以下のように0始まりの番号を付ける。
![binarytree_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321747/b4374bdf-efe7-cb89-72c1-cf2f324201a9.png)

1始まりのノード番号をn、0始まりのノード番号を$n'$とすると、$n' = n - 1$
あるノードに対する左の子は1始まりの番号では、$2n = 2(n'+1)$で、これを0始まりに直して$2(n' +1) -1 = 2n' + 1$、右の子は$2n'+2$となる。
親についても1始まりの番号では、$floor(\frac{n}{2})=floor(\frac{n'+1}{2})$で、これを0始まりに直して$floor(\frac{n'+1}{2}) - 1 = floor(\frac{n'+1}{2} - 1) = floor(\frac{n'-1}{2})$

# 終わりに
プログラミングコンテストチャレンジブックを読んで、どうしてこうなるのか小一時間考え込んでしまったのでメモ
herokuでマイグレートしようとしたらMysql2::Error: Table  already existsが起きたときの解決策

## 起こったこと

Railsでポートフォリオを作成中、デプロイした後にマイグレートしようとしたら、
```Mysql2::Error: Table 'users' already exists```
が吐かれてマイグレートできなくなりました。
![errorのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859156/2aba4053-0711-a20c-c450-90427068543c.png)
## 原因
原因ははっきりとしていて開発環境でテーブルを増やしてアソシエーションを組んだときに、マイグレーションファイルの作成順序が誤っていて（最初からちゃんとやっておけば良い話）マイグレートに失敗し、マイグレーションファイルの作成日時を手動で変更したことが原因でした。

## 試してみたこと
まず、```heroku run rails db:migrate:status```で本番環境のデータベースの状態を確認してみました。
![error2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859156/8964aa14-c2c9-2a1b-f8e9-d094ee90a2c9.png)

予想通り、マイグレーションのステータスがおかしなことになっています。
本来、テーブルは４つありますが、下から２つ目のファイルは **NO FILE** となっています。
これが手動でマイグレーションファイルの作成日時を変更した弊害です。

この後、```heroku run rails db:migrate:reset```でデータベースのリセットを試みましたが、別のエラーが起こりうまくいきませんでした。

## 解決策
**```heroku run DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop db:create db:migrate```**

を実行します。
このコマンドはデータベースを一度壊して作り直し、マイグレートするのを一度に実行するものです。
これでもう一度```heroku run rails db:migrate:status```を実行し、ステータスを確認してみます。
![error3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859156/24a69f2d-f8b2-63d2-773a-1f0dd80f7ed8.png)

ステータスが正常に戻りました。
他にも方法はあると思いますが私のケースではこのコマンド一発で解決できました。

## エラーを通じて
本来、データベースをしょっちゅうresetしたりdropするということ自体、あまり好ましくないものだと思います。設計の甘さで今回のようなことになってしまったので、今後作成していく個人アプリケーションでは後々のことも考えてテーブル設計、実装順序の組み立てをしていこうという学びになりました。

同じようなエラーにあたった方の、助けになれれば幸いです。
【JavaScript】 クラスの仕組みを考える

クラスの定義
---
オブジェクト指向のプログラミング言語における、モノ（オブジェクト）を作成する際に必要なものです。

実装方法は、2パターンあります。

- クラス宣言
  - 先頭に「class ⚪︎⚪︎」 と宣言する方法
- クラス式
  - クラスを値として定義する方法で、クラス名は定義してもしなくても良い方法 

クラス宣言について
---
まずクラス名を設定するには、基本的に大文字から始めるルールというあります。
そしてそのクラスの中には、`コンストラクター(constructor)`が存在します。
コンストラクターとは、クラスで生成された`インスタンス`を初期化するメソッドのことで、1つのクラスの中で1度だけ使用することが可能です。
クラスからインスタンスを生成するには、必ず`new`演算子を使用する必要があります。new を宣言して、クラス内でインスタンス作成することを`インスタンス化`と呼びます。

今回は、プロフィールを例にして考えてみます。

```javascript
class Profile {
  // インスタンスを初期化する
  constructor(name, age) {
    // コンストラクター内の記述のことを、インスタンスプロパティと呼ぶ
    this.name = name;
    this.age = age;
  }
}

// new を宣言してインスタンス作成(インスタンス化)
const profA = new Profile('Taro', 15)
const profB = new Profile('Hanako', 20)

console.log(profA);
console.log(profB);


// 結果は...
Profile { name: 'Taro', age: 15 }
Profile { name: 'Hanako', age: 20 }
```

クラス式
---

>名前付きクラスの名前は、クラス内のローカルとして扱われます。(ただし (インスタンスのではなく) クラスの name プロパティによって取得可能)
(参照元) [MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes)

この説明だけでは少し分かりにくかったので、参照元にも掲載されていますが、私も手元で確かめてみることにしました。

- クラス名を定義する書き方

```javascript
const Profile = class ProfileA {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
console.log(Profile);
console.log(Profile.name);

// 結果は...
[class ProfileA]
ProfileA
```

- クラス名を定義しない書き方

```javascript
const Profile = class  {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

console.log(Profile);
console.log(Profile.name);

// 結果は...
[class Profile]
Profile
```

実際に手元で確かめてみることにしました。
クラス名を定義した場合には、定数名`Profile`の値を出力すると、クラス名の`ProfileA`が表示されます。
クラス名を定義しない場合には、定数名`Profile`の値を出力すると、そのまま`Profile`が表示されます。
参照元の文章は少し難しく感じましたが、試してみて目で確認すると実際は難しいことを言っていないのがよく分かります。

終わり
---
今回は以上になります。
最近JavaScriptを触れ始めたのですが、これはどういう意味？、何が起きている？と混乱の日々です。小さな気づきや得たことを忘れないように、サボり気味だったQiitaさんにまた少しずつ投稿いていきたいと思います。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
DNSのしくみ

# DNS
ドメインは文字列で記述される。インターネット上でコンピュータ同士の接続にはあくまでもIPアドレスが利用されるため**ドメインをIPアドレスへ変換**する必要がある。
ドメインをIPアドレスへ変換する仕組みを**DNS（Domain Name System)**と呼ぶ。
## ドメインとIPアドレスの変換
DNSはドメインとIPアドレスが紐づいて管理された、「電話帳」のようなものである。ドメインからIPアドレスを取得することを「正引き」（Aレコード）、IPアドレスからドメインを取得することを「逆引き」（PTRレコード）という。
DNSのサービスを提供するサーバーを**DNSサーバー**と呼び、膨大な数のドメインを、階層構造をとる複数のサーバーが分散処理している。
![8330333A-D458-4EE2-916C-C7A90044D6DD_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/84c5e4fd-ea12-256a-6e4b-79a91c121a84.jpeg)


### IPアドレスを取得する流れ
ドメインは「.」で区切られた階層構造になっており、それぞれの階層にDNSサーバーがある。各DNSサーバーは同階層のドメインとIPアドレスの紐付けと、下層に位置するDNSサーバーの管理を行なっている。
クライアントとのやりとりはDNSキャッシュサーバーが行う。一度問い合わされたIPアドレスは一定期間DNSキャッシュサーバーに保管され、同じ問い合わせがあった場合はここで応答する。
# 参考
[イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/gp/product/B06XNMMC9S/ref=ppx_yo_dt_b_d_asin_title_o05?ie=UTF8&psc=1)
【備忘録】rails console が起動できない場合

rails consoleを実行するとターミナルが固まってしまい立ち上がらないという現象が起こったため、解決法を忘れないように備忘録として残しておきます。

# 結論
springを止めたら起動できるようになります！

# 手順

```ruby:ターミナル
# 裏で動いているプロセスがないか確認
$ ps aux | grep rails
ユーザー名      9005   0.0  0.0  4268284    680 s000  S+   10:20PM   0:00.01 grep rail
# 特になかった。
```

```ruby:ターミナル
# spring（裏で動いてアプリを快適にしてくれるもの）を確認
$ ps aux | grep spring
ユーザー名      6544   0.0  0.3  4375700  24804   ??  Rs    9:48PM   0:01.36 spring app    | my_portfolio4 | started 0 secs ago | development mode      
ユーザー名      6543   0.0  0.3  4374676  24876   ??  Rs    9:48PM   0:01.37 spring app    | my_portfolio4 | started 0 secs ago | test mode      
ユーザー名       931   0.0  0.1  4372216  11024   ??  S    日02PM   0:01.01 spring server | my_portfolio4 | started 55 hours ago   
ユーザー名      9064   0.0  0.0  4297404    576 s000  R+   10:21PM   0:00.00 grep spring
# startedと書かれているし、動いていそうな雰囲気。。。
```

```ruby:ターミナル
# 止めてみる。
$ bundle exec spring stop
Spring stopped.
```

```ruby:ターミナル
# 再度コマンドの実行をしてみる。
$ rails console 
Running via Spring preloader in process 9252
Loading development environment (Rails 6.0.3)
[1] pry(main)> 
```
無事に起動しました！！

【参考記事】
https://qiita.com/YumaFuu/items/aa10290e8c48613089a6
Vue.js(@vue/cli)のインストール

# 概要

WindowsでのVue.js(@vue/cli)のインストール手順をまとめる。

# 手順

## Node.js(npm)のインストール

Vue.jsをインストールするためにnpmが必要なため、先にNode.js(npm)のインストールを行う。

### 1. インストーラーのダウンロード
[Node.js公式](https://nodejs.org/ja/)からインストーラーをダウンロードする。

### 2. インストーラーのダウンロード
インストーラーを起動し、画面に従ってインストールを進める。
※基本的にNextを押して進めて行けば良い。

### 3. インストール完了確認

インストールが完了したらコマンドプロンプトから以下のコマンドを入力し、Node.jsとnpmがインストールできていることを確認する。

```
$ node --version
v14.16.1 // 正常にインストールできていればバージョンが表示される

$ npm --version
6.14.12 // 正常にインストールできていればバージョンが表示される
```

## @vue/cliのインストール

### 1. インストーラーのダウンロード
以下のコマンドで@vue/cliをインストールする。

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

### 2. インストール完了確認
インストールが完了したらコマンドプロンプトから以下のコマンドを入力し、@vue/cliがインストールできていることを確認する。

```
$ vue --version
@vue/cli 4.5.12 // 正常にインストールできていればバージョンが表示される
```

---

バージョンが表示されず以下のようなメッセージが表示されたら何らかの問題が発生している可能性がある。

```
'vue' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```
筆者は上記状態になったためNode.jsとnpmをアンインストールし関連ファイルを手動で完全に削除後、再度Node.jsと@vue/cliとインストールを行ったところ正常にバージョンが表示されるようになった。
※おそらくnpmが環境変数に追加されていなかったために発生していた。
Angular11＋Materialでログイン画面作成した時のコマンド記録（作成中）

あるプロジェクトでログイン画面を作るために行ったコマンドなどのメモ。

# プロジェクト作成と構成ファイル作成

まずはAngularのプロジェクトを一つ作ります。

```
ng new olympic-tokyo
```

strict type checking : yes 
Angular routing: yes 
stylesheet: SCSS

(ng new my-app --routing --style=scss)

Materialを追加

```
ng add @angular/material
```

prebuilt theme: Custom 
global Angular Material typography style: No
browser animation : Yes 

ここまでできたら、まず起動して確認して見る。

```
ng serve
```

ブラウザを開き、localhost:4200で画面を確認

イメージを追加したい場合は：
https://via.placeholder.com/728x90.png?text=Visit+WhoIsHostingThis.com+Buyers+Guide
使うと便利

この時点でVSCodeを立ち上げ

```
code . 
```

まずログインモジュールを作成する

```
ng g m login
```

appの下にloginフォルダを作成すると同時に、login.module.tsを作成

そのモジュールに入るコンポーネントを作成

``` 
ng g c login/login-form -m login.module
```

このコマンドはlogin/login-formフォルダにlogin-formのコンポ年とを作成し、このコンポーネントをloginモジュールに登録してくれる。

```
ng g c login/select-menu -m login.module
```

同じ方法でselect-menuコンポーネントを作成。

```
ng g s login/login 
```

このコマンドではloginの下にloginサービスを作成する。

# 画面の作成

まず、app.component.html にて<router-outlet></router-outle>以外の全てを削除

mat- を使いMaterial要素を使ってデザインを行う。




# Router定義


メインモジュールでの定義方法(LazyLoad)

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
// import { LoginModule } from './login/login.module';

const routes: Routes = [
  { 
    path: '', 
    loadChildren: () => import('./login/login.module').then(m => m.LoginModule),
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
```

サブモジュールでの定義方法

```
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CommonModule } from '@angular/common';
import { LoginFormComponent } from './login-form/login-form.component';
import { SelectMenuComponent } from './select-menu/select-menu.component';

const loginRoutes: Routes = [

  { path: 'login', component: LoginFormComponent }, 
  { path: 'menu', component: SelectMenuComponent }, 
  { path: '**', component: LoginFormComponent },

];

@NgModule({
  declarations: [
    LoginFormComponent,
    SelectMenuComponent
  ],
  imports: [
    CommonModule, 
    RouterModule.forChild(loginRoutes),
  ]
})
```

# ソースをGoogle　Firebaseにデプロイする

ログインする

```
firebase login
```

プロジェクトリストを見る

```
firebase projects:list 
```

初期化する前に、まずFirebaseにアクセスしてFirestoreを作る必要がある（そうしないと下記の firebase initでエラーなってしまう）。

本番で、ロケーションは　Asia-north1（日本・東京）を選択する。

作成できたら下記の初期化を行う。

初期化する

```
firebase init
```

必要に応じてサービースを選択する
firestore / functions / hosting / remote config など

その後プロジェクトを選択し、一連の設定を完了。

そうするとpublicフォルダができるので、コンパイルしたファイルをそこに置いてDeployすればアクセスできるようになる。

```
ng build --prod 
```

distのしたのファイルをpublicにコピー、そして下記のコマンドでDeploy

```
firebase deploy --only hosting
```

# 状態管理Akitaをインストールする

Akitaを追加する
``` 
ng add @datorama/akita
```

コマンドラインを追加する
```
npm install @datorama/akita-cli -g
```



参考：
[Angular CLI](https://angular.io/cli)
[Firebase CLI](https://firebase.google.com/docs/cli?hl=ja)
オリジナルコマンドをつくろう

Desktopにフォルダを作り、オリジナルコマンドを作成し管理してみます。

#フォルダを作成する
まずはDesktopにshフォルダを新規作成

```
$ mkdir ~/Desktop/sh
```

###パスを通す
本来、このフォルダ内のファイルを実行するためには`$HOME/Desktop/sh/ファイル名`を入力して実行する必要があります。

しかし、以下のように格納先のディレクトリまでを`環境変数のPATHに追加`することで、実行する際に追加したパスを省略して`ファイル名だけで実行でき便利`になります。

```
$ export PATH=$HOME/Desktop/sh:$PATH
```

###環境変数のPATHに追加されているか確認
以下コマンドで環境変数のPATHの値を出力出来ます。
`:`区切りです。先頭に追加されました。

```
$ printenv PATH

*実行結果*
/Users/sampletarou/Desktop/sh:/usr/local/sbin:/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

<strong>設定を更新</strong>

```
$ source ~/.bashrc
$ source ~/.bash_profile
```

#実行ファイルを作成する
shフォルダ内にシェルスクリプトを記述するファイルを作成します。

```
$ touch ~/Desktop/sh/print.sh
```

###実行できるように権限を変更
この時、Macのユーザーパスワードを求められると思います。

```
$ sudo chmod 755 ~/Desktop/sh/print.sh

*実行結果*
-rwxr-xr-x (変更前: -rw-r--r--)
```

###スクリプトを記述
先頭に必ず`#!/bin/sh`の１行を入れてから処理を記述してください。

```print.sh
#!/bin/sh
echo ' Hello Word!'
```

#実行してみる
カレントディレクトリはどこでもいいので以下を実行しHello Word!が出力されたら完成です。

```
$ print.sh

*実行結果*
Hello Word!
```

#参考
コマンド作成について
https://wemo.tech/3949
PATHについて
https://qiita.com/Naggi-Goishi/items/2c49ea50602ea80bf015
http://pocketstudio.jp/linux/?%A5%D1%A5%B9(PATH)%A4%CE%B3%CE%C7%A7%A4%C8%C0%DF%C4%EA%CA%FD%CB%A1%A4%CF%A1%A9
https://qiita.com/soarflat/items/d5015bec37f8a8254380
環境変数確認コマンドについて
https://webkaru.net/linux/printenv-command/
#PowerApps DateTimeValue関数 実行環境による差異

DatePicker（日付選択コントロール？）から DateTimeValue 関数と Time 関数で年月日＋時分の値を生成したかったんです。アプリ作ってテストしていたら、実行する実行環境によって動きが異なる点があったんですよ。いつか忘れて、またハマりそうなので記事にしておきます。

# 参考文献

[Power Apps での日付の選択コントロール](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/controls/control-date-picker?WT.mc_id=BA-MVP-5004053)

[DateTimeValue](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-datevalue-timevalue?WT.mc_id=BA-MVP-5004053#datetimevalue)

[Power Apps での Date および Time 関数](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-date-time?WT.mc_id=BA-MVP-5004053)

# やりたかったコト
DatePicker で選択した年月日に、とある条件によって時間を組み合わせて日時型にしたうえで判定する、みたいなコトです。

例えば「DatePicker ＝ 2021/04/01」と選択されていた場合、2021/04/01 9:00 の日付型を生成して、とある値と比較する感じですね。なお、時刻の部分も条件で可変にしたいので Time 関数と DateTimeValue 関数を組み合わせていたんです。

さて、何が起こったか？

# Windows 10 Edge
![01-Win10Edge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/983660cc-4312-573f-b2c6-cc0a638a9ab8.png)

# iPhone
![02-iPhone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/83034ae3-2b5c-b419-7dc1-dbebf620dde9.png)

# Android(Pixel3)
![03-android.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/1b13c9ff-86d3-c3ba-c161-f6f761bc0477.png)

# Windows 10 Edge(スマホエミュレート)
![04-Edgeエミュレート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/b98506d9-1912-5be6-79a7-8c148c5165dc.png)

# 症状
おわかりいただけただろうか・・・

上記のスクリーンショットは調査のために作成したアプリです。DatePicker と ラベルが並んでいるだけです。各ラベルに指定した関数は左側にキャプションよろしく置いてありますが、念のため下記にしておきます。

``` 
DatePicker1.SelectedDate
DateTimeValue( DatePicker1.SelectedDate & Time(9,0,0))
Time(9,0,0)
DateTimeValue( DatePicker1.SelectedDate & " " & Time(9,0,0))
```

上から順番に各ラベルコントロールへ指定しています。
2番目の関数がブラウザーでは動作しているのですが、iPhone も Android もスマートフォンではブランクが返ってきています。「年月日時分秒」だとスマホはNGって感じです。当方が作成したロジックは判定処理に利用していたので、ブランクと比較して処理が意図しない結果に陥ってた、ってコトです。（いや、こんなのわかるかい汗）

4番目の関数は年月日と時分秒の間に半角スペースを強制的に入れています。「年月日△時分秒」（△＝半角スペース）です。これであれば検証した限りのデバイスで問題無く意図した動作をしてくれました。

この半角スペースが有るか無いかによって異なる動作ですが、エラーになるワケでもないし警告も出ない・・・。なので、半角スペースに気づけなかったら今でも「スマホで動かない！なぜだ！！」って悩んでいたコトでしょう((((；ﾟДﾟ))))

# まとめ
- DateTimeValue 関数はブラウザーとスマートフォンで動きが変わる
  - 年月日△時間（△＝半角スペース）じゃないとスマホでは結果が返ってこない
- ブラウザーでスマホ画面をエミュレートしても再現はしない
  - 実機検証は重要です

PC上では完璧に動作してて、自信満々にアプリを発行してスマホで動作確認したら「動きませんけど」ってなったんですよね。関数や処理には全く不具合なくて、何度見返してもロジック的には間違いはなさそう。「なぜだー！？」って悩みまくったんです。

で、まさか？

と思って半角スペースを文字列連携したら動いたんですよねー。ロジックは正解だったけど、実行環境における差異にやられたって感じです。ほんと、こういう罠っぽいトコは知らないとハマります(;´Д｀)

Power Apps はマルチデバイスに対応したアプリが即座に作成できるのが強みのひとつなのですが、各種端末で動作確認するのが非常に重要だ、とお伝えできたかと思います。PC上でブラウザーだけ操作してるだと気づかないコトもありますわね、という良い実体験になりました。
他の開発者言語だとコンパイルして云々して・・・やっと各種デバイスでテストができるって感じでしょうか。Power Apps なら発行するだけでスマホでも動作確認できるので、スピード感もって検証できます。めんどくさがらず動作確認は可能な限りやりましょう。

それでは、皆さま、素晴らしい Power Platform Life を！
bundle install, rails s, rails c ... ができない

##概要
私が2021年4月13日直面したこの問題はmimemagicが原因でした。

まずはここでは経緯などを書いているので、同じくmimemagicが原因と思われ、とにかく解決をしたい方は下の解決策まで飛ばして頂いて構いません。
>Railsの一部であるactivestorageが依存しているmimemagic gemが、ライセンス関連の問題でrubygems.orgから取り下げられました。

この記事ではmimemagicのことに関しては詳しく解説はしていませんが、以上のニュースが世間を騒がしていた？ようです。

私はRailsなどweb系の勉強を始めたばかりのいわゆる駆け出しエンジニアです。

ことの発端はローカルにてRailsで開発していたアプリに修正を加えようとした時のこと。
ディレクトリを合わせ、`rails s`でサーバーを立ち上げようとするとエラーが。

```
$ rails s
Could not find rake-13.0.3 in any of the sources
Run `bundle install` to install missing gems.
```
`bundle install`を実行しろとのこと？だったので実行したところ、


```
$ bundle install
Fetching gem metadata from https://rubygems.org/............
Your bundle is locked to mimemagic (0.3.5), but that version could not be
found in any of the sources listed in your Gemfile. If you haven't changed
sources, that means the author of mimemagic (0.3.5) has removed it. You'll
need to update your bundle to a version other than mimemagic (0.3.5) that
hasn't been removed in order to install.
```
エラー文字列の中にはmimemagic ( 0.3.5 ) の文字が見える。
なるほどmimemagicが権利問題やらなんやらでRailsのアプリは影響を受けるというのは最近ネットで見かけていたが、悪さをしてきたか。
今まで問題なく出来ていたことができないのと、ズラズラと長い（実際には赤字で出た）エラーはビビる。
Qiitaで解決策を探していたらやはりありました。さすがはQiita様

>0.3.5はyanked（公開停止）されているようなのでアップデートすればOKです

##解決策

```
$ bundle update mimemagic
```
このコマンドを実行したところ`rails s`や`rails c`コマンドが使えるようになった！

ちなみにこれらのコマンドを実行するとまた長々と文字が表示される。「このgemはこのバージョンのrubyには非推奨だ」みたいなことなどが書いてあった。
しかし`rails c`などのコマンドは問題なく使えているので今のところは良しとし、新たに出た問題は後々探っていくこととする。

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

https://qiita.com/Wacci6/items/dc6ffec9b50578d44d6c

以上です。また何かエラーに出くわしたら記事にできるものはしていきます。
Windows10にてAnacondaでspaCy入れようとするとアクセスが拒否される件について

## 経緯
表題の通りAnacondaを使ってspaCyを入れようとすると、プロンプトには「アクセスが拒否されました」とのエラーが...権限周りが引っかかっているのかなと仮定し、プロンプトを管理者権限で再起動してみたがエラー解決できませんでした。

## 解決策
[こちら](https://qiita.com/hook125/items/3521a90fae7013f2f690)の記事に助けていただきました！感謝！ 
`easy_install -U pip` 後、spaCyインストールできました。
denoドキュメント リンク集

# 公式ドキュメント

 - https://deno.land/ : 公式サイト
 - https://deno.land/manual : 公式マニュアル
 - https://doc.deno.land/builtin/stable : ランタイムAPIのドキュメント
 - https://doc.deno.land/builtin/unstable : ランタイムAPIのドキュメント（--unstableフラグを付けて実行すると利用できるもの＝不安定API）
 - https://github.com/denoland/deno : リポジトリ
 - https://github.com/denoland/deno/issues?q=sort%3Aupdated-desc : issueのリスト（バグ報告とか）
 - https://github.com/denoland/vscode_deno : 公式が提供するvscode拡張


# 標準ライブラリ

 - https://deno.land/std : 公式サイト
 - https://github.com/denoland/deno_std : リポジトリ
 - https://golang.org/pkg/ : denoの標準ライブラリはGOの標準ライブラリがベースになっている。
 - https://doc.deno.land/ : 公式ドキュメントジェネレータ（サードパーティ製ライブラリにも利用できる）

# サードパーティ製ライブラリ

 - https://deno.land/x/ : 公式ホスティングサービス
 - https://www.skypack.dev/
 - https://unpkg.com/
 - https://jspm.org/
 - https://esm.sh/
 - https://github.com/ : githubに置いたjs/tsファイルを、rawボタンのリンク先URLを使って実行できる

※denoはURLから直接importできるので、npmに相当するレジストリがたくさんある

# コミュニティ

 - https://discord.gg/deno : discord。公式。コアチームのメンバーも参加している。
 - https://gitter.im/denolife/Lobby : 過去に公式で使われていたコミュニティ。現在はdiscordに移行済み。
 - https://scrapbox.io/deno-ja/Slack%E3%81%AE%E5%8F%82%E5%8A%A0%E6%96%B9%E6%B3%95 : slack。日本語のコミュニティ
 - https://github.com/denolib/awesome-deno : コミュニティ作成のリンク集。情報たくさん！
【初心者でもわかる】jsでクリックした数をカウントする装置

# どうも7noteです。カウンターを作ります。（記録保持機能なし）

jsを使った簡易カウンターを作ります。
動きの部分のみのだけなので、ページリロードすればまた0に戻ります。

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/f279ab94-129d-712a-f29e-dec077b11f23.gif)


## ソース

```index.html
<p>カウンター：<span id="count">0</span></p>
<input type="button" value="カウント" onClick="count();">
```

```script.js
function count(){
  var thisCount = $("#count").html();
      thisCount = Number(thisCount);
      thisCount = thisCount + 1;
  $("#count").html(thisCount);
}
```

## 解説

- html側はテキストとボタンを設置しています。カウントするところをわかりやすいようにspanで囲みidを指定します。
- `var thisCount = $("#count").html();`で**現状の値を取得**。
- このままだと文字列のままなので、計算できるように`var thisCount = Number(thisCount);`で**文字列から数字列に変換**。
- `var thisCount = thisCount + 1;`で取得した値に**1を足します**。
- `$("#count").html(thisCount);`で値を1足した数字に上書きします。

## まとめ

わかりやすく書くならこんな感じでしょうか。ただ記録を保持させたり、もっと複雑な計算をさせたり、カウントした前の数字を保管しておいてまた別で流用するなどが想定される場合はこのプログラムでは少ししんどいかなと思います。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
Haskellを使いながら計算論　【1】自作自然数型を定義し、加算関数をHaskellで帰納的に定義する

# 前置き
この記事シリーズの目的は、
>数学やプログラムを知ったかぶる著者が、『習うより慣れろ』の精神で、Haskellを使って計算論を学び、アウトプットしているうちに、いつの間にか計算論を理解しHaskell使いになっていることを目指す

ことで、
Haskellの実行環境構築や基本的な文法について詳細に解説すること、ではありません。

著者はHaskellや計算論のお勉強中なので、誤りなど、なんかよくないことを書いちゃっていたらご指摘いただけると幸いです。

# 今回の目的
Haskellで、シンプルな自然数の型を定義し、自然数の加算関数を帰納的に記述してみること。

# 自然数ざっくりメモ
## 自然数の定義
自然数を以下のように帰納的に定義します。

- 0は自然数である
- nが自然数ならば、succ n は自然数である

ここで、succ n は n の次の自然数を表します。 
つまり、succは、自然数を与えると自然数を返す関数です。
succはsuccessorの略で、英語で「後継」という意味です。

例えば、1 は succ 0 として定義します。
自然数は0から始まり、次々とsuccを適用していくことで、$1,2,3\cdots$という馴染み深い自然数を定義できます。

こう考えると自然数は

- 0
- 後継関数 succ

から構成されていると言ってよいのかな。
例えば、5 は

```
5 = succ 4
  = succ (succ 3)
  ・・・
  = succ (succ (succ (succ (succ 0))))
```
で、succ と 0 で表現し定義できます。


## 自然数の加算
日常で加算(足し算)って、 + を使いますよね。

例えば、
$2+1=3$
とか。

[今回の目的](#今回の目的)で書いた通り、Haskellで足し算を表す関数を帰納的に定義してみます。
Haskellではもちろん「+」は用意されており、あまり意味ないかもしれませんが、帰納的定義に慣れることが目的です。
ちなみに、Haskellでは、数値型の値を引数にとる「succ」も用意されています。
ですが、今回Haskellで実装する加算関数では、自然数の型を自分で定義して自然数のみを対象としたいので、succは使いません。

### 加算を帰納的に定義してみる
$1 + 2 = 3$

って、 1 と 2 を 「+」 に与えることで 3 を得ているように見えるかもしれません。

もっと一般的に、

$x + y = z$

という式を考えると、「＋」は自然数の組 ( x , y ) を引数にとって、自然数 z を返す関数に見えるかもしれません。

```
+ (x,y) = z
```

のような感じで。
（こんな書き方しないと思いますが、例えです。）

ここでは、自然数の加算を「+」ではなくて、関数 myAdd を用いて次のように帰納的に定義することを考えてみます。

---
### myAddの定義

- x = 0 の場合

```
myAdd x y = y 
```

- それ以外の場合、ある自然数 x' を用いて、x = succ x' と書けて、

```
myAdd succ(x') y  = succ myAdd x' y
```

myAddは自身を再帰呼び出ししています。

また、myAddは自然数の組(x,y)を受け取っているというよりは、
まず、myAddがxを受け取り、次にyを受け取る、と考えます。(カリー化)
myAddはxを受け取り、「1つの自然数を引数として自然数を返す関数」を返すと言えばいいのかな。
(その返ってきた関数にyを与えることで、結果として自然数(つまり $x+y$ の結果)を得るイメージ。)

---

例えば、myAdd 2 1 を計算すると、

```
myAdd 2 1 = myAdd succ(1) 1
          = succ (myAdd 1 1)
          = succ (myAdd succ(0) 1)
          = succ (succ (myAdd 0 1))
          = succ (succ 1)
          = succ 2
          = 3
```
となり、 myadd 2 1 は、 $2+1=3$ と同じ結果になります。
$2+1=3$ と計算するとき無意識に行っていると思います。
計算の理屈としては、加算は後継関数 succ を繰り返し適用することで行っています。

# HaskellでmyAddを実装
まず、Haskellで自然数の型を定義してみましょう。
型の名前をMyNaturalとでもしましょうか。

```haskell
data MyNatural = Zero | Successor MyNatural deriving Show
```

これだけの簡単なモデルですけど、MyNatural型は、「Zero もしくは Succerssor MyNatural」のみとすることで、[自然数の定義](#自然数の定義)で述べたことを表現しようとしています。

ここで、ZeroはHaskellの数値型で出てくる「0」とは、今のところ全く関係がないことに注意してください。
Zeroと書くと「0」を連想しやすいかなー、と思ってそうしてます。
Successorは今まで述べてきたsuccのことだと思ってください。

[myAddの定義](#myaddの定義)を確認すると、myAddは次のように書けます。

```haskell
myAdd :: MyNatural -> MyNatural -> MyNatural
myAdd Zero y = y
myAdd (Successor x) y = Successor (myAdd x y) 
```
1 を Successor Zero
2 を Successor ( Successor Zero )
のことだと考えると、上で例としたmyAdd 2 1 は

```haskell
myAdd (Successor ( Successor Zero )) ( Successor Zero )
```
と書けます。

確認のために、以下のようにコーディングして実行してみましょう。

```haskell
main :: IO ()
main = do
  print $ myAdd (Successor (Successor Zero)) (Successor Zero)

data MyNatural = Zero | Successor MyNatural deriving Show

myAdd :: MyNatural -> MyNatural -> MyNatural
myAdd Zero y = y
myAdd (Successor x) y = Successor (myAdd x y) 
```

結果は、

```haskell
Successor (Successor (Successor Zero))
```

となってSuccessorが３つあるので、0の次の次の次、つまり3を表す値となりました。

今回は以上です。
最後までご覧いただきありがとうございました。
<(_ _)>
【Rails】CSRFが引き起こすエラー

#CSRF
CSRF(クロスサイトリクエストフォージェリ)とは、Webアプリケーションの脆弱性を利用したサイバー攻撃の一種
例:悪意のある第三者が用意したリンクをサービスの利用者が踏んだ際に、本人の意図しない操作が行われてしまう
詳しくは、https://qiita.com/wanko5296/items/142b5b82485b0196a2da

#CSRFが引き起こすエラー
CSRF対策として、サーバはクライアントに対してトークンを設定します。
リクエストが発動した際に、クライアントのトークンとリクエストのトークンを確認し、攻撃者からのリクエストを防ぐことができます。
通常、GET以外のリクエストではセキュリティトークンが必須となっています。
Railsの場合、

```ruby
protect_from_forgery with: :exception
```
で、アプリ内のフォームに対してトークンを発行しています。


しかし何らかのエラーでトークンが一致しない場合、リクエストが正常に動作しない場合があります。
(以下のようなエラーが起きる)

```
Can't verify CSRF token authenticity.
```

#対応
メソッドのあるコントローラー内に、以下の記述を追記します。

```ruby
skip_before_action :verify_authenticity_token
```

この記述で、トークンの比較自体がスキップされるのでリクエストは動作するはずです。
しかし、トークンの比較をスキップするとのことなのでセキュリティ的にはどうなのかなとは思いますが、、
（詳しい方がいれば教えていただけると嬉しいです）
GiNZAで機械分析入門してみました

いままでMeCabを使っていたのですが、この度GiNZAに入門したので備忘録的なやつを書いときます。

## GiNZAとはなんぞや
欧米で有名な自然言語処理ライブラリであるspaCyの日本語版(超ざっくり)
係り受け解析とか形態素解析とか色々できるっぽいです


## 環境
Python 3.6.5
pip 21.0.1
Mac Catalina

## 環境構築
今回は仮想環境にGiNZAをinstallして動かしていこうと思います。
ひとまず適当なフォルダをつくって

```
$ mkdir sample
$ cd sample
```

venvで仮想環境を構築して中に入ります。

```
 $ python -m venv venv
 $ source venv/bin/activate
```

pipをアップデートして、Ginzaをインストールします。

```
 (venv)$ pip install --upgrade pip
 (venv)$ pip install -U ginza
```

インストールが完了したら念のため確認します。

```
 (venv)$ pip list
 ・
 ・
 dartsclone         0.9.0
 ginza              4.0.5
 idna               2.10
 ・
 ・
```

ちゃんと入ってますね！！

## 動かしてみる
さっそくスクリプト書いて形態素解析してみましょう。
今回は百人一首のあの有名な歌を解析してみます

```sample.py
import spacy

nlp = spacy.load('ja_ginza')
doc = nlp('秋の田の　仮庵の庵の　苫をあらみ　わが衣手は　露にぬれつつ')

for sent in doc.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, 
              token.tag_, token.dep_, token.head.i)
```

結果がこちらです

```
(venv)$ python sample.py
0 秋 秋 NOUN 名詞-普通名詞-副詞可能 nmod 2
1 の の ADP 助詞-格助詞 case 0
2 田 田 NOUN 名詞-普通名詞-一般 nmod 6
3 の の ADP 助詞-格助詞 case 2
4 　 　 X 空白  3
5 仮 仮 NOUN 名詞-普通名詞-一般 compound 6
6 庵 庵 NOUN 接尾辞-名詞的-一般 nmod 8
7 の の ADP 助詞-格助詞 case 6
8 庵 庵 NOUN 名詞-普通名詞-一般 nmod 11
9 の の ADP 助詞-格助詞 case 8
10 　 　 X 空白  9
11 苫 苫 NOUN 名詞-普通名詞-一般 obj 13
12 を を ADP 助詞-格助詞 case 11
13 あら あり VERB 動詞-非自立可能 acl 18
14 み み NOUN 接頭辞 aux 13
15 　 　 X 空白  14
16 わが わが DET 連体詞 amod 17
17 衣 衣 NOUN 名詞-普通名詞-一般 nmod 18
18 手 手 NOUN 名詞-普通名詞-助数詞可能 ROOT 18
19 は は ADP 助詞-係助詞 case 18
20 　 　 X 空白  19
21 露 露 NOUN 名詞-普通名詞-一般 obl 23
22 に に ADP 助詞-格助詞 case 21
23 ぬれ ぬれる VERB 動詞-一般 ROOT 23
24 つつ つつ SCONJ 助詞-接続助詞 mark 23
```

一応解析できてますね！！
ただ、「仮庵」とか「衣手」は一つの形態素として抽出してほしかったのですが、うまくいってないみたいです...
MeCabと同様辞書登録が必要かもしれません。
とはいえ、特定の品詞に絞って抽出とかもできそうで色々と可能性を感じますねー！

ざっくりでしたが今回はここまでです。
React入門 - Part1 - VsCodeをインストールしてReactでHello World

#目次
[React入門 - 目次](https://qiita.com/yokowake12345/items/0919ad144cbc4684e64e)

# node.jsのインストール
[ここから](https://nodejs.org/ja/download/)環境に応じたものをダウンロードしインストールします。
[ここにあるように](https://wakky.tech/install-node-js-windows/)「Automattically install the necessary tools. …」にはチェックを入れずインストールしました。

インストールが終わったら念の為、node.jsがインストールされていることを確認します。
コマンドプロンプトで以下のコマンドを実行し、バージョンが表示されることを確認しましょう。

```typescript
node --version
```

```typescript
npm --version
```

# yarnのインストール

```
npm install -g yarn
```

# VsCodeのインストール
[ここにあるように](https://azure.microsoft.com/ja-jp/products/visual-studio-code/
)ダウンロードしてインストールしてください。
日本語化の手順等は、ググるとすぐ出てくるので、ググって対処ください。

# GitBashのインストール
何かと使用するのでダウンロードしインストールしておきます。
[ここを参考にしてください](https://qiita.com/suke_masa/items/404f06309bb32ca6c9c5
)

# create-react-appをグローバルにインストール

[ここにあるように](https://qiita.com/gumiTECH/items/4b82e4e3757f226df6b0)create-react-appをグローバルインストールする

```
$ npm install -g create-react-app
```


# プロジェクト作成、Hello World表示

プロジェクトを作成したいディレクトリまで移動し、以下コマンドを実行する。

```
npx create-react-app プロジェクト名
cd プロジェクト名
```

※実行エラーになった場合、[ここを参考に](https://www.curict.com/item/d1/d1c4a3e.html)スクリプトの実行権限を変更する。

起動してみます。

```
npm start
```

```
http://localhots:3000
```

で以下のような画面が表示されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/e0cebe70-5a94-43df-28b4-7f679ae800ab.png)

※Hello Worldでは無かったです。。。。Learn Reactでした。
ReactNativeで「続きを読む/続きを見る」を実装する

# 省略したTextコンポーネントを展開するUIを実装する方法
React Nativeで、インスタやTwitterなどの**省略した文章を展開する「続きを見る」ボタン**を実装する方法がなかなか見つからなかったので作ってみた。
展開した状態で行数を取得し、その後すぐに縮小している。省略・展開にはnumberOfLinesを利用している。
以下は行数が2行より多い場合に、続きを見るボタンを表示するサンプルである。

```jsx:投稿のキャプション部分を実装した例
const Caption = ({navigation, text}) => {
  const onTextLayout = ({nativeEvent: {lines}}) => {
    // 展開された状態の行数を取得する
    if (typeof lineCount === "undefined"){
      setLineCount(lines.length)
      setIsExpanded(false)
    }
  }
  const [lineCount, setLineCount] = useState() // はじめはundefinedにしておく
  const [isExpanded, setIsExpanded] = useState(true)

  return (
    <Text numberOfLines={isExpanded ? undefined : 2} onTextLayout={onTextLayout}>{text}</Text>
    // 行数が2行より多く、省略されている場合のみ「続きを見る」ボタンを追加
    {lineCount > 2 && !isExpanded && <Text onPress={() => setIsExpanded(true)}>続きを見る</Text>}
  )
}
```

より良い方法があれば、ぜひ教えて下さい！！
PythonでPDFから表の取得（camelot）-社会保険料の標準報酬月額の取得に利用-

#1.前置き
この春、新社会人になりました。来たる給料日が非常に楽しみです。
給料のことを気にしていると、手取りも気になってきます。
予想したおおよその手取りよりも実際の手取りが少なかったら、少し悲しむ気がしてきました。
そんな理由で、手取りを正確に計算することで、心の平穏の維持に備えようと考えました。

　
さて、手取りを計算するためには、社会保険料と税額を求める必要があります。
この内の社会保険料は、**月収を標準報酬月額に変換して、その値にある保険料率を掛け算する**ことで求められます。
本記事では、PythonでPDFから表の取得を行うことで、社会保険料の計算に必要な標準報酬月額の取得を目指してみました。

#2.ライブラリのインストール
PythonでPDFから表を取得するための方法は、ざっと調べてみると二つありそうでした。
tabuler-pyライブラリもしくはcamelotライブラリを用いる方法です。
tabuler-pyは、ライブラリの中身はJavaで書かれているそうなので、PCにJava環境がないと動きません。
プログラミング環境は雑に作りたくないので、Java環境を作ってtabuler-pyを使うのは見送ることにして、今回はcamelotライブラリを使用しました。

camelotライブラリ自体は、

```python
pip install camelot-py[cv]
```
でインストールできます（Anaconda利用者は、pipでなくcondaで管理）。

ただこのライブラリの利用には、Ghostscriptが必要ですので、インストールしておきましょう。
For Windows : https://www.ghostscript.com/download/gsdnld.html
For macOS : brew install tcl-tk ghostscript


#3.PDFから表の取得
では、実際にcamelotを使って、PDFから表を取得しましょう。

今回は、厚生年金保険料計算のための標準報酬月額を調べるために、[日本年金機構が出している保険料額表](https://www.nenkin.go.jp/service/kounen/hokenryo/ryogaku/ryogakuhyo/20200825.files/01.pdf)をサンプルとして取り上げてみます。

```python
import camelot

table_nenkin = camelot.read_pdf('nenkinR3.pdf') #TableList
table_nenkin[0].df
```
PDFをnenkinR3.pdfという名前で保存して、camelot.read_pdfに引き渡すと、
PDF中の全ての表がDataFrameとして取得され、ページ上部の表から順にリストへ格納されます。
本PDFは表が一つしかなく、table_nenkin[0].dfで目的の表をデータフレームとして取得できます。
この表をJupyter環境で表示すると下図のようになるはずです。

![table_nenkin_df.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378787/c3e91e04-6b63-4aac-aebf-1541e088485e.png "table_nenkin_df")

**簡単ですね！！**
表取得は完了しましたので、当初の目的通りに、これを標準報酬月額の取得に応用してみましょう。

以下コードと実行結果。

```python
import re
month_salary = 238000 # your salary
for i in range(3,35):
    if i == 34:
        standard_month_salary = int(re.sub(r"\D", "",  table_nenkin[0].df[1][i]))
        break
    s = table_nenkin[0].df[2][i]
    Range = s.split('\n')    
    Range_H = int(re.sub(r"\D", "",  Range[2]))
    if Range_H >= month_salary:
        standard_month_salary = int(re.sub(r"\D", "",  table_nenkin[0].df[1][i]))
        break    
print('標準報酬月額（円）：', standard_month_salary)
```

```python
標準報酬月額（円）： 240000
```


#4. 最後に
社会常識のお勉強ついでに、Pythonを用いてPDFから表の取得をする方法を調べてみました。camelotの使い勝手は良さそうです。
SQLServer: パフォーマンスチューニングに関する資料を公開しました

#背景
SQL Serverのパフォーマンスチューニング（特にクエリチューニング）について体系的な資料を作成したかったので、コツコツと準備を進めていました。

#おすすめの対象者
- SQL Serverのパフォーマンスチューニングに興味がある方
- クエリチューニングの評価方法について学びたい方
- サーバーのCPUを下げたい、という目的のときにどのような観点で調査していけば良いか知りたい方

#資料
こちらにまとまっています。
https://www.slideshare.net/relaxatmos/sql-server-performance-tuning-essentials


#動画
ビデオとしても公開されています（有料）
https://www.linkedin.com/learning/microsoft-sql-server-performance-tuning/

こちらのリンクからだと、24時間無料で視聴可能です。
https://www.linkedin.com/feed/update/urn:li:activity:6783646329181749248/

#最後に
「クエリストア」や「列ストアインデックス」、「intelligent query processing」、「軽量なクエリプロファイリング」等、新しめの概念には触れられていませんが、エッセンスについては網羅できている自負があるので、ご興味あるかたはご覧いただけると嬉しいです。
Fargate タスクを定期実行したいときに EventBridge 以外の選択肢も検討してみる

# 概要

- Amazon ECS の Fargate タスクを cron のようにスケジュール実行したい場合、候補として挙がるのが EventBridge (CloudWatch Events)
- ただし EventBridge には考慮しなければいけない 2 つの問題点がある
- メリット・デメリットを理解して、それ以外の選択肢も考えてみる

# EventBridge

## 利点

- サーバレスでフルマネージド
- 実装不要

## 欠点

### 1. 少なくとも 1 回の起動が保証される

よく知られている特徴で、稀に 2 回以上イベントが実行されることがある。

https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eventbridge-troubleshooting.html#rule-triggered-more-than-once

#### 対策

同時実行耐性や冪等性が保証されるようにアプリケーションを実装する必要がある。

### 2. Fargate タスクの起動は保証しない

ポイントは以下。

- EventBridge はタスクの RunTask の実行を保証する
- ただし RunTask によってタスクが起動したかどうかは保証しない

筆者も経験があるが、稀に AWS 側の不具合で Fargate が起動に失敗することがあった。
なお、この事象は EventBridge からの呼び出しに限らず、AWS CLI や SDK など RunTask API を利用するもの全般にいえる。

#### 対策

Step Functions を間に挟み、もし Fargate の起動に失敗した場合はリトライするようにステートマシンを組む方法がある。

```text
EventBridge --> Step Functions --> Fargate
```

https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/concepts-error-handling.html#error-handling-retrying-after-an-error

# 議論

EventBridge を利用する場合、欠点で挙げた 1. (稀に 2 回以上起動) と 2. (Fargate の起動保証はしない) を考慮しなければいけない。
一方で、EventBridge を使わずにあえて crontab を動かすためのサーバーを別で用意するという原始的な手もある。この場合、欠点で挙げた 1. は考慮しなくてもよい。ただし依然として 2. は cron 側の実装でなんとかしなければいけないし、新たに cron の可用性を考慮しなければいけない。
このあたりはトレードオフにはなるが、同時実行耐性や冪等性を保証するアプリケーションの実装が困難な場合は検討してもよいのではないだろうか。
LPIC.lv1 101対策用コマンドまとめ①

|lspci　　　　　　　| PCIデバイス情報の表示
|:-------------|:-----------------------
| -v   | 詳細情報の表示     　   
| -vv  | さらに詳細な情報の表示   

|lsusb　　　　　　　| USBデバイス情報の表示
|:---------------|:-----------------------
| -v   | 詳細情報の表示     　   
| -t   | ツリー状に表示  

|lsmod　　　　　　　| カーネルに取り込まれた（ロードされた）デバイスドライバの表示
|:-----|:----------------------
|modprobe|デバイスドライバを手動で取り込む

|dmesg　　　　　　　| システム起動時にカーネルが行った処理の確認
|:-----|:-----------------------

|shutdown　　　　　| システムのシャットダウンや再起動
|:-----|:-----------------------
| -h  | シャットダウン     　   
| -r  | シャットダウン後再起動
| -f  | 次回起動時にfsckをスキップ    　   
| -F  | 次回起動時にfsckを必ず実行
| -k  | シャットダウンせずに警告メッセージを出す   　   
| -c  | シャットダウンキャンセル
|$ shutdown -h +5 "Please logout"  | 警告を出し、5分後にシャットダウン

|runlevel　　　　　　　| ランレベルの確認
|:-----|:----------------------
|init or telinit|ランレベル変更
|$ init 1 |シングルユーザモードへ変更
|wall | ランレベル変更の前にユーザの端末へメッセージを送信しよう

|systemctl　　　　　　　| systemdのサービス管理
|:-----|:----------------------
|start|サービス起動
|stop|サービス停止
|restart|サービス再スタート
|reload|サービス設定再読み込み
|status|サービスの稼働状況確認
|is-active|サービスが稼働しているどうか
|enable|システム起動時にサービスを自動起動
|disable|システム起動時にサービスを自動起動しない
|list-unit-files|全てのUnit表示
|reboot|システム再起動
|poweroff|システムシャットダウン
Java学習　基礎編　変数名の付け方

Java学習の備忘録になります。
内容は初心者なので基礎的な部分となります。
Javaに興味がある方やJava学習初心者の参考になれば幸いです。
* * *

#### 変数名の規則とは？

変数名には、以下のような規則がある。
文字数制限はないが、あまり長い名前を付けると、タイプミスが起こりやすく、プログラムが読みにくくなる。

**・変数名には、半角英数字(A~Z、a~z、0~9)、_(アンダーバー)、$(ドルマーク)などの一部の記号を使える
・下記のようなJava言語自体が利用するキーワード(予約語)を変数名に使うことはできない**

```
int class = 10;  // コンパイルエラー　classという変数名はつけられない
int int = 10;  // コンパイルエラー　intという変数名はつけられない
```
**・数字は2文字目以降で使える(1文字目には使えない)**

```
int number1 = 10;  // 2文字目以降で数字が使われているのでOK
int 1number = 10;  // コンパイルエラー　1文字目には使えない
```
**・大文字/小文字は、別の文字として区別される**

```
// 下記は別々の変数として区別される

int number = 10;  
int Number = 10;  
```
* * *

#### 変数名の慣習的なルール

**・_(アンダーバー)、$(ドルマーク)などの記号は使わず、英数字のみを利用する
・用途のわかるような名前をつける
・１つの単語からなる変数名は、すべて小文字にする
・複数の単語を組み合わせるとよりわかりやすくなる。その際は、あとから付ける単語の先頭のみを大文字にして、単語の区切りをわかるようにする
・変数名の途中にスペースは使えない**

```
// ダメな例

int a = 10;  // どのような用途で使われるのか、変数名を見ただけではわからない
String userfirstname = "Sasaki";  // 単語の区切りがわかりにくい
String user first name = "Sasaki";  // 変数名の途中にスペースが入っている
```
* * *
#### おわりに
そのほか、命名ルールがありましたらご教授ください。
よろしくお願い致します！！
ServiceNow - Visual Task Boardカードのフィールドを編集する

#概要
Visual Task Boardから作成するカードにCIフィールドを追加する手順です。
![visual_task_board_add_ci_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/71249073-d4dd-0676-fd2b-dbff4b9a3de3.png)

#手順
1. アプリケーションナビゲータから「visual task」を検索して、Self Service下のVisual Task Boardsを選択する。<br/>ボードを開き、「Add Card」ボタンを押下しる。<br/>![visual_task_board_add_ci_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/2d94632f-41d5-ac06-676f-94e6e79d337c.png)
1. ダイアログの左上の設定アイコンをクリックして「Configure」ー「Form Design」を選択する。<br/>![visual_task_board_add_ci_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/265f0ccb-0d8d-63a2-9ff2-a2c650eaa1bd.png)
1. 左マニューから「Configuration item」をフォームにドラッグ＆ドロップする。<br/>![visual_task_board_add_ci_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/9b1078f8-b005-44af-663f-418c822d337c.png)
1.「Save」ボタンを押下する。<br/> ![visual_task_board_add_ci_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/9f6e16af-1a34-ff5a-17d0-cbcb5c177fe7.png)
1. 元のカードに戻り設定アイコンをクリックして「Reload form」を選択する。<br/>![visual_task_board_add_ci_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/28877a81-78ce-7329-eb2e-526c9abb7934.png)
1. カードにフィールド「Configuration item」が追加されていることを確認する。<br/>![visual_task_board_add_ci_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/71249073-d4dd-0676-fd2b-dbff4b9a3de3.png)

以上
【備忘録】【VBA】検索ツール　　


<h1>背景
<p>課題として検索ツールの作成が出されたので、今までVBA・マクロは全く触って来なかったんですが、なんとか完成しました。
今回は、その備忘録です。

<h1>目的
<p>別シートの顧客リストから、名前検索して指定した項目のみを抽出させる

<h1>準備
<p>
1枚目のシート→【顧客リスト】
２枚目のシート→【検索ツール】

【検索ツール】の名前を記入するところは、セルの名を定義する。
例）D3　→　氏名


<h1>VBA
<p>


```
Option Explicit　　　　←決まり文句


Sub 名前検索()   ←マクロの名前決め

Dim 氏名 As String
Dim Count As Long


'入力した値の取得
氏名 = Sheets("【検索ツール】").Range("氏名")

'もし入力されていたら
If 氏名 <> "" Then

    '検索結果のクリア
    Sheets("【検索ツール】").Range("C86").CurrentRegion.ClearContents
    
    '【顧客リスト】にフィルターをかける
    With Sheets("【顧客リスト】")
    .Range("A1").AutoFilter Field:=2, Criteria1:=氏名
    End With

        'もし入力された値のデータがない、間違いがある場合
        If Sheets("【顧客リスト】").AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Count = 1 Then
        'エラーの表示
        MsgBox "データがない、もしくは名前が間違っています"



        'もしデータがあったら
        Else
        With Sheets("【顧客リスト】")
        'コピー
        .Range("D:G,M:N").Copy
        'ペースト
        Sheets("問題").Range("C83").PasteSpecial
        Range("C83:H83").Interior.Color = RGB(250, 241, 211)
        'フィルター解除
        .Range("A1").AutoFilter
        End With
        End If


'入力されてない場合
Else
MsgBox "氏名を入力してください", vbExclamation


End If
End Sub

```



<h1>後日談
<p>これエクセルでしかできないんですな。
家でできなかったからネットカフェで泣きながら２日かけて作成したげな。
嘘。楽しかったです。
めも）イテレーターとジェネレーター関数

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Iterators_and_Generators

イテレーターオブジェクトが作成
`next()` を繰り返し呼び出すことによって、
明示的に反復することができます。

イテレーターを反復することを、イテレーターを消費すると言います。

一般的に 1 回しか実行できないためです。
終了値が返された後、さらに `next()` を呼び出しても、単に `{done: true}` を返し続けます。
複数の配列を比較し、共通項の数を算出する

受け取った6つの数字を親配列に入れ、同様にN回６つの数字を受け取り子配列に入れます。
親配列と子配列を比較し、共通の数字の数を出力します。
※便宜上、基準となる配列を親配列と名付け、比較する配列を子配列と名付けてます。

```Ruby
# 6つの数字を受け取り配列にする
a, b, c, d, e, f = gets.split(' ').map(&:to_i)
# 冗長になるので変数luc_numsに代入
luc_nums = a, b, c, d, e, f

# 試行回数を変数Nに代入する
N = gets.chomp.to_i

# N回下記の処理をする
N.times do |i|
    # 新たに6つの数字を受け取り配列にする
    a_l, b_l, c_l, d_l, e_l, f_l = gets.split(' ').map(&:to_i)
    # 冗長になるので変数lot_numsに代入
    lot_nums = a_l, b_l, c_l, d_l, e_l, f_l
    # luc_numsとlot_numsを比較し、共通項を変数common_numsに代入
    common_nums = luc_nums & lot_nums
    # lengthメソッドでcommon_numsの数を出力
    puts common_nums.length
end
```

他に簡潔な方法があると思いますが、Rubyの基本のみで解いてます。

最後にコメントアウト無しを載せます。

```Ruby
a, b, c, d, e, f = gets.split(' ').map(&:to_i)
luc_nums = a, b, c, d, e, f

N = gets.chomp.to_i

N.times do |i|
    a_l, b_l, c_l, d_l, e_l, f_l = gets.split(' ').map(&:to_i)
    lot_nums = a_l, b_l, c_l, d_l, e_l, f_l
    common_nums = luc_nums & lot_nums
    puts common_nums.length
end
```
ローカルでは動いてたのにサーバーに上げたら"not found"って怒られたときの話

<h2>初めに</h2>
プロジェクトの一環として、先輩から任されたツール作成。
この手のタスクにもだいぶ慣れ、サクッとLaravelでコードを書き上げる。

いつも通りローカルで念入りに動作確認し、無事に動くことを確認する。
そしてAWS上の保守環境へ適用するためにパイプラインを実行。

いざ画面で動作確認...


すると、エラー画面へ遷移。
何度やってもエラー画面。

「なぜ？」と思いながらCloudWatchへ。

ログ「そんなファイルないぞ」
私「え？」

<h2>事象</h2>
__ローカルでは問題なく動いていたコードが、保守環境（AWS）上に挙げたところ動かなくなった。__

エラー内容：
>　View [pages.tool.TestView] not found.


<h2>結論</h2>
__ファイル名の大文字小文字は正確に打ちましょう。
OSによっては読み込まれないことがあります。__
ディレクトリにも大文字小文字を不用意に混ぜないようにしましょう。

<h2>詳しいお話</h2>
今回引っかかったのがコントローラー内の以下のコード。

```TestController.php
return view('pages.tool.TestView', ['action' => 'get']);
```

実際のファイル構造はこんな感じ
views
 └pages
 　 └__Tool__
  　 　 └ TestView.blade.php

...皆さんもわかっただろう。
"tool"と"Tool"のタイポという、ひっっじょうにしょうもないミスである。

__「じゃあなんでローカルだと動いたの？」__という話であるが、
どうやら__ローカルと保守環境のOSの違い__が原因だったらしい。

| ローカル環境           | 保守環境             |
|:-:                    |:-:                  |
| PHP ビルドインサーバー  | AWS EC2インスタンス  |
| Windows               | Linux               |


ここで[こちらの記事](https://qiita.com/tadsan/items/6c6329eeb43929271119)から引用させていただくと、
PHPは文法においては大文字小文字を区別しない（ケースインセンシティブ）。
しかしファイル名となると、
>これは実はPHPは関係なく、ファイルシステム(OS)に依存します。

>一般的にWindowsやmacOSのデフォルトのファイルシステムではファイル名はケースインセンシティブ(大文字小文字を区別しない)、GNU/Linuxではケースセンシティブ(大文字小文字を区別する)です。

つまり、PHPの文法上ではifだろうがIfだろうがIFだろうが許容されるものの、
__ファイル名は大文字小文字をしっかり区別しうるのだ。__

そして今回は、ローカル環境がケースインセンシティブなWindowsだったのに対し、
保守環境がケースセンシティブなLinuxだった。

そのため、ローカルではちゃんと動いたにもかかわらず、保守環境上ではファイルが正しく読み込まれなくなったという話。

<h2>まとめ</h2>
__ファイルやフォルダの命名規則はちゃんと守って、
大文字小文字はちゃんと区別しておきましょう。__

~~こんなしょうもないミスに1時間もかかったとか恥ずかしくて言えない~~

OSによる文字区別については、経験のあるエンジニアの皆さんには常識かもしれないが
自分にとってはかなり衝撃的だった。
ちゃんとサーバーやOSについても理解を深めたいと思った次第...

<h3>参考ページ</h3>
・ローカル環境（XAMPP）では読み込めたのに、サーバーにアップすると読み込めないファイルが…。原因はファイル名にある？(https://incloop.com/file-case-differences/)
・Q. PHPは大文字小文字を区別するか？(https://qiita.com/tadsan/items/6c6329eeb43929271119)
（備忘用）React Refの関数がいつからか変わってた

ReactのRefのメソッドが一部変わってました。
他にもあるかもしれませんが、備忘用に。

`scrollResponderScrollTo`はレンダリングされたときのスクロール位置を指定できる関数です。

関数自体が変わったのかもしれませんが、動きはいまのところ同じっぽいです。

**※変更になったversionは正確にあってないと思うのでご参考までに。。。**

公式のドキュメントには載っていないメソッドも結構あったので、modulesの中身を直接見に行ったほうが分かりやすかったです。

## 旧（~v16.8.6?）

``` js
scrollViewRef: React$ElementRef<*> = React.createRef();

render() {
  <
    onWillFocus={() => {
      this.scrollViewRef.current.scrollResponderScrollTo({ // この関数
        y: 0,
        animated: false,
      });
    }}
  />
}
```

## 新（v17.0.1~?）

``` js
scrollViewRef: React$ElementRef<*> = React.createRef();

render() {
  <
    onWillFocus={() => {
      this.scrollViewRef.current.scrollTo({ // この関数
        y: 0,
        animated: false,
      });
    }}
  />
}
```
Uncaught Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js): の解決方法

##注意
今回の内容は場当たり的な解決できた参考例である事を前提として、実行の際にはよく内容を検討いただいた上で自己責任でお願いいたします。

##環境
・AWS Cloud9 (Ubuntu 18.04.5 LTS, Bionic Beaver)[^1]
・Node.js[^2]

##エラー内容
```shell:Terminal
Uncaught Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
```

##解決策
以下を実行。

```shell:Terminal
npm install --save-dev --unsafe-perm node-sass
```

##経緯
検索した結果で最頻の方法を試すも解決しなかった。以下のコマンド。

```shell:Terminal
npm rebuild node-sass
```


##エラー原因・背景など
・原因：EC2のデフォルトのnode-sassが古かった？(導入：2021/2/14時点)
https://stackoverflow.com/questions/54354644/error-in-module-build-failed-from-node-modules-sass-loader-lib-loader-js

・コマンド背景参考URL
https://qastack.jp/programming/48147896/error-in-cannot-find-module-node-sass

[^1]: 2021/2/14時点
[^2]: バージョンは失念しました...すみません