OmniAICreator/Qiita-1.07M huggingface dataset:
背景の画像や色によって文字色のテイストが変わる文字加工

## はじめに

- 背景の色や写真の輪郭に合わせて文字のテイストが変わる、ファーストビューで文字をアニメーションでスライドさせたい時といったインパクトを持たせたい箇所に使えそうな、簡単で面白い合成加工方法があったのでメモ。

## コード

```html
<div class="background">
  <div class="blend-txt">blend-txt</div>  
</div>
```

```css
.background {
  height: 3000px;
  background: linear-gradient(30deg,blue,orange);
}

.blend-txt {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
  font-size: 100px;
  font-weight: 900;
  letter-spacing: 10px;
  color: #fff;
  mix-blend-mode: difference;
}
```

## 仕様

- 大枠となる`background`でスクロールして変化を確認できるような高さとグラデーションの背景色を設定しています。
- 子要素として入れ込んである`blend-txt`にはスクロール時にテキストの変化がわかりやすいように`position: fixed;`を指定。
- そして今回のミソである`mix-blend-mode`を`blend-txt`に指定することで背景によって文字色のテイストが変わる面白いエフェクトがかかります。（今回は`difference`を指定）

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="mimi_hokuro" data-slug-hash="MWJrdQa" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="mix-blend-mode">
  <span>See the Pen <a href="https://codepen.io/mimi_hokuro/pen/MWJrdQa">
  mix-blend-mode</a> by mimihokuro (<a href="https://codepen.io/mimi_hokuro">@mimi_hokuro</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
WindowsServer2016のネットワーク自動メトリック値確認

WindowsServer2016のネットワークメトリック値について確認してみました。
結論だけ言うと、以下ウェブページの記載内容と一致していました。

https://docs.microsoft.com/ja-JP/troubleshoot/windows-server/networking/automatic-metric-for-ipv4-routes

#1.構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201787/88506193-86ce-e6b5-f1d6-2ed66c225118.png)


|NIC|device|speed|teaming|speed|
|:-|:-|:-|:-|:-|
|NIC0|vmxnet3|10Gbps|teaming01(Act)|40Gbps|
|NIC1|vmxnet3|10Gbps|teaming01(Act)|-|
|NIC2|vmxnet3|10Gbps|teaming01(Act)|-|
|NIC3|vmxnet3|10Gbps|teaming01(Act)|-|
|NIC4|vmxnet3|10Gbps|teaming02(Act)|10Gbps|
|NIC5|vmxnet3|10Gbps|teaming02(Sta)|-|
|NIC6|vmxnet3|10Gbps|-|10Gbps|
|NIC7|E1000e|1Gbps|-|1Gbps|

<br>
＃teaming設定については以下を参照

https://qiita.com/Higemal/items/a98fe11a46b6083a764e


#2.実測

```
C:\Windows\system32>netsh interface ip show interface

Idx     Met         MTU          状態                 名前
---  ----------  ----------  ------------  ---------------------------
  1          75  4294967295  connected     Loopback Pseudo-Interface 1
 24          10        1500  connected     teaming01
 38          15        1500  connected     teaming02
 29          15        1500  connected     Ethernet6
 30          25        1500  connected     Ethernet7
```

#3.確認
以下ウェブページの記載内容と比較。

https://docs.microsoft.com/ja-JP/troubleshoot/windows-server/networking/automatic-metric-for-ipv4-routes

>
その他のインターフェイスの種類:
>
|リンク速度|測定基準|
|:-|:-|
|100 Gb 以上 5
|40 Gb 以上 100 Gb 未満|10|
|10 Gb 以上 40 Gb 未満|15|
|2 Gb 以上 10 Gb 未満|20|
|200 Mb 以上 2 Gb 未満|25|
|80 Mb 以上 200 Mb 未満|35|
|20 Mb 以上 80 Mb 未満|45|
|4 Mb 以上 20 Mb 未満|55|
|500 Kb 以上 4 Mb 未満|65|
|500 Kb 未満|75|

→一致していることを確認。

#参考
IPv4 ルートの自動メトリック機能の説明
https://docs.microsoft.com/ja-JP/troubleshoot/windows-server/networking/automatic-metric-for-ipv4-routes

ネットワーク アダプタの基本
https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-AF9E24A8-2CFA-447B-AC83-35D563119667.html

WindowsServer2016のネットワークチーミング設定
https://qiita.com/Higemal/items/a98fe11a46b6083a764e
React学習アウトプット（redux-container）

今回は``redux``における``container``について。

``container``の役割は、明示的にStoreの内容を変更するために行う作業。

ただし、今現在では``Hooks``を使う方が圧倒的に記述量、ファイル数が減るため``Hooks``を使う方がおススメらしい。

まぁいつか使う時が来たときに備忘録も兼ねて書いていきます。

```javascript
import { connect } from 'react-redux'
import { compose } from 'redux'
import Class from 'Class.jsx'
```

まずは、``import { connect } from 'react-redux'``と``import { compose } from 'redux'``が必要になる。

また、対象とする**クラスコンポーネント**が必要になる。

今回は例として``import Class from 'Class.jsx'``としている。

次に``mapStateTpProps``と``mapDispatchToProps``の２つが必要となる。

これら２つは``useState``と``useDispatch``と同じ役割を果たす。

```javascript
import { connect } from 'react-redux'
import { compose } from 'redux'
import Class from 'Class.jsx'

const mapStateTpProps = state => {
  return {
    users: state.users
  }
}

const mapDispatchToProps = dispatch => {
  return {
    actions: {
      signIn() {
        dispatch(アクション)
      }
    }
  }
}
```

最後に``compose``と``connect``を使ってこれらのアクションが行えるようにする。

```javascript
import { connect } from 'react-redux'
import { compose } from 'redux'
import Class from 'Class.jsx'

const mapStateTpProps = state => {
  return {
    users: state.users
  }
}

const mapDispatchToProps = dispatch => {
  return {
    actions: {
      signIn() {
        dispatch(アクション)
      }
    }
  }
}

export default compose(
  connect(
    mapStateTpProps,
    mapDispatchToProps
  )
)(Class)
```

``compose``の中で``connect``を使い、``connect``の引数には``mapStateTpProps``と``mapDispatchToProps``を渡す。最後に対象のクラスコンポーネントを渡す。

これで準備はOK。

後は対象のクラスコンポーネントを以下のようにする。

```react
import React, {Component} from 'react'

export default class Class extends Component {
  render() {
    console.log(this.props.users)
    console.log(this.props.actions)
  }
}
```

``Component``をインポートし、``this.props``でコンテナーで定義したものを参照できる。

感想としてはまぁ使う場面は少ないのかなと思います。

やはりクラスコンポーネントに変えてさらに継承も行わなきゃいけないし、継承を行うために色々記述しなければいけないので当分は``Hooks``を使っていきます。

アウトプットは大事！
【3分解説】ブロックチェーンって何がすごいの？

ブロックチェーンと騒がれてしばらくたつのに、これといって何ができるのか分からない。
何がすごいのかわからない...
と考えている人は多いのではないでしょうか？

この記事では、そのような疑問をお持ちの方々に「ブロックチェーンの何がすごいのか？」「実世界でどう役に立つのか？」ということを理解できる手助けになればいいなと思います。

技術的な要素は全て割愛するため、技術が苦手な方でも安心して読んでいただければと思います。

ちなみに、私は大学の研究室でブロックチェーンの活用をテーマに日々、研究しています。

# ブロックチェーンって何がすごいの？

## P2P(Peer to Peer)を知る
ブロックチェーンのすごさを理解するためには、まず「P2P(Peer to Peer)」という概念を知る必要があります。Peerを直訳すると「仲間、対等な人」という意味になります。

何らかの取引をするときに、全員が対等に取引ができるような関係のことをP2Pと呼びます。
図にすると以下のような感じです。
![p2p.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450257/25b02946-58c4-b925-e880-43383ba53c31.jpeg)
参照：[クライアントサーバーとP2Pネットワークの大きな違いとは?](https://coinhack.info/server_p2p/)

## P2Pがレコード会社を破産に追いやった。
実はP2Pという仕組み自体にビジネス的に大きな可能性が潜んでいるのです。なぜなら、P2Pでの取引は仲介者を必要としないからです。P2Pによって業界に大きな変化が起きた例としてレコード会社が挙げられます。従来のレコード会社の役割は、アーティストの歌や演奏を録音し、それを様々なメディア(テープ、CDなど)で音楽レコードを制作し、マーケティングを行い、レコード店やデパートを介して販売することでした。レコード会社の役目は歌や演奏を届ける人とそれを消費する人をつなげる仲介だったのです。ですが、「Napster」と言われるP2Pで音楽ファイルをやりとりできるようにしたサービスの登場により、アーティストや消費者が直接やり取りできるようになり、従来のレコード会社は存在意義を失いました。(P2Pが可能になった背景には、個人がインターネットに接続する時代が来たことや音楽をデジタル情報に置き換えられるようになったことがあります。)

## P2Pを支えるためのブロックチェーン
Napsterのケースは「仲介者をP2Pのやり取りに置き換える」ということを実現したことで音楽業界を大きな変化をもたらしました。この例から仲介者を無くし、ダイレクトに取引ができることによる「中抜き」のインパクトが大きいことが理解していただけたかと思います。

ここで、P2P内での取引を安心してできるようにすることを保証する仕組みとして登場するのが「ブロックチェーン」という技術です。つまり、ブロックチェーンは「中抜き」を達成するのに役立つ**手段**にすぎません。

これが**「ブロックチェーンって何がすごいの？」**という疑問が多くなる原因だと考えます。


今話題のAIを例にとると、**「AIって何がすごいの？」**という疑問はあまり多くないように感じます。なぜなら、AI技術は「たくさんの患者のレントゲンを学習させることでがんの判定をする」等の分かりやすい課題解決ができるため、直感的に理解しやすいからです。

# ブロックチェーンと仮想通貨の関係
ブロックチェーン技術活用の最大の成功例が仮想通貨です。

これまでは、政府や銀行がお金の仲介役として機能していました。
これは、政府や銀行に十分な信用があったために成立していたことです。ですが、これが仕組みによって信用が担保されるとなったらどうでしょう？もはやお金の仲介役としての政府や銀行は必要なくなります。

そしてそれを達成したのがブロックチェーンなのです。

ブロックチェーン技術によって下支えされた通貨(仮想通貨)により、お金のやり取りが信用できる環境(記録の改竄ができない環境)でP2Pでできるようになりました。


まだ、ギャンブル的要素が強い仮想通貨ですが、多くの人が参加するようになれば世界共通通貨としてお金のやり取りがP2Pでできるようになり、もっと効率的で便利な世の中がやってくるのではないかと考えています。

「中抜き」を達成するための、ブロックチェーンと考えると色々な可能性が見えてくるのではないでしょうか？

今後は、ブロックチェーンが仮想通貨のほかにどのように使われる余地があるのかを紹介したいと思います。

【参考文献】
「徹底理解 ブロックチェーン ゼロから着実に分かる次世代技術の原則」, インプレス, (2018/7/1)
Qiita の記事を Zenn に移行してみる（Qiitaを退会した訳ではない）

# Zenn 使ってみたかった
いま話題の [Zenn](https://zenn.dev/) とりあえず触ってみたかったので Qiita での記事を移行してみた。決してQiitaを退会した訳ではないｗ

ともかくZenn は「GitHubリポジトリ連携」ができるので Qiita が突然サービスしても記事を自分で管理できるのがいいかなと思いました。

# Zenn公式サイトに書いてある
Zenn で「GitHubリポジトリ連携」する方法は、Zenn公式サイトに記載されているのでそちらを参照すとして、「Qiita → Zenn に記事を移行」するとき Frontmatter の制約があるのでそこを気にする必要がある。

・[GitHubリポジトリでZennのコンテンツを管理する](https://zenn.dev/zenn/articles/connect-to-github)

# Frontmatter の制約
これだけ押さえておけば簡単に移行できる。あとはスクレイピングして多少整形してあげればよい。

| タグ | Qiita → Zenn |
|:-----------|:------------|
| title | title を設定, 70文字の制約あり、「":」はパースエラーになる |
| emoji | アイキャッチとして使われる絵文字 |
| type| "tech"固定でよい |
| topics | tags を設定 | 
| published | true |

# スクレイピングについて
やり方はどんな方法でもよいが、Qiitaの記事をごっそり移行するならslug値を取得した方が簡単。slug 値は、同じで管理していた方が後々便利そうなので同値にしておく。

Frontmatter の制約があるのでZenn側でデプロイに失敗したら適宜手修正する。


① [fkooo](https://qiita.com/fkooo) さん記事の「[Qiita API v2 を使って投稿一覧を取得する](https://qiita.com/fkooo/items/250f42a0b641fb96b5ff)」 の Python スクリプトで URL だけ取得するようにしておく。② slug 値だけを抜き出してファイルに保存。※下記コマンドで

```text
python Qiita.py | grep "https" | sed "s/^https:\/\/qiita.com\/murachi1208\/items\//$1/" >> Qiita.txt
```

④ 下記の PHP に ③で処理した「Qiita.txt」を読み込ませて Zennで表示できる mdファイルを作成する。

```php5
<?php
require_once('spyc.php');

$fh = fopen("Qiita.txt", "r");
while (($line = fgets($fh))) {
  $line = str_replace(array("\r\n","\r","\n"), '', $line);
  $tmp = qiita($line . ".md");
  $fw = fopen($line . ".md", "w");
  fwrite($fw, $tmp);
  fclose($fw);
}
fclose($fh);

function qiita($md) {
  $user = 'murachi1208';
  $html = file_get_contents("https://qiita.com/" . $user . "/items/" . $md . "", false);

  $position = strpos($html, '---',4);
  $yaml = substr($html, 0, $position + 3);
  $body = substr($html, $position + 3);

  print $md ."\r\n";
  $obj = Spyc::YAMLLoadString($yaml);

  $obj['emoji'] = '📝';
  $obj['type'] = 'tech';
  $obj['topics'] = $obj['tags'] ;
  $obj['published'] = 'true' ;

  //
  $ret = "";
  $ret = $ret .  '---' . PHP_EOL;
  $ret = $ret . 'title: "' . mb_strcut($obj['title'], 0, 70) . '"' . PHP_EOL ;
  $ret = $ret . 'emoji: "📝"' . PHP_EOL ;
  $ret = $ret . 'type: "tech"' . PHP_EOL ;
  $ret = $ret . 'topics: ' . $obj['topics'] . PHP_EOL ;
  $ret = $ret . 'published: true' . PHP_EOL ;
  $ret = $ret . '---' . PHP_EOL;
  $ret = $ret . $body;

  return $ret;
}
```

⑤ 作成されたファイルを ```articles/``` にコピーする。
※YAMLパースには、[spyc](https://blog.sus-happy.net/spyc-yaml) を使用しています。

# うまくいったのだろうか
とりあえず120投稿分を移行してみた。タイトルを"なろう風"にしていたのがダメでしたね。失敗ｗ

https://zenn.dev/murachi

# Qiita → Zenn 自動連係する？ あとZenn使ってみて
毎日投稿しているならまだしも、個人でメモ程度に月１あるかないかのペースなので適当に手動同期するのでいいかなと思いました。が、仕組みを作るのは面白いからそのうち簡単にできるようにするかも。

Zenn は、投げ銭とか、記事を売ったり Qitta と方向性は違うと思うが根本は同じかなと思います。技術のオープン化は必要と思いますが、苦労して調べたことがお金になるのもモチベーションアップになると思うしいいことだと考えますね。


# 参考サイト
・[Zenn CLIで記事・本を管理する方法](https://zenn.dev/zenn/articles/zenn-cli-guide)
・[GitHubリポジトリ連携を通して感じたZennの良さ](https://zenn.dev/unsoluble_sugar/articles/9c04a36a5decdb6d1b20)
・[Qiitaの記事をzennに移行したときにしたこと](https://zenn.dev/luna_chevalier/articles/ca9cb142a3111944f6af)
・[4ステップでGithubからZennに記事を公開してみる(トラブルシューティング付き)](https://zenn.dev/ohbashunsuke/articles/20200917001-deploy-with-github)
Flutterのパスを通す

初めてzshrcをいじって戸惑ったので書きました。
久しぶりにvi触ってi押し忘れて、ずっと上書きできなくて困って泣いてました。

```zsh
# 今どのシェルを使っているか調べる
% echo $SHELL
/bin/zsh

# zshの場合
# homeディレクトリでこうするか
vim .zshrc

# どこかでこうする
vi $HOME/.zshrc

# こんな感じで書く
export PATH="$PATH:/Users/user_name/development/flutter/bin"
```

### 参考にさせていただきました
[Flutterの環境構築\(Mac編\)｜KBOYのFlutter大学【基礎編】](https://zenn.dev/kboy/books/ca6a9c93fd23f3/viewer/5232dc#%E3%83%91%E3%82%B9%E3%82%92%E9%80%9A%E3%81%99)

[macOS install \- Flutter](https://flutter.dev/docs/get-started/install/macos#update-your-path)
React学習アウトプット（redux-operations）

今回のアウトプットは``redux``における``operations``になります。

operationsの役割としては、storeの情報を外部から取得した情報（APIとか）を元に変更する時に非同期処理で``async await``を使えるためにoperationsを行うらしいです。

方法としては簡単！

ただ無名関数を``return``すれば良いだけ！

以下コード例になります。

```javascript
import { signInAction } from './action'

export const signIn = () => {
  // 非同期処理の関数をリターン
  return async (dispatch, getState) => {
    await axios.get('https://api.github.com/users/aki-743').then((res) => {
      dispatch(signInAction({
        isSignedIn: true,
        username: res.login
      })
    }))
  }
}
```

このようにして非同期処理を実行しつつ、Storeの内容を変更することが可能。

ここらへんはVueと少し似ているところがあったので理解はし易かった。
【Git】リモートからローカルに取り込むコマンドまとめ

# 【masterに取り込み、更新】リモートのmasterが更新されたため、ローカルのmasterに単純に取り込みたい

```
[branch上]
$ git checkout master

[master上]
$ git fetch
$ git merge

[now:masterに更新かかった状態]

[その他]
$ git branch [新しいbranch切る]
$ git branch -D [先程までのいらないbranch]
```

#【master更新〜ブランチ取り込み】ブランチで開発中、リモートmasterに更新がかかった場合

```
[ブランチ上]
$ git stash

[master上]
$ git checkout master
$ git fetch
$ git merge
$ git checkout [先ほど作業していたブランチ名]

[ブランチ上]
$ git merge origin/master
$ git stash apply [先程、退避した履歴]
$ git stash drop [先程、退避した履歴]
```

##ローカルのmasterに更新をかける

- ```git stash```：変更の退避（addはしたけど、commitしてないもの）。commitしたくないけど、逃したい場合に有効。

【状態】
・ローカルのmasterと同じ状態
（master→ブランチに切り替えして、一度もcommitしていなければ）

- ```git checkout master```：
同じ状態にしてから、masterに切り替える。（そうでないと、ブランチの状態がそのままmasterに反映されるから。）

【状態】
・現在、ローカルのmasterにいます。

- ```git fetch``` ：もしくは、```git fetch origin master```。

ここでおさらい。

ここで出てくるmasterの種類は3種類。

>①（リモート）origin master
originというリモートブランチのmasterブランチ（デフォルトでは）

>②（ローカル）origin/master：
リモートmasterを追跡する、リモート追跡ブランチ。かつ、ローカルmasterの上流ブランチ。

>③（ローカル）master：
origin/masterを上流ブランチとする、作業ブランチ。

```git fetch```は①→②に取り込むコマンド。
あくまで、ローカルのブランチに引き出すだけ。書き換えられることはない。

【状態】
②（ローカル）origin/masterに、①（リモート）masterの更新がかかった

- ```git merge```：もしくは、``` もしくは git merge origin/master```

②→③に取り込むコマンド。

【状態】
③（ローカル）masterに、②（ローカル）origin/masterの更新がかかった。
（これで、masterのリモート〜作業ブランチまで全て同じ状態）

>※ git fetch と　git mergeを同時に行ったものが、git pullになります。
何をしているかわからずコマンドを打っている段階では、```git pull```は使わない方がいいですね。

##ローカルブランチに更新をかける

- ```git checkout [先ほど作業していたブランチ名]```：ブランチに、戻ります。

【状態】
・現在、ブランチに移動。ブランチの状態は、リモートのmasterを取り込む前のmasterの状態と同じ

- ```git merge origin/master```：すでに、fetchしてあるので、origin/masterをブランチにも取り込みます。

【状態】
・これで、ブランチも最新状態

- ```git stash apply [先程、退避した履歴]```：ここで先程退避した、ものを引っ張ってきます。
（```$ git stash list```で確認してください。）

【状態】
・ブランチは、最新の状態に、現在編集途中のものを取り込んだ状態になります。

- ```$ git stash drop [先程、退避した履歴]```：先程逃したものは必要ないので削除しておきます。

完成！！

#【ブランチ取り込みのみ】ブランチで開発中、リモートmasterに更新がかかって取り込みたい場合

```
$ git stash
$ git fetch
$ git merge もしくは git merge origin/master
$ git stash apply [先程、退避した履歴]
$ git stash drop [先程、退避した履歴]
```

上の説明と、同じなので省略。

#git pullについて

| コマンド  | 説明 |
| ---- | ---- |
| pull  |  fetch + merge |
| fetch | ダウンロード |
| push | アップロード |
| merge | リモートを、ローカルに合流（logに残しにくいが、初心者はコッチ）→checkoutはmaster |
| rebase | リモートを、ローカルに合流（logに残しやすいが、ミスしやすい）→checkoutは作業ブランチ |

#注意点
###①コミットが済んでいないのに、checkoutでブランチを切り替えるのはやめましょう。

なぜなら、（例）branch1→masterに切り替え

ブランチで更新した内容がそのままmasterに反映されるから。

###②編集途中の現branchから、別branchに切り替える時
→現branch内容が、別branchにも反映される

#参考
[【初心者向け】git fetch、git merge、git pullの違いについて](https://qiita.com/wann/items/688bc17460a457104d7d)

[【git stash】コミットはせずに変更を退避したいとき](https://qiita.com/chihiro/items/f373873d5c2dfbd03250)
【Ruby】コールスタックを調査したい時（デバック）

Rubyのコードを読んでいて、「これはどれから呼ばれているんだろう？」
と思ったときに良い方法があったので、忘備録として残しておく。

# 組み込み関数`caller`を使う
`caller`を使う事で呼び出し元の情報を文字列の配列として取得できる。


### サンプルプログラム(callstack_test.rb)

```ruby
class TestClass
  def foo
     bar
  end

  def bar
    baz
  end

  def baz
    puts caller(0)
  end
end

TestClass.new.foo
```

### rubyを実行
```
$ ruby callstack_test.rb
test.ruby:11:in `baz'
test.ruby:7:in `bar'
test.ruby:3:in `foo'
test.ruby:15:in `<main>'
```

`caller`の引数の指定によって、呼び出し元を変更できます。
(呼び出し元を含める場合は0を指定します。)
引数によって呼び出し元を変えることもできるが`0`と`1`以外はそんなに使わないと思う。

### caller(0)で実行（呼び出し元を含める）
```
test.ruby:11:in `baz'
test.ruby:7:in `bar'
test.ruby:3:in `foo'
test.ruby:15:in `<main>'
```

### caller(1)で実行（呼び出し元を含めない）
```
test.ruby:7:in `bar'
test.ruby:3:in `foo'
test.ruby:15:in `<main>'
```

### caller(2)で実行（引数によって呼び出し元を指定できる）
```
test.ruby:3:in `foo'
test.ruby:15:in `<main>'
```

# 参考文献
Ruby 2.5.0 リファレンスマニュアル 
https://rurema.clear-code.com/2.5.0/method/Kernel/m/caller.html
[Java]インクリメント・デクリメントについて

#### Javaのインクリメント・デクリメントについて

オペランド(演算の対象になる式のこと。以下iで示す。)を加算または減算するときに用いる。

- インクリメント
オペランドを1加算すること。
`i++`または`++i`のように記述する。意味としては、`i += 1`と同じ。
`i++`と`++i`の違いは、記述された部分の処理の前に加算するか、処理の後に加算するかの違い。

- デクリメント
オペランドを1減算すること。
`i--`または`--i`のように記述する。意味としては、`i -= 1`と同じ。
`i--`と`--i`の違いは、記述された部分の処理の前に減算するか、処理の後に減算するかの違い。


### 記述例
```java

//sample_code1
		int i = 8;
		System.out.println("インクリメントについて\n");

		System.out.println("後置のインクリメント:" + i++); //8と表示される。表示後、+1される。
		System.out.println("前置のインクリメント:" + ++i); //10と表示される。表示前に+1される。
		System.out.println("i += 1の場合:" + (i += 1)); //11と表示される。

		System.out.println("\n以下デクリメントについて\n");

		System.out.println("後置のデクリメント:" + i--); //10と表示される。
		System.out.println("前置のデクリメント:" + --i); //8と表示される。
		System.out.println("i -= 1の場合:" + (i -= 1)); //8と表示される。

```
AWS cognitoのEメールのカスタマイズ

#AWS CognitoのEメールのカスタマイズ
##概要

- AWS SESで特定のSESリージョンでメール認証する ※ドメイン認証は不要

- AWS CognitoのEメールカスタマイズから認証したメールアドレスを選択する

## AWS Cognitoで使えるSESリージョンを確認する
AWS cognito Eメールで設定できるSESリージョンは現時点(2021/03)で以下の3リージョンのみ

1. バージニア
1. オレゴン
1. アイルランドAWS 

Cognito>ユーザープール>メッセージのカスタマイズから選択できるSESリージョンが確認できる 
上記3つのどれかのリージョンで新しくメールの認証を行う

![2021-03-25-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/2e36664a-419d-0bcf-6414-d17db2af09c2.png)


## AWS SESによるメールアドレスの認証
メールアドレスの認証　※これは単なるAWS SESのメール認証の手順
AWS SESを開く対象のリージョンに変更する「Verify a New Email Address」を押下する

![2021-03-25-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/725fac2a-5663-004c-42a3-3dd00ff64035.png)

ポップアップが表示されるので認証したいメールアドレスを登録する 

![2021-03-25-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/6edc69b0-a115-6355-789a-495f5edd88ab.png)

メールを送信すると以下のメッセージが表示される
認証されるのに最大1時間ぐらいかかると。
私がこちらの作業を行った際は5，6分で認証はできました。

![2021-03-25-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/7e9fe3db-2889-961f-6d15-fb0859c14c4a.png)

 
このようなメッセージが認証に設定したメールアドレスに届く 

![2021-03-25-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/f65122e6-55fe-8679-ffcd-55ef18d0cd70.png)


このメールに入っている認証メールを押下すると現時点(2021/03)ではこちらの[サイト](https://aws.amazon.com/jp/ses/details/)に飛ばされます　※認証はされている
 
![2021-03-25-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/7d4a40b8-78d2-52f4-c743-7ccf655dd071.png)


AWS SESの画面で認証したメールアドレスを確認すると、
以下ののように認証されていることが確認できる。
Verification StatusがverifiedになっていればOK

![2021-03-25-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/539c23e4-76cd-96a0-aa3c-195d1f18f5db.png)

##AWS CognitoのEメールカスタマイズの画面でメールアドレスを選択
AWS Cognito側AWS cognitoのEメールカスタマイズの画面に戻ると、
認証したメールアドレスが選択肢に表示されることが確認できる。
![2021-03-25-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336049/27be8ef8-3ad7-6461-54e1-23f27857aa47.png)
スプレッド構文について

JavaScriptを触りはじめの時にスプレッド構文の理解をすることがとても苦手でした。
今でも完璧に理解できてはいないですが現段階で理解している部分を言語化してみたいと思います。
スプレッド構文の理解で苦しんでいる方の一助になれれば幸いです！

##スプレッド構文とは

```
スプレッド構文 (...) を使うと、配列式や文字列などの反復可能オブジェクトを、0 個以上の引数 (関数呼び出しの場合) や要素
(配列リテラルの場合) を期待された場所で展開したり、オブジェクト式を、0 個以上のキーと値のペア (オブジェクトリテラルの場合) 
を期待された場所で展開したりすることができます。
```
MDNによると上記のように定義されていました。
正直どういうことか理解するの難しいですよね...(私は全く理解できませんでした）
※MDN（https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax）

コードをみた方が理解できるかと思うので実際にコードと一緒に説明していきたいと思いますが、
ざっくりとした機能としては...（ピリオド３つ） を書くことで個々の値に展開ができ、それを順番に処理して結合させることができます。
※ちなみに「codesandbox」という手軽に環境構築などができるサイトがあるので、そちらで実際にコードを打ちながら試してみると理解度が上がるかもしれません。

###コードと一緒に解説

```
const arr1 = ["hoge", "foo"];
console.log(arr1);
//["hoge", "foo"]
//スプレッド構文を使ってこちらを展開してみます。
console.log(...arr1);
// hoge foo
//最初のコンソールでは配列で出力されてましたが、次のコンソールでは個々の値（hoge,foo）で出力されます。
```
上記のように配列の中身を順番に処理してくれます。
もう少し配列の例をあげてみます。

```
const sum = (x, y, z) => {
  console.log(x + y + z)
};
const num1 = 1;
const num2 = [2, 3];
sum(num1, ...num2)
//6
//スプレッド構文でnum2の要素を順番に設定しているので２、3が設定されています。
//なのでsum(1, 2, 3)と同じことをしている状態です。

```
※参照とコピーの違いについても解説したいのですが長くなってしまうので今回は省略します。

###最後に
スプレッド構文は私としてはかなり難しく感じました。色々とスプレッド構文で書いていくことで覚えられるようになると思うのでコードサンドボックスなどで是非試して見て欲しいです。
[Swift]分かりやすく解説するdelegate（デリゲート）

<h1>意味不明の代表格Delegate</h1>
Swiftをやる上で意味不明の代表格 **デリゲート**について解説します。
まずは今回のテスト環境から説明します。
構成はこんな感じ。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1276686/44616af4-3423-f5ff-f036-cb4c2a2145f2.png" width=50%>



デフォルトのMain.storuboardの初期画面にViewオブジェクトを追加。
その　ViewのクラスにCustomViewクラスを割り当てている。
CustomView.xivにはCustomView.swiftファイルが割り当てられている。

もちろん、Viewオブジェクトは、ViewController.swiftファイルから扱えるようにGUIで紐付けをして、
CustomView.swiftファイルにも,Buttomオブジェクトのタップを感知できるようにGUIで紐付けてある。


画面を見るとこんな感じ。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1276686/43f5f689-e2e7-d89a-fb5e-b0bb8648608c.png" width=50%>

ここで2つのSwiftファイルを見てみましょう。

**CustomView.swift**

```Swift
import UIKit

//①プロトコルを宣言
protocol testDelegate: class{
//②関数名と引数の型を定義
    func tappedSendButton(text: String)
}


class CustomView: UIView {
    var text = "これはCustomViewクラスのフィールド変数だよ"
    //②デリゲートを宣言
    weak var delegate: testDelegate?
    
//
    @IBAction func tappedtTestButton(_ sender: Any) {
        //④委任する関数を呼び出す。
        delegate?.tappedSendButton(text: text)
    }
    
//ここから下は、XivをViewに貼り付ける処理で今回のデリゲートの処理には関係ない
    override init(frame: CGRect){
        super.init(frame: frame)
        self.configureView()
    }
    
    required init?(coder: NSCoder){
        super.init(coder: coder)
        self.configureView()
    }
    
    private func configureView(){
        guard let view = self.loadViewFromNib(nibName:"CustomView") else {
            return
        }
        view.frame = self.bounds
        self.addSubview(view)
    }
    
}
```

ViewController.swift

```swift
import UIKit
//testDelegateプロトコルを継承
class ViewController: UIViewController, testDelegate {
            
    @IBOutlet weak var testView: CustomView!
    
　　 //④で呼び出された関数がViewControllerに委任されてるためtappedSendButton関数が呼び出される
    func tappedSendButton(text: String) {
        print(text)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        testViewオブジェクトの処理を自分自身（ViewController）に委任しますと宣言する。
        testView.delegate = self

    }


}
```

ボタンをタップすると

consoleに

**これはCustomViewクラスのフィールド変数だよ**
と表示される


<h2>デリゲートとはつまり</h2>

あるクラス（今回はController.swift）から、あるクラス（CustomView.swift）の関数を呼び出したい時に使う。
今回でいえば、ボタンがタップされたかどうかはCustomView.swiftでしか感知できないが、そこにデリゲートを追加してController.swiftに紐付いた関数を用意することでボタンがタップされた時に呼び出される関数から
ControllerクラスのtappedSendButtonを呼び出すと言うことになる。

```swift
@IBAction func tappedtTestButton(_ sender: Any) {
        //ControllerクラスのtappedSendButton関数を呼び出す。
        delegate?.tappedSendButton(text: text)
    }
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1276686/2fca9d43-9003-2728-9d8d-1ee5c51918fd.png" width=50%>

<h3>デリゲートのメリット<h3>

勘のいい人ならわかると思うがデリゲートも最大のメリットは

**クラス間で変数を自由に受け渡しができること**
**関数を呼ぶタイミングを任意のタイミングに調整できること**

だと思う。今回の場合で言えばもしCustomView.swiftで
テキストフィールドを持っていたら、ボタンが押された瞬間のテキストフィールドをViewControllerに送る事ができる。
しかも、ボタンが押された瞬間と言う任意のタイミングで。

<h3>まとめ<h3>
デリゲートとは関数の処理を他のクラスの関数に委任することなんだな。
書き方についてはこう言う風に書くんだな。と覚えましょう。

（書き方が難しすぎるからややこしくなってるだけ）
ウェブ入門

# はじめに
初めまして、@takashi_sakamotoです。
現在Webアプリの開発を行ってますがWebの仕組みがよくわかっていないので、改めて情報を漁ってまとめてみました。
ゴールは、Webの仕組みがなんとなくわかったなぁーというレベルです。

## Webの仕組み
パソコンや携帯で情報を調べる際にWebブラウザで「yahoo」などを入力して検索すると思います。
裏側で何が行われているかざっくりベースですが、まとめていきます。

### クライアントとサーバー
様々な情報があるインターネットから情報をとってくる際に以下のように設定することができます。
* クライアント・・・PC、携帯の装置上に情報を表示する道具であるブラウザ(Chrome、firfoxなど)のこと。情報を取得して表現する。
* サーバー・・・Webページなどの情報を保存しているコンピュータのことです。


### ブラウザ表示の仕組み
1. ブラウザ(クライアント)はサーバ(DNS)にアクセスし、Web サイトのあるサーバの実際のアドレスを探し、情報の場所(IPアドレス)を引き当てます。
1. ブラウザは情報が保存しているサーバーに、ほしい情報をリクエスト(URI(URL))を投げて指定します。
1. サーバーは「Webサイトみてもいいですよー」ということで、Webサイトのファイル(HTML、CSS、JavaScriptなど)を送り返します。
1. ブラウザは受け取ったWebページ(HTML、CSS、JavaScriptなど)などをブラウザ上に表現し表示します。

##まとめ
* Webは受け取った情報を表示するクライアントとWebサイトなどの情報が保存されているサーバーによって、やり取りされている
* サーバー内のファイルであるWebサイトはHTML、CSS、JavaScriptなどが保存されており、クライアントは受け取ったファイルを組み合わせて表現している

###関連記事
* [Web のしくみ](https://developer.mozilla.org/ja/docs/Learn/Getting_started_with_the_web/How_the_Web_works)
BitbucketでSouceTreeのインストールをする

###注意
メモ程度の内容の薄い記事です。手順くらいしか乗ってません。
BitbucketとSouceTreeでインストールをする方法です。
Gitからもできるみたいですが、おいおい試せたら追記します。

#Bitbucketでの手順
準備
・Bitbucketのアカウントを持っていること。なければ作成する。

1. 自分のアカウントでBitbucketにログインし、「Create Repository」を押す。
2. リポジトリを作成する。

#SouceTreeでの手順
準備
・SouceTreeのソフトをダウンロードしておく。(Macの人はここ→https://www.sourcetreeapp.com/)
・アカウントが必要になると思うので、Bitbucketのアカウントを用意する。

1. SourceTreeのインストールが終わったら、インストールポップアップが出る（画像撮り忘れた）
2. 現時点(2021/04/11)のバージョンでは、「Bitbucket クラウド」と「Bitbucket サーバ」のどちらかのアカウントを使うか求められる。
サーバの方は詳しくわからないが、通常のBitbucketアカウントの場合は「Bitbucket クラウド」を選択。登録がある場合はすぐにアカウントを取得し、次のステップに移る。
3. 「GitとMercurialアカウント」がどうのこうのと言われるが、なければ無視でOK
4. 設定完了後、SourceTreeが開く。URLからクローンするかBitbucketで作ったリポジトリが表示されているので選択すかのどちらかでリポジトリを取得できる。 

画像とるの本当に忘れててすみません。
tailwindcssで横スクロール

# 概要

tailwindcssで横スクロールを実装する

# 実装

```html
<div class="flex overflow-x-auto">
  <div class="flex-none w-10">
  </div>
</div>
```

- `overflow-x-auto`は横方向に伸びていく
    - https://tailwindcss.com/docs/overflow#class-reference
- flex-noneで横幅の伸縮をoffにしている
    - https://developer.mozilla.org/ja/docs/Web/CSS/flex
Skypeの履歴 'messages.json' をPythonでいい感じに出力する

Skypeの履歴を出力したいと思いましたが、
アプリからまとめてコピペができなかったので
こちらのページから履歴をダウンロードしました。

[ファイルとチャット履歴のコピーの要求](https://secure.skype.com/ja/data-export)

ダウンロードできたのは'messages.json' 
`エクスポート用のメッセージ ビューアー`で見るといいらしいのですが
ダウンロードできませんでした。macには対応していないのかな？

そこで、pythonで読みやすく出力してみました。

```skype2txt.py
import json

# jsonファイル読み込み
json_open = open('messages.json', 'r')
json_load = json.load(json_open)

#ざっくり確認
#print(json_load)

# conversationsから印刷したいスレッドを探す
df = pd.json_normalize(json_load,record_path='conversations')

# 印刷したいスレッドを指定
df1 = df.iloc[1]
df2 = pd.json_normalize(df1['MessageList'])
#df2.head(1)

# idがUNIX時間なので、ソートして変換
df2 = df2.sort_values(by="id")
df2['timestamp'] = df2['id'].astype(int)/1000
df2['timestamp'] = pd.to_datetime(df2['timestamp'].astype(int), unit='s')
```

# 画面で確認する

```skype2txt.py
for index, row in df2.iterrows():
    print()
    print(row['timestamp'])
    print(row['displayName'])
    print(row['content'])
```

#印刷して確認する

```
f = open('skype.txt', 'w', encoding='UTF-8')
for index, row in df2.iterrows():
    f.write('')
    f.write(row['timestamp'])
    f.write(row['displayName'])
    f.write(row['content'])
f.close() 
```
残念、印刷すると改行がうまく反映されない。

とりあえず、ざっくり見渡すのはこれでよさそうです。
PORTが既に使用されているときに使うコマンド

# はじめに
# 今回のケース
使用言語：Java
使用フレームワーク：SpringBoot
エラー文：
![スクリーンショット 2021-04-11 11.13.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340562/c63c3bcf-96cd-f689-95ea-210c86d4b1bf.png)

問題：
ポート８０８０が既に使われている。
対策：
使用状況を確認し、不要なプロセスな場合プロセスを終了させる。

# 該当PORTを使用しているプロセスを特定

```terminal
$ sudo lsof -i:8080
COMMAND   PID        USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
java    38534 　　userName   43u  IPv6 0xa0f58e4315acc383      0t0  TCP *:http-alt (LISTEN)
```
# プロセスを削除

```terminal
$ sudo kill PID
```
Chrome で username がオートフィルされて困った件

# 困った
username でない入力欄に Chrome に保存した ID がオートフィルされてしまい、困った。

# 調べた

https://momdo.github.io/html/form-control-infrastructure.html#autofill-processing-model

上記 §4.10.18.7.2 (Processing model） の末尾：

> ユーザーエージェントは、ユーザーが要素のオートフィルフィールド名を上書き可能にしてもよい。

| フォームのコントロール | New autofill field name |
|-----|:---|
| an input element whose type attribute is in the Text state that is followed by an input element whose type attribute is in the Password state | "username" |

つまり、当該の input は、password の直前にあったので、username とという名前に補正されたようだ。
なお、password 欄の記述はポップアップ用なので、問題の input と同時に表示されることはなく、謎に見えたという顛末。
Railsのコントローラーでインスタンス変数を使う時

初歩的なことですので
[こちら](https://teratail.com/questions/99281)に書いてありましたので抜粋します

- メソッド間でのデータの受け渡し(典型的には、before_actionでデータをロードしておくとか)
- ビューへのデータの受け渡し

newアクションとcreateアクションでインスタンス変数(@item)を定義

```ruby
  def new
    @item = Item.new
  end

  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to root_path
    else
      render :new
    end
  end
```
これをform_withの引数へ受け渡す

```html
<h2 class="items-sell-title">商品の情報を入力</h2>
    <%= form_with model: @item, url: items_path, local: true do |f| %>
```

フォームで入力されたデータをcreateアクションで生成、保存する
レガシーコード改善ガイド 20章 このクラスは大きすぎてもうこれ以上大きくしたくありません

# 前提
レガシーコード改善ガイドのoutputを章ごとにやってます。
自分のoutputとある程度の人に伝わったらラッキー程度の考えを前提にしているので、分かりやすい記事ではないです。
イラストもないので、完全に理解したい人は書籍を読みましょう。

# 概要
肥大化したクラスは単一責務の原則に基づいてクラスの分割を行う必要がある。その時は機能スケッチを用いて、見える化することで分割が容易になる。依存関係が強く分割することが困難なクラスの場合はまず、インターフェースの分離を行い、クラス間の依存関係を軽減してリファクタを行いましょう。


# 説明
実装しているとついつい、既存のクラスに関数を追加してしまいたくなる。もしくは自分以外の誰かがこういうことをして、肥大化し複数責務を請負ったクラスをみたことがあるのではないか？そのときに振り返るべきのが原則。
オブジェクト思考のクラス設計の原則はやはりSOLID原則

- Single Responsibility Principle：単一責務の原則
- Open/closed principle：オープン/クロースドの原則
- Liskov substitution principle：リスコフの置換原則
- Interface segregation principle：インターフェース分離の原則
- Dependency inversion principle：依存性逆転の原則

リファクタをする指針としては、この単一責務の原則にそっているのか？を判別軸にして、単一責務でなければリファクタをする。
その際の単一責務かどうかを判別するにはテストがしやすいか？一文で名言化できるか？で単一責務であるかどうかがわかる。
両方の判別方法にクリアすれば問題ない。クリアしなかった場合、リファクタを進める。
リファクタをするにあたり、どのようなクラスに分割すれば良いのか？を考える。その時の手法が

- 関数名を参照して、同様の名前がついている関数だけをまとめ上げて別クラスに移動する。
- 変数と関数の関係性をイラストで表現する機能スケッチを行い、同じ処理をしているものたちだけまとめあげてクラスを移動する。

である。機能スケッチとは、どの関数が何を利用していて、どのような関係性なのかをぱっと見で把握しやすくし、別クラスに移動できそうな関数・変数群を識別するための手法である。作成するには、まず変数一式を一列に書き出す。それにたいして関数を一つずつ追記し、追記した関数が利用している変数もしくは別の関数に対して矢印を記載する。これにより変数・関数同士の依存関係がぱっと見でわかるようになる。
この依存関係にのっとって、別クラスに分割できそうなものは分割する。分割した結果、相互に利用がしづらくなった場合は依存の関係性を変えたりすることで改善が可能になるケースもある。
また、依存関係が多く、改善が容易でない場合インターフェース分離の原則に則り、クラス間の依存度を軽減する。

# リファクタを実施するにあたり
前提として、現在の構成でもアプリケーションは安定稼働していることを認識し、またリファクタでテストを以下に追加したとしてもリファクタ直後は不安定になることを認識しましょう。それでもリファクタをした方が、今後のコストが回収できるのであればリファクタを実施しましょう。
権限確認linuxコマンドメモ

タイトルの通り、権限確認用のLinuxコマンドのメモです。

現在のディレクトリ配下の権限確認

```
ls -l
```

現在のディレクトリ配下の権限確認（隠しファイル含めた全て）

```
ls -al
```

指定したファイル、ディレクトリの権限確認

```
ls -l | grep ファイル、ディレクトリ名
```
deck.glのTile3dLayerでPLATEAUの3D都市モデルを表示してみた

## はじめに

今話題の[PLATEAU](https://www.mlit.go.jp/plateau/)のデータをdeck.gl+Mapbox GL JSで表示してみるぞ！

## Tile3dLayer

みんな大好きdeck.glに[Tile3dLayer](https://deck.gl/docs/api-reference/geo-layers/tile-3d-layer)というクラスがあり、これはいわゆる3d-tilesを読むためのレイヤーです。

点群でも3Dモデルでも、3d-tilesならこのレイヤーで表示する事が出来ます（一応``Experimental``です）。以下のように定義します。

```javascript:

import { Tile3DLayer } from '@deck.gl/geo-layers';
import { Tiles3DLoader } from '@loaders.gl/3d-tiles';

const tile3dLayer = new Tile3DLayer({
    id: 'tile3dlayer',
    pointSize: 1,
    data: 'https://s3-ap-northeast-1.amazonaws.com/3dimension.jp/13000_tokyo-egm96/13101_chiyoda-ku_notexture/tileset.json', // PLATEAU千代田区
    loader: Tiles3DLoader,
    onTilesetLoad: (tileset) => {
        const { cartographicCenter } = tileset;
        const [longitude, latitude] = cartographicCenter;
        console.log(longitude, latitude); // 3dtilesの中心座標を取れるぞ
    },
});
```

## Mapbox GL JS上に表示してみる

deck.glレイヤーをMapbox GL JS上で表示する手法は[https://deck.gl/docs/api-reference/mapbox/mapbox-layer](https://deck.gl/docs/api-reference/mapbox/mapbox-layer)を見ればわかります。

![スクリーンショット 2021-04-11 10.42.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/f6414038-7703-e73e-53e7-c52e2f7700b9.png)

表示は出来ましたがなんかモデルが宙に浮いています（静止画像なのでわかりにくいですがかなり浮いています）。

## モデルが浮く問題

PLATEAU-Viewをみてみると、モデルは標高とリンクしている事がわかります。おそらく標高と建物は同時に計測されているのかと思われます。

![スクリーンショット 2021-04-11 10.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/f86f1ce7-3253-cf4d-0f7f-50d7b66c6a1b.png)

Mapbox GL JSは基本的に平面地図で標高はゼロです（v2なら3D表現ができるが…）。仮に3Dだとしても、PLATEAUで使われている標高データは<b>すぐウェブで使える形式では</b>公開されていないので、やはり基準の標高値がゼロでも、マシな見た目にする事を考えた方がいいでしょう。つまり全体の高度を一律に下げる事を考えます。

> 標高データはCityGMLで公開されていて中身をみる限りTINなので、何かしらウェブで使える標高データに変換する方法はあるでしょう

## 高度を調整してみた

さっきの``tile3dLayer``にオプションを追加します。

```javascript

import { Tile3DLayer } from '@deck.gl/geo-layers';
import { Tiles3DLoader } from '@loaders.gl/3d-tiles';
import { Vector3 } from 'math.gl';

const tile3dLayer = new Tile3DLayer({
    id: 'tile3dlayer',
    pointSize: 1,
    data: 'https://s3-ap-northeast-1.amazonaws.com/3dimension.jp/13000_tokyo-egm96/13101_chiyoda-ku_notexture/tileset.json',
    loader: Tiles3DLoader,
    onTilesetLoad: (tileset) => {
        const { cartographicCenter } = tileset;
        const [longitude, latitude] = cartographicCenter;
        console.log(longitude, latitude);
    },
    onTileLoad: (tileHeader) => {
        tileHeader.content.cartographicOrigin = new Vector3(
            tileHeader.content.cartographicOrigin.x,
            tileHeader.content.cartographicOrigin.y,
            tileHeader.content.cartographicOrigin.z - 40,
        );
    },
});
```

タイル単位で保持しているらしい基準標高値を、一律40m下げました。

![スクリーンショット 2021-04-11 10.49.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/3be03bf4-8d5e-7656-cf31-a44770705ebc.png)

さっきよりも地に足のついた見た目になりましたね。

## 終わりに

3Dデータを表示するなら素直にCesium使っておいた方が良い気がしていますが、ベクタータイルや2D地図表現はやはりMapbox GL JSの強みだと思います（最近では3D地形も表示出来ますし…）。
[Ruby] eachとmapの違い


eachとmapの違いについてまとめました．
#each
繰り返し処理を行う際に使用する．ただ，戻り値は繰り返し処理の前の値となる．

###使用例
```
array = [1, 5]
array.each do |item|
  item * 2
end
2
10
=> [1, 5]
```

#map
繰り返し処理の結果を配列として保持したい場合に使用する．

###使用例
```
array = [1, 5]
result = array.map do |item|
  item * 2
end
=>[2, 10]
```

#mapをeachに書き換える方法
```
array = [1, 5]
result = []
array.each do |item|
  result << item * 2
end
=>[2, 10]
```

上記のように書き換えるとeachでmapと同じ処理を実行することができるようになる．
しかし，mapに比べると記述量が多くなってしまうので，繰り返し処理の結果を使用する際はmapで記述するようにする．

#参考リンク
[【Ruby】eachとmapの違い](https://qiita.com/massaaaaan/items/d90d10cb023bedc74fb2)
初心者向け rails db:migrateのエラー

## 開発環境
・Mac OS　Big Sur 11.2
・Ruby 2.6.5
・Rails 6.0.0

## エラーの状況 
アイディアを管理するためのAPIを、railsを用いて作成。
ideasテーブル、categoriesテーブルを作成し、rails db:migrateコマンドを実行した結果、以下のようなエラーが出ました。

```
== 20210411003522 CreateIdeas: migrating ======================================
-- create_table(:ideas)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'category_app_development.categories' doesn't exist
```
エラー内容を見ると、"Mysql2::Error: Table 'category_app_development.categories' doesn't exist"
とあり、categoriesテーブルが存在しない、と指摘されています。

ideasテーブル、categoriesテーブルをそれぞれ見てみます。

```20210411003529_create_categories.rb
class CreateCategories < ActiveRecord::Migration[6.0]
  def change
    create_table :categories do |t|
      t.string :name, null: false
      t.timestamps
    end
  end
end
```

```20210411003522_create_ideas.rb
class CreateIdeas < ActiveRecord::Migration[6.0]
  def change
    create_table :ideas do |t|
      t.references :category,  foreign_key: true
      t.text :body,            null: false
      t.timestamps
    end
  end
end
```

 ideasテーブルに、"t.references :category,  foreign_key: true" とあるように、ideasテーブルは外部キーとしてcategoriesテーブルを参照しています。categoriesテーブルが親テーブル、ideasテーブルが子テーブルという関係です。
外部キー制約を設定する場合、外部キーの対応するデータが必ず存在しなくてはいけません。
外部キー制約とは、「他のテーブルのデータに参照（依存）するようにカラムに付ける制約」だからです。
ところが、今回のやり方だとcategoriesテーブルとideasテーブルを同時にmigrateしてしまい、本来なら先に作成されているべき親テーブルであるcategoriesテーブルが存在しない、といったエラーが出ていたのです。

## 解決方法
rails d model ideaコマンドで、ideaモデルとテーブルを一旦削除。
その後、rails db:migrateを実行し、まずはcategoriesテーブルを作成します。
そして、ideasモデルとテーブルを再度作成し、rails db:migrateを実行するとideasテーブルも無事に作成できました。

## まとめ
外部キー制約は、親テーブルに存在しないデータを子テーブルに登録させないためのツールですので、テーブルを作成する時にも、まずは親テーブルを作成してから子テーブルの作成をするように気をつけたいです。
ブログでSEO対策やってます

ブログでSEO対策やってます!
https://zawablog555.com/

[blog-2355684_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1305138/c09209cb-40e3-3d4e-73a5-c7590c829768.jpeg)
Pulp - Ubuntuで自分で用意したCBCソルバーを利用する

Google Colaboratory環境などを想定

## ソルバーを入手
<a href="https://bintray.com/coin-or/download/Cbc/master#files">ここ</a>の「Cbc-master-bionic-linux-x86_64-gcc7.tgz」をダウンロード。
解凍して任意のディレクトリに配置。
解凍先ディレクトリの``` /bin/cbc ```が実行するソルバーファイルとなる。

## パスを通す
```python
import sys
sys.path.append('保存場所/bin/')
```
###　設定ファイルを更新
パスを通す代わりに、ソルバーの設定ファイルを編集しても良い。
```pulp.__path__``` を実行し、設定ファイルのパスを確認。
設定ファイルのディレクトにある``` pulp.cfg.linux ``` を開き 
``` CbcPath = ```に、上記で配置した``` /bin/cbc ```のパスを設定。
Google Claboratory上で実行する場合はエラーの元になるので、
パスを通すやり方を推奨。

## 実行

```pulp.COIN_CMD``` にて実行されるソルバーが変更される。
マルチスレッド対応しているので、``` threads ```に適切なスレッド数を設定することで高速化が期待される。
※設定スレッド数を増やすことで逆に計算時間が増えることも有る。

```python:ソルバー指定の例
solver = pulp.COIN_CMD(threads=2, timeLimit=1800)
```
migrateに何度か失敗したあと、勝手にmigirationファイルができたと思い込みファイルを削除してしまった

migrationファイルを削除する経緯
-
sqlにきちんと命名してカラムを作成しようとしていました。
名前の読みがなカラムを「last_name_pronounciation」と命名してテーブルを作ろうとすると

```terminal:terminal
Mysql2::Error: Specified key was too long; max key length is 767 bytes
```

と怒られました。（名前が長すぎるようです）

何度か試しているうちに↑（上）矢印キーで過去に入力したコマンドを呼び出していたようで
勝手にmigrationファイルを作ってしまっていました。

```terminal:terminal
maedatakuo@maedatakudainoMacBook-Air furima-32844 % rails g devise user
Running via Spring preloader in process 19160
      invoke  active_record
      create    db/migrate/20210409083100_add_devise_to_users.rb
File unchanged! The supplied flag value not found!    app/models/user.rb
```

勝手にできているのだからと思い考えもせず追加migrationファイルを削除して、
続きでカラム名を考えながらテーブル構築していました（２度かdb:resetもしました）

ようやく名前が決まって最終的にmigrateする段階でmigrationファイルをdownしようとrollbackしたら

```terminal:terminal
================================
-- remove_index(:users, {:column=>:reset_password_token})
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
```

migrationはキャンセルされましたとターミナルから言われました。
db:migrate:statusでmigrationのファイルの状態を調べてみると


```terraform:terminal
database: furima_32844_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     000             ********** NO FILE **********
   up     20210409081355  Devise create users
```

MigrationIDが書いてあれば仮ファイルを手作業で複製して通常通り手順に戻ってファイルを削除するのですが、

対処法
-
db:migrate:reset
再度テーブルをdelite、createし、migrationファイルも作成してくれるコマンドを実行して新しい名前のカラム作成に成功しました。

参考：削除ファイルのMigrationIDが残っていた場合
-
もし削除ファイルのMigrationIDが000でなくきちんと数値として残っていた場合の対処法

①手作業でmigrationファイルを作成する
②通常の手順に戻ってファイルをrollbackし、ファイルをdownした状態で削除する

①のみ解説します。（②は通常の作業のため割愛）
１）db:migrate:statusを実行
２）削除された（NO FILE）ファイルのMigrationIDをコピー
３）db/migrateフォルダ内に
先ほどコピーしたMigrationIDを使って「20210409081355sample.rb」（＊sampleは勝手に考えて入れています）
を作成
４）ファイルの中身ですが

```rb:MigrationID_sample.rb
class Sample < ActiveRecord::Migration[6.0]
  def change
  end
end
```
をコピーしてお使いください。
【Rails】Useridがnilになったとき

#環境
Rails 6.1.3.1
Ruby 3.0.0
MySQL 8.0.23

#エラー内容
Rails consoleで新しいユーザーを作成したときのこと、

```ruby
irb(main):001:0> User.create(name: "hogege",email: "hoge@hoge",password: "password",password_confirmation: "password")
  TRANSACTION (0.2ms)  BEGIN
  User Exists? (0.7ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'hoge@hoge' LIMIT 1
  TRANSACTION (0.2ms)  ROLLBACK
=> #<User id: nil, name: "hogege", email: "hoge@hoge", created_at: nil, updated_at: nil, password_digest: [FILTERED]>
```
Userid, created_at, update_atがnilになってしまいました

```
+-----------------+--------------+------+-----+---------+----------------+
| Field           | Type         | Null | Key | Default | Extra          |
+-----------------+--------------+------+-----+---------+----------------+
| id              | bigint       | NO   | PRI | NULL    | auto_increment |
| name            | varchar(255) | YES  |     | NULL    |                |
| email           | varchar(255) | YES  | UNI | NULL    |                |
| created_at      | datetime(6)  | NO   |     | NULL    |                |
| updated_at      | datetime(6)  | NO   |     | NULL    |                |
| password_digest | varchar(255) | YES  |     | NULL    |                |
+-----------------+--------------+------+-----+---------+----------------+
```
確認してみても、idはauto_increaseになっているので、`create!`を使ってみる

```ruby
irb(main):002:0> User.create!(name: "hogege",email: "hoge@hoge",password: "password",password_confirmation: "password")
  TRANSACTION (6.7ms)  BEGIN
  User Exists? (4.3ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'hoge2@hoge' LIMIT 1
  TRANSACTION (1.9ms)  ROLLBACK
Traceback (most recent call last):
        1: from (irb):7:in `<main>'
ActiveRecord::RecordInvalid (Validation failed: Email is invalid)
```

なんてことはない話でした。emailの形式が間違っていました、、、

```ruby
irb(main):008:0> User.create(name: "hogege2",email: "hoge2@hoge.com",password: "password",password_confirmation: "password")
  TRANSACTION (0.2ms)  BEGIN
  User Exists? (1.5ms)  SELECT 1 AS one FROM `users` WHERE `users`.`email` = 'hoge2@hoge.com' LIMIT 1
  User Create (1.5ms)  INSERT INTO `users` (`name`, `email`, `created_at`, `updated_at`, `password_digest`) VALUES ('hogege2', 'hoge2@hoge.com', '2021-04-11 00:45:14.108385', '2021-04-11 00:45:14.108385', '$2a$12$g5Ks0L4Eiw.QotTeTzt2ieBsTNKBbrpJiNtb6C/JxERBqmus7UD7q')
  TRANSACTION (1.9ms)  COMMIT
=> #<User id: 1, name: "hogege2", email: "hoge2@hoge.com", created_at: "2021-04-11 00:45:14.108385000 +0000", updated_at: "2021-04-11 00:45:14.108385000 +0000", password_digest: [FILTERED]>
```
無事成功！

#まとめ
`create`  失敗しているときは何も教えてくれず終わり
`create!` エラー内容を教えてくれる
box-shadowを用いてクリックするとボタンが凹むようにする

## 実現したいこと

動画見たく、クリックするとボタンが凹むような挙動にしたい。
![recommends-8-1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/f301d759-e71d-e666-f0f9-5d66b86e3656.gif)

## 結論

以下の2つをやります

- hover要素でbox-shadowを付与
- active要素でbox-shadowを削除。margin-topを付与

## コード

こんな感じになります。

```css
    a {
      display: inline-block;
      text-decoration: none;
      background-color: #0ACC64;
      color: #FFF;
      border-style: none;
      border-radius: 5px;
      padding: 5px 10px;
    }

    a:hover {
      cursor: pointer;
      font-weight: bold;
      box-shadow: 0 5px 10px black;
    }

    a:active {
      box-shadow: 0 0 5px black;
      margin-top: 5px;
    
```



## ポイント

active要素でmargin-topを付与する。これをやらないと以下のようになる。影はなくなっているけど、ボタンが凹んでいる感じがしない。
![recommends-8-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/6dccb745-ce70-0273-1c19-57db27c4dd52.gif)


これを解決するために、margin-topを付与する。margin-topのpxはbox-shadowの2番目の値(上下方向の影のpx)に合わせる。こうすると影がなくなるだけでなくボタンが凹んでいる風の挙動になる。
データカタログの業界標準化

国が主導し、業界全体もしくは各業界に適したデータカタログの定義を行っている。
・データカタログ作成ガイドライン
(一般社団法人データ流通推進協議会(現在はデータ社会推進協議会に名称変更))
https://www.google.com/url?sa=t&source=web&rct=j&url=https://data-trading.org/2019/02/20/%25E3%2583%2587%25E3%2583%25BC%25E3%2582%25BF%25E3%2582%25AB%25E3%2582%25BF%25E3%2583%25AD%25E3%2582%25B0%25E4%25BD%259C%25E6%2588%2590%25E3%2582%25AC%25E3%2582%25A4%25E3%2583%2589%25E3%2583%25A9%25E3%2582%25A4%25E3%2583%25Bww3v1-1%25EF%25BC%2588%25E4%25B8%25AD%25E9%2596%2593%25E3%2581%25A8%25E3%2582%258A%25E3%2581%25BE/&ved=2ahUKEwj_4dKy-fTvAhVF7GEKHT4LC1oQFjAAegQIBBAC&usg=AOvVaw3J-G2oKkwhCHSvD8g3GPN4

https://data-society-alliance.org/data-ex/
ActionTextを使うときにユーザー情報の関連づけで詰まった話

Rails6から出てきたActionTextというかんたんにブログ投稿ができるようになる機能があるのですが、これらを使うときにエラーになってしまったので共有します。

まずやりたかったこととしては、ユーザーの情報とこのブログの情報を関連づけさせたかったのですが、それらをするときにエラーになってしまいました。

しかし以下のようなエラーが出ました。

```
Mysql2::Error: Field 'user_id' doesn't have a default value
```
というエラーが投稿ボタンを押して投稿しよようとしたときに出てきました。
どうしてかというとマイグレーションファイルにある記述に問題がありました。
今回結構参考になると思います。

##まずActionTextとはなにか

ActionTextとは何かというとかんたんにブログなどの長文のコンテンツを書くことができるものです。
全然違いますがはてなブログさんのようにブラウザ上でブログを書くことができます。

詳しい使い方はググってください、今回は私がどうしてミスったのかそこだけを解説していきます

まずActionTextを使うとマイグレーションファイルが生成されます

・ ブログ投稿に関するマイグレーションファイル
・ActionTextに関するマイグレーションファイル
今回のActionTextには画像投稿ができるのできるようにするための
・Active Storageのマイグレーションファイル

以上の3つが生成されます。
そして今回何故ミスったかというと、ブログ投稿に関するマイグレーションファイルには

```
      t.references :user, null: false, foreign_key: true
```

と記述してユーザーの情報を引っ張ってこようとしても何も問題はないのですが、ActionTextに関するマイグレーションファイルにその記述を書いてしまうとActionTextそのものにもユーザー情報が渡されないといけなくなってしまいます。

しかし今回投稿をする際にはブログ投稿の部分のカラムにはきちんと渡されるのですが、ActionTextの部分に関するテーブルにはユーザー情報行きません。
なので一番最初に出たようなエラーになってしまうわけです。

みなさんも是非気をつけてくだい。
useStateで定義した配列内のオブジェクトの値を変更する

## はじめに
今回アプリを作成中useStateをオブジェクトにして複数のキーを持たせていたのですが、そのうち一つの値を変更するにはどうしたらいいのかというところでかなり苦戦したので自分の備忘録として記事にして残すことにしました。

## 状況

ここはとあるバー、useStateでの話です。
お客さんをid等で管理して、未成年はadult = falseとして
お酒を出さないようにしていました。

ある日、一人の若い青年が日付が変わった頃に入店しました。
バーテンダーはその顔に見覚えがありました。
バーの常連、喜一郎おじいちゃんの孫、太郎君です。

しかし彼は未成年だったはず、今日はどうしたのだろう？

カウンター席に座った太郎くんに今日はどうしたの？と話しかけます。

すると、ついさっき２０歳になったからここのお酒を飲みたいというのです。

なるほど、日付が変わってすぐにここに来たのはそういうことか！

そんなにお酒を飲んでみたかったのか、そう思うととてもほっこりしました。

さっそくadult = trueにしてお酒を出そうと思います。

```
  const [customer, setCustomer] = useState([
    ~
    { id:154, name: "田中　喜一郎", adult: true },
    ~
    { id:16325, name: "田中　太郎", adult: false },
    ~
  ]);
```

この時、idを引数にして、adultを変更するための関数を作成します。

```
const changeAdult = (id) => {
    setCustomer(
      customer.map((c) => {
        if (c.id === id) {
          return { ...c, adult: !c.adult };
        } else {
          return c;
        }
      })
    );
}
```

あとは、buttonのonClickにこの関数を指定してあげれば
大丈夫です！

```
<button onClick={() => changeAdult(c.id)}>
大人の階段
</button>
```

無事大人になった太郎くんは、初めてのお酒を美味しそうに飲んでいました。

また今度お爺ちゃんと飲みに来るそうです。

完
Python3: ファイルのアップロード (cgi)

jQuery を使わないで Python3 の cgi でファイルをアップロードする方法です。
複数のファイルを同時にアップロードできます。
![upload_python.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/2bcce858-c39b-dc49-92e2-e9006bb2d04f.png)


```html:upload_python.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>upload python (Apr/11/2021)</title>
</head>
<body>
<h2>HTML5</h2>
<form method="post" action="upload_python.py" enctype="multipart/form-data">
<input type="file" name="files"  multiple>
<p><input type="submit" value="送信する"></p>
</form>

<blockquote>
<p>File is uploaded to /tmp.</p>
</blockquote>
<hr />
Nginx<br />
<blockquote>
	<pre>
	server {
		client_max_body_size 20M;
	</pre>
</blockquote>
<hr />
Apr/11/2021 AM 08:25<p />
</body>
</html>
```

```py:upload_python.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
#
#	upload_python/upload_python.py
#
#					Apr/11/2021
#
# --------------------------------------------------------------------
import os
import sys
import cgi
#
# --------------------------------------------------------------------
def single_upload_file_proc(upload_dir,item):
	filename = item.filename
	try:
		path = os.path.join(upload_dir,os.path.basename(filename))
		chunk = item.file.read()
		if chunk:
			fout = open(path,mode='wb')
			fout.write(chunk)
			print(filename + "<br />")
			fout.close()
			os.chmod(path, 0o666)
	except Exception as ee:
		print("*** error *** single_upload_file_proc ***<br />")
		print(filename + "<br />")
		print(str (ee))
		print("<br />")
# --------------------------------------------------------------------
def multi_uploaded_file_proc(upload_dir,fileitem):
#
	for item in fileitem:
		single_upload_file_proc(upload_dir,item)
#
# --------------------------------------------------------------------
upload_dir = "/tmp"
#
print("Content-Type: text/html")
print("")

form = cgi.FieldStorage()
if "files" in form:
	fileitem = form["files"]
	print(isinstance (fileitem,list))
	print("<br />")
	if (isinstance(fileitem,list)):
		multi_uploaded_file_proc(upload_dir,fileitem)
	else:
		single_upload_file_proc(upload_dir,fileitem)
else:
	print("*** Select files ***<br />")

print("*** end ***<br />")
#
# --------------------------------------------------------------------
```

jQuery を使ったアップロードのサンプル
[Python3: ファイルのアップロード](https://qiita.com/ekzemplaro/items/3ff9ea440fd9619d24e3)
DirCaster をmp4対応にする。

podcastで　mp4形式を　使いたくなったので　Dircaster　を　改修した　ときのメモ

```php:dircaster.php
        switch (strrchr(strtolower($file), ".")) {
          --略--
          case ".m4a";
          case ".mp4";
            $tit = @$ThisFileInfo['quicktime']['comments']['title'][0]; // artist from any/all available tag formats
            $alb = @$ThisFileInfo['quicktime']['comments']['album'][0]; // artist from any/all available tag formats
            $art = @$ThisFileInfo['quicktime']['comments']['artist'][0]; // artist from any/all available tag formats
            $com = @$ThisFileInfo['quicktime']['comments']['comment'][0]; // artist from any/all available tag formats
            $cmp = @$ThisFileInfo['quicktime']['comments']['writer'][0]; // artist from any/all available tag formats
```

と　.m4a　の　case　文のつぎの行に　.mp4　を　追加する。

```php:config_inc.php
  // Allowed File Types (file extensions) in Feed URL, make sure your type is listed
  $sftypes = "(.mp3 .aac .m4a .mp4 .asf .wma .wav .avi .mov .m4b .m4v)";
```

設定ファイルの　対象ファイルに　.mp4　を　追加する。

これだけです。

RSSフィードに アクセスして ファイルのURLが 表示されていることを 確認したあと
posdcastツールで 読み込んで再生できることを確認。
mp4 が 配信できるようになりました。
[Git] Untrackedなファイルをadd --patchする流れがとても面倒なのでワンラインにしてみた

untrackedファイルを`add --patch`するには、
`git add --intent-to-add`を対象ファイルに対して行わなければならず、

尚且つ`git add --intent-to-add`を実行した対象ファイルを
一つ一つ`git reset`しなければ`git commit`ができなくなるというもので、
本来であれば以下のような流れが必要になる。

1. `git add -N $UNTRACKED_FILES`
2. `git add -p`
3. `git reset $UNTRACKED_FILES`
4. `git commit`

これはファイル数が多くなれば、とても面倒。

ということで以下のようなワンラインを作成してみた。

```
$ git config --global alias.add-patch-with-untracked
! git status -s | cut -c4- | xargs git add -N && git add -p && git status -s | grep '^ ' | cut -c4- | xargs git reset
```

上記のような面倒な手順が、

1. `git add-patch-with-untracked`
2. `git commit`

で完結するようになる。

上記を追加するには、直接`~/.gitconfig`をいじってしまうのが早い

```
$ git config --global --edit
```

``` ~/.gitconfig
[alias]
    add-patch-with-untracked = ! git status -s | cut -c4- | xargs git add -N && git add -p && git status -s | grep '^ ' | cut -c4- | xargs git reset
```

以上。