OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでdiff

# 対象読者
- 「pythonのネイティブライブラリにdifflibがあるのは知ってるけど使い所は？」って思ってる方
- 「テキストデータの比較バッチを作ろう」と思っていてpythonも選択肢にある方
- 「pythonのネイティブライブラリいっぱいあるけどdifflibは知らないなぁ」何者か知っておくかと思う方

# 序章
みなさんdiffってどうやってとってますか？
1. Linuxのdiffコマンド？
2. WindowsやMacのネイティブアプリ？
3. VSCodeなどのエディタやIDE？

だいたい上記3択かなと。僕の場合エビデンスを残さないでいい小さいファイルでは3、大きなファイルだったりエビデンスを残す場合には1で行います。（余談ですがWSL2のおかげで1がとても行いやすくなりました。）

でも今あなたが何らかのチェックバッチを作成中だとして、プログラム上から大きな文字列同士のdiffの結果を残す必要が出てきたら、この3択の中から対処しますか？

# なんでPythonでdiffを取ろうと思ったの？
序章の通りプログラム上でdiffを取ることになったことによります。もう少し詳しく書くとDB上の数千、数万件のデータを比較するチェックバッチを作成することになり、完全な一致を検出するのは難しくないんですが 比較結果NGだった場合にわかりやすく差分内容を伝えたいという意図でdiffをログ上に出すことにしたのがきっかけです。

# 最初にやろうと思ったこと~プログラム上からdiffを取る~
pythonで気軽にdiffが取れることをしらなかった私は
比較対象である２つの情報を２つのファイルにそれぞれ書き出し、プログラムから実行環境に合わせたdiffのコマンドをコールして結果を取得しそれをログに残そうとしました。

これでも要件は当然満たされているんですが、
`比較対象である２つの情報を２つのファイルにそれぞれ書き出し` 
これのI/Oに掛かるオーバーヘッドが気になりました。

他にも細かいところだとバッチはdocker上で起動するを前提にしてましたが「baseイメージにdiffコマンド入ってたっけ？入れるのめんどいな」とか、プログラムからOSのコマンド実行も色んな意味でイケてないし、仮にWEB系のアプリだったりするとOSのコマンドコールはインジェクションが致命的だし（今回の要件とは別ですけど）

# Pythonで使えるdiffライブラリないかな？
で、ちょっと調べたらすぐにpythonネイティブライブラリにdifflibがあることがわかりました。（Python公式が見つかりました）
https://docs.python.org/ja/3.7/library/difflib.html

使い方は公式をほぼそのまま転載しちゃいますが こんな感じです。
Linuxコマンドのdiffに見慣れていれば、わかりやすいですよね。

```python
>>> from difflib import context_diff
>>> s1 = ['bacon\n', 'eggs\n', 'ham\n', 'guido\n']
>>> s2 = ['python\n', 'eggy\n', 'hamster\n', 'guido\n']
>>> sys.stdout.writelines(context_diff(s1, s2, fromfile='before.py', tofile='after.py'))
*** before.py
--- after.py
***************
*** 1,4 ****
! bacon
! eggs
! ham
  guido
--- 1,4 ----
! python
! eggy
! hamster
  guido
```

若干難点なのは、`generator<str>` で結果が返ってくるところです。
完全に`list<str>` で返ってきてると思って 結果をindex指定で参照してみようとしてpythonに怒られました。
とはいえ、普通そんなことしないと思うのでそれほど難点でもないですね。

# まとめ
Pythonで比較バッチを作る際、「一致してないよー」を親切に教えてあげるときは `difflib.context_diff` を使おう！
いつもの見慣れたLinuxのdiffコマンドっぽく比較した結果が取得できて「一致してない情報があるよ！」をログに残しやすいよ！

といったところです😄
Chrome Console のメッセージの重複(グループ化)をオフにする方法

度々メッセージがまとめられてしまうのが嫌で、調べたら日本語の記事が見つからなかったので書きました。

例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579635/381011ad-0537-a2f9-21f5-c138f5923c37.png)
引用・参考：[Chrome debugger - how to turn off console.log message grouping?](https://stackoverflow.com/questions/25706235/chrome-debugger-how-to-turn-off-console-log-message-grouping)

## 方法

![スクリーンショット 2020-12-21 15.52.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579635/b7387c91-e28f-7f52-c707-dd4863f3866d.png)
検証ツールのConsoleを開いて、右上の設定から`Group similar`のチェックを外すだけ！

</br>
</br>

#### P.S.

誰かVSCodeのデバッグコンソールでこのグループ化をOFFにする設定を知っている方がいたら教えて欲しいです...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579635/0b1f375b-0c88-ddce-1b16-bafc3769da98.png)
Pardot-salesforce コネクタv2へのアップグレード

こんにちは

twitterアカウント　tomoaki　@akitomomax　です。

Salesforce-Pardot コネクターの v2 へのアップグレードをしてみました。

アップグレードなどをすると、不具合が起きたりするので悩んだのですが、
カスタムオブジェクトの同期がすぐできる、との記載からやろう、と決意しました。

 ![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532958/5d1ebfd2-b7f0-522d-49ac-4bd5a83b1e6a.png)


ただ、やるには、以下をしっかり熟読していただき、
慎重に実施するようにしてください。


Salesforce コネクター v2 の設定を開始する前に
https://help.salesforce.com/articleView?id=pardot_sf_connector_setup_v2_prework.htm&type=5
Salesforce-Pardot コネクターの v2 へのアップグレードに関する考慮事項
https://help.salesforce.com/articleView?id=pardot_sf_connector_setup_v2_upgrade_connector_parent.htm&type=5

今回、私は、コネクタユーザーを、システム管理者のプロファイルを持っているユーザーからPardot インテグレーションユーザーに
変更をしました。（コネクタユーザーは選べます。）

注意点としては、

コネクタユーザーが、インテグレーションユーザーになるため、
SFDC側とカスタムオブジェクト連携をしている場合など、そのSFDCのそのオブジェクトの各項目に、
インテグレーションユーザーに権限を与えておかないといけないということになります。

環境などが違うので、なんとも言えませんが、
アップグレードは怖いですよね、ほんとに。
用心に用心を重ねても何が起こるか分からないという不安があります。

チェックシートを用意し、全ての事項を確認し、クリアしてから、
慎重に行うというのが重要ですね。
一人、システム管理者なので、そこは不安なので、チェックシート、スケジュールシートなど全て準備して、
一個ずつ潰しながら日々業務にあたっております。

緊張したけど、完了して、ほっ。

少しして、問題発覚！！！


CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY: record type missing for: 取引先　というエラーが出て、
Pardotから入ってきたプロスペクトがSFDCに同期しなくなる、という現象が発生。
年始に気付き、400件くらい、シンクしていないプロスペクトがあることが分かる。
ちょーーーぜつ焦りましたが、弊社、個人取引先を使用しているのですが、そのプロファイルの設定が足りていなかったようです。

SFDCサポートの方に教わりました。本当に助かりました。400件くらいで済んで良かった(T_T)

◆ 設定手順
1. Salesforce の「設定」から「クイック検索」のところに「プロファイル」を検索・クリックします。
2. 「B2BMA Integration User」をクリックします。
3. 「レコードタイプの設定」のところまでスクロールダウンし、「取引先」の右側に表示されている「編集」リンクをクリックします。
4. 「個人取引先」を追加・保存します。
5. 該当エラーが発生しているプロスペクトレコードに移動し「CRM と同期」ボタンをクリックいただくなど、同期エラーが解消されるか確認します。


あーーー、コネクターユーザー変更の落とし穴があるなーー

怖いよーーーー
LaravelのEloquentで子を引っ張り出す時の覚え書き

長いことLaravel触ってないとちょこちょこ忘れるのでメモ。

例えば

```php
class Hoge extends Model
{
    public function moge()
    {
        return $this->HasMany(Moge::class);
    }
}
```
というMogeを子に持つHogeモデルがある場合、

```php

class HageController extends Controller
{
    private function getHogeMoge($condition)
    {
        $hoge = Hoge::find($condition->hoge_id);

        $moge_collection = $hoge->moge->where('id', $condition->moge_id);    // collection
        $moge_eloquent   = $hoge->moge()->where('id', $condition->moge_id);  // eloquent
    }
}
```
の`$moge_collecrion`は`$hoge->moge`のCollectionメソッドでwhere抽出された結果で、
`$moge_eloquent`は`$hoge->moge()`のEloquentメソッドでwhere抽出された結果。

時々ごっちゃになって、Eloquentのwhere内でクロージャ使った条件抽出する時に
Collectionの書き方してて、引数が足らんでとかララ公に言われてあれってなる。
三項演算子の書き方

# 概要
- 三項演算子の書き方を言語別にわけました。

