OmniAICreator/Qiita-1.07M huggingface dataset:
Rubyのヒアドキュメント (行指向文字列リテラル)について

### 概要

Rubyのヒアドキュメント（行指向文字列リテラル）について簡潔に要点をまとめます。
複数行に渡る長い文字列をスッキリ書けます。

## 識別子の種類

### <<識別子

```ruby

word = <<TEXT
長い長い文字列をヒアドキュメントで簡潔に書こう。
長いSQLを叩く時も、ヒアドキュメントを利用すれば上手く書けます。
TEXT

#"長い長い文字列をヒアドキュメントで簡潔に書こう。\n長いSQLを叩く時も、ヒアドキュメントを利用すれば上手く書けます。\n"

#識別子は、自由につける事が出来ます。

word = <<LIGHTTEXT
長い長い文字列をヒアドキュメントで簡潔に書けるよ。
長いSQLを叩く時も、ヒアドキュメントを利用すれば上手く書けるよ。
LIGHTTEXT

#"長い長い文字列をヒアドキュメントで簡潔に書けるよ。\n長いSQLを叩く時も、ヒアドキュメントを利用すれば上手く書けるよ。\n"

```

###<< -識別子
<< -をつけると、終端のEOS（SOUND）をインデントさせる事が出来ます。


```ruby
class Animal
  def roar
  <<-SOUND
  grrr
  baww
  SOUND
end

#"    grrr\n    boww\n"

```

### << ~識別子
~（チルダ）を識別子の手前に置くと、内部の文字列をインデントさせても、先頭の空白部分が無視されます。

```ruby

class Animal
  def roar
  <<~SOUND
  grrr
  baww
  SOUND
end

#"grrr\nboww\n"
```

### 式としての識別子

メソッド引数としてもヒアドキュメントを使用出来ます。
（引数呼び出し時に、()で冒頭識別子を閉じる必要があるので、その点に注意が必要です。）

```ruby
lang = "Japanese"
lang.prepend(<<TEXT)
 English
 Chinese
TEXT

#" English\n Chinese\nJapanese"

```
引数として渡す場合でも、上記の~や-を使用しインデント付与や先頭の空白文字除去が可能です。

```ruby
lang.prepend(<<~TEXT)
 English
 Chinese
TEXT

#"English\nChinese\nJapanese"

```

```ruby
lang.prepend(<<-TEXT)
 English
 Chinese
TEXT

#" English\n Chinese\nEnglish\nChinese\nJapanese"
```
SQLのクエリを引数として渡す際にも、ヒアドキュメントが使えます。

```ruby
Post.find_by_sql(<<~QUERY)
  SELECT p.title, b.author
  FROM posts p, books b
  WHERE p.id = b.post_id
QUERY
```
複数の引数の一部にのみ、ヒアドキュメントを使用する事も出来ます。

```ruby
class Vihicle
  def run(city: "tokyo road", time: "12:00", speed: nil)
    p "run on #{city} at #{time} by #{speed}"
  end
end

car = Vihicle.new()
car.run(time:<<~TIME, speed: "100km")
 24:00
TIME

#"run on tokyo road at 24:00\n by 100km"

```
ワンラインで複数のヒアドキュメントの一括指定も可能です。

```ruby
#Ruby 2.7.0 リファレンスマニュアルより引用

print <<FIRST_DOC, <<SECOND_DOC
   これは一つめのヒアドキュメントです。
   まだ一つめです。
FIRST_DOC
   この行からは二つめのヒアドキュメントです。
   この行で終わります。
SECOND_DOC
```

## メソッド呼び出し

```ruby
word = <<TEXT.upcase
Chao,
Goodbye
TEXT

#"CHAO,\nGOODBYE\n"
```

