OmniAICreator/Qiita-1.07M huggingface dataset:
関数内で配列を書き換えた際の関数呼び出し後の挙動まとめ(python)

# 1.配列を関数内で書き換えたとき、関数呼び出し後に配列はどうなる？

以下の状況を想定する。

- 関数`test(array)`に配列`array`を引数として渡す
- 関数`test(array)`内で、何らかの方法で配列の要素を増やす
- 関数`test(array)`呼び出し後に、配列`array`の中身を確認する

ここでは、関数呼び出し後に`array`の中身が書き変わっているかどうかを考える。  

コードで書くと次のようになる。

```python:
def test(array):
    #ここでarrayに[3]を追加して[1,2,3]にする
    return sum(array)

array = [1,2]
ans = test(array)
print(array) # 結果は[1,2]か?、それとも[1,2,3]か?
print(ans) #6
```



今回は、

- 関数呼び出し後に`array`の中身が書き変わってしまうパターン
- 関数呼び出し後も`array`の中身が書き変わらないパターン


をそれぞれ2つずつ紹介する。


# 2. 関数呼び出し後にarrayの中身が書き変わってしまうパターン

## 2.1. 書き変わるパターンその1 : append()を使う

```python
def test(array):
    array.append(3) #aの要素を増やす
    return sum(array)

array = [1,2]
ans = test(array)
print(array) #[1,2,3]と表示される(!)
print(ans) #6
```

関数`test(array)`を実行すると、`array`が書き変わってしまうことがわかる。これは、関数`test(array)`に対して配列`array`が参照渡しされていることが原因である。関数`test()`は配列`array`そのものを参照するため、関数内で`append`すると、関数の呼び出し後には`array`は書き変わってしまう。

## 2.2. 書き変わるパターンその2 : +=を使う

```python
def test(array):
    array += [3] #aの要素を増やす
    return sum(array)

array = [1,2]
ans = test(array)
print(array) #[1,2,3]と表示される(!)
print(ans) #6
```
この場合も同様。関数の呼び出し後には`array`は書き変わってしまう。
`+=`は実質`append()`と同じで、`array`の要素を一つ追加すると考えてよい。


# 3. 関数呼び出し後もarrayの中身が書き変わらないパターン

上記のような、関数内での配列操作が外に伝わってしまう状況を回避するには、要は関数内で`array`のコピーを作ってから作業を始めれば良い。

## 3.1. 書き変わらないパターンその1 : copy()を使う
pythonでは、配列の中身を丸ごと値渡しでコピーする`copy.copy()`と`copy.deepcopy()`が用意されている。それぞれ、いわゆる「浅いコピー」と「深いコピー」に対応する。よくわからなければとりあえず`deepcopy()`を使っておけば間違いない(たぶん…)。

```python
import copy
def test(array):
    array = copy.deepcopy(array)
    array = array + [3] #aの要素を増やす
    return sum(array)

array = [1,2]
ans = test(array)
print(array) #[1,2]と表示される
print(ans) #6
```

確かに、関数呼び出し後も`array`の中身は書き変わっていないことがわかる。

## 3.2. 書き変わらないパターンその2 : array = array + [3]とする
意外にも、`array = array + [3]`としても要件を満たすことができる。

```python
def test(array):
    array = array + [3] #aの要素を増やす
    return sum(array)

array = [1,2]
ans = test(array)
print(array) #[1,2]と表示される
print(ans) #6
```

確かに`array = array + [3]`とした場合でも、関数呼び出し後も`array`の中身は書き変わっていないことがわかる。  
この結果は、`array += [3]`を用いた場合と対称的である(2.2.節参照)。おそらく、`array += [3]`とした場合はもとの配列に要素が`append()`されるのに対し、`array = array + [3]`とした場合は新たに配列が確保されることが挙動の違いを生んでいるものと思われる。紛らわしい！

# 4. まとめ
書き変わってほしくない配列はとりあえず`deepcopy()`しよう。  
`array = array + [3]`と`array += [3]`で挙動が異なるのが大変紛らわしい。
[Rails]検索フォームでの検索機能/複数ワードでの検索を実装する

# 記事の概要
　[前回の記事](URL "https://qiita.com/kei-kun1960/items/3eaf2f64ccfee1213700")の続き。前回は検索フォームに入力した文字列で、あるテーブルの複数カラムを対象に検索を実行した。今回はフォームに複数のワードを入力し、AND検索できるよう実装してみたので備忘録として。検索ワードは、例えば「旅行,グルメ」のように" , "で区切るとする。

# 複数ワードでAND検索

```ruby:app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  def search

    # フォームから検索ワードを取得
    keywords = params[:keyword]
    
    # モデルオブジェクトを生成
    @articles = Article.all
    
    # 検索ワードの分割   
    split_keywords = keywords.split(",")

    # 分割したワードを一つずつ検索にかける
    split_keywords.each do |word|
      @articles=@articles.where(['カラム1 LIKE(?) OR カラム2 LIKE(?) OR カラム３ LIKE(?) OR カラム4 LIKE(?)',"%#{word}%", "%#{word}%", "%#{word}%", "%#{word}%"])          
    end  
  end
    
end
```
xargsの-iコマンドについて

xargsの-iコマンドは-Iコマンドと同等。
前のコマンドの出力を{}でとることができる。

```
find . | xargs -i cp {} /dir/name/
```
下のように引数に対して内容を付け足すこともできる。使い道があるかもしれない。

```
find . | xargs -i cp {}.png /dir/name/
```
上から100個のデータを取ってきてコピーしたいとき

```
ls | head -100 | xargs -i cp {} /dir/name
```
Go言語でパスパラメータの値を構造体に自動代入させる

`Go`言語でWebアプリケーションを開発する際に、パスパラメータの値を構造体に`parse`することはよくあることです。
例えば、下記のようなエンドポイントがあるとして、まずパスパラメータを受け取り、次にそれらのパラメータを構造体にparseしたいとします。

```
/firstname/{first_name}/lastname/{last_name}
```