# Python

- 通常

```Python
score = 100
result = ""
if score >= 60:
    result = "合格"
else:
    result = "不合格"
print(result)
```

- 三項演算子

```Python
score = 100
result = "合格" if score >= 60 else "不合格"
print(result)
```


# Java

- 通常

```Java
Integer score = 100;
String result = "";
if(score>=60){
    result = "合格";
}else{
    result = "不合格";
}
System.out.println(result);
```

- 三項演算子

```Java
Integer score = 100;
String result = (score >= 60)?"合格":"不合格";
System.out.println(result);
```



# C

- 通常

```C
int score = 100;
char *result;
if(score >= 60){
    result = "合格";
}else{
    result = "不合格";
}
printf("%s",result);
```

- 三項演算子

```C
int score = 100;
char *result = (score >= 60) ? "合格":"不合格";
printf("%s",result);
```




# C\# 

- 通常

```C#
int score = 100;
string result = "";
if(score>=60){
    result = "合格";
}else{
    result = "不合格";
}
System.Console.WriteLine(result);
```

- 三項演算子

```C#
int score = 100;
string result = (score >= 60)?"合格":"不合格";
System.Console.WriteLine(result);
```
DDQNについて何となく理解してること

※この記事にはソースコードは一切ありません
※まだ理解しきれているとは言い難いので、もし間違っていればご指摘お願いします

#はじめに
　今、Ape-XをKerasで実装しようとしているけど、それに使われている手法「DDQN(Double Deep Q Network)」の理解がようやくできたので書いていきます。

#DDQNの誕生
　まず、DDQNが誕生した経緯を説明していきます。
　従来使われていたDQN(Double Q NetWork)では、行動を決定するときに使うネットワークと、あとでその行動を評価するときに使うネットワークが同じであることが問題でした。言い換えると、自分の行動を自分で評価しているため、過大評価・過小評価になってしまうということです。
　これを解決するために、自分の行った行動を「第三者」に評価してもらおう、というのがDDQNの基本的な考え方です。

#DDQNの流れ
　まずは疑似コード(っぽいもの)を書いてみます。

```Python:DDQN
行動決定用ネットワークを定義
価値計算用ネットワークを定義
経験を保存するためのMemoryを定義

for epoch in range(試行回数):
    行動決定用ネットワークによる行動決定(a)
    実際にaを行ってみる(b)
    Memoryに(行動前の状況・行動・行動後の状況・報酬)を格納

    行動決定用ネットワークの重みを価値計算用ネットワークにコピー
    if Memory.len()>batch_size(=学習が可能なくらい経験がたまった):
        学習()

def 学習():
    Memoryから一定数取り出す(batchに格納)
    batchのそれぞれのデータについて、そのときの次の状態(state(time+1))における行動を行動決定用ネットワークを使って選択
    選択した行動を価値計算用ネットワークで評価。
    これに割引率をかけたものとそのとき得られた報酬(reward(time))を足し合わせて教師用データに
    state(time)はターゲットデータ(ねっっとワークに与える情報)にする
    
    ターゲットデータと教師用データで行動決定用ネットワークを更新
```

こんな感じです
こうすると、ループの初め(行動決定(a)のとき)で、
行動決定用ネットワークは学習後の状態に
価値計算用ネットワークは学習前の状態に
なります。

