OmniAICreator/Qiita-1.07M huggingface dataset:
react 시작했다.


2019년인가 react 공부를 하고 
그동안 손을 놓고 있었다. 좀 어렵기도 하고 차라리 viewjs 를 공부를 하는것이 낳을것인가? 고민도 되고 했지만
올해 1월부터 react 프로젝트를 시작하게 되었다.
아직 나에게는 좀 어렵지만 이 기회에 공부를 해놓아야 겠다싶어서 내가 공부한것 앞으로 공부한것을 글로 남기고자 한다.

순전히 개인의 공부를 위한것이며 코드들은 copy and paste 가 아닌 직접 코딩하는것이므로 오타가 있을수 있다.

##react 

```react:Hello.js
import React from 'react';
function Hello({color,name,isSpecial}){
  return (
    <div style={{color}}>
      {isSpecial && <b>*</b> }
      hello{name}
    </div>
  )
}

export default Hello
```

```react:App.js
import React from 'react'
import Hello from 'Hello';

function App(){
  return(
    <Hello name="react" color="red" isSpecial />
  )
}

export default App;
```
#간단한 카운터 만들어보기 

```react:Counter.js
import React,{useState} from 'react'

function Counter(){
  const [state, setState] = useState(0);
  const Increase = () => {
    setState(state + 1)
  }
  const Decrease = () => {
    setState(state - 1)
  }
  return(
    <div>
      <h1>{state}</h1>
      <button onClick={Decrease}>-1</button>
      <button onClick={Increase}>+1</button>
    </div>
  )
}

export default Counter;
```

```react:App.js

import React from 'react;
import Counter from 'Counter'

function App(){
  return(
    <Counter />
  )
}

export default App;
```
Vueでタブメニューを作成する

#概要
SPAにおいてタブメニューは割と使い場面が多いので、実装方法を忘れないようにメモします。
こういうやつ↓
![ダウンロード.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/3847f35e-2176-f17b-0684-776c077c7a5a.gif)


#実装
```.vue
<div class="tab">
    <div class="tab_box container">
        <ul class="tab_list">
             <li @click="changeTab('1')" v-bind:class="{'active': isActive === '1'}">New</li>
             <li @click="changeTab('2')" v-bind:class="{'active': isActive === '2'}">Trend</li>
             <li @click="changeTab('3')" v-bind:class="{'active': isActive === '3'}">Items</li>
        </ul>
    </div>
</div>
<div class="container">
    <div class="article">
        <!--タブで入れ替えたいコンポーネントの配置-->
        <new-timeline v-show="isActive === '1'" class="item"></new-timeline>
        <trend-timeline v-show="isActive === '2'" class="item"></trend-timeline>
        <trend-item v-show="isActive === '3'"  class="item"></trend-item>
    </div>
</div>
<script>
import NewTimeline from './NewTimeline.vue'
import TrendItem from './TrendItem.vue'
import TrendTimeline from './TrendTimeline.vue'
export default {
    components: { NewTimeline, TrendTimeline, TrendItem },
    data() {
        return {
            isActive: '1',
        };
    },
    methods: {
        changeTab(val) {
            this.isActive = val;
        },
    },
}
</script>
<style scoped>
    .tab{
        width: 100%;
    }
    .tab_list {
        overflow: hidden;
        list-style: none;
    }
    .tab_list li {
        float: left;
        padding: 10px 20px;
        cursor: pointer;
        transition: .3s;
    }
    .tab_list li:not(:first-child) {
        border-left: none;
    }
    .tab_list li.active {
        border-bottom: 3px solid #000;
        cursor: auto;
    }
    .article{
        overflow: hidden;
        margin-top: -1px;
    }
</style>
```

#ポイント

1.タブをクリックしたらchangeTabメソッドが発火する(このメソッドでは変数isActiveが変わるだけ)
2.isActiveの中身によってコンポーネントを`v-show`で入れ替える
3.`v-bind:class`では動的にクラスを切り替えることができるので、isActiveの内容によって↓を発火させる
>
    .tab_list li.active {
        border-bottom: 3px solid #000;
        cursor: auto;
    }


