OmniAICreator/Qiita-1.07M huggingface dataset:
vuelidateを使ってバリデーションを実装する。


インストール

```shell
npm install vuelidate --save
```

グローバルで使用するときは、下記のように記述

```javascript
import Vue from "vue";
import Vuelidate from "vuelidate";
Vue.use(Vuelidate);
```

コンポーネント内で直接使用するときは、

```javascript
import { validationMixin } from 'vuelidate'

var Component = Vue.extend({
  mixins: [validationMixin],
  validations: { ... }
})
```

のようにコンポーネントファイルに追加してください。

例えば、age と message という 2 つの属性にそれぞれ必須のバリデーションを、
加えて、名前のほうに 4 文字以上で入力させたい場合は、下記のように validations
の中でそれぞれ`required`、name に minLength を書いていきます。

```javascript
import { required, minLength, between } from "vuelidate/lib/validators";

export default {
  data() {
    form {
      name: "",
      message: ""
    };
  },
  validations: {
    name: {
      required,
      minLength: minLength(4)
    },
    message: {
      required
    }
  }
};
```

最後に、下記のようにフォームに使用する場合は、下記のように
`v-if="!$v.form.属性.バリデーション"`でエラーメッセージを
表示させることができます。(下記はVueの例です。)

```html
<form @submit.prevent="validateForm">
  <div class="sender-info">
    <md-field :class="getValidationClass('name')">
      <label for="name" class="label">名前</label>
      <md-input
        name="name"
        id="name"
        autocomplete="given-name"
        v-model="form.name"
        class="md-accent"
      />
      <span class="md-error md-primary" v-if="!$v.form.name.required"
        >名前を入力してください</span
      >
      <span class="md-error md-primary" v-else-if="!$v.form.name.minlength"
        >名前は4文字以上で入力して下さい</span
      >
    </md-field>
  </div>
</form>
```

```javascript
  methods: {
    getValidationClass(fieldName) {
      const field = this.$v.form[fieldName];
      if (field) {
        return {
          "md-invalid": field.$invalid && field.$dirty
        };
      }
    }
  },
  validateForm() {
    this.$v.$touch();
    if (!this.$v.$invalid) {
      this.submit();
    }
  },
  submit () {
    // Instead of this timeout, here you can call your API
    window.setTimeout(() => {
      this.lastUser = `${this.form.firstName} ${this.form.lastName}`
      this.userSaved = true
      this.sending = false
      this.clearForm()
    }, 1500)
  }
```
pythonで挿入ソートを実装してみた

pythonとアルゴリズムの勉強かねがね、挿入ソートを実装してみました。

1.ランダムなリストを作成する
例:
[4,2,3,0,1]

2.一番左の値を取り出す
例:
[4,2,3,0,1]→4を取り出す

3.4を操作完了にする（初回は比較対象がないので）

[2,3,0,1]→[4]→4は操作完了

4.また一番左の値を取り出す

[2,3,0,1]→2を取り出す

5.操作完了の値と比較して、今回取り出した値のほうが小さければ位置を入れ替える。
　今回取り出した値のほうが大きければ、取り出した値を操作完了として次の数字を取り出してくる。

[3,0,1]→[4,2]→4より2のほうが小さいので値を入れ替え→[2,4]→左端に到達したので2は操作完了
[0,1]→[2,4,3]→4より3のほうが小さいので値を入れ替え→[2,3,4]→2より3のほうが大きいので値は入れ替えず3は操作完了

-すべての値が操作済になるまで5を繰り返す。

…という処理を挿入ソートと呼ぶらしいです。


```
import random

# 準備する値の数を入力
numbers = 10

# チェック済の値を格納するリストの作成
pop_list = []

# 乱数の作成
num_list = list(range(numbers))
random.shuffle(num_list)

def _insert_sort(num_list, pop_list):
    pop_list.append(num_list.pop(0))
    pop_num = pop_list[-1]
    print(pop_list)
    for i in range(1,len(pop_list)):
        check_num = pop_list[-i-1]
        if check_num > pop_num:
            pop_list[-i] = check_num
            pop_list[-i-1] = pop_num
        else:
            break
    
    return num_list, pop_list



def main(num_list, pop_list):
    # メイン処理
    print("START : ",num_list)

    while True:
        num_list, pop_list = _insert_sort(num_list, pop_list)
        if len(num_list) == 0:
            break

    print("GOAL  : ",pop_list)

if __name__ == '__main__':
    main(num_list, pop_list)
```
何もない状況から低コストでプログラミングを学ぶ方法を考えてみた。(RaspberryPi編)

# Background