(Ape-Xのコードは[github](https://github.com/Luke256/Ape-X)にあります（2020年12月21日時点制作中）)

参照ページ
[【強化学習初心者向け】シンプルな実装例で学ぶQ学習、DQN、DDQN【CartPoleで棒立て：1ファイルで完結、Kearas使用】](https://qiita.com/sugulu_Ogawa_ISID/items/bc7c70e6658f204f85f9)
プログラマ向けmacOSで使える有料アプリのおすすめ

よく見かける記事は無料のばっかりなので有料アプリ版。

## PathFinder
$36.00
Finderの高機能版。タブ表示や2画面表示、フォルダを上書きじゃなくてマージコピーできる。いまはもうFinderでもできるんだっけ？
気に入ってる機能はドロワーとドロップスタック。ドロップスタックは複数のファイルを一時的にスタックに置いて一括操作ができる機能。これは他のアプリでもあまり見かけない気がする。
[Home - Cocoatech](https://cocoatech.com/#/)

## TablePlus
$59.00
RDB操作ツール。まだSequelPro使っててMySQL8に困ってるならさっさと乗り換えるのがおすすめ。
対応DBはこんな感じ。
![スクリーンショット 2020-12-21 15.27.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126845/708ab74b-70cb-055e-5850-b7e41227a837.png)
[TablePlus | Modern, Native Tool for Database Management](https://tableplus.com/)

PostgreSQL だけを使う人なら [Postico](https://eggerapps.at/postico/)(4,199円) でも良い。

## Paw
$49.99
RESTクライアント。API 開発するときに使える。URLやデータに変数も使えるし、環境を prod, local と定義してサーバのURLとかログイン用のメールアドレス、APIキーなどワンクリックで切り替えられる。
Swaggerの読み書き、curl用のコマンド出力など欲しい機能は完全に揃ってる。
[Paw – The most advanced API tool for Mac](https://paw.cloud/)

## OmniGraffle
$249.99
macOS版Visio。説明用の図を書くときはこれ。Visio形式のファイルも扱えるらしいけど使ったことない。
[Visual Communication Software To Make Pro Diagrams - OmniGraffle - The Omni Group](https://www.omnigroup.com/omnigraffle/)

Omni系はたぶん全部買ってていまは OmniFocus と OmniGraffle を使ってる。

## BetterTouchTool
$8.50
キーボードとかマウスのカスタマイズ用ソフト。ウインドウを移動させるときにタイトルバーを掴まないで Control + マウスだけで動かせるのが良い。Control + Shift + マウス だけで拡大・縮小もできる。
[folivora.ai - Great Tools for your Mac!](https://folivora.ai/)

## Quiver
1,220円
プログラマ用の多機能ノートアプリ。MarkdownやLaTexで書ける。Vimキーバインドがあってこれにしてる。無料でも使える。
[‎「Quiver - take better notes」をMac App Storeで](https://apps.apple.com/jp/app/quiver-take-better-notes/id866773894?mt=12)
JavaScript,14,日付を取得・表示,Date,

14,JavaScriptで日付を取得・表示などをするための方法

JavaScript（ジャバスクリプト）のDateオブジェクトを使って、
今日の日時や曜日などを取得・表示してみましょう！
基本が分かったら、明日の今の日時を表示したり、
ある日付までのカウントダウン日を表示させてみる方法を紹介しています。

```
const today = new Date();
days = ["日", "月", "火", "水", "木", "金","土"]

console.log(today.getFullYear());
console.log(today.getMonth() + 1);
console.log(today.getDate());
console.log(today.getHours());
console.log(today.getMinutes());
console.log(today.getSeconds());
console.log(days[today.getDay()]);
```

月は０が１月　１が２月　になるので＋１すること
曜日に関しては０１２３４の数値になるので
配列を作っておく

```
      days = ["日", "月", "火", "水", "木", "金","土"]

let outputtext = "今は";
outputtext += "「" + today.getFullYear() + "年";
outputtext += (today.getMonth() + 1) + "月";
outputtext += today.getDate() + "日";
outputtext += today.getHours() + "時";
outputtext += today.getMinutes() + "分";
outputtext += today.getSeconds() + "秒";
outputtext += "(" + days[today.getDay()] + ")";
outputtext += "」です";

document.getElementById("date").textContent = outputtext;
```

今は「2020年12月14日0時40分47秒(月)」です


```
const today = new Date();
      days = ["日", "月", "火", "水", "木", "金","土"]

function outputDate(date) {
  let outputtext = "「" + date.getFullYear() + "年";
  outputtext += (date.getMonth() + 1) + "月";
  outputtext += date.getDate() + "日";
  outputtext += date.getHours() + "時";
  outputtext += date.getMinutes() + "分";
  outputtext += date.getSeconds() + "秒";
  outputtext += "(" + days[date.getDay()] + ")";
  outputtext += "」です";
  return outputtext;
}
document.getElementById("date").textContent = "今は" + outputDate(today);

today.setDate(today.getDate() + 1);
document.getElementById("tomorrow").textContent = "明日の今は" + outputDate(today);
```


今は「2020年12月14日0時54分29秒(月)」です
明日の今は「2020年12月15日0時54分29秒(火)」です

today.setDateはまた新たに日を取得する



```
const targetDate = new Date(2021, 7 -1, 23);
document.getElementById("countDown").textContent = "オリンピックまであと" + Math.ceil((targetDate - today) / (1000 * 60 * 60 * 24)) + "日";
```


オリンピックまであと221日

new Date(2021, 7 -1, 23)
この指定した日までのカウントダウン

Math.ceil端数切り上げ
ActiveModel で ActiveRecord と同等のバリデーションを可能にする (before_type_cast)

# 現状の動作
ActiveModelを利用して作成したフォームクラスが存在する

```ruby:hoge_form.rb
class HogeForm
  include ActiveModel::Model
  include ActiveModel::Attributes
  include ActiveModel::AttributeMethods

  attribute :number, :integer
  validates :number, numericality: { only_integer: true }
end
```

`number` に対して整数の値以外が来た場合、バリデーションエラーにしたい

```ruby:検証
form = HogeForm.new
form.number = 'hoge'
form.valid?
# => true
form.number
# => 0
```
`hoge`を代入しても内部で`integer`にキャストされてしまい、バリデーションエラーにならない

# 期待する動作

`ActiveRecord`で同様のことを行うと、キャストする前の値に対してバリデーションをかけるため、エラーになる
`ActiveModel`でも同様にエラーになることを期待する

# 調査
`ActiveModel` の `numericality` のバリデーションの実装のソースコードは[こちら]
(https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations/numericality.rb)

バリデーションの検証に使う値を特定するメソッドを引用

```ruby:activemodel/lib/active_model/validations/numericality.rb

      def prepare_value_for_validation(value, record, attr_name)
        return value if record_attribute_changed_in_place?(record, attr_name)

        came_from_user = :"#{attr_name}_came_from_user?"

        if record.respond_to?(came_from_user)
          if record.public_send(came_from_user)
            raw_value = record.public_send(:"#{attr_name}_before_type_cast")
          elsif record.respond_to?(:read_attribute)
            raw_value = record.read_attribute(attr_name)
          end
        else
          before_type_cast = :"#{attr_name}_before_type_cast"
          if record.respond_to?(before_type_cast)
            raw_value = record.public_send(before_type_cast)
          end
        end

        raw_value || value
      end
```
雑に読んだところ `#{attribute}_before_type_cast` の実装があればその値を利用するようだ

`ActiveModel` には `before_type_cast` 周りの機能が入っていないため、キャスト後の値でバリデーションを行っている


# 解決方法

`ActiveModel` に `before_type_cast` の機能が入っていれば `ActiveRecord` と同等のバリデーションになりそう

`ActiveRecord` で `before_type_cast` の機能を実装しているソースを探した
https://github.com/rails/rails/blob/2a0d4950398d1c5b5cd73186ac5269a9afa933e8/activerecord/lib/active_record/attribute_methods/before_type_cast.rb

このモジュールをフォームクラスで`include`する

```ruby:hoge_form.rb
class HogeForm
  include ActiveModel::Model
  include ActiveModel::Attributes
  include ActiveModel::AttributeMethods
  # 追加
  include ActiveRecord::AttributeMethods::BeforeTypeCast
  

  attribute :number, :integer
  validates :number, numericality: { only_integer: true }
end
```

## 動作確認

```ruby:動作確認]
form = HogeForm.new
form.number = 'hoge'
form.number # cast 後の値
=> 0
form.number_before_type_cast # before_type_cast が使えている
=> "hoge"
form.valid?
=> false # invalidな状態
form.errors.messages
=> {:number=>["は数値で入力してください"]} # 数値でない(hoge)のでエラー

form.number = 1.5 # 小数を代入
=> 1.5
form.number # castされて1
=> 1
form.valid? # invalid
=> false
form.errors.messages
=> {:number=>["は整数で入力してください"]} # ちゃんとcast前の1.5に対してバリデーションされている
```

# あとがき
あるべき論だとActiveModelにBeforeTypeCastが取り込まれるのが良いと思います
`ActiveRecord::AttributeMethods::BeforeTypeCast` を `include` しても副作用が起きそうには見えなかったのですが
推奨されるものでは無さそうです(不具合の責任は取りません)


弊社コラビットではRailsエンジニアを募集しています
https://github.com/collabit-inc/job-offer-engineer
アナログ回路 その17

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。

# トランジスタ・ダーリントン接続回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/93cce0e7-c559-5cd6-a6ba-a2fc5ee4a346.jpeg)


# 結果

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c103446c-f115-3a2e-3b91-219d165fc853.jpeg)


# 説明

増幅率を上げたい場合に使う。


# 成果物

https://embed.plnkr.co/plunk/XyCOGbIVjiDPlspU


以上。
javasript, jquery（オブジェクトへのイベントの追加）

#初めに
オブジェクトへのエベントを追加する
### ①html、 javasriptのツールの開発
　→オンラインツールを使えるため、ツールのダウンロードが不要です。
　　　https://jsfiddle.net/

![スクリーンショット 2020-12-21 10.23.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/f1eea67f-b1b5-cb0e-569d-d28db2bae1f8.png)


### ②HTML分に以下のHTMLソースを追加する
```html

<html>

  <head>
    <title>Hoge</title>
  </head>

  <body id="main-id">
  </body>

</html>
```

### ③JQUERYを選択してから、JAVASRIPT分に以下のソースを追加する
```javascript

//マインオブジェクト
var $main  = $("#main-id");

//ulオブジェクトに変換する
var $ul = $("<ul>");    

//liオブジェクトに変換する
var $li = $("<li>").html("hoge");

//親オブジェクトに子オブジェクトを追加
$ul.append($li);
$main.append($ul);
```

![スクリーンショット 2020-12-21 15.07.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/5aee59f0-24ef-e07d-4819-4bfabe0ab3fb.png)


### ④オブジェクトへのクリックイベントの追加

　　①クリックイベントを追加　

```javascript

// liオブジェクトへのクリックイベントを追加する
$li.click(function() {
   // class-textのCSSが存在する場合、削除する
   if($li.hasClass("class-text")) {
      $li.removeClass("class-text");
   
   // class-textのCSSが存在しない場合、追加する
   } else {
       $li.addClass("class-text");
   }
});
```
　　②CSSクラスを追加

```css

.class-text {
  font-size: 50px;
}
```

イメージ
![スクリーンショット 2020-12-21 15.20.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/1e6eae3c-a4da-12f4-240f-59bc209b6252.png)

実行
→・hogeテキストをクリックすると、文字列が大きくなる
![スクリーンショット 2020-12-21 15.26.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/9765bd77-d8a1-93b3-ec79-d935f1634e69.png)


#jQueryにはクリックイベント以外、いろいろなイベントがあります。
例）.change()など

```javascript

//選択ボックスオブジェクト
var $select = $("<select>");
$select.change(function(){
    //todo
});
```

jQueyの参考ページ
https://api.jquery.com/category/events/


以上
[ServiceNow]インスタンスのバージョンを知る方法

インスタンスのバージョンを知る方法をITSM Fundamentalsの研修で知ったので記載します。

# ServiceNowインスタンスのバージョン
ServiceNowインスタンスのバージョンは年に2回アップデートされます。
2020年12月現在の最新バージョンはParisになります。

## インスタンスの（メジャー）バージョンを調べる方法

### 確認方法
1. アプリケーションナビゲータに[stats.do]と入力し、Enterキーを押下  
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/bbbd0031-fe2f-98c1-ffb8-6b2283f32b48.png)
<br>
2. 「Build name」の値がバージョン情報
以下のインスタンスは、Orlandoということがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/364826fd-0cd1-7613-a247-df3c82ffe3bd.png)

# ServiceNowのバージョンの歴史
以下のリンクから確認可能です。
https://www.servicenow.com/community/now-platform-articles/servicenow-versions-release/ta-p/2312014
timedatectl set-timezone Asia/Tokyoコマンドで、 zsh: command not found: timedatectlというエラーが発生してしまう。

### timedatectl set-timezone Asia/Tokyoコマンドで、 zsh: command not found: timedatectlというエラーが発生してしまいます。

環境構築でタイトルのコマンドを実行した際にcommand not foundエラーが発生してしまいました。
パスの設定が必要だと仮説をしておりますがパスの設定記事が見つからずにいます。

どなたかご教授お願いいたします。
Google Slides APIを使ってみた

# はじめに
ABEMAの広告プロダクト開発でサーバーサイドエンジニアをしているimaiです。

今回は[CyberAgent PTA Advent Calendar 2020](https://adventar.org/calendars/5741)の22日目の記事になります。

# きっかけ
部署内でプレゼン資料を自動で作成したい。ってお話があったのでGoogle Slidesを編集するアプリを作成しました。
そこで **Golang** にて **Slides API** を実行して実現しておりその中で得た知見を気していこうと思います。

# 実行してみる
### サービスを作る
[クイックスタート](https://developers.google.com/slides/quickstart/go)では `slides.New(client *http.Client)` を使用していますがこれは **Deprecated** となっているので `slides.NewService(ctx context.Context, opts ...option.ClientOption)` を使用します

```golang
import (
	"context"
	"log"

	"golang.org/x/oauth2"
	"google.golang.org/api/option"
	"google.golang.org/api/slides/v1"
)

func newSlidesService(ctx context.Context, tokenSource oauth2.TokenSource) *slides.Service {
	srv, err := slides.NewService(ctx, option.WithTokenSource(tokenSource))
	if err != nil {
		log.Panicf("failed to slides new service: %+v", err)
	}
	return srv
}
```

### テキストを挿入する
```golang
func setText(requests []*slides.Request, objectID, text string) []*slides.Request {
	return append(requests, &slides.Request{
		InsertText: &slides.InsertTextRequest{
			ObjectId: objectID, // 挿入先のオブジェクトID
			Text:     text,     // 挿入するテキスト
		},
	})
}
```

### ページを削除する

```golang
func deleteSlides(requests []*slides.Request, objectID string) []*slides.Request {
	return append(requests, &slides.Request{
		DeleteObject: &slides.DeleteObjectRequest{
			ObjectId: objectID, // 削除するページのオブジェクトID
		},
	})
}
```

### スライドの並び替え
`InsertionIndex` には先頭ページが0からのページ番号を指定します

```golang
func sortSlides(requests []*slides.Request, index int64, objectIDs []string) []*slides.Request {
	return append(requests, &slides.Request{
		UpdateSlidesPosition: &slides.UpdateSlidesPositionRequest{
			InsertionIndex: index,     // 挿入するページ番号
			SlideObjectIds: objectIDs, // 並び替えるスライドのオブジェクトID
		},
	})
}
```

### 更新

```golang
func update(slidesSrv *slides.Service, requests []*slides.Request, slidID string) {
	_, err := slidesSrv.Presentations.BatchUpdate(slidID, &slides.BatchUpdatePresentationRequest{Requests: requests}).Do()
	if err != nil {
		log.Panicf("failed to batch update: %+v", err)
	}
}
```

# 最後に
Slides APIには他にも便利なのがありそうなので色々試す価値はありそうです。
技術的な側面だけではなくビジネス的な側面から必要なの、便利になるのを探るのも良さそうですね。
SourceTree アプリにて、Git LFS を設定する方法

# SourceTree アプリにて、Git LFS を設定する方法

SourceTree（git管理ツール）にて、画像や動画（容量が大きいファイル）等をgit管理するかどうか悩んだ末（容量が大きいと警告が表示されたり、あとでリポジトリが使えない事態にもなる（経験上））、やっぱり容量が大きいからgit管理していなかった方、その方にLFSを利用しgit管理できるようにする簡単な方法を共有いたします。

##環境
- システムの種類：MacOS
- SourceTree（ https://www.sourcetreeapp.com/ ）

##方法
1.コミットを目前にしている案件があるとする。
![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/90715eb7-a247-f8d3-6dbf-46d506e6c8cb.png)

2.メニューにて、「リポジトリ」ー＞「Git LFS」ー＞「リポジトリの初期化」をクリックする。
![スクリーンショット 2020-12-17 11.55.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/b12c9738-b983-83b8-7389-2e3ad8a1ae6a.png)
（「Git LFSとは？」というところで、説明は読んでみよう。）

3.「Git LFSを利用する」をクリックする。

4.「追跡しているGit LFS:」の「＋」をクリックし、対象ファイルを*.拡張子（または直接ファイル名）を登録する。
![スクリーンショット 2020-12-17 11.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/0e179d3c-e1ac-1a5d-f7cb-070fc08e96b0.png)

5.「トラックファイル」をクリックする。

＊もちろん、git コマンドでもLFSは利用できるので、やってみよう。

OK
【Vue.js】はじめてのOSS -OSS初心者がコントリビューターになるまで-

## はじめに
本記事はOSS初心者（というかはじめて）の私がVue.jsでコントリビューターになるまでのお話です。
（※2020/12/21現在、PRを出している最中なのでm、厳密にはコントリビューターではありません。笑）

## きっかけ
単純に英語を勉強したいな、と思っていたのと、OSSってコードのメンテナンスや機能開発以外にも道があるので、ゴリゴリにコードかけなくてもOSS参加できるよ！ということと、ゴリゴリにコード書くだけがエンジニアの価値じゃないよ！ということを伝えたかったのでチャレンジしてみました。

## 何をやったか
平たくいうと、Vue.jsのドキュメントの翻訳をやりました！

Vue.jsは2020年9月にVue 3.0.0がリリースされ、Vue.jsのコミュニティ内（Slack内）で翻訳されてないものがある、ということだったので覗いてみたところ、分量も多くなく、Google 翻訳やDeepLなども使って良いということだったので、チャレンジしてみました。


## OSSコントリビュートまでの手順
言語やライブラリ、フレームワークによって違うと思いますがVue.jsの場合は[こちらに記載](https://github.com/vuejs/jp.vuejs.org/blob/lang-ja/CONTRIBUTING.md)されているような手順で進みます。
大雑把にかくと

* GitHubのリポジトリをフォークする
* フォークしたリポジトリからブランチを生やしてコツコツとコミットを積んでゆく
* できた！と思ったらプルリクを出す
* レビューしていただく
* OKならばマージされ、無事にコントリビューターに🎉

いやあ、意外と簡単ですね！こんな僕でもOSSコントリビューターになれるなんて！
（※2020年12月21日時点ではまだコントリビューターになっていないけど）

## フォークした後の開発環境構築

* 今回は普段開発でも触ったことあるVue.jsの開発環境構築だったので、そんなに手間取ることはなく

`npm install`
`npm run dev`
のコマンドを叩いてlocalhost:8080にアクセスすると

こんな感じの画面が出てきてくれます。Vue.jsのドキュメント画面ですね。（これはVue2系のものをキャプチャしています）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/e4bfbecd-0d1c-0781-6c44-191d8fd4e5c7.png)


## いざ、OSSコントリビュート！
* まずはサクサクと1文ずつDeepLとGoogle翻訳に入れていきます。
* 次に、翻訳された文章の意味を自分が理解できるかを確認します。
* 理解できない場合、意味がわかりにくい場合は、その箇所に使われている英語の構文や単語をもう少し掘り下げて調べます。
* その作業を終えて、（自分として）理解しやすい文になったな、と思ったら次の文にいきます
* 以後、上記の手順を繰り返し…

※書いているファイルはmarkdownなので、.mdファイルの記法は知っておくと読みやすいかもしれません。（エンジニアなら誰でもわかると思うけど…）

翻訳している時の様子はこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/58650799-da2d-68b9-d52b-5bbc57369b88.png)


* 全てができたら、 元のリポジトリに対してプルリクエストを出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/a53b6288-4398-f962-2fc4-a2a46479eb62.png)

* レビュアーがレビューしてくださるので、修正を積み重ねていきます。
* 無事にLGTMが出たら晴れてコントリビューターです🎉

## つまづいたポイント
* jp.vue.js.orgとja.vue.js.orgがあって、最初間違えてフォークしてた…
* 日本語のlintがあるので、そこでめっちゃ引っかかった（半角と全角の文字の間には半角スペースを開けるなど）

## 所感
意外とあっさりPRを出すところまでいけました。
追って、コントリビューターになったら記事を更新したいと思います！
アナログ回路 その16

# 概要

circuit sandboxをplunkerでホスティングした。
アナログ回路をシュミレーションで、説明してみる。

# トランジスタ・プッシュプル回路

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/48831099-4194-968e-ac5e-3e3d2fdde8e9.jpeg)


# 結果

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3619e69e-bf2a-f120-7e64-e464b327f5cc.jpeg)



# 説明

プラス側は、npnトランジスタが動作し
マイナス側は、pnpトランジスタが動作する。


# 成果物

https://embed.plnkr.co/plunk/8EGvpJ64tb4BwHPq


以上。
WindowsへのPrestoドライバ設定

# せっかくなのでQiitaへ
Redshift DBができるまでの間、暫定運用のtableauの抽出更新作業をご自身でやっていただくために記します。

# TDでのAPIキー発行
### まずログイン
https://console.treasuredata.com/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/85807918-4ff6-ab52-5c53-4d5453616c36.png)

### 画面左下のMy Profile
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/c96dad4f-31ed-32a7-761a-c89ffc173e20.png)

### API Keysを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/ffc23b52-226d-cf4a-5a59-244912d8c486.png)


### API keyの一覧が出てくるので画面右上のActionsからCreate Api Key

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/96b6de4c-0ba3-352c-c9a8-4d16d78ebea0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/57570941-e82f-4ae7-abf3-ef6d161bc098.png)

### 分かりやすい名前を付けてSave
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/40078a53-1dd6-2b29-7221-7467c953169c.png)

### 今作ったやつがでてくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/ede80372-e2c4-f311-7e51-e1b087dea94f.png)


### 選択してコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/4c27a3da-98c2-cf95-f466-18c7e5a82cfe.png)

## Windows のODBCに設定していきます
### PrestoドライバをPCにインストール
https://docs.treasuredata.com/display/public/PD/ODBC+Driver+for+Presto
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/f99873ce-d2fa-5472-2beb-9639e8c125ae.png)

### ダウンロードしたドライバをインストール
こういうのが出るかもしれないので出た場合は詳細→実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/5d06fc1a-b729-4c04-18b8-35e0c41137be.png)