#参考文献
[Vue.jsでタブメニューをつくる](https://qiita.com/mimoe/items/86d5312b3741320b717b)
jQueryのセレクタで同じIDのDOM要素を全取りする

同じページに同じIDの複数のDOM要素がありそれらを全て取得したいとき、jQueryで`#ID名`で指定する方法では最初の１つしか取得できません。例えば以下の例では最初のSample1だけ取得できます。

```page.html
<span id="sample">Sample1</span>
<span id="sample">Sample2</span>
<span id="sample">Sample3</span>
```

```jscode.js
var elems = $("#sample");
for(var elem of elems) {
  console.log($(elem).text());
}
```

結果

```
Sample1
```

そんなときは、`[id=ID名]`のセレクタを使うと全部取れるようです。

```jscode.js
var elems = $("[id=sample]");
for(var elem of elems) {
  console.log($(elem).text());
}
```

結果

```
Sample1
Sample2
Sample3
```

IDが2種類以上の場合は少し異なり `#ID1, #ID2,...` のセレクタで重複するものも全て取得できるようです。

```page.html
<span id="sample_a">Sample1</span>
<span id="sample_a">Sample2</span>
<span id="sample_b">Sample3</span>
<span id="sample_b">Sample4</span>
```

```jscode.js
var elems = $("#sample_a, #sample_b");
for(var elem of elems) {
  console.log($(elem).text());
}
```

結果

```
Sample1
Sample2
Sample3
Sample4
```

これを応用すると、IDが1種類の場合もページ中には存在しないダミーのID名と組み合わせると取得できるようです。

```page.html
<span id="sample">Sample1</span>
<span id="sample">Sample2</span>
<span id="sample">Sample3</span>
```

```jscode.js
var elems = $("#sample,#dummy");
for(var elem of elems) {
  console.log($(elem).text());
}
```

結果

```
Sample1
Sample2
Sample3
```

# おわりに
そもそも同じIDのDOM要素を作らないように設計するべきで、こういう場合はクラス名を使うのが正しいやり方かとは思いますが、役立つシーンもあるかと思います。たまたまこう動いているだけという可能性もありますので注意しながらご利用ください。

`[id=ID名]`のセレクタについてはこちらを参考にさせていただきました。

- [jQuery #idでは一つし要素か選択できない、同じIDを持つ複数要素を選択するには](https://kinopyo.com/ja/blog/jquery-select-multy-element-with-same-id)
Vue.js テキスト入力表示を枠で囲みたい

# 目的

v-modelで入力された文字を表示させることができるが、さらにその表示された文字を枠で囲みたかった。

# 方法

テキスト入力されたかどうかを`v-on:keyup`によりメソッドを呼ぶことにした。しかしこれでは`v-model`を使う意味があるのか疑問に思った。

```index.html
  <div id="app">
    <input
      v-model="userText"
      v-on:keyup="showFrame"
      id="input"
      type="text"
    >
    <p v-if="isDisplay" class="userFrame">{{ userText }}</p>
  </div>
```

```main.js
var app = new Vue({
  el: '#app',
  data: {
    userText: '',
    isDisplay: false
  },
  methods: {
    showFrame: function() {
      if (document.getElementById('input').value) {
        this.isDisplay = true;
      } else {
        this.isDisplay = false;
      }
    }
  }
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/611bae0b-e6a2-dffb-a13c-05ad9a1ffa43.png)



# その他学んだこと

枠線の書き方について学んだ。

- `display: inline-block;`で枠線を文字幅に合わせることが可能
  - `border*`には枠の長さを自動調整するオプションはない

```style.css
body {
  margin: 100px;
  background-color: rgb(17, 2, 40);
  font-size: 40px;
  color: rgb(255, 255, 255);
}
input {
  font-size: 40px
}
.userFrame {
  border-style: solid;
  border-color: rgb(200, 200, 50);
  display: inline-block;
}
```

# 参考文献

サルワカ
【CSS】borderの長さを調整する方法3つ：文字に応じて可変など
https://saruwakakun.com/html-css/reference/border-length
Flutterの実行環境作成（Windows10、AndroidStudio）

WindowsのAndroidStudioでFlutterのデモページを表示するまでの手順を備忘を兼ねてまとめます。
覚書なので抜け漏れあったらすみません。
パッケージ管理ソフトのScoopを用いた手順なので、Scoopを使いたくない人向けではないです。

# Scoopのインストール

PowerShellで以下を実行する。

```shell:PowerShell
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
# or shorter
iwr -useb get.scoop.sh | iex
```
【公式サイト】https://scoop.sh/

【補足】Scoopでインストールしたパッケージはデフォルトだと以下に配置される。
`C:\Users\{UserName}\scoop\app`

# Scoopバケット追加

FlutterやAndroidStudio関連のパッケージをインストールするためbucketを追加する。

```shell:PowerShell
scoop bucket add extras
scoop bucket add java
```

# パッケージのインストール

必要となるパッケージをインストールする。

```shell:PowerShell
scoop install dart
scoop install flutter
scoop install android-sdk
scoop install android-studio
scoop install adb
scoop install adopt8-hotspot
```

# Flutter Applicationの作成

上記でインストールしたAndroidStudioを起動し、「Create New Flutter Project」→「Flutter Application」と選択し、デフォルトプロジェクトを作成する。

その際、「Flutter SDK path」は以下を指定する。
`C:\Users\{UserName}\scoop\apps\flutter\current`

# Android Studioの設定

「Tools」→「SDK Manager」を選択し、Android SDK Locationに以下を設定する。
`C:\Users\{UserName}\scoop\apps\android-sdk\current`

「Tools」→「ADV Manager」を選択し、Create Virtual Device... から実行したい仮想デバイスをインストールする。

# Flutterのデモページ表示

上記でインストールした仮想デバイスを設定し、実行ボタン押下でデモページが仮想デバイス（エミュレータ）にて表示されると完了です。

#### “Running Gradle task 'assembleDebug'… ”とでて進まない場合

コントロール パネル\システムとセキュリティ\Windows Defender ファイアウォールを開き、「Windows Defender ファイアウォールを介したアプリアプリまたは機能を許可」からAndroidStudioを追加する。

追加するパスは以下
`C:\Users\{UserName}\scoop\apps\android-studio\current\bin\studio.exe`
または
`C:\Users\{UserName}\scoop\apps\android-studio\current\bin\studio64.exe`
MySQLのバージョンごとの違いについて調査した

# MySQLのバージョンによる機能の違いについて

### MySQLについて、簡単に
- MySQLは世界で最も普及しているオープンソースのRDSMS. リポジトリは[こちら](https://github.com/mysql/mysql-server).
- MySQLはSQLパーサとストレージエンジンが分離していて、用途に応じたストレージエンジンを採用することができる。


### MySQLのバージョンについて

ex)MySQL5.1.30という表記をした場合

- 最初の数字(ex. 5)がメジャーバージョンおよびファイル形式を表す。特定のメジャーバージョンでファイル形式は変わらない。

- 2番目の数字(ex. 1)がリリースレベルで、バージョンアップにはメジャーな機能の追加や旧バージョンとのマイナーな非互換性が含まれる。

- 3番目の数字(ex. 30)は、新しいリリース毎に数が増える。バージョンアップにはリリースレベルでの安定性の改善が含まれる。

- リリース名には、リリースの安定性を占めるサフィックスが含まれることがある。サフィックスがない場合、GAリリースとなる。

参考: [MySQL公式リファレンス](https://dev.mysql.com/doc/refman/5.6/ja/which-version.html)

#### 歴史
- 2001 MySQL3.23が最初のプロダクションリリース.
- 2003 MySQL4.0がリリースされる.
- 2005 MySQL5.0がリリースされる.
- 2008 MySQL5.1がリリースされる(5.1.30よりGA).
- 2010 MySQL5.5がリリースされる(5.5.8よりGA).デフォルトのストレージエンジンがMyISAMからInnoDBになる.
- 2013 MySQL5.6がリリースされる(5.6.10よりGA).InnoDB、NoSQLの機能強化.
- 2015 MySQL5.7がリリースされる(5.7.9よりGA).レプリケーション機能の拡充やInnoDBの改善、パフォーマンス改善など.
- 2018 MySQL8.0がリリースされる(8.0.11よりGA).

#### サポート
- オープンソース版のMySQL Community Editionでは4以前のバージョンはサポートが終了している.
- AWSのRDSでは2020年にMySQL5.6のサポートが終了している.

参考: [MySQL | Wikipedia](https://ja.wikipedia.org/wiki/MySQL)

#### MyISAMとInnoDBについて

- MyISAMはシンプルな設計ゆえに高速であるが単純なデータ構造やリレーション、クエリを想定している.
- MyISAMは外部キー制約をサポートしていないが、innoDBはサポートしている.
- MyISAMはテーブルレベルの排他ロックしか実行できないのに対して、InnoDBは行レベルで共有ロックと排他ロックが組み合わされる.
- MyISAMではACIDなトランザクションが実装されていないのに対して、InnoDBでは実装されている.
- MyISAMでは、テーブルのキャッシュ管理をOSに任せているのに対して、InnoDBでは管理者が動的変数innodb_buffer_pool_sizeで設定することができる.

#### MySQL5.5 -> MySQL5.6

- [GTID](https://dev.mysql.com/doc/refman/5.7/en/replication-gtids-concepts.html)(Global Transaction ID)によって、マスタ-レプリケーション構成の時にトポロジー全体でユニークなIDがトランザクションに与えられる.
- パラメータのデフォルト値が変わり、デフォルト設定で優れたパフォーマンスが出るようになった. back_log(未解決の接続要求の上限)の値が、max_connectionsの値に比例して自動で調整される、など.
- カーネルmutexを分割することによる競合の軽減、フラッシュ操作の効率改善などのInnoDBのパフォーマンス改善.
- InnoDBのページサイズを、インスタンス作成時にパラメータとして設定できるようになった。ワークロードの性質に応じたページサイズにチューニングできる.

など

#### MySQL5.6 -> MySQL5.7

- パフォーマンスがMySQL5.6の3倍になったとされる.

- マルチソースレプリケーション(マスタ-スレーブ構成で複数マスタの選択が可能)機能が追加される.

- InnoDBのバッファプールサイズをオンラインで変えられるようになったり、オンラインでインデックス名を変えられるようになったり、InnoDBが改善された.

- クエリの最適化に使える機能が追加された.
- パスワードの有効期限が設定できるようになったり、DB管理者がユーザアカウントをロックできるようになったり、セキュリティが向上した.

など

#### MySQL5.7 -> MySQL8.0

- パフォーマンスがMySQL5.7より2倍高速になったとされる.
- デフォルトのキャラクタセットがutf8mb4になった.
- SQLを関数のように定義してネーミングすることで、複雑なSQLをシンプルなSQLを組み合わせて構築することができるCTE(Common Table Expression)という機能が追加された.
- コマンドラインからmysqldの再起動をまたいで永続的に反映されるパラメータ設定ができるSET PERSIST構文が追加された.
- mysqldの起動や停止をクライアント接続で行えるようになった.
- Window関数が実装された.
- JSON関連の機能が拡充された

など

参考:

[MySQL 5.6 リファレンスマニュアル2.11.1.3 MySQL 5.5 から 5.6 へのアップグレード](https://dev.mysql.com/doc/refman/5.6/ja/upgrading-from-previous-series.html)

[MySQL 5.7 Reference Manual 2.11.3 Changes in MySQL 5.7](https://dev.mysql.com/doc/refman/5.7/en/upgrading-from-previous-series.html)

[MySQL 8.0 Reference Manual 2.11.4 Changes in MySQL 8.0](https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html)

[運用視点なMyISAMとInnoDBと。](http://tech.lexues.co.jp/archives/1405)

[MySQL 5.7の重要機能まとめ](https://yakst.com/ja/posts/2478)
python バージョン切り替え

環境
macOS catalina (10.15.7)
MacBook Air (Retina, 13-inch, 2019)
1.6 GHz デュアルコアIntel Core i5
8 GB 2133 MHz LPDDR3


#切り替えられるpythonのバージョンの確認
```
$ pyenv versions  
  system
  3.6.1
* 3.6.2 (set by /Users/gen/.pyenv/version)
  3.6.5
  3.8.1
  anaconda3-4.2.0
  anaconda3-4.2.0/envs/py
```
#現在のバージョンの確認
```
$ python --version                        
　Python 3.6.2
```

#3.8.1に変更
```
$ pyenv global 3.8.1
```

#変更されたかの確認
```
$ python --version
  Python 3.8.1
```
変更されました．
phpのコーディング中のちょっとしたtipsを淡々と追加していく記事

タイトル通りの記事です。随時更新。ゆるゆるtipsを貯めていって、後々自分にとって役に立ったらいいなぁというモチベで書いています。

## 「ある文字列の中に、特定の文字列が存在するかどうか」だけを判断する際は、strstr()やstrpos()ではなくstr_contains()を使う[※version > 8]

```php
if ($str_contains($haystack, $needle)) {
    // 文字列が存在したときの処理
}
```
> 参考：https://www.php.net/manual/ja/function.str-contains.php

### ある文字列の中に、特定の文字列が存在するかどうかだけを判断する際は、strstr()よりstrpos()を使う[※version < 8]
やむを得ずphp version < 8で戦っている方はこちら。

```php
# こうではなく
if ($strstr($haystack, $needle, true) !== false) {
    // 文字列が存在したときの処理
}

# こっち
if ($strpos($haystack, $needle, true) !== false) {
    // 文字列が存在したときの処理
}
```

`strpos()`は`strstr()`より高速でメモリ消費も少ないらしい

> 参考：https://www.php.net/manual/ja/function.strstr.php

## array_key_exists()はkey_existsで良い

```php
key_exists($key, $array)
```
エイリアス。単純に文字数が減るので良い

> 参考：　https://www.php.net/manual/ja/function.key-exists.php

## exit はdie でも良い
```php
die; // exitと同じ
die(1); // エラーコード付き
```

エイリアス。単純に「へぇ」となるだけ。
> 参考：https://www.php.net/manual/ja/function.die.php

## スクリプト・クラスファイルで、?phpは閉じるな
`?>`で閉じてファイルの末尾に改行があると、改行がプログラムの出力となる。バグが起こりやすい。

まあちゃんとフォーマッタが動いていれば自動的に削除されるが。

## 連想配列操作は各フレームワークのcollectionを使うようにする
配列操作に関して、メソッドチェーンでできるようになるなど、多言語ライクに使えるようになり、ストレスフリー

> 参考：https://qiita.com/nori0620/items/08bba8649fa5b608f695

```php
# 配列から新しいコレクションインスタンスを生成
# 各要素に対しstrtoupperを実行し、それから空の要素を削除している
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
    return strtoupper($name);
})->reject(function ($name) {
    return empty($name);
});
```
(サンプルコードはhttps://readouble.com/laravel/8.x/ja/collections.html より拝借)
Arduinoでガス中酸素濃度を測定

#Groce Oxygen Sensor編
## 必要なもの
+ Arduino UNO
+ Grove Oxygen Sensor

Grove Oxygen Sensorはアナログ出力。RobotShopまたはSEEEDから入手可能。

## 配線
- センサーは、基板、センサーそのもの、Groveケーブルの三点セットになっている。それらを組み立てる。
- 以下のようにArduinoとセンサー（に取り付けられたGroveケーブル）に繋げる。
    - Arduinoの3.3Vまたは5V　<--> センサーの赤色の線
    - ArduinoのGND <--> センサーの黒色の線
    - ArduinoのA0 <--> センサーの黄色の線
    - （センサーの白色の線は使わない。）

## そのあとは
Arduinoの「01.Basics>AnalogReadSerial」で試すことができる。ただし、センサーはウォームアップするのに数分かかることがある。数分後、analogRead(A0)の値が安定したら、センサーに息を吹きかけてみる。値が一旦下がり、再び元のレベルに戻るはず。

## トラブル
- リスポンスが悪いことがあった。最近出たMIX8410を用いたセンサーは大丈夫かもしれない。
- 水や硫化水素対策（必要な場合）
    - 結露を防ぐために加温することも考えられる。
    - 硫化水素による劣化を防ぐため、金属部を樹脂（エポキシやシリコン充填剤）で保護する。

#LuminOx (SSTセンシング）編
## 必要なもの
+ Arduino UNO
+ LuminOx 酸素センサー（国内ではグローバル電子株式会社から入手可能）

## 配線
- 以下のようにArduinoとセンサー（に取り付けられたGroveケーブル）に繋げる。
    - Arduinoの5V　<--> センサーのピン1
    - ArduinoのGND <--> センサーのピン2
    - Arduinoの8 <--> センサーのピン3
    - Arduinoの9 <--> センサーのピン4
![LuminOx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1101191/3ec91b00-c7d7-9446-562b-8b28debc545f.jpeg)

なお、上記接続はジャンプワイヤーのオス-メスを用いてもよいし、また、センサーをブレッドボードに挿して、ブレッドボードからArduinoにつなげてもよい。
なお、LuminOxのUARTは3.3Vなのに対して、Arduino UNOは5Vである。LuminOxのUARTは5Vには耐えられる仕様なので壊れることはないと思うが、もしかすると不具合が出ることがあるかもしれない。今のところは直接つないでもうまく動いている。

## スケッチ
ライブラリSoftwareSerialはArduinoIDEにデフォルトで組み込まれているので新たにインストールする必要はない。

<detail><summary>スケッチ1</summary><div>

```
#include <SoftwareSerial.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial mySerial =  SoftwareSerial(8, 9);//rx,tx

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.print("M 1");  //最初にモードを設定する。M 1でリクエスト時に測定。
  mySerial.print("\r\n");
  i=0;
  lcd.init();
  lcd.backlight();
}

