OmniAICreator/Qiita-1.07M huggingface dataset:
個人アプリの制作日記

本日の積み上げ
①個人アプリの構想
②DB設計

①個人アプリの構想

■　個人アプリ名:スタサポ <= 突っ込まれるかも

■　どんなアプリか
ユーザーがメンターさんにわからないところをすぐに聞けるマッチングアプリ

　▶　手立て
　質問したいときに質問フォーマットにそってユーザーがメンターさんにビデオ通話を申し込む。
　グループチャットを通じて勉強し合う。
　ユーザーやメンター評価を搭載している。
　自分の学びをアウトプットがすることができる。

　▶　経緯
　昨今はコロナウィルスの影響でオンライン学習が増えている。が動画だけの学習だと受け身になりがちで質問
　したいところが聞けない。
　１対１のビデオチャットなら好きな質問ができると考えた。
　某スクールの学びを通して、わからないところだけ聞く自分がわかっていることを
　遠慮なく聞けるサービスに感動から。

　▶　ユーザー側のメリット
　周りに気にしないで、わからないところだけ聞きたい。
　動画では整理されていて分かりやすいが、その場の疑問が解決しずらい。
　自分がどこまで分かっているのアウトプットしながら確認ができる。
　自宅で簡単に取り組むことができる。
　コメントや評価を通じて自分の理解度を可視化でき、承認欲求が満たされる。

　▶メンター視点でのメリット
　隙間時間に行うことができる。
　教えることに携わりたい人が気軽な気持ちでできる。（その場にいればよい）
　その人だけに教えることができる。
　誰かに知識を伝える・教えること一番のアウトプット。

　▶実装したいこと
　ビデオ通話での応答
　コメント機能
　ログイン機能（メンター・生徒）
　評価機能（メンター・生徒）
　応答可能かどうか
　質問フォーム
　非同期通信（ビデオ通話、メッセージ）
　今日の積み上げページ（アウトプット）

■開発環境
rails 5.0.7.2
ruby 2.5.1
 gem device 


②　DB設計

usersテーブル
Column	Type	Options
name	string	null: false, unique: true
email	string	null: false, unique: true
password	string	null: false
my-image	string	
introduction	text	
profile	text	
subject	string	
rate	float	
Association
has_many :groups_users
has_many :groups, through: :user_groups
has_many :messages
has_many :tweets
has_many :teaches
groupsテーブル
Column	Type	Options
name	string	null: false, unique: true
Association
has_many :user_groups
has_many :users, through: :user_groups
has_many :messages
user_groupsテーブル
Column	Type	Options
group_id	integer	null: false, foreign_key: true
user_id	integer	null: false, foreign_key: true
Association
belongs_to :group
belongs_to :user
groupmessagesテーブル
Column	Type	Options
comment	text	null: false
image	string	
group_id	integer	null: false, foreign_key: true
user_id	integer	null: false, foreign_key: true
Association
belongs_to :group
belongs_to :user
Tweetsテーブル
Column	Type	Options
title	string	null: false
body	text	null: false
image	string	
user_id	integer	null: false, foreign_key: true
Association
belongs_to :user
tweetmessagesテーブル
Column	Type	Options
comment	text	null: false
image	string	
tweet_id	integer	null: false, foreign_key: true
user_id	integer	null: false, foreign_key: true
Association
belongs_to :tweet
belongs_to :user
teachテーブル
Column	Type	Options
title	string	
image	string	
body	text	
user_id	integer	null: false, foreign_key: true
Association
has_many :teach_tags
has_many :tags, through: :teach_tags
teach_tagsテーブル
Column	Type	Options
title	string	
image	string	
teach_id	integer	null: false, foreign_key: true
tag_id	integer	null: false, foreign_key: true
Association
belongs_to : teach
belongs_to :tag
tegsテーブル
Column	Type	Options
text	string	
Association
has_many :teach_tags
has_many :teaches, through: :teach_tags
JavaScript、jQuery個人的まとめ

#JavaScript

🔳DOMとは
HTMLを解析しデータを作成する仕組み
DOMツリーやドキュメントツリーとも言う

🔳ノード（オブジェクト）とは
HTML1つ1つのタグがDOMツリーの中ではノードと呼ばれる
例）body, header, side_barとか

js_foundation
#
```
window.addEventListener("load", function () {処理}
window.onload = function() {処理}
```
ロード時に全てのDOM要素を取得する

#
```
  let btn = document.querySelector("Button");
```
変数btnにセレクタButton（idのやつ）を代入
(“p”)だったり(“#Button2”)とかでも書く。
#
```
  btn.addEventListener("click", function () {処理}
```
btnがクリックされた時に{}内の関数を実行するイベントを追加

#
```
btn.innerHTML = “hoge”
```
指定したセレクタにhogeというHTMLを代入

#
```
btn.classList.add(“red”)
```
指定したセレクタにCSS要素を代入する

#
```
btn.classList.remove(“blue”)
```
指定したセレクタからblueというクラスを削除する

#js_tabの解説

#
```
  let tabs = document.getElementsByClassName("menu_item");
  let tabsAry = Array.prototype.slice.call(tabs);

tabsAry.forEach(function (value) {
    value.addEventListener("click", tabSwitch);
  });
```
の処理の流れを解説。

変数tabsAryにtabsの中身を配列に変換して代入する。
tabsAryをforEachでvalueという変数に代入して全て繰り返す。
valueの値がクリックされたらイベントが発火される
console.log();で配列の中身を確認したらとてもよく分かる。
他の部分はコメント解説の内容通りなので省略

#jQuery

🔳IDセレクタ
IDセレクタとは、HTML要素のid属性で指定するセレクタのことです。IDセレクタは、取得したいHTML要素のid属性の値に#（ハッシュ）を付けたものをセレクタとして利用します。
idセレクタの例
1	$("#idSelector") // idがidSelectorの要素を取得
クラスセレクタ
クラスセレクタとは、HTML要素のclass属性で指定するセレクタのことです。クラスセレクタは、取得したいHTML要素のclass属性の値に.（ドット）を付けたものをセレクタとして利用します。
クラスセレクタの例
1	$(".classSelector") // classがclassSelectorの要素をすべて取得
要素セレクタ
要素セレクタとは、h1やpのようなHTML要素を対象としたセレクタのことです。要素セレクタは取得したいHTML要素の要素名をそのままセレクタとして利用します。
要素セレクタの例
1	$("h1") // h1要素をすべて取得
属性セレクタ
HTMLのタグの属性値を指定したい場合、$("[ 属性 = '値' ]")で属性セレクタを取得できます。
属性セレクタの例
1	$("input[ type='radio' ]");  // <input type="radio">のHTML要素を取得する

🔳removeClass()、addClass()
クラスを追加したり消す。最初に0を指定しなくても自動的に最初の要素を指定してくれる

🔳index()
配列に変換しなくても、集合したDOM要素から引数に指定(thisとか）したDOMと同じ要素番号を戻す

🔳eq()
引数に要素番号を取って、集合したDOM要素から選択できる

分からない事はいきなり検索しないで、紙に実装できる流れを仮説立ててから調べる！
VSCodeでstyled-jsxの補完までする

styled-jsxをyarn addした後、vscodeで拡張機能を探すのは人類の遺伝子に刻まれた、いわば本能ともいえる行為だ。
そしてvscode-styled-jsxという名の拡張機能をインストールし、シンタックスハイライトが効いたことに喜び、涙するのもまた自然なことだ。
しかし人々はすぐに補完が効かないことに気づくだろう。
そして見つけ、絶望するのだ。
マーケットプレイスにあるこれと、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/e1c7f1a7-b37a-c77a-850a-d33c780af89d.png)
GitHub Readmeにあるこれを。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/5c5d3355-1124-1675-f381-224b31122932.png)