### Next
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/6275031b-7e45-3354-ab7e-2a44c2ae9e5a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/84882123-2410-829b-004f-65cc0dbdfdaa.png)

### インストールが終わったら設定するためODBC administratorを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/91e90c14-2c1b-dda6-123a-c7482d4c27ad.png)

### システムDSNタブを選択
ちゃんとインストールされていればTreasuredata presto ODBC driverが出ているはずなので、選択して構成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/52f41e6a-d8bf-51be-92a1-2ebf2dec3a75.png)

### 先ほど作成したAPIキーを（TD API KEY）の部分に入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/f6e92f42-4e76-7006-876f-75f315e0f66b.png)

### Test おして下記の画面でればOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143512/4e55acf2-f100-0803-6ff9-09838c3a3b9c.png)
Pannellum にて、Adobe AnalyticsのTrack links を設定方法

# Pannellum にて、Adobe AnalyticsのTrack links 設定方法

Adobe Analytics（Google Analyticsのような分析ツール）を使用するが、どうTrack links(対象のリンクをクリックしたかどうかを計測)を設定すればよいか、しかもPannellum（360度画面を実装するためのライブラリー）でどう設定すればよいか悩んでいる方に、設定方法を共有いたします。

##環境
- システムの種類：-
- Pannellum（https://pannellum.org/）
- Adobe Analytics（https://www.adobe.com/jp/analytics/adobe-analytics.html）