void loop() {
  Serial.print(" ");
  mySerial.flush(); 
  mySerial.println("O");    //センサーに測定を指示する。"O" for ppO2 [mbar], "%" for O2 in [%], "A" で圧力や温度を含め全データ
  while (mySerial.available() == 0) {  //センサーからの返事を待つ。
    delay(10);
  }
  while (mySerial.available() > 0) {
    String text=mySerial.readString();
    Serial.print(text);
  }
  i++;
  delay(1000);
}
```
</div></detail>

測定値を数字として得たいときは、

```
text = text.substring(3, 8);  //文字列の３文字目〜８文字目を得る
float result = text.toFloat(); //変数型を変換する
```

## コメント
センサーは、起動してから安定するまでに5分〜10分くらいかかるようである。
【 Nuxt 】v-cardを横並びにした際にテキストやボタン位置に統一性をもたらす

#はじめに
Nuxt（Vue）で本記事のような内容は見受けられなかったので、皆さんのお役に立てれば幸いです。
また、本記事はVuetifyを使用しています。

では、さっそく内容に迫っていきましょう。

#最終イメージ
![スクリーンショット 2021-02-09 16.33.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691815/e5b803cb-02d0-c8f0-29c5-761770684600.png)

#スタート

```vue
<v-row>
        <v-col
          v-for="(item, i) in items"
          :key="i"
          class="d-flex"
          cols="12"
          sm="6"
          md="6"
          lg="4"
        >
          <v-card
            outlined
            max-width="100%"
            height="100%"
            class="d-flex flex-column"
          >
            <v-img :src="item.img" style="max-height:214px" height="214px" />
            <v-card-title
              class="justify-center"
              v-text="item.title"
            />
            <v-card-text
              :style="'font-size:0.9rem'"
              height="100%"
              v-html="item.text"
            />
            <v-spacer />
            <v-card-actions class="mb-7">
              <a :href="item.link" target="_blank" style="text-decoration: none">
                <v-btn
                  text
                  color="primary"
                  class="mb-5"
                  :style="'font-size:1.0rem'"
                >
                  <span>{{ item.description }}</span>
                </v-btn>
              </a>
            </v-card-actions>
          </v-card>
        </v-col>
      </v-row>