だが安心するのだ。
主はstyled-jsxのReadmeに導きを残している。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/9fef8866-e005-0511-2958-361caecba184.png)](https://github.com/zeit/styled-jsx/blob/master/readme.md#autocomplete-visual-studio-code-extension)

人類に幸あれ。
ラーメン。
いつも「いつもお世話になっております」では芸がない

# まえがき
ある日のメールの文面

```
XXです．いつもお世話になっております．
```

何個ものメールを見ていると，いつも「いつもお世話になっております．」と書いている事に気づきます．流石に芸がない．

たまには，「いつも大変お世話になっております」などの他の表現も混ぜたいところです．
しかし，忙しい毎日の中で他の表現を考えるのは難しい．．．

自動でランダムに「お世話になっております」文面を入力してもらうようにしましょう！！！

# Hammerspoonによるランダム定型文入力

**目指す物** : 
Hammerspoonを用いて，
Macのメールソフトで CTRL + I と入力したら，
「いつもお世話になっております．」
「いつも大変お世話になっております．」
「毎々お世話になっております．」
「平素よりお世話になっております．」
「毎度お世話になっております．」からランダムランダムに入力されるようにする．

## Hammerspoonとは
https://www.hammerspoon.org
Mac OS X向けの強力な自動化ツールです．メッチャ便利．他にも色々できます．

hammerspoonのインストール方法は割愛します．
この辺を参照してください．
https://www.softantenna.com/wp/mac/hammerspoon/

## 実際のコード
以下のコードをhammerspoonの設定ファイル `~/.hammerspoon/init.lua`の中に書き込んでください．

```~/.hammerspoon/init.lua
itsumo_hotkey = hs.hotkey.new({"ctrl"}, "I", function()
    f_random = hs.math.randomFloat()
    if f_random < 0.73 then
        hs.eventtap.keyStrokes('いつもお世話になっております．')
    elseif f_random < 0.75 then
        hs.eventtap.keyStrokes('日頃よりお世話になっております．')
    elseif f_random < 0.8 then
        hs.eventtap.keyStrokes('毎々お世話になっております．')
    elseif f_random < 0.85 then
        hs.eventtap.keyStrokes('平素からお世話になっております．')
    else
        hs.eventtap.keyStrokes('毎度お世話になっております．')
    end
end)
hs.window.filter.new('メール') -- 日本語にしているとき
  :subscribe(hs.window.filter.windowFocused, function() itsumo_hotkey:enable() end)
  :subscribe(hs.window.filter.windowUnfocused, function() itsumo_hotkey:disable() end)
hs.window.filter.new('Mail') --　英語にしているとき
  :subscribe(hs.window.filter.windowFocused, function() itsumo_hotkey:enable() end)
  :subscribe(hs.window.filter.windowUnfocused, function() itsumo_hotkey:disable() end)
```

## 説明

先ずホットキーの定義をします．
`hs.math.randomFloat()`は0から1までの乱数を返す関数です．この値に応じてランダムな文字列を入力するようにします．
`hs.eventtap.keyStrokes('いつもお世話になっております．')`は文字列を入力する関数です．

```lua
itsumo_hotkey = hs.hotkey.new({"ctrl"}, "I", function()
    f_random = hs.math.randomFloat()
    if f_random < 0.73 then
        hs.eventtap.keyStrokes('いつもお世話になっております．')
    elseif f_random < 0.75 then
        hs.eventtap.keyStrokes('日頃よりお世話になっております．')
    elseif f_random < 0.8 then
        hs.eventtap.keyStrokes('毎々お世話になっております．')
    elseif f_random < 0.85 then
        hs.eventtap.keyStrokes('平素からお世話になっております．')
    else
        hs.eventtap.keyStrokes('毎度お世話になっております．')
    end
end)
```

以下の箇所で，メールアプリにフォーカスが当たっている時だけに，`itsumo_hotkey` を有効にする．
https://qiita.com/yohm/items/ed2bbc8f7c4340a55695
を参考にしました．

```lua
hs.window.filter.new('メール') -- 日本語にしているとき
  :subscribe(hs.window.filter.windowFocused, function() itsumo_hotkey:enable() end)
  :subscribe(hs.window.filter.windowUnfocused, function() itsumo_hotkey:disable() end)
```

メールアプリの言語設定を日本語にしたり英語にしたり切り替えているため，英語に切り替えている時のために，以下を定義．

```lua
hs.window.filter.new('Mail') --　英語にしているとき
```

# 感想
`CTRL+I`で無事，ランダムに「お世話になっております」文面が入力出来るようになりました！！！！！
問題点は，このショートカットを使っていることを知られてしまうと，「お世話になっている」という思いが`CTRL+I`だけで表現されている軽薄なものであると，相手に思われてしまいます．
10個ぐらい「お世話になっております」と付けないといけないかもしれない・・・

# 参考にしたページ
https://qiita.com/yohm/items/ed2bbc8f7c4340a55695
[GAS] スプレッドシートの onEdit() は「参照先」が変更されても検知しないみたいです

# 起こったこと

↓ スプレッドシートA の `data` シート

![A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/4a2ff5e2-2d97-f930-754f-6f9cff896608.png)


Aとは異なるスプレッドシートBの `まとめ` シートがこう↓

![B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/77eb566f-32d5-2e06-1b9d-d63d217533e8.png)


**`まとめ` シートのA2セルには下記のquery関数が入っていて**、スプレッドシートAの `data` シートのうちB列が「東京都」のデータだけを抽出しています。

```
=query(importrange("xxxxx","data!A2:C"),"where Col1 is not null and Col2 = '東京都'")
```

ここで、スプレッドシートBの `まとめ` のシートが更新されたら通知がほしいというリクエストがありましたが、**スプレッドシートAは私達の管轄ではありません。**(なのでAのスプレッドシートを触ることができない)


そこで、スプレッドシートBの更新を検知するために、スプレッドシートBに下記のGASを仕込みます。

```js
function onEdit(e) {
  Browser.msgBox("編集イベントきたよ");
}
```

この状態でスプレッドシートBの `まとめ` シートを手で編集する(例えばD1あたりに文字を入れてみる)と、「編集イベントきたよ」が出力されます。うん、ちゃんと効いてる。

しかし、スプレッドシートAの `data` シートに下記のように ID300 の行を追加してみると、query関数のおかげでスプレッドシートBには300のデータが追加されますが、イベントは発火しておらず、メッセージは出力されないじゃないですか。

![AB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/46bc07ca-710b-4748-c377-0a33a60eac61.png)


# 参照先が更新されてもイベントは発火しない

もうすこし「小さく」検証してみます。

例えばスプレッドシートCに下記のようなシートを作ります。
A2は空欄のセル。B2は `=A2` の式が入っています。

![C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/f47d8e2a-1bef-3f5b-74c1-fcf988e7f3a1.png)

さらにスプレッドシートCにこんなGASを埋め込みます。

```js
function onEdit(e) {
  Browser.msgBox(e.range.getA1Notation());
}
```

その後、A2に「あああ」を入力すると下記のようになります。

![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/9db402de-136a-ff15-05d4-dbcd7ef6ceff.png)

シートとしては「A3」も編集？更新？されているけど、イベントで取得できるのは**「直接」編集された**「A2」だけ、ってことですね。

そりゃそうか。。。例えば importrange とか query とかで、大量に他シートを参照してたら大変なことになるもんね。


# おまけ1

`onEdit(e)` の `e` に何が入っているのかは下記に書かれてます。
[Event Objects  \|  Apps Script  \|  Google Developers](https://developers.google.com/apps-script/guides/triggers/events)

ちなみに、`onEdit()` と `onChanged()` の違いは
[Google Spreadsheetのトリガーの「編集時」と「値の変更」の違いを検証してみた \- まだ中学生のブログ](http://madachugakusei.hatenablog.com/entry/2015/10/18/140439)


# おまけ2
onEditがどんな時に発火するのか、は下記に書かれています。
[Class SpreadsheetTriggerBuilder  \|  Apps Script  \|  Google Developers](https://developers.google.com/apps-script/reference/script/spreadsheet-trigger-builder)

> Specifies a trigger that will fire when the spreadsheet is edited.

「スプレッドシートが編集されたときに発火するよ」とのことですが、今回の実験結果によると「他セルを参照してるときに、参照先が変わったことで自分自身のセルの値が変わっても、それはeditには含まれない」みたいです。確かに自分自身のセルには「式」が値として入っていて、その式自体は変わってないので編集されてない、、、ですもんね。

...という解釈でいいのだろうか。どなたか情報を知っていたら教えてください！


# おまけ3

今回の例に挙げた件ですが、仕方ないので「スプレッドシートB」にGASを仕込んで、定期実行して「前回の起動時と比較して変更があれば通知する、で凌ぐことにしました。


Happy GAS Lifeを！
【TypeScript】ページの最下部にスクロールした際、イベントを発火させる方法

#最下部に来たのを計算する

①document.documentElement.clientHeight  ＝＞  表示されているページの高さ
②window.scrollY                         ＝＞  どこまでスクロールしたか
③document.documentElement.scrollHeight  ＝＞  スクロール稼働域（つまり隠れている分も含めたページの高さ）

表示されているページの高さ　＋　どこまでスクロールしたか（① + ②）が、隠れている分を含めたページの高さ（③）になるとき、一番下に到達したとなります。

#window.onscrollに仕込む

window.onscrollを仕込む事により、スクロールする度にイベントを発火できます。
スクロールする度に、どこまでスクロールしたかを計算し最下部に来た（① + ② = ③）かをif文の条件にします。
あとはif文の中に好きな処理を加えればOKです。

```
    window.onscroll = () => {
      if (
        document.documentElement.scrollHeight -
          document.documentElement.clientHeight ===
        window.scrollY
      ) {
        alert("bottom!");
      }
    };
```
RailsにFixturesで初期データを入れるためのyamlをCSVから作るスクリプト

Railsのデータベースにデータを投入する方法はfixtures用のyamlファイルを作って、railsコマンドで入れる方法などがよく知られています。
ですが、現実的にはExcelなどで元データを用意してCSV等で扱うことが多いと思われます。
yamlコンバータなども試してみたけどfixtures keyを入れるのがうまくいかなかったので、自分で作りました。
エスケープ文字の処理とかなにもやってないので、元データがそういうものを扱う場合は適宜加工してください。

たとえば、1行目にカラム名が入ったこんな感じのCSVファイルがあったとして。

~~~fruits.csv
id,item,price
1,りんご,100
2,みかん,80
3,バナナ,60
4,メロン,2000
5,いちご,300
~~~

Fixturesで扱うにはこういうyamlファイルが必要になります。

~~~fruits.yml
data1:
  id: 1
  item: りんご
  price: 100

data2:
  id: 2
  item: みかん
  price: 80

data3:
  id: 3
  item: バナナ
  price: 60

data4:
  id: 4
  item: メロン
  price: 2000

data5:
  id: 5
  item: いちご
  price: 300
~~~

`data1:`のところがfixtures keyというやつで、データベースには反映されないけど、レコードごとにハッシュとしてユニークな値をつけなければいけないようです。

スクリプトはこんな感じです。
ExcelからCSVに変換したら、UTF-8でBOMが付いてしまったので、ファイルをopenするときにオプションが付いてます。

~~~csv2yaml.rb
#!/use/bin/env ruby

filename = ARGV[0]

# UTF-8のBOMを消すオプション
file = open(filename, 'r:BOM|UTF-8')

# CSVファイルの先頭行を取得
column = file.gets.chomp.split(",")

# fixtures keyのプレフィックス(data)とそのあとに付けるカウンタ(num)
prefix = "data"
num = 1
str = ""

file.each do |line|
  unless line.strip == ""             ## 空白行を無視する
    str += "#{prefix}#{num}:\n"
    (0 .. column.length - 1).each do |i|
      str += "  #{column[i]}: #{line.chomp.split(",")[i]}\n"
    end
    str += "\n"
    num += 1
  end
end
print str
~~~

Shellから実行する時はこんな感じです。

~~~Shell
$ ./csv2yaml.rb fruits.csv > fruits.yml
~~~

500行くらいのCSVデータの変換して問題なかったし、fixturesでも取り込めたので大丈夫なようです。
カラムが異なる複数のCSVファイルでも変換できました。

yamlのライブラリなどを使えばもっと簡単に作れるかも。
八村塁（Rui Hachimura）の NBA初年度成績予測を振り返る（コロナ中断編）

以前、『八村塁（Rui Hachimura）の NBA初年度成績を予測する』というタイトルで記事を書いたんですが、NBA もコロナ禍で延期（もしかするとこのまま中止）になっているので、ここまでの成績を振り返ってみたいと思います。
https://qiita.com/chase0213/items/8065574e1a3bde659bbb#%E7%B5%90%E8%AB%96%E4%BA%88%E6%83%B3

まずは予測値から。

70ゲーム出場（56ゲーム先発）
平均25.0分プレイ
平均14.0得点
平均6.0リバウンド
平均0.8スティール
平均2.0ブロック
平均1.3ターンオーバー
平均3.2パーソナルファウル

というような予測でしたね。
この内、試合数だけは最後まで行われていないため、予測値を当てはめる必要があります。
NBAのレギュラーシーズンは全82試合ですが、現在まで 57試合行われており、そのうち八村選手は 41試合出場しています。
この欠場数は彼のパフォーマンスというより怪我によるのもなので、今後全ての試合に出ると考えて、シーズン中の試合出場数は 82 - 16 = 66試合が妥当ではないでしょうか。

さて、それでは予測値と実際の彼のパフォーマンスを並べてみます。

|項目|予測値|実際の値|誤差（※1）の絶対値|エラー率（※2）|
|:---:|:---:|:---:|:---:|:---:|
|出場試合数|70|66|4|6.06%|
|平均得点|14.0|13.4|0.6|4.29%|
|平均リバウンド数|6.0|6.0|0.0|0.00%|
|平均スティール数|0.8|0.8|0.0|0.00%|
|平均ブロック数|0.2|2.0|1.8|900.00%|
|平均ターンオーバー数|1.0|1.3|0.3|30.00%|
|平均パーソナルファウル数|3.2|2.2|1.0|31.25%|

※1 予測-実際の値
※2 誤差の絶対値/実際の値

![スクリーンショット 2020-05-19 12.02.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52780/5f1fe0c7-3203-fbec-f5f2-a4c711d080d3.png)

なお、八村選手の現在のデータは、NBA Statsという NBA公式のデータポータルから参照しています。
https://stats.nba.com/player/1629060/

エラー率は割合として算出しているため、もともと値が小さいものはエラー率も高く出てしまっています。
しかし、全体としては試合数を除いて全て ±2.0以内におさまっており、至極単純なモデルとしては非常に良く推論できているのではないかと思われます。
また、このモデルでは、八村選手とタイプが似通っていて、2020年現在NBAで活躍している選手よりも少し上（期待を込めて）という位置づけの予測を行っていたので、
かなり堅調な NBAキャリアの滑り出しと言えると思われます。

そろそろチーム練習がスタートし始めているという噂も耳にしますし、早くまた NBA が観たいですね。
【初心者】ChromeDevToolsを使ってJavaScriptで簡単に要素を取得する方法

# はじめに
会社で毎日ポチポチ画面操作していることをJavaScriptを使って自動化することにしました。値を取得や値のセットをするために、試行錯誤していたところ、簡単に出来るやり方がわかりました。

* document.querySelector()
* document.querySelectorAll()

メソッドが簡単に要素の取得や値のセットがしやすく、
ChromeDevToolsを使うことで、更に簡単に対応することが出来ました。

# ChromeDevToolsでDOMノード参照
以下のサイトで使い方をgifで説明しており、一瞬で使い方がわかります。

[Chrome DevTools: Generate a JavaScript expression to get a DOM node](https://umaar.com/dev-tips/185-copy-js-path/)



# コード
今回実際に使った使い方

```javascript
// 値のセット
document.querySelector("#tabTopics1 > a").value="test"

// 値の取得
document.querySelector("#tabTopics1 > a").value

// innerText取得
document.querySelector("#tabTopics1 > a").innerText
```


# 参考
* [Chrome DevTools: Generate a JavaScript expression to get a DOM node](https://umaar.com/dev-tips/185-copy-js-path/)
* [【JavaScript】要素の取得方法(getElement、querySelector)](https://qiita.com/tomokichi_ruby/items/c3ed6f6edbd5078ddf70)
シンボリックリンクを用いたTeXファイル管理

## はじめに

文献用BiBTeXファイル（.bib）や，よく使う定義をまとめたTeXファイル（.tex）はクラウド管理が可能なフォルダ上（例えばGoogleDriveフォルダ上）に置いておくが，どのTeXファイルでも相対・絶対パスを使わずに参照できるようにしたかった．ので，`C:\texlive\texmf-local`上にシンボリックリンクを置いた話．

ちなみに，TeX環境はTeXLiveで構成していること（ls-R運用をしていること）を前提としている．

## シンボリックリンクとは

簡単に言えば，ファイル本体は好きな場所に置いておいて，中身のないコピー（0 kB）としてシンボリックリンクを置くべき場所に置ける．ショートカットと違うのは，本体を参照するようにシンボリックリンクを参照できることである．

作り方は簡単．コマンドプロンプトを管理者権限で開き，`mklink (シンボリックリンク名) (リンク先ファイル)`を実行．以上！（詳細は[こちら](https://www.ipentec.com/document/windows-create-symbolic-link)を参照する）

## TeXファイルのシンボリックリンクを参照できるようにする

1. 適当な場所にbibファイル等を置く
1. たとえば，`C:\texlive\texmf-local\bibtex\bib`上にシンボリックリンクを作成する（環境によって`texmf-local`フォルダのパスは異なるので注意）
1. `mktexlsr`でls-Rを更新する（よく分からなくてもひとまずこのコマンドを実行すれば良い，詳細を知りたければ[TeX Wiki](https://texwiki.texjp.org/?LaTeX%E5%85%A5%E9%96%80%2F%E5%90%84%E7%A8%AE%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E5%88%A9%E7%94%A8#tc299bdb)）
1. たとえば`references.bib`の場合，TeXファイル上で`\bibliography{references}`とすれば参照できる（わざわざ`\bibliography{c:/texlive/texmf-local/bibtex/bib/references}`のようにパスを指定する必要はない）

## おわりに

まぁ参照元ファイルもクラウドフォルダに基本的に置いているので，相対パスで参照することに対した苦はないし，なんならシンボリックリンクを作る手間の方が......しかしシンボリックリンクの考え方は他にも応用が効く（TeXでもフォントを参照するときに使えたりする）ので，せっかくだから記事としてまとめた．
VSCodeの超基本的なショートカット

おそらくVSCodeを使用している人なら誰でも知っていることかもしれないのですが、、、私は知らなかった。

HTMLを書く時のショートカットですが、ショートカットを使用することでコーディングの時間をかなり削減できるんですね。。。

恥ずかしながら知らなかった。。。

```html
<!-- 「!」 を変換すると下記の文書型宣言ができる -->

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
</html>
```

```html
<!-- 「#id」　と#から始めて書くとid名を指定したdivタグができます -->
<div id="id"></div>
```

```html
<!-- 「.cls」　と.から始めて書くとclass名を指定したdivタグができます -->
<div class="cls"></div>
```

```html
<!-- 「.parent>.child」　例えば左記だと親要素と子要素、セットで書くことができます -->
<div class="parent">
  <div class="cls"></div>
</div>

<!-- もちろんidとclass掛け合わせてもできます　「#parent>.child」　 -->
<div id="parent">
  <div class="child"></div>
</div>
```

```html
<!-- 「.cls*6」　左記の場合*n文のタグが作れます。 -->
<div class="cls"></div>
<div class="cls"></div>
<div class="cls"></div>
<div class="cls"></div>
<div class="cls"></div>
<div class="cls"></div>
```

他にも沢山あるので、調べながら使っていって覚えていこうと思います！
deviseを導入したが更にカラムを増やしたい時



# deviseを使ってみて

deviseを導入したがカラムこれだけって時ありませんか？

今回はカラムの追加方法について説明します！！

#1.usersテーブルにカラムを追加します

今回はnameカラムを追加します。
ターミナルで以下のコマンドを実行しましょう。

```
$ rails g migration AddNameToUsers name:string

$ rails db:migrate
```

#2.application_controller.rbを編集

application_controller.rbを以下のように編集しましょう。
これでユーザー登録時にnameカラムが保存されるようになりました。

```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end
```

## ※今のままでは登録時にしかnameカラムが入っていないので、編集でnameを変更しても変更されません。


# 3.編集時に追加したカラムの編集もできるようにしましょう！

```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
    <!-- 以下のように編集時の対応する記述も追加してあげましょう -->
    devise_parameter_sanitizer.permit(:account_update, keys: [:name])
  end
end
```

これで編集時にデータが反映される様になりました:point_up_tone2:

この記事が少しでも参考になれば嬉しいです:pray_tone2:
command not foundのエラーの解消方法

もし何かインストールをしようとしたときに```command not found```が起きたときの対処方法について紹介します。

# 環境
macOS 10.15.4

# ライブラリのインストールを実行したときに...
わたしが実際にimagemagickというライブラリをインストールしようとしたときに下記のコマンドを初めに試しました。

```
$ sudo apt-get -y install imagemagick libmagick++-dev
bash: sudo: command not found
```
しかし```command not found```...では別の方法で同じライブラリを実行してインストールを試みました。

```
# brew install ImageMagick
bash: brew: command not found
```
しかしこちらも```command not found```...ライブラリやコマンドの問題かと思い、他のライブラリで試してみました。

```
$ npm install bootstrap
bash: npm: command not found
```
しかしこれも```command not found```...PATHが通っていないのかなぁと思い確認をすると

```
# echo $PATH
/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```
しっかり通っていました。

# そもそもインストールするための環境が整っていなかった
違う観点で調べてみたら原因を理解することができました。

### apt-getの場合
apt-getコマンドはLinuxのUbuntu/Debian系でのコマンドなので**そもそもmacOSでは対応していない**ことがわかりました。

### brewの場合
brewを使用してインストールをする場合は最初にHomebrewをインストールする必要があることを思い出しました。

### npmの場合
npmの場合はNode.jsのインストールが事前に必要であることも知りました。

# Homebrewをインストール
わたしはmacOSなのでHomebrewをインストールすることを選びました。下記のサイトからインストールをします。
[Homebrewのサイト](https://brew.sh/index_ja)

そしてもう一度下記のコマンドを実行します。

```
$ brew install ImageMagick
```
今度は無事にインストールができました^_^
Visual Studio Codeの拡張機能

## 今回やること
Visual Studio Code(以下、VSCode)で便利な拡張機能を紹介します。
この記事の執筆時以降に便利な拡張機能が会ったら適宜追記します。

## 一覧
### ・Japanese Language Pack for Visual Studio Code
VSCodeを日本語化してくれます。

### ・HTML Snippets
HTMLを書く際に自分が入力を補完してくれる。
つまり、自分がよく使用するコードを辞書登録機能のように呼び出すことができます。

### ・Ruby
Rubyの構文ミスをチェックしてくれる。

### ・zenkaku
コードに全角スペースが入っていたら灰色の四角形を表示してハイライトしてくれます。
⌘ + ⇧ + p　でzenkakuをenableにしないと全角スペースのチェックをしてくれないので注意。
![スクリーンショット 2020-05-19 22.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/0828f35a-c9f1-c910-d678-9c4bc25a2bfc.png)


今後便利な物があれば追記していきます。
[Python]探索(NumPy)　ABC165C


#[ABC165C](https://atcoder.jp/contests/abc165/tasks/abc165_c)

１次方程式の条件なので、NumPy配列を使うことで、計算回数を大きく削減できる。NumPy配列がイテラブルのような役割を果たす。

PyPyでも実行可能で、計算速度を上げることができる。（なぜかメモリ使用量が増える）
>Python3 1063 ms 106372 KB
>PyPy3    571 ms 155196 KB

```python:サンプルコード
import sys
import itertools
import numpy as np
 
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline

N, M, Q = map(int, readline().split())
 
A = np.array(list(itertools.combinations_with_replacement(range(1, M + 1), N)))
# [[1 1 1]
#  [1 1 2]
#  [1 1 3]
#  [1 1 4]
#  [1 2 2] ...

n = len(A)
score = np.zeros(n, np.int32)
m = map(int, read().split())
for a, b, c, d in zip(m, m, m, m):
    cond = A[:, b - 1] - A[:, a - 1] == c # NumPy配列
    score += d * cond
 
print(score.max())
```
絵文字によるコミュニケーション

## 概要
絵文字はもはや<a href="https://ja.wikipedia.org/wiki/Unicode%E3%81%AEEmoji%E3%81%AE%E4%B8%80%E8%A6%A7">Unicodeの文字コード</a>としても登録され、**世界共通の言語**です。


在宅勤務でチャットを使った業務のやりとりが増えたと思うので、
私がよく使う、**相手を威圧しないための絵文字**を紹介したいと思います。

## よく使う絵文字
<a href="https://slack.com/intl/ja-jp/help/articles/202931348-絵文字とエモティコンの使用">(※ Slackの絵文字の使い方はこちらを参照)</a>

<table>
 <thead>
  <th>絵文字</th>
  <th>入力文字</th>
  <th>印象</th>
 </thead>
 <tbody>
  <tr>
  <tr>
   <td>:pray:</th>
   <td>:pray</th>
   <td>相手に寄り添うような気持ちでお願いするとき</td>
  </tr>
  <tr>
   <td>:bow:</td>
   <td>:bow</td>
   <td>恐縮な気持ちを感じながらお願いするとき</td>
  </tr>
  <tr>
    <td>:eyes:</td>
    <td>:eyes</td>
    <td>取り急ぎ見たよ</td>
  </tr>
   <td>:muscle:</td>
   <td>:muscle</td>
   <td>頑張りたい、任せろ</td>
  </tr>
  <tr>
    <td>:raised_hand:</td>
    <td>:raised_hand</td>
    <td>よろしく、ウイっす</td>
  </tr>
  <tr>
    <td>:hand_splayed:</td>
    <td>:hand_splayed</td>
    <td>よろしく、ウイっす(これ以上は言うまい)</td>
  </tr>
  <tr>
    <td>:thinking:</td>
    <td>:thinking</td>
    <td>考えている感じで相手に意見を求める時</td>
  </tr>
  <tr>
    <td>:sweat:</td>
    <td>:sweat</td>
    <td>大体自分が悪いとき</td>
  </tr>
  <tr>
    <td>:sweat_smile:</td>
    <td>:sweat_smile</td>
    <td>大体相手が悪いとき</td>
  </tr>
  <tr>
    <td>:sob:</td>
    <td>:sob</td>
    <td>相手にすがりたい時、悲しくて構ってもらいたいとき</td>
  </tr>
  <tr>
    <td>:smirk_cat:</td>
    <td>:smirk_cat</td>
    <td>調子に乗っているのを理解した上で任せろやって気持ち</td>
  </tr>
  <tr>
    <td>:crying_cat_face:</td>
    <td>:crying_cat_face</td>
    <td>同情したくなるタイプの悲しみ</td>
  </tr>
  <tr>
    <td>:+1:</td>
    <td>:+1</td>
    <td>いいね (同レイヤー、目下の人に使う。先輩に使うのは時と場合と相手の性格による）</td>
  </tr>
  <tr>
    <td>:clap:</td>
    <td>:clap</td>
    <td>スバラなとき</td>
  </tr>
  <tr>
    <td>:raised_hands:</td>
    <td>:raised_hands</td>
    <td>全身を使って喜びを表現したいとき</td>
  </tr>
  <tr>
    <td>:metal:</td>
    <td>:metal</td>
    <td>ぱりぴ感を出すとき</td>
  </tr>
  <tr>
    <td>:point_left:</td>
    <td>:point_left</td>
    <td>それな</td>
  </tr>
  <tr>
    <td>:point_right:</td>
    <td>:point_right</td>
    <td>それな</td>
  </tr>
  <tr>
    <td>:ok_hand:</td>
    <td>:ok_hand</td>
    <td>ちょっと軽い感じのOK</td>
  </tr>
  <tr>
    <td>:ok:</td>
    <td>:ok</td>
    <td>業務的な感じのOK</td>
  </tr>
 </tbody>
</table>
※ 完全に主観です。


## 参考
@yamadasyさんが絵文字を一覧にしてくれているので、ご参考ください :pray: :pray: :pray:
> 【Qiita/Github/Slack/Discord 絵文字一覧】
> https://qiita.com/yamadashy/items/ae673f2bae8f1525b6af

## 最後に

息をするように絵文字を使っているが、差別引き起こす可能性もあるので気を付けてください :crying_cat_face: 
:point_right: :point_right_tone1: :point_right_tone2: :point_right_tone3: :point_right_tone4: :point_right_tone5:

※ Rails6だって気にしている
<img width="50%" height="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468458/94bcfdb9-1a57-98be-31d0-c6c0490db479.png">
active_hashの使い方について！！

某プログラミングスクールでフリマアプリを作成する際にactive_hashを使ってみたので是非見て下さい！！
初学者の書いた記事ですが参考になれば嬉しいです:pray_tone2:




# そもそもactive_hashとは？
・DBにデータとして保存しておくほど重要ではない。
・基本的に変更されない。
・Active_Recordのように読み込み専用情報をまとめたハッシュを扱うことができるものです。

# 1.gem 'active_hash'をインストール

アプリのGemfileに以下を記述

```
gem 'active_hash'
```
ターミナルでbundle installを実行

```
$ bundle install
```

# 2.Active_Hash::Baseを継承しているモデルを作成する

ActiveHash::Baseを継承したモデルを自作する。

今回は良くactive_hashが利用される事の多いprefecture(都道府県)モデルを作成していきます。

app/models/prefecture.rbという感じで自作します。

```prefecture.rb

class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end
```

#3.アソシエーションを組みます

今回はフリマアプリを作成しているので、商品の配送先を登録するときに都道府県をactive_hashを使って表示します。
product.rbにアソシエーションを組んでいきます。

```product.rb
class Product < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
end
```
#4.表示します
商品を登録するフォームなどでcollection_selectを使う際は以下のように表示できます。

<a href="https://gyazo.com/4b22dbfd07e1afaa2eeb29c1cbdd5b57"><img src="https://i.gyazo.com/4b22dbfd07e1afaa2eeb29c1cbdd5b57.png" alt="Image from Gyazo" width="459"/></a>

```ruby

= f.collection_select :prefecture_id, Prefecture.all, :id, :name, {prompt:"選択してください"}, {class:""}
```

# 5.登録した情報を表示したいとき

```ruby
= @product.prefecture.name
```

この様な感じでactive_hashを使う事ができます！！

最後まで見て頂きありがとうございます:pray_tone2:

少しでも参考になって頂ければ嬉しいです:thumbsup_tone2:
【Railsチュートリアル】第１章にあるGitのこと 


# はじめに

この記事では[Rails チュートリアルの第１章](https://railstutorial.jp/#toc)
で使用されているGitの使い方について
まとめた記事です。
ベストプラクティスや間違いがあれば
チュートリアルをやりながら書き直していく予定です。

--------------------------------
# Git
言わずと知れたVersion管理ツール
ちなみにGit HubとGitは別物
よく勘違いされているのであらかじめ書いておきます。

Git ： 技術の名前、コマンド
Git Hub : Gitを使ったサービス

--------------------------------
#チュートリアル 第１章
チュートリアル上で使われてるAmazonのクラウドIDE
Cloud9もそうですが、まぁ日頃使っていないので
使い方を忘れるんですよね。。。
それと同じようにGitも業務に取り入れていない状態で
案の定忘れていました。

今後、職場に導入することも考えて
自分なりのリファレンスをどこかで作りたいな。。。

今回はそんな忘れっぽい私のような人に贈る内容です。

--------------------------------
# 設定コマンド

インストールをするときに欠かせない設定コマンド
社内のそれも外の世界とつながっていない場合でも
これは入れるのだろうか。。。

```
git config --global user.name [username]
git config --global [mailaddress]
```
--------------------------------
# 最低限知っておきたい Gitコマンド

```
$ git init
$ git add -a
$ git status
$ git commit -am "命令系のコメント"
```

git addの-aオプションは
作業ツリーのファイルをすべてステージするという意味
チュートリアルでは注意して使うように書いてある。
***「変更する必要のないファイルも
一緒にステージングしてしまうから」という意味で書いてるのかな***

といっても中途半端にあらゆるファイルに変更を加えるのにはリスクがある。
そう思うのは一人で開発しているからかな。

ちなみに初めて知りましたがGitのコメントは命令形
（チュートリアルでは体言止めと表記）が良いみたいです。

筆者は日頃から体言止めで書いているので
ここは当たり前のようにcommitしてました。

--------------------------------
# Git初心者から脱却したいなら

リポジトリやバックアップについて勉強しよう。
Gitではブランチを使うことで
変更履歴を複数持たせることができる。

文字通どおり枝分かれさせることができるので

オリジナルファイルを複数持つことなく
変更履歴A 変更履歴B といった感じに
変更履歴のみを管理することができる。

何がすごいってオリジナルファイルを
２コ３コと持たなくてよいということ

よくファイル名で
ファイル名_YYYYMMDD-0.txtやファイル名_YYYYMMDD-1.txtといった
ファイルを目にすることだろう。

どれが新しいのかわからない
そういった面倒な版数管理をする必要がないのだ。

また、どうしても
２重管理したいということであれば
別のサーバ上にリポジトリを作成することができる。

これを

「リモートリポジトリを作成する」

という。

リモートリポジトリ作成する場合は
cat コマンドでリポジトリ内にある公開鍵を表示して
リポジトリを登録する先に登録しておく必要がある。

手順については第２章に記載します。

```

'リモートリポジトリの操作（ここではmasterブランチにプッシュ）
$ git remote add origin リポジトリURL
$ git push origin master

' 枝分かれtestの新規作成して切り替える
$ git checkout -b test

' 枝分かれtestとmasterの結合(masterにスイッチ後)
$ git merge test

' 全ての枝分かれを表示
$ git branch

' コミットログの表示（変更履歴が多い場合はこのまま打つのは得策ではないかも）
$ git log

'任意の変更箇所まで戻る（もしかすると、ベストプラクティスがあるかも）
$git reset ハッシュ値

```
--------------------------------
# 出力メッセージの日本語翻訳

あと、チュートリアルの最中に気になった文言

|単語|日本語|
|:-------------------------------------|:-----------------------|
|On branch master                      |親ブランチを参照しています         |
|No commits yet                        |まだコミットされていません           |
|Changes to be committed               |コミットされる変更               | 
|Changes not staged for commit         |変更がステージングされていません   |
|nothing to commit, working tree clean |作業ツリーにコミットするものは何もありません|
|discard changes in working directory  |作業ディレクトリの変更を無視する      |

--------------------------------
# おわり
blocklyでobjectを動かす。その17


#概要

blocklyでobjectを動かす。
bdpediaからsparqlで取得してみる。

#stageを書く。


```
function dbpedia(query) {
	var endpoint = "http://ja.dbpedia.org/sparql";
	query = "SELECT DISTINCT * WHERE { dbpedia-ja:" + query + " dbpedia-owl:abstract ?abstract .}"
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if (xhr.readyState == 4 && xhr.status == 200)
		{
			var json = JSON.parse(xhr.responseText);
			alert(json.results.bindings[0].abstract.value)
		}
	};
	xhr.open("POST", endpoint, true);
	xhr.setRequestHeader("Accept", "application/sparql-results+json");
	xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xhr.send("query=" + encodeURIComponent(query));
}

```

#objectを書く。


```
Blockly.Blocks.dbpedia = {
	init: function() {
		this.jsonInit({
		message0: "dbpedia %1",
		args0: [{
			type: "input_value",
			name: "TEXT"
		}],
		previousStatement: null,
		nextStatement: null,
		style: "text_blocks",
		tooltip: Blockly.Msg.TEXT_PRINT_TOOLTIP,
		helpUrl: Blockly.Msg.TEXT_PRINT_HELPURL
	})
}};

Blockly.JavaScript.dbpedia = function(a) {
    return "dbpedia(" + (Blockly.JavaScript.valueToCode(a, "TEXT", Blockly.JavaScript.ORDER_NONE) || "''") + ");\n"
};
```

#フローを書く。

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3d1a5f41-42ed-5660-e3b6-339eec3d8162.png)


#成果物

http://embed.plnkr.co/plunk/JBBZ84uSYG6UR1cf

以上。
deno run で typescript系のエラーが出た際の対処法

## 事象
- `deno run`実行時に以下のエラーが出た

```
error: TS1219 [ERROR]: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning.
```

## 対処方法
- tsconfig.jsonを以下のように設定

```
{
    "compilerOptions": {
        "strictPropertyInitialization": false
    }
}
```

## 問題
- 上記の設定をした上で`deno run`を実行しても解決せず
- denoでは明示的に指定しないとtsconfig.jsonを読み込んでくれない模様

## 実行コマンド
- configオプションの引数に`tsconfig.json`のファイルパスを指定することによって設定を反映できる
- `deno run --config tsconfig.json sample.ts`
検索機能の活用

１．Lightning Experience のインスタント結果に最近使ったデータを表示するにはどうすればよいですか?
２．Lightning Experience で検索結果を絞り込むにはどうすればよいですか?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/7dc00c47-e786-f24b-2ef7-7adfc643fe84.png)
Ruby と Python と numpy で解く AtCoder ABC054 B 行列演算

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

# 今回のお題
*[AtCoder Beginner Contest B - Template Matching](https://atcoder.jp/contests/abc054/tasks/abc054_b)*
<font color="green">Difficulty: 828</font>

今回のテーマ、行列演算

2次元配列ですが、行列のライブラリを使用すると演算が簡単になることがあります。
# Ruby
```ruby.rb
require 'matrix'

class Matrix
  # v2.3 では代入不可
  def []=(i, j, x)
    @rows[i][j]=x
  end
end

n, m = gets.split.map(&:to_i)
rows = Array.new(n + m){gets.chomp.chars.map{|c| (c == '#') ? 1 : 0}}
a = Matrix.rows(rows.shift(n))
b = Matrix.rows(rows)
(n - m + 1).times do |i|
  (n - m + 1).times do |j|
    if a.minor(i, m, j, m) == b
      puts "Yes"
      exit
    end
  end
end
puts "No"
```
```matrix.rb
require 'matrix'

class Matrix
  # v2.3 では代入不可
  def []=(i, j, x)
    @rows[i][j]=x
  end
end
```
`require 'matrix'`で行列のライブラリを呼び出します。
ローカル環境の`v2.7.1`では行列の要素に代入できるのですが、AtCoder環境の`v2.3.3`では代入できないのでメソッドを追加しています。
標準ライブラリに対してもこういうことができるのが**Ruby**の面白い所でもあります。

```minor.rb
    if a.minor(i, m, j, m) == b
```
`minor`で部分行列を取得し行列の比較を行っています。

```error.rb
(n - m).times do |i|
  (n - m).times do |j|

(n - m + 1).times do |i|
  (n - m + 1).times do |j|
```
~~`1 x 1`の行列の時、行列の比較がうまくいかないので、それに対応した処理が入っています。~~`(n - m)`は間違いで`(n - m + 1)`が正解でした。

**追記**
2次元配列版については、コメント欄を参照願います。
# Python
```python
import numpy

n, m = map(int, input().split())
a = numpy.zeros([n, n], dtype=int)
b = numpy.zeros([m, m], dtype=int)
for i in range(n):
    s = input()
    for j in range(n):
        if s[j] == '#':
            a[i, j] = 1
for i in range(m):
    s = input()
    for j in range(m):
        if s[j] == '#':
            b[i, j] = 1
for i in range(n - m + 1):
    for j in range(n - m + 1):
        if numpy.all(a[i: i + m, j: j + m] == b):
            print("Yes")
            exit()
print("No")
```
```all.py
        if numpy.all(a[i: i + m, j: j + m] == b):
```
numpyの行列の比較は、例えば`[[True, True], [True, True]]`を返しますので、all関数を用いて全て`True`かどうかを調べています。

||Ruby (Matrix)|Ruby (Array)|Python (numpy)|
|:--:|:--:|:--:|:--:|
|コード長 (Byte)|420|288|534|
|実行時間 (ms)|22|10|166|
|メモリ (KB)|3196|1788|12512|
# まとめ
+ ABC 054 B を解いた
+ Ruby に詳しくなった
+ Python に詳しくなった
+ numpy に詳しくなった
Express4系でのreq.paramsの値の取得

# Express3系のやり方
『現場で通用する力を身につけるNode.jsの教科書』にも記載のあるやり方です。/index/12/taro等でブラウズした際にid=12,name='taro'で値を取得したい場面です。日本語で説明のあるサイトを探しましたが見つからず、ネタ帳がわりにここに記します。

```app.js
var routes = require('./routes');

app.get('/', routes.index);
//次の3行を追加 
app.get('/index', routes.index);
app.get('/index/:id', routes.index);
app.get('/index/:id/:name', routes.index);
```
```index.js
exports.index = function(req,res){
  var id = req.params.id;
  var name = req.params.name
  //id,nameを使って様々な処理
}
```
これが2020年5月19日現在でガラッと変わってしまっています。app.getが使えなくなってしまいました。

# Express4系での方法
## スタート地点のコード
Expressプロジェクト作成時点でのコードの一部です。

```app.js
var indexRouter = require('./routes/index');

app.use('/', indexRouter);
```

```index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;
```
Routerオブジェクトが新しく追加されましたが、何となく以前と似た経路を辿りそうです。
## パラメーターの追加方法
前のバージョンではapp.jsに'./index/:id'などを加えていましたが、今はindex.jsに加えるとうまくいくみたいです。router.getを何回もコピーして'/'を変えるやり方です。コードの見易さをよくするために中の無名関数に名前をつけます。

```index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', func);
router.get('/index', func);
router.get('/index/:id', func);
router.get('/index/:id/:name', func);

function func(req, res, next) {
  var id = req.params.id;
  var name = req.params.name; 
  //id,nameを使って様々な処理
}
module.exports = router;
```
これで、/index/12でブラウズすればid=12が、/index/12/taroでブラウズすればid=12,name='taro'が取得できるようです。
Macで'¥'をデフォルトで'\'にする方法

#結論
¥キーをタイプした時、デフォルトで'\'(バックスラッシュ)が入力される方法を紹介します。

##環境
- macOS Catalina 10.15.4

##方法
1.システム環境設定のキーボードを選択
2.入力ソースタブを選択
3.下の方の「"¥"キーで入力する文字」を"\\(バックスラッシュ)"に変更

##メリット
- 言語や環境にも依りますが、改行文字'\n'を打つのが圧倒的楽。以上

#+αのおすすめ設定
- 同じく入力ソースタブの上の方の"ライブ変換"を外しておくとタイピングの早い人は幸せになれるかも
- 「"¥"キーで入力する文字」設定の一個下の"数字を全角入力"も外しておくと入力モードに依らずに半角数字が入力できるので幸せ
Seleniumをできるだけ軽くする方法

#要件

-　いまさらですが、ラズパイもカード会社のスクレイピングにトライしました。
-　ラズパイゼロをつかって、Seleniumにて、スクレイピングをしようとしたため、タイムアウトが多々発生。
-　極力軽くスクレイピングが実装できるようにしました。
-　パスワードとかの管理は自己責任で。。

#コード
```Python
from selenium import webdriver 
from selenium.webdriver.chrome.options import Options 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.webdriver.support.ui import WebDriverWait 
import time
from bs4 import BeautifulSoup as BS 
import re
import requests

 options = Options()
 options.add_argument("no-sandbox")
 options.add_argument("--disable-extensions")
 options.add_argument("--headless")
 options.add_argument('--disable-gpu')  
 options.add_argument('--ignore-certificate-errors')
 options.add_argument('--allow-running-insecure-content')
 options.add_argument('--disable-web-security')
 options.add_argument('--disable-desktop-notifications')
 options.add_argument("--disable-extensions")
 options.add_argument('--lang=ja')
 options.add_argument('--blink-settings=imagesEnabled=false')
 options.add_argument('--disable-dev-shm-usage')
 options.add_argument('--proxy-server="direct://"')
 options.add_argument('--proxy-bypass-list=*')    
 options.add_argument('--start-maximized')
 driver = webdriver.Chrome(options=options)

 driver.get (http:///~~~)
```

また、読み込み範囲を縮小するために、スクレイピング直前のClassまでの読み込みする形で
タイムアウトを最大限にして、記載

```Python
 wait = WebDriverWait(driver, 300);
 element=wait.until(EC.presence_of_element_located((By.CLASS_NAME,"fluid")));
```

あとは、BeautifulSoupで読み込み、加工

```Python
 res = driver.page_source.encode('utf-8')
 print("loading")
 soup=BS(res,"html.parser")
```

これで、なんとか、タイムアウトを避けることができるようになりました。
Gmailでメールテストしてたら送信元（FROM）アドレスがGoogleグループのアドレスになってしまう

##原因
DMARCポリシーを"p=reject" または "p=quarantine" が設定されているドメインからGoogleグループにメールが送信していたからでした。
他にも、送信元のドメインと [From] アドレスのドメインが一致しない場合。たとえば、john.smith@gmail.com から受信したメールが、Gmail ではなくソーシャル ネットワーク サイト経由で送信された場合も同じ事が起こるようです。

##DMARCポリシー

|  ポリシー | 動作 |
| --- | --- |
|  none | 認証失敗してもなにもアクションを取らない |
|  quarantine | 認証に失敗したメールは隔離され、たいていは迷惑メールフォルダに入る |
|  reject | 無条件に拒否され受信されない |


##Googleグループの仕様
Googleグループの配信システムは、送信者のドメインの DMARC ポリシーをトリガーせずに適切に配信するため、このように表示されます。

##メールヘッダ調査結果
X-Spam-Checked-In-GroupというヘッダにGoogleグループ情報が入っていました。
GoogleグループではDMARCポリシーがreject、quarantineの場合、正しく受信できないので新たにヘッダを追加してFROMを書き換えることで受信できるようにしている仕組みのようです。

##解決
DMARCポリシーを"p=none"にすることでテストすることができます。
【PHP】 プロセスが永遠に起動している問題への対策と知見

# はじめに

「いい感じにTIMEOUTしてくれるだろう普通。」と思っていたら痛い目に合いました。

PHPで、とある監視プロセスをcron的に繰り返し実行しているときに、ログからプロセスが全くkillされないことに気づいた。
※そのプロセスの内部では、CURLコマンドを使って外の情報を取得してきている。

どうしてだろうと調べているときに、下記を上司に教えていただき頭の整理がつきました。
上司かつ以下のリンク著者に感謝です。

https://ngyuki.hatenablog.com/entry/2019/09/21/191552




# 内容

## 結論

「CURLOPT_TIMEOUT」を設定していない状況で、端末へ映像などの情報を取得しに行く際に取得できなかったとき、無制限に待たされるとのこと。

## 詳細

```text:CURLOPT_TIMEOUT
これは、端末へ接続にでき、映像などの情報を取得しに行くときに設定するTIMEOUTになります。
例）
「端末に接続で来たけど情報取得で待たされる。」
というときに、どれくらいでTIMEOUTするのかを設定する項目となっています。
```

ちなみに、「CURLOPT_CONNECTTIMEOUT」も適切に設定しなければ、端末への接続時に失敗したときに、デフォルト値が参照されたり設定されたものが適応されるので注意が必要です。

```text:CURLOPT_CONNECTTIMEOUT
これは、端末へ接続しに行くときに設定するTIMEOUTになります。
例）
「端末に接続しに行こうとしたけど、待たされる。」
というときに、どれくらいでTIMEOUTするのかを設定する項目となっています。
```


以下参考

https://ja.coder.work/so/php/143295



さらに、以下も注意しておきたいところです。

```
CURLOPT_CONNECTTIMEOUTはCURLOPT_TIMEOUTで表される時間のセグメントであるため、
CURLOPT_TIMEOUTの値はCURLOPT_CONNECTTIMEOUTの値より大きくする必要があります。
```


また、デフォルト値がどういう設定になっているかなどは以下を参考。

https://www.it-swarm.dev/ja/php/php%EF%BC%9A%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AEcurl%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E5%80%A4/1067580731/
[React]JSX, props, stateについて

# はじめに
Reactに今まで全く触れてこなかったのですが、元々興味があったため最近になって少し勉強をし始めました。
その中で、新しい内容や概念が多く登場したため簡単に調べた内容を簡単にまとめてみます。
自分がプログラミングに触れてから時間も浅いため、この内容も初学者向けのものになります。

## React.jsとは
Facebook社が公開している,UIのパーツ（構成部品）を作るためのライブラリです。
#### React.jsの特徴

- UIの機能追加に特化しており、ユーザーが使いやすいUIを作りやすくしてくれる
- 効率よく処理を行い、できるだけユーザーが操作にストレスを感じないように高速で動作する
- コンポーネント指向 (UIを部品化して管理を行いやすくし、再利用をしやすくする設計手法の1つ)

## JSX
JavaScript XMLの略で、JavaScriptを拡張した言語です。
テンプレート言語の一つになります。

#### JSXの特徴

- HTML風に書けるため可読性が高い
- HTMLのタグが使える
- JSXTransfomerが自動でコンパイルをしてくれる 

実際にAppクラスを定義してその中に、JSXで画面にHello world.と表示するコードを書いてみます。

````Test.js
import React, { Component } from 'react';

class App extends Component {
  render() {
    return <h1>Hello world.</h1>;
  }
}

export default App;
````
このように直感的に書くことができることがメリットとなります。
JSXでの記述だけを見ると、1行目の`import React, { Component } from 'react';`は必要無いようにも思えますが、JSXで記述したものはwebpackコマンド実行時に内部的にbabelが呼ばれて、以下のように変換されることにより一般的なWebブラウザでも解釈できるJavaScript構文へと変換されています。

````Test.js
import React, { Component } from 'react';

class App extends Component {
  render() {
    return React.createElement (
      "h1",
      null,
      "Hello world."
    );
  }
}

export default App;
````

そのため、JSXを使用するためには1行目の記述が必要になります。

## Component(コンポーネント)

- クラスコンポーネント
- ファンクショナルコンポーネント(関数コンポーネント)

の2種類があります。

## props
コンポーネントのプロパティのことです。
親コンポーネントから子コンポーネントへの受け渡しが出来るが、受け取ったpropsの変更や更新は出来ません。
なお、関数の受け渡しも可能です

#### propsの参照
````
this.props
````

#### defaultProps
propsのデフォルト値を設定できます。

#### propTypes
propsのバリデーションです。

````Test.js
// 型のチェック
Hoge.propTypes = { num: PropTypes.number }

//型と値の有無のチェック
Hoge.propTypes = { num: PropTypes.isRequired.number }
````

## state
コンポート内部の状態のことであり、コンポーネント内で使用できる値です。
値が変更される度に`render`が走ります。
propsと似ているようで違います。

#### propsとの違い
- 使用箇所
    - props: 親コンポーネントから子コンポーネントへ受け渡してが可能
    - state: そのコンポーネント内部でのみ使用可能
- 変更、更新
    - props: 不可
    - state; 可

#### stateの参照


````
this.state
````

#### 初期値の設定

`constructor`メソッドを使用します。
なお、`constructor`メソッドには`props`を渡すことができます。

````Test.js
constructor(props) {
  super(props);
  this.state={
      hoge: 0,
  };
}
````

#### 値の更新

`setState`メソッドを使用します。

````Test.js
this.setState({hoge: 1});
````
`setState`メソッドを使用して更新するとレンダリングがされるのですが、以下の方法ではレンダリングがされないため非推奨となっています。

````Test.js
this.state.hoge = 1;
````

# おわり
今回はReact.jsで必須となる知識について自分のアウトプットも兼ねて書きました。
最後まで見ていただき、ありがとうございました。
DataDirectでGoogle BigQueryからODBC接続でデータを取得

本記事ではDataDirectドライバーを使用してGoogle BigQueryからODBC接続でデータを取得します。
JupyterNotebook上でデータを取得し、Google BigQueryのチュートリアル同様にデータ処理を行いました。

**※以下のチュートリアルではODBC接続ではなく、直接BigQueryからデータを取得する方法が書かれています。**
https://cloud.google.com/bigquery/docs/visualize-jupyter?hl=ja

## 環境
OS：Windows10
ODBCドライバー：DataDirect 8.0 Google BigQuery
Pythonバージョン：3.8

## DataDirect 8.0 Google BigQueryのインストール
以下URLより評価版をダウンロードできます。
https://www.progress.com/connectors/google-bigquery

ダウンロード出来たらインストールを行っていきます。
基本的に「Next」で次に進めましょう。
以下の画面のチェックボックスはWindows ODBC AdministratorにユーザーDSNを追加するかを聞かれています。
後から設定するのでチェックを入れておくといいかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/645ca861-99b1-b188-68c3-93c199581d58.png)

あとは「Done」でインストールが完了するのを待ちましょう。

## Windows ODBC Administratorの設定
設定をする前Google Cloud Platfoamのサービスアカウントの作成とアカウントキーのJSONファイルが必要になります。

分からない場合は以下を参考にしてみてください。
https://www.magellanic-clouds.com/blocks/guide/create-gcp-service-account-key/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/faf8858f-72e7-1c30-7195-2f95263069e5.png)

|         設定項目        |        入力する内容        |
|:----------------------:|:-------------------------:|
|    Data Source Name    |          任意の名前        |
|        Project         |        プロジェクトID      |
| Authentication Method  |       Service Account     |
|         Email          | サービスアカウントのアドレス |
|    Private key File    |      JSONファイルのパス    |


以上を設定し終わったら、「Test Connect」で接続を確認します。

## JupyterNotebookでデータを可視化
本記事では前章で設定したプロジェクトのリソースにsamplesデータセットのnatalityテーブルをコピーして使用しています。
Google BigQueryのチュートリアルにある年別の出生数の合計を可視化してみます。

pyodbcのインストール
`pip install pyodbc`


```py
import pyodbc
import pandas as pd

cnxn = pyodbc.connect('DSN=Google BigQuery',autocommit=True)  #DSN=設定したDSN名
tableResult = pd.read_sql('SELECT source_year AS year,COUNT(is_male) AS birth_count  \
                        FROM samples.natality GROUP BY year ORDER BY year DESC LIMIT 15', cnxn)

df = pd.DataFrame(tableResult)
df
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/8589e945-3095-1dbf-eff8-710de31092ce.png)

```py
%matplotlib inline
df1.plot(kind='bar', x='year', y='birth_count')  #年別の出生数の合計の棒グラフ
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628207/5ea7d389-4278-1995-10e5-9a121a383d93.png)

## まとめ
チュートリアルを実行したコードは以下で共有していますので参考にしてください。
Colaboratoryでは実行できないのでローカルにダウンロードしてJupyterNotebookで実行してみてください！
[チュートリアル実行例](https://colab.research.google.com/drive/1WKSRN6I941no3s1DuKNfdIaWtRwvEZSX?usp=sharing)

公式ではSimba社のODBCドライバーを提供していますが、Progress社の提供するDataDirectでも同じことが可能です。

DataDirectを使用する**メリット**は、国内企業であるアシスト社がDataDirectを扱っておりサポートを受けられることです。Simba社は日本に展開していないこともあり不安がある人、評価版を使用して気に入ったという人はDataDirectを検討してみてもいいかもしれませんね！
[アシスト社のホームページ](https://www.ashisuto.co.jp/datadirect/connectors/google-bigquery.html)
BATファイル内でパイプを使いたい！

# TL;DR

ネット記事に正しい情報があんま載ってないっぽい、
バッチファイル内でパイプする方法のご紹介
実はあるあるネタだったらすいません、、

# まえせつ

コマンド打って特定の文字をひっかけるような~~脳死~~テストを
バッチファイルで書こうとすると

### バッチ スクリプト外でバッチ ラベルを呼び出すことはできません。

にブチあたったりしません？
**バッチファイル内でパイプ**すると起きます。
コマンドプロンプトから成功してもパイプ使うと発生します。

[Using pipe command in a batch file](https://stackoverflow.com/questions/32700386/using-pipe-command-in-a-batch-file)

こういう記事とかに **^ (キャレット)** 使って！と書いてあるけど
どうにも解消されません。。

色試して解決しました。

## とりせつ

なんと以下のように **"** を二重に囲う事で解決します！

```
@echo off

call :checkFunction "reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\DataCollection" | find "REG_DWORD" | find "0x1""
REM call :checkFunction "(テストコマンドをがんがん書いてく)"
exit /b

:checkFunction
cmd /c %*  > nul 2>&1
if %errorlevel% neq 0 (
	echo %*が失敗した！
	exit /b 0
)
echo %*が成功した！
exit /b 1
```

# おしまい

これで終了コードでは判定出来ないようなレジストリの値チェックや、
さらにpowershell呼び出すようなケースでも。
追加ツール導入しないでチェックできますね！やったね！！

### 追加でツール入れられない環境なんて無いって？？あるんですよ！！
【django】raise ValidationErrorで指定したエラーメッセージを表示する

pythonの通常のtry, exceptの例外処理とは違っていて例外検出とその内容の表示に詰まったので、記録に残しておきます。

今回はフォームやモデルでバリエーションチェックする場合に、独自のバリデーションチェックに引っかかったときのエラーメッセージの表示について記事にしたいと思います。

# 簡単な状況説明

OpenCVを使って簡単なBlur（ぼかし）フィルタ機能を開発していて、ユーザからフィルタサイズを入力してもらって、その値から効果強度（フィルタの大きさ）を決めようと思いました。

そこで、Formクラスを使ってフォームを作りましたが、ガウシアンフィルタを使ったため入力された値が偶数だとエラーがでます。

ここから、Formクラスに「入力された値が偶数ならエラー処理する」という独自のバリエーションチェックを作ろうと考えました。

# ソースコード

間違っていたら、ごめんなさい。
models.pyはあまり気にしなくてもいいです。

```python:app/urls.py
app_name = 'app'
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
]
```

```python:models.py
class Image(models.Model):
    img_src = models.ImageField(upload_to=get_upload_to)   
```

```python:form.py
def is_oddnumber(value): #奇数かどうかをチェックする関数
    if value % 2 == 0:
        raise ValidationError('偶数を入力してください')
class Form(forms.ModelForm):
    class Meta:
        model = Image
        fields = ('img_src')

    filter_size = forms.IntegerField(
        required=True,
        max_value=100,
        min_value=1,
        validators=[is_oddnumber], #追加で上のis_oddnumberでバリデーションチェックを行う
    )
```

```python:views.py
class IndexView(generic.TemplateView)
     
    template_name = index.html
    
    def get(self, request, *args, **kwargs):
        form = Form()
        return render(request, self.template_name, {'form': form})

    def post(self, request, *args, **kwargs):
        form = Form(request.POST, request.FILES)
        if form.is_valid():
             return redirect(○)
        return render(request, self.template_name, {'form': form}) #エラーメッセージを含んだフォームをセットして再表示
```

```html:index.html
<form action="{% url 'app:index' %}" method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
</form>

{% if form.errors %}
<ul>
    {% for error in form.non_field_errors %}
    <li>{{ error }}</li>
    {% endfor %}
</ul>
{% endif %}
```

raise ValidationErrorの引数であるエラーメッセージはform.errorsに格納されるみたいです。

そのため、バリエーションエラーが発生した場合は、エラーメッセージをform.errorsに含んだformをrenderとかで再度表示しなおしてやれば、形としては画面遷移なしにエラーメッセージを表示できます。