##方法
1.Adobe Analyticsのアカウントにログイン、計測scriptを取得して、head, bodyタグ内に設定する。
　（ここの詳細は割愛する）

headタグ内
![111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/87689375-e8ad-fc74-3f1e-f77b6c5b5892.png)
bodyタグ内
![222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/957ac75b-608d-0c83-f172-c9a427d5e6dc.png)

2.Pannellumで使用している「hotSpots」内目的のところに、"clickHandlerFunc"を設置、クリックイベント関数名を記載する。（今回例：AAA）

3."pannellum.viewer(..."より上に、クリックイベント関数名（今回例：AAA）を記載、その中に
tlコアコンポーネントを設定する。（今回計測名称の例：AAA result）
![333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676239/c5e97182-382f-d901-a503-b4fb114e0e6a.png)

＊注意点１：関数は"pannellum.viewer(..."より上に記載すること。
＊注意点２：clickHandlerFuncで記載する関数名にダブルクォーテーションは記載しないこと。
　"clickHandlerFunc": "AAA"　（X）、"clickHandlerFunc": AAA　（O）

4.動作はChromeの拡張機能（Adobe Experience Cloud Debugger）をインストールして確認しよう。
https://chrome.google.com/webstore/detail/adobe-experience-cloud-de/ocdmogmohccmeicdhlhhgepeaijenapj?hl=ja&gclid=CjwKCAjw7IbaBRBqEiwA6AyZgjGVojxLR2JEgcJQc8YvLb9ttuWZ7RGKRaXUO-I14rGy1ZIa2J8uvhoC5qQQAvD_BwE


＊参考サイト：
- pannellumの option説明：https://pannellum.org/documentation/reference/
- Adobe Analyticsの tlメソッド説明：https://experienceleague.adobe.com/docs/analytics/implementation/vars/functions/tl-method.html?lang=ja-JP#vars
- 他：https://stackoverflow.com/questions/53494240/pannellum-clickhandlerfunc

OK
【Ruby on Rails】has_secure_passwordについて

#はじめに
has_secure_passswordメソッドについてまとめてみた。

#has_secure_passwordとは
has_secure_passwordは、パスワードをハッシュ化（暗号化）してくれるメソッド。

このメソッドを使う為に以下二つを行う必要がある。
・`bcrypt`というgemを追加すること。
・データベースに`password_digest`というカラムを作成すること。


##使い方
以下のように、モデルファイルに定義する。

```ruby:user.rb
class User < ApplicationRecord
~
~
~
 has_secure_password
end
```

##使える機能
・2つのペアの仮想的な属性が使えるようになる。（`password`と`password_confirmation`）
・`autheticate`メソッドが使えるようになる。


###２つの仮想属性について
・`password`属性
データベースに保存される。（仮想属性なので、テーブル上には見えない）

・`password_confirmation`属性
データベースに保存されない仮想の属性で、パスワードの入力確認が行われる。
この属性を使用すると、`password`属性と`password_confirmation`属性の双方が一致しているかのバリデーションが自動的に追加されるようになっている。

補足
`password_digest`属性には、`password`属性に入れた値をハッシュ化した値を入れる。


###autheticateメソッドについて
`authenticate`メソッドはパスワードが一致しているかどうかを確認するメソッド。

```terminal
001:0> user = User.find_by(email: "example.com")

002:0> user.password_digest  #パスワードのハッシュ値を確認する。ハッシュ化されていることを確認する。
=> "$2a$10$YmQTuuDNOszvu5yi7auOC.F4G//FGhyQSWCpghqRWQWITUYlG3XVy"

003:0>user.authenticate("not_the_right_password")  #間違ったパスワードを入力する
=> false

004:0>user.authenticate("foobar")  #正しいパスワードを入力する
=>　#<User id: 1, name: "example_user", email: "exampleuser@example.com",
created_at: "2014-07-25 02:58:28", updated_at: "2014-07-25 02:58:28",
password_digest: "$2a$10$YmQTuuDNOszvu5yi7auOC.F4G//FGhyQSWCpghqRWQW...">

005:0>!!user.authenticate("foobar")  #頭に「!!」をつけることで論理値を取得する。
=> true
```
IntelliJ IDEAのHTTPクライアントが使いやすい話

この記事は[Voicy Advent Calendar 2020](https://qiita.com/advent-calendar/2020/voicy)の21日目の記事です。
昨日は@moonumの[DRMで音声コンテンツを不正利用から守る(Android + ExoPlayer) part 1](https://numamyk.medium.com/drm%E3%81%A7%E9%9F%B3%E5%A3%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%82%92%E4%B8%8D%E6%AD%A3%E5%88%A9%E7%94%A8%E3%81%8B%E3%82%89%E5%AE%88%E3%82%8B-android-exoplayer-part-1-f76210f2d800)でした。

# はじめに

直近はAPIの開発をしていて、エンドポイントの動作確認を行うことが多かったので使い勝手の良いHTTPクライアントないかなーと改めて探してみたら、え、IDEAについてるやん・・・となり使ってみたら結構良かったので紹介してみることにしました（IDEAに限らず他のJetBrains製品のIDEなら多分ついてるのかも？）。ちなみに以前はPostmanを使っていました。

# 準備
準備と言っても特段ないんですが、リクエストを記述するためのファイルを作成します。
`.rest`か、`.http`として作ればHTTPクライアントがそれと認識してくれます。
なので、自分で適当にファイル名をつけて作成するか、Scratchファイル作成から作ればOKです。
ScratchファイルはMacなら Shift+Command+N から HTTP Request を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125095/27650e12-be5a-704d-f054-0e9b2fac813b.png)


# 文法
IDEAのHTTPクライアントはGUIがあって画面のどこに何を書いてという形ではなく、スクリプトチックです。
基本はこんなかんじ↓

Method Request-URI HTTP-Version
Header-field: Header-value

Request-Body

# やってみる
上記の文法になぞらえていくつかリクエストの例を並べてみます。

```
// 普通のGET
GET http://example.com

### 

// Bodyを指定してPOST
POST http://example.com/api/users
Content-Type: application/json

{
  "id": 1,
  "name: "natacon"
}

```

`###`はファイル内で利用できるセパレーターで、同ファイルにリクエストを複数書けます。
ただのGETは特段説明不要ですね。
POSTのほうも読んだままですが、一点挙げるとしたらHeader-filedとRequest-Bodyの間は一行あける必要があります。

使ってみると地味にうれしいところがあって、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125095/b05cc3d4-2493-5e5d-9ec2-74f416fa1083.png)
こんなふうに実行した結果を履歴で勝手に保存しておいてくれて、かつ行数のとなりに出ているアイコンからこの結果同士を比較する画面を簡単に開けたりします。このあたりは開発中の変更が見つけやすくて重宝します。
邪魔な方は`@no-log`をつけてあげるとでなくなります。