```
＊ ポイントはv-cardにclass="d-flex flex-column"を付与させることでv-spacerが上手く動作します。

```javascript
export default {
  data () {
    return {
      items: [
        {
          title: 'ネーム1',
          text: 'テキス1トテキスト1テキスト1テキスト1テキスト1。',
          img: '/images/image1',
          link: 'https://?????????',
          description: 'ボタンの中身',
        },        {
          title: 'ネーム2',
          text: 'テキス2トテキスト2テキスト2テキスト2テキスト2。',
          img: '/images/image2',
          link: 'https://?????????',
          description: 'ボタンの中身',
        },        {
          title: 'ネーム3',
          text: 'テキス3トテキスト3テキスト3テキスト3テキスト3。',
          img: '/images/image3',
          link: 'https://?????????',
          description: 'ボタンの中身',
        }
      ]
    }
  }
}
```
#おわりに
v-cardにclass="d-flex flex-column"を付与させることでv-spacerが上手く実装することができました。
少しでもお役手に立てればLGTMをお願い致します🙇‍♂️
GiteaとMattermostの連携

Gitea上でのイベント(プッシュ、プルリク、等)がMattermostに通知されるようにします。

# Mattermost側の設定

1. 通知用のチャンネルを作成する。

1. System Consoleを開く。
![system_console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/379828b2-7841-14b8-32cf-ebebe53a3477.png)

1. Custom Integrationsを開き、Enable Incoming Webhooksをtrueに設定。
![custom_integration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/c0aa3f4f-e18b-090a-47b4-f571d9c3ffad.png)

1. Integragionsを開く。
![integrations.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/8890d730-0e74-e48c-08a8-5cdc293111b6.png)

1. Incoming Webhookを選択。
![incoming_webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/020a707c-7487-2a31-96e2-55f937a414d3.png)

1. Add Incoming Webhookを選択。
![add_incoming_webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/d9e705c1-1686-775c-006b-21e600f3dc60.png)

1. 情報を入力。Channelには先ほど通知用に作ったチャンネルを指定。
![add.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/bd1d00b1-ca60-fe31-2029-97d3a002ea7b.png)

1. Webhook用のURLを控えておく。
![webhook_url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/9a16ce39-b326-fed3-c4d7-2d2f86ab80bd.png)

1. 通知用チャンネルのメニューから"View Info"を開き、末尾のチャンネル名を控えておく。
![about_notifications.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/cd2214a5-4383-6d51-8b7a-73b1c151ba6e.png)

# Gitea側の設定

1. 管理者権限でログイン。

1. サイト管理画面から"デフォルトのWebhooks"タブを選択し、Webhookを追加を選択。
![add_webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/2a8cfc0c-688e-b151-0d41-8c085aabb281.png)

1. Slackを選択。
![select_slack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/52fde0f9-f24d-7d09-d95a-d77564c1dd3a.png)

1. 設定を入力。ターゲットURLとチャンネルに先ほど控えた情報を入れる。トリガーを好みに応じて設定。
![add_default_webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404447/ee067a2b-9d74-ae08-c3cf-299eb41f82d1.png)

以上でGiteaのイベントがMattermostに通知されるようになります。

# おまけ - Redmineとの連携

Redmineのチケット登録・更新情報などをMattermostに通知する場合は、[こちら](https://qiita.com/kazuki43zoo/items/e91c1aec8dac0b6b3bb7)や[こちら](https://www.ccs1981.jp/blog/mattermost-420/)を参考。

# 参考URL
+ https://discourse.gitea.io/t/mattermost-chat-integration/1203/4
+ https://qiita.com/kazuki43zoo/items/e91c1aec8dac0b6b3bb7
+ https://www.ccs1981.jp/blog/mattermost-420/
VSCodeVimの有効/無効をショートカットキーで切り替える方法

# はじめに

プログラムを組む際にはVimキーバインドが便利だけど、
日本語文章を打つときは煩わしくなった。

Vimキーバインド有効無効をショートカットキーで切り替えれる設定方法を調べたので、ここで紹介する。

## 私の使っているVScodeのVimプラグイン

https://github.com/VSCodeVim/Vim
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15085/5bcdd012-1f04-7c89-7e04-ce8d1975bff8.png)

## togglevimコマンドを実行

このコマンドを実行すると、Vimキーバインドが有効/無効が切り替わる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15085/03754916-5aa6-02b8-9484-4d6d5c569536.png)

## togglevimコマンドを呼び出すショートカットを設定

あとはコマンドにお好みのショートカットキーを設定するだけ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15085/1ec5c45b-8f81-93e4-30a4-77922cf485d3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15085/725f4089-fc1d-83d7-e198-cb6ed711b201.png)
じゃんけんが決まる平均の回数

#何人かでやったときにじゃんけんの決まる平均の回数

```java
import java.io.*;

public class Game {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int input=0;
        for (;;) {
            try {
                System.out.println("何人でじゃんけんするのか入力してください");
                input=Integer.parseInt(br.readLine());
                if (input==0) {
                    System.out.println("0以外の数を入力してください");
                }else if (input!=0) break;
            }catch (NumberFormatException e) {
                System.out.println("数字のみ入力してください");
            }
        }
        double count = 1.0;
        for (int j=0; j<1000000; j++) {
            int num = sumNum(input);
            count+=num;
        }
        System.out.println("勝者が一人に決まるまでの平均回数は"+count/1000000+"回です");
    }
    public static int sumNum(int input) {
        for (int i=1;;i++) {
            int rock=0;int scissors=0; int paper=0;
            for (int j=0;j<input;j++) {
                int rand = new java.util.Random().nextInt(3);
                if (rand==0) {
                    rock++;
                } else if (rand==1) {
                    scissors++;
                } else {
                    paper++;
                }
            }
            if (input>=3) {
                if (rock!=0&&scissors!=0&&paper!=0);
                else if (rock==input||scissors==input||paper==input);
                else if (rock==0) input=scissors;
                else if (scissors==0) input=paper;
                else if (paper==0) input=rock;
            }else if (input==2) {
                if (rock==input||scissors==input||paper==input);
                else return i;
            }if (input==1) return i;
        }
    }
}
```

javaの初心者でこのコードは比較的わかりやすいし色々と学べるところもあるからおすすめです。
参考:http://mittsu2017.com/post-224/
syntaxerrorの解決例

SyntaxError
/Users/○○/projects/ourblog_error2/app/controllers/posts_controller.rb:47:syntax error,unexpected end-of-input,expecting end

上記は、post_controller.rbの47行目に文法的な間違いがあり、
さらにunexpected end-of-input,expecting end よりendの数が足りないことが分かります。

したがってendを追加する修正を行います。
React TextFieldを削除ボタンで空白にする方法

#はじめに
ReactでMaterial-uiのTextFieldを使って、削除ボタンで入力した内容を消す方法を紹介します。
全然難しいことじゃなさそうですが、ちょっとだけハマってしまったので。
ちなみにすごく簡単です。

#最初はこうしてた
```react:App.js
import { useState } from 'react'
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';


function App() {

  const [text, setText] = useState('');

  const DeleteHandler = () => {
    setText('')
  }

  console.log(text);

  return (
    <div>
      <TextField
        id="text"
        label="text"
        onChange={(e) => {
          setText(e.target.value)
        }}
      />
      <Button
        variant="contained"
        onClick={DeleteHandler}
      >
        Delete
      </Button>
    </div>
  );
}

export default App;
```
DeleteHandlerでtextを空にしてるはずなのに。
console.log(text)で見てみると確かに値は空なのに、画面のTextFieldの文字は消えてくれない、、、

#こうしたら上手くいった

```react:App.js
      <TextField
        id="text"
        label="text"
        value={text}
        onChange={(e) => {
          setText(e.target.value)
        }}
      />
