OmniAICreator/Qiita-1.07M huggingface dataset:
link_toでカラムに値を代入する

link_toで飛ぶと同時にカラムに値を代入する様にするまでの方法をまとめます。
今回は飲食店の投稿サイトを例に使います。

お店の詳細情報ページから、そのお店のレビューを投稿するためにlink_toを用いてshop_idをlink_toに持たせてレビューを投稿できる様にします。

#使いたい値をlink_to内で飛ばす


```ruby:show.html.erb
...

<%= link_to "お店について投稿する", new_post_path(:shop_id => @shop.id) %>

...

```
お店の詳細ページでレビュー（postsモデル)が持つ`:shop_id`カラムにお店の`id`カラムをlink_to内で代入します。こうすることで飛んだ先のpostsのnewページのurlは
`localhost:3000/posts/new ?shop_id=1`
という形になり`params[:shop_id]`で受け取れる様になります。

#link_toで飛ばした先のアクションで値を受け取る

```ruby:posts_controller.rb
 def new
   @post = Post.new
   @post.shop_id = params[:shop_id]
 end
```
先ほどのurlから値を受け取ります。

#form_with内でf.hidden_fieldを使い受け取った値を使う

```ruby:new.html.erb
 <%= form_with(model: @post) do |f| %>
  ...
  <%= f.hidden_field :shop_id, :value => @post.shop_id %>
  <%= f.submit "投稿する" %>
 <% end %>
```

`f.hidden_field`を用いてユーザーが入力することなく`form_with`内でパラメータを引き渡します。
これで`link_to`で飛ばした`shop_id`をpostsのcreateアクションに引き渡すことができました。


追加：　path指定ではなく、コントローラ、アクション指定の場合

```ruby:follow_index_link
#以下のlink_toではrelationshipsコントローのfollowingアクション内で
#params[:id]でuser.idを受け取ることができます。
<%= link_to "フォロー数", {controller: :relationships, action: :following, 
                         id: user.id} %>
```
【Docker】Unhandled exception: Drive has not been shared

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

で「Unhandled exception: Drive has not been shared」エラーが発生した場合、以下の設定を変更することで解消します。

![2020-02-25_162047.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557038/15c0c6d8-005b-57f1-7a07-4c8ee3802686.png)

*setting→Resources→FILE SHARING→Cドライブにチェック*

画面キャプチャはDocker Desktop for windowsです。
three.jsでanimation system その4

#概要

three.jsでanimation systemを、理解したかった。
vrmを表示して、腕と足を動かして見た。

#参考にしたページ

https://qiita.com/segur/items/9da1dd179e4061d39e21

#成果物

https://embed.plnkr.co/8fbmark1GSjS1FwI4fGR/

以上。
Ansibleでバックスラッシュをto_jsonフィルタで出力したい

# Problem
Ansibleのtemplateモジュールでvarsに定義したバックスラッシュ`\`を含む文字列を出力する場合、varsで`'\'`のようにシングルクォートで囲めばバックスラッシュのまま出力されますが、`to_json`フィルタでJSONとして出力させようとすると、`\\`のように勝手にエスケープされてしまいます。

## 環境
- Ansible 2.8.5
- jinja2 2.10.1

## 例
### 単純な出力
```YAML:vars.yml
---
vars:
  include_backslash_text: '\n'
```

```python:template.j2
{{ vars.include_backslash_text }}
```
```bash:出力結果
\n
```

### to_jsonフィルタによる出力

```YAML:vars.yml
---
vars:
  include_backslash_text: '\n'
```

```python:template.j2
{{ vars.include_backslash_text | to_json }}
```
```bash:出力結果
"\\n"
```

おそらく、`to_json`フィルタによって値がダブルクォートで囲まれるため、フィルタが気を利かせてエスケープするものと思われます。
では、`\n`のようなバックスラッシュを含む文字列をそのままJSON形式で出力するにはどうすればいいのでしょうか。

# Solution
試行錯誤の結果、以下でうまくいきました。

```YAML:vars.yml
---
vars:
  include_backslash_text: "\n" # ダブルクォートにする
```

```python:template.j2
{{ vars.include_backslash_text | to_json | regex_replace("\\\\", "\\\\") }}
```
```bash:出力結果
"\n"
```

なぜこれでうまくいくのかよく分かりませんが、もっといい書き方があれば教えてください。
XcodeのXCUITestで実行時に引数を渡す

## about

こちらの記事でUITest実行時以外の引数の渡し方について解説しているので
基本はこちらを参考にしてください。