```
// @no-log
GET http://example.com
```

# 変数が使いやすい
Postmanとかでももちろんあるんですが、エンジニアの手に馴染む形ではないかなーというところ。
IDEAではJSON形式で設定できるようになっていて、`http-client.env.json`もしくは`http-client.private.env.json`ファイルをプロジェクトに配置することによって変数定義を行えます。

例えばこんなふうに環境ごとのリクエスト先を定義しておいて、

```json
{
  "local": {
    "baseUrl": "localhost:8080/v1/api"
  },
  "dev": {
    "baseUrl": "https://dev.example.com/v1/api"
  },
  "stage": {
    "baseUrl": "https://stage.example.com/v1/api"
  },
  "prod": {
    "baseUrl": "https://example.com/v1/api"
  }
}
```

リクエストファイルはこうする。
変数参照は`{{variable}}`として二重波括弧で囲む。

```
GET {{baseUrl}}/users
```
こうしておくと実行時に下記のようにどの変数割り当てて実行する？と聞いてくれるので実行したい環境の切り替えも楽。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125095/4240b3fa-206f-9840-d89c-3a67dd41cbd8.png)


# おまけ
私はいまのところあまり使うことがなかったのですが、レスポンスの検証も行えます。
軽い実装例だと、こんなレスポンスがあったとします。

```
{
  "users": [
    {
      "id": 1,
      "name" "natacon"
    },
    {
      "id": 2,
      "name" "yuichi"
    }
  ]
}
```
それに対しリクエストを下記のようにするとusersオブジェクトの要素数を取得できます。
JavaScript ECMAScript 5.1で書けます。

```
GET http://example.com/api/users

> {%
  // IDEA側にresponseオブジェクトを作ってくれてる
  client.log(response.body.users.length)
%}
```
assertとかを使えるので、こういった値などをテストするように書いておけば、ミニマムに手元で一気にエンドポイントの動作確認を行えたりするのです。

# おわりに
社内勉強会でもJetBrains製品マジおすすめだよという発表をしたり、またこの記事書いたりほんとズブズブの関係なのですが、マジオススメ。
【PHP】オブジェクトのコピーは clone を使う


# ハマったポイント

オブジェクトは参照型なので、代入した際に代入先で値を変更すると代入元の値も変更されてしまう。

```php
$user = new User();
$user->name = '太郎';

$user2 = $user;
$user2->name = '次郎';

$user->name; // 次郎
$user2->name; // 次郎
```

# 結論
`clone`を使う

```php
$user = new User();
$user->name = '太郎';

$user2 = clone $user;
$user2->name = '次郎';

$user->name; // 太郎
$user2->name; // 次郎
```
macOSにRをHomebrewでインストール

Mac(macOS Big Sur)にRをインストールしようとしたところ、予想外に手こずってしまったので備忘録メモを残しておこうと思います。