```
`value={text}`の一文を加えるだけ。
valueを指定してあげないといけなかったんですかね。

#終わりに
見た感じ上手くいったのはいいものの、何でこうなるのかちゃんとした理由をちゃんと学びたい。
s3のライフサイクルルールを設定してみる

## 設定するライフサイクルルール

※ストレージクラスの詳細は [こちら](https://qiita.com/miyuki_samitani/items/2841caf67bf64a25bea5) をご覧ください

今回は、以下のように設定を行っていきたいと思います。
0日   から 30日  : s3標準
30日  から 120日 : Glacier
120日 以降      : 削除

## 設定

### 移動

今回は `test-life-cycle-configuration` というバケットを作成したのでこちらを使用します

```
Amazon S3 > バケット > test-life-cycle-configuration
```

![1S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/dc3687e9-da67-db15-08dd-b8dd15809951.png)


### 現状のライフサイクルルールを確認

今の所何も設定されていないので、 `ライフサイクルルール (0)` と表示されています

```
test-life-cycle-configuration > 管理 > ライフサイクルルール
```

![2S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/6889b991-d56c-ed33-b94e-7d725952b614.png)


### ライフサイクルルールを作成する

- ライフサイクルルールの設定

```
ライフサイクルルール名 : test-life-cycle-configuration-rule
ルールスコープ : バケット内のすべてのオブジェクトに適用
	※このルールは、バケット内のすべてのオブジェクトに適用されます にチェックを入れる
	こちらにチェックを入れないと作成できません
```

![3S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/bab301a8-619c-910d-77c2-ad591771ca01.png)


- ライフサイクルルールのアクション

今回はストレージクラスの移行 と 削除を行うので、以下2点にチェックを入れる

```
- オブジェクトの現行バージョンをストレージクラス間で移行する
- オブジェクトの現行バージョンの有効期限が切れる
```
![4S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/f56fb84f-c145-9cd2-af5e-11c8f1b73205.png)


- オブジェクトの現行バージョンをストレージクラス間で移行する

以下の設定を行います。
`30日  から 120日 : Glacier`

以下を行うことで、30日後にGlacireに移動します
この日数はアップロードされてから何日経っているかを示します。

```
ストレージクラスへの移行 : Glacire
オブジェクト作成後の日数 : 30
```

![5S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/11b76e87-541e-2b63-f645-2c9a99b6b33b.png)


- オブジェクトの現行バージョンの有効期限が切れる

以下の設定を行います。
`120日 以降      : 削除`

以下の設定を入れることで、アップロードから120日経ったら自動的に削除されるようになります

```
オブジェクト作成後の日数 : 120
```

![6S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/afb79b11-1b04-6125-0374-8b0023c04370.png)


- タイムラインの概要

最終確認を行います。
アップロードされてから30日後にGlacierに移動し、
120日後には有効期限切れ(削除)がされます。
こちらで問題なければ `ルールの作成` を行います

![7S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/097b5b37-fa80-57fd-49cc-6e7469dde59f.png)

### ライフサイクルルールの作成の確認

`test-life-cycle-configuration-rule` が enable になっていたので作成も完了し有効になっています

![8S3 Management Console - Google Chrome 2021-02-08 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/5b0e9a13-f801-cac0-bfcf-b8a345f03ca1.png)

※削除や移行のタイミングは、
協定世界時(UTC) で0時なので、日本では午前9時になります。

## 参考

- [S3 でライフサイクルポリシーを設定してみた件](https://blog.serverworks.co.jp/tech/2019/07/09/post-71647/)
ライフゲーム for ExcelVBA

![GameOfLife.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164214/3c2afed4-19e8-25bd-06c3-0943d08d6059.png)


```VB
Option Explicit

Const ROW_SIZE = 8
Const COL_SIZE = 8

Sub GameOfLife()
    Dim rng As Range, arr
    Set rng = Sheet1.Cells.Resize(ROW_SIZE, COL_SIZE).Offset(1, 1)
    arr = rng.Value
    
    If WorksheetFunction.Sum(arr) = 0 Then Call Init
    
    Dim i, j
    For i = 1 To ROW_SIZE
    For j = 1 To COL_SIZE
        Select Case WorksheetFunction.Sum(Sheet1.Cells(i, j).Resize(3, 3)) - arr(i, j)
        Case 2
        Case 3
            arr(i, j) = 1
        Case Else
            arr(i, j) = 0
        End Select
    Next j, i
    rng.Value = arr
    
    With rng.Resize(1, 1).Offset(-1, rng.Columns.Count + 1)
        .Value = .Value + 1
    End With
    
    Application.OnTime Now + TimeValue("00:00:02"), "GameOfLife"

End Sub

Sub Init()
    Sheet1.Cells.Clear
    With Sheet1.Cells.Resize(ROW_SIZE, COL_SIZE).Offset(1, 1)
        .Formula = "=RANDBETWEEN(0,1)"
        .EntireColumn.AutoFit
        With .FormatConditions.Add(xlCellValue, xlEqual, 0)
            .Interior.ColorIndex = 2
            .Font.ColorIndex = 2
        End With
        With .FormatConditions.Add(xlCellValue, xlEqual, 1)
            .Interior.ColorIndex = 1
            .Font.ColorIndex = 1
        End With
    End With
End Sub
```
GraphQLでローカルフォルダ上にある任意の画像データ取得する【GatsbyJS】

ローカル上のデータをGraphQLで引っ張ってくるネタ記事があまりなかったのでメモ代わりに記事にしました。


## 必要なライブラリ
gatsby-source-filesystem を使うのでインストールして設定します。GraphQL上にallFileスキーマを与えます。
<a href="https://www.gatsbyjs.com/plugins/gatsby-source-filesystem/">ライブラリの公式ページ</a>

加えてGraphQL上でGatsby用に最適化した画像を取得するために gatsby-transformer-sharp と gatsby-plugin-sharp を使います。

```
yarn add gatsby-source-filesystem gatsby-transformer-sharp gatsby-plugin-sharp
```


```gatsby-config.js
    ...,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`, //ソース名
        path: `${__dirname}/src/images`, //ファイルの置き場所
      },
    },
    ...
```

## allFileの中から取り出せる
ローカル上のディレクトリ名そのままで取り出すこともできますが、Gatsby用にtransformされた静的データとして受け取りたいため、childImageSharpスキーマの中の画像を取り出します。

gatsby develop で起動させて 

```
// http://localhost:8000/___graphql
{
  allFile {
    edges {
      node {
        childImageSharp {
          fixed {
            src
          }
        }
      }
    }
  }
}
```
これでローカル上の画像一覧が出力されます。

## Filterを使って対象のディレクトリを絞る
「画像枚数が多いからGraphQL側でフィルタリングしたい」という場合はfilterオプションを設定させることがでできます。

### 特定の画像を指定する場合
GraphQL上で allFile > filter > relativePath > eq と指定して

```gatsby-config.js
path: `${__dirname}/src/images`
``` 
gatsby-config.js上 で指定した上のディレクトリ以下を指定してあげることで取得できます。

```
{
  allFile(filter: { relativePath: { eq: "food/hogeMeat.png" } }) {
    edges {
      node {
        childImageSharp {
          fixed {
            src
          }
        }
      }
    }
  }
}
```

複数の特定の画像を指定する場合は、
allFile > filter > relativePath > in
で複数を指定可能。配列の形でPathをいれます。

```
{
  allFile(filter: {relativePath: {in: ["foodstuff/fish.png","foodstuff/meat.png"]}}) {
    edges {
      node {
        childImageSharp {
          fixed {
            src
          }
        }
      }
    }
  }
}

```

### 特定のディレクトリを指定する場合
「ディレクトリ単位でまるっと取得したい」
その場合は filterオプション を relativeDirectory でディレクトリのみフィルタリングできます。

```
{
  allFile(filter: {relativeDirectory: {eq: "foodstuff"}}) {
    edges {
      node {
        childImageSharp {
          fixed {
            src
          }
        }
      }
    }
  }
}

```
vs2010でmfc その5

#概要

vs2010でmfcやってみた。
コッホ曲線やってみた。

#参考にしたページ

https://www.kazetest.com/vcmemo/koch-curve/koch-curve.htm


#手順

- mfcアプリケーション、ダイアログベースでプロジェクト名は、mfc0で作る。
- IDD_MFC0_DIALOGを開く
- OKボタンをクリック。
- コードを書く。
- 実行。

#サンプルコード