[何もない状況から低コストでプログラミングを学ぶ方法を考えてみた。(Mac編)](https://qiita.com/satsukiya/items/1ca3554da096805e4228)の他にRaspberryPiを使って低コストでプログラミングできないか考えてみました。

てか、学習目的だったら15年前に発売されたMacでもOKと言いましたがよくよく考えたらガラケー携帯を買ってlineとかのアプリを使いこなしてねと無茶振りしているのと同義です。ジョブスすげ〜って話です。

RaspberryPiは欧米の小中高の教育向けとして広く普及している小型のPCで、5000円とかなり安いです。
またGPIOが内蔵されているので、カメラや温度・湿度・照度などのセンサー、LED、マイクなどの付属品を装着して連携することができます。

ちょうど、
[ラズパイ4で作るディスプレイ付きKubernetesクラスター](https://qiita.com/reireias/items/0d87de18f43f27a8ed9b)
と3台つないだ魔の改造:crystal_ball:をしています。
構成パーツ一覧にて価格と合計金額:moneybag:の記載が参考になります。

ここでは前回の流れの通りに
RaspberryPi？何それおいしいの？(てか食えるか:pizza:)
状態の初心者向けに最低限のパーツと価格を考えてみます。

# Price
|分類| 名前       | 価格 |リンク|
:------------------:|:-----------------|------------------:|:------------------:|
|PC本体+ケース| Raspberry Pi3 Model B+ ボード＆ケースセット| 6,490|[amazon](https://www.amazon.co.jp/dp/B07CNRTCZ9/)|
|SDカード+OS|Raspberry Pi SDカード 32GB|1,154|[rs-online](https://jp.rs-online.com/web/p/sd-cards/1360148)|
|電源| ACアダプター 5V/3.0A USB Micro-Bコネクタ出力 | 1,430 |[amazon](https://www.amazon.co.jp/dp/B01HNO7WXI/)|
|ケーブル| HDMI ケーブル | 680 |[amazon](https://www.amazon.co.jp/dp/B014I8SIJY)|
|ディスプレイ|AOPEN モニター ディスプレイ 21.5インチ (HDMI端子あり)|10,980|[amazon](https://www.amazon.co.jp/dp/B07VVFQCD2)|
|マウス| マウス USB有線|898| [amazon](https://www.amazon.co.jp/dp/B005EJH6RW) |
|キーボード|有線USBキーボード|640|[amazon](https://www.amazon.co.jp/dp/B005LL9J9G)|
||合計金額(モニターあり)|**22,272**|
||合計金額(モニターなし)|**11,292**|

# Comment
- 家電量販店で売っているmicroSDではOSが入っていない状態のため、本体に差し込んでも起動しません。何もわからない場合は[rs-online](https://jp.rs-online.com/web/p/sd-cards/1360148)にOSありのmicroSDを買ってください。もし、他にPCを持っている場合は一般的に売っているmicroSDにフォーマットをかけてbalenaetcherを使ってOSをインストールするのですがここでは方法は割愛します。
- ディスプレイはフリマサイトで安く手に入れるか、自宅にHDMI付きのテレビがあればそこから表示接続はできます。これによって合計金額よりも安く抑えることができます。
- マウス・キーボードは最初の初期設定をするときに有線でつないで操作した方が楽です。
- [Mac編](https://qiita.com/satsukiya/items/1ca3554da096805e4228)と同様に約1万から3万円の範囲内で予算が収まりました。
- 後はセッティングだけすればterminal+Python2.7は起動できます。
AWS CLI v2 の実行結果を less, more で表示したくない場合

# 結論

大抵の場合、下記コマンドで OK

```zsh
% aws configure set cli_pager ''
```

# どういう事か

今までの AWS CLI v1 はデフォルトでページャー無し表示だったが、AWS CLI v2 では実行結果の表示はデフォルトで less, more が使用される。
AWS CLI v2 でページャー無し表示したい場合には設定が必要。

Breaking Changes – Migrating from AWS CLI version 1 to version 2 - AWS Command Line Interface
https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration.html#cliv2-migration-output-pager

> By default, AWS CLI version 2 returns all output through your operating system’s default pager program. By default this program is the less program on Linux and macOS, and the more program on Windows. This can make it easier for you to navigate a large amount of output from a service by displaying that output one page at a time. However, you sometimes want all the output without needing to press a key to get each page, such as when you are running scripts. To do this, you can configure the AWS CLI version 2 to use a different paging program or none at all. To do this, configure either the AWS_PAGER environment variable or the cli_pager setting in your ~/.aws/config file and specify the command you want to use. You can specify a command that is in your search path, or specify the full path and file name for any command available on your computer. 

設定方法は下記の2つ

1. 環境変数 `AWS_PAGER` を空として設定する方法
2. `~/.aws/config` に `cli_pager` を空で設定する方法

で、大抵の場合2つ目の方法がマッチするはず・・・
`~/.aws/config` ファイルを自前で書き換えても良いものの、 AWS CLI には config 設定を行うコマンドとして `aws configure set` コマンドがあるので、これを使って設定する。

set — AWS CLI 1.17.17 Command Reference
https://docs.aws.amazon.com/cli/latest/reference/configure/set.html

> Set a configuration value from the config file.

というわけで、下記のコマンドで OK

```zsh
% aws configure set cli_pager ''
```

profile 指定したい場合

```zsh
% aws configure set cli_pager '' --profile myprofile
```

パッと反映されているか確認したい場合、 `describe-regions` がシンプルで良い

```zsh
% aws ec2 describe-regions
```

describe-regions — AWS CLI 1.17.17 Command Reference
https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-regions.html

おわり。
[font-awsomeのエラー]NoMethodError in Creditcard#indexの一例

#1.エラーの内容
<img width="1267" alt="スクリーンショット 2020-02-15 4.16.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/dd9324eb-5d48-b5af-4d60-28b06f2b1c09.png">

fontawsome利用の記述をしたところそのようなメソッドないというエラーが出ています

#2.エラーの原因
公式の記載方法に則っていましたが、gemfileに`gem "font-awesome-sass"`が抜けているからno methodエラーとなっていました

#3.エラーの解決方法
gemfileに`gem "font-awesome-sass"`を記載し、`bundle install`をすることで正しく読み込まれます

#4.その他で考えられる原因と解決方法
このエラー解決の後日別件でエラーと解決したことを記事にしましたのでこの記事で解決しなかった方はこちらもご覧ください。

https://qiita.com/KONTA2019/items/d925811fa09af69fd60e
【Python - open3d】3Dモデルのobjデータをポイントクラウドに変換する方法

# 概要

本記事では、Blenderなどで作成したモデルを、トポロジーデータ解析などに使われるポイントクラウドデータに変換する方法を示す。pythonでポイントクラウドを扱うことは少ないが、トポロジーデータ解析など解析分野で良いライブラリがあるので、解析用途で使用することがある。
その解析にobjデータを使う際、[open3D](http://www.open3d.org/docs/release/index.html)で読み込み、ポイントクラウドに変換する必要があるため、記載する。

少し調べたら出てきたので、忘備録用。


<img width="200" alt="スクリーンショット 2020-02-15 4.08.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481395/ee96f939-355d-80dd-e4f9-b4e52d911a57.png"><img width="200" alt="スクリーンショット 2020-02-15 4.08.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481395/95b96cd5-b2c2-81f2-8581-09f2c3d1f843.png">

# open3d

ポイントクラウドのデータを解析するライブラリ。基本的には、ポイントクラウドのマッチングや異常値の解析ができる。Depth情報を含むRGBDデータからポイントクラウド群の構築も可能。

# objデータの変換

ポイントクラウド(ply)形式でデータが配布されるのは稀で、3Dモデルはobj,fbxなどの形式で読み込まれる。そのため、以下のプログラムのようにobjデータのvertices(頂点)のみ取り出し、メッシュ情報を除去することで、ポイントクラウドに変換可能。

```python

import open3d as o3d
import numpy as np

def obj_mesh(path):
  return o3d.io.read_triangle_mesh(path)

def draw_mesh(mesh):
  
  mesh.paint_uniform_color([1., 0., 0.])
  mesh.compute_vertex_normals()
  o3d.visualization.draw_geometries([mesh])

def mesh2ply(mesh):
  pcd = o3d.geometry.PointCloud()
  pcd.points = o3d.utility.Vector3dVector(np.asarray(mesh.vertices))
  return pcd


if __name__ == "__main__":
  path = "/Users/washizakikai/data/obj3d/IronMan.obj"
  mesh = obj_mesh(path)
  
  pcd = mesh2ply(mesh)
```
[Rails]ActionController::UnknownFormat in UsersController#indexの解決方法

#1.エラーの内容

＜エラー文の例＞
<img width="1267" alt="スクリーンショット 2020-02-15 4.03.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/efbf538a-9541-7fab-9b32-e54804a88912.png">


題名部分の英語を読むと"creditcard_controllerに定義したindexアクションはありません"というエラー文となっています

#2.エラーの原因
1.viewファイルを作っていない
`rails g controller xxx`によってファイルを生成した直後はapp/view/xxxフォルダまでしかできておらず、viewファイルは手動で作成する必要があります

2.app/controllers/xxx_controller.rbの中の `def 〇〇` に連動したファイル名としていない
railsの機能によりcontroller.rbファイルの`def 〇〇`をrequire './view/xxx'という機能により見えないところで呼び出しを行なっています。（xxxフォルダを読み込む（実行されるのは〇〇ファイル）コマンド機能となっています)なので、その命名規則に則っていないとこのエラーとなります。

3.連動したファイル名としているがファイル（フォルダ）名を間違っている
2.と同様の理屈により、スペルミスがあったり、複数形のsをつけ忘れたりすると、呼び出し時にエラーを吐いてしまいます。

4.erbファイルではなく、hamlファイルで記載しようとした時に、gemfileの中に`gem 'haml-rails'`の記述を忘れている
hamlファイルというのは独自の追加機能で、読み込むにはgemファイルが必要であり、その記載を忘れているとファイル名があっていてもファイルそのものを読み込むことができず、エラーを吐いてしまいます

#3.エラーの解決法
1.app/view/xxx/〇〇.html.erb この位置にファイルをつくる
2.app/view の中のフォルダ名(xxx)とファイル名（〇〇）がコントローラ名と対応しているか確認する
3.対象ファイルが2.の命名規則に従いつつ誤字脱字や複数形のミスをしていないか確認する
4.（hamlファイルを使用する場合）gemfileの中に`gem 'haml-rails'`の記述を行い、`bundle install`コマンドを打つ

これで題名のエラーについて大抵のものは解決できるかと思います。
はじめまして！

マッキーです！
ブログを書くの人生初のなんですけど、何かのきっかけになればと思い書き始めました🙇‍♂️
今は、HTML/CSS,jQuery,Sassの勉強をしていて学習した内容を、アウトプットしていこうと思っています。
間違ってる部分とかあったらDMでコソッと教えてください💦

今は、この👇jQueryの本を勉強してます。
![D46A4695-DAA3-424C-87BC-F700883ECAE7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586308/1cae5807-0317-9d8f-1073-4b2dcbdd0a06.jpeg)

本当に頭悪いんですけど、一生懸命やってるので温かい目で見てやってください🙇‍♂️💦
よろしくお願いします。
xcodebuild コマンドで CODE_SIGNING_ALLOWED=NO をつけないと署名されることがある (Xcode 10.2 以降っぽい)

`xcodebuild` コマンドで iOS のプロジェクトをビルドする際の話。

# 発生した問題

Xcode 10.1 を使っていたときは下記のようなコマンドで問題なく動いていた。

```
xcodebuild clean build \
  -workspace Foo.xcworkspace -scheme Bar -configuration Debug \
  CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO
```

が、Xcode 11.1 を使うようにしたら、次のようなエラーが発生するようになってしまった。

> error: An empty identity is not valid when signing a binary for the product type 'App Extension'. (in target 'Baz' from project 'Foo')

どうやら署名しようとしたものの空の identity は valid ではないということでエラーになってしまう模様。

# 解決策

以下のように `CODE_SIGNING_ALLOWED=NO` をつけると Xcode 11.1 でも署名されないようで、ビルドできるようになった。

```
xcodebuild clean build \
  -workspace Foo.xcworkspace -scheme Bar -configuration Debug \
  CODE_SIGN_IDENTITY=\"\" \
  CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
```

# 備考

Xcode 10.1 の時は問題なくて Xcode 11.1 の時に問題に遭遇した、と書いたが、プロジェクトのコード自体も変化しているので、必ずしも Xcode のバージョンによる差異なのかどうかは確かではない。 が、下記 「参考」 に挙げた事例を見る感じ、Xcode 10.2 から挙動が変わったっぽい。

# 参考

* https://github.com/openbakery/gradle-xcodePlugin/issues/411 : Xcode 10.2 を使っていて同様の問題に遭遇した例
* https://github.com/realm/jazzy/issues/1057 : Xcode 10.2 でこの問題が起こるということが書かれている
モジュールを特異メソッドとして取り込む

特異メソッドで宣言してもincludeでは取り込めない

```ruby
module M
  def self.class_m
    "M.class_m"
  end
end

class C
  include M
end

p C.methods.include? :class_m #false
```

特異メソッドとしてクラスに取り込むには下記のようにする

```ruby
module M
  def class_m
    "M.class_m"
  end
end

class C
  extend M
end

p C.methods.include? :class_m # true
```
Refinementでクラスメソッドを再定義する

## 方法1
singleton_classを使う

```ruby
class MyClass
  def self.my_method
    'MyClass.my_method'
  end
end

module MyModule
  refine MyClass.singleton_class do
    def my_method
      'Myclass.my_method in MyModule'
    end
  end
end

using MyModule

puts MyClass.my_method # Myclass.my_method in MyModule
```

## 方法2
selfを使わずクラスメソッドを定義

```ruby
class MyClass
  def self.my_method
    'MyClass.my_method'
  end
end

module MyModule
  refine MyClass do
    def MyClass.my_method
      'Myclass.my_method in MyModule'
    end
  end
end

using MyModule

puts MyClass.my_method # Myclass.my_method in MyModule
```
もしくは

```ruby
class MyClass
  def self.my_method
    'MyClass.my_method'
  end
end

module MyModule
  refine MyClass do
    class << MyClass
      def my_method
        'Myclass.my_method in MyModule'
      end
    end
  end
end

using MyModule

puts MyClass.my_method # Myclass.my_method in MyModule
```

## selfの場合

うまく呼び出すことができない

```ruby
class MyClass
  def self.my_method
    'MyClass.my_method'
  end
end

module MyModule
  refine MyClass do
    def self.my_method
      'Myclass.my_method in MyModule'
    end
  end
end

using MyModule

puts MyClass.my_method # 'MyClass.my_method'
```
Githubのコマンドラインツール「GitHub CLI」を試してみた ～ issue編～

# はじめに

Githubのコマンドラインツール「GitHub CLI」が公開されたので、少し試してみました。
現在の「GitHub CLI」は、issueとプルリクエストに関する機能が提供されています。
この記事では、issueに関する内容を記載しています。

※ ベータ版なので、記載している内容は将来的に変更になる可能性があります。

# 環境

試した環境は、Windows10でGithub CLIのバージョンは0.5.5です。

# issue create

issueを作成します。
オプションなしで実行すると、対話形式でタイトルと本文を入力できます。

```shell
gh issue create

? Title new issue
? Body [(e) to launch notepad, enter to skip]
? What's next?  [Use arrows to move, type to filter]
  Preview in browser
> Submit
  Cancel
```

オプションでタイトルと本文を入力できます。

```shell
gh issue create -t "new issue2" -b "new issue body"
```

# issue list

存在するissueの一覧が表示されます。

```shell
gh issue list

#2  new issue2
#1  new issue
```

|オプション     |説明                                |例                             |
| ------------ | --------------------------------- | ----------------------------- |
|-a, --assignee|Assigneeでフィルタリング             |gh issue list -a [User Name]   |
|-l, --label   |Labelでフィルタリング                |gh issue list -l bug           |
|-L, --limit   |表示件数の指定(既定は30)             |gh issue list -L 10             |
|-s, --state   |状態(open/closed/all)でフィルタリング|gh issue list -s open           |

## issue status

Openのissueを状態別に表示します。

```
gh issue status

Issues assigned to you
  #2 new issue2  (bug) less than a minute ago

Issues mentioning you
  #2 new issue2  (bug) less than a minute ago

Issues opened by you
  #2 new issue2  (bug) less than a minute ago
  #1 new issue about 19 minutes ago
```

- `Issues assigned to you`は、自分がAssigneesに設定されているissueが表示されます。
- `Issues mentioning you`は、自分がメンションされているissueが表示されます。
- `Issues opened by you`は、自分が作成したissueが表示されます。

# issue view

issueをブラウザで開きます。

```
gh issue view 1
```

`-p`オプションを付けることで、ブラウザではなくコンソール上で確認できます。

```
gh issue view -p 1
```
ブラウザにデータを保存する方法

## 概要

Web システムを開発していて、データを保存しておきたいけどクライアント側だけでどうにかしたいという場合の方法をまとめました。

## 調査結果

調べた結果から書くと、`Web Storage`を使用しましょう。同じような仕組みとして`cookie`もありますが、以下の 3 つの違いから、`Web Storage`を使用した方が良いと思います。

1. 扱えるデータが`Web Storage`のほうが大きい（`cookie`は 4KB、`Web Storage`は 5MB）。
1. JavaScript による制御がより簡単。
1. `cookie`はリクエスト毎に自動送信されてしまう。

## 使用方法

まず`Web Storage`は`localStorage`と`sessionStorage`に分かれています。２つの主な違いはデータの有効期限で、`localStorage`は永続的、`sessionStorage`はウィンドウまたはタブを閉じるまでです。

２つの使用方法に大きな違いは無く、アクセスするオブジェクトが異なるだけです。

- localStorage

  ```javascript
  /* storageに値を設定 */
  localStorage.setItem("key", "value");

  /* storageから値を取得 */
  let value = localStorage.getItem("key");

  /* storageの値を削除 */
  localStorage.removeItem("key");
  ```

- sessionStorage

  ```javascript
  /* storageに値を設定 */
  sessionStorage.setItem("key", "value");

  /* storageから値を取得 */
  let value = sessionStorage.getItem("key");

  /* storageの値を削除 */
  sessionStorage.removeItem("key");
  ```

## 感想

今回調べてみて、`Web Storage`というものを初めて知りました。Jsonのような使い方ができるので使い勝手も良いと感じました。

記事に間違いや追加してほしい事がありましたら、コメントにご記入ください。
(感想も欲しいです！！💛)

## 参考文献

[MDN Web Strorage API](https://developer.mozilla.org/ja/docs/Web/API/Web_Storage_API)
Logicool G HUB でプロファイルの切替が行われないゲームを認識させる方法（Steamのゲーム限定）

細かい検証は行っておりませんので、自己責任でお願いします。
初稿：Logicool G HUB バージョン2020.1.31155
追記1：Logicool G HUB バージョン2021.9.7463
追記2：Logicool G HUB バージョン2021.10.8013

# 手動で.exe追加しても、切り替わらない・・・
G HUBにおいてPUBGのテストサーバの.exeを、自動で作られるPUBGのプロファイルのカスタムパスとして追加したが、ゲームを起動してもプロファイルが切り替わらない。
実行ファイルの方式？はライブサーバ版とテストサーバ版では変わらないはずなのになぜ？

#どうやって認識してるの？
自動で作られるプロファイルのパスは、Steamのゲームの場合
C:\Program Files(x86)\Steam\steamapps\common\PUBG\
のようにゲームフォルダまでで、.exeで指定されていない。

そこで、どのようにして、ゲームを認識しているかを解析してみた。

設定に関するファイルらしき物を探して中身をみていたら、
C:\Program Files\LGHUB\data 内の
applications.json
に奇妙な記述があった。

```json:
"detection": [
        {
          "steam": {
            "appId": "578080"
          }
        }
      ], 
      "name": "PlayerUnknown's Battlegrounds", 
      "poster_url": "pipeline://core/applications/playerunknowns_battlegrounds_poster.jpg", 
      "profile_url": "pipeline://core/applications/playerunknowns_battlegrounds_profile.jpg", 
      "version": 3
```

"detection"? 検知方法とかかな？
この"appId"の番号はsteamのストアの商品URLなどに使われるIDと同じだった。

これによりsteamから起動しているゲームの情報をもらっているのだと推測できる。
#こうしたらできました
applications.jsonに同じ書き方でsteamのゲームを追加すれば解決。
applications.jsonの構造はこうなっている（一例）

```json:
{
  "applications": [
    {
      "applicationId": "アプリケーションID（G HUB内のアプリケーション識別子）", 
      "commands": [
        ゲーム特有のコマンド(省略)
      ],
      "detection": [
        {
          "steam": {
            "appId": "steamでのID"
          }
        }
      ], 
      "name": "ゲーム名", 
      "poster_url": "プロファイルの画像の取得先", 
      "profile_url": "プロファイルの画像の取得先", 
      "version": 3
    }, 
  ]
}
```

"detection"がゲームの検知方法だと思われるが、steam以外にもレジストリを指定したりしていたが、ここではsteamを利用したゲームの検知に限定する。

よってPUBGのテストサーバを追加するには

- G HUBを一旦終了させる
- C:\Program Files\LGHUB\data\applications.json内のPUBGの部分をコピペ（ファイルのパスはG HUBのインストール先によって異なる）
- "applicationId"を別の値にする（おそらく重複していなければ何でも良い）
    - "name"のゲーム名は同じでも構わない
- "appId"をPUBGテストサーバのにする(622590)
- 管理者権限を使って上書き保存（一瞬コマンドプロンプトが立ち上がる）
- G HUBを起動する

するとゲームのパスを指定していないのに、追加されている。

<bl>
<dt>追記1</dt>
<dd> ~~いつの間にかapplications.jsonに記載されているSteamのゲームのプロファイルが追加されなくなっているのが気になり調べたところ、Redditにて[興味深い投稿](https://www.reddit.com/r/LogitechG/comments/oyqqwv/g_hub_not_detecting_games_installed_through_steam/)がされていたので、内容を軽く説明すると、
Steamがインストールされているフォルダ以外の場所にゲームをインストールするために、steamライブラリフォルダーを追加して、そこにインストールしたゲームについて~~ </dd>
<dd> ~~Steamのライブラリフォルダー関連のアップデートに対し、G HUBが対応できていないので、本記事の方法ではプロファイルの切り替えどころか、G HUBでプロファイルの自動追加すらされないことが確認されている。
<br>まぁよく見つけたなぁって感じですね~~
<br>
~~この現象については、後日別の記事でもう少し細かく解説しようと思う~~
</dd>
</bl>

<bl>
<dt>追記2</dt>
<dd>追記1の現象は、G HUBのアップデート内容に、バク修正ということで、問題が解決された記載があり、実際に未インストールとなっていたSteamのゲームが認識されているのを確認。
</dd>
</bl>

# さいごに
個人的な意見になりますが、Logicoolはハードに関しては良いものを作っているが、ソフトの可用性がイマイチで、もどかしい感じが強いです。技術的にそこまで難しいことではないと思うんですけどね。
Vagrant + Arch Linux で public_network または private_network を有効にすると vagrant up 時にエラーが出るときの対処法 → netctl をインストールする

# 解決手順
`$ sudo pacman -S netctl --noconfirm`
パッケージ `netctl` をインストールする。（--noconfirm: 確認なしで実行するオプション）

# 困っている状況
ゲストOS `archlinux/archlinux` で `Vagrantfile` の次の行を有効にした状態で `vagrant up` するとエラーが出る。

## 例1：public_network 有効化

```
config.vm.network "public_network"
```

## 例2：private_network 有効化

```
config.vm.network "private_network", ip: "192.168.33.10"
```

# 例1のエラー内容
```
==> default: Configuring and enabling network interfaces...
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

# Configure eth1
mv '/tmp/vagrant-network-eth1-xxxxxxxxxx-x' '/etc/netctl/eth1' &&
ip link set 'eth1' down &&
netctl restart 'eth1' &&
netctl enable 'eth1'

Stdout from the command:



Stderr from the command:

mv: cannot move '/tmp/vagrant-network-eth1-xxxxxxxxxx-x' to '/etc/netctl/eth1': No such file or directory
```

# エラーの意味と解消のメカニズム
`mv: cannot move '/tmp/vagrant-network-eth1-xxxxxxxxxx-x' to '/etc/netctl/eth1'`
`/etc/netctl/eth1` というディレクトリが見つからないと怒られている。

これは `netctl` をインストールすることで生成されるディレクトリである。

ゲストOS の box `archlinux/archlinux` は `netctl` を含んでいない。
`sudo pacman -S netctl` でインストールすることで解決する。

# 環境
- ホストOS: Windows 10 Pro (version 1809)
- ゲストOS: archlinux/archlinux (virtualbox, 2020.02.04)
- VirtualBox バージョン 6.0.16 r135674 (Qt5.6.2)
- Vagrant 2.2.7
TechCommitのお年玉企画で当たったTechpitの教材「Tinder風マッチングアプリを作ってみよう！」を終えて

# TechpitのTinder風マッチングアプリを作ってみよう！を完了しました

Qiita初投稿です。
TechCommitのお年玉企画で当選したこちらの教材を無事終わらせることが出来たので、感想と学んだことのメモを残しておきます。

## 学んだこと

- **content_tag**は動的にHTMLを生成出来る便利なコード。erbとhtmlが混ざってしまう時にすっきり書ける。
  - `content_tag(:i, "", class: "fas fa-cog fa-2x")` → `<i class="fas fa-cog fa-2x></i>`が生成される。
    - これは自分がInstacloneを作ってた時、font-awesomeを使う際にどのようにslimを書いていいか混乱したので、これからは迷わなくてすみそう。
- `& > a`とかはScssじゃなくCSSの書き方で、子供セレクタのみ指定する（孫はダメ）
- **transition**は変化するまでの時間や変化の度合いを指定するCSSのプロパティで、JavaScriptを使わなくても動きのある見た目の変化をつけることが出来る。
  - [【CSS3】Transition（変化）関連のまとめ - Qiita](https://qiita.com/7968/items/812d6a21fc4dd9ae9c75)
  - [transition - CSS: カスケーディングスタイルシート \| MDN](https://developer.mozilla.org/ja/docs/Web/CSS/transition)
- **border-radius**は角（ボックスで言うところのborder）を丸めるときに使うやつ。そのまま。
- `border-color: transparent transparent #fff #fff`
  - この書き方は、順に上辺｜右辺｜下辺｜左辺と、それぞれの辺の色を指定している（paddingとかと同じ仕組み）
- `@users = User.where.not(id: current_user.id)`
  - **where.not**は条件に当てはまらないものだけ取得するという意味。この場合はidがcurrent_user.id以外のものだけ取得する。NOTクエリにあたる。
- `find_or_initialize_by`メソッドは、引数で渡したカラムでfindをかけて引っかからなかったらインスタンスを作成する便利なメソッド。データべースに保存はしない。
  - TechPitのTinder風マッチングアプリ作成教材では、update_attributesでデータベースの更新をしていた。
    - [saveとupdate_attributesの違い - Qiita](https://qiita.com/katsuyuki/items/729825cf11550f38d0f3)
- `input[type="text"]:focus`はinput要素のtype="text"がユーザーの操作でフォーカスされた時のスタイルを指定する。疑似要素＝:hoverと同類。
  - [:focus擬似クラス－スタイルシートリファレンス](http://www.htmq.com/selector/focus.shtml)

## 感想

- 単純にとても楽しかった。最近取り掛かっているスクール課題と違って答えのある安心感もあった。
- また最初にアプリケーションのデータベース設計について解説されていたのが良かった。
- Deviseをはじめて使ったけど簡単すぎてびっくり。
  - ただその分魔法のようなところが多くて、英語のリファレンスを読み込まないと自分の動かしたいように動かせないなとも感じた。
- CSSをきちんと書いてくださってるので、見た目が本当に綺麗なアプリが出来ていくのでテンションが上がる。
  - 学習初日はCSS手打ちせずコピペしていたが、それでは勉強にならないと思い、手打ちして1行か2行追加するごとにページを読み込み直してCSSの挙動を確認した。
- 少し複雑そうなコードに関しては説明があるので、基本的な部分で詰まるところは少なかった。
- ただし、JavaScript（jTinder関連のコード）や、Action Cableの部分は分からないところがまだまだ多く、説明もそこまで詳しくされていなかったのでもう一度見直す必要がある。
  - [Action Cable の概要 - Railsガイド](https://railsguides.jp/action_cable_overview.html)
  - ↑書いてることが今のレベルじゃちょっと分からない
- そんなAction Cableを使ったリアルタイムチャット機能が出来たときは今まで作ったことのないような機能だったので感動した。


## 終わりに

2周目はerbではなくSlimで書きながら、JavaScriptとAction Cableの理解に重点を置きつつ復習出来たらいいなと思います。
重めのスクール課題が待ち構えているので、それが終わって余裕がある時にやります。
SwiftMailerでメールが送信できない。 Expected response code 354 but got code "554", with message "554 5.5.1・・・

local.ERROR: Expected response code 354 but got code "554", with message "554 5.5.1 Error: no valid recipients

これに遭遇した時は、メールアドレスを別のサーバで取得したメールアドレスのSMTP設定をして試してみて下さい。

取り立てドメイン、作り立てのメールアドレスだからいけないのかわかりません。
別サーバのメールアドレス変えたら、送信が出来ました。
システム側のバグではないです。バグの原因を調べる時間が喰われるのって本当やだよね。

でわ、また。
iPhoneやiPadのアプリで無料で広告ブロックする方法

#参考にした記事

iPhoneのアプリで無料で「広告」を「消す」方法　（　広告　ブロック　iPhone iPad アプリ）
広告 ブロック iPhone LINE spotify スマートニュース グノシー うざい 消し方 多い 消す ios ipad みんはや ゲーム 広告消す chrome
https://saltiga.hatenablog.com/entry/2020/02/14/221426


# ブロックにはDNScloakというアプリを用います

https://github.com/s-s/dnscloak

https://github.com/DNSCrypt/dnscrypt-proxy

DNS cloakはgo製の dnscrypt2のラッパー。(どちらもOSSです)

ローカルにDNSサーバーを立てて、フィルターにリスト化された広告サーバーのURLのリクエストを返さないことで広告を遮断します。

アプリで流れる動画広告などは完全に遮断することができます。

広告のあった場所は空白になります。（空白の部分がないように整形してhtmlを返すことも技術的には可能でadguardなどが行なっていますがセキリュティ的な問題があります）

# 実際の広告の消し方


1  app storeで「dnscloak」と「ショートカット」をインストール



[https://itunes.apple.com/jp/app/id1452162351:embed]



[https://itunes.apple.com/jp/app/id915249334:embed]



2  Safariで以下のリンクを開く(ショートカットが起動します)


[https://www.icloud.com/shortcuts/f26f84bd19e24c548079a12e0b622664:embed:cite]


3 「ショートカットを追加」をクリック

<figure class="figure-image figure-image-fotolife" title="ショートカット　広告ブロック">[f:id:saltiga:20200214215208j:plain]<figcaption>ショートカット　広告ブロック</figcaption></figure>

4  画面左下の「My workflow」を押し、「DNS cloak helper」をクリック（dns cloakが起動します）

<figure class="figure-image figure-image-fotolife" title="dns cloak hellper 広告ブロック iPhone">[f:id:saltiga:20200214215711j:plain]<figcaption>dns cloak hellper 広告ブロック iPhone</figcaption></figure>

5  DNS cloakの画面でDNS を選び、（cloudflaireが一番速いのでおすすめ）左上の再生ボタンを押す。

<figure class="figure-image figure-image-fotolife" title="広告ブロック　dns 画面">[f:id:saltiga:20200214221056j:plain]<figcaption>広告ブロック　dns 画面</figcaption></figure>



6  左上にVPNと言う表示が出たら成功です！


もしできなかった場合はコメント欄に報告してください。原因がわかれば教えます。



* 参考・引用元

[https://www.reddit.com/r/privacytoolsIO/:embed:cite]


[https://wikiwiki.jp/nanj-adguard/iOS%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E5%BA%83%E5%91%8A%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF:embed:cite]
GoとMongoDBとProtocol Buffersでの小数の扱い

MongoDB上で[`NumberDecimal()`](https://docs.mongodb.com/manual/core/shell-types/#numberdecimal)を使い`decimal`で小数を格納していたのだが、それを["mongo-go-driver"](https://github.com/mongodb/mongo-go-driver)を介して`Decode()`する時に、`cannot decode 128-bit decimal into a float32 or float64 type`とエラーが出て困ったので、各々の小数周りの仕様を調べた。

それぞれの小数周りの仕様へのリンク集としても役立つはず。

## Go

Go上で小数に対応する型は、[Numeric typesの仕様](https://golang.org/ref/spec#Numeric_types)によると、`float32`と`float64`のよう。

## Protocol Buffers
"proto3"のLanguage Guideにある[Scalar Values Type表](https://developers.google.com/protocol-buffers/docs/proto3#scalar)によると、proto上での小数表記は`float`と`doouble`で、それぞれGo上では`float => float32`、`double => float64`となるらしい。

## MongoDB
MongoDB上では、[schema定義のドキュメント](https://docs.mongodb.com/stitch/mongodb/document-schemas/#numbers)曰く、`double`と`decimal`が存在する。これはBson Typeにあたるので、[Bsonの仕様書](http://bsonspec.org/spec.html)を見てみると、どうやら64bitで表現されるのが`double`であり、128bitで表現されるのが`decimal (decimal128)`であることがわかる。

MongoDBとGoの間でやり取りするには、基本的に["mongo-go-driver"](https://github.com/mongodb/mongo-go-driver)を使うことになると思うが、その中の["go.mongodb.org/mongo-driver/bson"についての箇所](https://godoc.org/go.mongodb.org/mongo-driver/bson)を見ると、BSONの`double`は`float64`に、`128-bit decimal`は`primitive.Decimal128`にエンコードされることがわかる。

["mongo-go-driver"でのDecimal128の扱い](https://github.com/mongodb/mongo-go-driver/blob/b10214111f8116cb1caa4eb871ee3769e0d1cb8f/bson/primitive/decimal.go)を読んでみると、`BigInt()`で`big.Int`とexponential部分を返すメソッドはあるようだが、`Decimal128`をGo標準の`float64`などに変換するメソッドはないことがわかる。

## 結論 string 最強

今回は、計算したい要件がなく、ただMongoDBから取得したデータをGoを介してProtocol Buffer経由でクライアントに送りたいだけだったので、結局`string`にすることにした。他にも、別にMongoDBに入れるのに`decimal`であることにこだわりがなければ、`double`を使用することでGo上では`float64`として扱うことができるので、問題は発生しない。

もし計算したいなら、`Decimal128`を`string`にして、それをさらに`float64`などにするのが良いのか、`BigInt()`を使って頑張れるのか（["math/big"](https://golang.org/pkg/math/big/)の`Float`に頑張って変換できれば良いのだが）、`Decimal128`のまま計算する方法があるのかはわかっていない。

何れにしても、小数周りはどの言語でも辛いんだなぁと思った。
（jsだけじゃなかった。。。
これからプログラミングを始めるインフラエンジニア(俺)にとって勇気づけられるエントリー

非IT企業に勤める中年サラリーマンのIT日記
http://pineplanter.moo.jp/non-it-salaryman/2018/02/18/python-matplotlib/

Chartkickを使ってRailsプロジェクトでグラフを描画してみた
https://techblog.gmo-ap.jp/2019/06/20/rails-de-graph-with-chartkick/

「中年の危機」ど真ん中のオッサンがWEBサービス作ってみた。
https://qiita.com/hiroz31/items/d7f2f9b7d02f9be1ca92

ある文系プログラマがテックリードを任されるまでに学んだこと ── 最前線で生き延びる4つの戦略
https://employment.en-japan.com/engineerhub/entry/2017/06/28/110000

学生でもできる！Webサービスの開発・リリースするまでの道のり
https://qiita.com/minakawa-daiki/items/1d7b840c0850ec7c834c

WEB開発に役に立つAPI一覧+API毎に関連するQiita記事を分類 ！
https://qiita.com/hamaup/items/cd7212aa1d0b1f0e37de
#PowerAutomate で配列に連番を付与する

今回も文字列の半角⇔全角カナ変換を実現するためのテクニックの紹介です。
Power Automate上で配列に連番 (0,1,2...とかID1,ID2,ID3とか)を付与する方法を紹介します。

**2022/01/07:式の一部でカッコが足りなかったので修正しました**

前回：[Power Automateで文字列を1文字ずつに分割する方法](https://qiita.com/h-nagao/items/e0153b9a2c700cc2c95e)

# 準備：配列を用意
まずは変数の初期化アクションで配列を準備します。

```input.json
[
    {
        "Name": "Yamada",
        "Age": 18
    },
    {
        "Name": "Sato",
        "Age": 21
    },
    {
        "Name": "Tanaka",
        "Age": 32
    }
]
```

このような簡単な配列です。これに連番を付与することで、

```out.json
[
    {
        "rowNum": 1,
        "Name": "Yamada",
        "Age": 18
    },
    {
        "rowNum": 2,
        "Name": "Sato",
        "Age": 21
    },
    {
        "rowNum": 3,
        "Name": "Tanaka",
        "Age": 32
    }
]
```
こんな風に番号を振っていきます。 Flowのアクションには上のinput.jsonをコピペすればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/5a626fa4-1a45-d574-c00f-f2dc553b5b37.png)

# 連番付与
今回も選択(Select)のアクションを利用します。
入力になる配列は、
```range(0,length(variables('Arr')))```
で指定しています。これは前回も紹介しましたが、0から始まって、Arrという配列の長さ(行数)だけ整数列を作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/a051dd46-d8f5-8134-6c99-c6cb91022260.png)

あとはMapのところに、rowNumとして ```add(item(),1)``` を追加、その他の変更しない列については、Nameなら
```variables('Arr')?[item()]?['Name']``` のように指定しています。

## 数式の解説
ここで使った ```variables('Arr')?[item()]?['Name']```  ですが、以下のような意味合いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/0297c627-d894-c26c-7c8f-592228a1c03b.png)

これをMapに書くことで、元の配列の要素・値を出力される配列に加えることができます。

## 実行結果
Flowを実行すると以下のように目的の連番付きの配列が生成されます。
ここでは連番を簡単に1,2,3...としましたが、接頭語などを付けたい場合には

```
1,2,3.. ->  add(item(),1)
ID1,ID2,ID3 --> concat('ID',add(item(),1))

```
こんな風に、concatを使うと実現できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/fb338ddf-7022-9999-2d44-bbc1d3db7ac2.png)


#まとめ

連番の付与にも選択(Select)のアクションが有効です。
ポイントは、
- 選択アクションの入力配列として、[0,1,2,..,配列の長さ]を設定すること
- 連番にはitem()を利用する
- 配列のitem()番目を取得すると元の配列の順序を崩さずに新配列を定義できる

次回はいよいよカタカナの全角半角変換にトライします。
Raspberry PiにUbuntu MATE 18.04をインストール

Raspberry PiではRaspbianが標準的なOSですが、Raspbianは32bitのため色々と障害がありました。
64bitのOSを使用したいので、今回はRaspberry PiへのUbuntu MATEのインストールを行います。


# 使用するもの

1. MacBook Pro（macOS Mojave 10.14.6）
1. Raspberry Pi 3 Model B+
1. microSDカード
1. SDカードリーダー

インストールしたいOS：Ubuntu MATE 18.04.2 (Bionic)


# OSイメージの準備

[公式ページ](https://ubuntu-mate.org/raspberry-pi/)を参考にインストールしていきます。

## OSイメージのダウンロード
[ダウンロードページ](https://ubuntu-mate.org/download/)から対応するOSのイメージをダウンロードします。
今回はRaspberry Pi対応で64bitの最新のものを選択しました。

![ubuntu1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555646/6480d4dd-e27d-63ac-6f7a-733be94b8498.png)

![ubuntu2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555646/433dee60-8a8d-be90-24ea-c181c09baa98.png)

<img width="1195" alt="ubuntu3" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555646/f653ecb5-72c1-43b2-3537-23af785a50ce.png">

## イメージファイルの解凍
ダウンロードしたファイルを解凍します。

```Bash
$ cd /path/to/file
$ xz -dv ubuntu-mate-18.04.2-beta1-desktop-arm64+raspi3-ext4.img.xz
```


# OSのインストール

## microSDを接続する
microSDをPCに接続します。
32GB以下のものはFAT32でフォーマットしておきましょう。

## デバイス名のチェック
接続したmicroSDのデバイス名をチェックします。
今回は`/dev/disk2s1`となっています。

```Bash
$ diskutil list
#/dev/disk2 (external, physical):
#   #:                       TYPE NAME                    SIZE       IDENTIFIER
#   0:     FDisk_partition_scheme                        *31.0 GB    disk2
#   1:             Windows_FAT_32 NO NAME                 30.9 GB    disk2s1
$ df -h
#/dev/disk2s1    29Gi  3.2Mi   29Gi     1%       0                   0  100%   /Volumes/NO NAME
```

## microSDをアンマウントする
下記コマンドでアンマウントします。

```Bash
$ diskutil umount /dev/disk2s1
#Volume NO NAME on disk2s1 unmounted
```

## イメージの書き込み

下記コマンドで書き込みます。

```Bash
$ sudo dd if=ubuntu-mate-18.04.2-beta1-desktop-arm64+raspi3-ext4.img of=/dev/disk2 bs=32m
#1192+1 records in
#1192+1 records out
#5000000000 bytes transferred in 2267.894765 secs (2204688 bytes/sec)
```

私の環境では40分ほどかかりました。
終了するまで何も表示されないので不安になりますが、気長に待ちましょう。


# 起動してみる

取り出したmicroSDをRaspberry Piに挿入し、電源を入れましょう。
無事ubuntuが起動すれば成功です！
最初の設定画面が出てくるので、適宜入力しましょう。

最後に、一応パッケージの更新をしておきましょう。

```Bash
$ sudo apt update
$ sudo apt upgrade
```

今回はここまでです！
twitterの情報発信を助けるWebサービス「EMOEMO」の延期理由について。

#[EMOEMOはこちら](http://emotionalemo.herokuapp.com/)

# はじめに

初めまして！てらって呼んでください:relaxed:
簡単に自己紹介をするとごみくずプログラミング初学者です。(３ヶ月目)
現在個人開発中のWEBサービス（EMOEMO）をデプロイする予定だったのですが、想定外のバグが発生し、
デプロイはもう既にしているのですが公開できない状態です。現状のバグと今後の対策案について考えてみましたので、報告できればと思います。

# 現状のバグ＆対策案

- 全てのログインしているユーザーがツイートを送信しても僕のアカウントにツイートされてしまう。

どうやらtwitter認証周りのコードが悪さをしているような気がするので、その辺りから攻めてみようかと思っております。苦しい戦いになりそうです。

# 嘆き

画像の投稿関連の実装にもかなり時間をかけていて結構ギリギリでも実装できたのでこの勢いでと思ったのですが、
やはり、簡単にはいかないようです。引き続きどうにか頑張って、修正して使えるようにして見せるので待っていてください！

# EMOEMOの新規実装機能

- 画像投稿機能
- 一覧ソート表示機能

ソート機能は大した事はなかったのですが、画像を投稿する実装がめちゃくちゃ大変でした。4日くらいかかりました。
具体的にどのような感じの実装になったかというと↓のような感じです。投稿するのが難しく、できても編集できるようにする機能の実装が滅茶苦茶大変でした。最終的に投稿した画像を編集できるようにするためのコード200行くらいになりました。汗

![alt](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565068/5c594a2d-ae60-c649-50a9-20fb54e75299.png)


フロントは全然いじってないのですが基本的な機能を実装し終えて、デプロイし、皆さんに使ってもらっている間に手を入れようと思っています。

引き続きEMOEMOをよろしくお願いします。(まだデプロイして無いですが...)

#最後に

もし最後まで読んでくれた方がいたら、いいね！をおねがします！

#[EMOEMOはこちら](http://emotionalemo.herokuapp.com/)
batファイルからmakeファイル経由で、cファイル内のプリプロ(#define XXX)の値を操作


以下cファイルの例で言うと、外部からの設定(GSW_\**)でY_IDの値を切り替えるというのが狙いです。
実装しようと思ったキッカケは、ROMを複数作りたくないのと、パターンの多いデバッグで役立つかな。。なんて思ったからです

■cファイル

```c:hello.c
#include "stdio.h"

#if GSW_A==(0) && GSW_B==(0) && GSW_C ==(0)
#define Y_ID ("A0B0C0")
#elif GSW_A==(0) && GSW_B==(0) && GSW_C ==(1) 
#define Y_ID ("A0B0C1")                          /* ★今回の目標設定★ */
#elif GSW_A==(1) && GSW_B==(1) && GSW_C ==(1)
#define Y_ID ("A1B1C1")
#else 
 error"GSWの設定を確認して下さい"
#endif

int main(void) {
 printf("Y_ID:%s",Y_ID);
 while(1);
 return 0;
}
```
■batファイル

```
@echo off
@rem ++++++++++++++++Windows bat (jenkinsでも試したい) ++++++++++++++++
@rem ▼ここでGSW_*の値を設定▼
set a=0
set b=0
set c=1
@rem ▲ここでGSW_*の値を設定▲

@rem ひとまずインクルード用のファイルを生成します。-Dオプションが肝です。
echo ADDOP =-DGSW_A=%a% -DGSW_B=%b% -DGSW_C=%c% > IncludeForGSW.mk

del hello.o
del hello.exe

@rem make実行の際にインクルードファイルを読み込むので設定した値が反映される
make 
.\hello.exe
pause
```
■makeファイル ＜IncludeForGSW.mk＞(batファイルにより自動生成されたもの)

```
ADDOP =-DGSW_A=0 -DGSW_B=0 -DGSW_C=1 
```

■makeファイル ＜GNUmakefile＞

```
include IncludeForGSW.mk
hello: hello.o 
	gcc -Wall  -o hello hello.o 
hello.o: hello.c 
	gcc -Wall ${ADDOP}  -c hello.c
```



■実行結果

```
Y_ID:A0B0C1
```

もっと良い方法があれば知りたいです！よろしくお願いします！
目標設定初めの一歩

初めましてハンドルネームが思いつかないので

唐揚げが好きなので
唐揚げ系エンジニアと名乗らせていただきます。
元々ゲームやYoutubeが好きでどういう仕組みになっているのか
興味があり勢いでITにエンジニアにチャレンジできる企業に転職しました。
早速ではありますがタイトルにあります通り目標設定をさせていただきます。

「SES企業を卒業して受託開発の会社に転職」
「2年以内に自社開発企業に転職する」
です。
その為何をすべきか自分なりに調べてみました。
①Progateの基礎学習
→HTML・CSS(2週間)
→PHPorRuby(1か月)+JavaScript(できれば)
②ⒶUdemyやセミナーなどで実践的な物の作成に触れる(2か月)
PHPとMySQLのプログラミングの動画にチャレンジします。
https://www.udemy.com/course/php7basic/learn/lecture/9835200
ⒷRubyを選んだ場合はRailsチュートリアルを行う(3か月)

③データベース(MariaDB)+GitHuBなどソースコード共有する技術をつける（1か月）

④ポートフォリオ作成(1か月)
・具体的には・・・会員登録をしてログアウトする＋投稿ができるもの+BootStrapでコーディングは楽する。
(Twitter・Instagramなどの高クオリティーはおそらく時間がかかりすぎる)

⑤Wantedlyやレバテックなどを利用してベンチャーや中小企業にエントリーする
同時並行で企業HPのフォームからエントリーする。


色々動画や当サイトで情報収集したので受け売りかもしれませんが実践します。


私の現状はSES企業にて
客先常駐エンジニアとして働かせていただいております。
現在1年半ほどパソコンのキッティングやアラームの運用監視などを経験

現場の撤退を勧告され、インフラ構築ときいていた筈の現場で面談のはずが
ヘルプの仕事をアサインされる。
今までを振り返った結果
スキルがつかない単純作業労働の繰り返しで落ち込んでました。
そして一番重要なことですが、現場や会社のせいにして自己研鑽をせずに結果として
「スキルセットがなにもない」状態から逃げていました。

それを抜きにしても現職では「未経験可、金融システムの構築や５Gに携われる」
という甘い謳い文句に騙されたと思います。


現状は変えられないと絶望していました。
同じように夢見てエンジニアになったつもりなのに単純労働から抜け出したい方の参考になればと思います。
Windowsのパスワードを変更した時にgitの認証が通らなくなった

Windowsのパスワードを変更して、gitの認証が通らなくなって困りました。

```bash
$ git pull
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/ko-flavor/atcoder-java.git/'
```

コントロールパネル > ユーザー アカウント > 資格情報マネージャー
編集したい資格情報の右側の↓をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561891/ea424ec1-8b86-42ce-df75-07d6e7c1d87a.png)

編集から、パスワードを入力して、保存。

これで解決しました！
【備忘録】python+vscode+pipenvありがちだけどwarningとかめんどかったので備忘録

初投稿です。
今まではnotepad++を使ってコードを書いていたのですが色々便利ということでVScodeを使おうと思い立ちました。
pythonの勉強用なのですが、せっかくならpipenvとか使って管理しやすいようにしたいなーと思って環境を作ってました。
しかしwarningが消えなかったり色々苦戦したので、備忘録的にここに残しておこうと思います。

今回構築する環境は以下になります。
-OS：windows10
-Python:3.8
-使用ライブラリ:pipenv、Django

#1.VScodeのインストール
以下ページから自分の環境にあったものをインストールしてください。
https://code.visualstudio.com/download

#2.pythonのインストール
以下ページから環境に沿った欲しいバージョンのものをダウンロードしてインストールしてください。
https://www.python.org/downloads/windows/
また、windowsの場合途中に環境変数を追加するチェックボックスがあるはずなので、忘れずにチェックをいれてください。
（"Add pythonX.X to PATH"みたいな文言のチェックボックスがあります。）
インストールしたら一応以下コマンドでインストールが完了していることを確認しましょう。

```コマンドライン
python --version
```
バージョン情報が表示されたら正常にインストールされたということです。
（PATHが通ってなかったらここでコマンドを認識できないと思います。）

#3.Pipenvをインストールする。
2からそのままインストールしちゃいましょう。
以下のコマンドを実行してください。

```
pip install pipenv
```
pipenvのインストールが完了したら環境変数の追加を行います。
以下の環境変数を追加し、値を"true"に設定してください。

```
PIPENV_VENV_IN_PROJECT
```
これを実施することでpipenvで仮想環境を作った際にワークディレクトリに".venv"フォルダ作られるようになります。
この環境変数を追加しなかった場合、ユーザフォルダ配下に作成されてしまいます。
それでも問題ないのですが、後々VScode上で環境及びフォルダを管理するときに地味に面倒くさいので設定しておくことをお勧めします。

#4.VScodeを設定していく。
1.サイドバーのExtentionsから以下を検索してインストールしてください。
（Pythonの便利ツールパッケージ。Lint機能とか、自動インデントとかやってくれる。）

```
python extension for visual studio code
```
2."ファイル"→"基本設定"で設定を開き、"拡張機能"→"python"の中の"Python: Venv Path"に以下を設定する。

```
.venv,
```
これを設定するとワークスペースを開いた際に直下にある.venvフォルダを読み込んでくれるようです。
3.一旦VScodeを再起動。ここまでの設定を読み込ませます。
4.ここから本格的に環境を作っていきます。
　"ファイル"→"フォルダーを開く"から自分が作業するフォルダを開きます。
5."ターミナル"→"新しいターミナル"と選択しターミナルを開きます。
6.pipenvで仮想環境を作っていきます。ターミナルで以下コマンドを実行してください。

```
pipenv install
```
この時右下に「仮想環境作られたみたいやけど、使うん？」みたいなことを英語で聞かれるので"YES"を選びましょう。
すると以下のようなフォルダ構成になると思います。

```
.
├─.venv　←pipenvで作られる
├─.vscode　←Yesをクリックしたら作られる
├─Pipfile　←pipenvで作られる
└─Pipfile.lock　←pipenvで作られる
```
.vscodeが作られなかった（もしくはNoをクリックしてしまった場合）ワークスペース直下に適当な名前の.pyのファイルを作りましょう。そしたら作られるはずです。
7.ワークスペース直下に".env"という名前のフォルダを作って以下を記述します。

```
PYTHONPATH=.venv/src
```
8."./.vscode/setting.json"に以下を追加します。
```
"python.envFile": "${workspaceFolder}\\.env"
```
バックスラッシュはエスケープキーとして認識されるので二重にするのを忘れないでください。
7、8の手順を踏むことによって仮想環境でライブラリを読み込めずワーニングが出るということがなくなります。

あとは

```
pipienv install xxx
```
でお好みのライブラリをインストールして

```
pipenv shell
```
を実行すればお好みの仮想環境で開発することができます！
以上です！お疲れさまでした！

#最後に
今まではとりあえずコードが打てれば良いの精神であまり気にしてなかったのですが、現場によってはvscodeが標準だったりgitとの連携が便利だったりということで使い始めた次第です。
この記事を書いてる先から今日も頭の中の消しゴムは頑張って仕事をしていて
消えゆく記憶と格闘しながら作成した次第です。

お前こんなんも知らんのかい？
ここ違うで

等ありましたら是非ご指摘いただけると嬉しいです。
先達の皆様よろしくお願いします。
Codeforces CodeCraft.20 B. String Modification : 文字列操作(逆順)

https://codeforces.com/contest/1316/problem/B

for文で書くのが簡単な関数を、規則性を見つけてO(N)に書き直して全列挙。
アプローチは悪くなかったと思うので、どのように実施したかを記録する。

# 概要
- lの長さの文字列sが与えられる。
- あなたはあるkを考える
- 1文字目からk文字目までを反転させる
- つぎにその文字列の2文字目からk+1文字目までを反転させる...これをlまで繰り返す。
- こうしてkを定めたうち、最も辞書順で小さくなる文字列とkと答えよ

# 例
分かりにくいのでシミュレートのコードを書き、結果を見てから考える。

```Python
def do(s, k):
    l = len(s)
    t = s
    for i in range(l - k + 1):
        t = t[:i] + t[-l + k - 1 + i: -l - 1 + i: -1] + t[i + k:]
        print(t)
    return t

# k = 3のとき
print("abcdefg")
do("abcdefg", 3)

```

これにより、以下のように結果が得られる

```
abcdefg
^^^
cbadefg
 ^^^
cdabefg
  ^^^
cdebafg
   ^^^
cdefabg
    ^^^
cdefgba
```

尚、k = 7とすれば１回だけ文字列を反転できるので、`gfedcba`になる。

# もう少し試したこと
シミュレーションコードを書いたのでkを回した。

```Python
def do(s, k):
    l = len(s)
    t = s
    for i in range(l - k + 1):
        t = t[:i] + t[-l + k - 1 + i: -l - 1 + i: -1] + t[i + k:]
        #print(t)
    return t

s = "abcdefg"
for i in range(1, len(s) + 1):
    print(i, ": ", do(s, i))
print("---")
s = "abcdefgh"
for i in range(1, len(s) + 1):
    print(i, ": ", do(s, i))
```

```
1 :  abcdefg
2 :  bcdefga
3 :  cdefgba
4 :  defgabc
5 :  efgdcba
6 :  fgabcde
7 :  gfedcba
---
1 :  abcdefgh
2 :  bcdefgha
3 :  cdefghab
4 :  defghcba
5 :  efghabcd
6 :  fghedcba
7 :  ghabcdef
8 :  hgfedcba
```

これを見ると、大まかにkにたいして`(k-1文字目までの文字列) + (それより先の文字列)`になっている。
さらによく見ると、奇数と偶数で後半の`(それより先の文字列)`はkが奇数と偶数の時で時折、反転していることが分かる。
例えば、後半の部分を見ると`5 :  efghabcd`は$abcd$が順列だが、`6 :  fghedcba`は$edcba$が逆順になっている。
しかも、前半の7文字では、`5 :  efgdcba`時、`dcba`は逆順である。
これらを試すと、以下のことが分かる。

```
文字列sが偶数文字数の場合 で k=奇数の時: (k-1文字目までの文字列) + (それより先の文字列)
文字列sが偶数文字数の場合 で k=偶数の時: (k-1文字目までの文字列) + (それより先の文字列 の 逆順)
文字列sが奇数文字数の場合 で k=偶数の時: (k-1文字目までの文字列) + (それより先の文字列)
文字列sが奇数文字数の場合 で k=奇数の時: (k-1文字目までの文字列) + (それより先の文字列 の 逆順)
```

と分かる。
つまり、上記で書いた、doの関数は、

```Python
def do2(s, k):
    l = len(s)
    t = s
    k = k - 1
    if l % 2 == 0:
        if k % 2 == 0:
            return t[k:] + t[:k]
        else:
            return t[k:] + t[-l + k - 1: -l - 1: -1]
    else:
        if k % 2 == 1:
            return t[k:] + t[:k]
        else:
            return t[k:] + t[-l + k - 1: -l - 1: -1]
```
と示せ、これはO(N)で動作する。

# 考えたこと
do2の関数は極めて軽いので、Nが5000以内という制約であれば、すべてを列挙して、最も辞書順で小さい文字列を表示すればよい。

# コード
```Python
def do(s, k):
    l = len(s)
    t = s
    k = k - 1
    if l % 2 == 0:
        if k % 2 == 0:
            return t[k:] + t[:k]
        else:
            return t[k:] + t[-l + k - 1: -l - 1: -1]
    else:
        if k % 2 == 1:
            return t[k:] + t[:k]
        else:
            return t[k:] + t[-l + k - 1: -l - 1: -1]
t = int(input())
for _ in range(t):
    n = int(input())
    s = input()
    l = list(s)
    res = []
    #print(s)
    for i in range(1, n+1):
        res.append( (do(s, i), i) )
    res.sort()
    print(res[0][0])
    print(res[0][1])
```
https://codeforces.com/contest/1316/submission/72443500
Android x86 9.0-r1 をHP Pavilion 11-k128TU x360にインストールしてみた

最初、Chromium OSをインストールしようとしたんだけど、CloudReadyはUSBメモリから起動はするけどインストールできないし、ChromiumOSのイメージをUSBメモリに入れても起動しないし、もう、ChromiumOSあきらめた！
ということで、Android x86を入れてみた。
ちなみに、HP Pavilion 11-k128TU x360はノートPCの状態から、キーボードを360度回転させることでタブレットとしても使える2015年発売のPCです。

入れ方とかはググれば出てくるので、インストールしてみてどうなのかを書き残しておく。

書いててスクショ取ろうとしたら、許可されてなくてスクショが撮れなかったのでスマホのカメラで撮影することになるとは・・・
![P_20200305_232142.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/f4631445-6e15-ff2b-bf06-103ee34224a7.jpeg)

#タブレットのようにつかえるのか？
このPC、冒頭にも触れましたが、タブレットとしても使えるPCです。
ある程度、キーボードを回転させると、キーボードが無効になって、タブレットモードになります。
買った時のようにWindows10が入っていれば。
Android x86を入れると、タブレットモードにしても、キーボードが有効なままになります。
おそらく、出荷時のWindows10では専用ドライバが入っていて対応していたのではないかと思います。
そんな状況なので、タブレットのように使うのはあまり向いていません。
常に物理キーボードが接続されている状態になるので、折りたたんでも、仮想キーボードが出ないので、設定で物理キーボードが接続されていても仮想キーボードが出るようにしないといけません。
キーボードを回転させて、自立させることもでき、その場合に入力が困るので、使い方次第ではこの設定は必須となります。
![P_20200305_232221.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/d4d87efb-bb98-0d78-7ab7-fe194d235597.jpeg)

#アプリは動くのか？
ゲームはMinecraftは動きます。
他にいくつか入れてみましたが、ほぼ起動せずに落ちます。

ランチャーはNova Launcharは問題なく動きます。
Win X Launcher、Win 10 Launcherをれてみましたが、なんか動作が怪しいところがありました。
この辺入れるとPCっぽくなって面白いんですけどね^^;

お絵かき関係でメディパンペイント、アイビスペイントXを入れてみました。
メディパンペイントは起動時に落ちましたが、アイビスペイントXは起動しました。お絵かきもできました。

音楽関係はMusic StudioとKORG Kaossilatorを入れてみました。
Music Studioは起動時に落ちました。
KORG Kaossilatorはちゃんと動きました。

その他Amazon Prime Video、Amazon Kindleなどを入れましたが、動くもの動かないものがありました。

という感じで、動かないアプリが割とあります。

とりあえず、Youtube、Twitterは動くので、仕事しながら動画見たりTwitter見ることはできます。
あ、Twitterはアプリより、PWA版を使ったほうが使いやすいです。

他のPCにAndroid x86を入れた場合にどうなるかわかりませんが・・・

#PWAを試してみた

なぜかインストールしてもアイコンが出なかったりしました。
twitterは出るようになったけど、自作PWAのLT Timerはなぜかアイコンが表示される。
ちゃんとしたAndroid端末やiPadでは動くので、PWAの開発や動作確認ではあまり使わないほうが良いのかも。

#開発環境として使えるのか
AIDEがインストール可能で動きます。
課金すればUIもデザイナで編集可能です。
![P_20200305_230413.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/44a03c0e-0297-24fa-e969-e1db0626e857.jpeg)

ただ、Android Studioとは違った操作性なので慣れがかなり必要そう。
とりあえず、開発は可能・・・と思ったんですがなにか謎のエラーが出て、動かない・・・
![P_20200305_230330.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277984/4275fac8-f6a2-bd25-c2d7-dcaa3057fbdc.jpeg)
エラーも文字化けしててなんだかわからない・・・
これ、AIDEの設定ファイルか何かなのかな？

ちなみに、AIDEはJavaコンソールアプリやC/C++のコンソールアプリ、PhoneGapなどの開発も可能です。
Javaコンソールは実行までできたので、Javaの勉強は出来そうです。
PhoneGapやHTML,CSS,JavaScriptは追加でインストールが必要となります。

#終わりに
Android x86はYoutubeを見たり、twitterを見たりする用途には使用できます。
ゲームはPCによる可能性がありますが、期待はしないほうがいいです。
開発は、エラーが何とかなればAndroidアプリの開発ができるんじゃないかと思います。
ただ、CPUがarmではないので、NDK周りがどうなのか気になります。
また、動作確認で利用することにも向いていないと思います。

Android x86でAIDEでなんとかAndroidアプリをビルドしてみたい！
Raspberry PiでGoogle Assistantを試した時のInvalid sample rate エラーの対処法

Raspberry Piでgoogle assistantを入れてgoogle homeみたいに使うという記事はたくさんあるので、手順はそちらで確認してください。
今回は、その時に自分が以下のエラーで時間を取られたのでそのメモです。
#動作環境
Raspberry Pi 3B
OS: Rasbian
HDMI接続でスピーカ出力
USBマイク使用

#エラー
以下のコードを実行します

```
googlesamples-assistant-pushtotalk --project-id <your project id> --device-model-id <your model id>
```
####エラーメッセージ

```
sounddevice.PortAudioError: Error opening RawStream: Invalid sample rate [PaErrorCode -9997]
```

Invalid sample rateね、なるほど。
とにかく音声のサンプルrateが変なのでそこを直します。

#対処法
.asoundrc
というファイルの中身に一行
rate 16000
を足します！それだけ！
参考URL: https://github.com/googlesamples/assistant-sdk-python/issues/155
場所はpcm.speaker{}の中です。

```shell:.asoundrc
pcm.!default {
  type asym
  capture.pcm "mic"
  playback.pcm "speaker"
}
pcm.mic {
  type plug
  slave {
    pcm "hw:1,0"
  }
}
pcm.speaker {
  type plug
  slave {
    pcm "hw:0,0"
    rate 16000 #これが必要!!!!!!!!!
  }
}
```

これで自分は動きました。
Gravioでボタンを押したときにslackにメッセージが投稿され、Mi Smart Band4が振動するようにした

#経緯
とあるホステルで宿直をしております。
離れたところで作業をしているときに、フロントへお客さんがいらっしゃることがありまして。
ボタンが押されたら、Mi Smart Band 4が振動してくれれば良いなと思い、設定しました。
アステリアさんのGravioの力をお借りして、簡単にIoTの設定をしてみました。

#ゴール
https://www.youtube.com/watch?v=Vgktf_bZPIU
[![デモ動画](http://img.youtube.com/vi/Vgktf_bZPIU/0.jpg)](https://www.youtube.com/watch?v=Vgktf_bZPIU)

#使ったもの
  - Mac
  - Gravioのシングルボタン
  - [Gravio Hubkit, Gravio Studio](https://www.gravio.com/jp/product#Gravio-Server)
  - [Xiaomi Mi Smart Band4](https://www.amazon.co.jp/dp/B0834QJ9WC/ref=cm_sw_em_r_mt_dp_U_y1iyEb4EDQVF6)
 
#設定する中で工夫が必要だったこと
下記の内容を拝見し、設定することが出来ました。
[最初に必要なセンサーのセットアップ](https://www.gravio.com/jp/sensor-setup-guide)
[ドキュメント](https://doc.gravio.com/manuals/gravio-setup-guide/1/ja/topic/introduction)

この記事では、その中で工夫が必要だったことだけ書こうと思います。
特に難しい点はありませんでしたが、ちょっと試行が要りました。

|流れ|工夫した？|
|:---|:---:|
|Gravio Hubkitとセンサーの連携||
|Gravio Studioでトリガーの設定||
|slackのトークン取得|△|
|Gravio Studioでslackにメッセージを送るよう設定|△|
|Mi Smart Band4で、slackの通知を受け取る設定|△|

#slackのトークン取得
botがメッセージを送るのに必要なtokenをGravio Studioに入力しないと、slackのメッセージを送信することが出来ません。[token](https://qiita.com/TakahikoKawasaki/items/e37caf50776e00e733be)は超ざっくり表現すると、許可証みたいなものです。

まず、下記にアクセスして、Create New Appボタンを選択します。
https://api.slack.com/apps

その後は、
1 Botsを選択
2 App Home画面が開かれるので、サイドバーのFeatures > OAuth & Permissionsページを開く
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/f9680ba2-9957-aa76-0c55-8767786ccd14.png" width=80% />
3 少しスクロールすると、Scopes欄が出てくる
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/bba06f90-887f-39ba-338d-ad536ee35866.png" width=80% />
4 そこで「Bot Token Scopes」にあるAdd an OAuth Scopeボタンを押し、chat:writeを選択すると、botがメッセージを投稿できるtokenが得られる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/fd22cc63-13e5-9f99-db52-dc69dad796fa.png" width=80% />

#Gravio Studioでslackにメッセージを送るよう設定
GravioStudioのSlackPostMessageコンポーネントを使って、slackにメッセージを送る設定が出来ます。
ただし、入力の際にいくつか注意する点がありました。
![スクリーンショット 2020-03-05 22.29.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/d11b6431-ccfc-7d09-3444-94bc556f9e6b.png)
###注意点
- tokenは""で囲む
- メンバーにメンションをつけたい場合は、上記のように<アットuserId>を入力する。
- ※userIdの調べ方は[こちら](http://help.receptionist.jp/?p=1100#memberid)

#Mi Smart Band4で、slackの通知を受け取る設定
Mi Fitアプリをインストールして、「プロフィールのMiスマートバンド4>アプリ通知>その他」をONにする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/547dc4ef-ccfa-0133-7523-48f2b080e508.png" width=30% display="flex"/>　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/981d4101-7df5-8630-7ccf-4d0b13e8acb6.png" width=30% display="flex"/>　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182279/713cc6ba-3405-8ee6-257a-4f2bcdfea47d.png" width=30% />



#感想
試してみたところ、フロントから8,9m先でも振動しました。
2階の部屋で作業していても、反応できそうです。
Mi Smart Band4, 安い割にいい商品でした。