# OpenBLASのインストール
行列演算ライブラリのOpenBLASをインストールします。Rをインストールすると自動的にビルド済の物がダウンロードされインストールされますが、[参考](https://glong355.hatenablog.com/entry/2020/10/24/164623)より、ソースからビルドしてインストールすることで高速化が期待出来る様です。(ソースビルドに時間が掛かりますが、気長に待ちましょう)

```bash
brew install openblas --build-from-source
```

# コンソール版Rをインストール
ターミナル上で`R`コマンドでRを起動出来るようにしたいので、まずコンソール版のRをインストールします。

```
brew install r
```

# Rコンソールのインストール
Rコンソール(GUI)をインストールする場合は、`--cask`オプションを付けてHomebrewを実行します。

```bash
brew install --cask r
```

# XQuartzのインストール
最後にXQuartzをインストールします。これをインストールしないと何故かRコマンドが動作しません。以下よりインストーラーをダウンロードします。

* [XQuartz](https://www.xquartz.org/)

`XQuartz-2.7.11.dmg`がダウンロードされるのでダブルクリックし、ディスクイメージをマウントします。以下のウィンドウが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/a277a4cd-200c-89ec-a59d-51a20ab6a749.png)

`XQuartz.pkg`をダブルクリックし、後はウィザードに従ってインストールします。

# OpenBLASの関連付け
最初にソースをビルドしてインストールしたOpenBLASとRの関連付けを行います。

```bash

mv /usr/local/Cellar/r/4.0.3_1/lib/R/lib/libRblas.dylib /usr/local/Cellar/r/4.0.3_1/lib/R/lib/libRblas.dylib.org
ln -s /usr/local/opt/openblas/lib/libopenblas.dylib /usr/local/Cellar/r/4.0.3_1/lib/R/lib/libRblas.dylib
```

# 起動確認
ターミナルで`r`と入力し、Rが起動すればインストール完了です。

```bash
$ r

R version 4.0.3 (2020-10-10) -- "Bunny-Wunnies Freak Out"
Copyright (C) 2020 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin20.1.0 (64-bit)

R は、自由なソフトウェアであり、「完全に無保証」です。 
一定の条件に従えば、自由にこれを再配布することができます。 
配布条件の詳細に関しては、'license()' あるいは 'licence()' と入力してください。 

R は多くの貢献者による共同プロジェクトです。 
詳しくは 'contributors()' と入力してください。 
また、R や R のパッケージを出版物で引用する際の形式については 
'citation()' と入力してください。 

'demo()' と入力すればデモをみることができます。 
'help()' とすればオンラインヘルプが出ます。 
'help.start()' で HTML ブラウザによるヘルプがみられます。 
'q()' と入力すれば R を終了します。 

> 
```

# Reference
* [経済学修士残酷物語](https://glong355.hatenablog.com/entry/2020/10/24/164623)
* [Mac に X11 (XQuartz) をインストール](https://macperson.net/mac-x11-xquartz/)
* [OS XにRをインストールする2種類の方法の検討](https://qiita.com/tatzyr/items/584b6f9e185423dd3d40)
* [Mac OS X に Homebrew で R をインストールする](https://blog.amedama.jp/entry/2016/10/12/211749)
BigSur で "wchar.h: No such file or directory" コンパイルエラー

## きっかけ
MacBook に BigSur をクリーンインストールして、Homebrew で gcc を入れてから、g++ で C++ をしてみると、以下のエラーが出てコンパイルできなかった。

```console
$ g++ main.cpp
（・・・中略・・・）
/usr/local/Cellar/gcc/10.2.0/include/c++/10.2.0/cwchar:44:10: fatal error: wchar.h: No such file or directory
   44 | #include <wchar.h>
      |          ^~~~~~~~~
compilation terminated.
```

## 環境

- MacOS BigSur
- zsh 5.8
- g++ 10.2.0

## 模索

https://qiita.com/yoya/items/c0b26cba3c040c581643
こちらの記事で知ったのですが、、Xcode10 からは、インクルードファイルは、`/usr/include/` の中ではなく、SKD の中のものを使う仕様に変更されたようです。（以下、Xcode10 のリリースノート）

>  The command line tools will search the SDK for system headers by default.
 However, some software may fail to build correctly against the SDK and
require macOS headers to be installed in the base system under /usr/include.
 If you are the maintainer of such software, we encourage you to update
your project to work with the SDK or file a bug report for issues that are
preventing you from doing so. 

そこで、SDK がどこにあるか探してみます。

```console
$ xcrun --show-sdk-path
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
```

つぎに、g++ がどこからインクルードを読み取ってるかを調べてみます。

```console
$ /usr/local/bin/g++ -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/g++
（・・・中略・・・）
 --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX11.0.sdk 
（・・・後略・・・）
```

```
$ ls /Library/Developer/CommandLineTools/SDKs
MacOSX.sdk     MacOSX11.1.sdk
```

## 原因と解決

どうやら、g++ 自体は Xcode の変わった規定に対応していたようですが、なにかしらの拍子で改変されたか、Mac のファイルが事故で消えたかで、参照がうまく行っていなかったようでした。alias で正しい参照をするようにしておきます。

```shell:.zshrc
alias g++='g++ --sysroot=`xcrun --show-sdk-path`'
```

## 参考サイト

他の原因によるエラーの場合もあるので、その際は以下を参照してみてください。
- [macOS 'wchar.h' File Not Found (Stack Overflow)](https://stackoverflow.com/questions/26185978/macos-wchar-h-file-not-found)
- [Can't compile C program on a Mac after upgrade to Mojave
 (Stack Overflow)](https://stackoverflow.com/questions/52509602/cant-compile-c-program-on-a-mac-after-upgrade-to-mojave)
- [Build issues on macOS Catalina (fatal error: 'wchar.h' file not found) #1055 (GitHub)](https://github.com/imageworks/OpenShadingLanguage/issues/1055)
[Rails]中間テーブルを用いたタグ付け機能の実装(Gemなし)

# 目標
チェックボックスを複数選択し、中間テーブルを介してタグ付け機能を実装する。

# 開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

# E-R図
<img width="902" alt="スクリーンショット 2020-12-21 10 58 14" src="https://user-images.githubusercontent.com/68432256/102731569-7e10ca00-437b-11eb-8910-2dbec495771a.png">
上記の画像は今回の実装するイメージです。
今回は私が実装したサウナの種類を複数選択して登録する例で話させていただきます。

# 事前準備
画像のようなサウナを新規作成する画面を用意しました。
今回の話で使用するのは、`サウナジャンルの複数のチェックボックスを選択して中間テーブルであるサウナジャンルを用いて実装する`方法です。
登録機能など基本的な機能は実装済みの前提でお話させていただきます。
<img width="442" alt="スクリーンショット 2020-12-21 11 07 41" src="https://user-images.githubusercontent.com/68432256/102732050-f4fa9280-437c-11eb-8386-736c124c5f05.png">

# モデルにアソシエーションを記述する

```ruby:app/models/sauna.rb
class Sauna < ApplicationRecord
  has_many :sauna_genres, dependent: :destroy
  has_many :genres, through: :sauna_genres
end
```

```ruby:app/models/sauna_genre.rb
class SaunaGenre < ApplicationRecord
  belongs_to :genre
  belongs_to :sauna
end
```

```ruby:app/models/genre.rb
class Genre < ApplicationRecord
  has_many :sauna_genres
  has_many :saunas, through: :sauna_genres
end
```

### controller

```ruby:app/controllers/saunas_controller.rb
  def create
    @sauna = Sauna.new(sauna_params)
    @sauna.user_id = current_user.id
    if @sauna.save
      redirect_to user_sauna_path(@sauna)
    else
      render 'new'
    end
  end

 #省略

   def sauna_params
    params.require(:sauna).permit(
      :name,
      genre_ids: []
    )
  end
```
`genre_ids: []`は複数チェックボックスの値を配列で渡すことを許可しています。



```java:html.erb
<div>
  <%=f.label :genre_ids, "ジャンル機能" %>
  <span>
    <% Genre.all.each do |genre| %>
      <%= f.check_box :genre_ids, 
         { multiple: true, checked: @sauna.genres.find_by(id: genre.id).present?, 
         include_hidden: false }, genre[:id] %>
       <label class="form-check-label">
         <%= genre.name %>
       </label>
     <% end %>
  </span>
</div>
```
`form.check_box :label_ids`→　paramsの値として、`"label_ids"=>["1", "2", "3"]`このような形でハッシュのキーを持つ値を送れます。
`multiple`オプションを使用することで、複数のチェックボックスのパラメータを配列形式で送れます。
`checked: @task.labels.find_by(id: label.id).present?`これは編集画面等で登録されている`ラベル`にチェックを付けるということをしています。
`include_hidden: false`→登録のない項目については、パラメータを送らないメソッドです。

***このまま実装すると一見複数中間テーブルも作成できるし、編集の時もしっかりチェックついてるし問題ない***と思っていたのですが、編集画面でチェックを全て外して更新してもジャンルの複数の名前は消えなかったのです。
何が原因か、、、この実装方法だと、***空で送ってしまうと値としてnilが返ってきてしまいます。***
それを解決するためにストロングパラメーターを少し工夫します。

```ruby:app/controllers/saunas_controller.rb
#省略

  def sauna_params
    values = params.require(:sauna).permit(
      :name,
      genre_ids: []
    )
    if values[:genre_ids].nil?
      values[:genre_ids] = [] 
    end
    return values
  end
```
このようにすることでgenre_idsにもしnilが返ってきた時に空の配列を送ることでジャンルを持たないものも作成することができました。
ジャンルを作っている以上、ジャンルなしということはないとは思いますが、気づいたので備忘録として残しておきます。

ありがとうございました
docker psで指定したコンテナのIDのみ取得する

## 抽出

```
docker ps -f "name=postgres*" -q
```

## 便利な使い方
- IDをいちいち確認しなくて良くなる

```
docker exec -it $(docker ps -f "name=postgres*" -q) psql -c 'DROP DATABASE testdb'
```
【GRU,RNN,LSTM】作家の作品をもとに作家らしい文章生成をしてみよう

## はじめに
この記事は筆者が学習上作成したnlpモデルを説明したものです。初学者向けの内容になります。具体的にはGRU,LSTM,RNNを使用して芥川龍之介を再現しました。

##環境
Google Colaboratoryを使いますので、googleアカウントを持っている方なら誰でも使うことができます。
言語はPythonです。

##Google Colaboratoryとは
Googleが提供しているデータサイエンス用のノート型シェルです。言語はPythonだけでなく他の言語も対応しています。Google Colaboratoryは非常に手軽かつGPUを使用でき、機械学習や大規模の数理モデルの計算に通常のCPUだと30分かかるところを数分ほどで計算できます。

##コードとコーパスの配布
こちらのgithubにて配布しております。
https://github.com/Kokusho-gif/nlp_akutagawa
akutagawa.ipynbというファイルとコーパス（未整形の学習元データ）が入っているフォルダです。
ノート(ipynb)にはあらかじめコードの説明文を記載しているので、それらを読めばこの記事は必要ないかもしれません。これらのファイルをGoogleDriveにアップロードしてください。akutagawaフォルダごとあげると楽かと思います。

僕の場合My Drive直下にakutagawaフォルダを置きました。
GoogleDriveにアップできましたら、akutagwa.ipynbファイルを右クリックし、アプリで開く→Google Colaboratoryを選択して開きましょう。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392111/405f901b-863e-3386-7452-cf8be5217f3c.png)


##コード説明
Google Driveにアップロードしたテキスト（学習用データ）にアクセスできるようにする
上2行はGoogleDriveを参照するために必要なコードです。

```python
from google.colab import drive
drive.mount('/content/drive')
```
My Driveへパスを移動したいます。自分の場合このフォルダ直下のakutagwaフォルダにファイルがあります。ここは皆さんのアップした場所によって変わります。

```python
%cd drive/'My Drive'
%ls
```
要インストール:ノート内で%pip install globとうって実行してください。

glo.glob関数を用いて、学習用に用いるテキストファイルをlist形式で得る。

```python
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline
```

```python
import glob
files = glob.glob("./akutagawa/corpus/*.txt")
print(len(files))
```

mecabライブラリが標準で入っていないのでGoogleColabにインストールします。

```python
!apt install aptitude
!aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
!pip install mecab-python3==0.7
```
Mecabを用いて文章を単語ごとに分割します、がその前に元の文章には不要な記号や記述、学習を妨げる特殊な文字（いわゆる外れ値）があるので、
まずreライブラリを用いて消去してます。

その後、Mecab.Tagger()ドライバを用いてフォルダにあるテキストファイル20個までについて形態素解析（単語へ分割）したのち、一つのリスト(text_all)へ格納。できればファイルの数だけ読み込みをしたかったがデータ量が莫大になってしまったため20個に断念。


```python
import re
def making_data(file):
  with open(file,mode='r',encoding='shift_jis', errors='ignore') as f:
    text_original = f.read()

  text = re.sub("《[^》]+》", "", text_original) # ルビの削除
  text = re.sub("［[^］]+］", "", text) # 読みの注意の削除
  text = re.sub(".*-", "", text, flags=re.DOTALL) #-より上の部分の削除
  text = re.sub("（[大正|明治.年]+.*", "", text, flags=re.DOTALL) #＃地付きより下の部分の削除
  text = re.sub("\n.\n", "", text, flags=re.DOTALL) #題名の削除
  text = re.sub("\n", "", text) #改行の削除
  text = re.sub("[0-9]+|[０-９]+", "", text, flags=re.DOTALL) #数字の削除
  text = re.sub("[Ａ-Ｚ]+|[A-Z]+|[a-z]+", "", text, flags=re.DOTALL) #全角英語の削除
  text = re.sub("[｜ 　―\,\，./「」\：\:（）＊×…※△『』〜＼／]", "", text) # 各種記号の削除
  text = re.sub("\[\［", "", text)
  text = re.sub("\]\］", "", text)





  return text
```

```python
import MeCab
m = MeCab.Tagger('-Owakati')
text_all = []
for i in range(20):
    text = making_data(files[i])
    text = m.parse(text)
    text = text.split(' ')
    text_all.extend(text)
```

以降続きは配布したノートに書いてあるのでそちらを参照してください。
React Component に HTMLElement を流し込む

React の Component が持つ `ref` 属性はコールバック関数を受け取れます。
コールバック関数は引数としてComponent 自身 の DOM要素が渡り、マウント時に実行されます。
したがって、以下のようにして Component （が render されてできる DOM要素）の子要素に HTMLElement を追加できます。

```react
<ReactComponent ref={ref => ref?.appendChild(_HTMLElement)} />
```

ライブラリが HTMLElement を返す場合、React Component との接点として、以下のコンポーネントを用意します。

```react
const ReactHTMLElement: React.FC = ({children}) => {
    return (
        <div ref={ref => ref?.appendChild(children)} />
    )
}
```

JSX の自然な構造として、React Component に HTMLElement を流し込むことができます。

```react
<ReactHTMLElement>
  {_HTMLElement}
</ReactHTMLElement>
```
Pythonで学ぶアルゴリズム　第8弾：アルゴリズムの評価

# #Pythonで学ぶアルゴリズム< アルゴリズムの評価 >

##はじめに
基本的なアルゴリズムをPythonで実装し，アルゴリズムの理解を深める．
その第8弾としてアルゴリズムの評価を扱う．今回は実装はしないが，アルゴリズムを学んでいく中で，どのようにアルゴリズムを評価するのかという基礎的なところをまとめる．

##プログラムはどのように評価するのか？
実装していくつかのデータで計測し1つ1つ試して評価する？

単純な発想でわかりやすいが，次のような問題が出てくる
・プログラム設計時には評価できない
・環境や言語に依存するかもしれない

だから…
**計算量(Computational Complexity)**という考えがある

##計算量(Computational Complexity)
計算量には時間計算量や空間計算量，ほかにも通信計算量や回路計算量など，様々なものがある．

プログラム上でよく評価の指標として使われるのが時間計算量と空間計算量である．
**時間計算量**：処理時間を指す
**空間計算量**：メモリなどの記憶容量をどれくらい必要とするのかを指す

例）
フィボナッチ数列を幾つか記憶した状態でプログラムすれば，時間計算量は減らせるが，事前に記憶するための空間計算量が大きくなる．

##擬似的処理時間
実際の処理時間$[s]$を測ると，実行環境にも影響し得るため，その1つの処理に対してかかる時間を定数とし，繰り返し数に比例するという形にして，これを計算量としてとらえて評価する．

例えば，次のようにfor文で50回まわし，1回ずつprint処理をすることを考える．

```python
for i in range(50):
    print(i)
```
このとき，print1回の処理時間を$a$とすると，このプログラムの処理時間は$a\times50$と考えられる．これを50ではなく，任意数$n$回とすると，その処理時間は$a\times50$と考えることができる．

```python
n = 100 # 任意数
for i in range(n):
    print(i)
```
これは，ある処理に対して，プログラム処理時間はデータ数$n$に比例しているといえる．
ほかにも例を挙げる．

```python
n = 100 # 任意数
for i in range(n):
    for j in range(n):
        print(i)
```
この場合，処理時間は$a\times n \times n=a\times n^2$と考えられる．（$n^2$に比例）

```python
n = 100 # 任意数
for i in range(n):
    for j in range(n):
        for k in range(n):
            print(i)
```
このようにfot文3つを入れ子状態にすると，処理時間は$a\times n \times n \times n=a\times n^3$と考えられる．（$n^3$に比例）

このようにある定数にデータ数$n$を掛け合わせて，処理時間がデータ数に対してどのように関係しているのかというのを処理時間と考えたものを擬似的処理時間とし，次に示すオーダー記法の考えになる．

##オーダー記法
$n$個のデータに対してどのくらいの割合で処理時間がかかるのかを$O$(~)の形で表したもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/2df9b0b2-9ac1-d565-bda6-0dc2c11fff7f.png)

##感想
今まで，時間[s]で処理時間を計測して，いくつかのアルゴリズムを評価していたが，今回のオーダー記法というものを知って，確かに，環境や言語に依存し得るものに対してはこのような共通の指標というものは大事だと思った．ただ，単純にあるアルゴリズムと他の方法の相対的な評価であるならば，実際にかかった時間で評価することもありなのかと感じるとともに，実際にそのようなことで評価している論文もあるからそうなのだろうと思う．ただ，アルゴリズム自体の絶対的評価（そのアルゴリズムは本当に優秀なのか）というのであれば，オーダー記法のほうが分かりやすく，信頼性があると思う．「for文を回しすぎるのはよくない」ということをpythonを学び始めたころに聞いたことがあったが，このことだったんだなと納得できた．

##参考文献
Pythonで始めるアルゴリズム入門　伝統的なアルゴリズムで学ぶ定石と計算量
　　　　　　　　　　　　　　　　　　　　　　　　 増井 敏克　著　　翔泳社
レスポンシブ対応 ~電話番号のCSSが反映されない問題~

レスポンシブ対応していて、safariでのcssだけ反映されないという問題が起きたので、
対処法を記します。

状況をもう少し具体的にいいますと、
①電話番号が表示されず、②（電話番号記載の個所を）タップすると表示される。
という状態になりました。

結論として、head要素内で次のmeta要素を記述すればOKです。

```<meta name="format-detection" content="telephone=no">
```

#参考リンク
https://gray-code.com/html_css/how-to-delete-auto-link-of-telephone-number/
Swift CombineにてhandleEventsのクロージャがコールされない

Combineを使用する際に勉強不足が故にハマってしまったので、備忘録として残します。

# 問題

関数から返されるFuture型の変数にて

```swift
func handleEvents(
    receiveSubscription: ((Subscription) -> Void)? = nil, 
    receiveOutput: ((Output) -> Void)? = nil, 
    receiveCompletion: ((Subscribers.Completion<Failure>) -> Void)? = nil, 
    receiveCancel: (() -> Void)? = nil, 
    receiveRequest: ((Subscribers.Demand) -> Void)? = nil
) -> Publishers.HandleEvents<Future<Output, Failure>>
```

をコールしてクロージャ内で処理を行いたいが、クロージャが実行されない。

https://developer.apple.com/documentation/combine/future/handleevents(receivesubscription:receiveoutput:receivecompletion:receivecancel:receiverequest:)

# 解決方法

```swift
func sink(
    receiveCompletion: @escaping ((Subscribers.Completion<Failure>) -> Void), 
    receiveValue: @escaping ((Output) -> Void)
) -> AnyCancellable
```

上記のsinkをコールするなりして、サブスクライバーを接続する必要がある。

https://developer.apple.com/documentation/combine/future/sink(receivecompletion:receivevalue:)

# 原因

当初は以下のコードを実装し、promise(.success(()))が実行されたタイミングでhanleEventsによって設定したクロージャがコールされると思った。
が、コールされない。

```swift
// Playgroundにて実行
import Combine
import Foundation

struct APIError: Error {
    var description: String
}

func delay() -> Future<Void, Error> {
    return Future<Void, Error>{ promise in
        print("実行されます")
        Thread.sleep(forTimeInterval: 2.0)
        promise(.success(()))
        return
    }
}

func executionDelay() -> AnyPublisher<Void, Error>{
    print("実行します")
    return delay()
        .handleEvents(receiveSubscription: {_ in
            print("Subscription")
        }, receiveOutput: { _ in
            print("Output")
        }, receiveCompletion: { _ in
            print("Completion")
        }, receiveCancel: {
            print("Cancel")
        }, receiveRequest: {_ in
            print("Request")
        })
        .eraseToAnyPublisher()
}

// 処理を実行
executionDelay()
```

handleEventsのリファレンスを読むと、「Performs the specified closures when publisher events occur.」とあり、パブリッシャーイベントが発生した時にクロージャが実行されるとのこと。
しかし、よくよく考えると、サブスクライバーに接続されていないことに気づいた。
sinkメソッドをコールしてサブスクライバーを接続する必要がある。

改善したコードが以下のもの。

```swift
import Combine
import Foundation

func delay() -> Future<Void, Error> {
    return Future<Void, Error>{ promise in
        print("実行されます")
        Thread.sleep(forTimeInterval: 2.0)
        promise(.success(()))
        return
    }
}

func executionDelay() -> AnyPublisher<Void, Error>{
    print("実行します")
    return delay()
        .handleEvents(receiveSubscription: {_ in
            print("Subscription")
        }, receiveOutput: { _ in
            print("Output")
        }, receiveCompletion: { _ in
            print("Completion")
        }, receiveCancel: {
            print("Cancel")
        }, receiveRequest: {_ in
            print("Request")
        })
        .eraseToAnyPublisher()
}

// 処理を実行
executionDelay()
    .sink(receiveCompletion: {completion in
        print("receiveCompletion")
        switch completion {
        case .failure(let error):
            print("失敗：\(error)")
        default:
            print("成功")
        }
    }, receiveValue: { _ in
        print("receiveValue")
    })
```