```


typedef struct tagFPOINT {
    double x;
    double y;
} FPOINT;
void DrawLine(FPOINT p1, FPOINT p2, CDC * pDC)
{
    pDC->MoveTo((int)(p1.x + 0.5), (int)(p1.y + 0.5));
    pDC->LineTo((int)(p2.x + 0.5), (int)(p2.y + 0.5));
}
FPOINT RotateLine(FPOINT p1, FPOINT p2, double alpha)
{
    double x0 = p1.x;
    double y0 = p1.y;
    double x1 = p2.x - x0;
    double y1 = p2.y - y0;
    FPOINT pntRet;
    pntRet.x = x1 * cos(alpha) - y1 * sin(alpha) + x0;
    pntRet.y = x1 * sin(alpha) + y1 * cos(alpha) + y0;
    return pntRet;
}
FPOINT ShortenLine(FPOINT p1, FPOINT p2, double Ratio)
{
    FPOINT pntRet;
    if (p1.x == p2.x && p1.y == p2.y)
    {
        pntRet = p1;
    }
    if (p1.x == p2.x)
    {
        pntRet.x = p1.x;
        pntRet.y = p1.y + (p2.y - p1.y) * Ratio;
    }
    else if (p1.y == p2.y)
    {
        pntRet.y = p1.y;
        pntRet.x = p1.x + (p2.x - p1.x) * Ratio;
    }
    else
    {
        pntRet.x = p1.x + (p2.x - p1.x) * Ratio;
        pntRet.y = p1.y + (p2.y - p1.y) * Ratio;
    }
    return pntRet;
}
void KochCurve(int n, FPOINT p1, FPOINT p2, CDC * pDC)
{
    if (n == 1)
    {
        DrawLine(p1, p2, pDC);
    }
    else
    {
        FPOINT pc1 = ShortenLine(p1, p2, 1.0 / 3.0);
        FPOINT pc2 = ShortenLine(p1, p2, 2.0 / 3.0);
        FPOINT pc = RotateLine(pc1, pc2, -acos(1.0 / 2.0));
        KochCurve(n - 1, p1, pc1, pDC);
        KochCurve(n - 1, pc1, pc, pDC);
        KochCurve(n - 1, pc, pc2, pDC);
        KochCurve(n - 1, pc2, p2, pDC);
    }
}
void Cmfc0Dlg::OnBnClickedOk()
{
    CClientDC dc(this);
    FPOINT p1 = {
		200, 
		300
	};
    FPOINT p2 = {
		800, 
		300
	};
    KochCurve(6, p1, p2, &dc);
}

```

以上。
初めてのRaspberry Pi Pico ⑫ Circuitpythonで14セグLEDに温度を表示

　ebayなどで入手しやすいHT16K33コントローラを使った14セグメントLED（QUAD ALPHANUMERIC）を点灯します。HT16K33コントローラは、マトリクスなどの表示にも使われています。
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b60c60ba-0cb6-a36b-52c8-34f0c942501e.png">


###14セグメントLEDの接続
　インターフェースはI2Cです。ピン穴の横に書かれているシルク印刷で、CはSCL、DはSDA、＋はVcc、ーはGNDへ接続します。

|14segLED端子 |Pico物理的ピン番号 |Pico GPIOピン番号|
|:-----------|------------:|:------------:|
|＋　Vcc（Vi2c）|36 |3.3V|
|＋　Vcc|36 |3.3V|
|ー　GND|33 |GND|
|D　SDA|31 |GP26|
|C　SCL|32 |GP27|

　このあたりで見つかります。
https://www.ebay.com/itm/0-54inch-4-digit-Digital-LED-Red-Tube-Display-for-Control-Module-I2C/333878187451?_trkparms=aid%3D1110006%26algo%3DHOMESPLICE.SIM%26ao%3D1%26asc%3D20131231084308%26meid%3D0b4e641e80d9410290805c3aac2e8498%26pid%3D100010%26rk%3D1%26rkt%3D12%26sd%3D193868686579%26itm%3D333878187451%26pmt%3D0%

###Adafruitのブレークアウト・ボード
　I2C専用の4ピン・コネクタを搭載したボードです。
　　[TMP117 Precision Temperature Sensor](https://www.adafruit.com/product/4821)

<img width="450" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c6408e59-912f-49d3-0517-d50551b15208.png">
　SDA/SCL信号には10kΩのプルアップ抵抗が入っています。I2Cのスレーブ・アドレスがデフォルトが0x48で、裏面のADDRの部分をショートすると0x49になるようです。
　GP27/26のI2Cバスにつなぎます。



###必要なファイル
　ダウンロードして解凍したファイルのうちlibとexamplesは、ラズパイの/home/piにコピーしています（第2回を参照）。
　ダウンロード・フォルダにあったadafruit-circuitpython-raspberry_pi_pico-en_US-6.2.0-beta.1.uf2をデスクトップにドロップしておきます。
　BOOTSELボタンを押したまま、ラズパイとPicoをUSBケーブルをつなげます。つながったら、BOOTSELから手を放します。RPI-RP2ドライブがマウントされます。そのRPI-RP2ドライブへ、adafruit-circuitpython-raspberry_pi_pico-en_US-6.2.0-beta.1.uf2をドラッグします。コピーが数秒で終わると、デスクトップには、CIRCUITPYドライブがマウントされています。


　CIRCUITPYドライブを開きます。この中にあるlibフォルダに、/home/pi/libにあるadafruit_ht16k33フォルダをコピーします。温度センサTMP117を使うので、adafruit_tmp117.mpyもlibフォルダへコピーします。



###温度計のプログラム
　エディタはMuを使います。CIRCUITPYドライブが存在している状態で起動すると、Circuitpythonモードで立ち上がります。

```python
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
# Author: Tony DiCola

import time
import board
import busio
from adafruit_ht16k33 import segments
import adafruit_tmp117

# Create the I2C interface.
i2c = busio.I2C(board.GP27, board.GP26)

# Create the LED segment class.
display = segments.Seg14x4(i2c)

tmp117 = adafruit_tmp117.TMP117(i2c)

# Clear the display.
display.fill(0)

while 1:
    print("Temperature: %.2f degrees C" % tmp117.temperature)
    display.print('{:.1f}c'.format(tmp117.temperature))
    display.show()
    time.sleep(1)
```

　実行中の様子です。
<img width="500" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/405ef20e-b497-e10c-229e-f43ae8fcb7eb.png">

　温度表示部分を次のように差し替えると、横スクロールします。

```python
display.marquee("tmp117 " + '{:.1f}c '.format(tmp117.temperature), 0.5)
```
【Ansible】 file モジュールで権限がバグってはまった話

こんにちわ！ @ktoshi です！

先日、Ansible ではまってしまったことを共有しようと思います。

# 概要
Ansible でディレクトリを作ったが、権限設定が全然意図したものにならない。

# 事象
ディレクトリを作ろうとして下記のタスクを用意した。

```yaml
- name: Create Test Directory.
  file:
    path: /opt/test
    mode: 755
    state: directory
```

よし、実行。

```shell
$ ansible-playbook -i hosts.yaml setup.yaml

PLAY [all] ***************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************
ok: [192.168.100.123]

TASK [Create Test Directory.] ********************************************************************************
changed: [192.168.100.123]

PLAY RECAP ***************************************************************************************************
192.168.100.123              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```
うん、動いた。

```shell
$ ls -ld /opt/test/
d-wxrw--wt 2 root root 6 Feb 11 21:21 /opt/test/
```
バカな権限だなぁ！！（カミナリ風）

と、言う風に意図しない権限が設定されました。

# 原因
[公式ドキュメント](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/file_module.html)に**ちゃんと**記載されている。
> You must either add a leading zero so that Ansible's YAML parser knows it is an octal number (like 0644 or 01777) or quote it (like '644' or '1777') so Ansible receives a string and can do its own conversion from string into number.

file モジュールの「mode」要素で8進数を利用する際は頭に「0」を付けるか、「'」などで囲い、明示的に文字列で指定する必要がある。

そのため、下記のように指定する必要がある。

```yaml
- name: Create Test Directory.
  file:
    path: /opt/test
    mode: 0755
    state: directory
```
もしくは

```yaml
- name: Create Test Directory.
  file:
    path: /opt/test
    mode: '755'
    state: directory
```

# まとめ
しっかり公式ドキュメントは読みましょう。
[メモ] 一般的な日本語配列キーボードで 変換キー+J(/K/L/I) を 矢印キー に割り当てる

自分環境構築用のメモです。

市販されている一般的な日本語配列キーボードを使用しているのですが、矢印キーを打鍵しようとするとホームポジションから外れなければなりません。
Fnキーがあるキーボードだとホームポジションで済む場合がありますが、通常のキーボードでなんとかしたいのです。

やりたいことは、下記のようになります。

- 変換キー+J -> ←キー
- 変換キー+K -> ↓キー
- 変換キー+L -> →キー
- 変換キー+I -> ↑キー
- 変換キー+H -> Homeキー
- 変換キー+N -> Endキー
- 変換キー+U -> PageUpキー
- 変換キー+O -> PageDownキー
- 変換キーの機能自体は使いたいので、カタカナひらがなキーはつぶす


そこで、ソフトウェアでなんとかするための設定です。

## PowerToys(Keyboard Manager)

ショートカットの再マップ機能で、修飾子キー＋文字を、矢印キーなどに割り当てることができます。
ただし、変換キーは修飾子キーにはならないため、変換キー+Jといった組み合わせをマッピングできません。

ここでは変換キーのことは置いておいて、代わりにAlt(Right)を修飾子キーとして使用し割り当てます。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124276/7c991e51-0970-6d88-ba8a-94648859ee2c.png)