パラメータの受け取りは[gorilla/mux](https://github.com/gorilla/mux)を使えば、できることが分かっています。
`mux.Vars`関数を使えば、いい感じに`map`にして返してくれます。
今回お話ししたいのは、この`map`を構造体に`parse`する方法についてです。

## `json`パッケージを利用して`parse`する方法があるが・・・
この`map`の中身を構造体に`parse`する方法も実はあって、`json`パッケージを使えば簡単にできてしまします。
このソースは、[The Go Playground](https://play.golang.org/p/ovoLSxSrgoE)でそのまま実行できます。

```go:json
package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	LastName  string `json:"last_name"` // タグ名を json にする
	FirstName string `json:"first_name"` // タグ名を json にする
}

func main() {
 	m := map[string]string{
		"last_name": "Taro",
		"first_name": "Suzuki",
	}
	
	p := Person{}
	fmt.Printf("%+v\n", p)
	parseParam(m, &p)
	fmt.Printf("%+v\n", p)
}

// parseParam mapの値を構造体に parse する
func parseParam(m map[string]string, p interface{}) error {
	bytes, err := json.Marshal(m)
	if err != nil {
		return err
	}
	return json.Unmarshal(bytes, p)
}
```


しかし、Person構造体のフィールドのタグに`json:"last_name"`とか`json:"first_name"`とか、`json`と記載することに非常に抵抗感を感じました。
なぜなら、パラメータを`json`で受け取っているわけではないからです。
そこで、`json`タグを使用せず独自のタグを設定して`parse`できる方法を考えてみました。

## `reflect`機能を使って動的に`parse`する
上の例と比べてみると、構造体のタグ名が`json`から`param`に変わったことにお気づきでしょうか。
結果`parseParam`関数が長くなりますが、本来の目的に合ったタグ名を設定して目的を達成することができました。

`reflect`機能を使うと、構造体のフィールドを動的に解析して好き放題にいじることができます。
コンパイル言語の安全性を損ねる恐れがあるので`reflect`の使いすぎは控えるべきですが、このような場面ではその威力を発揮してくれます。

このソースは、[The Go Playground](https://play.golang.org/p/PUCdW62Qfwp)でそのまま実行できます。

```go:reflect
package main

import (
	"errors"
	"fmt"
	"reflect"
)

type Person struct {
	LastName  string `param:"last_name"` // タグ名を独自に設定できる
	FirstName string `param:"first_name"` // タグ名を独自に設定できる
}

func main() {
 	m := map[string]string{
		"last_name": "Taro",
		"first_name": "Suzuki",
	}
	
	p := Person{}
	fmt.Printf("%+v\n", p)
	parseParam(m, &p)
	fmt.Printf("%+v\n", p)
}

// parseParam mapの値を構造体に parse する
func parseParam(m map[string]string, p interface{}) error {
	t := reflect.ValueOf(p).Elem()
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		tag := t.Type().Field(i).Tag.Get("param")
		if tag == "" {
			continue
		}
		value, ok := m[tag]
		if !ok {
			return errors.New("invalid value")
		}
		field.SetString(value)
	}
	return nil 
}
```
matplotlib オブジェクト指向インターフェイス

引用:https://jakevdp.github.io/PythonDataScienceHandbook/04.00-introduction-to-matplotlib.html#Two-Interfaces-for-the-Price-of-One

Object-oriented interface
The object-oriented interface is available for these more complicated situations, and for when you want more control over your figure. Rather than depending on some notion of an "active" figure or axes, in the object-oriented interface the plotting functions are methods of explicit Figure and Axes objects. To re-create the previous plot using this style of plotting, you might do the following:

```
# First create a grid of plots
# ax will be an array of two Axes objects
fig, ax = plt.subplots(2)

# Call plot() method on the appropriate object
ax[0].plot(x, np.sin(x))
ax[1].plot(x, np.cos(x));

```
マージソート C++

C++ によるマージソートの実装
番兵に**INT16_MAX**を使っているが、適時他を使え。

```c++
#include <iostream>
#include <random>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)

void display(const vector<int> &v) {
    rep(i, v.size()) cout << v[i] << " ";
    cout << endl;
}
// 昇順チェッカー
void ascendingOrderChecker(const vector<int> &v) {
    bool flag = true;
    rep(i, v.size() - 1) flag &= v[i] <= v[i + 1];
    if (flag) {
        cout << "Correctly sorted." << endl;
    } else
        cout << "Not sorted correctly." << endl;
}
void swap(int *a, int *b) {
    int *t = a;
    a = b;
    b = t;
}
void merge(vector<int> &v, int i, int j) {
    int h = (i + j) / 2;

    vector<int> A(h - i + 1);
    vector<int> B(j - (h + 1) + 1);
    for (int s = 0; s < A.size(); s++) A.at(s) = v[i + s];
    for (int t = 0; t < B.size(); t++) B.at(t) = v[h + 1 + t];
    A.push_back(INT16_MAX);
    B.push_back(INT16_MAX);
    int a = 0, b = 0;
    for (int k = i; k <= j; k++) {
        if (A[a] < B[b]) {
            v[k] = A[a];
            a++;
        } else {
            v[k] = B[b];
            b++;
        }
    }
}
void MergeSort(vector<int> &v, int i, int j) {
    if (j - i + 1 == 1) return;
    int h = (i + j) / 2;
    MergeSort(v, i, h);
    MergeSort(v, h + 1, j);
    merge(v, i, j);
}

int main() {
    vector<int> test(100);
    random_device rnd;
    mt19937 mt(rnd());
    uniform_int_distribution<> rand100(-99, 99);
    rep(i, 100) {
        rep(i, 100) test[i] = rand100(mt);
        // ソート前の状態
        ascendingOrderChecker(test);
        MergeSort(test, 0, test.size() - 1);
        // ソート後の状態
        ascendingOrderChecker(test);
        // display(test);
    }
    return 0;
}
```
web学習日記#1 Ajax通信

![スクリーンショット-2019-08-15-16.12.38-300x198.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1531446/bf01ac2b-2cf8-4022-f563-170163a16c38.jpeg)
JavaScriptでAjax通信　
---
学習講座
udemy 「[HTML/CSS/JavaScript] フロントエンドエンジニアになりたい人の Webプログラミング入門」

---

本日はJavascriptでAjax通信を用いたコーディングを行った。

今まで画像を表示させたいときはディレクトリ内の画像ファイルをhtmlまたはcssから直接パスを指定して参照していた。

今回はJavaScriptからXMLHtmlRequestというサーバーと通信するためのAPIを使って、サーバーからjsonといわれる形式のデータを受け取ることで、データ内にある画像へのパスやテキストを使ってweb上に画像やテキストを表示させた。

コード
---
```
<script>
    var ajax = new XMLHttpRequest(); //オブジェクトの作成
    ajax.open('GET', 'https://h2o-space.com/htmlbook/images.php'); //送信時のメソッド、送信先のURLの設定
    ajax.responseType = 'json'; //jsonタイプを受け取る
    ajax.send(null); //サーバーへリクエスト

    ajax.onreadystatechange = function() { //読み込み中の状態が変わるごとに処理する
        if(ajax.readyState === XMLHttpRequest.DONE && ajax.status === 200) { 読み込み完了&&ステータスが200
            for(var i = 0; i < this.response.length; i++) {
                var data = this.response[i];

                var img = document.createElement('img');
                img.setAttribute('src', data.path);

                var caption = document.createElement('div');
                caption.className = 'inner';
                caption,innerHTML = '<p>' + data.caption + '<span>' + data.name + '</span></p>';

                var div = document.createElement('div');
                div.className = 'photo';
                div.appendChild(img);
                div.appendChild(caption);

                document.getElementById('img_unit').appendChild(div);
            }
        }
    };
</script>
```
WSL上のLinuxで動かしているVimとクリップボードを連携させる

# この記事について

本記事は私のブログ記事 https://blog.aotake91.net/posts/20210327-enable-vim-clipboard-on-wsl/ を転載・加筆修正したものです。

# はじめに

わたしはVimが好きです。そしてUNIX的なコマンドが使える環境が好きです。今までWindows上でGVimを主に使ってきましたが、最近、Windows Subsystem for Linux上のLinuxでCUI版Vimを利用するようになりました。

基本的にはVimのパッケージをそのままインストール（Ubuntuでしたら apt install vim）して設定すれば最高の環境が得られますが、ひとつだけ問題があります。パッケージとして配布されているVimはクリップボード連携機能が無効化されてビルドされています。そのままでは、Windowsの他のアプリケーションとの間でやり取りするのに苦労します。

クリップボードを利用できるようにするにはいくつか方法がありますが、そのうちのひとつ、VcXsrv Windows X Server を利用する方法を紹介します。

# 環境

- Windows Subsystem for Linux (1でも2でもOK)
    - Ubuntu 20.04.2

あとの手順で導入する各種依存関係は、Ubuntu の apt で導入できる最新版を用いて差しつかえありません。

# 手順概略

1. Vimの機能有効化状態を確認
1. Vimをクリップボード機能有効にしてビルド
1. VcXsrv をセットアップ
1. VcXsrv に接続

# 詳細

## 1. Vimの機能有効化状態を確認

Vimを起動した状態で「:version」コマンドを実行するか、シェルコマンドラインから次のコマンドを実行します。

    $ vim --version

このときに、「+clipboard」とあればクリップボード機能は有効化されていますので手順3に進んでください。「-clipboard」でしたら、手順2のビルド作業をします。

ビルド作業をするのでしたら、ついでに各種スクリプト言語のインタプリタとの連携機能も有効化しておくと、将来的にいろいろ捗るかもしれません。「python」「python3」「ruby」「lua」などについて、頭に「-」がついていたら手順2で有効化できます。

## 2. Vimをクリップボード機能有効にしてビルド

基本的に、必要な（必要そうな）ライブラリを入れて make すると完了です。

    # ビルドのために最低限必要なツールを導入
    $ sudo apt install git gettext libtinfo-dev libacl1-dev libgpm-dev build-essential
    
    # Python2, Python3, Ruby, Lua, Perl連携に必要なツールとライブラリを導入
    $ sudo apt install python python-dev python3 python3-dev ruby ruby-dev lua5.3 liblua5.3-dev libperl-dev
    
    # GitHubから最新版のVimをクローン
    $ git clone https://github.com/vim/vim.git
    
    # ビルドオプションの設定
    $ cd vim/src
    $ ./configure --with-features=huge \
                  --disable-gui \
                  --enable-perlinterp=dynamic \
                  --enable-pythoninterp=dynamic \
                  --enable-python3interp=dynamic \
                  --enable-rubyinterp=dynamic \
                  --enable-luainterp=dynamic \
                  --enable-fail-if-missing
    
    # ビルドとインストール
    $ make
    $ sudo make install
    
    # 新しい Vim が呼び出せるように、コマンドへのパスのキャッシュを再構築
    $ hash -r

各インタプリタ連携については、不要なものは外しても大丈夫です。また、連携するためのライブラリはすべてダイナミックリンクとしています。GUIについては利用しないため無効化しました。

インストール後の最後の手順は重要です。コマンドへのパスのキャッシュがあると、意図しない（もとのバージョンの）方のVimを呼び出してしまいます。キャッシュを再構築することで新しいVimを呼び出せるようにします。

## 3. VcXsrv をセットアップ

続いて、VcXsrv Windows X Server をセットアップします。

1. https://sourceforge.net/projects/vcxsrv/ からプログラムをダウンロードしてインストールします。
1. XLaunch を実行します。Disable access control <- これをチェックすることを忘れずに。Save Configuration ボタンをクリックして、 C:\Users\<Your User Name>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\config.xlaunchにファイルを保存すると、自動起動できます。

1. Windowsファイアウォール通信許可のダイアログが出たら、VcXsrvを許可するよう設定します。

## 4. VcXsrv に接続

WSLのバージョンが1であるか、2であるかによって、設定すべき内容が変わります。

    # WSL 1 の場合
    export DISPLAY=localhost:0.0

    # WSL 2 の場合
    LOCAL_IP=$(cat /etc/resolv.conf | grep nameserver | cut -d' ' -f2)
    export DISPLAY=$LOCAL_IP:0.0

上記のコマンドを .bash_profile など、利用しているシェルの起動スクリプトに記述してください。

以上で手順は終わりです。よいVimライフを！

# 参考文献

- <a href="https://qiita.com/necojackarc/items/8129ed9e6d8083aec34a">Qiita - Ubuntu on WSL2 上の Vim でクリップボード連携</a>
- <a href="https://vim-jp.org/docs/build_linux.html">vim-jp - Linuxでのビルド方法</a>
Laravel ページネーション　検索条件が引き継がれない


<h1>検索条件が引き継がれない問題発生</h1>

検索機能を実装して、ページネーションで次のページに遷移したとき検索条件が引き継がれない
問題が発生して解決したので記事にしました。

検索をかけて、URLを確認すると,下記のように表示されています。
<pre>
category_id=1&page=1
//検索フォームで検索した結果
</pre>
そして、2ページ目に遷移すると、
<pre>
page=2
//ページ遷移した結果
</pre>
あ、category_id=1が消えていました。
現状、bladeのページネーションのコードを確認すると下記のように設定されています。
<pre> 
{{ $projects->links() }}
</pre>

下記のように変更すると、ページ遷移してもcategory_id=1&page=2
のように引き継がれました。
<pre> 
{{ $projects->appends(request()->input())->links() }}
</pre>

<h1>参考記事</h1>
https://blog.dododori.com/create/program/laravel-search-page/
クイックソート C++

C++によるクイックソートの実装


```c++
#include <iostream>
#include <random>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)

void display(const vector<int> &v) {
    rep(i, v.size()) cout << v[i] << " ";
    cout << endl;
}
// 昇順チェッカー
void ascendingOrderChecker(const vector<int> &v) {
    bool flag = true;
    rep(i, v.size() - 1) flag &= v[i] <= v[i + 1];
    if (flag) {
        cout << "Correctly sorted." << endl;
    } else
        cout << "Not sorted correctly." << endl;
}
void swap(int *a, int *b) {
    int *t = a;
    a = b;
    b = t;
}
void QuickSort(vector<int> &v, int left, int right) {
    if (left >= right) return;
    int pivot = v[(left + right) / 2];
    int l = left, r = right;
    while (1) {
        while (l < right && v[l] < pivot) l++;
        while (r > left && v[r] > pivot) r--;
        if (l >= r) break;
        swap(v[l], v[r]);
        l++, r--;
    }
    QuickSort(v, left, l - 1);
    QuickSort(v, r + 1, right);
}
int main() {
    vector<int> test(100);
    random_device rnd;
    rep(i, 100) {
        rep(i, 100) test[i] = rnd();
        // ソート前の状態
        ascendingOrderChecker(test);
        QuickSort(test, 0, test.size() - 1);
        // ソート後の状態
        ascendingOrderChecker(test);
        // display(test);
    }
    return 0;
}
```
[Swift] structがデフォルトで持つMemberwise Initializerを使い続けたい。別のイニシャライザをextensionで追加すれば使い続けられるよ！

# 問題

## Memberwise Initializer

Swiftの構造体（struct）にはメンバ変数の初期化を行うイニシャライザ（_Memberwise Initializer_）がデフォルトで自動的に生成されます。この機能によって新しいメンバ変数を構造体に追加したとしても自動的にイニシャライザへの引数の追加が行われるため、イニシャライザの変更を手動でする必要もなく、対応漏れもありません。

```swift
struct Person {
    let name: String
    let age: Int
}

let john = Person(name:"John" , age: 18)
```

## Memberwise Initializerが使えなくなる

ただこの便利な_Memberwise Initializer_は、イニシャライザを追加すると上書きされて使えなくなってしまいます。
下の例では新しく追加した`birthday:`を引数にとるイニシャライザは問題なく使えるのですが、_Memberwise Initializer_が上書きされてしまい、使おうとするとエラーが出てしまいます。Xcodeではサジェストもされません。

```swift
struct Person {
    let name: String
    let age: Int

    init?(name: String, birthday: Date) {
        let today = Date()
        let dateComponents = Calendar.current.dateComponents([.year], from: birthday, to: today)

        guard let age = dateComponents.year, age >= 0 else {
            return nil
        }

        self.name = name
        self.age = age
    }
}

let john = Person(name: "John" , age: 18) // error: extra argument 'age' in call
let paul = Person(name: "Paul", birthday: someBirthday) // ok

```

## 解決方法

この問題はイニシャライザを`extension`で追加すると解決します。
下の例では`birthday:`を引数に取る新しいイニシャライザはもちろんですが、デフォルトの_Memberwise Initializer_も使えるようになっています。


```swift
struct Person {
    let name: String
    let age: Int
}

extension Person {
    init?(name: String, birthday: Date) {
        let today = Date()
        let dateComponents = Calendar.current.dateComponents([.year], from: birthday, to: today)

        guard let age = dateComponents.year, age >= 0 else {
            return nil
        }

        self.name = name
        self.age = age
    }
}

let john = Person(name: "John", age: 18) // ok
let paul = Person(name: "Paul", birthday: someBirthday) // ok
```

良いですね 👍
Flutter環境構築で「NoClassDefFoundError」が発生したときの対処法


Flutter環境構築する時にかなりハマってしまい、記事が見つからなかったためメモ。

##対象読者について
「flutter doctor --android-licenses」を入力したときに、以下のエラーが発生した方向けの記事です。

```
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
	at com.android.repository.api.SchemaModule$SchemaModuleVersion.<init>(SchemaModule.java:156)
	at com.android.repository.api.SchemaModule.<init>(SchemaModule.java:75)
	at com.android.sdklib.repository.AndroidSdkHandler.<clinit>(AndroidSdkHandler.java:81)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:73)
	at com.android.sdklib.tool.sdkmanager.SdkManagerCli.main(SdkManagerCli.java:48)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
```

##対応方法について

###①Javaのバージョン確認
まずはJavaのバージョンを確認する。

```
java -version
```

以下以外のバージョンが表示された場合、インストール済みのjavaを削除し、java8をダウンロードする。
https://www.oracle.com/jp/java/technologies/javase/javase-jdk8-downloads.html

```
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
```

###②AndroidStudioのSDK設定を変更する

以下の画面で「Configure」→「SDK Manager」を選択。
![スクリーンショット 2021-05-21 17.07.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304361/4b7432c4-173f-0be3-3c17-1bba1817030d.png)


SDKManagerが表示されたら、サイドメニューでAndrod SDKを選択し、以下２つの画面で設定を変更する。

１、SDK Platformsは以下のように。
![スクリーンショット 2021-05-21 19.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304361/681478b0-9e49-abb9-d355-a566e0cc535f.png)


２、SDK Toolsは以下のように。
![スクリーンショット 2021-05-21 19.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304361/646bae4a-0362-2169-ba38-1758ffba3432.png)


上記２つをそれぞれ変更した後、Applyを押すと変更が反映される。

変更後、再度「flutter doctor --android-licenses」を入力すると、ライセンスの設定が開始される。
flutter doctorの結果は以下。
![スクリーンショット 2021-05-21 19.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304361/52039fb8-86f0-4572-baf8-7718c7d4c24f.png)

誰かの役に立てば幸いです。
参考にしたのは以下URLです。
https://github.com/flutter/flutter/issues/57017
【未経験・自社開発】新卒一か月目の在宅エンジニア事情


## 目次
* 自己紹介
* 入社する前にやったこと
* 未経験や新卒で入社した一か月目の業務
* いま感じていること

## 自己紹介
* 新卒3ヶ月目Webエンジニア(バックエンド)
* バックエンド未経験で自社開発系企業に入社
* 大学では情報工学を専攻．フロントエンドも少し触る
* 現在は既に社内の案件に触れて実務を行っている  

### ＜業務環境＞
基本在宅勤務で、オンラインオフィスで社内のコミュニケーションは取っています。
その他GoogleMeetやZoom等のオンラインの通話ツールを使ってミーティングや
業務外の交流も行っています。
作業環境は支給のmacbookを使っていて、モニターをつないでウィンドウを拡張しながら、
据え置きのPCのように使っています。
出退勤時の移動やお昼休憩が曖昧だったりするので仕事とプライベートの境目がになりつつあります汗


## 入社する前にやったこと
就活・仕事の為として行った活動は以下の二つです。
1. Webの勉強
2. ポートフォリオの制作

1に関しては情報系の分野を大学で専攻していたため、関係する講義を受けたり、初学者が見るようなyoutubeの動画を主に
閲覧していました。フロントエンドを学生時代に勉強したり教えていたので、そこから広げるような形で少しづつサーバー
サイドの知見を広げました。例えば有名なCMSサービスの"WordPress"のテーマを作ると少しサーバーサイドの知識が必要になったりします。フロントエンドエンジニアは調べてコードをコピーすればよい話なのですが、プログラミングは慣れていたため「これは何を参照されて得られた情報なのか？」というのを遡ったりすると気が付いたらバックエンドの領域だった、といった風に気になることを調べていくうちに知見がある程度ついたのと、自分のエンジニア志向がバックエンドよりだということにも気づきました。
2は自社開発系のエンジニア求人は新卒でもポートフォリオを求められることが多かったため制作した、という経緯で
私は外部APIから飲食店情報を取得、表示、というフロントエンドメインの飲食店検索webアプリを作りました。
就活と並行しての制作だったので新たに知識をインプットして作るというよりは、”今自分ができること”を主軸に”これから専門としていきたいこと”を少し取り入れることを意識しました。

## 入社一ヵ月目の業務
* 動画研修
新卒で入社すると社会人としてのマナー研修等を含めた研修が数か月あると思いますが、
私が受けているのは動画配信サービスを使った研修です。
技術的な研修もそこで受けることができ、一日3時間ほど受講に時間を割いています。
朝出社後お昼まで受講、が毎日のルーティンです。

* 案件の着手
入社してすぐに既存サイトの管理システムの修正の担当に任されました。
先輩や上長の方と実際に手を動かしながら、開発の基礎をインプットしていきました。
この間にディレクターや他の職種の方との打ち合わせも行い、実際の業務に初月から着手していました。 

* 技術のアウトプット
今期の目標として、技術のアウトプットとして上の動画研修の内容をまとめたり、個人的に取り組んだことを
発信するという項目があるのですが、それに向けて知識をまとめる作業をしていました。

## 今感じていること
プログラミングが未経験なわけではないですが、入社後すぐに一人のエンジニアとして業務に充てていただき、とても緊張するとともに大きな責任を感じました。
社内のエンジニアの方々の印象はとてもアウトプットが豊富でオンラインのコミュニケーションだからこそ自ら発信することが大事だということがわかりました。今は入社して3か月ほどたち、いまだに多くの方に助けを求めることが頻繁にありますが、成長を楽しみつつ頑張っております。今後もこのブログを含めて自分の知見等を共有していこうと思います。
webviewでアンカーリンクが効かないのでjsで処理する


# 経緯
webviewでアプリから目次があるwebページ開いた時に正しく動作しなかったので忘備録。
なんでアンカーリンクが効かないのかは分からないのでわかる方いたら教えてください。

# HTML
```html
<h2>目次</h2>
<h3>
  <a href='#1'>第一章</a>
</h3>
<ol>
  <li>
    <a href="#1-1">第１節</a>
  </li>
  <li>
    <a href="#1-2">第２節</a>
  </li>
</ol>

<h2><a id="1">第１章</a></h2>
<h3><a id="1-1">第１章 第１節</a></h3>
<h3><a id="1-2">第１章 第２節</a></h3>

```

webブラウザだと↑だけで正しくアンカーリンク先に遷移するんですが、
webviewだと動かないので、

# 解決策

```javascript
const goToAnchor = event => {
  const target = event.target;
  const id = target.getAttribute('href').replace('#', '');
  document.getElementById(id).scrollIntoView();
  event.preventDefault();
};

document.querySelectorAll('a[href]').forEach(element => {
  element.addEventListener('click', goToAnchor);
});
```

`scrollTo()`だと動かないので、
`scrollIntoView()`で

## scrollToでいけるかなって思ったやつ

```javascript
const goToAnchor = event => {
  const target = event.target;
  const id = target.getAttribute('href').replace('#', '');
  const elemY = document.getElementById(id).getBoundingClientRect().top + window.pageYOffset;
  scrollTo({
    top: elemY,
    behavior: 'auto'
  });
  event.preventDefault();
};

document.querySelectorAll('a[href]').forEach(element => {
  element.addEventListener('click', goToAnchor);
});
```

どっちもwebブラウザ上だと動くんだけど、webviewだとscrollIntoView()しか動かなかった。
【初心者超必見】Google Colab で YOLO v3 を軽く実装してみた。（とりあえずテストのみです。学習のステップは次の記事で！）

<h1>はじめに</h1>
<p></p>
<p>〜本記事で分かること〜</p>
<p>【Google ColabでYOLO v3をテストするやり方】</p>
<p>以前、他の記事を見て実装を試みたのですが、上手くいかなくて...。<br>
   「bin.bash : darknet is directory」とかエラー出るし。<br>
   ちゃんと記事の通りに従ったんですけどね〜。っていう人向けです。</p>

<h1>実験環境</h1>
<ul>
<li>Windows10 professional</li>
<li>python 3.6.6</li>
<li>TensorFlow 1.10.0</li>
</ul>
<p>つらつらと記述しましたが、インターネットさえ繋がっていれば問題ないかと...。<br>
   今回、OSとかGPUとかほぼ関係ないので！<br>
   PythonやTensorflowなどの環境もGoogle Colab上で完結していますしね。<br>
   <br>
   つまり、<font color="red">ネット環境の整ったPC</font>があれば問題ないです。便利な世の中になりましたね。</p>

<h1>実装</h1>
<p>まず、Google Colabを開きます。<a href="https://colab.research.google.com/notebooks/intro.ipynb#recent=true">こちら</a>から、アクセスできます。<br>もし、Googleアカウントを持っていないよ！って方は、この際なので作ってしまいましょう！<br>3分もあればすぐ作れちゃいます！</p>

<p>アクセスしますと、違うタブに移行します。<br>
ここでは、下の図のようなウィンドウが開かれると思いますが<br>
「<font color="blue">ノートブックを新規作成</font>」をクリックしましょう。</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553432/3d176d3f-a4f0-3a34-1ef6-ead11f1af7a9.png")
<br><br><br><br><br>

<p>そして、Google Colabのトップページがこんな感じ。↓<br>上の画像の赤枠から新しくコードを生成していきます。</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553432/335291cc-2b2a-5a96-6d47-cde5cb5ab7e2.png">
<br><br><br>
<p>すると、新しくブロックが生成されているかと思います。<br>
ここにコードを書いていくわけですね。<br>
因みに、このブロックを「セル」と言ったりします。</p>



<br><br><br>
<p>さてさて、本番はここからです。<br>
先程生成したセルに以下のコードを打ち込んでください。<br>
次に実行します。実行方法は</p>
<ul>
<li>「Ctrl」+「Enter」を押す。</li>
<li>セルの横にある実行ボタンを押す。</li>
<li>「ランタイム」→「現在のセルを実行」を押す。</li>
</ul>
<p>があります。どれでも構いません。</p><br>

<div class="code-frame" data-lang="bash">
<div class="highlight"><pre><span class="nv">
%%bash
git clone https://github.com/pjreddie/darknet
cd darknet
make</span></pre>
</div>

<br><br><br>
<p>実行が完了しましたら、「コード」を押して、また新しくセルを生成します。<br>
そして以下のコードを打ち込んで下さい。打ち終わったら実行。<br>
このセルでは、ディープラーニングにおいての必須級アイテム「重み」を入手しています。</p>
<br>
<div class="code-frame" data-lang="bash">
<div class="highlight"><pre><span class="nv">
!wget https://pjreddie.com/media/files/yolov3.weights</span></pre>
</div>
<br><br><br>


<p>そして、いざっ！　テストへ！！<br>
新しくセルを生成して、以下のコードを打ち込み、実行です！<br><br>
詳細な説明は省きますが、以下のコードでは、<br>
「用意された関数」「dataファイル」「cfgファイル」「weightsファイル」「テスト画像」<br>
で構成されています。それぞれを適宜変更することで<br>
皆さんの用意した画像でも物体検出ができてしまうわけです。 </p>
<br>
<div class="code-frame" data-lang="bash">
<div class="highlight"><pre><span class="nv">
!./darknet detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights data/dog.jpg
</span></pre>
</div>



<h1>結果</h1>
<p>ちゃんと出力されるかなぁっとワクワクしていましたが、<br>
一向に表示される気配がありません。<br>
失敗か？と思いきや、ちゃんと保存されていました！<br>
</p>
<p>上の画像のサイドバーにある橙色で囲われた「ファイル」をクリックして、<br>
darknet → prediction.jpgの順に開いてみて下さい。</p>

<p>こんな画像が出力されれば、成功です！<br>
犬と自転車、それからトラックがしっかりと検出されていますね！</p>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553432/8237a473-87d7-d7b6-a1d9-1cbb26f77b37.jpeg">

<h1>さいごに</h1>
<p>この記事では、Google Colabを用いてYOLO v3のテスト実装を行いました。<br>
   去年はなぜか分かりませんが、うまくいかなかったんですよね〜。<br>
   結果、途中で諦めてしまったわけですが...。<br>
   今回は事前学習済みモデルを使ったテストのみだったので、次は学習の記事でも<br>
   書いてみたいと思います。<br>
   <br>
   ※あくまで私のための備忘録なので、完成度については多めに見てくださると嬉しいです。</p>
【FileMaker】PDFがうまく出力・保存されないとき〜

FileMakerでPDFを作成し、オブジェクトフィールドに保存したい場合、「あれ？保存されてない？」というときに少しこちらの記事を読んでみてください。

# よくある事例
## PDFが指定の場所に出力されていない
###パスの書き方を見直しましょう。
出力するフォルダを編集する際、直に名前を書いたりしていませんか？
#### 関数を利用する
素直にパスを取得する関数を利用してみましょう。
![スクリーンショット 2021-05-21 18.28.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/07641c5d-b7b2-6009-eb58-5febafe77cb6.png)

#### カスタム関数を作る
固有のフォルダに出力したい場合は、カスタム関数にフォルダ名を編集しておくのも直書きでのミスを防げます。
![スクリーンショット 2021-05-21 18.36.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/f0501297-a8e4-ea08-ce6f-253b13bea9db.png)
作ったカスタム関数を、フィールド設定で使います。
![スクリーンショット 2021-05-21 18.38.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/ed4293ae-0c56-1382-f90b-6639117d06ef.png)



## 出力されたけど、オブジェクトフィールドに保存されていない
### スクリプトでオブジェクトフィールドに移動しましたか？
PDFを保存するフィールドは作成してあるけれど、「[PDF を挿入](https://help.claris.com/ja/pro-help/content/insert-pdf.html)」ステップを使う場合は、フィールドに移動しておきます。
![スクリーンショット 2021-05-21 18.20.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/47020c47-7c53-21b4-ad9e-3003cba9bdca.png)

### レイアウトに出力先のオブジェクトフィールドがありますか？
フィールドに移動をする場合、そのレイアウトにフィールドがないと移動できないので、移動の段階でエラーになり、結果的に次のPDF保存のステップがエラーになります。


### レイアウトのオブジェクトフィールドはPDFモードに設定されてますか？
盲点ですが、レイアウトに配置したオブジェクトフィールドは、書式設定で「インタラクティブコンテンツ(PDF、MP3など)」に設定する必要があります。
![スクリーンショット 2021-05-21 18.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/61e1d667-7d96-3bb6-b935-00a71fc429f1.png)


# 出力したファイルの削除
削除は、今回の出力・保存とは直接関係ないですが、後から「あ、なんでこのファイルがパソコンに残ってる？」となりがちなので、追加で書いておきます。
意外と忘れがちですが、オブジェクトフィールドに保存するために一旦FileMaker外に出力したファイルを削除していますか？
テンポラリパスにファイルを出力した場合はFileMakerアプリケーションを閉じた際に自動的に削除されますが、それ以外の場所に出力した場合、ずっとファイルが残っています。
昨今は何かのトラップで自分の端末の中身が狙われる時代です。
保存し終わったらしっかりと削除しておきましょう。
以下は、ver.18以上で提供されている、「[ファイルを削除](https://help.claris.com/ja/pro-help/content/delete-file.html)」ステップの利用例です。
![スクリーンショット 2021-05-21 19.02.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/12830577-adb5-aea6-4f6f-b4c0c5cc3640.png)

ご利用のFileMakerのバージョンが17以下の場合は、「[レコードのエクスポート](https://help.claris.com/ja/pro-help/content/export-records.html)」ステップを、何も出力フィールドを指定しない方法で実行すると削除されます。
![スクリーンショット 2021-05-21 19.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/4ec81c31-0f29-89a4-7dc6-6a1b3e2f6821.png)
この時、エラー処理をオフったままだとエラーダイアログが表示されてしまうので、意図的にエラーメッセージが表示されないようにします。
オンにしたら、処理終了後オフっておくことをお忘れなく。


# 全体的なスクリプト
表紙PDFをつけるかどうかのダイアログを表示して見積書を出力するスクリプト例を貼っておきます。
![スクリーンショット 2025-03-03 12.55.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/1575e768-8e1d-454c-a7cf-5325289139f2.png)
画像にも書きましたが、PDFを保存するときにエラーが出る場合、"image:"を付けて保存してみてください！

一つのスクリプト例なので、他にも色々試してみてください。

では、解決の糸口になることを祈って！
【Ansible】regex_searchの検索内容に変数を使いたい

### はじめに
<バージョン>
ansible 2.9.7

　文字列の検索には__regex_search__が便利なので使っていましょう。
　今回は以下のような複数行のデータに対し、与えられた条件のような確認をしてみましょう。
__条件__
1. appleが含まれること
2. orangeが含まれないこと

```text:sample_data
fruit
  apple
  peach
  banana
```


### 1. 参考playbook
　今回は、loopで変数を渡すことによって検索を行います。このようにすると汎用性も高まりますね。
__ポイント__
（1）__multiline=true__を入れると、複数行にわたって検索出来る
（2）regex_search内に変数を入れることも可能

```yaml:sample_search.yml
---
- hosts: localhost
  connection: local
  gather_facts: false
  vars:
    sample_data: |
      fruit
        apple
        peach
        banana
  tasks:
    - name: "search"
      debug:
        msg: "match"
      loop:
        - "apple"
        - "orange"
      when:    # ポイント
        - >-
          sample_data | regex_search('^\s+' + item + '$', multiline=true)
```

### 2. 実行結果
　想定通りの結果を得ることが出来ました。ちなみに、whenの内容を__not sample_data ～__にすると
regex_searchにマッチしない場合に処理が実行されます。

```text:出力
(venv) [centos@ip-<ip addr> ansible]$ ansible-playbook sample_search.yml 

PLAY [localhost] *********************************************************************************************************

TASK [search] **************************************************************************************************************
ok: [localhost] => (item=apple) => 
  msg: match
skipping: [localhost] => (item=orange) 

PLAY RECAP ***************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

### 参考記事
[フィルター — Ansible Documentation](https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_filters.html#id19)
ActiveRecordでSQL_CALC_FOUND_ROWSを使う

ページネーションなどを実装するときに、実際に取得するデータをLimitでとりつつ、総レコード数を取得したい時があります。

同じクエリ条件で`count`を使って再度クエリ発行すればできますが、MySQLを使っている場合は`FOWND_ROWS`と`SQL_CALC_FOUND_ROWS`を使えば実現できます。

### FOUND_ROWS
直前のSQLで返されたレコード数が取得できるMySQLの関数です。
実際にクライアントに返されたレコード数なので、LIMITをつけているとLIMITで制限されたレコード数が取得されます。

### SQL_CALC_FOUND_ROWS
SELECT文にこのオプションをつけると、FOUND_ROWSの結果が、直前のSQLで検索された総レコード数になります。
つまり、LIMITをつけてクライアントに返されるデータを制限した場合でも、そのSQLで`count`した場合と同じレコード数が返ってくるようになります。

## ActiveRecordでの使い方
Articleテーブルにレコードが10件入っている場合。

```ruby
Article.select([
  'SQL_CALC_FOUND_ROWS id',
  :title,
  :posted_at
])
.order(:posted_at)
.take(5)

ActiveRecord::Base.connection.select_one("SELECT FOUND_ROWS() as count")
#  => {"count"=>"10"}
```

## 参考
https://dev.mysql.com/doc/refman/5.6/ja/information-functions.html#function_found-rows
【Xcode】Deployment Infoから変更したつもりになりがちなやつ備忘録

# はじめに
これのことです。
![DeploymentInfo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1165708/63c026ff-559e-d110-acc1-c0abc8763329.png)

# 1. (a)「Hide status bar」にチェックを入れたのに表示される / (b)「Status Bar Style」を変更したのに反映されない
View controller-based status bar appearance — NO //(共通)これをInfo.plistに追記
Status bar is initially hidden — YES //(a)これはチェックを入れれば変更される
Status bar style - 変更したいもの //(b)これは変更すれば反映される

# 2. 「Device Orientation」がiPadで効いていない
Supported interface orientations //チェックボックスはこちらのiPhone用にしか反映されない
Supported interface orientations (iPad) //こちらをInfo.plistから変更

※value一覧
Portrait (bottom home button)
Portrait (top home button)
Landscape (left home button)
Landscape (right home button)

# 3．「iPad」のチェックを外したのに、iPadのApp Storeに表示される
iPhone互換モードというものがあり、iPad非対応でもiPadでインストールできてしまいます。
（黒背景に小さな画面で表示されます。表示サイズ等詳細は検索してください）

Device Orientationを設定する場合、2．と同様、Supported interface orientations (iPad)にて変更しますが、加えて、一度「iPad」にチェックを入れ、表示された「Supports multiple windows」のチェックを外し、再度「iPad」のチェックを外す必要があります。
【docker】よく使うコマンド集

#コマンド
###✅コンテナbackgroundで起動

```
$ docker-compose up -d
```

###✅sync立ち上げ

```
$ docker-sync-stack start
```

###✅ひながたコマンド

```
$ docker-compose run --rm <service名>
```

###✅実行中のコンテナでコマンドを実行する

```
$ docker exec -it コンテナ名 パス（/bin/bashなど）
（例） $ docker-compose exec db bash
```

###✅Dockerで不要な（起動していない）コンテナとイメージを削除する（全部消えます笑）

```
$ docker system prune -a
```

###サービスの停止

```
$ docker-compose stop
```

###コンテナ・ネットワーク・イメージ・ボリュームの停止と削除

```
$ docker-compose down
```

###コンテナのlogチェック

```
$ docker logs -f --tail=500 <container-name>
```

###DB操作

```
$  docker-compose run --rm app rails dbconsole
```
【MQL4】IndicatorCounted()とprev_calculated

# 概要
プログラミングの基礎も知らん時に始めた言語なんで初歩的な内容になります。
逆に言えばプログラミングを知らずにインジケータをいじってる方には約に立つかも？
けど今更star()使ってる人はおらん気も…
ということで自分用の備忘録です。

# 違い
`IndicatorCounted()`は旧MQL4のint型を返す組込みメソッドで、`prev_calculated`は新MQL4のOnCalculate()の第二引数です。
似たような使い方をしますが中身が違います。
また、新MQL4の`Bars`と新MQL4のOnCalculate()の第一引数の`rates_total`も絡む内容なので同じように比較していきます。

```:IndicatorCounted()
インジケーターを立ち上げてから変化していないバーの数を返す
```
```:prev_calculated
前回OnCalculate()を呼び出した時のバー数を数える
```
```:Bars
バーの総数を数える
```
```:rates_total
バーの総数を数える
```

## start()とOnCalculate()
どちらも新しいtickを受信した時に実行される組込みメソッドです。
実行されるタイミングは同じなので深く考える必要はありませんが、実行されるタイミングは理解している方がいいので書きました。


# 比較
※ バーの最大数が100、Oncalculate()の戻り値が`rates_total`の場合

１．チャートに表示させたとき
Bars = 100
IndicatorCounted() = 0
rates_total = 100
prev_calculated = 0

２．tickを受信した時
Bars = 100
IndicatorCounted() = 99
rates_total = 100
prev_calculated = 100

３．新しいローソク足が生成された時
Bars = 101
IndicatorCounted() = 99
rates_total = 101
prev_calculated = 100

４．tickを受信した時
Bars = 101
IndicatorCounted() = 100
rates_total = 101
prev_calculated = 101

## 使用上の違い
`prev_calculated`はtickを受信した時`rates_total `と同じ値になることです。
`Bars - IndicatorCounted();`だとtick受信時に値は1となりますが、`lrates_total - prev_calculated;`だと値は0となるため期待通りの動きになりません。

## 最新のバーだけを繰り返して処理するには
変数を宣言してから、繰り返し計算する回数を+1するだけです。
こうすることでtick受信時の`lrates_total - prev_calculated;`は1になり、1回だけ繰り返す処理を実行できるようになります。

```:
limit = rates_total - prev_calculated;
if (prev_calculated > 0) limit++;
```

## 新しいバーが生成された時だけ処理するには
処理の途中で何かしらの処理を実行する際は以下の要領にすれば新しいバーが生成された時のみ実行させることができます。
毎度これを書くのは煩雑なのでメソッドにしておくと便利かもです。

```:
if(rates_total != prev_calculated && prev_calculated > 0) {
   // 処理内容
}
```

# prev_calculatedの活用方法
アラートやサイン系のインジケータを作ってる時に一番困るのがリペイントすることです。
そこで`prev_calculated`が便利になります。
`IndicatorCounted()`でも対処できる方法ですが`prev_calculated`について検証しているうちに気づきました…

結論としては、新しいバーが生成された時のみ処理を実行するように記述するということです。
要は`lrates_total - prev_calculated;`で繰り返し処理を記述すれば、新しいバーが生成された時のみ値が1となりtick受信時には処理が実行されません。
記述は以下のもののみでfor()をlimit回繰り返させるだけです。
ただ計算する箇所が変わるのでtickで処理する場合と同じ処理では期待通りの結果にならないが注意点です。

```:
limit = rates_total - prev_calculated;
```
Git　~リベース編~ 続き

#リベースコマンドの使い方

**※リベースの基本的な使い方は限定共有記事に記載してある**

```ruby:rebase
git rebase -i <コミットID>
git rebase -i HEAD~3
#’-i’はinteractiveの略で、対話的みたいな意味で話しながら変更するよみたいな意味
```

上のコマンド打った後には、ターミナルが起動するのだが、
変更したい対象のコミットの行に対して以下の変更をする。

’pick’となっているところを'edit'に変更してから保存すれば
実際に変更ができるようになる。

```ruby:一連の流れはこんな感じ
git rebase -i HEAD~3
#と入力
↓

edit hg3322 ヘッダー修正
pick tu8877 ファイルを追加
pick hg5544 READMEを編集
#editに変更してから保存
↓

#変更が完了したら以下を実行
git commit --amend
↓

#リベースが完了したら以下のコマンドを実行（これでリベース完了）
git rebase --continue
```

上の流れを'edit'と変更した箇所に対して
繰り返し行っていき、変更するコミットがなくなると終了する。
慣れていかないと使い方がムズイので
慣れていこう。。。

##コミットをまとめる

コマンドの流れは上記といっしょで、`pick`となっているところを
`squash`と変更して保存すればコミットをまとめることができる。


```ruby:squash
git rebase -i HEAD~3
#と入力
↓

squash hg3322 ヘッダー修正
squash tu8877 ファイルを追加
pick hg5544 READMEを編集
#squashに変更してから保存
↓

#この後にコミットメッセージなどの内容を書き換えたりできるので、書き換えて終了するとコミットがまとまる
```

##コミットを分割する

```ruby:一連の流れは最初に似てる
git rebase -i HEAD~3
#と入力
↓

pick hg3322 ヘッダー修正
pick tu8877 ファイルを追加
edit hg5544 READMEとindex修正
#editに変更してから保存
↓

git reset HEAD^
#'git reset'コマンドとはコミットを取り消して、ステージングしてない状態まで戻すコマンド
#'HEAD^'とはeditと変更したコミットのことを指している

#ここからそれぞれの変更をコミットしていく
git add README
git commit -m "README修正"
git add index.html
git commit -m "index.html修正"
git rebase --continue
```

これで分割が完了します。
実際のデータがどうやって動いているのかを理解してかないと
よくわからなくなるので、使って慣れるしかなさそうです:baby_tone5:
あと何よりも注意しなきゃいけないのが、
**GitHubに`push`したコミットに対しては絶対に変更したらダメです！**
【Laravel6】Hash化したURLに注意！スラッシュが入ると404エラー

#解決方法
**URL埋め込み時にHash→base64でエンコード、確認時にbase64→Hashにデコード**


#言葉の説明
●＜エンコード＞
データの符号化

●＜デコード＞
符号化されたデータを元に戻す

●＜Hashと、base64＞
base64：暗号化。そのため、双方向に戻すことができる。
Hash  ：元に戻すことができない（入力されたpasswordには戻せない）。←**こちらの方が安全**


#コード
```example.php
// DBのトークンをbase64にエンコード
$encodeToken = base64_encode($user->verified_token);
// エンコードしたものをURLに埋め込み

// Hash化されたトークンにデコード（Hash化されたものに戻す）
User::where('verified_token', base64_decode($token))->first();
// DBとの確認の際はHashに戻す
```
Git コミットせずに作業を一時的に避難させる方法

#一時避難ができる便利なコマンド

使い所としては、こんな時:information_desk_person:

何かの作業中に急なバグに対応が必要になり、
まだ作業中なのでコミットはしたくないけど、
別のブランチでの作業をしなければいけなくなってしまった時。。。
そこで、作業を一時避難することができるのが今回のコマンド

###作業を一時避難するコマンド

```ruby:stash
git stash save
#省略が可能で以下のコマンドでもOK

git stash
```

このコマンドを実行すると、変更した内容が一時的に保存される。

###一時避難した作業をリストで確認する方法

```ruby:stash_list
git stash list
#一時避難した作業の一覧を表示
```

###一時避難した作業を復元する方法

```ruby:apply
git stash apply
#最新の作業を復元してくれる

git stash apply --index
#ステージの状態を復元する

git stash apply [スタッシュ名]
#特定の作業を復元する
# git stash apply stash@{1}
```

基本的に避難した作業は0,1,2,...という順番で数字がつけられていき、
復元したい情報に合わせてスタッシュを使い分けると良さそう。

###一時避難した作業を削除する方法

```ruby:drop
git stash drop
#最新の作業を削除する

git stash drop [スタッシュ名]
#特定の作業を削除する
# git stash drop stash@{1}

git stash clear
#全部の作業を削除する
```
最後にやっておくべきこととしては、
ワークツリーを綺麗にしておくことを忘れずに。
なので、最後に`git checkout [対象のディレクトリ名・ファイル名]`をしておくことを忘れずに。。。
JavascriptでFont Awesomeのアイコンを生成する方法


Javascriptの`createElement`で Font Awesomeのアイコン`<i>`を生成する方法のメモ。
Font Awesomeの読み込みができる状態で、`<i>`を生成した後にclass名をつけてあげればOKです。
https://fontawesome.com/icons

```js:index.js
const div = document.getElementById('box');
const icon = document.createElement("i");
icon.className = "fas fa-exclamation-circle"; //アイコンのclass名
div.appendChild(icon);
```
簡単ですね。
オブジェクト指向とはを自分なりにまとめる

##はじめに

オブジェクト指向とは**概念だ！**と言われても何を言っているかさっぱり分かりませんでした。
自分の中でも整理をさせたいのでアウトプットします。

オブジェクト指向は・・・
簡単に言えば、「モノ」　と　「操作」に分けてプログラムを設計していく事である。　


##車で例えるなら・・・

様々なモノで例える事が出来ますが、今回は車で例えてみます。![スクリーンショット 2021-05-21 16.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/b7851133-b7a9-bb0a-ae06-4888f31ee59e.png)

モノとは・・・エンジンが1つある事、タイヤが4つある事、ナンバープレートがある事

操作とは・・・鍵をつけるとエンジンがつき、アクセルを踏むと走り出す

車を何千万台プログラムしてくださいってなったら相当苦痛である事が分かります。

またブレーキを踏んだら止まる事にしようとなったらまた何千万台分追加でコードを記述しなければなりません。

そうならなないためには**「車」**というモノをあらかじめ定義しておく（設計しておく）と便利だと分かります。

パトカーを作るとするなら・・・
・車を定義

・色は白黒

・サイレンをつける

大雑把ではありますが、最初に定義しておく事でモノを短縮して作る事が出来ます。

##オブジェクト指向で覚える事

3つの言葉が出てきます

**カプセル化**

**継承**

**ポリモーフィズム**

こちらもできるだけ例えで説明します。

1.カプセル化

他のプログラミングからできるだけ、変更できないようにする事です。
「車」というモノとして使い回す事が出来ますが変更したくない部分があると思います。
例えば、アクセルは1つで踏むと進む・・・
このプログラムを他のプログラムから変更できないように設定して守る事が**カプセル化**です。

2.継承

同じようなプログラミングを1箇所にまとめてコードを再利用しやすくする。
先ほどパトカーを作ったように、車の設計書を再利用して色などを変えて簡単に作る事です。

3.ポリモーフィズム

日本語訳だと多様性などと訳されます。

意識をしないで当たり前のことと思うことがあると思います。
アクセルは右足で踏む、ハンドルを右に切ると右に車が曲がるなど。

とても理解に苦しむのでプログラミングで簡単に言うと同じ名前のメソッドを複数のクラスで使用できるようにし、そのメソッドを通して、動作を切り替えることができる事です。

アクセルを踏んで動くというメソッドを使ったとして
前に動く
右に動く
左に動く

##終わりに

言葉にして書いてみてもまだまだ理解できていないなと感じました。

日々学び、知識を
増やしていきます！
個人的 Google I/O のキャッチアップの仕方

人それぞれやり方があるとは思いますが、自分はこんな感じで I/O のキャッチアップをしているよという紹介です。
ちなみに自分は現地には行かずセッション動画を見てキャッチアップする派の人です。


https://events.google.com/io/?lng=ja


## メモを取りながらセッション動画を見る
- 自分が興味あるセッションを見る
    - 自分はよく Android や Material Design 関連を中心に見ることが多い
    - 自分が詳しくない分野のセッションを見るのも知識を広げるいい機会だとは思うけど、知らないことばかりの世界は個人的にちょっとしんどい…
- 動画なので一時停止しながらメモすることができる
- セッション内に出てくるコードはメモするよりもスクショを撮るほうが手っ取り早い
- こんな感じで Scrapbox につらつら要点を書いている
![スクリーンショット 2021-05-21 17.34.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/dc9ea629-e2a1-7bf2-3843-0f1dac584c94.png)

- ここで残したメモは後に自分の引き出しになる 

## メモした内容を整理してアウトプットする
- メモしたものから記事に起こす
    - ここでアウトプットした内容が誰かの知見になる
    - こんな感じで記事にしました
        
https://qiita.com/Nabe1216/items/fe75ed2401a8047d3f21

https://qiita.com/Nabe1216/items/6460890f472af030f31b

- 社内・社外の勉強会で発表したり
    - 社内はエンジニアだけでなく、デザイナーや PL・PM 向けに共有できることもあるはず
    - I/O あとは社外の勉強会で登壇できるチャンスが多い
        - 逆に他の人の発表を聞く機会も多い
- メモを整理することで自分の中の知識を整理することができる 
    - メモした内容を整理していてよくわからない箇所があればもう一度セッション動画を確認する
既にGitHubにpushしたファイルを後からgitignoreに含めたい時

git pushしたファイルの中に一般公開してはセキュリティ上良くないファイルがあったりすると思います。
僕の場合、railsで開発しているアプリにおいて、seeds.rbファイルに管理者ユーザーの情報を記載しており、一般公開されると良くないことに後から気づきました。
ファイルをgitignoreに含める方法は段階によって色々ありますが、ここではgit pushまで実行してしまっている場合を想定しています。


##実行手順

①「git rm --cached ファイル名」コマンドにて該当ファイルの削除。(ディレクトリ毎削除する場合は-rをつける。)
②.gitignoreファイルにプッシュしたくないファイル名を追記。
③再度git addからpushまでを実行する。

※①のコマンド入力時に「fatal: pathspec 'ファイル名' did not match any files」と表示される場合は、「git rm --cached --ignore-unmatch .」コマンドを入力してみてください。
このエラーはgitの管理対象外のファイルが含まれていることが原因みたいです。


##おわりに
「該当ファイルをGitHubから削除→ローカルでgitignoreに追記→再度push」という簡単な流れで実行できてよかったです。
この手順だとコミット履歴が残るという点だけ注意が必要です。
axiosとvue.jsで簡易な掲示板を作る

コードの中のコメント参考に

ボタンを押したら、
postメソッドでデータの登録を行います。
そして、からの配列に入れて、表示するというものです。

```
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>axiosとvue.jsによる掲示板</title>
</head>
<body>
  <div id="app">
    <input v-model="name"><br>
    <button v-on:click="createNewUser">作成</button>
    <ul>
      <li v-for="user in users">{{ user.name }}</li>
    </ul>
  </div>

  <script src="https://unpkg.com/vue@next"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

  <script>
Vue.createApp({
    el: '#app',
    data(){
        return {
            users: [],
        }
    },
    methods : {
    createNewUser: function(){
     axios.post('https://jsonplaceholder.typicode.com/users',{
            name: this.name
           })
          .then(response => this.users.unshift(response.data))
          .catch(error => console.log(error))     
    },
  },

}).mount('#app')
</script>

</body>
</html>
```

参考
https://reffect.co.jp/vue/vue-axios-learn
Ubuntuを新規インストールしたときによくやる設定

Ubuntuを新規にインストールした際によく行う設定をまとめておく．

# デュアルブート時の時刻ずれを直す
```bash:
$ sudo timedatectl set-local-rtc true
```

# フォルダ名を英語に変更
```bash:
$ LANG=C xdg-user-dirs-gtk-update
```


# grubの初期選択項目を変更
（Windowsアップデートの為にデフォルトで選択される順番を変更したい時に）

```bash:
$ sudo vim /etc/default/grub
```
で

```
GRUB_DEFAULT=0
```
の部分を変更．

最後に

```bash
$ sudo update-grub
```


ちなみに，順番は以下のコマンドで確認可能．

```bash
$ grep -e "^\(menuentry\)\|\(submenu\)" /boot/grub/grub.cfg
```

# Mozcでキーボードの配置がおかしくなった場合
```
$ sudo gedit /usr/share/ibus/component/mozc.xml
```
で

```
<layout>default</layout>
```
を

```
<layout>jp</layout>
```
に変更．

# 参考リンク
https://qiita.com/yoshinyan/items/d56a56414f2d21814f88
https://qiita.com/OldS9l/items/dc84f8912fc3d86f646a
https://qiita.com/arai-wa/items/3123ecb350097f79c6ef
【GAS】スタンドアロンスクリプトの導入方法 備忘録

#記事化した理由
記事の冒頭にあるような情報はググればいくらでも見つけられるのですが、
「あれ？ライブラリ化させるのにはどうすんだっけ？」とド忘れした時に
いちいち調べてるのは面倒だなあと思い、メモすることとしました。
旧IDEでの操作方法は既に記事があるので、新IDEでの操作方法について
書いていきたいと思います。

#スクリプトの作成
新IDEより版を管理しなくともライブラリ化しているようです。
スプレッドシートより「ツール」 > 「スクリプトエディタ」で新IDEを表示した後、
適当にスクリプトを書いてみます。

プロジェクト名は「HelloWorld」としておきます。

```Javascript:Sample.gs
function Hello(){
   Browser.msgBox("Hello World");
}
```

作成したら、左側の歯車マークをクリックし「プロジェクトの設定」 > 「ID」に移り、
スクリプトIDをコピーします。

#ライブラリの読み込み、実行
ライブラリを読む側のスプレッドシートのスクリプトエディタ(新IDE)を開き、
左側の「<>」ボタンをクリックしエディタを開きます。
左側メニューの「ファイル」「ライブラリ」「サービス」の中から
「ライブラリ」を選び、「+」ボタンをクリック。
するとスクリプトIDの入力フォームが現れますので、先程コピーしたIDをペーストし、検索。
そうすると先程書いたライブラリがヒットしますので、追加を押す。

後はライブラリを呼び出す記述をすればOKです。

```Javascript:Call.gs
function CallScript(){
    HelloWorld.Hello();
}
```

尚、デフォルトでバージョンはHEAD(開発モード)となっています。
バージョンを管理しもって運用する場合は、旧IDEでの操作が必要なようです。
Git コミットにタグをつける

#コミットにタグをつける

単純な話しで、コミットにタグをつければ後から
何かバグが起きても以前の状態に戻したり、
変更内容を閲覧する時に
便利となるのがタグ付けの機能。
- - - 
このコミットに対するタグ付け機能
どうやら2つほどの種類があるらしい。
一つは注釈付きのタグ(annotated)版で、付加される情報は、
1. 名前つけれる
2. コメントをつけれる
3. 署名をつけれる

もう一つは、軽量版(lightweight)版で、付加される情報は、
名前がつけれるだけです:baby:

##タグを作成する方法

※注釈付きタグの作成方法

```ruby:tag_a
git tag -a [タグ名] -m "[メッセージ]"
#例:git tag -a 20210515_01 -m "version 20210515_01"
```

`-m`オプションをつけることで、エディタが立ち上がらずに
メッセージをつけれるので、つけた方が楽。

- - -
※軽量版のタグの作成方法

```ruby:tag
git tag [タグ名]

#後からタグ付けすることもできる
git tag [タグ名] [コミット名]
#git tag 20210515_01 87fr44
```
このようにオプションをつけいないと軽量版のタグが作成される。

##タグを一覧表示させる

```ruby:tag
git tag

git tag -l 
#パターンを指定してタグを表示させる
```

##タグのデータを表示するには

```ruby:show
git show
#git show 20210515_01
```

**コマンドを打ち込むことによって、以下の情報が表示される。**
1. タグ付けした人の情報
2. タグ付けした日時
3. 注釈メッセージ
4. コミット

#リモートリポジトリにタグ情報を送信する

```ruby:tag
git push [リモート名] [タグ名]
# git push origin 20210515_01

git push origin --tags
#タグを一斉に送信するコマンド
```

- - -
実際に使われそうな場面としては、バグが起きた時とかなのかなあ~
基本的にはデプロイした日付や、
重要な変更をした時などに使うと、バックアップとしての機能に使えるので、
バンバン使っていこう。
「依存関係かく乱攻撃」を用いたソフトウェアサプライチェーンのハッキングを回避する方法

2月9日にMicrosoftは「依存関係かく乱攻撃（Dependency Confusion）」または「置換攻撃（Substitution Attack）」と呼ばれる新種の攻撃手法を警告しました。この攻撃手法の仕組みは、テクノロジー企業のアプリのビルド時に用いられるプライベートライブラリーの名前を擬制し、悪意のあるコードのライブラリーに付けてパブリックなパッケージライブラリーに登録することです。
開発者が自社環境でアプリをビルドする際に、パッケージマネージャーが社内リポジトリーに格納されたライブラリーではなく、パブリックリポジトリーに格納されている同名の（悪意ある）ライブラリーを使用することで依存関係かく乱攻撃」が自社開発環境に乱入し、それを汚染させます。

この攻撃手法は私たち開発者、テクノロジー大手企業でも大きな障害です。今回「依存関係かく乱攻撃」を用いたソフトウェアによるその障害を回避するために、DevSamurai会社は6月9日にSonatypeとともに「依存関係かく乱攻撃」を用いたソフトウェアサプライチェーンのハッキングを回避する方法Webセミナーを共催します。「依存関係かく乱攻撃」の仕組みと回避方法を徹底的に解説されますのでご興味のある方はぜひご参加ください。
申込み方法：https://www.sonatype.com/resources/webinar-q2-2021-dependency-confusion-software-supply-chain-hack-japan?utm_campaign=q2+2021+devsamurai+dependency+confusion+webinar&utm_source=email&utm_medium=email&utm_content=devsamurai
![Thiết kế không tên.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1251304/4510227f-6bf4-3d5e-8547-be6d06b63558.png)
【Unity】SpoutSyphonの紹介 ソフト間の動画転送をクロスプラットフォーム化

#はじめに
Unityの映像をTouchDesignerやOFなどにリアルタイムで転送させたい。
要はVJみたいなこと。**しかも、Win/Mac両方で**。

#どうやるか？
Windowsだと[Spout](https://spout.zeal.co/)、Macでは[Syphon](http://syphon.v002.info/)が有名。
ただ、Win/Mac両方で〜となると、SpoutとSyhonの入れ替えが必要。
入れ替えるの面倒くさい。。。

ということで、OS判定で切り替わる [**SpoutSyphon**](https://github.com/fuku02/SpoutSyphon) という仕組みを作りました。<br>
<iframe width="560" height="315" src="https://www.youtube.com/embed/bNbexI9FOLA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><br>

https://github.com/fuku02/SpoutSyphon

#少し解説

Unity用のSpoutはこちらが解説が詳しいです。
TouchDesignerでの受信方法も書いてあります。

https://cgworld.jp/regular/201908-codelight-unity10.html

Unity Japanのkeijiroさんが素晴らしいUnity用プラグインを公開されているので、それをOS判定で切り替えます。詳しいインストール手順は[**SpoutSyphonのReadMe**](https://github.com/fuku02/SpoutSyphon/blob/main/README.md)をご覧ください。

・[KlakSpout](https://github.com/keijiro/KlakSpout)
・[KlakSyphon](https://github.com/keijiro/KlakSyphon)

##用語の統一
SpoutSyphonを作るにあたって、用語をSpoutのものに統一しました。
送信側を**Sender**、受信側を**Receiver** としました。
(Syphonではそれぞれ ServerとClient)
![senter_receciver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/6773d6a9-7f43-c742-81d9-825f52212a3c.png)

##機能の統一
機能も統一しました。こちらは2つの良いとこどりをしています。

###キャプチャモード
キャプチャモードとして、**CameraCaptureMode** と **RenderTextureMode** がありますが、**KlakSyphonではMetalとの相性のため RenderTextureMode が使えません(2021年5月現在)**。明示的にするため、SpoutSyphonではCameraCaptureModeのみサポートしています。

###Senderセレクター
KlakSpoutはUnityEditor上の機能が充実していて、Senderを選択するセレクターがあります。
SpoutSyphonでは、ランタイム上にプルダウンメニューのセレクターを表示するようにしました。
![スクリーンショット 2021-05-14 17.01.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/96d6b4e9-5087-1772-ebf2-5a52553902c1.png)

###SenderName
SpoutSyphonでは、Syphonの命名規則を取り入れ**「AppName:SenderName」**となります。
(通常のSpoutでは「AppName」は付かない)

UnityEditor上で再生している場合は、**「Unity:SenderName」**となります。
これにより、SenderNameの重複を避けやすくなります。また、もしフルSenderNameが重複した場合は受信できなくなるので、エラーログを出すようにしました。

##拡張した機能
より使いやすくするために。

###解像度の指定
フレームレートを安定させるために、Sender/Receiverの解像度を変えたいことがあります。
SpoutSyphonでは、**インスペクターで解像度を指定できるようにしました**。指定した解像度のレンダーテクスチャーは自動生成されるので、あらかじめレンダーテクスチャーを用意しなくてよくなりました。

###AutoConnect
SpoutSyphonでは、**Receiverで指定したSenderNameに自動接続します。**この時、AppNameは評価しません。通常、ReceiverからPullする必要がありますが、AutoConnectをOnにすると接続するまでポーリングし続けるので、SenderからPushすることが可能です。
![receciver_autoConnect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/656eb00b-17f3-8c5a-6b9b-5e49129e839e.png)

#おわりに
元々は、Spout用に作った AutoConnect 機能をSyphonに移植しようとしたのが始まりでした。結果として、クロスプラットフォーム化することで、今後も拡張機能を追加しやすい仕組みになったと思います。
また、SpoutSyphonのスクリプトをアタッチするだけで使えるようになっているので、WinだけMacだけの人にもオススメです。

使ってみた感想などをいただけると励みになります。