### 参考
[リテラル (Ruby 2.7.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html#here)
[Rubyのヒアドキュメントの書き方いろいろ](https://blog.toshimaru.net/ruby-heredoc/)
[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774193976)
相対パスの書き方（特に`./`と `../`）を段階的に学ぶ記事

# 本記事の目的

* 相対パスの書き方（特に`./`と `../`）がイマイチ掴めない人が段階的に理解できるようにするため（自分の備忘録）
* ルート相対パスは本記事では対象外

# お詫び

「枝分かれ」や「階層」という表現が適切ではないかもしれません。あくまでイメージだと思っていただけると。


# 絶対パスと相対パスの違い

<dl>

<dt>絶対パス</dt>
<dd>・ピンポイントで対象のファイルを指すことができる。
</dd>
<dd>・但しフルパスを書く必要があり、ドメインがなくローカル環境で作業している状態などでは使用できない</dd>

<dt>相対パス</dt>
<dd>・現在のページを起点に辿るようにしてパスを指定する</dd>
<dd>・現在のページが属するフォルダ名を「../」と省略に近い形で書ける</dd>
<dd>・ドメインがなくてもパスが書ける</dd>

</dl>

# 相対パスのルール（`./`と `../`）

現在のページが属する階層やその上の階層は、フォルダ名をわざわざ書かなくても以下のように表せる。

- `./`：現在の階層を表すが省略可能で通常は省略する
- `../`：1つ上の階層を表す。
    - 2つ上：`../../`
    - 3つ上：`../../../`

## 現在の階層（同じフォルダ内）にあるファイル

`./home.html`でもいいが、`./`は通常省略するのでファイル名のみでOK。


```html:相対パス：home.html
homepage
　┣ index.html（現在のページ）
　┗ home.html（対象）
```

## 1つ上の階層

```html:相対パス：../
homepage（対象）
　┗ index.html（現在のページ）
```


## 2つ上の階層

```html:相対パス：../../
top（対象）
　┗ homepage
　　┗ index.html（現在のページ）
```

# 枝分かれした別のフォルダのファイルを指定する場合

* 今までのように現在のページから辿るように`../`で階層を上がっていく。
* 枝分かれした別のフォルダなのでフォルダ名をしっかりと記述する。

## 1つ上の階層→枝分かれ先にあるファイル

```html:相対パス：../sample.html
top
　┣ homepage
　┃　┗ index.html（現在のページ）
　┗ sample.html（対象）
```

## 1つ上の階層→枝分かれして1つの下の階層

```html:相対パス：../sample/sample.html
top
　┣ homepage
　┃　┗ index.html（現在のページ）
　┗ sample
　　 ┗ sample.html（対象）
```


## 2つ上の階層→枝分かれして2つの下の階層

```html:相対パス：../../sample/sample2/sample.html
top
　┣ homepage
　┃　┗ web
　┃　　┗ index.html（現在のページ）
　┗ sample
　　 ┗ sample2
　　 　┗ sample.html（対象）
```

# 同じ階層にある枝分かれしたファイルを指定する場合

ポイント：同じ階層だから頭に何もつけないでOK

## 同じ階層→枝分かれして1つ下の階層

```html:相対パス：dummy/dummy.html
homepage
　┣ index.html（現在のページ）
　┗ dummy
　　┗ dummy.html（対象）
```

## 同じ階層→枝分かれして2つ下の階層

```html:相対パス：dummy/dummy2/dummy.html
homepage
　┣ index.html（現在のページ）
　┗ dummy
　　┗ dummy2
　　　┗ dummy.html（対象）
```


以上です。

---

<details>
<summary>参考記事</summary>
<ul>
<li>[絶対パス、相対パス、ルート相対パスをわかりやすく解説！まずはイメージをつかもう！ | D-FOUNT -大阪・京都のグラフィックデザイン／Webデザイン-](https://d-fount.com/absolute-path-and-relative-path/)
<li>[相対パスについて - HP作成講座](http://juen-cs.dl.juen.ac.jp/html/hp/03/02/explanation.html)
</ul>
</details>
django transaction.atomic() + 自前エラークラス


を書くんだよ

tryの中でこけると、user.save()はrollbackされる。
うまくいったところだけ保存したいならwith transaction.atomic()は外す

```python

class UserNameError(BaseException):
    """ UserName must contain two '@' s. An example is 'MailAddress@Organization_name'"""
    pass

...

    if organization.name != params["name"]:
        users = User.objects.filter(organization_id=organization_id)
        try:
            with transaction.atomic():
                for user in users:
                    user_name = user.username
                    if (ユーザー名の形式をチェックする条件):
                        user.username = params["name"]
                        user.save()
                    else:
                        # usernameが形式通りではないユーザー名を変更しようとした時は、何もしない
                        raise UserNameError(f"""UserName {params["name"]} はユーザーネームが形式通りではないと思います的な英語などのメッセージ""")
        except Exception:
            return None

...

```
Vivado 2020.2.2 でPost-Synthesis Simulationが[XSIM 43-3255], [XSIM 43-3217], [USF-XSim-62]で停止する場合の対処法

#エラー内容
```:TCL_console
INFO: [USF-XSim-61] Executing 'COMPILE and ANALYZE' step in '<Project>/<Project>.tmp/<IP>_ip_v1_0_project/<IP>_ip_v1_0_project.sim/sim_1/synth/func/xsim'
xvlog --incr --relax -prj testbench_1_vlog.prj
ERROR: [XSIM 43-3255] File name is missing.
ERROR: [XSIM 43-3217] testbench_1_vlog.prj (line 3): Incorrect project file syntax. Correct syntax is one of: vhdl <worklib> <file>, verilog <worklib> <file> [<file> ...] [[-d <macro>] ...] [[-i <include>] ...], or NOSORT. Presence of NOSORT on a line of its own disables file order sorting.
INFO: [USF-XSim-69] 'compile' step finished in '2' seconds
INFO: [USF-XSim-99] Step results log file:'<Project>/<Project>.tmp/<IP>_ip_v1_0_project/<IP>_ip_v1_0_project.sim/sim_1/synth/func/xsim/xvlog.log'
ERROR: [USF-XSim-62] 'compile' step failed with error(s). Please check the Tcl console output or '<Project>/<Project>.tmp/<IP>_ip_v1_0_project/<IP>_ip_v1_0_project.sim/sim_1/synth/func/xsim/xvlog.log' file for more information.
ERROR: [Vivado 12-4473] Detected error while running simulation. Please correct the issue and retry this operation.
ERROR: [Common 17-39] 'launch_simulation' failed due to earlier errors.
```

```:..../sim_1/synth/func/xsim/xvlog.log
# compile verilog/system verilog design source files
verilog xil_defaultlib  \
"testbench_1_func_synth.v" \

verilog   \
"../../../../../../../../ip_repo/<IP>_ip_1.0/hdl/testbench.v" \

# Do not sort compile order
nosort
~
```

#対処法
https://support.xilinx.com/s/question/0D52E00006iHilWSAS/error-xsim-433217-incorrect-project-file-syntax-even-with-a-library-selected?language=ja

Testbenchのソースコードにライブラリが設定されていなかったのが原因
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427718/705120db-7e47-56a8-c51d-ac31f97c0d85.png)

ここでxil_defaultlibに設定することでシミュレーションが走り出した。

(検索用：Google検索が[]内のキーワードを拾ってくれないので)
XSIM 43-3255
XSIM 43-3217
USF-XSim-62
Vivado 12-4473
Common 17-39
Ubuntuバージョン確認/アップデート

#Ubuntuの更新
忘れすぎて何回ググったか分からないくらいになってきているのでいい加減まとめます。

##バージョン確認
```
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```

##アップデート
```
$ sudo apt-get update
```

##アップグレード
```
$ sudo apt-get upgrade
```
AWS cloud9で、rails serverが起動しない時にやったこと。

#AWS cloud9で、rails serverが起動しない時にやったこと。


昨日中断するまでは起動していたはずの`＄　rails server`を再開しようとしたら

```ruby:qiita.rb
Could not find gem 'puma (= 3.9.1)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
```

出たよと思いつつ、とりあえず`＄　bundle install`をしてみる。

```ruby:quitta.rb

$ buindle install

Command 'buindle' not found, did you mean:

  command 'bundle' from snap ruby (3.0.2)
  command 'bundle' from deb ruby-bundler

See 'snap info <snapname>' for additional versions.
```


豪快にスペルを間違えるも、本人はなんかエラー出てるなと流し見して気づかず、` $ bundle install `ではない。と決めつけて、ググる。

:::note alert
エラーは本当によく読もう（笑）
:::
　
なので、最初にスペルミスをしなかった場合の結果が分からないのが悔しい。
また次のエラーで会いましょう。

それはさておき、私が解決した方法は、[こちらの記事](https://qiita.com/ibarakishiminn/items/94bbee2109304468bf53
)を参考にしました。

実際にこのコマンドを上から入力して解決しましたが、なぜ解決したのかはわかりません。
もっと勉強していけばわかるようになると思っていますが、足踏みしていられないので試しました。


```ruby:quitta.rb

#remove user-specific gems and git repos
$ rm -rf ~/.bundle/ ~/.gem/

# remove system-wide git repos and git checkouts
$ rm -rf $GEM_HOME/bundler/ $GEM_HOME/cache/bundler/

# remove project-specific settings and git repos
$ rm -rf .bundle/

# remove project-specific cached .gem files
$ rm -rf vendor/cache/

# remove the saved resolve of the Gemfile
$ rm -rf Gemfile.lock

# try to install one more time
$ bundle install
```
M1macにmatplotlibを入れる

# はじめに

M1macでmatplotlibをimportしたらエラーが出る
numpy関連のエラーらしい
TensorFlow-macosをインストールしてあるからnumpyでエラーが出るのはおかしい
調べてみたら追加でパッケージをインストールしないといけないらしいのでまとめる

# matplotlibを使えるようにする
1. numpyをインストール
1. matplotlibをインストール
1. libjpegをインストール

1は既にnumpyを入れてる人は不要
ただし私はTensorFlow-macosをインストールした際に一緒にインストールしたものなので、それ以外の方法でインストールした人は知らない

# numpyをインストール

私の[この記事](https://qiita.com/he-mo/items/1ceda6e0c1465c6b18ad)を参考にtensorflow-macosをインストール

そしたら一緒にnumpyがインストールされる

# matplotlibをインストール

普通にpipでインストール

```
pip install matplotlib
```

# libjpegをインストール

下のコマンドを叩いく

```
brew install libjpeg
```
GoogleAnalytics のRetention viewをPythonで模倣する

# なにがしたいか

GoogleAnalyticsからの出力を得てレポート化する案件があり、無理やりスクリプト化しました。
Imageとして出力して終わりでもよかったのですが、グラフ中にキャプションを入れたり、微妙にいじる必要があったので、一度数値に落として再描画するという中途半端なソリューションになってしまいました。

以下のビューをレポートに入れたい、ただそれだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146939/21ea721e-e8ab-6005-d251-226b7c0107b1.png)

バージョンはGA3用になります。

# そんなやり方でよいのか？

だったら、最初からログ分析しろ、ってところですが、このソリューションの良いところは、

- Google Analyticsのretention計算の結果と完全に一致する
- 上記のスナップショットを一時的に保存できる
- 見た目をいじれる
- 場合によっては後処理を加えられる（使いにくいが）

などです。


# コード

## データの読み出し

GAのキーを使って読み出します。ga_utilというライブラリが、つつがなくdata frame化してくれるので苦労は皆無です。

``` Python
import pandas as pd
import numpy as np
import ga_util as ga
from pylab import rcParams
KEY_FILE_LOCATION = 'client_secrets.json'
VIEW_IDApp = '00000000'
analytics = ga.gar_initialize_analyticsreporting()
week = 12
response = ga.gar_get_retention_report(analytics,VIEW_IDAndroidApp,week)
dfAndroid = ga.gar_decodeResponse(response)
response = ga.gar_get_retention_report(analytics,VIEW_IDiOSApp,week)
dfiOS = ga.gar_decodeResponse(response)
df = (dfAndroid[0] + dfiOS[0]) / (dfAndroid[1] + dfiOS[1])
df.columns = ["{}th week".format(int(x)) for x in df.columns]
df
``` 

これでこうなります：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146939/eca3da34-38ac-20c6-2c42-285681306d7c.png)
ここから先はただのお絵かきです。

## それっぽく表示

``` Python
import matplotlib.pyplot as plt
import seaborn as sns

rcParams['figure.figsize'] = 16,12
# get retention for both OS, Android, iOS
retention = (dfAndroid[0].sum() + dfiOS[0].sum()) / (dfAndroid[1].sum() + dfiOS[1].sum())
retentionAndroid = (dfAndroid[0].sum()) / (dfAndroid[1].sum() )
retentioniOS = ( dfiOS[0].sum()) / (dfiOS[1].sum())

# plot time series
plt.subplot(2, 1, 1)
plt.plot(retention,marker='o', color='r',label="combined")
plt.plot(retentionAndroid,marker='^', color='g',label="Android")
plt.plot(retentioniOS,marker='x', color='b',label="iOS")

# plot x
pos = np.arange(len(retention))
plt.xticks(pos, df.columns)
ax = plt.gca()
# plot oresen: y
plt.ylim([0,1])
plt.yticks([0,0.25,0.5,0.75,1])
vals = ax.get_yticks()

# plot texts
plt.title("retention rate (%) - Android/iOS combined")
plt.legend(loc = 'upper right')
plt.grid(True, which='major', axis='y')
ax.set_yticklabels(['{:,.2%}'.format(x) for x in vals])
txt = "{0:2.1%} of total ********************".format(retention[0]-retention[1])

plt.annotate(txt, xy=(1,retention[1]), xytext=(0.5, 0.2),arrowprops=dict(arrowstyle="->"),fontsize=16,color="red")
plt.subplot(2, 1, 2)

#  heatmap
sns.heatmap(df, annot=True, fmt='2.1%', cmap='coolwarm', annot_kws=None ,linewidths=.5,vmin = 0.3,vmax=0.7)
ax = plt.gca()
ax.tick_params(top=True, bottom=False,
           labeltop=True, labelbottom=False)
# save image
plt.savefig("fig_retention_rate.png", bbox_inches='tight', dpi=200)
```

これで少し色ランプは違いますが、似たようなビューができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146939/7f082e83-1d2d-e143-9558-f4a293193d50.png)


# まとめ

こんな事をして同じ見た目にするのにどんな意味があるのか、今一歩利点がわからないかもしれませんが、ここから発展させたレポートが必要な場合に、特に自動化されたキャプションなどを、毎度作るのが面倒な局面では、結構有益ではないでしょうか？
【Ruby】present?はblank?の真逆のメソッド

##present?
```!blank?``` を実行するメソッド
```nil```, ```""```, ```" "```(半角スペースのみ),  ```[]```(空の配列), ```{}```(空のハッシュ) のときにfalseを返す


##blank?
```nil?``` + ```empty?``` のようなメソッド
```nil```, ```false```, ```""```, ```" "```(半角スペースのみ), ```[]```(空の配列), ```{}```(空のハッシュ) のときにtrueを返す





##参考

https://railsdoc.com/page/empty

https://qiita.com/go_d_eye_0505/items/541110cb9821734b0623
[Kotlin]webViewの読み込み中に画面遷移したらアプリが落ちてしまう

#前置き
viewBindingを使用したプロジェクトの話です。
#概要
webView付きのFragmentでHTMLの読み込みが終わるまで同じ画面で待っていれば問題は発生しませんが、読み込み途中で別のFragmentに画面を遷移させるとアプリが落ちてしまいます。
ネットで検索しても結局対応策が見つけられなかったのでここに共有したいと思います。
#本文

```kotlin
class WebViewFragment : Fragment() {
    private var _binding: FragmentWebViewBinding? = null
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentWebViewBinding.inflate(inflater, container, false)
        binding.webView.loadUrl("https://www.google.com/?hl=ja")
        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        // webView読み込み中の画面遷移によるエラーを防止する為の終了処理
        binding.webView.stopLoading()
        binding.webView.destroy()

        _binding = null
    }
}
```

#補足
webViewの読み込み処理はFragmentを移動した後も継続するので、ちゃんと終了させる必要があります。

エラー自体はbindingが元で起きているので、viewBindingを使っていないプロジェクトならこの処理は必要無いと思います。
【RSpec】let!で定義した値がnilを返す現象

テストを書いていてlet!で定義した値がなぜかnilで返ってくる現象に時間をとられたので
もう引っかからないようにまとめる。

##テスト失敗
pryでデバッグしたところ```cat_count```がnil


```spec.rb
describe 'cat_countテスト' do
  let!(:cat_count) { 2 }
  it '1が足されること' do
    #binding.pry
    cat_count += 1
    expect(cat_count).to eq 3
  end
end
```


```
 NoMethodError:
       undefined method `+' for nil:NilClass
```

##原因
（近日更新予定）


##テスト成功

```spec.rb
describe 'cat_countテスト' do
  it '1が足されること' do
    cat_count = 2
    cat_count += 1
    expect(cat_count).to eq 3
  end
end
```
incompatible library version - msgpack.bundle (LoadError) 解決法

# はじめに

```
require': incompatible library version - /Users/[name]/rails/rails-tutorial/sample_app/vendor/bundle/ruby/3.0.0/gems/msgpack-1.4.2/lib/msgpack/msgpack.bundle (LoadError)
```
railsチュートリアルをローカル環境で進めているときにこのエラーに出くわしました。
static-pagesコントローラを生成してから何故かrailsコマンドが使えなくなり、身動きが取れなくなりました。
私の環境にピッタリの記事が中々見つからなかったので書くことにしました。

# 筆者の環境

Macbook Air(M1, 2020)
macOS Big Aur バージョン11.4

`ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [arm64-darwin20]`
`Rails 6.1.4.1`
`Bundler version 2.2.29`

# 解決策

rubyのバージョンを2.7.3にしたら動きました。

参考にした記事はこちら
https://stackoom.com/question/4YA1j


# 試したこと

・railsのバージョンを下げてみる
・rubyのバージョンを3.0.2 -> 3.0.1にしてみる
・gemを一回消してからまたインストールする
.msgpackをインストールする
・springを再起動させる
・bundlerのバージョンを下げてみる

などなど
調べて出てきたことを割と片っ端からしました。


# 感じたこと

検索をかけて調べているうちに、こちらのエラー文はM1mac（arm64）の環境に多いもののように感じました。
Rosettaを使用していればでない、Rosettaに変えたら解決されるエラーのようです。
私と同じような環境の方は試してみてください。
Webスクレイピングツール５選 | Webクローラーを簡単評価(4)

Webスクレイピングツールは、Webサイトで必要な情報を取得するように開発されています。前回はscrapestormなどのスクレイピングツールを紹介しました。今回は他の五つのWebスクレイピングツールを紹介します。
##1) Bright Data (formerly Luminati Networks)
Bright Dataの次世代データコレクターは、コレクションのサイズに関係なく、1つのダッシュボードで自動化およびカスタマイズされたデータフローを提供します。eComのトレンドやソーシャルネットワークデータから競争力のあるインテリジェンスや市場調査まで、データセットは、お客様のビジネスニーズに合わせて調整されます。
**特徴：**
・データ収集プロセスを完全に制御できる
・数分で信頼できるデータフローを取得する
・データ収集はシンプルで動的であり、ターゲットサイト側の変更に対応できる
・コーディングの経験や複雑なデータ収集インフラストラクチャは必要なし
・24時間年中無休のカスタマーサポート
リンク:https://brightdata.com/products/data-collector?lang=ja
![1.Bright Data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/a202f6e6-bd61-3324-36d1-5d4f312ad1b2.png)
##2) Import.io
Import.ioは、Webページ内の半構造化情報を構造化データに変換するプラットフォームであり、Appや他のプラットフォームとの統合など、及びビジネス業務決定の促すに使用できます。
JSON RESTベースおよびストリーミングAPIによるリアルタイムのデータ取得、および多くの通用するプログラミング言語とデータ分析ツールとの統合を提供します。
**特徴：**
・クリックだけでトレーニングができる
・Webインタラクティブとワークフローを自動化する
・データをスゲジュールしやすいです
リンク: http://www.import.io/
![2.Import.io.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/1bf3bd49-f81b-27fb-d67c-0f34ed424ea3.png)
##3) Webhose.io
Webhose.io APIは、メッセージボード、ブログ、レビュー、ニュースなどの数十万のグローバルなオンラインソースから、統合が容易な高品質のデータとメタデータを提供します。
Webhose.io APIは、クエリベースのAPIまたはfirehoseを介して利用でき、高カバレッジデータで低遅延を提供し、記録時に新しいソースを追加する効率的な動的機能を備えています。
**特徴：**
・JSONおよびXML形式の構造化されたデータセットを取得できる
・追加料金を支払うことなく、データフィードの膨大なリポジトリにアクセスできる
・詳細な分析を実行できる
リンク: https://webhose.io/products/archived-web-data/
![3.Webhose.io.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/bf41da41-074d-47d8-c51c-0d9c39eb1623.png)
##4) Apify
Apifyは、WebサイトのAPIを作成することができるWebスクレイピングと自動化プラットフォームです。それは、データ抽出のために最適化される住居とデータセンタープロキシで、統合された代理サービスを含みます。Apify Storeには、Instagram、Facebook、Twitter、Googleマップなどの人気のあるWebサイト向けのさまざまな既製のスクレイピングツールがあり、カスタムソリューションではあらゆる規模のスクレイピングと抽出が可能です。
**特徴：**
・構造化形式でデータを抽出する
・GoogleSERPプロキシでGoogle検索エンジンの結果ページからデータを抽出する
・5ドルのプラットフォームと30日間のプロキシを無料トライアル
リンク:https://apify.com/
![4.Apify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/815cb716-75d5-764d-abfc-740018c66a98.png)
##5) Common Crawl
Common Crawlは、データを調査および分析し、そこから意味のある洞察を明らかにしたい人のために開発されましたスクレイピングツールです。Common Crawlを使用すると、料金やその他の複雑さを心配することなく、このツールを使用できます。 これは登録された非営利プラットフォームであり、寄付に依存して運営しています。
**特徴：**
・非コードベースの使用例をサポート。
・データ分析を教える教育者にリソースを提供する
・Webページデータとテキスト抽出のオーブンデータセットを提供する
リンク:https://commoncrawl.org/
![5.Common Crawl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/0730972a-764f-5afe-0396-f76ee28aa72a.png)
免責事項： 本文はユーザーが提供して、侵害がありましたら、ご連絡してすぐに削除します。ScrapeStormは、ユーザーが本ソフトウェアを使って行うすべての行為に対して、一切責任を負いません。
vscodeでgitの異なるbranch間の差分を確認する方法

# はじめに
意思に反してBranch間の差分が大きくなってしまった場合に一つ一つのファイルに関して修正していくことが時間はかかりますが，正攻法となることがあります．
この記事ではVSCode上において，どのように異なるbranch間のファイルの差分を確認するか記述します．
なお，この情報は2021年時点での回答となり，参照は[StackOverflow](https://stackoverflow.com/questions/42112526/how-to-compare-different-branches-in-visual-studio-code)に存在します．

# 手順
**手順1**. 拡張機能の[GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)をinstallする
**手順2**. source control (下図参照) をクリックする

![C3jLv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355593/99f0e257-b7cc-212e-3e61-599a8373a2bd.png)

**手順3**. Search & compareをクリックしてタブを開く（見つからない場合はsource controlのタブをクリックしてタブを縮小する）

![yB7Xw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355593/878b20c7-a155-4c8c-4834-978c808581e5.png)

**手順4**. Compare referencesをクリックする

![VbdTg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355593/ac65e8c4-8251-792f-c3cf-40e6a243688f.png)

**手順5**. 比較したいbranchを選ぶ

ここでは現在自分のいるBranchに関係なくBranchを2つ選択し，それらのBranchが比較されます．

![Bp2m6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355593/b22ed050-d863-9e54-675d-06a7ffec5235.png)

これによって，Branch間の比較ができるようになりました．
特定IP・VPC Endpointからのアクセスに限定したECRをCloudformationでデプロイする方法

以下のように `aws:sourceVpce` や `aws:SourceIp` を利用して、特定のIPやVPC Endpointからのアクセスに限定したECRを作成することができます。

ただ、下記のようなCloudformaitonのテンプレートをそのままデプロイすると以下のメッセージが発生してデプロイできません。

>Resource handler returned message: "You are about to set a repository policy that will prevent you from setting another one in the future. Use the force parameter to override this exception.

```yaml
Resources:
  MyRepo:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryPolicyText:
        Version: "2012-10-17"
        Statement:
          - Sid: Deny
            Effect: Deny
            Principal: "*"
            Action:
              - ecr:*
            Condition:
              StringNotEquals:
                aws:sourceVpce:
                  - vpce-xxxxxxxxxx
              NotIpAddress:
                aws:SourceIp:
                  - 100.100.100.100/32
```



これは `aws ecr set-repository-policy` の `--force` オプションに当たる設定が必要とのことです。

回避策をAWSサポートに問い合わせたところ、 `aws:CalledVia = [cloudformation.amazonaws.com]` のようにCloudformationからの呼び出しを許可することで事象を回避できました。


```yaml
Resources:
  MyRepo:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryPolicyText:
        Version: "2012-10-17"
        Statement:
          - Sid: Deny
            Effect: Deny
            Principal: "*"
            Action:
              - ecr:*
            Condition:
              StringNotEquals:
                aws:sourceVpce:
                  - vpce-xxxxxxxxxx
                aws:CalledVia:
                  - cloudformation.amazonaws.com
              NotIpAddress:
                aws:SourceIp:
                  - 100.100.100.100/32
```

ググっても出てこなくて時間を使ってしまったので、こちらに残しておきます。
メモ：Unityの「2.5D作るのは思ってるより簡単だよ」動画を試す


3Dモデルを2D世界で動かしたいので
元動画の[2.5D is Easier Than You Think](https://www.youtube.com/watch?v=PECZS26lgtM)
を見ながら何をやっているのかを確認しながら試してみる。
Unityは2020.3.21

とりあえず3Dモード（モバイル）で環境は作成した。
動画の画質をHDにしないと文字は見えない。

### カメラ設定
普通に3Dカメラの設定の話。
背景色を付けている程度？背景にグラデーション設定が出来るのかと思ったけどそういうわけではない。
ライティングの設定は先日のチュートリアルにはなかった。
調べるとWindowの中にライティングというものがあったのでそれを開いて確認。
シーンの「新しいライティング設定」混合ライティングをOFFに。
フォグの設定は「環境」の方でとりあえず付けてみた。

### スプライトシェイプ
スプライトシェイプというものは使ったことがない。
これはパッケージマネージャーからインストールして使うもの。
[解説](https://blog.unity.com/ja/technology/intro-to-2d-world-building-with-sprite-shape)をみると、変形したりしているのは分かった。

プロジェクトでスプライトシェイプのプロファイルを作って、オブジェクトはこの当時と変わっているのか、openとcloseのようなものが存在しているので適当にopenを設定してみた。
Edgeコライダー2Dが設定されているので追加。

### 背景
マテリアル設定したパネル置いているのかと思ったら違った。
3DのTerrain（地形）を配置。山とかも作れる。
どうして緑色になっているのか⇒歯車マークの基本設定にマテリアル設定が出来た。
[Terrainレイヤー](https://www.ame-name.com/archives/338)のようなものを使うとリアルになるらしい。

### キャラクター
動画ではスタンダードアセットのロボットの2Dキャラクターを配置している。
2.5Dでキャラクターも3Dモデルにしたいので、適当に猫をダウンロードして2Dコライダーをセットしてみると普通にスプライトシェイプとの衝突判定があるっぽいのでこれでいけそう。
インスペクタでplatformer characterをセットしているようなので、似たようなことをしたい。
スタンダードアセットの問題は[ここ](https://nekojara.city/unity2020-standard-assets)とかに書いてあって、最新には適合していないものもあるらしい。
2Dのコントローラを無理やり3Dモデルに適合してみたがエラーが出た。

エラー探しのついでにInputSystemに適応させる。
こんな感じでクロスプラットフォームから変更しといた

```
 private void Update()
{
    if (!m_Jump)
    {
        // Read the jump input in Update so button presses aren't missed.
        //m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
        m_Jump = inputAction.Player.Fire.triggered;
    }
}
```

エラーの問題はバージョンではなく

```
m_GroundCheck = transform.Find("GroundCheck");
m_CeilingCheck = transform.Find("CeilingCheck");
```
これが返ってきてないため。
スクリプトしかインポートせず、元のロボット君を見ていないので分かっていなかったが、オブジェクトの子要素として判定用のGroundCheckがあるという事っぽい。
ので実際にロボットをインポートして中身を確認すると空のオブジェクトが入っていたので配置。
エラーは出なくなった。

![新しいビットマップ イメージ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081290/6f5d9258-1ab6-660c-b7cc-86e65beaab28.png)



アニメーション関係を全く設定していないのでジャンプの判定を

```
//if (m_Grounded && jump && m_Anim.GetBool("Ground"))

if (m_Grounded && jump )
```

に書き換える事で、3Dモデルを2Dの世界として動かす事はとりあえずできた。

このままだとアニメーション関係で警告が出るが、アニメーションの所を書き換えるのが面倒なので、
スタンダードアセットからアニメーターをインポートして、適当に３Dのモーションを割り当て。
後ろ向きに走るので、ここだけソースコードを書き換えて向きを反転させてやる。
実際のコード上はFlipメソッドで行っていて、

```
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
```
で反転しようとしているが、zに入れないと3Dモデルは左右反転してくれないので、zの反転も追加して対応。
インポートした猫モデルのアニメーションのループ設定がされていなかったので追加で（ジャンプモーションがなかったが）とりあえず動いた。

# 再度スプライトシェイプと背景の木
やはり動画と違いすぎるのでClosedのシェイプにしたら似たような感じになったので、こちらっぽい。
テクスチャとして適当にグネグネ作った芝生っぽい画像を使えばOKだが手元にないので適当に塗りつぶしで対応
木はスタンダードアセットの中にあるのでそれを利用してTerrainに配置＝樹木はプレハブを作って、樹木を編集からツリーにADDしてやると選択可能になった。
※この樹木のアセット？の影響でビルドがめっちゃ時間かかった

動画にはないけど、2Dカメラを追加して猫を追いかけるようにして、今回のお試しは終わり。

![新しいビットマップ イメージ (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081290/47fbbdae-73c3-3579-0057-3c84ee077b24.png)
【Vue.js】算出プロパティのキャッシュ

#はじめに
こんにちは！
今回は【Vue.js】算出プロパティのキャッシュについてアウトプットしていきます！

#キャッシュとは
・cpmputed・・・キャッシュされる（依存関係に元付きキャッシュされる）
・methods・・・キャッシュされない

#書き方・解説
ランダムの数字を返す処理をcpmputedとmethodsで記述。

```HTML:HTML
<div id="app">
  <h2>
    Computed
  </h2>
  <ol>
    <li>{{ computedNumber }}</li>
    <li>{{ computedNumber }}</li>
    <li>{{ computedNumber }}</li>
    <li>{{ computedNumber }}</li>
  </ol>
  <h2>
    Methods
  </h2>
  <ol>
    <li>{{ methodsNumber() }}</li>
    <li>{{ methodsNumber() }}</li>
    <li>{{ methodsNumber() }}</li>
  </ol>
</div>
```
```Vue.js
var app = new Vue({
  el: '#app',
  computed: {
    computedNumber: function() {
    console.log('computed!')
      //⏫動作確認
      return Math.random()
      //⏫ランダムな数字を生成できる
      }
    },
    methods: {
      methodsNumber: function() {
      console.log('methods!')
        return Math.random()
      }
    } 
})
```
![スクリーンショット 2021-10-18 20.38.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/1836dd1b-0d94-f851-1dee-6f427fddc0a7.png)

`cpmputed`と`methods`を記述します。処理内容は全く一緒です。
上記のように`cpmputed`は全く同じ数字（キャッシュされている）、`methods`は全て異なる数字（キャッシュされない）という風な特性があるからこうなります。

算出プロパティのキャッシュの再構築のトリガーとなるのはリアクティブなデータのみです。`Math.random()`関数はリアクティブではないので、複数回よんでもキャッシュされたデータか使われて同じ値が返される。


#まとめ
`cpmputed`はキャッシュされ全く同じ値が出力される。console表示は１回のみ。
`methods`はキャッシュされないので全て異なる値が出力される。console表示は表示された値の数と一緒。

#最後に
今回は算出プロパティのキャッシュについてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
Envoy とは

## 勉強前イメージ

プロキシ的なイメージ持ってたけど、中身はよくわからない

## 調査

### Envoy とは

エンヴォイ と読み、Webサービスのために開発されたロードバランサーで
L4、L7のプロキシのソフトウェア・ツールになります。
マイクロサービスの分散システムの構築や運用を安定させるために開発され、
サービス間のネットワークの制御をライブラリではなくネットワークプロキシとして提供し、
これによってサービスはEnvoyを経由してそれぞれのサービスへ接続します。
また、EnvoyはL7に焦点を当てているので、RedisやMongodb,DynamoDBなどサポートしています。

### Envoyの主な特徴

- 高度な負荷分散

Envoyは自己完結型のプロキシなので、1箇所に実装すればいろんなアプリケーションからアクセスをさせることができます。

- 豊富な構成API

下位互換性のあるAPIを使用して、データとコントロールプレーンを完全に分離します。

- ハイパフォーマンス

スループットとレイテンシーの画面に関して高パフォーマンスを発揮できます。

### Envoyの主な機能

- L3/L4フィルターアーキティクチャ	

TCPプロキシ、HTTPプロキシ、TLSクライアント証明書認証などをサポートします。

- HTTP L7フィルターアーキティクチャ

HTTP L7フィルターレイヤーをサポートしており、
バッファリング・レート制御・ルーティング/フォワーディングをサポートします

- HTTP L7ルーティング

httpモードで動作していたら、パスに基づくリダイレクトリクエストや認証・コンテンツタイプなどをサポートします。

### Envoyの構築イメージ・用語

Envoyはサービス間のネットワーク制御をネットワークプロキシとして開発したので、
それぞれEnvoyを通じて別のサービスに接続します。
アプリケーションと同じホスト上にEnvoyを構築して、各サービスは別のサービスを直接参照するのではなく、
ローカルのEnvoyを参照します。

![12021-10-25 # Envoy とは - diagrams.net - Google Chro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a7553d56-9fd7-2ec5-323c-640b02f7225c.png)


### Envoyの構築パターン

- Edge Proxy

サービス群の中と外の境界のプロキシ

- Egress Proxy

外部へ接続する際のトラフィックの通信先などを書き換える

- サービスメッシュ

サービス間の通信をEnvoyを経由して行う


## 勉強後イメージ

ちゃんとプロキシサーバ作ったことないから、
正直ちょっとむずかしい・・・・
何でもいいから一個つくってみないとわからないのかな

## 参考

- [Envoy とは？](https://openstandia.jp/oss_info/envoy/)
- [入門Envoy](https://speakerdeck.com/kurochan/ru-men-envoy?slide=27)
「The DevOps ハンドブック　理論・原則・実践のすべて」読んでみた

# 読んだ本

https://www.amazon.co.jp/gp/product/B073PRMWR5

# 読んでみた感想

- 初めて読んだDevOps関連の書籍であり、多くのケーススタディをもとにDevOpsの範囲の広さを認識することができた。DevOps = CI/CDパイプラインのような感覚で扱っていたため、A/Bテストなどによって素早くフィードバック得ることもDevOpsであることを学んだ。
- 特に、Googleのケーススタディで説明されていたSREに興味をもった。以前に少しだけ調べたことがあったが、どのような役割なのか全く理解できていない。SRE関連の書籍も読んでおきたい。
Unity アニメーション実装時によく参考にしているサイト

# はじめに

よく参考にするサイトの紹介記事です。

UnityでDOTweenを使用して以下のコードを書いたとします。

```csharp
transform.DOMoveX(1f, 1f).SetEase(Ease.Linear);
```

イージングでアニメーション具合を調整したいと思った時に以下の問題があります
・どれを設定して良いか直感的にわからない
・一つずつ確認していたら骨が折れてしまう

そのとき私がよく利用するのが以下のサイトです。

# [easing.net](https://easings.net/)
![Screen Shot 2021-10-25 at 19.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188476/92205a3a-be3c-f99f-0c22-0ddd284a271b.png)

グラフでイージングの意味がわかることに加えて、マウスをかざすとアニメーションが再生されるため直感的にイージングを選ぶことができます。

また、グラフを選択すると以下の詳細を見ることができます。

![Screen Shot 2021-10-25 at 19.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188476/6d45d9e1-1013-fac5-65d2-347c9f0f69b2.png)

Web関連のサンプルが多いですが、私は時々一番下のMath functionを確認することがあります。

実際の使用例を挙げるとすると、
SEが重複して再生される時の対策として、重なっている音が多いほど音量を再生時に減衰させる実装をするときにこちらのサイトを使用してイージング関数を選択しました。
(こちらに関してはまた別記事で書きたいと思います)

# 最後に

イージンググラフを確認できるサイトは他にも色々あると思いますが、私のお気に入りのサイトを紹介させていただきました。

ぜひ、アニメーション実装の時にご活用ください！
terraform planをファイル出力する方法

ある程度規模のある環境を Terraform で管理していると`terraform plan`の結果をファイル出力したいケースが出てくるかと思います。例えば、一回の変更差分が長いのでファイルとして保存するだったり、CIで出力した結果をどこかに通知、転送したりといったケースです。

自分は当初「結果をリダイレクトするだけでしょ？」と思っていたのですが、少しハマったので備忘録を残します。

## NG例

以下のように単純にリダイレクトするだけだと`terraform plan > tfplan.txt`とやると以下のように不要な文字列がファイルに追加されてしまいます。

```console
$ terraform plan > tfplan.txt
```

```terraform
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  [31m-[0m destroy
[0m
Terraform will perform the following actions:

[1m  # google_container_cluster.primary[0m will be [1m[31mdestroyed[0m[0m
[0m  [31m-[0m[0m resource "google_container_cluster" "primary" {
      [31m-[0m [0m[1m[0mcluster_ipv4_cidr[0m[0m           = "10.96.0.0/14" [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0mdefault_max_pods_per_node[0m[0m   = 110 [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_autopilot[0m[0m            = false [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_binary_authorization[0m[0m = false [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_intranode_visibility[0m[0m = false [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_kubernetes_alpha[0m[0m     = false [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_legacy_abac[0m[0m          = false [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_shielded_nodes[0m[0m       = false [90m->[0m [0m[90mnull[0m[0m
      [31m-[0m [0m[1m[0menable_tpu[0m[0m                  = false [90m->[0m [0m[90mnull[0m[0m
...
```

## OK例

調べたところ`[1m`や`[31m`は装飾用の文字コードとのことで、ファイルに出力する場合は環境変数`TF_CLI_ARGS`に`-no-color`を追加するか、以下のように実行コマンドでオプションとして渡してやる必要があります。

```console
$ terraform plan -no-color > tfplan.txt
```

```terraform
Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # google_container_cluster.primary will be destroyed
  - resource "google_container_cluster" "primary" {
      - cluster_ipv4_cidr           = "10.96.0.0/14" -> null
      - default_max_pods_per_node   = 110 -> null
      - enable_autopilot            = false -> null
      - enable_binary_authorization = false -> null
      - enable_intranode_visibility = false -> null
      - enable_kubernetes_alpha     = false -> null
      - enable_legacy_abac          = false -> null
...
```

以上「terraform planをファイル出力する方法」でした。
【初心者向け】2回目以降のgit pushの方法

環境
---
MacOS BigSur11.5.2
git version 2.31.1

この記事を書いた理由
---
初期設定や初回のgit pushの仕方は多くあるものの2回目以降のpushの仕方の情報はあまりなかったためまとめます。自分自身もハマりました。
Macのためターミナルにて作業を行います。

方法
---
```
$ git add -A
```
AはAllの略
全て追加するということ
↓

```
$ git commint -m "コミットメッセージ"
```
メッセージは英語でも日本語でも大丈夫です。自分にとってわかりやすいものにすると後から楽です。

```
$ git push
```
##完了！
めでたし。
big surにしたらVirtualBoxがエラー吐いてへそ曲げた

VirtualBox6.1.28にて
max os11.6 big surにしたら

VirtualBoxが以下のエラーを吐きだした

```
==> default: Clearing any previously set network interfaces...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["hostonlyif", "ipconfig", "vboxnet0", "--ip", "xxx.xxx.xx.xx", "--netmask", "xxx.xxx.xxx.0"]

Stderr: VBoxManage: error: Code E_ACCESSDENIED (0x80070005) - Access denied (extended info not available)
VBoxManage: error: Context: "EnableStaticIPConfig(Bstr(pszIp).raw(), Bstr(pszNetmask).raw())" at line 242 of file VBoxManageHostonly.cpp
```

とりあえず、VirtualBoxをダウングレード（6.1.26）にしたら
https://www.virtualbox.org/wiki/Download_Old_Builds_6_1

vagrant up

で起動できた。
Stylelint 14.0.0 で Sass ファイルを lint させる方法

突然 SCSS ファイルの lint が動かなくなり、Visual Studio Code が以下の警告メッセージを通知してきました。

:::note warn
Stylelint version 13.11.0 is no longer supported — you may encounter unexpected behavior. Please upgrade to version 14.0.0 or newer. See the migration guide for more information.
:::

はいはい。
Stylelint が古いからアップグレードしろってわけね。

どうやら4日前（2021/10/25現在）に Stylelint の 14.0.0 がリリースされたようです。

言われた通りアップグレードしてみるも…
CSS ファイルは lint されますが SCSS ファイルは反応なしです…:confounded:

というわけで、Stylelint 14.0.0 で SCSS ファイルを lint させる方法をまとめました！

## Stylelint 14.0.0 の変更点

詳細については以下ページに記載されています。

https://stylelint.io/migration-guide/to-14/

## 変更手順

### SCSS 用のモジュールをインストール

SCSS 用の [stylelint-config-standard-scss](https://www.npmjs.com/package/stylelint-config-standard-scss) モジュールをインストールします。

```
npm install --save-dev stylelint-config-standard-scss
```

### Stylelint の設定ファイルにモジュールを登録

```js:.stylelintrc.js
extends: ['stylelint-config-standard-scss'],
```

### Visual Studio Code の Stylelint 拡張機能 に設定を追加

詳細については以下ページに記載されています。

https://marketplace.visualstudio.com/items?itemName=stylelint.vscode-stylelint#migrating-from-vscode-stylelint-0.xstylelint-13.x

```json:setting.json
"stylelint.validate": ["css", "scss"]
```

## Stylelint のルールを変更

SCSS ファイルでも lint されるようになりましたが、エラーがめっちゃ出ます…:sob:
しかも1行目が必ずエラーになるような？
とりあえず、私は以下のような設定をしました。

```js:.stylelintrc.js
rules: {
  // scss を使うには以下2つがないと @mixin とかでエラーになってしまう
  'at-rule-no-unknown': null,
  'scss/at-rule-no-unknown': true,
  // 透明度を数値かパーセンテージで指定（'number'|'percentage'）
  'alpha-value-notation': 'number',
  // @ルールの前に1行空けるか（'always'|'never'）
  'at-rule-empty-line-before': 'never',
  // url を引用符で囲むか（'always'|'never'）
  'function-url-quotes': 'never',
  // 詳細度の高いセレクタの後に詳細度の低いセレクタを禁止
  'no-descending-specificity': null,
  // セレクタの重複を禁止
  'no-duplicate-selectors': null,
  // セレクタの前に1行空けるか（'always'|'never'|'always-multi-line'|'never-multi-line'）
  'rule-empty-line-before': 'never-multi-line',
  // セレクタのパターンを指定
  'selector-class-pattern': null
}
```
Azure Blob Storage REST APIをcurlで実行する方法

# サービスプリンシパル作成
* Azure ADを選択して、[アプリの登録]→[新規登録]の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/073019fd-2f38-6445-a058-b10458b2cf54.png)

* アプリケーション名を入力します。他はデフォルトでOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/98404ab7-83a9-58f9-f32b-96acb42b4ada.png)

* 作成されるとアプリケーションの概要ページに遷移するため、[アプリケーションID]、[ディレクトリID]を控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/afd2c518-3a52-98f1-f7cb-0cb54f44ec81.png)

* 左メニューから[証明書とシークレット]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/c9396f36-db89-ea6b-2d90-5f068aa98431.png)

* [新しいクライアントシークレット]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/e1da4c9e-30b9-714e-aff3-475ce25ae5f3.png)

* [説明]、[有効期限]を任意で入力して作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/5676ad78-e640-0b45-5cb5-d3b48a77858b.png)

* [値]を控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/9dba2099-9e58-a589-8fee-58069b7d3bf2.png)

# サービスプリンシパルに権限を付与する
* 対象のストレージアカウントを選択し、左メニューより[アクセス制御(IAM)]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/a66a2d78-b0c7-0718-4064-3e6df0d5e241.png)

* [追加]→[ロールの割り当ての追加]の順に選択します。ちなみにこのとき操作しているユーザが[所有者]もしくは[データアクセス管理者]の権限を持っていないと本操作は権限不足でできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/7f2d6df3-31f0-6e47-2ea1-ded20a3f5e0a.png)

* [ストレージBLOBデータ共同作成者]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/94e4808a-fb1d-8d8e-b372-253451ea61c9.png)

* [メンバーを選択する]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/956671cd-7c26-8954-45cc-9214bce1472a.png)

* 先ほど作成したサービスプリンシパルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/6972660f-d632-6ac9-1c31-a25ad0aad61f.png)

* 以下のように追加されればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/d12bf242-b6c2-0f20-f39d-b71efd8013d9.png)

* 条件は特に設定せず次へ。最後に確認画面が出るので問題なければ設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/e475b00c-022f-2ae9-bc9c-ef70eec43a94.png)

# アクセストークン取得
* アクセストークンを取得して、変数tokenに代入します。

```
token=`curl -X POST https://login.microsoftonline.com/[AAD Tenant ID(Directory ID)]/oauth2/token -F grant_type=client_credentials -F resource=https://storage.azure.com/ -F client_id=[Clinet ID(Application ID)] -F client_secret=[Client Secret ID(token)] | jq -r .access_token`
```

# List Blobs API
* コンテナーのBLOB一覧を表示するAPIを実行します。  
https://docs.microsoft.com/en-us/rest/api/storageservices/list-blobs

```
curl -X GET -L -H "Content-Type: application/json" -H "Authorization: Bearer $token" -H "x-ms-version: 2020-10-02" "https://[Storage Account Name].blob.core.windows.net/[Container Name]?restype=container&comp=list"
```

ダウンロードAPIも使えますが、結果がファイルそのものをダウンロードするというのはできず、ファイルの内容を取ってくる形になります。バイナリデータの場合は結果をファイル出力するなどの処理を実装する必要があります。

以上
[C#]ジェネリッククラスをジェネリック非依存で利用するには

# はじめに

本記事はタイトル通り、ジェネリッククラスをジェネリック非依存で利用したいことがあったので、その時とった解決策をまとめることを目的としています。

もう少し具体的に言うと、ジェネリッククラスをプロパティとして保持したいが、そのクラスはジェネリッククラスにしたくないということが起きました。
色々な型を指定したジェネリッククラスのインスタンスを保持できるようなクラスにしたいということです。
ジェネリッククラスを保持するには、保持する側のクラスもジェネリックでないとコンパイルエラーになります。しかし、これをやると、保持する側のクラスをインスタンス化した際に型引数に指定した型でしかジェネリッククラスを扱えなくなってしまうため、色々な型を指定したジェネリッククラスのインスタンスを保持できるクラスを作れません。
以下に、この時とった解決策を記載します。

# 解決策

ジェネリッククラスのI/Fを作り、保持する側はI/Fで保持するようにします。
また、I/Fにはジェネリックで定義したいプロパティやメソッドを扱える窓口を用意しておきます。
具体的には以下です。

```cs
// ジェネリッククラスのI/Fです。
public interface ISample
{
    // Action<T>型を実行するためのメソッドを用意しておきます。
    // I/F側には、プロパティを用意せず、実行するメソッドだけを用意しておくのがポイントです。
    // 引数の型は、ジェネリックの型制約にするような基底クラスの型です。
    // 今回はサンプルの所有者となるようなクラスがいくつかある前提で、その基底クラスを渡しています。
    public void InvokeSampleAction(SampleOwner owner);
    
    // ...
}

// ジェネリッククラスです。ISampleを実装しています。
public class Sample<T> : ISample where T : SampleOwner 
{
    // ジェネリック型を引数に指定するAction型のプロパティ
    public Action<T> SampleAction { get; set; }
    
    // I/Fの実装で、自身が持っているSampleActionを実行する処理を書きます。
    public void InvokeSampleAction(SampleOwner owner)
    {
        // このメソッドの引数は、ジェネリックの型制約となるような基底クラスの型で渡ってきますが、
        // 引数を、このインスタンスに指定されたT型にキャストし、それを用いてActionを実行することで、
        // ジェネリックに指定した型でジェネリックではないI/FからAction<T>型を実行できるようにしています。
        // （xxxにはジェネリックで指定したものと同じ型のインスタンスが入ってくる前提です）
        if (!(owner is T t)) return;
        SampleAction.Invoke(t);
    }
}
```

利用イメージは以下です。

```cs
public class SampleManager
{
    // I/Fで保持します
    private IDictionary<string, ISample> m_Samples = new Dictionary<string, ISample>();

    // 呼び出しはこんな感じです。
    public void DoSomething(SampleOwner owner)
    {
        // ownerの情報から、呼び出したいSampleクラスをm_Samplesから抽出
        var samples = ...
        foreach(var sample in samples)
        {
            sample.InvokeSampleAction(owner);
        }

        // ...
    }
}
```

# さいごに

インターフェースを使うことで、ジェネリッククラスを横断的に扱えるようになるのは、面白いと思いました。
インターフェースはクラス間を疎結合に保つとかそういった使われ方をすることが多いと思いますが、こんな使い方もあるのは勉強になりました。
今後もこういった設計パターンを学んでいきたいと思います。
SES営業とSalesforceの兼務 備忘録①


こんにちは。初投稿です。

都内でSES営業をしつつ、社内のSalesforceのシステム管理者を兼任しております。

ここでは自分に対するメモのような形で残してきますので
参考にできる部分、もしくはアドバイスいただける部分があれば是非教えてください。


※ちなみに、Salesforceエンジニアとしてのキャリア形成の為出向先の案件を探しております。
併せてご紹介いただくこともありがたく思います。
openapi-generator-cli (python-flask)

こちらで行ったことを openapi-generator-cli で行いました。
[OpenAPI 3.0 の使い方 (GET 引数付き）](https://qiita.com/ekzemplaro/items/fffea0f0b2313ebe1b65)

バージョン

```text
$ npx @openapitools/openapi-generator-cli version
5.3.0
```

```yaml:hello.yaml
openapi: 3.0.2
info:
  description: ユーザ名を与えると挨拶を返してくれるAPI
  version: 1.0.0
  title: Hello
tags:
  - name: hello
    description: ユーザに挨拶を返すAPI
paths:
  /hello:
    get:
      tags:
        - hello
      description: ユーザに挨拶する。
      operationId: getHello
      parameters:
        - name: userName
          in: query
          description: ユーザ名
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  HelloUser:
                    type: string
                    example: Hello, userName
        "400":
          description: Bad Request
        "500":
          description: Internal Server Error
```

#Flask のサーバーを作成#

```bash
npx @openapitools/openapi-generator-cli generate \
	-g python-flask \
	-i ./hello.yaml \
	-o ./src \
	--api-package=api \
	--model-package=model \
	--additional-properties=withSeparateModelsAndApi=true
```

コードの修正

```py:openapi_server/controllers/hello_controller.py
（省略）
#    return 'do some magic!'
    return 'Hello, ' + user_name + ' !'
```

ライブラリーのインストール

```bash
pip3 install -r requirements.txt
```

サーバーの実行

```bash
python3 -m openapi_server
```

クライアントでアクセス

```text
$ http http://0.0.0.0:8080/hello?userName=Scott
HTTP/1.0 200 OK
Content-Length: 17
Content-Type: application/json
Date: Mon, 25 Oct 2021 09:51:48 GMT
Server: Werkzeug/1.0.1 Python/3.9.7

"Hello, Scott !"

```
TypescriptでReactの環境構築

# TypescriptでReactの環境構築
TypescriptでReactの環境構築をまとめたいと思います。

https://create-react-app.dev/docs/adding-typescript/

## プロジェクトの作成
create-react-appコマンドを使って、プロジェクトを作成します。
TypeScriptを使用するのでオプションで```--template typescript```を加えます。
react-typescript-app というプロジェクトを作成しました。

```sh
$ npx create-react-app react-typescript-app --template typescript
$ cd react-typescript-app
$ yarn start
```

無事動作することが確認できました！


## TypeScriptの環境構築
TypeScriptの設定などは下記を見て設定します。

https://qiita.com/YSasago/items/778eef2a50d5664da572
【Mac】ホットリロードできない時の対処法

環境
---
・macOS Big Sur バーション11.5.2
・シェル zsh
・Ruby 3.0.2
・rails 6.1.4
・My SQL 8.0.23
・Docker 20.10.8
・react　　17.0.2
・typescript　　4.4.4

希望
---
Docker+rails+react+typescriptで環境構築し、ホットリロードまでしようとしていました.

したこと
---
①webpacker.ymlのwatch_options:の下に


aggregateTimeout: 300
poll: 500

を追加しました。
こんな感じです。

```rails:webpacker.yml
watch_options:
      ignored: '**/node_modules/**'
      aggregateTimeout: 300
      poll: 500
```
これでできるはずだができず、、、

次に
②.envファイルを作り

```rails:.env
CHOKIDAR_USEPOLLING=true
```
を追記。

これも複数の記事を参考にし実行しましたがホットリロード（リロードなしで即テキストエディタの内容が反映される）はできず。

よってリロード画面を開発者モードで見ることに。
そこでこんなエラーを発見。

エラー
---
Access to XMLHttpRequest at 'http://localhost:3035/sockjs-node/info?t=1635142686037' from origin 'http://0.0.0.0:3000' has been blocked by CORS policy: The request client is not a secure context and the resource is in more-private address space `local`.

調べるとCORS policyというものでURLがブロックされているとのこと。

解決策
---
chrome://flags/#block-insecure-private-network-requests

以上のサイトにアクセスし、

Block insecure private network requests
をDisabledにする。

↓
無事ホットリロードできました！めでたしめでたし。

参考にしたサイト
---
[Docker + Rails6 + React + TypeScript の環境構築](https://cloudpack.media/56851)
一眼で、パーミッション確認

#パーミッション

```
読みのみ
$ chmod 600 sample.txt
```

| 百 | 十 | 一 |
|---|---|---|
| 所有者 | グループ | その他 |

| パーミッション | ビット | 8進数 |
|---|---|---|
| rwx | 111 | 7 |
| rw- | 110 | 6 |
| r-x | 101 | 5 |
| r-- | 100 | 4 |
| -wx | 011 | 3 |
| -w- | 010 | 2 |
| --x | 001 | 1 |
| --- | 000 | 0 |

| r | w | x |
|---|---|---|
| 読み | 書き | 実行 |
【Next.js】デプロイでこけてlocalいじったら死んだ話【AWS Amplify】

久々にNextいじって、いい感じにできたのでデプロイした時。

```terminal
22 error Exit status 1
23 error Failed at the nomulog_v2@1.0.0 build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
```

???
なんぞこれ。
調べてみると`webpack.config.js`にmodeを追加する必要があるらしい。
だが、webpackとかいじったことがなくさっぱりなのである。
とりあえずトップレベルに`webpack.config.js`を作って記事にあったコードを入れてデプロイしてみるも変化なし。

そもそもlocalでは動作してるんだよなぁと思って再度実行したところ。

# 動けNext! なぜ動かん!!
さっきまで動いてたはずのNext君が砕け散ったのである。スイカバーが刺さったのである。
たぶん、今まではビルドコマンドたたかずにテストしてたからなのかなとか思っているが正直覚えていない。
いったい何が原因なのかわからないが、迷宮に突き落とされたので同にか脱出しようといろいろ試していく。

# やったことリスト(覚えてる限り)
- モジュールの削除と再インストール
- Nodeのバージョンアップ
- webpackとwebpack-cliをインストール
- 新しくプロジェクト立てて原因調査
- モジュールをひとつづつ入れてどれが影響してるか確認
- npmのバージョンアップ
- npm install sass
- next.config.jsの修正
- *.scss -> *.module.scss


上からやった理由とか結果を載せてく。

# モジュールの削除と再インストール
とりあえず依存関係の問題でなんか動かんのやろ、とか思って`node_modules`と`package-lock.json`を削除して再インストールしてみる。

```powershell
$ npm cache clean --force
$ npm install --save-dev
```

結果は変わらず。

# Nodeのバージョンアップ
何となくバージョンのせいかと思いバージョンアップしてみる。
Nodeのバージョンアップは、公式から新しいインストーラーを持ってきて実行すればいいので割愛。

結果は変わらず。

# webpackとwebpack-cliをインストール
どうやらwebpack4からはcliがいるとのことなのでこれを入れてみる。

```powershell
$ npm install webpack --save-dev
$ npm install webpack-cli --save-dev
```
確かこれを実行した段階でエラー内容が変わった気がする。
残念なことに詳しいエラーは覚えていないが、SASSがコンパイルできないよ!みたいなエラーだった気がする。
今まで実行できてたのに謎だったので、新しく環境立ち上げていろいろ試すことにした。


# 新しくプロジェクト立てて原因調査
もしかしたらそもそも動かないんじゃないか…とすべてを疑い始めたので`npm create-next-app`で新しくプロジェクト作って実行してみた。
もちろん動く。

# モジュールをひとつづつ入れてどれが影響してるか確認
やっぱりモジュールのせいかと思って、一個ずつインストールしては実行を繰り返してみた。
もちろん動く。
`npm install --save @zeit/next-sass node-sass`を実行後、
そういえばnext.configにもSASSの設定あったなーと思い、

```js:next.config.js
const withSass = require('@zeit/next-sass')
module.exports = withSass({
  cssModules: true
})
```
とやったところ、おんなじエラーが出た。


# npmのバージョンアップ
もしかしてバージョンのせいではと思い(n回目)バージョンアップさせてみるも変化なし。

# npm install sass
あきらめずにバージョンが悪い!という固定概念の元調べ続けた結果、
どうやらNextが普通にSCSSをコンパイルできるらしいことを知った。昔の私はなんでこれしてなかったんだろう。わからん。
ということで

```powershell
$ npm install --save-dev sass
```
インストールして、config.jsをもとに戻した。
またまたエラーが変わって確か

```powershell
TypeError: Cannot read property 'tap' of undefined
```
が出てきたと思う。

# next.config.jsの修正
原因がwebpakc4のせいらしく、webpack5を使いましょう、的なことだった。
なのでnext.config.jsを修正する。

```js:next.config.js
module.exports = {
  future: { 
    webpack5: true, 
  },  
  reactStrictMode: true,
}
```
するとエラーが変わり、

```powershell
Global CSS cannot be imported from files other than your Custom <App>. Please move all global CSS imports to pages\_app.tsx.
```
となった。

# *.scss -> *.module.scss
上記の原因は、scssファイル名に`module`が含まれてないとglobal CSS扱いになって、global CSSは_app.tsxでしか使えないよ!とのこと。
なのでファイル名を変更していった。もちろん対応するimport部分も修正。

# こいつ... 動くぞ！
ようやくlocalでの実行ができるようになりました。
いろいろやったので直接的な原因がどれなのかさっぱりですが、多分`@zeit/next-sass`あたりが大きかったと思います。
localで今まで動いてたのはきっとデプロイ->実行という流れを試してなかったからだと思います。(next startしかやってない)

ちゃんとデプロイもできたので万々歳ですね。
まだ出来上がってないですがデプロイできた時はうれしいものです。

引き続き躓きながら開発できればいいかな。
(何とでもなるはずだ!)
「 [トリビアの泉]1から9の数字が重複な...」を参考にSymPy Liveでやってみたい。

証明になりますか？教えて下さい。

オリジナル　証明すッゾォ＜

https://qiita.com/poppy1115/items/6fb4958761bcae55d7fc#%E8%A8%BC%E6%98%8E%E3%81%99%E3%83%83%E3%82%BE%E3%82%A9


#SymPy Liveで

以下サイトに、ソースコードを貼り付けて、Evaluateです。

https://live.sympy.org/

```python
from sympy import *
var('i n p')
p=symbols('p', cls=Function)
n=9
f1=  Sum( 10**(n-i)     *p(n-i),(i, 1, n  ))
f2=9*Sum((10**(n-i)-1)/9*p(n-i),(i, 1, n-1))
print("#",simplify(f1-f2))
print("#",simplify(f2+simplify(f1-f2)))
print("#",simplify(Sum(i,(i,1,n ))).doit() % 9)
# p(0) + p(1) + p(2) + p(3) + p(4) + p(5) + p(6) + p(7) + p(8)
# p(0) + 10*p(1) + 100*p(2) + 1000*p(3) + 10000*p(4) + 100000*p(5) + 1000000*p(6) + 10000000*p(7) + 100000000*p(8)
# 0
```
Athena で JST ベースの日付を得る方法

BigQuery なら `CURRENT_DATE('Asia/Tokyo')` で良かったのですが、Athena ではできなかったので今のところ以下のような感じで対応中。調べたのが 9:00 を回ってしまっていたので `America/Chicago` を使いました。[^1]

```
10-13 11:54 現在
SELECT DATE(CURRENT_TIMESTAMP AT TIME ZONE 'America/Chicago')
> 2021-10-12

SELECT DATE(CURRENT_TIMESTAMP)
> 2021-10-13

SELECT DATE(CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Tokyo')
> 2021-10-13
```

もし他に良い方法があればご教示ください！

[^1]: シカゴはサマータイム中は「GMT-5」だそうです。これをやるにあたって調べました。なので、14:00 までであればこういう日付系の検証に使えそう。