## スキャンコードのマッピング

Alt(Right)キーとの組み合わせができるようになったので、変換キーをAlt(Right)キー扱いにしたいと思います。
PowerToys(Keyboard Manager)にキーの再マップ機能があるので、これを使って入れ替えれればいいのですが、残念ながらできませんでした。(v0.31.2時点)

そこで、Windows側の設定でキーをマッピングします。
よく[Caps Lockキーの入れ替え方法](https://ascii.jp/elem/000/004/034/4034117/2/)として紹介されている、スキャンコードのマッピングを行います。

レジストリーの`KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout`下の`Scancode Map`に、下記の設定を行います。

- 変換キーをAlt(Right)キーに割り当て
- カタカナひらがなキーを変換キーに割り当て

レジストリーの値は下記です。

```
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout]
"Scancode Map"=hex:00,00,00,00,00,00,00,00,03,00,00,00,38,e0,79,00,79,00,70,00,\
  00,00,00,00
```

使用している値はスキャンコードで、Microsoftのドキュメントでは[scancode.doc](https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc)に記載があるようですが、面倒なので[SharpKeys](https://github.com/randyrants/sharpkeys)というソフトを使って編集しました。
(編集が終われば不要)
編集後にログオフ＆ログオンすれば反映されます。

これで望んでいたことができるようになりました。

## 制約

変換キーをAlt(Right)キーに割り当てているので、単体で押すと当然Altキーとして振舞ってしまいます。

また、コンテキストメニューのようなポップアップするメニューではメニューが閉じられてしまい、正しく動作しません。
(もしかしたらCtrl(Right)とかにすれば改善するかもしれません。)
vs2010でmfc その4

#概要

vs2010でmfcやってみた。
sin波やってみた。

#手順

- mfcアプリケーション、ダイアログベースでプロジェクト名は、mfc0で作る。
- IDD_MFC0_DIALOGを開く
- OKボタンをクリック。
- コードを書く。
- 実行。


#サンプルコード

```
#include <math.h>

void Cmfc0Dlg::OnBnClickedOk()
{
	CDC *pdc;
    pdc = GetDC();
    pdc->Ellipse(10, 10, 100, 100);
	int posx;
	int posy;
	double x;
	double y;
	for (x = -5.0; x <= 15.0; x += 0.05)
	{
		y = sin(x);
		posx = (int)(150 + x * 20);
		posy = (int)(200 - y * 30);
		if (x == -5.0)
		{
			pdc->MoveTo(posx, posy); 
		}
		else
		{
			pdc->LineTo(posx, posy);
		}
	}
    ReleaseDC(pdc);
}


```
以上。
デザイナーがSwiftを理解するまでの記録

#**自己紹介**
株式会社ゆめみでデザイナーとして働いている村上雄太郎です。

デザイナーとして働いて2年ほどたつのですが、業務の中でもっとシステムやエンジニアリングのことを理解したいと思うようになったので、Swiftを学び始めました。その記録として今後Qiitaにてアウトプットしていこうと思っています。自分でアプリを一通りつくれるようになる、というところを目指して頑張ろうと思います。

#今やっていること
今は同僚からおすすめされた[Swift Playgrounds](https://www.apple.com/jp/swift/playgrounds/)に取り組んでいます。
またUdemyで[みんなのiOS講座 ゼロからSwiftで学ぶiPhoneアプリ開発の基礎](https://www.udemy.com/course/ios-apps/)というコースを購入し、進めています。

まだ全体像が全然見えていなくて、何がわかっていないのかもわかっていないので少しずつ頑張ろうと思います。
It's a template for in-site wiki


# About
(If you look at this part, you can judge if you need to read this page)

*AuthorName create(update,delete) dd/mm/yy*


# Contents
- About
- Topic1(Noun)
   - Sub Topic1 (Noun)
   - Sub Topic2
- Topic2
- Topic3
  - Do Step1 (Start with a verb about procedures)
  - Do Step2
  - Do Step3
- Topic4
- Summary

# Topic1
(content)
### Sub Topic1
(content)
### Sub Topic2
(content)

#Topic2
(content)

#Topic3
(content)

1. Do Step1
1. Do Step2
1. Do Step3

#Topic4
(content)

#Summary
(If you look at this part, you can briefly review the contents shown on this page)
[Unity3D] Playerの動く範囲を設定する(NavMesh)

1, WindowのAI→Navigationを選択
![3626E491-D483-42B8-8733-B56EC84CE2ED_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/23e9fdbe-3716-06ab-8912-cd313528d99b.jpeg)

2, PlayerにNavMeshAgentを設定する
![2330533F-8B04-42BC-BABE-B47E3D48028E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/605316cb-b48d-8715-0d15-fc4e035b804a.jpeg)

3, 下記のスクリプトを作成し、Playerにアタッチする

```C#:Mover
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Mover : MonoBehaviour
{
    [SerializeField] Transform taget;

    // Update is called once per frame
    void Update()
    {
        GetComponent<NavMeshAgent>().destination = taget.position;
    }
}
```

4, Targetを設定してあげる
![F4145B53-8F53-4AAF-876A-407A5AC8EB60.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/7272c82f-d320-ca2c-c1bc-c84d1316b339.jpeg)

5, Meshに含めないobjectなどは、staticにチェックをして選択し、bakeする
![5461DD48-B19A-49F1-874A-56308F722462_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/d055c48d-5406-2114-a7d9-8f87b442b094.jpeg)
![DF27D531-36AA-4B1A-8611-9F7726531CE2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/85d2ca09-13fe-3c23-f820-62efad036c79.jpeg)

6,Meshの範囲はBakeの設定で変更する
![D206FB64-57D5-40C1-893D-7C23C0368B67.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/02de0eb9-0edb-72a7-711c-bec361100496.jpeg)

クリックで操作する
---
1, クリックでRayを出す。下記スクリプトを書く。

```C#:Mover
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Mover : MonoBehaviour
{
    [SerializeField] Transform taget;

    Ray lastRay; //変数の宣言

    // Update is called once per frame
    void Update()
    {
        // 下記を書く
        if (Input.GetMouseButtonDown(0))
        {
            lastRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        }
        Debug.DrawLine(lastRay.origin, lastRay.direction * 100);

        //
        GetComponent<NavMeshAgent>().destination = taget.position;
    }
}
```

2, クリックした箇所にPlayerを移動させる

```C#:Mover
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Mover : MonoBehaviour
{
    [SerializeField] Transform taget;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            MoveToCursor();
        }
    }

    private void MoveToCursor()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        bool hasHit = Physics.Raycast(ray, out hit);
        if (hasHit)
        {
            GetComponent<NavMeshAgent>().destination = hit.point;
        }
    }
}
```
マークダウンで書いてみよう

![だめおやじエンジニア.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099376/95a01a13-e508-faf4-c47e-be2cad2ff764.jpeg)
# マークダウン記法とは

すごく便利なので覚えておきましょう。

#見出しの設定
まずは見出しですね。「#」の数で設定が変わるよ。
ちなみに「見出し」は「# 見出しの設定」って書いてるよ。
では見出し１～６で#の数を変えて早速チェックしてみよう。

# 見出し1
## 見出し2
### 見出し3
#### 見出し4
##### 見出し5
###### 見出し6

Qiitaだと5段階まで設定できるようですね。

# 引用
参考サイトなどの文章を引用したい場合あるよね。
そういったときは「>」を使おう
「> ここは引用部分です」と書いてみよう。

> ここは引用部分です。

できました。> で書いたあとは1行開けよう。
そうしないと引用部分が続いていると思われてしまいます。

# 区切り線
続いて区切り線をためしてみましょう。

もちろん見出し1,2を使えば区切り線が入れられますが、
「見出しは入れたくない」、でも、
「話題がかわるのでちょっと見やすくしたい」
と思ったことありませんか？
区切り線は「---」と書いて前後の行をあければＯＫです。

まずは、区切り線無しで、、
スポーツの話
ビジネスの話

う～ん、ちょっと味気ないですね。
では区切り線を付けてみましょう。
区切り線は「---」と書いて前後の行をあければＯＫです。

スポーツの話

---

ビジネスの話

出来ました。

# 強調
文章中で単語や一文のみ強調したい場合ありますよね。
> その場合は「\`\`」「\*\*」で強調したい部分を囲んでください「``」で囲むとグレーマーク塗りつぶしで、「**」で囲むと太字に変更されます。

では早速試してみましょう。
この文章を`蛍光マークで強調しました`そして**太字で強調しました**  
できました。

# 箇条書き
箇条書きは、簡単。
番号無し箇条書きは、ハイフン「-」の後に空白を入れればOK.段落下げは
> 例
\- リスト1 
\- リスト2
\- リスト3

試してみましょう。
- リスト1 
- リスト2
- リスト3

番号付き箇条書きは、番号+.「1.」の後に空白を、
入れてかけばOK。
1. 番号1
2. 番号2
3. 番号3

段落下げはできませんでした。
半角空白2つを入れればできるとおもったのですが、、、
あとで調べてみます。

# リンク
今回リンクです。

> 書式は以下の通り。
\[リンクテキスト名\]\(リンクのURL\)

マークダウンを勉強するにあたって参考にしたドットインストールさんのリンクを貼ってみましょう。

- [ドットインストール](https://dotinstall.com)


できました！！

# ソースコード
では、ソースコードも見やすくしましょう。
ソースコードの一行前、一行後にバッククオート3つ(\`\`\`)を入力してみましょう。

> 書式は、以下の通り。
\`\`\`
function f() {
  return 0;
}
\`\`\`

```
function f() {
  return 0;
}
```
う～ん、エンジニアっぽいぞ:wink:！！

文中に入れたい場合は、バッククオート1つ(\`)で強調（グレーマーク）しましょｌ

> 書式は以下の通り。
一部は、\`return 0;\`です。


試してみよう
一部は、`return 0;`です。

こんな感じ。

# 画像リンク
Qiitaでは画像を画像選択ボタンから簡単に読み込めますが、せっかくなので勉強を兼ねて自分が作ったロゴをクリックするとQiitaのトップページにアクセスするようにしてみます。
> 書式は以下の通り。URLリンク貼り付けと違うのは最初に「\!」をつけることですね。おさらいも含めてリンク貼り付けと比べてみよう。
`画像貼り付け`
\!\[画像のテキスト名\]\(画像の保存先\)
`リンク貼り付け`
\[テキスト名\]\(対象のURL\)
`画像リンクの貼り付け`
\[\!\[画像のテキスト名\]\(画像の保存先\)\]\(対象URL\)

リンク貼り付けのテキストの部分に画像貼り付けの部分と置き換えればOK。

[![だめおやじエンジニア.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1099376/3e19eba8-e9d5-7624-1272-20ba5d4629b6.jpeg)](https://qiita.com/)

画像から「新しいをウィンドウを開く」で確認してみました。

完成しました。

# さいごに
Qiitaに投稿する前にマークダウンを勉強しました。
これから少しずつ勉強したものをアップしようと思います。

**おじさんSEもがんばるぞ！**:blush:

### 参考サイト
[どっとインストール（マークダウン記法入門）](https://dotinstall.com/)
Nest.js と TypeORM で MariaDB に接続

次にあるサンプルを実行してみました。
[05-sql-typeorm](https://github.com/nestjs/nest/tree/master/sample/05-sql-typeorm)

MariaDB の用意
>User: scott
>Password: tiger123
>Database: my_database

プログラムのクローン

```bash
git clone https://github.com/nestjs/nest/
```

プログラムの準備

```bash
cd nest/sample/05-sql-typeorm
npm install
```

データベースの接続情報の設定

```ts:src/app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'scott',
      password: 'tiger123',
      database: 'my_database',
      autoLoadEntities: true,
      synchronize: true,
    }),
    UsersModule,
  ],
})
export class AppModule {}
```

サーバーの起動

```bash
npm run start:dev
```

クライアントでアクセス

```text
$ curl http://localhost:3000/users
[]
```

MySQL にデータを入れる

```sql:insert.sql
insert into user set id =101, firstname='漱石', lastname='夏目';
insert into user set id =102, firstname='鴎外', lastname='森';
insert into user set id =103, firstname='藤村', lastname='島崎';
insert into user set id =104, firstname='治', lastname='太宰';
insert into user set id =105, firstname='龍之介', lastname='芥川';
quit
```

SQL の実行

```bash
mysql -uscott -ptiger123 my_database < insert.sql
```

クライアントからアクセス

```text
$ curl http://localhost:3000/users | jq .
[
  {
    "id": 101,
    "firstName": "漱石",
    "lastName": "夏目",
    "isActive": true
  },
  {
    "id": 102,
    "firstName": "鴎外",
    "lastName": "森",
    "isActive": true
  },
(省略)
```

IDを指定してアクセス

```text
$ curl http://localhost:3000/users/104 | jq .
{
  "id": 104,
  "firstName": "治",
  "lastName": "太宰",
  "isActive": true
}
```

データの削除

```bash
curl -X DELETE http://localhost:3000/users/102
```

データの挿入

```text
$ curl -X POST http://localhost:3000/users -d firstName='左千夫' -d lastName='伊藤'
{"firstName":"左千夫","lastName":"伊藤","id":108,"isActive":true}
```

次のバージョンで確認しました。

```text
Server version: 10.5.13-MariaDB-0ubuntu0.21.10.1 Ubuntu 21.10
Server version: 8.0.27-0ubuntu0.21.10.1 (Ubuntu)
```
ArduinoでArduino本体の時計を使う

# Arduino本体の時計を使う
　ネット検索をすると外部のRTCを使う記事はたくさん見つかるのですが、Arduino本体の時計を使う記事は案外見つけにくいと感じました。
　そこで、ここにメモをしておきます。
　なお、事前にライブラリマネージャでライブラリTime（by Michael Margolis)をインストールしておく必要があります。

<details><summary>スケッチ例</summary><div>

```ArduinoIDE:time.ino
#include <TimeLib.h>

void setup() {
  setTime(0, 0, 0, 1, 1, 2021);  //set time
  Serial.begin(9600);
}

void loop() {
  Serial.print(year());
  Serial.print("-");
  Serial.print(month());
  Serial.print("-");
  Serial.print(day());  //同様にhour(), minute(), second()が使える。
}
```
</div></details>

##コメント
周期的に装置を動作させるスケッチを作る時、delay関数を使って記述してもよいのですが、時間のかかる処理が間に入るとその分タイミングがずれてしまいます。millis()を使うことも考えられますが、50日程度でオーバーフローしてしまうとのこと。そんな時、Arduino本体の時計を使うとよいと思います。RTCを使ってもよいのですが、RTCがないときは便利でしょう。