OmniAICreator/Qiita-1.07M huggingface dataset:
Rails6でJavaScriptの動的読み込み

## 実現したいこと
JavaScript内からDB内のデータを動的に読み込みたい✅

<br>

## 開発環境
Rails６系
Ruby３系

アプリ：[Muscle Beat](https://www.muscle-beat.com)（スマホ専用筋トレ系音ゲー）
[GitHub](https://github.com/jibiking/muscle_beat)
テーブル（例）↓
[![Image from Gyazo](https://i.gyazo.com/a0eef96b76e54d3df43a1c5255f5566e.jpg)](https://gyazo.com/a0eef96b76e54d3df43a1c5255f5566e)

<br>

## 結論
<font color="DeepPink">view内の```scriptタグ```に```erbタグ```を用いて動的に読み込ませたいJSを記載します！</font>

たしかにRails６系のJavaScriptの記述は```app/javascript/packs```以下にするのが通常です。
しかし上記pack以下のJavaScriptファイルはRailsのWebpackerにより、RailsによるDB読み取り以前に出力されてしまいます。
そのため、動的にDBデータをJavaScriptに読み込ませるにはviewの```scriptタグ```内に記述する必要があります！！！
　
↓```erbタグ```でcontrollerで定義したグローバル変数を呼び出しています↓

```html:任意のview（今回はbeats#show）
<!-- 任意のviewの記述 -->

<script>

  //記述は一部省略
　　　var ASSETS = {
  sound: {
    music: "<%= @beat.music.url %>",
  },
  json: {
    beatmap: "<%= @beat.notes.url %>"
  },
  image: {
    'sprite': "<%= @beat.gif.url %>",
    'thumbnail': "<%= @beat.thumbnail.url %>",
  },
</script>
```


<br>

## 最後に
RailsでJavaScriptの動的読み込みに関する記事がなかったので執筆しました！
この記事が多くの悩める方に届くことを願っています🌱
SwiftUIのViewでNotificationCenterを監視する

# ViewでNotificationを受け取る方法です。

# サクッと通知したい。タイミングに注意

Notification便利ですよね。SwiftUIで使うには以下です。
Viewが生成されるより前にpostされると、受信できないので注意です。

# 方法

### post 発信する側

```swift
class Greetings:NSObject {
    override init() {
        super.init()
            NotificationCenter.default.post(name: NSNotification.greeting, object: self, userInfo: ["greeting":"Ciao mondo!"])
    }
}

extension NSNotification {
    static let greeting = NSNotification.Name.init("greeting")
}
```

### observe　受信する側

```swift
struct ContentView: View {
    @State var greeting:String = "Hello, world!"
    var model = Greeting()
    var body: some View {
        Text(greeting)
            .padding()
            .onReceive(NotificationCenter.default.publisher(for: NSNotification.greeting)) { notification in
                if let greeting = notification.userInfo?["greeting"] as? String {
                    self.greeting = greeting
            }
        }         
    }
}
```

これだと、Viewに通知が反映されません。
なぜかというと、Viewより先にNotification元のクラスが作られて、Viewでオブザーブするよりも先にpostされているからです。
Timerで解消しました。

```swift
class Greetings:NSObject {
    override init() {
        super.init()
            Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
                NotificationCenter.default.post(name: NSNotification.greeting, object: self, userInfo: ["greeting":"Ciao mondo!"])
            }
    }
}
```

Timerを止めたい場合は、受信側のViewからクラスに通知する必要があるでしょう。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)

[相棒](https://twitter.com/oka_yuuji)

[note](https://note.com/oka_yuuji)
Railsでphina.jsの動的読み込み

## 実現したいこと
バックエンド（Rails)から保存したDB内のデータを呼び出して、動的にフロント（phina.js）に入れて、ゲームをプレイできるようにする✅

[phina.jsとは](https://phinajs.com/)：ゲームを簡単に作ることのできるJavaScriptのライブラリ

<br>

## 開発環境
Rails６系
Ruby３系
phina.js 0.2.3（CDN）
アプリ：[Muscle Beat](https://www.muscle-beat.com)（スマホ専用筋トレ系音ゲー）
[GitHub](https://github.com/jibiking/muscle_beat)
テーブル（例）↓
[![Image from Gyazo](https://i.gyazo.com/a0eef96b76e54d3df43a1c5255f5566e.jpg)](https://gyazo.com/a0eef96b76e54d3df43a1c5255f5566e)

<br>

## 1. viewでphina.jsの環境構築
ゲームプレイ画面を作成するviewにCDNでphina.jsを読み込ませます。
```html:任意のview（例：beats#show）
<script src="https://cdn.jsdelivr.net/gh/phinajs/phina.js@v0.2.3/build/phina.js"></script>
```
参考：[phina.jsの環境を構築する](https://qiita.com/alkn203/items/ffb4c1a94c781536d5e6)

<br>


## 2. viewにゲーム用の記述を行う。
1でphina.jsを読み込んだviewの```scriptタグ```内に作成するゲームの記述を行います。
[実際のコード](https://github.com/jibiking/muscle_beat/blob/main/app/views/beats/show.html.erb)
```html:任意のview（例：beats#show）
<script src="https://cdn.jsdelivr.net/gh/phinajs/phina.js@v0.2.3/build/phina.js"></script>

<script>

  //ここにphina.jsを用いたゲーム用の記述をする

</script>
```

Q. なぜJavaScriptの記述をview内にするのか？
<font color="DeepPink">A. 動的にDBのデータを読み取るためです！</font>
たしかにRailsのJavaScriptの記述は```app/javascript/packs```以下にするのが通常です。
しかし上記pack以下のJavaScriptファイルはRailsのWebpackerにより、RailsによるDB読み取り以前に出力されてしまいます。
そのため、動的にDBデータをJavaScriptに読み込ませるにはviewの```scriptタグ```内に記述する必要があります！！！

<br>

## 3. erbタグでデータの動的読み込み
```html:任意のview（今回はbeats#show）
<script src="https://cdn.jsdelivr.net/gh/phinajs/phina.js@v0.2.3/build/phina.js"></script>

<script>

  //ゲームの記述は省略
　　　var ASSETS = {
  sound: {
    music: "<%= @beat.music.url %>",
  },
  json: {
    beatmap: "<%= @beat.notes.url %>"
  },
  image: {
    'sprite': "<%= @beat.gif.url %>",
    'thumbnail': "<%= @beat.thumbnail.url %>",
  },
</script>
```
ゲームの記述内に```erbタグ```を入れてDBのデータを動的に読み込ませます。

controllerは```rails g scaffold ~~~```で作成したままでも大丈夫です。
```ruby:任意のcontroller（今回はbeats_controller）
class BeatsController < ApplicationController
  before_action :set_beat, only: %i[show edit update destroy]

  # 該当箇所以外は省略

  def show; end

  private

  def set_beat
    @beat = Beat.find(params[:id])
  end
end
```

<br>

## 4. データを入れる
ここまでできたら、任意のフォームからerbタグで出力するよう設定したデータを入れればphina.jsが動的に値を読み取ってくれて、ゲームが動きます！

私の場合は音ゲーに必要な、MP3や譜面などの計９つのデータを動的に読み込んでます。
```rails console```や```curlコマンド```でデータを入れるよりも、```formタグ```を使って専用の入力フォームを作ってしまった方がその後の管理性が良くなるのでおすすめです✅


<br>

## 最後に
phina.jsとRailsを連携させる記事がなかったので執筆しました！
この記事が多くの悩める方に届くことを願っています🌱
React全然わからんので経過を書いていくとこにした

## 2022年3月13日

https://developer.mozilla.org/ja/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_getting_started

上記記事をよみながらで開発スタート
下記コマンドを打つ。
```
npm start
```

最初はできた！
で、満足して次の日。ですよ。

同じコマンドを打つとエラーが出てしまう。
```
Error: ENOSPC: System limit for number of file watchers reached,
```
的な。

### ちょっと何言ってるかわかんないですけど…

でなくて、ログを読むと監視できるプロセスが上限に達しているらしい。
（ログを読みましょう）

じゃあ、という事で、npmプロセスだから、、、nodeのプロセスを調べていくつかkillすれば
いいのかな？

という事でググると、
http://katzplus.com/centos-6/apache/%E7%8F%BE%E5%9C%A8%E3%81%AE%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E6%95%B0%E3%82%92%E8%AA%BF%E3%81%B9%E3%82%8B/
こういう感じの記事が見つかったので、
```
ps aux | grep node
```
で調べると、nodeのプロセスがなんか多い。

ケツの方からプロセスをkill していった。
```
kill -9 [プロセス番号]
```
で、もう一回
```
npm start
```
で成功！

ふうむ。
でもよくわからんな、というのが1点。

https://honmushi.com/2020/02/26/linux-sys-limit-file-num/

この記事を参考に、
```
cat /proc/sys/fs/inotify/max_user_watches
```
で調べると、プロセス数は8192いける。
（ちなみに開発環境はAWSのEC2上）

しかし、
```
ps aux | wc -l
```
を打つと、111とか。
うーん。
全然上限に達してない。

もしかしたら
```
npm start
```
を実行すると、localhost:3000を使用するプロセスが生成されるけど、
それがダブってた、というだけの話かもしれん。

というところで力尽きました。
### お後がHere we go!
という事で、今日はおしまいです。



閑話休題、開発環境はAWS上のEC2なんだけど、
localhost:3000が自分のPCに帰ってきてすごいな（便利だな）
と思った。（できんと思ってました）

## 2022年3月14日

上記の記事通りに編集してみたよ
```
import logo from './logo.svg';
import './App.css';

function App() {
  const subject = "React";
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Hello {subject}!
        </p>
      </header>
    </div>
  );
}

export default App;
```
ここで特に新しいことはありません。

お後がHere We Go!
という事で本日はここまで。
些細だけど進んだ記録を残しておきます。

## 2022年3月25日

ここまで、AWS上で開発してたんだけど、やたら料金がかかっていることが発覚。
月5000円は高いので、開発環境のお引っ越し作業にいそしむことに…

## 2022年3月28日

春の嵐にやられて、体調が劇的に悪化。しばらくお休みしていました。
AWSの開発環境に合ったソースを移行できたので、（rsyncコマンドをし使用）AWSを解約。
自前のVagrantで立ち上げたVirtualBox内で開発することに。

まず、npmが入ってないので、入れましょう。
という事で入れようとしたが、ミラーリストが無いと言われてしまった。
続きはまた今度。
webdriver-managerで更新失敗

webdriver-managerで躓いたのでメモ。


## 問題 
```
====== WebDriver manager ======
Could not get version for google-chrome with the command:  powershell "$ErrorActionPreference='silentlycontinue' ; (Get-Item -Path "$env:PROGRAMFILES\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion ; if (-not $? -or $? -match $error) { (Get-Item -Path "$env:PROGRAMFILES(x86)\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion } if (-not $? -or $? -match $error) { (Get-Item -Path "$env:LOCALAPPDATA\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion } if (-not $? -or $? -match $error) { reg query "HKCU\SOFTWARE\Google\Chrome\BLBeacon" /v version } if (-not $? -or $? -match $error) { reg query "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome" /v version }"
Current google-chrome version is UNKNOWN
Get LATEST chromedriver version for UNKNOWN google-chrome
Trying to download new driver from https://chromedriver.storage.googleapis.com/99.0.4844.51/chromedriver_win32.zip
```


- PowerShellの実行結果
```
> (Get-Item -Path "$env:PROGRAMFILES\Google\Chrome\Application\chrome.exe").VersionInfo.FileVersion ;
Get-Item : パス 'C:\Program Files\Google\Chrome\Application\chrome.exe' が存在しないため検出できません。
```

## 解決策

- webdriver-managerのバージョンを3.5.3から3.2.2へダウングレード



https://stackoverflow.com/questions/71223000/could-not-get-version-for-google-chrome-with-the-command-powershell-erroracti
https://github.com/SergeyPirogov/webdriver_manager/pull/324#issuecomment-1054010544
バージョンの取得方法が変わったようだ。
[Mac版]VSCodeでEmacsキーバインドを使う

# はじめに
Web開発の基礎を学ぶことを思い立ってMacを使い始めたのですが、「control」キーと組み合わせたショートカットを使うと、キーボードから手を離さずテキスト編集ができて便利ですね。(^^)
Emacsのキーバインドと似てるようなので、VSCodeにEmacsキーバインドを入れることで、学習コストを節約したいと思います。
あと、よく使うショートカットを備忘録としてまとめておきました。

# Awesome Emacs Keymapをインストールする
VSCodeでEmacsキーバインド用のエクステンションを検索するとたくさん出てきます。どれがいいか分からなかったので、「[VSCodeのEmacsキーバインド拡張まとめ](https://qiita.com/kurun_pan/items/507517c3f569b080abe2)」を参考にさせていただき、Awesome Emacs Keymapをインストールすることにしました。

# 注意事項
* Emacsでテキストをコピペするには、選択範囲の開始点を指定する必要があるのですが、そのキーバインドが「Ctrl+Space」になっています。これは、MacのSpotlightを呼び出すとても便利なショートカットでもあります。Emacsのキーバインドを優先される場合は、システム環境設定 > Spotlight で[キーボードショートカット]を開き、[Spotlight検索を表示]のチェックを外してください。
* Emacsでコピペするときに使うのは、クリップボードではなく「kill ring」というものらしいのですが、以下の備忘録ではそのあたりは区別できていません。VSCodeでEmacsキーバインドを使っていく中で支障が出てきたら、見直したいと思います。

# ショートカット
##### カーソル移動（行単位）
|やりたいこと|キーバインド|英語の説明|
|:---:|:---:|:---|
|１文字右|Ctrl+F|Move one character forward|
|１文字左|Ctrl+B|Move one character backward|
|１行上|Ctrl+P|Move up one line||１行下|Ctrl+N|Move down one line|
|行の先頭|Ctrl+A|Move to the beginning of the line or paragraph|
|行の末尾|Ctrl+E|Move to the end of a line or paragraph|
##### カーソル移動（画面単位）
|やりたいこと|キーバインド|英語の説明|
|:---:|:---:|:---|
|１ページ上|Option+V|Scroll up by one screen unit|
|１ページ下|Ctrl+V|Scroll down by one screen unit|
|水平方向に画面中央へ|Ctrl+L|Center the cursor or selection in the visible area|
##### 削除
|やりたいこと|キーバインド|英語の説明|
|:---:|:---:|:---|
|左の文字|Ctrl+H|Delete the character to the left of the insertion point|
|右の文字|Ctrl+D|Delete the character to the right of the insertion point|
|行末まで|Ctrl+K|Delete the text between the insertion point and the end of the line or paragraph, and copy it to the Clipboard|
##### 範囲選択
|やりたいこと|キーバインド|英語の説明|
|:---:|:---:|:---|
|開始点の設定|Ctrl+Space|Set the beginning point|
|終了点の設定（切取り）|Ctrl+W|Cut the selected item and copy it to the Clipboard|
|終了点の設定（コピー）|Option+W|Copy the selected item to the Clipboard|
##### 貼り付け
|やりたいこと|キーバインド|英語の説明|
|:---:|:---:|:---|
|貼り付け|Ctrl+Y|Paste the contents of the Clipboard into the insertion point|
##### UNDO
|やりたいこと|キーバインド|英語の説明|
|:---:|:---:|:---|
|UNDO|Ctrl+X, U|Undo the previous command|
100日でSQLの達人になる@LeetCode! Day41 <WITH句ですっきり>

## 1077. Project Employees III （問題レベル: Medium）要課金
今日の問題はこれ。
プロジェクト毎に最も経験数が長い職員IDをリストアップするという問題。

試行錯誤したが何とか自力で解けました。
今回の問題は、到達すべき目的はシンプルなのですが、テーブルが複数に分かれているためになかなかクエリが書きづらい。
そこで今まであまり使ってこなかった`WITH`句でもともとテーブルが一つにまとまっていたら・・・と考えてみるとスッキリ解けました。

```:SQL
WITH CTE AS (
SELECT p.project_id, p.employee_id, e.experience_years
FROM project p
LEFT JOIN employee e
ON p.employee_id=e.employee_id)
-- ここまでで情報が別れて存在していたのが一つのテーブルにまとまった理想のテーブルが出来ました
-- 後は割とシンプル

SELECT a.project_id, a.employee_id
FROM CTE a
JOIN 
(SELECT project_id, MAX(experience_years) AS max
FROM CTE
GROUP BY project_id) b
ON a.project_id=b.project_id AND a.experience_years=b.max
```

`MYSQL`だと複数条件で`IN`句が使える（実際`Discuss`内の`MYSQL`の解答例ではこれが多かった）のですが`MS SQL Server`では一つしか条件が使えないためにこの解法を選択しました。

今日のポイントは複数テーブルに情報が別れている場合は`WITH`句でまとめてスッキリ！としました。
中級問題も残すところ後3問。


* [LeetCode](https://leetcode.com/)の問題は、`MS SQL Server`で解いています。
JavaでAtCoder黄色になりました

青色になった時の記事は[こちら](https://qiita.com/sounansya/items/bd0c5d3e2fdb9256c953)

遭難者です。[ABC243](https://atcoder.jp/contests/abc243)でAtCoder黄色になったので記事を書くことにしました。
![スクリーンショット 2022-03-12 23.55.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/5e80cec3-ba98-629b-106a-3cc37ed5e107.png)
気が向いたら精進するスタンスを取っているのでレートのグラフがかなり歪です。

# 自己紹介

現在高専2年の、情報系の学生です。
数学が好きです。文字列が苦手です。

# 精進量

![スクリーンショット 2022-03-13 0.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/d7a47508-7cbb-1d4a-9bc7-794fec60f0a3.png)
![スクリーンショット 2022-03-13 0.01.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/51307bf6-7303-034c-84e0-4b9dd4d8da70.png)
![スクリーンショット 2022-03-13 0.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/56d6abdd-2b90-a587-1bff-5ab9c57c20da.png)
画像の通りです。気が向いた時に沢山解いています。

# 習得したアルゴリズム
青色から黄色に上がるまでに習得したアルゴリズムを並べていきます。

- 全方位木dp
全方位って言う割には根を頂点1で固定した方が分かりやすいように感じました。
まだコンテスト本番で実装したことは無いです。
かつっぱさんの[こちら](https://www.youtube.com/watch?v=zaCz4zOnwY8)の動画で履修しました。

- Mo's algorithm
クエリをソートして順番に見てくだけなので非常にシンプルでした。
まだコンテスト本番で実装したことは無いです。
ネット上の記事では理解できなかったのですが、友人に具体的なケースで教えてもらい理解しました。

過去に解いた問題を遡って見ましたが、青色から黄色になる過程で習得したアルゴリズムはこの2つのみでした。青色から黄色になるには知識よりも考察力の方が重要だと考えています。実際、私が最近のコンテストで解けた青diff・黄diffの問題は考察がメインで実装は比較的簡単な問題がほとんどです(例:[この問題](https://atcoder.jp/contests/arc131/tasks/arc131_e)や[この問題](https://atcoder.jp/contests/abc243/tasks/abc243_g)、ネタバレに注意してください)。なのでもし現在青色で黄色になりたい！という人がいたら、過去問を大量に解くのが近道だと思います。特にDPの遷移の式の導出等は完全に慣れだと思うので、手を動かし、頭を使って考えるとすぐに出来るようになると思います。

# Javaを使ってみて思うこと

- 遅い
ループ等は速いです。しかし、ArrayListやHashMapといったラッパークラスを必要とするものがかなり遅いです。
この遅さは例えば [ABC242-F Skate](https://atcoder.jp/contests/abc241/tasks/abc241_f)のような問題で露骨に差が出ます。
![スクリーンショット 2022-03-13 1.37.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/4dad0d3b-7228-4feb-df51-8509bda5eadf.png)
![スクリーンショット 2022-03-13 1.36.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/de7a2485-c19a-b3c3-ded4-c462dbae05e3.png)
![スクリーンショット 2022-03-13 1.36.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227863/742f110e-c706-0609-c72c-4afb3ac3a7bb.png)
上3枚の画像はC++、Python3(PyPy3)、Javaの提出のうちACとなったものを実行時間順に並べたものです。Javaが特に遅いのが一目瞭然です。これが原因で苦しい定数倍高速化を要求されるケースも少なくないです。

- ラムダ式が便利
配列に値をセットしたい時やソートの方法を指定する時に非常に便利です。ルールが結構複雑ですが、慣れれば非常に強力な武器になります。
例えば [ABC225E-フ](https://atcoder.jp/contests/abc225/tasks/abc225_e)で入力を受け取ってからソートするまでは以下のように書くことができます:
```Java
var a = new long[sc.nextInt()][];
Arrays.setAll(a, i -> new long[] { sc.nextLong(), sc.nextLong() });
Arrays.sort(a, (i, j) -> Long.compare(i[0] * (j[1] - 1), j[0] * (i[1] - 1)));
```
([ACコード](https://atcoder.jp/contests/abc225/submissions/30087830))
ソートもそうですが、特に `Arrays.setAll`は非常に強力です。Javaを使っていて良かったと思う数少ない場面の1つです。

# 今後の目標
- 海外のコンテストに挑戦する
英語を読むことに強い拒否感があり、AtCoderやyukicoder、TechFULといった国内のコンテストにしか出場できていません。これを克服してより多くの問題を解こうと思います。
- パソコン甲子園で良い成績を取る
情報オリンピックもパソコン甲子園も今年度はどちらもオンライン開催となり、交流の機会が減ってしまいました。来年度こそはパソコン甲子園で会津に行きたいです。

# 終わりに
競技プログラミングを始めた当初は緑色になるのが目標だったのですが、まさか黄色になれるとは思いませんでした。今後も競技プログラミングを頑張っていきます。
ここまで読んでくださりありがとうございました。
ゼロから始める株取引！Pythonで株価トレンド予測（Tips：特徴量重要度を表形式で表示）

# はじめに

過去2本立ての記事で、「**東証1部の銘柄コードに対して翌日の株価トレンド（上昇／下降）を予測する**」を紹介しました。

1. [モデル作成に使うCSVファイルの準備](https://qiita.com/Blaster36/items/9bdf777f35fda3335f6a)
2. [CSVファイルをInputにした予測モデルの作成](https://qiita.com/Blaster36/items/00c1f95f173b63ab3c42)

本稿は、そのこぼれ話のTips紹介です。
**lightgbm.plot_importance**[^1]を利用して特徴量重要度を可視化していましたが、**図だと特徴量名や重要度スコアが正直見づらい**。。。
というわけで、自身の備忘を兼ねて、表データとして特徴量重要度の情報を確認する方法を紹介します。

:::note info
時間のない方は、Notebookだけパパっと参照あれ。
結論を言うと、**lightgbm.Booster.trees_to_dataframe**[^2]を利用します。
:::

## 本稿で紹介すること

- 特徴量重要度の確認（可視化）

## 本稿で紹介しないこと

- データの収集および整形
- 特徴量設計
- 予測モデルの作成（含むハイパーパラメータのチューニング）
- 予測精度の確認

# Notebook（Pythonコード）

githubで公開しました。

https://github.com/Blaster36/Script/blob/main/StockPrice/predStockPrice-LightGBM2-2.ipynb

# ポイントを簡単に説明

ざっくり言うと、以下3ステップです。
1. 決定木の情報をDataFrame形式で取得
2. DataFrameを集計して特徴量重要度を算出
3. DataFrameを重要度スコアでソートして表示

# 1. 決定木の情報をDataFrame形式で取得

**lightgbm.Booster.trees_to_dataframe**[^2]を利用します。
下記CodeではCSVファイルにそのまま一旦出力していますが、CSVファイルへの出力は任意です。

```python
import csv
# 決定木をDataFrameに変換
clf.booster_.trees_to_dataframe().to_csv('predStockPrice-LightGBM-dicisiontrees.csv', encoding='utf-8', index=False, header=True, quotechar='"', sep=',', quoting=csv.QUOTE_ALL)
df_tree = pd.read_csv('predStockPrice-LightGBM-dicisiontrees.csv')
```

中身を確認すると、こんな感じ。
```python
df_tree.head(10)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/892351f5-9965-78bd-6146-6c74da099a65.png)

# 2. DataFrameを集計して特徴量重要度を算出

DataFrameは決定木を形成する情報が全て詰まっていますが、特徴量重要度に関係するのはNode（条件分岐式）です。
Nodeの情報を対象に、集計関数で特徴量重要度を算出します。

```python
# 特徴量重要の集計に不要なLeafを除去する
df_tree = df_tree[df_tree['split_feature'].notnull()]

# 特徴量重要を集計する
#df_tree.groupby('split_feature').agg({'split_gain':'sum', 'tree_index':'count'}).sort_values('split_gain', ascending=False)
df_tree = df_tree.groupby('split_feature').agg({'split_gain':'sum', 'tree_index':'count'})
df_tree.rename(columns={'split_gain':'gain', 'tree_index':'split'}, inplace=True)
```

中身を確認すると、こんな感じ。

```python
df_tree.head(10)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/c62257a2-ee6e-300f-15ad-9197619cb480.png)

# 3. DataFrameを重要度スコアでソートして表示

あとは、表示するだけです。
importance_type='**split**'ないしimportance_type='**gain**'に相当する列をKeyとして、降順にソートして表示します。

```python
# 特徴量重要度（importance_type='split'）を降順で表示する
df_tree.sort_values('split', ascending=False)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/6c8ea3ba-3f68-78b6-08c6-dde2f149951d.png)

```python
# 特徴量重要度（importance_type='gain'）を降順で表示する
df_tree.sort_values('gain', ascending=False)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685193/b75dd212-bbc4-c8a3-8776-40d932844c69.png)

# まとめ

LightGBMで作った予測モデルの特徴量重要度を表形式で表示する方法をご紹介。
さらに正規化するともっと見やすくなるかもしれませんが、Code紹介は割愛します。

[^1]: lightgbm.plot_importance | https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.plot_importance.html
[^2]: lightgbm.Booster.trees_to_dataframe | https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.Booster.html#lightgbm.Booster.trees_to_dataframe
ERESOLVE unable to resolve dependency treeでパッケージがインストールできない場合の対応方法

# 概要

「依存関係がおかしいからインストールできねぇよ」って怒られた場合の対応方法をまとめる
なお、パッケージ管理ツールは`npm`を利用しています

- 解決に至った参考資料

https://stackoverflow.com/questions/64936044/fix-the-upstream-dependency-conflict-installing-npm-packages



```bash
npm i --save @nestjs/websockets @nestjs/platform-socket.io
```

https://docs.nestjs.com/websockets/gateways

```bash
npm notice 
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: websocket-server@0.0.1
npm ERR! Found: @nestjs/common@7.6.18
npm ERR! node_modules/@nestjs/common
npm ERR!   @nestjs/common@"^7.6.15" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @nestjs/common@"^8.0.0" from @nestjs/websockets@8.4.0
npm ERR! node_modules/@nestjs/websockets
npm ERR!   @nestjs/websockets@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
```

# 解決方法

`--legacy-peer-deps`オプションを追加してインストールします

```bash
npm install --legacy-peer-deps @nestjs/websockets @nestjs/platform-socket.io
```

# 原因

`npm v7`にバージョンアップした際に`peerDependencies`をデフォルトでインストールするようになったことで、バージョンの衝突によるエラーが発生するようになったみたい

今回追加した`--legacy-peer-deps`オプションは`peerDependency`の自動インストールを回避する方法として 導入されたもので、`peer deps`を無視してインストールさせます

なお、今回参考にしたサイトでは`--save`オプションも指定してますが、`npm v5`以降はデフォルトで`save`してくれるので割愛してます

https://qiita.com/havveFn/items/c5beda8572aa8c1e6be6

https://stackoverflow.com/questions/66239691/what-does-npm-install-legacy-peer-deps-do-exactly-when-is-it-recommended-wh

> One way of thinking of this flag is that it isn't doing something new; rather it's telling NPM not to do something new, since NPM v7 now installs peerDependencies by default.
In many cases, this is leading to version conflicts, which will break the installation process.
The --legacy-peer-deps flag was introduced with v7 as a way to bypass peerDependency auto-installation; it tells NPM to ignore peer deps and proceed with the installation anyway. This is how things used to be with NPM v4 thru v6.
「Rails」urlとpathの違いを初心者向けに解説

# _urlと_pathの違いについて

簡単に申し上げるとurlは絶対パスでpathは相対パスである。

### urlについて解説

_urlの形は絶対パスである。例えば、　
```new_user_url```という書き方は ```http://localhost:3000/users/new```と書くのと同意である。
リダイレクトではHTTPの性質上、完全なURLが求められるのでredirect_toメソッドの引数はURLで指定するべきである。
逆に言えばredirect_toメソッドの引数でしか_urlという書き方は使われない。
### pathについて解説


_pathの形は相対パスである。
```new_user_path``` という書き方は ```/users/new```と書くのと同意である。
_pathという形は基本的にredirect_to以外で使うと覚えておけば良い。
例えばform_withやlink_toなど。

## 「```redirect_to @post```」という書き方（上級者向け）


```redirect_to　post_url(@post)```という書き方を```redirect_to post_url```という書き方に省略できる。また```redirect_to post_url```を```redirect_to @post```という書き方に省略できる。

言い換えると```redirect_to　post_url(@post)```という書き方は```redirect_to @post```という書き方に省略できる！
```
redirect_to　post_url(@post)  =>  redirect_to @post
```

## まとめ
```
絶対パス
new_user_url  =>  http://localhost:3000/users/new

相対パス
new_user_path  =>  /users/new

_urlでもなく_pathでもなく変数で指定する方法（上級者向け）
redirect_to　post_url(@post)  =>  redirect_to @post
```

以上です！分からないことや気になったことがあればお気軽に言ってください！
テストにおける種類と考え方

# テストとは？
要件や仕様書の内容と、同じ処理がされているかを確認する。
仕様から漏れたプログラムのミスを見つけることが目的である。

ソフトウェアは常に変更されていくので、テスト当時にはバグが見つからなくても、後の変更されたタイミングで見つかる可能性がある。
つまり常にテストすることが大切。

## テスト設計
テストをするときには、テスト設計を行う。

* 何のためにテストをするのか
* 何をテストするのか
* どういったテストをするのか
* どんな値を入れるのか
* 欲しい値が取れるか
  * 欲しい値とは何か
* どのような期待結果を求めるのか

などを踏まえた上でテスト仕様書を作成する。


## テストの種類
大きく分けて4種類のテストがある。

* 単体テスト
* 結合テスト
* 総合（システム）テスト
* 受入テスト

### 単体テスト
ざっくり言うと、作成したプログラムに対してのテスト。
クラス、メソッド、処理など作成したプログラム

### 結合テスト
プログラムがまとまり「機能」が作られる。
この機能を確認するテストのこと。
さらに機能と機能の連結確認のテストも行う。

例：ログインした状態で、YouTubeのトップ画面を表示させると、ユーザごとのおすすめ一覧が表示される

### 総合（システム）テスト
機能がまとまり「システム」としての動作確認のこと。
リリースできるか判断するテストに相当する。

* 性能確認
  * アクセスして画面に何秒で表示されるのか
  * 登録処理が何秒で終わるのか　など
* 負荷確認
  * 1秒間に1000回などのリクエストを送ったときに、アプリが落ちずに処理できているのか　など
* セキュリティ
  * 社内のセキュリティ専門チームが対応することが多い
* ユーザが使いやすいのか（UX）

### 受入テスト
納品されたシステムをユーザが確認するテストのこと。
機能要件、使い勝手、運用などを確認する。

## ホワイトボックステスト
システムの機能や内容を把握している状態でのテストのこと。

### カバレッジ（網羅率）
プログラムに対して、どこまでテストが実施され網羅されたのか割合を示す。

* 命令網羅
* 分岐網羅
* 条件網羅

仮にこのようなプログラムがあった場合の各網羅を記載する。

```java:Coverageクラス
public class Coverage {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in); // 標準入力

		System.out.println("Movie or Game");
		System.out.println("↓ 入力待ち");
		String str = scan.nextLine(); // 1行分の入力を取得する
		System.out.println(str + " を選択");

		System.out.println("**********");
		System.out.println("所持金は?");
		System.out.println("↓ 入力待ち");
		int money = scan.nextInt(); // 数値の入力を取得する
		System.out.println("所持金は " + money);

		System.out.println("**********");
		System.out.println("今日は");

		if (str.equals("Movie")) {
			if (money >= 1900) {
				System.out.println("映画を見る");
			} else {
				System.out.println("ゲームする");
			}
		} else if (str.equals("Game")) {
			System.out.println("ゲームする");
		} else {
			System.out.println("入力ミスです");
		}
	}
}
```
```:条件
「Movie」を選択かつ、「所持金が1900円以上」
→ 「映画を見る」　が表示される

「Movie」を選択かつ、「所持金が1900円より少ない」
→ 「ゲームする」　が表示される

「Game」を選択かつ、「所持金が1900円以上」
→ 「ゲームする」　が表示される

「Game」を選択かつ、「所持金が1900円より少ない」
→ 「ゲームする」　が表示される
```
```:分岐
「Movie」を選択かつ、「所持金が1900円以上」
  |
  |---No 「ゲームする」
  |
  Yes 「映画を見る」
```

### 命令網羅
プログラムが実行できているかを確認する。
例の場合、```「Movie」```を選択し、「所持金が```1900円以上```」なら```「映画を見る」```が表示されることを検証する。
全てが網羅できるわけではない。

### 分岐網羅
YesもしくはNoの分岐処理が実行されたかを確認する。
分岐を網羅しているだけなので、```「Game」を選択かつ、「所持金が1900円以上」```など条件は、抜けている可能性がある。

### 条件網羅
各分岐の各条件を全て網羅して、実行されたかを確認する。
ただしテストケースが膨大になる可能性がある。

## ブラックボックステスト
要件や機能が実行できるかを確認するためのテストのこと。
プログラムの内容を見ずに、要件や仕様が実現されているかを確認する。

### 同値分割
入力した内容と出力された結果の組み合わせを確認する。

```:例
３つの入力フォームに、「１」「１」「１」と入力
→ 結果：「正三角形」と表示される

３つの入力フォームに、「2」「2」「1」と入力
→ 結果：「二等辺三角形」と表示される
```

### 境界値分析
値を入力するときに、「有効な値」と「無効な値」の境界でテストすること。

```:例
入力フォームに、「0〜100」の値が入力されると、「OK！」と表示させる機能がある
```
この場合「-1」「0」「1」「２」「98」「99」「100」「101」の値でテストすることで、全ての値で確認することなく、効率的に検証することができる。
s3 のバケットを全公開にする

AWS の勉強を始めたので、勉強した全てを細かくメモしていくことを決意

# s3 のバケットを全公開にする

## 全公開したい対象のバケットを選択

![s3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/64254da7-a507-a382-47b5-20cf7f46c5a6.png)

## アクセス許可タブをクリック

![s3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/7f25b15a-bc9a-6f59-4589-976cdba1167f.png)


## バケットポリシー を編集

「対象バケット名」に公開したいバケット名を入力する

```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "AddPerm",
			"Effect": "Allow",
			"Principal": "*",
			"Action": "s3:GetObject", 
			"Resource": "arn:aws:s3:::対象バケット名/*"
		}
	]
}
```



<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NR3DM2YWBD"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-NR3DM2YWBD');
</script>
100日でSQLの達人になる@LeetCode! Day40 <要復習：分析関数COUNT() OVER()句内でDISTINCTは使えない!?>

## 550. Game Play Analysis IV （問題レベル: Medium）要課金
今日の問題はこれ。
全ユーザーの中で初日から2日連続プレイした人の割合を計算するという問題。

最終的に提出した回答はこちら。
```:SQL
SELECT
    ROUND(COUNT(b.player_id)*1.0/COUNT(DISTINCT a.player_id)*1.0,2) AS fraction
FROM 
    (SELECT player_id, MIN(event_date) AS fday FROM activity GROUP BY player_id) a
LEFT JOIN
    activity b
ON DATEDIFF(day, a.fday, b.event_date)=1 AND a.player_id=b.player_id
```
ロジックはそれほど難しくないが、初日の取得、重複したIDの処理など細かい処理が重なるためヒント無しでは出来ませんでした。

躓いたのは、
```:SQL
SELECT a.player_id, COUNT(DISTINCT b.player_id) OVER() AS b
FROM activity a
LEFT JOIN
activity b
ON a.player_id=b.player_id
```
このように分析関数では`COUNT() OVER()`句内で`DISTINCT`は使えない!?ようです。
自信が無いのですが、調べた限りは使え無さそう。この辺りまた復習します！

今日のポイントは`COUNT() OVER()`句内で`DISTINCT`は使えない!?としました。

* [LeetCode](https://leetcode.com/)の問題は、`MS SQL Server`で解いています。
さっきまで出来ていたgit pushが急にできなくなる

## git pushがある日突然できなくなる
git pushができなくなる要因はいくつかあると思います。Githubの認証が変わったタイミングとか、commitの内容が多いとか。	
今回自分は、**昨日までできていた`git push`が急にできなくなりました。**
コマンド打ってもずっとこのままで動かない、、、
```
$ git push
```

## 原因
自分の場合の原因は、**お店のwifiを使っていること**でした。
お店のwifiなどを使っている場合は他のネットワークに繋ぎ直しましょう。
自分はスマホのテザリングに繋ぎ直したら実行できるようになりました。
Bitbucket に push できなくなった件

# Bitbucket Push failed
AndroidStudio よりBitbucketへpushしたときに、下記エラーでpushできなくなっていた。
```
Invocation failed Unexpected end of file from server
java.lang.RuntimeException: Invocation failed Unexpected end of file from server
・・・
・・・
fatal: could not read Password for 'https://username@bitbucket.org': Device not configured
```

# Atlassian ユーザー名/パスワード認証を非サポート
https://bitbucket.org/blog/deprecating-atlassian-account-password-for-git-and-bitbucket-api-activity
> Starting Mar 1, 2022, Bitbucket users will no longer be able to use their Atlassian account password to interact with Bitbucket via Git over https and the Bitbucket API. Users will need to start using Bitbucket app passwords for Git commands, scripts, and integrating tools.

いつの間にかユーザー名とパスワード認証が非サポートとなっていた模様。メールとかでアナウンス来てたっけ？見落としただけ？

# 対応方法
アプリパスワードを設定する。
![スクリーンショット 2022-03-13 0.34.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663620/6e465c30-178c-90cb-bc59-977bf4bc6845.png)
設定すると、パスワードが発行されるので、その値でアクセスする。
一度しか表示されないため、メモして忘れないようにする。
アプリパスワードは何個でも発行できるようなので、最悪忘れたらもう一度作れば良さそう。

# AndroidStudioへの反映方法
AndroidStudio メニューから
Git > Manage Remotes 
`https://[username]:[発行したパスワード]@bitbucket.org/foo/bar.git`

やっとpushできました。
Gitもパスワード認証できなくなったし、その流れでしょう。
Git,Githubを使用してherokuへデプロイ

初めての投稿になります。
こちらは、私の備忘録として残しておきます。

# 前提
デプロイしたいアプリが作成済み、GitHubにアカウント登録済み、GitHubにリポジトリを作成済みで、ブランチを切っている状態で、今回はrailsで作成したアプリをデプロイしていきます。

# 実行の流れ
```!!!
まず、ステージングエリアにカレントディレクトリ以下のファイルをまとめて追加します
git add .

次に自分が変更したファイルをローカルリポジトリに保存します。
git commit -m "コミット名"

Githubにプッシュします。
git push --set-upstream origin ブランチ名

こちらでmasterブランチに変更します。
git checkout master

Githubにプッシュしたブランチ名を使用してマージを行います。
git merge ブランチ名

最後にherokuにデプロイします。
git push heroku
```
これでherokuへのデプロイが完了です。

# まとめ
初めての投稿なので、誤字脱字やご指摘等ありましたらコメントお願いします。
S3からcsvを取得して表示する。（Node.js）

今回はwebサイトのコンテンツ管理にcsvでやろうと思い、タイトルのサンプルコードをnode.jsで作成しました。

## ・前提
* s3の作成していること（コンソールから）
* s3にcsvをアップロードしていること（コンソールから）
* ローカルでawsのconfigurationが設定されていることの確認。
※参考：https://qiita.com/yuchaman/items/29458107c8ea7f2e0b42


## ・コード
```
const aws = require('aws-sdk');
const csvToJson = require('csvtojson');

module.exports = {

    // get csv from s3

    getDataFromS3: async () => {
        console.log("call getDataFromS3");

        const s3Client = new aws.S3({ apiVersion: '2006-03-01' });

        let params = {
            Bucket: 'bucketの名前を記載',
            Key: 'sample.csv',
        }

        const s3Stream = s3Client.getObject(params).createReadStream();

        const json = await csvToJson().fromStream(s3Stream);

        console.log(json);

    }

}
```

csvの中身

```
id,sampleNo,dataNo
2,sample2,data2
3,sample3,data3
4,sample4,data4
```

## ・ソースについて
* aws-sdk：awsに対してなにかする際には必要となるもの。
* csvtojson：取得したcsvのデータをjsonに変換するmodule。
* fromstreamを利用するとcsvの1行目を項目と認識してくれて、各値のkeyになります。

## ・s3に作成されたフォルダ以下のファイルを取得したい場合
上記の場合には、paramsのKeyの値を下記のように記載します。

```
let params = {
    Bucket: 'bucketの名前を記載',
    Key: 'sample_dir/sample.csv',
}
```

##　・最後に
サンプルコードには、errorハンドリングなどは入っていませんが、getObject()だったり、fromstreamについてはtry/catchでerrorハンドリングを追加した方がよいと思います。
awsのローカルデバッグでの必要になる認証の設定について

最近、会社のPCやら家のデスクトップやらノートやらで実装していて、タイトルについて何回も同じことを調べてのでこの際メモにしました。
aws関連のローカルでの実装（自分はnode.js）の際に、必ず必要になるのがローカルデバイスでの認証情報の設定。

## ・前提
*　AWS CLIがインストールされている
*　やりたいことができる権限を持ったアカウントを作成済み。（例えば、s3にファイルをアップロードしたければ、s3に対しての操作の権限があるアカウントを作成）
※secretKeyは必要になるので必ずメモしておきましょう。


## ・configurationの確認
まず/user/.aws/にconfigurationのファイルがあるかを確認する。

## ・ファイル自体がない場合(/.awsのディレクトリがない場合も同様)：
configurationのファイルがない場合には下記コマンドを実行
```
aws configure
```
※上記コマンドを実行するといろいろ聞かれますが、大事なのがaccessKeyとsecretKey。
secretKeyに関しては、アカウントを作成した際にコンソールで表示されるのでそれをメモしておくこと。
入力を完了するとconfigurationの設定も完了しているのでローカルでのデバッグもスムーズにいくと思います。

## ・ファイルがある場合
この場合には、前提でも記載しているアカウントの確認を行います。
アカウントが異なれば、上記コマンドを実行して、該当のアカウントのaccessKeyなどを入力してconfigurationの内容を変更しましょう。

## ・注意事項
configurationで設定するアカウントについてですが、ルートアカウントを使うのはやめましょう。awsでもその使い方は推奨されていません。
ルートアカウントは万が一流出してしまうと何から何まで好き放題にされてしまいます。

## ・参考

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-files.html

## ・最後に
ずいぶんと雑な記事になってしまいましたが、自分のメモなので参考程度に見ていただけるとよいかと。
参考にあげてるのはAWSの公式リンクなのでこちらを見てもよいかと思います。
ローカルでのアカウントの使い分けの方法とかも記載されています。
駆け出しエンジニアがシェル芸に入門してみた(1)

### 経緯

実は以前実務でシェルスクリプトを書く機会があったのですが、思ったほどすらすら書くことが出来ずに苦戦した思い出があります。そうこうしている間に「新しいLinuxの教科書-三宅英明-」と出会い、使う機会がなかったコマンドが多くあることを知り、また手をこまねいている内に今度はAWS CLIを使う必要が出てきました。いったい何時になったら自分はシェルスクリプトをキチンと扱えるレベルになるのか。。。そこで一度基礎からみっちりやってみようという気になった次第でございます。

### 挨拶
思ったより多くの方にご覧になって頂けたようで、感謝感激でございます。
実務で扱うようになった事をきっかけにシェル芸に入門して、今に至ります。
もしよろしければ、後続の記事と合わせて読んでいただけると幸いです。


### 自己紹介

・エンジニア歴半年未満の駆け出し。
・初めて書いたコマンドは /usr/bin/aws rds create-db-snapshot(なんとAWS CLIw)
・将来DevOps系の業務担当となるために日々此れ学習。

### 環境構築

今回は私が普段から愛用しているiTermを使っていきます。

起動してすぐ、下記のコマンドを実行していきます。

```
$ echo $SHELL
```

![スクリーンショット 2022-03-12 22.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280830/b5bc54bc-7ff5-fd06-a57e-e96bc7ea1b67.png)

これは今使っているshellを確認しています。教科書通り、難しいことは抜きにしてbashを使っていきましょう。

```
$ chsh
```

パスワードの入力を求められるため、ご自分のパスワードを入力してください。

![スクリーンショット 2022-03-12 22.46.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280830/ffce01b4-83e8-1e12-51cc-a048746153d3.png)

画像のようにShellの部分をzsh→bashに変更します。viの基本操作通り、esc→:wqを押してファイルの変更を保存。デフォルトでbashを使用するように設定します。これでターミナルからシェルスクリプトを実行していきます。
一度iTermを終了してから再度Shellを確認すると、

```
$ echo $SHELL
```

![スクリーンショット 2022-03-12 23.02.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280830/a765f159-b981-8e8a-007a-02351e0572ce.png)

bashに変更されていることが確認できます。次からは実際にシェルスクリプトを実行していきます。

(1)延々と時を止める。
```
$ sleep 10000
```

Ctrl + C　で止めてあげましょう。笑

(2)簡単な計算

```
$ echo '100+100'|bc
200
```
|bcは計算をせよという命令で、これが抜けると'100+100'は文字列として認識されます。

(3)ファイルへの出力

```
$ echo '100+100'|bc > addition
```

100 + 100の計算結果をadditionというファイルにリダイレクトします。

(4)今作ったいらないファイルを消す。

```
$ rm addition
```

(5)フォルダ(ディレクトリ)を作成する。

```
$ mkdir Charizard
```

(6)今作ったフォルダに移動する。

```
$ cd Charizard
```

(7)フォルダ(ディレクトリ)を削除する。

```
$ rmdir Charizard
```

(8)今いるディレクトリ(カレントディレクトリ)から前のディレクトリに戻る
<font color="red">**めっちゃ使います！**</font>

```
$ cd ..
```

(9)これまで使ったコマンドを確認する

```
$ history
1 sleep 10000
2 echo '100+100'|bc
3 echo '100+100'|bc > addition
4 rm addition
5 mkdir Charizard
6 cd Charizard
7 rmdir Charizard
8 cd ..
```
(10)カレントディレクトリのファイル一覧を表示する
<font color="blue">**(さっき消したからほんとは存在しないよ)**</font>

```
$ ls -l
addition
```
基本情報技術者試験対策 3日目

基本情報技術者試験対策　三日目
--
目的・前提
--
・文系大学生　
・ITパスポートは取得

今年の5月の基本情報技術者試験を合格する。
模擬試験を1日最低でも30問は解き、間違えた箇所をまとめて、記しておく。


間違えた箇所
--
1.静的関数
処理が終了した関数をメモリから消去せず，必要になったとき再び用いること

2.フィードバック制御
あらかじめ決められた順番ではなく，起きた事象に応じた処理を行うこと

3.再使用可能(リユーザブル)
プログラム終了後、再ロードせずに使用しても正しい結果を返すことができるプログラム

4.再帰的(リカーシブ)
実行中に自分自身を呼び出しても、正しい結果を返すことができるプログラムの性質。

5.再入可能(リエントラント)
複数のタスクから同時に呼び出されてもそれぞれに正しい結果を返すことができるプログラムの性質

6.再配置可能(リロケータブル）
プログラムをメモリ上のどこに配置しても実行できるようにした性質です。

7.リストの特徴（配列の場合）
・実際の要素数に関わらず、リストの最大長に対応した領域を確保し、実際には使用されない領域が発生する可能性がある
・配列リストは連続したメモリ領域に添字順に要素を格納するため、次の要素の位置を容易に計算する

リストの特徴（ポインタの場合）
・リストの要素を格納する領域の他に，次の要素を指し示すための領域が別途必要
・リストの中間要素を参照するには，リストの先頭から順番に要素をたどっていくので，要素数に比例した時間が必要

8.CMMI(Capability Maturity Model Integration)
統合能力成熟度モデルと呼ばれ、組織におけるプロセス改善をガイドするモデル
レベル1：初期
場当たり的で無秩序な組織として最も低い状態。
レベル2：管理された
プロジェクト管理のための基本的なプロセスが備わっている状態。
レベル3：定義された
組織内に標準化された一貫性のあるプロセスが定義されている状態。
レベル4：定量的に管理された
定量的な品質目標が存在し、プロセスはデータに基づき予測可能である状態。
レベル5：最適化している
継続的な改善プロセスが常に機能している状態。

9.線形解読法
平文と暗号文と鍵の関係を表す代数式を手掛かりにして鍵を見つけ出す

10.差分解読法
平文を一定量変化させたときの暗号文の変化から鍵を見つけ出す

11.関連鍵後継
平文の一部分の情報と，暗号文の一部分の情報との間の統計的相関を手掛かりにして鍵を見つけ出す。
RC4の解読攻撃など

12.シェーディング
立体感を生じさせるため，物体の表面に陰付けを行う処理

13.アンチエイリアシング
スクリーンの画素数が有限なので図形の境界近くに生じる，階段状のギザギザを目立たなくする処理

14.レンダリング
CG映像作成における最終段階として，物体のデータをディスプレイに描画できるように映像化する処理

今後
-
今月中に、午前対策を終わらせるため、残りの「18」日も続けていく。
エラーメッセージの日本語化

オリジナルアプリを開発する過程で、ユーザー登録時に入力に誤りがあった場合に表示されるエラーメッセージを日本語化に。

備忘録のため手順を記載する。

まずはapplication.rbを編集。

```ruby:config/application.rb
module Grucale
  class Application < Rails::Application
   version.
    config.load_defaults 6.0
    config.i18n.default_locale = :ja   #追記
  end
end
```

※``:ja``は日本語設定を意味する

次にGemfileの記述

```rubu:Gemfile
#最下部に追記
gem 'rails-i18n'
```
追記したら``bundle install``を実行。

ここまでで挙動を確認すると、``Passwordを入力してください``のように一部しか日本語化されていない。
それを解消するために英語から日本に翻訳してくれるファイルを作成する。

config/localesディレクトリに、**devise.ja.ymlファイル**を作成する。
作成したファイルに以下のサイトに記述しているコードをそのままコピペで貼り付ける。

https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml

これで日本語訳にしてくれたが、追加したカラム名は``Nameを入力してください``と英語表記のままになっている。
次にこれを解消するために自作でファイルに記述していく。

config/localesディレクトリに、**ja.ymlファイル**を作成し、以下の内容を記述する。

```yaml:config/locales/ja.yml
ja:
  activerecord:
    attributes:
      user:
        name: 名前
```

挙動を確認。

![スクリーンショット 2022-03-12 17.30.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533566/7aa94f10-c039-baab-2db7-ccac2cfc32e2.png)

無事に成功。
Ruby と Python で解く AtCoder ABC243 D

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。
# 今回のお題
https://atcoder.jp/contests/abc243/tasks/abc243_d

今回のテーマ、ビット演算

この問題は、扱う数値が大きいので計算が大変そうに見えます。
しかし、数値（10進数）を2進数で表しよく見ると．．．
![20220312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/cc255973-9d05-bade-892f-c4f7a7e6b780.png)
+ S の i 番目の文字が `U` のとき、今いる頂点の親に移動する
-> 2進数の右側の文字を除去
+ S の i 番目の文字が `L` のとき、今いる頂点の左の子に移動する
-> 2進数の右側に`0`を追加
+ S の i 番目の文字が `R` のとき、今いる頂点の右の子に移動する
-> 2進数の右側に`1`を追加

即ち、右側に文字を出し入れしているだけの操作になります。
# Ruby
```rb
n, x = gets.split.map(&:to_i)
s = gets.chomp.chars
y = x.to_s(2).chars

n.times do |i|
  case s[i]
  when 'U'
    y.pop if y.size > 1
  when 'R'
    y << '1'
  when 'L'
    y << '0'
  end
end

puts y.join('').to_i(2)
```
|10進数->2進数|2進数->10進数|
|:--:|:--:|
|xxxx.to_s(2)|'xxxx'.to_i(2)|
# Python
```py
n, x = map(int, input().split())
s = input()
y = list(format(x, 'b'))

for i in range(n):
    if s[i] == 'U':
        if len(y) > 1:
            y.pop()
    elif s[i] == 'R':
        y.append('1')
    elif s[i] == 'L':
        y.append('0')

print(int(''.join(y), 2))
```
|10進数->2進数|2進数->10進数|
|:--:|:--:|
|format(xxxx, 'b')|int('xxxx', 2)|
# まとめ
タネを知ってしまえばなんてことない問題ですが、コンテスト中は大変ですよね。
【Docker】Docker基本コマンド一覧

## はじめに
　本記事は、プログラミング初学者、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## Docker基本コマンド一覧

```
// イメージ関連
検索
  docker search [OPTIONS] 検索ワード
e.g.
  docker search ubuntu


ダウンロード
  docker pull [OPTIONS] イメージ名:[TAG]
e.g.
 docker pull docker/whalesay
 ※Tagを指定しない場合はlatestがpullされる


イメージ一覧
 docker images [OPTIONS]
e.g.
 $ docker images
 REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
 hello-world   latest    18e5af790473   5 months ago   9.14kB
 my_whalesay   latest    6b362a9f73eb   6 years ago    247MB
 my_whalesay   ver1      6b362a9f73eb   6 years ago    247MB
 // digestsを表示
  docker images --digests hello-world


イメージの確認
 docker inspect [OPTIONS] イメージID
e.g.
docker inspect 18e5af790473


イメージ削除
 docker rmi [OPTIONS] イメージID
e.g.
 docker rmi 18e5af790473


ヒストリー確認
 docker history [OPTIONS] イメージID
e.g.
 docker history 18e5af790473




// コンテナ関連
生成と起動
 docker run [OPTIONS] イメージ名[:TAG] [ARG]
e.g.
 docker run docker/whalesay cowsay Hello!


ネットワーク
 docker run [OPTIONS] イメージ名[:TAG] [ARG]
e.g.
// ポートマッピング(-dはバックグラウンド起動)
 docker run -d -p 80:8080 httpd
// DNSサーバ指定
 docker run --dns=192.168.3.3 httpd
// ホスト名の設定
 docker run -it --hostname=mo-sample.com --add-host=test.com:192.168.2.3 ubuntu
// MACアドレスの指定
 docker run -it --mac-address="88:e9:fe:56:bd:65" ubuntu
// ホスト名とIPアドレス定義
 docker run -it --add-host=sample.com:192.168.3.3 ubuntu
// ロギング・ドライバの設定(docker logsでログが表示されない時に使用した）
 docker run -it --name mycentos --log-driver=json-file centos:8 /bin/bash


リソースを指定
 docker run [OPTIONS] イメージ名[:TAG] [ARG]
e.g.
 docker run --cpu-shares=256 --memory=512m ubuntu


稼働コンテナを一覧表示
 docker ps [OPTIONS]
e.g.
 docker ps
// 全て表示
 docker ps -a


コンテナの稼働確認
 docker stats コンテナID
e.g.
 docker stats 18e5af790473


停止
 docker stop [OPTIONS] コンテナID
e.g.
 docker stop 18e5af790473


再起動
 docker restart [OPTIONS] コンテナID
e.g.
 docker restart  18e5af790473


削除
 docker rm [OPTIONS] コンテナID
e.g.
 docker rm 18e5af790473
// 一括削除
 docker rm --force $(docker ps -aq)


稼働コンテナで実行
 docker exec [OPTIONS] コンテナID COMMAND [ARG]
e.g.
 docker exec -it ubuntu /bin/bash


稼働コンテナへ接続
 docker attach コンテナID
e.g.
 docker attach 18e5af790473




ログの出力
docker logs コンテナID
リアルタイムログの出力
docker logs -f コンテナID
データの永続化
// ホスト側のdocker管理ディレクトリ以下をコンテナにマウント
docker run -d --name sample -v my-vol:/app nginx:latest
```
Google Formsの回答をFetch APIでPOSTする

Google Formsを自作のデザインで使うときのTIPSです。

ネットで見かけるのはformタグに送信先、inputタグにnameを指定する以下のような方法。

```html
<form action="https://docs.google.com/.../formResponse">
  <input type="text" name="entry.xxxx">
  <input type="text" name="entry.yyyy">
  <textarea type="text" name="entry.zzzz"></textarea>
</form>
```

ページが遷移してしまうのが少しイマイチなので、Fetch APIで送信する方法を考えました。
[このサイト](https://mattgreer.dev/blog/using-google-drive-for-form-submissions/)にもっと詳しく説明している方がいたので、合わせてご参考になさってください。

---

Google Formsの作成方法を一通り知っている前提で話しています。

作成したフォームのプレビュー画面で一度テストデータを送信し、ブラウザの検証ツールで内容を確認します。
以下の例では、用意した3つのテキストエリアを入力し送信後、送信後のページで検証ツールを開いています。
NetworkタブでformResponseの項目を探します。（画面はGoogle Chromeですが、ブラウザの種類、バージョンなどで探し方は異なると思います。）

![forms1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591762/a65edf7f-f71c-254c-91cb-0f5f9bb00d5e.png)

大事なのはentry.1000---の項目で、フォームのIDと入力した内容が書かれています。実際にPOSTされたデータはURLエンコードされており、view sourceを押すと確認できます。

https\://docs.google.com/.../formResponseに対し, Content-Typeとしてapplication/x-www-form-urlencodedを指定し、URLエンコードした文字列をbodyにいれてPOSTすれば、同じ内容をGoogle Formsに送信できます。ちなみにentry.1000---以外の項目はなくても正常に送信できます。

POSTするところだけをコードにすると以下のような感じになります。

```JavaScript
const form1 = encodeURIComponent('フォーム1の回答');
const form2 = encodeURIComponent('フォーム2の回答');
const form3 = encodeURIComponent('フォーム3の回答');

fetch('https://docs.google.com/.../formResponse', {
  method: 'POST',
  mode: 'no-cors',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
  body: `entry.xxxx=${form1}&entry.yyyy=${form2}&entry.zzzz=${form3}`
});
```

no-corsを指定しないと、データは届きません。
POSTするデータとGoogle Formsの設定(requiredなど)が一致していないとちゃんとデータが届かないので、 そのあたりの検証は必要ですし、そもそもJavaScriptが動いていない状態ならば、データが送信されないので、各種エラー処理は必要です。

それでもデータベースを用意する必要もなくて、無料で利用できるんで、Google Formsは個人利用にピッタリですね。
[TypeScript]インデックスシグネチャで感覚的には理解できなかったことまとめ


## 概要
TypeScriptについて学んでいて、インデックスシグネチャに関して感覚的には挙動が理解できなかったので、調べたことを備忘として記録しておくもの。
コード例は基本的にTypeScript Handbookから引用し、一部は自分で書いています。

## 参考資料
[Udemy-Understanding TypeScript 日本語版](https://www.udemy.com/course/understanding-typescript-jp/)
[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures)

## インデックスシグネチャとは
TSで、プロパティの具体名は指定せず、型だけを指定して定義を行う記法。
stringかnumber型のみ指定できる。以下はnumberの例
```typescript
interface StringArray {
  [index: number]: string;
}
// ↑数値の明示はせず、number型であることのみを定義している
 
const myArray: StringArray = getStringArray();
const secondItem = myArray[1];
```

ここからが感覚的には理解できなかった挙動になります

### インデックスシグネチャでstringを指定しても、numberを使うことができる。

```typescript
interface Player {
  [index: string]: string;
}


const yusukeChiba: Player = {
  1: 'vocal',
}
// ↑1を指定してるけど、エラーにはならない
```

[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures)内にこれを根拠付ける記述がありました。

`This is because when indexing with a number, JavaScript will actually convert that to a string before indexing into an object`
JSではobjectのindexを理解する際に、numberで記載されていた場合はstringにコンバートしてから解釈されるとのこと。
なので上記のコードの1も、実際には'1'というstringと解釈されるため問題にならない(=定義に反していない)とのこと。

```typescript
interface Player {
  [index: string]: string;
}


const yusukeChiba: Player = {
  part: 'vocal',
}
// ↑1を指定してるけど、エラーにはならない
```
これは調べてないんですが、stringで定義した後に、上記の様にシンボルでpartと書いて書きエラーが出ないことにも全く違和感を覚えてなかったんですが、これもちゃんと'part'とstringとして解釈してもらっているからかな？と思うなどしました(真偽はわかってません)

### number、string両方のインデックスシグネチャを指定した場合、numberに対するvalueはstringに対するvalueのsubtypeでなくてはならない

```typescript
interface Animal {
  name: string;
}
 
interface Dog extends Animal {
  breed: string;
}
 
interface NotOkay {
  [x: number]: Animal;
  [x: string]: Dog;
}
// 'number' index type 'Animal' is not assignable to 'string' index type 'Dog'.というエラーが発生する

interface Okay {
  [x: string]: Animal;
  [y: number]: Dog;
}
// これはDogがAnimalのsubtypeなのでok
```
これも原理はさきほどの例と同じ。
こちらとしてはyとしてnumberを指定指定したとしても、JSの挙動でstringにconvertされて解釈されるということは、同時にx側(stringと定義した側)として読み取られる。
なので、number側で指定したvalueが、string側のvalueとしても成立しなければならない。
この様な状態が成立するのは、number側のvalueがstring側のvalueのsubtypeである時なのでタイトルの通りとなる。

### インデックスシグネチャを指定した型に他のpropertyを指定することはできるが、valueは同じ型でなければならない

```typescript
interface NumberDictionary {
  [index: string]: number;
  length: number;
  name: string;
}
// Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
```
これも[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/2/objects.html#index-signatures)に説明があったので引用します
`This is because a string index declares that obj.property is also available as obj["property"]~`

要はこれもnameプロパティを指定したとして、インデックスシグネチャ側の定義に沿ったものとして解釈されうるから、ということなんでしょうか。

```typescript
interface NumberDictionary {
  [index: string]: number;
  length: number;
  name: number;
}
const sample: NumberDictionary = {
  name: 2,
  length: 5,
}

console.log(sample['name']); // => 2
```
確かに上記の様に書くことができるので、インデックスシグネチャ側の定義にそって解釈されるとvalueがnumberでないとダメ、というのは納得感があります。


### 感想
TS、安全性が高くありがたいな〜といつも書いてて思いますが、コンパイラの挙動だったりJSの挙動だったりを理解してないと理解できない挙動もたまにあるので、そういう所の理解は掘り下げが必要だなあ、と思いました。
Dockerと仮想マシンについて

https://udemy.benesse.co.jp/development/system/docker.html
この記事が分かり易かったです。
Dockerは一つのosを使用しているので、仮想マシンに比べて起動が速いことがしっくりきた。

venvで作成する仮想環境との違いがいまいち分からず、調べ中。
Railsの3つの環境【Ruby on Rails】

Railsには以下の3つの環境がある
* テスト環境（test)
* 開発環境（development)
* 本番環境（production)

Railsの`Rails`オブジェクトには`env`属性があり、開発環境において、`Rails.env.development`を実行すると、`true`が返ってくる。

Rails consoleやRails serverはデフォルトでは開発環境だが、`$ rails console test`、`$ rails server --environment production`など環境をパラメータとして渡すと、その環境で実行することができる。

また、アプリケーションを本番環境で実行する場合は、`rails db:migrate`を本番環境で実行してデータベースを作成する必要があり、`$ rails db:migrate RAILS_ENV=production`を実行する。

注意としては、上記のように、console、sever、migrateで環境の指定の仕方が違う。

Herokuは本番サイト用のプラットフォームのため、デフォルトで本番環境で実行される。
wslでchromeを使う

https://sunababox.com/ubuntu/chrome-install/
この記事を参考にwslにChromeをインストール。
https://rooter.jp/web-crawling/wsl-selenium/
これを参考にpathの通しまで行い、chromedriverが使えることを確認した。

https://html-css-wordpress.com/failed-to-read-descriptor-from-node-connection-%e3%82%b7%e3%82%b9%e3%83%86%e3%83%a0%e3%81%ab%e6%8e%a5%e7%b6%9a%e3%81%95%e3%82%8c%e3%81%9f%e3%83%87%e3%83%90%e3%82%a4%e3%82%b9%e3%81%8c%e6%a9%9f/
この記事でエラーの対処をしました。
SQL CHARとVARCHARについて

SQLを勉強していく中で、CHARとVARCHARの違いを理解したのでそれをまとめようと思います。

## CHAR
例えば、CHAR(10)と指定された場合、格納される列は常にちょうど10バイトとなります。
たとえ10バイトに満たなくても、ちょうど10バイトになるように調整されるんです。

## VARCHAR
CHAR型とは違って、格納される列数は調整されないんです。
例えば、VARCHAR(10)とされた場合、10バイトに満たなかった場合、10バイトになるようには調整されず、5バイトなり7バイトなりに調整されるんです。

短いですが、以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考資料】

https://qiita.com/aberyotaro/items/c589430bdb00c6ab4922
JavaScript JSON.stringify() JSON.parse()

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/2801caa3-6b4a-5415-a85f-19c194be94ae.png)

# JavaScript オブジェクトをJSON形式に変換する方法


```javascript:index.js

  // まずローカルストレージをクリアにする
  localStorage.clear();

  // オブジェクトを生成
  const object = {
    name: "mario",
    age: 12,
  }

  // コンソールに表示
  console.log(object)

  // JavaScriptオブジェクトをそのままローカルストレージに保存
  localStorage.setItem("example1", object)

  // JavaScriptオブジェクトをJSON形式にして保存
  localStorage.setItem("example2", JSON.stringify(object))

  // JSON形式をJavaScriptオブジェクトに変換
  const example2 = JSON.parse(localStorage.getItem("example2"))

  // example2をコンソールで表示
  console.log(example2)

  // example2のnameを表示
  console.log(example2.name)

```

# ローカルストレージを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/24fe9909-57f0-e7a8-e136-2e7c8e074fd2.png)

### example2の方は、JSON形式でローカルストレージに保存されていますね！

# コンソールでも確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/fbd18da4-28a2-3d26-1c3e-4d753454d1ec.png)



### JSON.parse()を使って、JSON形式のデータをJavaScriptオブジェクトに変換できました！
### example2のnameも表示することができました(^^♪

# 参考動画

https://youtu.be/OfRGJF3dT0o