[Xcodeに引数を渡す LaunchArg & Env Variables](https://qiita.com/kanari3/items/2d2792cc47d22d3172ad)


ここではUITest実行時の引数の受け取り方について触れます。

Bitriseの環境変数を渡す方法についても少し触れます。


### 環境
- Xcode11.x
- Swift4.x

## 設定方法

対象Scheme -> Edit Scheme -> Run -> Arguments

![scheme_argv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/122e0124-89d1-dca9-ff62-2ce229526539.png)

それぞれチェックの入っているものをAppendしてみました。

２種類の入力が可能なので以下でみていきます。

- Arguments Passed On Launch
- Environment Variables


## Arguments Passed On Launch

型：[String]


### 取得方法

```swift
class SampleTests: XCTestCase {

    override func setUp() {
        if ProcessInfo.processInfo.arguments.contains("isTestMode") {
            print("test mode enable")
        }
    }
}
```

### 注意点

似た要素に`XCUIApplication().launchArguments`がありますが、こちらはコード内で設定したい場合に利用すればOKだと思います。

```swift
class SampleTests: XCTestCase {

    let app = XCUIApplication()

    override func setUp() {
        app.launchArguments.append("isTestMode")

        if app.launchArguments.contains("isTestMode") {}
    }
}
```

## Environment Variables

型：[String : String]

### 取得方法

スクショでの引数を受け取る方法は以下

```swift
class SampleTests: XCTestCase {
    
    override func setUp() {
        print(ProcessInfo.processInfo.environment["mode"]) //develop
    }
}

```

### 注意点

似た要素に`XCUIApplication().launchEnvironment`がありますが、こちらはコード内で設定したい場合に利用すればOKだと思います。

```swift
class SampleTests: XCTestCase {

    let app = XCUIApplication()

    override func setUp() {
        app.launchEnvironment = ["mode": "develop"]
        switch app.launchEnvironment["mode"] {
            case "develop":
                print("develop env")
            default:
                print("default env")
        }
    }
}
```

## Bitriseから環境変数を設定してコードから取得したい場合

Schemeファイルは以下のようなファイルになりますが、Bitriseのビルド時に書き換えるのはdiffを見れば分かりますが脆いのでplistを利用するのが良いと思います。
`TargetProject.xcodeproj/xcshareddata/xcschemes/TargetUITests.xcscheme`

そちらは別記事にて書きたいと思います。
Codeforces Round #624 A. Add Odd or Subtract Even

場合分けゲー。

# 概要
- 正の整数a,bが与えられる。
- あなたは何度でもaに対して、以下の2つの操作のいずれかを行える。尚、xは毎回変更して良い。
- $a = a + x$とする。ただし、xは正の任意の奇数である。
- $a = a - x$とする。ただし、xは負の任意の偶数である。
- a=bとするために最低何回の操作を行えばいいか？

# アプローチ
つまり、

- a + 奇数
- a - 偶数

を一定回数繰り返せる。以下の場合分けを行えばよい。


- a,b が一緒の場合、操作を行う必要はない。(=0)
 例: 2,2の場合。

- a < bであり、aが偶数、bが奇数なら、奇数を足せばよい(=1)
 例: 2,5 の場合 2 + 3

- a < bであり、aが偶数、bが偶数の場合、奇数を足して奇数を足せばよい(=2)
 例: 2,4 の場合 2 + 1 + 1

- a < bであり、aが奇数、bが偶数なら、奇数を足せばよい(=1)
 例: 3,8の場合 3 + 5

- a < bであり、aが奇数、bが奇数なら、奇数を足して奇数を足せばよい(=2)
 例: 3,7の場合 3 + 1 + 1

- a > bであり、aが偶数、bが奇数なら、偶数を引いて、奇数を足せばよい(=2)
 例: 6, 3 の場合 6 - 4 + 1

- a > bであり、aが偶数、bが偶数の場合、偶数を引けばよい(=1)
 例: 6, 2の場合 6 - 2

- a > bであり、aが奇数、bが偶数なら、偶数を引いて奇数を足せばよい(=2)
 例: 5, 2の場合 5 - 4 + 1

- a > bであり、aが奇数、bが奇数なら、偶数を引けばよい
 例: 5, 3の場合 5 - 2

```Python
q = int(input())
for _ in range(q):
    a, b = map(int, input().split())
    if a == b:
        print(0)
    elif a > b:
        if a%2 == 1 and b%2 == 0:
            print(2)
        elif a%2 == 1 and b%2 == 1:
            print(1)
        elif a%2 == 0 and b%2 == 0:
            print(1)
        elif a%2 == 0 and b%2 == 1:
            print(2)
    else: # a < b
        if a%2 == 1 and b%2 == 0:
            print(1)
        elif a%2 == 1 and b%2 == 1:
            print(2)
        elif a%2 == 0 and b%2 == 0:
            print(2)
        elif a%2 == 0 and b%2 == 1:
            print(1)
```
https://codeforces.com/contest/1311/problem/A
【Unity】blenderのことはよく分からないけど爆速でオブジェクトの上にクルクル回るポインタを作成したい

#はじめに

オンラインゲームでよく敵オブジェクトの頭上にクルクル回ってる矢印がありますよね。あれを作ります。
![gorilla.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/06dbd2c2-3130-b93e-47ae-6f3de63255d6.gif)

ゴリラはAssetStoreの[Gorilla Character](https://assetstore.unity.com/packages/3d/characters/animals/gorilla-character-5108)から拝借しました。

ゴリラ可愛い。

#矢印を作る

四角錐はUnityにはないので自分で作らないといけません。 [Blender](https://blender.jp/)で作ります。Blenderは無料で使えていいね。 滑らかな3Dオブジェクト作りたいなら[Sculptris](https://oakcorp.net/pixologic/sculptris/)もおすすめ。

さて、blenderを立ち上げると以下のような画面が立ち上がる。

![スクリーンショット 2020-02-14 21.09.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/a7f5006a-d49e-3fa7-4285-4d00fe511d10.png)

①立方体にカーソルを合わせて**右クリックで選択**(オレンジ色の線でほんのり囲まれていればok)

②左に「削除」ボタンがあるので削除実行する。同様にカメラとライトも消す。

③画面の中心を**左クリックでカーソル移動**、左下の方に「add」あるいは「追加」があるので、クリックしてメッシュ->円錐と選ぶ

④左下に円錐の設定画面が小さくでてくるので、頂点を4、フィルタイプをなし、にします。(下画像)
![スクリーンショット 2020-02-14 21.15.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/6a3a7290-594f-75e9-2a3a-c5fc4656f6b8.png)

⑤作成できたら右側のアイコンから、下画像で選択してるアイコンを選び、その中にある**新規**を選びます。
![スクリーンショット 2020-02-14 21.19.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/1ea339ab-6038-9288-6d37-bc95ba8ca861.png)

⑥ディフューズから好きな色に設定します。(下画像)
![スクリーンショット 2020-02-14 21.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/1796a3c9-a733-fb30-75dd-404952962ae4.png)

以上で作成終了です。ファイル->保存 します。
保存できたらUnityの適切なフォルダにドラッグアンドドロップして取り込みます。

このプレハブをゲームシーンの適当な場所に配置して反対向きに回転させれば、、
<img width="834" alt="スクリーンショット 2020-02-25 17.51.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/7fda84fe-6d06-8a0d-d87b-37096a31b3dc.png">

真っ黒ですね。これはライトの関係で、上から光を当ててるような設定にしてるので全体が影になってしまっています、、

真下に上向きスポットライトを置いて解決したことにします。

<img width="834" alt="スクリーンショット 2020-02-25 17.59.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/d05f8afd-7156-08be-3d23-aa3dcc944c99.png">

これでポインタが完成です！ ゴリラの上に移動させましょう。

<img width="832" alt="スクリーンショット 2020-02-25 18.01.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/176a6064-8bab-ddce-ebfb-1c71a4bcfba4.png">

#ポインタを回転させる。

以下のコードをUpdate関数内に書いて、ポインタにアタッチします。

```C#
// ワールドのy軸に沿って1秒間に90度回転
transform.Rotate(new Vector3(0, 90, 0) * Time.deltaTime, Space.World);
```

これで実行すると、最初に貼ったgifのような動作を実現することができます！！

#おしまい

長くなってしまったので、ポインタの上に文字を表示する方法などはまた別の機会に載せたいと思います。
【Unity】オープンワールドゲームでよくある近づいたらボタンが表示されるオブジェクトの実装

#はじめに
![gorrila_mypage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/836db70b-b0d1-5ea7-957c-e150a4acbbd7.gif)
上のgifのように、近づいたらMyPageへのボタンを表示してくれるマイページゴリラを作成します。
ただボタンで画面遷移するよりグッとゲームっぽくなりますね！
ゴリラや黄色いポインタの設置は別記事で書いたので以下を参照
[【Unity】blenderのことはよく分からないけど爆速でオブジェクトの上にクルクル回るポインタを作成したい](https://qiita.com/charly-snoopy/items/e85370203f677a716dcd)

#橙色で書かれたMyPageを表示する

簡単に説明すると、MyPageという文字の画像を用意し、それをゴリラの上に置いているだけです。

###文字を画像化する
![MyPageTitle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/28bbc859-b5a2-764d-8be6-4d34b7e8bebc.png)

僕は[MediBangPaintPro](https://medibangpaint.com/pc/)という無料のペイントツールを使って作りましたが、webでつくれるツールもあるのでよしなにしてください。ここは割愛します。

ただ、背景は**透過**にしましょう。でないと背景まで写ってしまいます。

###Canvasを設置し、その中にImageオブジェクトを設置して貼り付ける

**1**.GameObject->UI->CanvasでCanvasを設置
**2**.設置したCanvasのInspectorから、RenderModeを**World Space**にし、Event CameraにMain Cameraを設定

これで自分の好きな位置にCanvasを移動できるようになるので、位置やサイズを調整します。僕はこのCanvasを**ゴリラの子オブジェクト**にして、Positionをすべて0にしました。

次に先ほど作成した文字画像をUnityに取り込みます。

**3**.先ほど作成した文字画像をUnityに取り込みます。Projectビューで適当にフォルダを作成し、そこに文字画像をドラッグアンドドロップします。
**4**.画像のInspectorビューから、TextureTypeを**Sprite(2D and UI)**に設定。

これで画像を取り込み、表示する準備が完了しました。
最後にこの画像をCanvas内に表示します。

**5**.GameObject->UI->Imageで、先ほど設置したCanvas配下に画像オブジェクト作成
**6**.ImageオブジェクトのInspectorで、SourceImageに先ほどの画像を設定し、PreserveAspectにチェックを入れます。

以上で文字画像の表示が完了しました！ あとサイズは自身の仕様に合わせて変えましょう。




#プレイヤーがゴリラに近づいたことの判定処理

これは以下の画像のようにゴリラにColliderを二つアタッチすることで実現します。

![スクリーンショット 2020-02-25 19.04.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290141/5eb52988-9f62-81fe-3f54-931d97d65a38.png)

ゴリラが透過しないように一つCapsuleColliderをつけます。
もう一つはプレイヤーがゴリラの近くにいることを判定するためのColliderなので、ゴリラ前方に少し大きめのSphereColliderをアタッチします。
**SphereColliderだけisTriggerにチェックを入れておきましょう**。こうすることでオブジェクトがSphereColliderに衝突せず、CapsuleColliderに衝突するようになります。

次にプレイヤーが近づいた時の処理をコードで実装します。
isTriggerにチェックを入れているので、**OnTriggerStay**でプレイヤーがゴリラの近くにいること、**OnTriggerExit**でプライヤーがゴリラから遠ざかったことを判定します。

**プレイヤーオブジェクトにPlayerタグをつけ**、以下のコードをscriptに書いてゴリラにアタッチします。
なお、今回は長くなってしまうため、画面遷移のボタン等設置したパネルはあらかじめ作っているものとします。

```C#
void OnTriggerStay(Collider other)
{
    if (other.CompareTag("Player"))
    {
        //プレイヤーがゴリラ圏内にいるときの処理
        //ボタン等を設置したPanelを表示させる。
        Panel.SetActive(true);
    }
}
void OnTriggerExit(Collider other)
{
    if (other.CompareTag("Player"))
    {
        //プレイヤーがゴリラ圏内から出た時の処理
        //Panelを非表示にする。
        Panel.SetActive(false);
    }
}
```

これで冒頭に貼ったgifのように、プレイヤーが近づいた時だけボタンを表示するゴリラの実装ができました！！

#おしまい
簡単すぎる説明になってしまったかもしれません。
わかりにくいところなどあればコメントいただければ随時追加します。
CentOS8にVNC Serverを導入

# はじめに

コンテンツやアプリケーションによってはGUIでインストールする必要があると思います。
Oracleとかね。

今回、GUIでアプリケーションの導入が必須なため、CentOSにvnc serverを導入してみたので、その内容を記載しておく。

### 環境

クラウド:Google Cloud Platform上のCompute Engine

OS:CentOS8

# 設定

### デスクトップ環境インストール

```
$ sudo dnf groupinstall "Server with GUI"
```
### VNC Serverをインストール

```
$ sudo dnf install tigervnc-server
```

### VNC Serverの設定

dnfでtigervnc-serverをインストールした後、一度vncserverを起動し、初期設定と初期パスワードを設定します。


```
$ vncserver
```

**vncserverコマンドを実行する際は、sudoを付けずに実行してください。**

```none:出力結果

You will require a password to access your desktops.

Password:
Verify:
Would you like to enter a view-only password (y/n)? n
/usr/bin/xauth:  file /home/hogehoge/.Xauthority does not exist

New 'server1.hogehoge.com:1 (hogehoge)' desktop at :1 on machine server1.example.com

Starting applications specified in /etc/X11/Xvnc-session
Log file is /home/hogehoge/.vnc/server2.example.com:1.log
```

最初にパスワードを2回入力します。
view-only passwordの箇所はNo(n)としないと、GUIでログインできません。


更なる設定箇所がありますが、ここで一旦vncserverを停止します。

```
$ vncserver -kill :1
```

GNOMEデスクトップ環境を利用するために以下の設定ファイル(~/.vnc/xstartup)を変更します。

```none:~/.vnc/xstartup
#!/bin/sh
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
vncconfig -iconic &
dbus-launch --exit-with-session gnome-session &
```

上記設定変更後、再度vncserverを起動させれば接続できますが、リモートデスクトップの解像度を変更したい人は追加で以下のファイルのgeometryの箇所をアンコメントして解像度を変更します。

```none:~/.vnc/config
geometry=1920x1080
```

最後に再度vncserverを起動します。

```
$ vncserver
```

TCP:5901番ポートでアクセスできます。

### vnc viewerで接続

<a href="https://www.realvnc.com/en/connect/download/viewer/">このサイト</a>からvnc viewerをダウンロードして、インストールします。

IPアドレス:5901で接続

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527863/955aefa0-87c3-6cce-6d53-34163476cbf8.png)

はい。ログインできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527863/9941abca-16f4-7504-4564-bf9c5d54488d.png)


# 余談

今回GCPのCompute EngineのCentOS8環境にGNOMEデスクトップ環境とvnc serverを入れたのだが、OSの再起動後、SSHでもログインできなくなる現象に陥った。

どうも、GNOMEのデスクトップ環境をインストールすると発生するようだ。

調べた結果、GNOMEのデスクトップ環境をインストールするとDHCPクライアントが動かなくなり、IPアドレスが自動的に割り当てられない事象であることが判明。

手動で以下のコマンドを実行することにより、IPアドレスが割り当てられるようになった。

```
# dhclient
```
Google Cloud Composer で Bigquery にロード時 「Error: Bad character (ASCII 0) encountered.」の回避策

## 環境
* Google Cloud Composer （Airflow 1.10.2-composer）

## 背景
GoogleCloudStorageToBigQueryOperator を使った csv ファイルを Bigquery にロードする処理で、下記のエラーが発生しました。

> 「Error while reading data, error message: Error detected while parsing row starting at position: XXX. Error: Bad character (ASCII 0) encountered.」  

## 回避策
調べたところ、取込 csv ファイルに「[ヌル文字 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%8C%E3%83%AB%E6%96%87%E5%AD%97)」が混入しました。
さらに、こちらの[Embulk でASCII 0 encountered エラーの回避方法](https://qiita.com/kinpira/items/590217490f85451983bc#ascii-0-encountered-%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E5%9B%9E%E9%81%BF%E6%96%B9%E6%B3%95) に回避策を教えていただきました。
さて、BashOperator を使いましょう。

``` python
rm_null_char = BashOperator(
    task_id='rm_null_char',
    bash_command='./rm_null_char.sh',
    params={"src_file": "gs://src_file.csv", "fixed_file": "gs://fixed_file.csv"},
    dag=dag,
)
```

``` bash:rm_null_char.sh
#!/bin/bash

gsutil cp {{ params.src_file }} - | tr -d '\000' | gsutil cp - {{ params.fixed_file }}
```

シェルスクリプトに書いてあるコマンドは bash_command に直に書くことも試しましたが、「\000」は Airflow に解析されて、「tr -d ''」となり、何も変更しないことになりました。

## 懸念点
まだ検証、勉強不足のところがありますが、
上記のコマンドはメモリ上で動いている気がします。
大量データの csv ファイルを処理する時に、他のタスクに影響が出そう、、

あと、ヌル文字混入したのところを解決するのが根本策ですが、
csv ファイルはお客さんが提供しているものなので、回避策までにしました。
Azure DevOps Wiki の作り方

Azure DevOps は一般的な Wiki より高機能なため、作成方法や権限が少し特殊です。内容をまとめたので参考にしてください。

## 作り方

プロジェクトに wiki が存在しない場合はこのページが開きます。作成したい wiki を選択すれば wiki が作成できます。

[![Image from Gyazo](https://i.gyazo.com/3631d8575e9f06b0875a87d0e931ea49.png)](https://gyazo.com/3631d8575e9f06b0875a87d0e931ea49)

もし既に wiki が存在する場合は wiki menu から `Create new project wiki` or `Publish code as wiki` を選択すれば、新しい wiki を追加することができます。

[![Image from Gyazo](https://i.gyazo.com/ed4bb4e97eefd35c2b675155ffef2418.png)](https://gyazo.com/ed4bb4e97eefd35c2b675155ffef2418)

## 種類

Wiki の種類は `Project wiki (Provisioned)` and `Code wiki` の二種類があります。それぞれに特徴があるので、プロジェクトにあったものを選択してください。二種類は共存可能なので、二種類使うことも可能です。

公式ドキュメントに記載されている二種類の比較表はこの通りです。これだけ見てもよくわからない部分があるので、それぞれ詳しくメリットを解説します。

[![Image from Gyazo](https://i.gyazo.com/29e46a30e54de6ed90c2a1bba280fa65.png)](https://gyazo.com/29e46a30e54de6ed90c2a1bba280fa65)

### Project wiki (Provisioned)

メリットだと感じることは wiki page のみで全て操作可能、 Stakeholder が参照可能というところです。規模が小さいプロジェクトや、情報共有をしたいだけの wiki などは、基本的にこちらを使用するのがよいと思います。

- 作成制限: プロジェクトに一つのみ
- 編集: Wiki page からのみ編集可能
- 前のバージョンに戻す: Wiki page からページ単位で元に戻せる
- バージョンごとの wiki: 作成不可能
- 参照: Stakeholder も参照可能
- 置き場所: 意識しない。内部で {ProjectName}.wiki という置き場所が自動的に作られて、そこで管理される。

### Code wiki

Repos Git で管理されるとても自由度が高い wiki です。 Markdown で設計書を書く場合や、チームごとに必要な情報を細かくまとめたい場合に便利です。

- 作成制限: プロジェクトに複数作成可能
- 編集: Wiki page または Repos page または Repos への Git Push で編集可能
- 前のバージョンに戻す: Repos page または Git Push で元に戻す。 Git Revert と同じ手順
- バージョンごとの wiki: Repos の Git branch を使って作成可能
- 参照: Stakeholder は参照不可能
- 置き場所: Repos Git. Git 上の Folder の場所を選択して作る。一つの Git に複数設定することも可能。

## 権限

Azure DevOps の分かりづらい部分をまとめました。 Access Level が前提にあって、その後に Permission があります。

### Access Level

- Stakeholder: プロジェクト wiki の参照のみ。
- Basic (or VS Subscription): Permission に準ずる。

### Permission

デフォルトの Project Readers / Project Contributors / Project Administrators を使用した場合の一覧表です。

| Permission             | Wiki 作成 | Wiki 参照 | Wiki 編集 |
| ---------------------- | :-------: | :-------: | :-------: |
| Project Readers        |     x     |     o     |     x     |
| Project Contributors   |   △ ※1    |     o     |     o     |
| Project Administrators |     o     |     o     |     o     |

- `Wiki 編集` は wiki page の追加、更新、削除を含む。
- `Project wiki (Provisioned)` and `Code wiki` の二種類とも、ほぼ同じ権限です。
  - すごく細かい権限の wiki 名の変更などは権限が異なります。
- ※1: 既に Repos 上に Git が存在する状態のみ `Code wiki` の作成が可能。 `Project wiki (Provisioned)` と Repos Git の作成は不可能。

## 参考文献

- 公式ドキュメント: [Share information using READMEs or Wikis in Azure DevOps - Azure DevOps | Microsoft Docs](https://docs.microsoft.com/en-us/azure/devops/project/wiki/index?view=azure-devops)
UiPath セレクターを理解してみる【part1】

[前回の続き](https://qiita.com/k_rana/items/87527de9f181d892e1d5)です。

# セレクター手動生成？
セレクターとは下図のようなものですね。
UiPathを触っている方は見たことない人はいないですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/fabb94d1-172e-e8d6-a870-a00a9c543f83.png)

ちなみに、このセレクターはGoogle検索のここを指しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/9e62b8ad-82e8-be87-eaed-d7a4a8ad7346.png)


さて、みなさん[XML](https://ja.wikipedia.org/wiki/Extensible_Markup_Language)ってご存じでしょうか。
ご存じの方はぴんと来ていると思いますが、セレクターってXMLなんですよ。

```xml
<html title='Google' />
<webctrl name='q' tag='INPUT' />
```

htmlタグがあって、htmlタグにはtitle属性がある。
webctrlタグがあって、webctrlタグにはname属性とtag属性がある。

このXML文字列がセレクターということは、これがどういったルールで記載されているか解析すれば、手動生成できそうです。

# 開発者ツールでHTMLを見て、手動生成してみる
Chromeブラウザを開いて、F12を押すと開発者ツールが開けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/c28d23ae-0790-9c65-fdda-5ceb629b5e17.png)

Elementsタブをクリックし、赤枠の矢印を押しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/d0f1abf2-3b3e-d110-95b2-ff8c64f770d4.png)

そして、Google検索の入力欄へマウスを持っていくと、こうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/6cdbb21a-8b93-2194-8f86-867b1592a82a.png)

その状態でクリックすると、該当の[HTML](https://ja.wikipedia.org/wiki/HyperText_Markup_Language)をハイライト表示してくれます。
赤枠のところは[css-selector](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Selectors)と呼ばれるものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/9f6351af-673a-d3c9-2a86-ead95045d204.png)

試しにcss-selectorで手動生成してみましょう。
UiPathはcss-selectorに完全に対応しているわけではないので注意が必要です。
classとidはcss-selectorに指定できません。

下記のようなセレクターが作りました。
chromeで動作させたい場合は、app属性に「chrome.exe」を指定してください。
その場合、UiPathにChrome拡張機能をインストールしないと動かないので注意してください。

```xml
<html title='Google' app='iexplore.exe' />
<webctrl css-selector='html>body>div>div>form>div>div>div>div>div>input' class='gLFyf gsfi' />
```

では、TypeIntoアクティビティに文字列を丸ごとつっこんで実行しましょう。
赤枠の個所に""で囲んだセレクターを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/e1000e3d-efa1-0640-d981-c059d12d0d26.png)

iexplore.exeを立ち上げ、https://google.co.jp にアクセスした状態にしておきます。
そして、TypeIntoアクティビティを用意して、セレクターをセットしたら、実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222887/578fe838-c18e-c02c-f242-efb22d43ed20.png)

問題なく実行できると思いますので、確かめてみてください。

# 終わりに
かなり飛ばし飛ばしに説明しましたが、自分でセレクターを研究してみると面白いです。
HTMLやCSSといったWeb知識はもちろん、WinFormやWPF、UWPといったWindowsのGUIフレームワークについても理解しておくと、理解の手助けになります。
gitのコミットメッセージにブランチ名を自動で含める方法

```shell
$ vi .git/hooks/prepare-commit-msg
```

```shell:prepare-commit-msg
#!/bin/sh

mv $1 $1.tmp
echo "`cat $1.tmp` `git rev-parse --abbrev-ref HEAD`" > $1
```

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [Gitlab commitメッセージに issue ID を自動で紐付ける](https://kengotakimoto.com/post-2737/)
[python]List内の値の順位を昇順／降順で取得する

# 記事の内容
PythonのListの値の順位を昇順／降順で取得したい。
昇順は調べるとすぐに見つかりましたが、降順は少し工夫が必要だったのでメモとして残します。

# コード
早速、コードです。

~~~ sample.py
from scipy.stats import rankdata

# 対象のデータ
array = [10,30,30,40,20]

# rankdataでインデックス毎の順位を取得
asc = rankdata(array)

# 昇順の表示
print(type(asc))
print(asc.astype(float))

# 降順の計算
desc = (len(asc) - asc + 1).astype(float)

# 降順の表示
print(type(desc))
print(desc)
~~~

降順はrankdataに降順で取得する処理が実装されていない様なので計算する必要がありました。
色々試してみた結果、これが一番簡単に出来そうな気がします。

以下、実行結果です。

~~~
<class 'numpy.ndarray'>
[1. 3. 5. 4. 2.]
<class 'numpy.ndarray'>
[5. 3. 1. 2. 4.]
~~~

astypeをastype(int)に変更すると

~~~
<class 'numpy.ndarray'>
[1 3 5 4 2]
<class 'numpy.ndarray'>
[5 3 1 2 4]
~~~
こうなります。

この状態で同じ値が入っていると・・

~~~
# 対象のデータ
array = [10,30,30,40,20]
~~~

~~~
<class 'numpy.ndarray'>
[1 3 3 5 2]
<class 'numpy.ndarray'>
[5 2 2 1 4]
~~~
こうなります。結果が変わってしまいました・。
floatのままだと

~~~
<class 'numpy.ndarray'>
[1.  3.5 3.5 5.  2. ]
<class 'numpy.ndarray'>
[5.  2.5 2.5 1.  4. ]
~~~

こうなります。

データに被りがない時、限定のやり方ということで・・。

# 追記
konandoirusa さんよりご指摘頂いた方法の方が圧倒的に簡単なので追記

~~~ sample.py
import numpy as np
from scipy.stats import rankdata
# 対象のデータ
array = [10,30,30,40,20]

# 昇順
print(rankdata(np.array(array)))
# 降順
print(rankdata(-np.array(array)))
~~~
実行結果

~~~
[1.  3.5 3.5 5.  2. ]
[5.  2.5 2.5 1.  4. ]
~~~
C言語のセンター試験作った。

センター試験に新しい科目が追加されました。
その名も...
＿人人人人人＿
＞　Ｃ言語　＜
￣Y^Y^Y^Y￣

~~<font color="DarkGray">センター試験もう終わったよ</font>~~

## 紹介
センター試験っぽい感じのＣ言語に関する問題を作ってみました。
[ここで公開中です。](https://legohasiri.booth.pm/items/1862096)
タダで公開中です。間違いとかあったら教えてください。

###難易度とか
時間は60分、合計32問あります。
内容としては、C言語に関する一般的な知識、C言語に関すること、プログラムの読み取りの3分野です。
多分簡単ですが、一部マニアックなものもあります。

##制作記
センター試験って結構フォントの使い分けが多いんですよね。
`問１`とか`誤っているもの`とかのところはMSゴシック。それ以外は明朝体といった感じで使い分けてるんですね。そこらへんが結構めんどくさいですね。作る方としては。

そしてセンターの特徴といえる、本文中の四角。[  1  ]っていう感じの。あれってWordでできるんですね。やり方は調べて。

そして気づいたことは、数字は基本**全角数字**ということ。プログラマが嫌う全角文字ですよ。

##訂正とか
公開からしばらく時間がたち、訂正とか書いていきます。また、公開している問題のほうは訂正してあります。
2/25
第1問 B　問3　4行目　`[  5  ] str`を`[  5  ] str[128]`に
　　　同問　　6行目　`printf("Scaned String is %s\n" a);`を`printf("Scaned String is %s\n" str);`に
　　　　 問4　選択肢の6を`lf`から`o`とし、正解を4とする。

2/26
5番の正解を2から1に訂正
第2問　問1　選択肢6の「C99まで」を「C99以前まで」に
第3問　問2　表中の「コンパイル時」を「プリプロセス時」に
第4問　問1　26～28の選択肢の4「コンパイル時」を「プリプロセス時」に

##最後に
問題を作るって知識を必要とする分やっぱり勉強になります。勉強するときは問題を作るというのはおすすめですね。
あと、Word、Excelて高い分いろんなこともできるんですね。問題はWord、解答と解答用紙はExcelで作りました。

2/26　追記
皆さんご指摘ありがとうございます。近日中に自分の犯した間違いとかをまとめて記事にしようかなと思ってます。
初心者がAdobe XDで書き出し設定をする時に高確率で遭遇する問題を解決する方法

こんにちは、デザイナーの@m-akagiです。
先日、Adobe XDをデザイナーの同僚が初めて使用した際に、以前の自分と全く同じ所でつまづいてしまったので、このメモで少しでも悩んでいる人が減るといいなと思います。

#XDの書き出し設定で迷宮に入りやすいところ
![settei2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486362/135173a3-e7a3-f4ea-9bfe-70251ad15872.png)

###書き出し設定
オブジェクトを選択＞ファイル＞書き出し＞選択したオブジェクト…
をクリックし、上記の設定画面を表示させる。

ここまでは何事もなく進むと思いますが、実はこの**設定画面にハマりポイントがある**のです。

例えば書き出し先をweb、デザイン倍率は書き出し後の倍率に設定しようとするのが自然な流れなのではないでしょうか？
特にイラレとフォトショに慣れていた人であれば、書き出し後の倍率を想定してこのデザイン倍率を設定するのが普通だと思います。

しかしXDではこの概念が違ったんです・・・！（何故そうなのかは未だに不明）

###XDの書き出しではデザイン倍率の観点が通常と真逆

つまり、書き出し結果のサイズを設定するのではなく、自分のデザインしたオブジェクトを何ｘに位置づけて設定するかなのです。

![bairitu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486362/87c36c69-290c-ad5b-0122-bb449328d760.jpeg)

**倍率1xを選択した場合**
自分のデザインが今1x起点となり、webなら2xも必要になるので1x（等倍サイズ）と2x（2倍サイズ）の画像が書き出される。

**倍率2xを選択した場合**
自分のデザインが2ｘ起点となるので、2ｘ（等倍）と1ｘ（0.5倍）が書き出される。


2xを選択したら今の画像サイズの2倍が書き出されるはずだと思い込んでいたのに、
実際は何故か1/2サイズで小さく書き出されるわけです。
この概念を理解するまで本当に悩まされました・・・



**XDでの書き出しは自分起点で倍率を設定するようにしましょう**

#まとめ
同じところで悩んでいる方の力になれるといいなと思います。
最初はつまづくこともあるかも知れませんが、XDはとても使いやすく良いツールなので
怖がらずにガンガン使い倒していきましょう！

以上！
Tableau初心者の入門メモ（フィルタの順番ークエリパイプライン）

Tableauにはクエリパイプラインという処理の順番があるらしい。
フィルタがうまく機能しないときとかはだいたいこいつのせい。なんとなく自分なりの理解ができた気がするので、忘れないように( ..)φメモメモ。
ちなみにTableauさんのヘルプページ下記。
https://help.tableau.com/current/pro/desktop/ja-jp/order_of_operations.htm
（なぜこんなにも理解しにくいのだろう。）

#処理の順番
Tableauさんによれば以下の通り。

１．抽出フィルター
２．データソースフィルター
３．コンテキストフィルター
４．セット、条件、上位Nフィルター、FixedのLOD表現の計算
５．ディメンジョンフィルター
６．データブレンド
７．INCLUDE、EXCLUDEのLOD表現の計算
８．メジャーのフィルター
９．合計の計算
１０．予測、表計算の計算
１１．傾向線、リファレンスラインの計算

今回はコンテキストフィルターとディメンジョンフィルター、メジャーのフィルターに焦点を当てて。
#やってみよう
今回はいつものスーパーストア。
お題：「2019年」の「家具」の売上が20万円以上の「顧客」を調べたい。

ということで、やってみよう。
![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/776e3658-c927-1e8f-ac31-775e36117071.png)
オーダー年（2019年）、カテゴリ（家具）でフィルタして、顧客名で売上が20万円以上の条件フィルタをつけて、ドン。
![q2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/a25c8d4e-a161-6dc7-45bb-91b653c51d06.png)
20万円未満の人たちが残っている。何故。
（わかり易いように定数線もいれてみた。）
ということで、ここでクエリパイプラインの話が出てくるわけで。
##何が起きているのか
20万円以上の顧客名フィルタだけ残して、年・カテゴリのフィルタをすべてにしてみよう。オーダー年・カテゴリを列に入れてみるとこんな感じ。
（ついでに売上を色に移動して、ステップドカラーで20万円を境にピンクになるようにしてみる。）
![q3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/666dc82c-98d1-75f4-5b8e-4eec1b2fc0c5.png)
なんやこれ・・・。
下の方まで見てみる。
![q4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/ad4a8483-ac30-9e50-3823-b141a2099bd3.png)
総計の列を見てもらえばわかる通り、年・カテゴリによらず総計が20万でフィルタされている様子。（ちなみに顧客名のフィルタを外すと、20万未満の人も出てきます。）

ということは、さっき2019年の家具でフィルタしたのに20万円未満の人が存在したのは、総計で20万でフィルタした中で、2019年・家具でフィルタされているという事っぽい。

クエリパイプラインは同じディメンジョンフィルターなのになぜ総計のフィルタが優先されているように見えるのか・・・。
##ここが肝
ここで理解をしたいのが、同じレイヤーのフィルタ（今回で言えばディメンジョンフィルター）は同時にフィルタ処理がされる。
そのフィルタ処理をする対象は、フィルタをする前のテーブル。

今回のケースはフィルタがない状態のテーブルに対して、売上合計20万以上・2019年・家具を同時にフィルタする処理が走ったためこのような動きになると理解。
ではどうしたらよいか。オーダー年・カテゴリのフィルタが売上（顧客名）フィルタより優先されるようにすればいいと。クエリパイプラインで言えば、上位にあればいいと。

そんな時に使うのがコンテキストフィルター。

##コンテキストフィルターの使い方
使い方は簡単。
優先度をあげたいディメンジョンフィルターを右クリックして、コンテキストに追加を選択
![q5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/c1258605-4a4e-8f14-83a8-59649cdd566c.png)
フィルタの色がグレーになればOK。
それでは、オーダー年とカテゴリをコンテキストフィルターに変えてみよう。
![q6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/4a2b7009-26f7-6cd0-3560-37a00352ee17.png)
できた！フィルタ入れ替えてもちゃんと動いてるっぽい。

ということで、フィルタした後にフィルタする（カテゴリを絞った上で上位Nをみる等）みたいな優先順位をつける必要があるときは、コンテキストを活用すればうまくいくと。

##別の方法
ここまではコンテキストフィルターの話。一応他のやり方も。
上の話の通り、オーダー年・カテゴリがクエリパイプラインの上にいればいいので、売上合計のフィルタを下に下げるって手も。今回は売上のメジャーがあるのでメジャーフィルターとして使えばやりたいことが実現。
![q7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/4e1d29b6-8ebb-c652-0519-fc0c301f4591.png)
顧客名のディメンジョンをフィルタから外して、売上のフィルタをドン。
下限を20万に設定してみると・・・
![q8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589595/0c6f2a0e-9ae5-5e0e-68bd-fbb95d84a086.png)
できた！

#おわりに
今回はフィルターの話だけにしたけど、LOD表現が絡むと結構重要になりそうなクエリパイプライン。FIXEDとその他で動作順序が違うとか罠だと思う。（しょうがないのだろうが・・・）

今回のメモもいつも通り自分の理解でつらつらと。
もし誰かが見て理解が違うよ！ってことがあれば教えてほしいです。切に。
javascriptでcontent-typeを自動で取得する方法

content-typeを自動で取得する方法を探した結果、`mime-types`を使うことにしました。

# 前提条件
- npmがインストールされていること

# インストール
```shell
$ npm i --save mime-types
```

# 使い方
## 設定

`touch`コマンドでファイルを作成します。

```shell
$ touch test.js
```

mime-typesモジュールの読み込みと、引数にパスを入れてメソッドを使用します。

```javascript:test.js
const mime = require('mime-types')

console.log(mime.lookup('test.json'))
console.log(mime.contentType('test.json'))
```

## 実行
`node`コマンドでtest.jsを実行します。

```shell
$ node test
```

## 出力結果

```console
application/json
application/json; charset=utf-8
```

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [mime-types - npm](https://www.npmjs.com/package/mime-types)
Open3Dの基本と点群のボクセル化

# はじめに
卒業研究でOpen3Dは一通り触れましたが、Open3D触り始めのとき日本語情報が少なすぎて困ったので少しまとめます。

たぶんOpen3Dを触り始めた人の多くがたどり着くであろうサイト→Open3D：http://lang.sist.chukyo-u.ac.jp/classes/Open3D/
こちらは公式チュートリアルの和訳ですが、チュートリアル以外にもたくさんできることがたくさんあります。
やりたいことがある場合は[公式ドキュメント](http://www.open3d.org/docs/release/index.html)を探せば大体できます（英語ですが）。

研究で行ったのは「RGB-Dカメラ画像からの点群生成」「外れ値の除去」「点群の位置合わせ」などなど。
他に行ったのは「点群のボクセル化」「RANSACを用いた平面推定」です。

今回はOpen3Dの基本と「点群のボクセル化」について書きます（といっても関数の紹介だけですが）。

# 環境
- Open3D 0.9.0
- Python 3.6

Open3Dはバージョンごとに仕様が大幅に異なるので注意。
本記事ではv0.9.0対応で記述してありますが、自分も研究にはv0.7.0を使用していたので、v0.9.0では最低限の動作確認しか行っていません。

# Open3Dの基本
RGB-D画像からの点群生成と可視化、pcdファイルへの読み書き
## RGB-D画像からの点群生成
![box.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510197/50192ff2-281e-0558-5aa8-efb9e0ccbd58.png)
右上がRealSenseから取得した画像で左が生成した点群（研究では画像を切り取ってから点群生成を行いました。）

```
import open3d as o3d

"""
Open3DにRGB-D画像入力
"""
color = o3d.Image(color_numpy) # numpy配列から変換
depth = o3d.Image(depth_numpy)
rgbd = o3d.geometry.RGBDImage.create_rgbd_image_from_color_and_depth(color, depth, convert_rgb_to_intensity=False)
pcd = o3d.geometry.PointCloud.create_point_cloud_from_rgbd_image(rgbd, pinhole_camera_intrinsic)
pcd.transform([[1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, 1]]) # 見やすくするための回転
```
pinhole_camera_intrinsicの取得方法はRealSenseなら以下の方法で取得可能。
RealSenseの設定などの処理は省いてます。

```
import pyrealsense2 as rs

# camera intrinsics取得
intr = profile.get_stream(rs.stream.color).as_video_stream_profile().get_intrinsics()
pinhole_camera_intrinsic = o3d.camera.PinholeCameraIntrinsic(intr.width, intr.height, intr.fx, intr.fy, intr.ppx, intr.ppy)
```
## 点群の可視化
```
o3d.visualization.draw_geometries([pcd])
```
点群以外にもボクセルやメッシュの可視化にも使います。

## pcdファイルへの読み書き
### 書き込み
```
# バイナリでの書き込み
o3d.io.write_point_cloud("hoge.pcd", pcd)

# asciiでの書き込み
o3d.io.write_point_cloud("hoge.pcd", pcd, True)
```
pcdファイル以外にも出力可能です。
asciiで出力しておくと見やすいので便利です。
### 読み込み
```
pcd = o3d.io.read_point_cloud("./hoge.pcd")
```

# 点群のボクセル化
```
voxel = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd, 0.03) # ボクセルのサイズ指定
o3d.visualization.draw_geometries([voxel])
```
![2020-02-25 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510197/8f61c281-4d98-ae60-306c-8db0eb862dd3.png)

Open3D触りたてのときは自分で点群のボクセル化関数を作成しましたが、もともと用意されていたらしい。。。

# おわりに
今回はOpen3Dの基本についてまとめました。
時間があれば研究内容やRANSACでの平面推定についてまとめたいですが、たぶんやりません。
【RPA導入】最初に検討する部分

"ログ保存は検討する
https://knowledge.bizrobo.com/hc/ja/articles/360027878832-%E3%83%AD%E3%82%B0%E4%BF%9D%E6%8C%81%E6%97%A5%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95"

"ロボ作成時の注意点
https://knowledge.bizrobo.com/hc/ja/articles/360028946891-%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E4%BD%9C%E6%88%90%E6%99%82%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9-%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E8%A8%AD%E8%A8%88%E3%82%AC%E3%82%A4%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3-"

"KCUを増加する前の確認「ポイント
https://knowledge.bizrobo.com/hc/ja/articles/360027987932-KCU%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B%E5%89%8D%E3%81%AE%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90%E3%81%AE%E6%B5%81%E3%82%8C%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6"

"KCU確認方法
https://knowledge.bizrobo.com/hc/ja/articles/360027878932"

"KCUのログファイルを出力する
https://knowledge.bizrobo.com/hc/ja/articles/360028154971"

"ログ保持期間などの設定
https://knowledge.bizrobo.com/hc/ja/articles/360027878832-%E3%83%AD%E3%82%B0%E4%BF%9D%E6%8C%81%E6%97%A5%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95"

"ロボット稼働の分析　まちの仕組みも書いてある
https://knowledge.bizrobo.com/hc/ja/articles/360029748592-%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E7%A8%BC%E5%83%8D%E7%8A%B6%E6%B3%81%E3%82%92%E5%88%86%E6%9E%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84-"
【DS】エクセルをCSVに出力

<img width="813" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/a79d6e30-aa68-095e-d2ef-5bd1c942dba9.png">
 
https://portal.bizrobo.com/ja/%E8%A3%BD%E5%93%81/bizrobo%EF%BC%81-basic/%E3%82%A2%E3%83%89%E3%82%AA%E3%83%B3%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8-%E3%81%A8-%E8%A3%9C%E5%8A%A9%E3%83%84%E3%83%BC%E3%83%AB?title=EXCEL%E3%82%B7%E3%83%BC%E3%83%88CSV%E5%A4%89%E6%8F%9B%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB

エクセルをCSVに出力するとき、longtextだと一気にとれる
Ruby/GTK3 - ToggleButton

`gem install gtk3`

# ToggleButton

トグルボタンは通常のGTKのボタンとよく似ているが、クリックすると再びクリックされるまでアクティブなまま、押されたままになる。ボタンの状態が変化すると「toggled」シグナルが発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/e451714a-92df-2412-4e55-ac1603b1fd15.png)

> Button 2 was turned on
> Button 1 was turned on
> Button 2 was turned off
> Button 1 was turned off


```ruby
require 'gtk3'

class ToggleButtonWindow < Gtk::Window
  def initialize
    super
    self.title = "ToggleButton Demo"
    self.border_width = 10

    hbox = Gtk::Box.new(:horizontal, 6)
    add(hbox)

    button = Gtk::ToggleButton.new(label: 'Button 1')
    button.signal_connect('toggled') { |b| on_button_toggled(b, 1) }
    hbox.pack_start(button)

    button = Gtk::ToggleButton.new(label: 'Button 2')
    button.signal_connect('toggled') { |b| on_button_toggled(b, 2) }
    button.set_active true
    hbox.pack_start(button)
  end

  def on_button_toggled(button, name)
    state = button.active? ? 'on' : 'off'
    puts "Button #{name} was turned #{state}"
  end
end

win = ToggleButtonWindow.new
win.signal_connect('destroy') { Gtk.main_quit }
win.show_all

Gtk.main
```

* [Python version](https://python-gtk-3-tutorial.readthedocs.io/en/latest/button_widgets.html#id1)
GitHubの scheduled reminders を設定して Pull Requestのレビュワー指定/ 再レビュー依頼/ Conflict等々をSlack通知する


みなさん、**[Scheduled Reminders](https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/managing-scheduled-reminders-for-pull-requests)** 使ってますか？

Scheduled Reminderとは, GitHubが Pull Pandaを買収して実現したGitHubのPR通知機能です。
[GitHub acquires Pull Panda—a better way to collaborate on code reviews](https://github.blog/2019-06-17-github-acquires-pull-panda/)

レビュワーのアサイン通知、approveやrequest change、conflictの発生などを**DMで**受け取れます。
（その点で、リポジトリを subscribeしてチャンネルに投稿するGitHubのSlack Botとは異なります）

# 手順

（私の環境では既にインストール済みなので、初めてインストールする人と画面上の差異があります）

1. [Settings > Reminders](https://github.com/settings/reminders) から、リマインダーを受け取りたいOrganizationを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/9c864354-353d-9049-8a4b-39825258ee8a.png)

2. Slackへのアクセスを承認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/de9d8667-e8fc-dbcc-21b1-5a03945643f9.png)

3. リマインダーを設定します。このとき、`Enable real-time alerts` を設定すると、レビュワー指定を受けた瞬間に通知が来るようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/0ecd553f-90f3-5d32-2a17-7e46bc2fde98.png)

ちなみに、 `You are assigned a review` は レビューの再リクエスト♻️にも対応していました。

以上です。
Airflowのタスク/DAGが失敗した時にSlackで通知する仕組み

# 背景

<img width="691" alt="スクリーンショット 2020-02-25 18.06.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/8396faf0-91b1-f398-29d0-8bc59fa881a4.png">

↑こんな感じでタスクが失敗したらSlackに通知する仕組みを実装したかった

# 実装

- Slackへの通知は Webhookを利用したAPIを利用する -> [Sending messages using Incoming Webhooks](https://api.slack.com/messaging/webhooks)
- 各TaskへのSlack通知処理の埋め込みはOperatorのコンストラクタ引数の [on_failure_callback](https://airflow.apache.org/docs/stable/_api/airflow/operators/index.html#airflow.operators.BaseOperator) を利用する
  - DAGの粒度で監視したい場合はDAGのコンストラクタ引数の [on_failure_callback](https://airflow.apache.org/docs/stable/_api/airflow/models/dag/index.html#module-contents) に同様に渡せばok
- `slack_noti` はpackage化して各DAGで呼び出せるようにすると便利


```py

import airflow
import requests
import json
from datetime import timedelta
from airflow import DAG
from airflow.operators.python_operator import PythonOperator

WEBHOOK_URL = "https://hooks.slack.com/services/xxxxx"

def slack_noti(context=""):
    url= WEBHOOK_URL
    requests.post(url, data = json.dumps({
        'username': 'Airflow',
        'channel': 'some_channel',
        'icon_url': 'https://xxx.jpeg',
        'attachments': [{
            'title': 'Failed: {}.{}.{}'.format(context['dag'], context['task'], context['execution_date']),
            "color": 'danger'
            }]
        }))

default_args = {
    "owner": "airflow",
    "depends_on_past": False,
    "start_date": airflow.utils.dates.days_ago(1),
    "retries": 1,
    "on_failure_callback": slack_noti,
    "retry_delay": timedelta(minutes=1)
}

dag = DAG("slack_dag", default_args=default_args, catchup=False, schedule_interval="@daily")

def success_py():
    # 1/0
    return 'success'

def fail_py():
    1/0
    return 'fail'

sp = PythonOperator(
    task_id='success_py',
    python_callable=success_py,
    dag=dag,
)

fp = PythonOperator(
    task_id='fail_py',
    python_callable=fail_py,
    dag=dag,
)

sp >> fp
```
Laravel　artisanコマンドのエラー　Could not open input file: artisan




##今回の題

今回の題材は、タイトルの通りです

```terminal
Could not open input file: artisan
```

という、たまーーに目にする小さなエラーです。

##解決策

簡単なことで、

**「artisan」コマンドを叩くディレクトリが間違っています。**

「artisan」コマンドは**Laravelのプロジェクトディレクトリ**で叩きます。


……解決。

##終わりに

こんな感じの小さな記事を打ちまくります。
よろしくお願いします。
「パーシャルを一部だけ非表示にしたい」`defined?`で分岐よりデフォルト値をパーシャル内に書く。が腹落ちした

# はじめに
パーシャルの内容がほとんどおなじで、一部だけ表示を変えたい（追加したい、非表示にしたい）要件がでてきました。

たとえば、以下のようなときです。

1. `posts#index`：「タイトル、公開日、書いた人」が確認できる
2. `users#show`：ユーザーの記事一覧が「タイトル、公開日」で確認できる。けれど「書いた人」の列は表示させない

## 画面のイメージ

`posts#index`では、すべての列が表示されて、

|タイトル|公開日|書いた人|
|:---:|:---:|:---:|
|タイトル|公開日|書いた人|

`users#show`では、「書いた人」の列が表示されません。

|タイトル|公開日|
|:---:|:---:|
|タイトル|公開日|


# 解決策１：`defined?`で条件分岐させる方法

[Railsのrenderでdefined?による分岐 \- PIYO \- Tech & Life \-](https://blog.piyo.tech/posts/2014-07-12-193000/)で紹介されていた「`defined?`をつかった分岐」をするとスッキリと意図どおりに書くことができて便利でした。

```rb:index.html.haml
= render "posts/list", posts: @user.posts
                       with_name_column: true
```

```rb:show.html.haml
= render "posts/list", posts: @user.posts
```

```haml:_list.html.haml
%table
  %thead
    %tr
      %th タイトル
      %th 公開日
      - if defined? with_name_column
        %th 書いた人

  %tbody
    - posts.each do |post|
      %tr
        %td= post.title
        %td= l(post.created_at)
        - if defined? with_name_column
          %td= post.user.name
```

ですが、いくつか微妙なところがありました。

- `true`でも`false`でも定義されていれば真になる（値に意味がなくてモヤッとする）
- `if with_name_column` と書きたい（`defined?`が冗長におもえる）

**変数が定義されているかどうか**を条件にするのでなく、ストレートに`true, false`で判断したいです。

# パーシャルの先頭にデフォルト値を設定すればスッキリした


```haml:_list.html.haml
-# 初期値をfalseにしておくと、"未定義"状態がなくなる！
- with_name_column ||= false
%table
  %thead
    %tr
      %th タイトル
      %th 公開日
      -# 条件式もスッキリした！
      - if with_name_column
        %th 書いた人

  %tbody
    - posts.each do |post|
      %tr
        %td= post.title
        %td= l(post.created_at)
        - if with_name_column
          %td= post.user.name
```

スイッチをONにするときは、上述したものとおなじように`with_name_column: true`とすれば、意図した動作をします。なにより`true`である意味が出ました。よいですね！ :clap:

```rb:index.html.haml
= render "posts/list", posts: @user.posts
                       with_name_column: true
```

# おわりに

「パーシャルは、呼び出し元から渡された値で動くもの」という考えが強かったため、**「パーシャル内でデフォルト値を持っておく」**という方法は発見でした :eyes::star:

パーシャル先頭に初期値を設定していることで、コードを読んだときに「初期値があるということは、呼び出し側でスイッチさせる仕様がある」ということも伝わってよいなあと感じました。
長ったらしいクエリの整形にはSQL Formatterサービスが便利

DBの実行ログやフレームワークが生成した長ったらしいSQL文を見る時面倒ではありませんか？
そんな時に便利なフォーマットサービスのメモです。

## Webサービス

### [SQLフォーマッターFor WEB](https://atl2.net/webtool/sql%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%82%BF%E3%83%BCfor-web/)

個人的にはこれがシンプルで機能的にも十分です。
日本のサービスのようなので日本語というのも嬉しいです。

### [Instant SQL Formatter](http://www.dpriver.com/pp/sqlformat.htm)

DBの種類や出力形式が幅広く選択肢があるのは素晴らしいなと。

### [Free Online SQL Formatter](https://www.freeformatter.com/sql-formatter.html#ad-output)

その他にはこんなのもあります。
ただ個人的には上記２選で十分かなという印象です。

## Chrome拡張機能

### [SQL Format](https://chrome.google.com/webstore/detail/sql-format/pdenfccaafflklfjiofedacmilbfpepb)

<img width="191" alt="スクリーンショット 2020-02-26 12.07.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/056ed2eb-52bc-b3d0-a49b-38d0e238f8d7.png">

頻繁に使う場合はweb版でなくChromeのプラグインもおすすめです。
シンプルで使いやすい。
【BluePrism】コレクションの行列変換を行う

##やりたいこと
コレクションの行列変換です。
既存のCollection ManipulationにTranspose Collectionがあるのですが、思ったのと違う結果が返ってきたので自作しました。

###Input
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/26963124-686f-ce8f-5458-06106cd8e4c7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/44c333ef-853f-db5b-3bcc-d628a841ff2d.png)
###結果
違うそうじゃない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/67497d70-4389-a9cf-9162-c4167673d384.png)

###求めている結果
行と列を変換しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186221/58ab23bc-565c-5514-9adf-8cbc0e8edda4.png)

###コード
きったないコードなので誰かリファクタリングお願いします（苦笑）

```vb
Try
	Dim New_Collection As DataTable
	New_Collection = New DataTable()

	'最大行列取得
	Dim maxRow, maxCol As Integer
	maxRow = Collection_In.Rows.Count
	maxCol = Collection_In.Columns.Count
	
	'フィールド作成,空行追加
	Dim tmpColCount As Integer = 0
	For Each r1 As DataRow In Collection_In.Rows
		New_Collection.Columns.Add("Column" & tmpColCount, Type.GetType("System.String"))
		tmpColCount = tmpColCount + 1
	Next
	For Each c1 As DataColumn In Collection_In.Columns
		Dim dr As DataRow
		dr = New_Collection.NewRow
		New_Collection.Rows.Add(dr)
	Next

	'データ登録
	Dim rowCount As Integer = 0
	Dim newColCount As Integer = 0
	While rowCount < maxRow
		Dim colCount As Integer = 0
		Dim newRowCount As Integer = 0
		For Each c3 As DataColumn In Collection_In.Columns
			New_Collection.Rows(newRowCount)("Column" & newColCount) = Collection_In.Rows(rowCount)(c3.ColumnName)
			newRowCount = newRowCount + 1
		Next
		newColCount = newColCount + 1
		rowCount = rowCount + 1
	End While

    Transpose_Collection = New_Collection.DefaultView.ToTable
    Success = True
    Message = ""
Catch e As Exception
    Success = False
    Message = e.Message
End Try
```

##注意
行列変換後のコレクションは、全列の型が「テキスト」になります。
パスワード型やフラグ型のパラメータはテキスト表記されるので、注意してください。
（例）**パスワード型の場合** ⇒ 変換前：●●●●●●●●  変換後：Password
（例）**フラグ型の場合** ⇒ 変換前：True  変換後：True（文字列）


##サンプル
https://github.com/falcslab/blueprism/tree/collection
BPA オブジェクト - コレクション行列変換.xml
【Laravel】ユーザーをシーダーで作る

## はじめに
- 業務でユーザー自身に登録させる仕様は少ない。
- コマンドラインから初期ユーザーを登録する必要がある。
- シーダーの使い方をまとめておく。

----
## シーダーの作り方
以下のコマンドで Users テーブルのシーダーを作成できる。

```
php artisan make:seeder UsersTableSeeder
```

----
## 記述方法
ファイルは database/seeds/UsersTableSeeder.php として作成される。

```
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class DatabaseSeeder extends Seeder
{
    /**
     * データベース初期値設定の実行
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => 'UserName',
            'email' => 'User@mailaddress.com',
            'password' => bcrypt('password'),
        ]);
    }
}
```
パスワードが bcrypt で暗号化しなければならないので、単純な insert 文ではデータを作成できない。

----
## 呼び出し
コマンドラインから呼び出せるように database/seeds/DatabaseSeeder.php　にクラスを登録する必要がある。

```
<?php
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call([
            UsersTableSeeder::class, // 呼び出すように追加
        ]);
    }
}
```

----
## 実行コマンド
seeder をすべて実行する。

```
$ php artisan db:seed
```

特定のクラスを指定して実行する。

```
$ php artisan db:seed --class=UsersTableSeeder
```

----
## さいごに
とにかく auth でログインを作っても、ユーザーがないとログインもできない。
[登録]を削ると新規ユーザーも登録できない。
シーダーで初期ユーザーを登録しておけば、ログインはできるし、
後でゆっくりユーザー管理機能を実装できるね。
Storage in Android11 Developer Preview

# この記事は
https://developer.android.com/preview/overview
https://developer.android.com/preview/behavior-changes-all
こちらを読めば済むことを気になったことだけ書いています。必ず最新の内容を確認してください。

また、ストレージ周りの変更については[2019のDevSummit](https://www.youtube.com/watch?v=UnJ3amzJM94&)にて同様の話がほぼされています。

# リリース時期
| Milestone      |       Timeline |    Note    |
|:-----------------|------------------:|:------------------:|
| Developer Preview|2月〜4月||
| Beta Release|5月〜7月頃？|Beta2(Final APIs and behaviors)は6月|
| Final Release|8月〜9月頃？|Android10のリリースは9月第二週|

# 全OS対象の変更
### 対象別ストレージ
Android10から物議を醸しているストレージ構造の抜本的変更

* requestLegacyExternalStorageはAPI29以下では継続して利用可能だが、30以上からは利用不可になる。
  * GooglePlayのAPIレベル要件の更新は例年11/1。現在は28であるため、実質の対応期限は2021/11/1の予想。

### 全ファイルアクセス権限付与
* MANAGE_EXTERNAL_STORAGE permissionを宣言することで、ユーザに権限を求めることができる。
* 共有ストレージ内の全てのファイルに対するread|write権限、及びMediaStoreのテーブルへのアクセス権限が付与される。
* Googleの申告フォームに申請し、ホワイトリストに載ることで初めて宣言が可能となる。
  * 「Googleが知る限りではファイルマネージャなど・・・」と言っているので、なんらかの審査があるらしい
  * 今後のdeveloper previewにて申請方法が開示される予定

### ディレクトリアクセス制限
* ACTION_OPEN_DOCUMENT もしくは　ACTION_OPEN_DOCUMENT_TREE を用いて特定のディレクトリにアクセス出来なくなる
* アプリの固有ディレクトリ（android/data等）
  * 権限を付与する必要無く、アプリ固有ディレクトリ内のファイルには最初からアクセス可能になっているためで、弊害はない。
* downloads
  * 全体が選べなくなるだけで、downloads/以下のディレクトリを個別に指定することは可能。
* SDカードのルートディレクトリ
  * おそらく全ファイルアクセス権限付与でカバーされるため？

### ファイルパスやネイティブライブラリを使ったアクセス
* 直接のファイルパスを使ってファイルにアクセスすることが可能となる
  * 詳細不明。今まではExternalStorageからパスが取れたけどMediaStoreを使わない直パスってScopedStorage以降どうなってるのか、そもそもdataからフルパス取れなくなった時点で使い勝手がかなりめんどくさいことになってるはずだしああああああああああ

# 所感
ファイルマネージャ系アプリ用に強い権限が入った以外、そこまでAndroid10と変わりないんじゃないでしょうか。直パスの使い勝手次第・・・？
【Android】リップルエフェクトとイベント遅延を併用したタップ時の演出

# 概要
Androidアプリで、リストの要素やボタンなどをタップした時に、押したことが見て分かるようにしたいです。
Androidには[リップルエフェクト](https://developer.android.com/reference/kotlin/android/graphics/drawable/RippleDrawable)という波紋のようなエフェクトがあるので、それを設定することにします。
以下では、[CardView](https://developer.android.com/reference/com/google/android/material/card/MaterialCardView?hl=ja)と[Button](https://developer.android.com/reference/kotlin/android/widget/Button)について説明します。
# 要素にリップルエフェクトを設定する
## CardView
CardViewにリップルエフェクトを付ける場合、`?android:attr/selectableItemBackground`を設定するのが簡単です。

```card.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="200dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:foreground="?android:attr/selectableItemBackground">
        <View
            android:layout_width="200dp"
            android:layout_height="100dp"
            android:background="#EEEEEE" />
    </LinearLayout>
</com.google.android.material.card.MaterialCardView>
```

![card-ripple-fore-loop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/81b5fe91-22e0-883a-2faf-01d78443a584.gif)

`background`に設定した場合は、以下のようにリップルが`View`の下に隠れます。
![card-ripple-back-loop.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124752/bb7017b1-f85f-872b-5b46-67202a0b26cf.gif)



## Button
Buttonには標準でリップルエフェクトが付いていますが、`background`を設定した場合は、リップルが付いていないもので上書きされてしまいます。
`<ripple>`を使うことで、リップル付きの`background`を設定できます。
以下では、リップル付きの角丸背景を作成しています（背景を角丸にした場合、`foreground`でリップルを付けるとリップルが角からはみ出してしまいます）。

```res/drawable/button_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:attr/colorControlHighlight">
    <item>
        <shape>
            <solid android:color="#AABEFF"/>
            <corners android:radius="28dp"/>
        </shape>
    </item>
</ripple>
```

リップルエフェクトを付けたい要素の`background`に、先ほどのdrawableを指定します。

```fragment.xml
<LinearLayout ...(略)>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/button_background" />
</LinearLayout>
```

# イベントを遅延させる
例えばカードやボタンを押すと画面遷移をする時、OSのバージョンやデバイスによっては、リップルエフェクトの発生と同時に画面が遷移してリップルが見えない場合があります。
タップイベントの実行を遅らせて、リップルが見えるようにします。
処理の遅延には`Handler()`を使っています。

```Fragment.kt
item.setOnClickListener {
    Handler().postDelayed(object : Runnable {
        override fun run() {
            // タップした時の処理
        }
    }, 100) // 遅延させたい時間をミリ秒で指定
}
```

# まとめ
- カードやボタンを押した時にリップルエフェクトが発生するようにしました。
- リップルが見えるようにタップした時の処理の実行を遅らせました。

# 参考
https://qiita.com/nissiy/items/bf2742ffb990e3c8f875
https://qiita.com/hkusu/items/32b96eef9bbaafb2dea6
シンボリックリンクのリンク先修正

# リンク先の絶対パスを変更（上書き作成）

リンク先がbeforeのパスにあった場合、そのパスをafterにしてシンボリックリンクを作成。-ilname なんてオプション初めて使ったので、メモ。


```bash
find /home/after -name "*.txt" -ilname "*before*" | while read f; do ln -snf $(readlink $f | sed 's%/home/before%/home/after%') $f; done

```
[rails] Modelに紐づく関連テーブル名一覧を取得するメモ

```ruby
User.reflect_on_all_associations.map(&:name)
=> [:orders, :address, :payments]
# has_one等を指定する事も出来る
User.reflect_on_all_associations(:has_one).map(&:name)
=> [:address]
```

参考
[reflect_on_all_associations](https://api.rubyonrails.org/classes/ActiveRecord/Reflection/ClassMethods.html#method-i-reflect_on_all_associations)
【Rails】carrierwaveの使用時「Nil location provided. Can't build URI.」が出てきた時の解決方法

#エラー発生
carrierwaveで実装中、画像を投稿しようとしても

```
Nil location provided. Can't build URI
```
のエラーが出てきた。

#解決方法
uploaderでデフォルトの設定を忘れてた。

```
  def default_url
    'board_placeholder.png'
  end
```

こうやって設定すると画像がない場合もデフォルトを出してくれるのでエラーが出なくなった。