OmniAICreator/Qiita-1.07M huggingface dataset:
Railsでのマイグレーションエラーを解決した１つの事例

今回はマイグレーションで失敗し、メンターに相談して、解決までのメモ書きです。
オンラインスクールの教材で、いいねをカウントするアプリのようなものを作っていました。
いいねをカウントするコードを入れてマイグレーションを実行したけれど、どうやらそこが上手くいってなかったようです。

## マイグレーションエラー発生
`rails db:migrate`を実行すると、

`An error has occurred, this and all later migrations canceled:PG::UndefinedColumn: ERROR: column "likes_count" of relation "posts" does not existLINE 1: UPDATE "posts" SET "likes_count" = $1 WHERE "posts"."id" = $...
`
というエラーが出ました。

Google翻訳ですが、「post列にlikes_countが存在してませんよ！」と怒られているようでした。

## rails db:migrate:statusを確認
メンターの方より、「`rails db:migrate:status`を確認してみてくれ」という指示を受けました。確認してみると、

```
database: like_app_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20201221071016  Devise create users
   up     20201221072319  Create posts
   up     20201221223916  Create likes
   up     20201222001044  Add likes count to posts
  down    20201222001313  Reset all post cache counters
```

どうやら、20201222001044の部分でlikes countが上手く追加できていなかったよう。

## rails db:rollbackを行う
問題となるファイル、

```ruby:20201222001044_add_likes_count_to_posts.rb
class AddLikesCountToPosts < ActiveRecord::Migration[6.1]
  def change
    add_column :posts, :likes_count, :integer, default: 0
  end
end
```

こちらを一旦コメントアウトし、`rails db:rollback`コマンドを使いロールバック。
そして、コメントアウトを戻して再度、`rails db:migrate`を実行。
無事に正しくマイグレーションが行われ、きちんと動作確認を取ることができました！！:clap::clap:

## まとめ
今回の失敗はおそらく、likes_countを入れる前にマイグレーションを行ってしまった事だったのだと思います。
マイグレーションを行う際はきちんとファイルの確認を行ってから、実行したいと思います。
それにしても、メンターの方の素早いレスと対応ですぐに解決することができました。
ありがたや、ありがたや！
今見ているページがGoogleオプティマイズなのか、オリジナルなのか判別する方法

## Cookieをみよう。

### _gaexp

 ![スクリーンショット 2020-12-22 16.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206790/9fb1f8c2-db19-adf7-d2e4-3da3a285e0b7.png)
 一番お尻の数字で見分けよう。


```js
GAX1.2.~~~~.1 //オプティマイズ
GAX1.2.~~~~.0 // オリジナル
```

おしまい

[Getting Google Optimize Data into Google Analytics and GTM](http://www.datacisions.com/google-optimize-in-gtm/)
Github ActionsでRubyとJavaScriptの各診断ツールを実行できるようにして、Siderを解約した

2019年4月から[Sider](https://sider.review/ja)の課金方式がリポジトリ数からチームのメンバー数に変わって月額費用が３倍くらいになった頃くらいに、Github Actionsのことを知って、乗り換えれば月の費用が抑えられそうと思いGithub Actionsを作り始め、ようやく先月にSiderを解約できました。

Rubyは[exec-ruby-diagnostic](https://github.com/marketplace/actions/exec-ruby-diagnostic)、JavaScriptは[exec-javascript-diagnostic](https://github.com/steiley/exec-javascript-diagnostic)を作成しました。

exec-ruby-diagnosticを使う場合の設定(RuboCopの場合)は以下です。
Gemfile.lockのバージョンで実行されるので、各ツールが最新にできていなくても問題ありません。

```yaml
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
  bundler-cache: true
- uses: steiley/exec-ruby-diagnostic@v1.0.7
  with:
    gem_name: rubocop
```

exec-javascript-diagnosticを使う場合の設定(stylelintの場合)は以下です。
Rubyと同様でpackage.jsonのバージョンで実行されます。

```yaml
steps:
- uses: actions/checkout@v2.3.2
- uses: steiley/exec-javascript-diagnostic@v0.0.2
  with:
    package_name: stylelint
    target_path: "app/assets/**/*.sass"
    # optinal(use this when the package name is different from the executable command name)
    execute_command: stylelint
```

よかったら使ってみて下さい。
ruby 電卓

## 目的
rubyで＋(足し算)、ー(引き算)、＊(掛け算)、/(割り算)を行える電卓のアルゴリズムを考えてみた。
電卓のアルゴリズムを作り方で一番有名な方法が、
①与えられた計算式を受け取る→②逆ポーランド記法に変換する→③演算し計算結果を返す。
今回はこの②から③にかけての私なりの考え方を紹介していきます。なお、実際のところ私自身が初心者なので何かと間違いがありましたらご指摘よろしくお願いします。
## アルゴリズムの考え方とそのコード
##### 1. 逆ポーランド記法で表された計算式標準入力で受け取る。
```
input = gets.chomp.split(" ")
```
※逆ポーランド記法(後置記法)とは、1 2 +や 2 6 *などのように演算子を数値の後ろに置く計算式。ちなみに普段私たちが目にするのは中置記法と言われ、演算子が真ん中にある1 + 2や2 * 6 といったものである。
##### 2. あとで演算子かどうか判断するために予め演算子の配列を作っておく.それと同時に数値を保管するスタックも作っておく。
```
operator = ['+','-','*','/']
num_stack = []
```
##### 2.受け取った計算式をループで回し、数値がきたらスタックにpushし、演算子が来たらスタック内の数値を二つpopし各演算を行い、その計算結果をスタックにpushする。
```
input.each do |s|
  #もし数値がきたらスタックに入れる（正規表現を用いている）。
  if s =~ /[0-9]/
    num_stack << s
  end
  #もし演算子が来たらスタックから二つの数値を取り出し、各演算子に沿って計算する。
  if operator.include?(s)
    a = num_stack.pop
    b = num_stack.pop
    a = a.to_i
    b = b.to_i
    case s
    when '+'    
      num_stack << b + a   
    when '-'  
      num_stack << b - a
    when '*'   
      num_stack << b * a
    when '/'   
      num_stack << b / a
    end
  end
end
```
##### 3. 最後にスタックに残った数値が計算結果となる。
```
ans = num_stack.pop
puts ans
```
README

![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) ![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 

# 概要

マルチスケールシミュレーション特論の個人的まとめ

# qiita\_links

## 学習メモ

-   [README](https://qiita.com/kotanlab/items/12c42efc87e99df94a45)
-   [第6回](https://qiita.com/kotanlab/items/cb95c5bbe73b6b1abc1a)

## 最終課題

------
 - **source** ~/grad_members_20f/members/kotanlab/README.org
AWS CDK Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment

#事象

CDK で以下のエラーがずっと出てくる。
プロファイルも合っている、MFAも入れていない、リージョンも合っているのになぜだろう・・・

```

Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment

```

#解決策

.configの中を調べる

→　ここの設定が間違っていたり ap-northeast-1 などリージョン指定に誤字があってもこのエラーが発生した
Webpackerのあれこれ

#目的
Webpackerとはなんぞや！？と思ったので分かりやすく言語化し定着する為の投稿

#Webpackerとは
webpackをRails仕様にし、専用の設定ファイルやヘルパーメソッドを用意してくれるGem。Railsバージョン6系以降からは、デフォルトでWebpackerが導入されている。
Webpackerによって、Sprocketsのアセットパイプラインと同じような静的ファイルのプリコンパイルに加え、JavaScriptのパッケージが利用できるようになります。

・```webpack```
Webアプリケーションを作成する際に必要な、様々なjavaScriptを```依存関係```に考慮しながら管理する為のツール。モジュールバンドラの一つである。
モジュールとは、機能を一つずつ分けて他のファイルから読み込めるようにした処理のまとまりのこと。JavaScriptでは複数の機能をファイルごとに分割すると、一つのファイルへまとめる際に不具合が生じる為、Node.js環境では機能をモジュールという単位で扱う。
```Node.js```=サーバーサイドで動くJavaScript
モジュールによって、大量の機能を複数のファイルに分ける事ができ、分けられた機能を一つのファイルにまとめても問題なく動作できる。ただし複数に分かれている為、```依存関係が生まれ、読み込みができていないモジュールがあると正しく動作できない問題がある。これを解決してくれるのがwebpack```

・```Sprocketsのアセットパイプライン```
アセットパイプラインの動作を担っているのがSprocketsです。application.cssに記述されている[/*]はコメントアウトとは異なりSproketsというgemの特殊な機能であり、その行を意味のある記述として認識してもらう為のものです。``` *= require_tree .```この記述により、app/assets/stylesheets/というディレクトリにあるCSSファイルは全てappcation.cssに読み込めれる事になる。なのでRailsではCSSを呼び込む際には一つの記述だけでそのディレクトリにあるCSSを読み込む事ができるのである。.（ドット）はカレントディレクトリを表すもの。

・```JavaScriptのパッケージ```
JavaScriptのフレームワークは基本的に大量のプログラムで構成されている。その大量のプログラムをひとまとめにしたものをパッケージという。

#Webpackerによる管理
WebpackerでjQueryというJavaScriptのライブラリを用いる。

```
% yarn add jquery
```
yarn addコマンドは、パッケージのインストールと共に、package.jsonへバージョンを書き込んでくれます。
webpackの設定ファイルで、jQueryを管理下に追加する為の記述。

```config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')

environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    jquery: 'jquery',
  })
)

module.exports = environment
```
application.jsでjQueryを呼び出す記述を加えます。

```app/javascript/packs/application.js
// 省略
require('jquery')
//省略
```

```app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>TryWebpacker</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%# 上記の記述でwebpackで管理されているJavaScriptを参照している %>
  </head>
```
これでjQueryの導入と読み込みができました。
続いてjQueryを用いた記述でJavaScriptファイルを作成する。例としてマウスオーバーすると色が変わる機能を記述しました。

```app/javascript/sample.js
$(function () {
  $(document).on("mouseover", "h1", function () {
    $(this).css({ "color": "blue" });
  }).on("mouseout", "h1", function () {
    $(this).css({ "color": "" });
  })
});
```
jQueryは長くなるJavaScriptを簡易的な記述にできる点がjQueyのメリットです。
AWS移行時にいくつか気になった事

こんにちは。
ウェブクルー AdventCalendar 23日目の記事です。
昨日は @kalzit さんの「 非同期スタックトレースについて 」でした。

<p>本投稿ではAWSを弊社で本格的に使い始めるにあたり、気づいた点等を記載していきます</p>

## はじめに

ウェブクルーでは以前からGCPの積極活用はしていましたが、AWSについてはGCPで動かないサービスやないサービスを少し動かすだけ程度しか利用していませんでいた。
ただ昨今クラウドの利用料金が低価格になってきた中で、オンプレでの運用がコスト高になってきたこともあり
オンプレでオラクルと連携している既存サイトについても、クラウドに移行することになりました。
GCPではオラクルのマネージドのサービスはなく、Accentureさんと連携して提供しているサービスはあるもののあくまで北米リージョンでの稼働のみであるため日本からのアクセスではアクセス速度が遅くなることからGCPは選択肢から外れ、自然とAWSはマネージドサービスを持っていることよりそちらに移行することにしました。

本格的にAWSを使うのは弊社としては初めてでしたので、気になって点をいくつか纏めてみました。

## 気になった点

#### ARPが使えない
AWSでは使えません。
ARPが使えないことで、弊社ではBIG-IPを使っているのですが、基本的にVirtual Server用に仮想IPを持たせることはできません。
※厳密にいえばルーティングを駆使して、直接EC2にIPを持たせずに仮想IPのような形の構成を取ることはできますが、
F5側から構成がサポート対象外になるとのことなので、サポートをしてもらうためにはこの構成は取れません。

ですので、Virtual serverのIPだとしてもEC2に直接IPを持たせる必要があります。
例えばサイトが多数あり、サイト毎にVirtual serverを持たせる場合は、割り振るIP(サイト数)に応じてインスタンスのサイズを
大きくして持たせるIPの数を増やしてあげる必要があり。

インスタンスのスペックが必要な処理能力に関わらず、大きくなってしまい料金がかさんでしまいます。

またBIG-IPのFAIL OVERでは仮想IPを対抗側に引き継ぐ際にGARPを使用しますが、こちらはBIG-IPのほうで
APIを使用しての切り替わり促進をするのでここらへんは問題ないかと思います。
https://support.f5.com/csp/article/K14827

#### IPレンジの最初の3IPは仕様不可
IPレンジが1.1.1.0/24の場合はネットワークアドレスとブロードキャストアドレスのほかに1.1.1.1-3は使用できません。
このレンジの最初の3IPはAWSですでに予約されているIPアドレスですので、例えばオンプレ環境からAWS移行をする場合に
様々な連携がありIPアドレスを変えたくないといった要件がある場合もここのアドレスを使っているサーバ等がある場合は
移行時はIPアドレスを変更する必要があります。


#### rDNSの登録はAWSに移行後でないと設定できない
メールサーバではグローバルに公開されるサーバネームを引き継ぐことでオンプレからAWSへの移行後もレピュテーションを引き継ぎたいといった場合に
オンプレで使用していたサーバネームに紐づくIPだけを変えることでAWSに移行するのが自然かと思います。
ただしこの場合に事前にrDNSだけを設定しておいて、後日移行のタイミングでサーバネームに紐づくIPを変更するという移行方法を実施するかと思いますが、
基本的にはAWSではrDNS設定は正引き設定がAWSのIPを向いており、尚且つ正引き設定と整合性が取れる場合のみに
逆引き設定を受け付けてくれるので、移行後最遅で3日ほど逆引き設定がない状態でメールサーバを運用する必要があり、メールの到達率に影響が出る可能性があります。


#### AWSで冗長構成をとれる仮想アプライアンスが限られる
当初弊社ではvSRXをFWとして使用する想定でしたが、vSRXはクラスターの冗長化がAWSではサポートされていません。
事前に仮想アプライアンスを導入する際は、冗長化できる製品なのかの入念な調査が必要です。

## まとめ
上記いくつか気になった点はありましたが、重ね保守の部分をAWS側に委託することが出来るため、作業コストと利用コストの削減に大きく貢献できると思います。

明日は @haruka_kouyama さんです。
よろしくお願いします！
tmux send-keys でターミナルを操作する

```terminal
$ tmux send-keys -t sessionname:windowname   ls C-m
# ls がコマンドなどキーボード操作
# C-m が改行コード
```

- [tmuxの画面をcronやスクリプトで自動操作する。 - むかぁ～ どっと　こむ](http://mukaer.com/archives/2012/07/07/tmuxcron/)
お前ら .gitignore をチマチマ編集するんじゃねえ！

> .gitignore に .vscode/ を追加
> チーム内でVSCodeを使っているのは僕だけですが、プロジェクトに混じると面倒だから、 .gitignoreにしてもいいですよね？

お前は、新しいツールを使うメンバーが出るたびに `.gitignore` を編集するのか！？そのたんびに、コードレビューを誰かにやらせるのか！？フンギー！！ :japanese_ogre: :japanese_ogre: :japanese_ogre: :japanese_ogre:

# プロジェクトの `.gitignore` にはこう書け！

```
# ドットで始まるファイルを全て削除
.*
```

ドットで始まるファイルは普通は管理対象外なんだから、全部無視して良いのです。

# でもドットで始まるファイルを管理したいんですけど・・・

`git add` に `-f` オプションをつけると無視されるファイルも管理対象にできます。

```
git add -f .terraform.lock.hcl
```

また、`.gitignore` で `!` をつけると、パターンを上書きして無視しないようにできます。

```
# .gitignore
.*

# !をつけると明示的に管理対象にできます。
!.terraform.lock.hcl
```

# でも、うちのツールはドットで以外で始まるファイルを作るんです。

「そんなツールは使うな！」と言いたいですが、

まず、そのツールがチーム内で共通して使う場合は、通常通り `.gitignore` に追加しましょう。

```
# 古いRailsプロジェクトで生成されるファイルを無視する
vendor/bundle

# Pythonパッケージビルド時に生成されるファイルを無視する
build/
dist/
```

そして、個人的に使うツールであれば、`~/.gitignore` に追加すれば、プロジェクトにコミットせずに、ファイルを無視できます。

```
# ~/.gitignore
SciTEUser.properties
```


もっとややこしいことをしたいなら、この記事が役立つかもしれません。

- [既に git 管理しているファイルをあえて無視したい - Qiita](https://qiita.com/usamik26/items/56d0d3ba7a1300625f92)
pandasでExcelファイル(xlsx)が読み込めない時の対処法

# 環境について
pandas== 1.1.4
xlrd==2.0.1

# エラーについて
pandasでExcelファイル（xlsx）を読み込む時に

```python
import pandas as pd

df = pd.read_excel('sample.xlsx')
```
下記のエラーが発生する．

```
xlrd.biffh.XLRDError: Excel xlsx file; not supported
```
# 原因
Excelファイルを読み取るライブラリであるxlrdが2.0.0からxlsxファイルに対応しなくなったため．
https://xlrd.readthedocs.io/en/latest/changes.html
# 解決方法

２つの解決方法があります．

## 1.xlrdのバージョンを下げる
```
pip3 install xlrd==1.2.0
```
## 2.ファイルを読み取るライブラリをopenpyxlに変更する
pipでopenpyxlをインストールする．

```
pip3 install openpyxl
```
Excel読み取り時にライブラリを指定する．

```python
df = pd.read_excel('sample.xlsx',engine="openpyxl")
```
エラー備忘録

# heorkuでデプロイしようとしたところエラーが発生した話。
ver. 'rails', '~> 6.0.0'

作成したappをデプロイしようとしたところ、Appliationエラーが発生してしまいました。
![errorimage](https://i.gyazo.com/1b702f09064ef68d8f27fb21aaa45fbc.png)

##　解決方法

＊まず、画像にも表示のあるheroku logs--tailをターミナルでやってみる。
するとどこでエラーが発生しているのか教えてくれます。

いろいろ調べてみたら、credentials.yml.encファイルと対になってるはずのmaster.keyファイルがVScode上に存在していなかったんです。

その為、一度VScodeを終了し再起動したところ、うまくmaster.keyファイルが出現してくれたのでエラー解決することができました！

デプロイする前にまたこんなエラーが発生しない様に必要なファイルが存在しているか一度みてからやってみたいと思います。

### いろいろ調べて実行してみる際の注意
記事通りにコマンド打つのはいいが、記事通りにrails newをするのはおすすめしない！とのことでした。

確かに、新しくアプリケーションの雛形が作られる、というコマンドなので、一度rails newしたものに再度やってしまったらマトリョーシカみたいになっちゃいますよね。気をつけます。
[絶賛更新中！！！]いい加減に覚えたいコマンドラインの基本操作

こんにちは
西日差す穏やかな午後
JR高田馬場駅前のカフェからお送りいたします

この度はコマンドライン基本操作に関して
何度ググり実行しても寝て覚めたら忘れておる状況に業を煮やした折記事にすれば脳裏に擦り付けられるのではと奮起いたしました為下記に記述いたします


移動系
任意のフォルダへ移動
$ cd フォルダ名
１つ上の階層に移動
$ cd ..
２つ上の階層に移動
$ cd ../../


状況確認系
現在のパス(場所)を表示
$ pwd
現在の階層の中身を表示
$ ls
現在の階層の中身を表示(詳細表示)
$ ls -la

手間省きたい系
過去に使用したコマンドを表示
$ history

階層構造整理したい系
現階層内の任意のフォルダに移動
$ mv ファイル名 フォルダ名
１つ上の階層へ移動
$ mv ファイル名 ../


書き出したら疲れてきました
随時更新していきmas
【mac】nodeのバージョンが変わらない

この記事は、nodebrewでインストールしたけど、nodeのバージョンが切り替わらない人向けに書かれています。

##結論
homebrewでインストールされているか、
nodebrewでインストールされているか問題だった。
zshにnodebrewのパスを通すことでnodeのバージョンが切り替わるようになる。

##経緯
node.jsの安定版が更新されていたので、確認した。
[Node.js Releases](https://nodejs.org/en/about/releases/)
2020/12/22現在、安定版は14.15.3 Fermium

```
$ node -v
v12.18.4

$ nodebrew ls-remote
なんかいっぱいバージョンが出る。

$ nodebrew install-binary v14.15.3
Fetching: https://nodejs.org/dist/v14.15.3/node-v14.15.3-darwin-x64.tar.gz
######################################################################## 100.0%

$ nodebrew use v14.15.3
use v14.15.3

$ node -v
v12.18.4
```
バージョンが変わらない
なんか前にもこんなことあったなぁと思いつつ、調査。
nodeのパスが通っている場所が違うんだろうとアタリをつける。

```
$ which node
/usr/local/bin/node
```

homebrewでインストールされていることがわかった。

## 対応

### ①homebrewのnodeを削除

```
brew uninstall --ignore-dependencies node
Uninstalling /usr/local/Cellar/node/15.0.1... (3,331 files, 61.0MB)
```

--ignore-dependenciesを削除したのは、下記が理由、これなら消せるよ、と書いてくれているのが嬉しい。

Error: Refusing to uninstall /usr/local/Cellar/node/15.0.1
because it is required by yarn, which is currently installed.
You can override this and force removal with:
  brew uninstall --ignore-dependencies node

結局、nodeのパスをzshで指定して解決したので、homebrewインストールしたnodeをアンインストールしなくても
解決できたような気がする。

### ②確認したが、変わらず。

```
$ nodebrew use v14.15.3
use v14.15.3
$ node -v
v12.18.4
```
パスを変更していないので、当然である。

### ③ zshでパスを通す。

```
$ vim ~/.zshrc
```
*vimはテキストエディタ、「.zshrc」ファイルを編集できれば何でもいい。

```~/.zshrc
export PATH=$HOME/.nodebrew/current/bin:$PATH
```
ちゃんと保存してね。

```
$ source ~/.zshrc
```
シェルを再読み込み

### ④確認

```
node -v
v14.15.3
```
切り替わった。

備考:デフォルトシェルの確認

```
$ echo $SHELL
/bin/zsh
```
[macOS Catalina以降はzshになっているらしい。](https://ja.wikipedia.org/wiki/MacOS_Catalina#cite_note-24)

## nodebrewを使ってバージョンを切り替える

```
$ nodebrew use v12.18.4
use v12.18.4

$ node -v
v12.18.4

$ node -v
v12.18.4

$ nodebrew use v14.15.3
use v14.15.3
```

## nodebrewでのバージョン探索とインストール

```
$ nodebrew ls-remote
なんかいっぱいバージョンが出る。

$ nodebrew install-binary v14.15.3
```

##参考
[何でHomebrewからじゃなくNodebrewでNode.jsのバージョン管理するのか](https://ocws.jp/blog/why-do-you-version-node-js-in-a-nodebrew-not-from-homebrew/)
[node.jsの管理をnodebrewに変更](https://qiita.com/yoshinariiii/items/c700b4a5f8364280cd04)
[【zsh, bash】macでPATHを通す方法 - not found と出てしまったら](https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def)
スクラムと組織論

https://qiita.com/tinagaki/items/a07e76819cf5e5c84516
の続き

# 組織論としてのスクラム
- 自己管理化、機能横断的な開発チームにすること
- チームの生産性を高めるような変化を促す。
- 未熟なスクラムチームのスクラムイベントのファシリテートすること
- 開発チームの進捗を妨げるものを排除することの促進
- チーム、組織に変化を促すこと

なチームにするために最近の組織論などと比較してみる

## 指標
googleがreworkで解説をしている。
効果的なチームにある共通の因子があります。
以下rework引用

### 心理的安全性
> 心理的安全性とは、対人関係においてリスクある行動を取ったときの結果に対する個人の認知の仕方、つまり、「無知、無能、ネガティブ、邪魔だと思われる可能性のある行動をしても、このチームなら大丈夫だ」と信じられるかどうかを意味します。心理的安全性の高いチームのメンバーは、他のメンバーに対してリスクを取ることに不安を感じていません。自分の過ちを認めたり、質問をしたり、新しいアイデアを披露したりしても、誰も自分を馬鹿にしたり罰したりしないと信じられる余地があります。

### スクラムにおける心理的安全性
チームとして作業を行うスクラムにおいてお互いに話し合うということは大切で話せる環境にあるというものは最重要かなと思っています。

### 相互信頼
> 相互信頼の高いチームのメンバーは、クオリティの高い仕事を時間内に仕上げます（これに対し、相互信頼の低いチームのメンバーは責任を転嫁します）。

### スクラムにおける相互信頼
体感の話になりますが、
信頼をおける環境下で働くことはスピードがあり、そのような環境にすることは生産性、幸福度を上げる上で大切かと思っています。

### 構造と明確さ
> 効果的なチームをつくるには、職務上で要求されていること、その要求を満たすためのプロセス、そしてメンバーの行動がもたらす成果について、個々のメンバーが理解していることが重要となります。目標は、個人レベルで設定することもグループレベルで設定することもできますが、具体的で取り組みがいがあり、なおかつ達成可能な内容でなければなりません。Google では、短期的な目標と長期的な目標を設定してメンバーに周知するために、「目標と成果指標（OKR）」という手法が広く使われています。

### スクラムにおける構造と明確さ
スクラムにおけるスクラムマスターの定義、プロダクトオーナーの定義をシンプルにしておくことで構造と明確さを保っていると思います。
スクラムマスターは優れた技術者とは一切定義されていないし各役割はしっかり定義されている(と思う)

### 仕事の意味
> チームの効果性を向上するためには、仕事そのもの、またはその成果に対して目的意識を感じられる必要があります。仕事の意味は属人的なものであり、経済的な安定を得る、家族を支える、チームの成功を助ける、自己表現するなど、人によってさまざまです。

### スクラムにおける仕事の意味
あんまりここはスクラムで明確化されていない気がします。

### インパクト
> 自分の仕事には意義があるとメンバーが主観的に思えるかどうかは、チームにとって重要なことです。個人の仕事が組織の目標達成に貢献していることを可視化すると、個人の仕事のインパクトを把握しやすくなります。

### スクラムにおけるインパクト
なぜこのプロダクトが必要なのか、
このプロダクトバックログがなぜ必要なのか、
インセプションデッキやPO,ステークホルダーによる説明を受ける必要があります。

## 組織論
### ティール組織、グリーン組織
ティール組織とは、社長や上司がマイクロマネジメントをしなくても、目的のために進化を続ける組織のこと
```
・Red（レッド）組織：個人の力で支配的にマネジメント
・Amber（琥珀）組織：役割を厳格に全う
・Orange（オレンジ）組織：ヒエラルキーは存在するが、成果を出せば昇進可能
・Green（グリーン）組織：主体性が発揮しやすく多様性が認められる
・Teal（ティール／青緑）組織：組織を1つの生命体としてとらえる
```

と段階を分けて世界で少しづつティールな組織ができていることから本が出版された。
(実体はどうなんだろうとも思いつつ)

### スクラムにおけるティール、グリーン組織
スクラムのチームにおける主体は各個人であり、上記に当てはめた場合にティール、グリーン組織に値する。
※オレンジ組織でもできるとは思うが裁量があるオレンジ組織でないと難しいとは個人的に思う。

```
ティール組織:目指すべき理想のチーム ->スクラムマスターがいなくてもいい世界
グリーン組織: 多様性があり、まずスクラムマスターが目指すべき世界->だんだんティールな(ひとつの生命体として動けるような)チームを目指していく
```
# まとめ
- スクラム自体はモダンな組織論と当てはめてもそれとそこまで遜色はない、、はず

# 引用
https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf
https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/steps/introduction/
RaspberryPiでOpenHabのインストール時に出たjava: Command not foundを修復する

# 環境
- Raspberry PI 3B
- Raspbian
- 16GB SD
- Zuluをインストールーパス追加ーJAVA_HOME設定済み

# エラー
https://www.openhab.org/docs/installation/linux.html を参考に進めたけど動作しない.
``` sudo systemctl status openhab.service -l```でログを見るとJava: command not foundで止まっている

#解決

(/usr/local/bin/zulu/bin/javaと/usr/local/bin/zulu/bin/javacはzuluのパスに置き換える)

```bash
sudo apt-get install default-jre
sudo update-alternatives --install /usr/bin/java java  /usr/local/bin/zulu/bin/java 1000
sudo update-alternatives --install /usr/bin/javac javac  /usr/local/bin/zulu/bin/javac 1000
sudo systemctl restart openhab.service
```

#原因
代替VMのリストにZuluが追加されていなかった

#参考
https://www.openhab.org/docs/installation/linux.html
https://community.openhab.org/t/solved-openhab2-service-failed-with-result-exit-code/45435/2
泥棒のテクニックから学ぶコード修正

<h1>コード修正のベストプラクティス <sub><sup>（と言うより TIPS）</sup></sub></h1>

## TL; DR <sub><sup>（今北産業）</sup></sub>

1. 泥棒がタンスを開ける時、時短のため下の段から上へ開けていく。<sub><sup>（らしい）</sup></sub>
2. コード修正も、エラー解析結果の下から順に修正していく。<sub><sup>（と良い）</sup></sub>
3. <font color=darkorange>**下から修正して行けば、それより上のコードの行番号はズレない**から</font>

例えば、下記のシェル・スクリプトの[静的解析](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90)の結果を修正していく場合、先に 324 行目から潰して（修正して）いけば 312 行目のエラー箇所がズレない。

```shell-session:シェルスクリプトの静的解析結果の例（２カ所でエラーが発生している）
$ shellcheck -x -s sh */*.sh
In ./tests/run-tests.sh line 312:
    php --version | grep Xdebug 2>/dev/null 1>/dev/null && {
                                                        ^-- SC2015: Note that A && B || C is not if-then-else. C may run when A is true.

In ./tests/run-tests.sh line 324:
        . "$path_file_conf_coveralls"
          ^-------------------------^ SC1091: Not following: ../tests/conf/COVERALLS.env: openBinaryFile: does not exist (No such file or directory)
```

## TS; DR

静的解析、[ユニット・テスト](https://ja.wikipedia.org/wiki/%E5%8D%98%E4%BD%93%E3%83%86%E3%82%B9%E3%83%88)や [Linter](https://ja.wikipedia.org/wiki/Lint#%E3%80%8Clint%E3%80%8D%E3%81%AE%E6%B4%BE%E7%94%9F%E7%94%A8%E6%B3%95) などの結果を見ながら修正する際に、いまさらながら「泥棒のテクニック」が使えることに気付きました。

**泥棒ってタンスをチェックする時に下の段から開けて行く**んですって。ゲーム実況でアイテム探しをしているシーンを観て知りました。

同じように、**解析結果で指摘されたコード行を「下の段から修正していく」ことで効率よく修正できる**んですね。（同じファイルに複数の修正箇所がある場合に限る）

今まで、アホみたいに上から修正していました。修正するたびに、それ以降の対象行がズレていくものだから、迷子になるたびに解析を走らせてたのです。そう、タンスを上から開けては閉めて、次の段をチェックするがごとく。いやはや。

コーディングが早い人って、こう言う細かいことがサラッとできてるんだろうなぁ。
html, javasript, jqueryのタグ（CSSの設定）

# 初めに
jQueryとCSSが別々ファイルを設定するという集めです。
#クラスの設定に対して
###①普通の設定

html要素）

```html
<html>
  <head>
    <title>Hoge</title>
  </head>
  <body id="main-id">
    <div>
        <p>jQuery練習</p>
        <ul>
            <li class="item">サンプルテキスト１</li>
            <li class="item">サンプルテキスト２</li>
        </ul>
    </div>
  </body>
</html>
```

 jQueryオブジェクト

```javascript

// html要素: p
$('p').css('color', 'blue');

// class .className
$('.item').css('color', 'red');
```
結果
![スクリーンショット 2020-12-22 14.28.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/0c43a583-826c-e1c0-a6cf-415e9cf129d9.png)


###②HTMLの表示の代わりに、jQueryタグで表示する
　jQueryとCSSが一つファイルの設定の代わりに、別々ファイルを分別する

html要素）

```html
<html>
  <head>
    <title>Hoge</title>
  </head>
  <body id="main-id">
  </body>
</html>
```
 jQueryオブジェクト

```javascript
//マインオブジェクト
var $main  = $("#main-id");

//divオブジェクトに変換する
var $div = $("<div>");

//ulオブジェクトに変換する
var $p = $("<p>").html("jQuery練習");

//ulオブジェクトに変換する
var $ul = $("<ul>");

//liオブジェクトに変換する
var $li1 = $("<li>").html("サンプルテキスト１");
$li1.addClass("item");

//liオブジェクトに変換する
var $li2 = $("<li>").html("サンプルテキスト２");
$li2.addClass("item");

//親オブジェクトに子オブジェクトを追加
$div.append($p).append($ul.append($li1).append($li2));
$main.append($div);
```

CSSの設定

```css
p {
  color: blue; 
 }
 
 .item {
   color: red;
 }
```
③表示の結果と同じですが、jQueryとCSSを分別したの方が分かりやすし、ソースの改善も便利だ。
![スクリーンショット 2020-12-22 14.56.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965456/8c8af633-4d9a-b5f7-9863-5903e9996992.png)

以上
DLLを他のプログラムで使う際にエラーが出て、そこから解決に至るまで

# 開発環境

Visual Studio Community 2019

# 前置き

昔UnityのC#を使っていた際、C#の知識をチームに教えるより、経験あるC++で作成したDLLを作っていたことがあります。

当時書いたDLLに関する記事はこちら。

[Unity(C#)でC++で作成されたDLLを使用する基本的な方法](https://qiita.com/Ryuki_TANAKA/items/559ccdcd8c6bc7e40b11)

そして現在、大学の研究室でC#を利用する機会を頂き、同じようなソースコードでDLLを実装したのですが、何故かエラーが出てくる状態に…。

それを解決するまでの経緯を記事にしておきます。

# 経緯

## DLLをダンブして関数が機能しているか確認する

上記記事のように、超単純なDLLでテストしても「DLLはあっても関数が存在しない」例外が出て、もしかしたら関数名がおかしいのでは？と思って、バイナリファイルをダンプして関数があるか調べました。

[こちらの記事](https://kazupon.org/visual-studio-dll-in-file/)を参考にして、

1. Visual Studioの「ツール」->「コマンドライン」->「開発者用PowerShell」を選択
2. 以下のようにコマンドを入力

```
dumpbin /exports Debug\example.dll > output.txt
```
こうすることで、Visual Studio内でデバッグ出力したDLLの関数の詳細がslnファイルがあるフォルダに生成されます。

生成されたテキストファイルを見てみると、関数がよくわからない名前になっていました。

## __stdcallがついてるか確認する

恐らくコンパイルしたときに何かの手違いで変な名前にされた可能性があると思い、他のDLLに関するソースコードを漁って比較しました。

そうすると、多くのソースコードに呼び出し規約である

```
__stdcall
```

を、関数を宣言する際に使われていました。そこで、

```dllamin.cpp
extern "C"
{
    __declspec(dllexport) void __stdcall example()
}

void __stdcall example()
{
    ...
}
```

のようにすることで、C#側でしっかり利用できるようになりました。

# まとめ

今回学んだことは以下の2つです。

- DLLのエラー困ったらdumpbinで確認する

- 呼び出し規約「__stdcall」をつける
Windows DockerDesktop で RUNTEQさんの環境をつくる

mysql / rails のコンテナをわけました

docker-compose.yaml

```yaml
version: '3'
services: 
  db:
    container_name: mysql
    image: mysql:8.0.21
    command: --default-authentication-plugin=mysql_native_password 
    environment:  
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      MYSQL_DATABASE: root
      TZ: 'Asia/Tokyo'
    ports:
      - "3306:3306"
    tty:  true
  ruby:
    container_name: ruby
    build: .
    volumes:
      - ".:/runteq:cached"
      # 1. exclude volumes
      - /runteq/vendor
      - /runteq/node_modules
      - /runteq/tmp
      - /runteq/log
      - /runteq/.git
    ports:
      - 3000:3000
    tty:  true
```


Dockerfile

```Dockerfile
FROM ruby:2.6.4
ADD . /runteq
WORKDIR /runteq
SHELL ["/bin/bash", "-c"]
ENTRYPOINT [ "/bin/bash" ]
EXPOSE 3000

# WORKING USER
ARG DOCKER_UID=1000
ARG DOCKER_USER=runteq
ARG DOCKER_PASSWORD=runteq
RUN useradd -m --uid ${DOCKER_UID} --groups sudo ${DOCKER_USER} && echo ${DOCKER_USER}:${DOCKER_PASSWORD} | chpasswd
ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
ENV DEBCONF_NOWARNINGS=yes

# INIT
RUN apt-get -y update
RUN apt-get install -y apt-utils 
RUN apt-get install -y build-essential
RUN apt-get install -y git-core 
RUN apt-get install -y vim

# bundler
RUN apt-get install -y bundler
RUN gem install bundler:2.1.4

# YARN
RUN apt-get -y remove cmdtest
RUN apt-get -y remove yarn
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update 
RUN apt-get -y install yarn

# rbenv
RUN apt-get remove rbenv
RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv
RUN echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
RUN source ~/.bashrc
RUN ~/.rbenv/bin/rbenv init -
RUN echo 'eval "$(rbenv init -)"' >> ~/.bashrc
RUN mkdir -p ~/.rbenv/plugins
RUN git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
# RUN curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash

# nodeenv
RUN apt-get remove nodeenv
RUN git clone https://github.com/OiNutter/nodenv /usr/local/nodenv
RUN echo 'export NODENV_ROOT=/usr/local/nodenv' >> ~/.bashrc
RUN echo 'export PATH=$NODENV_ROOT/bin:$PATH' >> ~/.bashrc
RUN source ~/.bashrc
RUN echo 'eval "$(nodenv init -)"'  >> ~/.bashrc
RUN mkdir -p /usr/local/nodenv/plugins
RUN git clone https://github.com/OiNutter/node-build /usr/local/nodenv/plugins/node-build

# Google chrome
RUN /bin/bash -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
RUN curl -sS https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
RUN apt-get -y update
RUN apt-get install -y google-chrome-stable

# sqlite3
RUN apt-get install -y sqlite3

# ETC
RUN git config --global credential.helper store 

```
API Gatewayで「Lambdaオーソライザー」と「APIキー認証」を一緒に利用する

# はじめに
タイトル通り、API GatewayでLambdaオーソライザーとAPIキーを同時に設定してみたので、そのまとめです。


Lambdaオーソライザーとは、
> Lambda オーソライザー (以前のカスタムオーソライザー) は、Lambda 関数を使用して API へのアクセスを制御する API Gateway の機能です。

本稿では説明しませんので、詳しく知りたい方は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-flow)を見てください。

今まで、API GatewayのAPIキーと、Lambdaオーソライザーをそれぞれ片方ずつ利用したことがあったのですが。今回、API実行数の制御を行いながら、認可をする必要があったため同時に利用することにしました。

# Lambdaオーソライザー
```golang
package main

import (
	"context"
	"errors"
	"fmt"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

// Help function to generate an IAM policy
func generatePolicy(principalId, effect, resource string) events.APIGatewayCustomAuthorizerResponse {
	authResponse := events.APIGatewayCustomAuthorizerResponse{PrincipalID: principalId}
	if effect != "" && resource != "" {
		authResponse.PolicyDocument = events.APIGatewayCustomAuthorizerPolicy{
			Version: "2012-10-17",
			Statement: []events.IAMPolicyStatement{
				{
					Action:   []string{"execute-api:Invoke"},
					Effect:   effect,
					Resource: []string{resource},
				},
			},
		}
	}
	return authResponse
}

func handleRequest(ctx context.Context, event events.APIGatewayCustomAuthorizerRequestTypeRequest) (events.APIGatewayCustomAuthorizerResponse, error) {
	if cookie, ok := event.Headers["Cookie"]; ok {
		// ここで認可処理をおこなう。例としてCookieを取得している
		fmt.Print("cookie: " + cookie)
	} else {
		return events.APIGatewayCustomAuthorizerResponse{}, errors.New("Unauthorized")
	}
	return generatePolicy("user", "Allow", event.MethodArn), nil
}

func main() {
	lambda.Start(handleRequest)
}

```
# 処理フロー
実際に動作させて確認した処理フローはこのようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156415/6a392709-eaa8-4d21-d178-562f171e71b3.png)

処理される順序としては、Lambdaオーソライザー→APIキー認証ということになりました。
検証前の予想では、APIキー認証→Lambdaオーソライザーの順かなって思っていたので、ちょっと意外でした。

これは、APIキーは認証に使うものではなく顧客に**「リクエストレートとクォータ」を提供するためのキー**という位置づけだからだと思われます。
仮にオーソライザー（認可）で弾かれた場合は、APIキー認証まで到達しないため、APIGatewayの使用量プランで設定したクォータが無駄に消費されることはありません。（素晴らしい）


# まとめ
- LambdaオーソライザーとAPIキー認証を同時に利用することはできます。
- 順序としては、Lambdaオーソライザーが呼ばれたあとに、認可OKの場合APIキー認証が実行されます。
    - Lambdaオーソライザーで401 Unauthorizedを返却した場合はAPIキー認証にはいきません。 

# 参考
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-flo
gemの開発directoryにできたgemsファイルを消すときに困った話．

\![Mac OS X-10.13.3](<https://img.shields.io/badge/MacOSX-10.13.3-brightgreen>) \![ruby-2.7.0p0](<https://img.shields.io/badge/ruby-2.7.0p0-brightgreen>) 


# はじめに

卒業研究でqiita\_orgというgemを作っていると, 'gems directoryが含まれているよ'とissueがきたので,これを消そうとしました．このときに困ったことをメモしておきます．


# 困ったことについて．


## 今回の件の始まり．

mensfeldさんより以下のようなissueが来た．

```
While reviewing the changes for this lib, I noticed, that the vendor/gems directory is being included.

Is this needed? Usually, it's added by mistake and causes:
a) confusion
b) problems when tracking changes
c) makes gem much bigger than it could be

ref: https://github.com/yamatoken/qiita_org/tree/master/gems/ruby/2.7.0

If the presence of vendor data is valid I would love the reasoning. Thanks!
```

rubyもgem開発も初心者でこんなこと考えたこともなかったし,いい学びを得れたので,いつの間にかできていたgems directoryは消してしまおうとしました．


## 自分の行ったこと．

消した後,念のため確認でqiita\_orgのpostコマンドを試して見ると以下のようになった．

```bash
Bundler could not find compatible versions for gem "command_line":
  In Gemfile:
    qiita_org was resolved to 0.1.35, which depends on
      command_line (> 2.0.0)

Could not find gem 'command_line (> 2.0.0)', which is required by gem 'qiita_org', in any of the sources.
```

とりあえず, 'bundle update'をして見ると,消したはずのgems directoryが復活していた．


## 原因について

rmで消しても復活するし，.gitignoreでgemsをGithubに上げないようにしても勝手に上がってる．

原因は,.bundle/configの中にあった．

```:.bundle/config
BUNDLE_PATH: "gems"
```

こんなものがあったのでgems directoryが生成されていた．

これを消して解決．



------
 - **source** ~/Github/yamatoken/bundler_path.org
ECサイトにクレカ番号や住所を教えずに買い物をする未来の話

ブロックチェーンを使うと、病院をまたいだ電子カルテの共有ができるとか、改ざんできない学歴の証明によって就職や採用に活用することができるとか、なんだかすごそうに聞こえますが、あまり身近な話ではなくピンとこない人が多いかもしれません。今回は、ごく身近にあるネットショッピングというテーマでブロックチェーンの活用方法を考えてみたいと思います。ちなみに今回の内容は是非ともブロックチェーンを使うべき、というものではありません。ブロックチェーンを組み込むことでDIDなどが目指す分散型アイデンティティを実現した、より安心できる社会の可能性について何か感じていただければと思います。

なお、今回のエントリーは前回に投稿した、[分散型識別子DID的に見たNEMはんこの技術的な解説](https://qiita.com/nem_takanobu/items/b1e85d5605f37a5da12f)、[ブロックチェーンで社会実装を加速させるデザインパターン９種類](https://qiita.com/nem_takanobu/items/cc2aa777ad1fa78d9ede)の内容を引き継いだものとなっていますので、ぜひそちらの方も併せてお読みください。

まず、現在のショッピングサイトの仕組みについて考察してみます。

- ECサイトで注文する
- クレジットカード番号を入力する
- 配送先住所を入力する
- 商品が出荷される

ここでECサイトにクレジットカード番号を入力したり、住所を入力するわけですが、これらはECサイトには関係の無い情報です。不要な情報のやり取りをそぎ落としていくと、必要な情報は`ECサイトへ商品代金を入金した事実`と、`配送業者への住所の通知`です。分散型アイデンティティの普及した社会では、自分に関する情報のすべてを提供せず、必要な事業者に対して必要な情報だけを伝えるというスタンスを持ちます。

では上記商品購入のフローを、分散型アイデンティティ的なモデルで考えてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29187/1a2ae709-fa48-a88e-b031-84ed42ec7cff.png)

商品を購入するユーザの周りに4つの関係者がいます。

- 自治体
    - ユーザがどこに住んでいるかを証明します。
- 銀行
    - ユーザーからの送金指示を受け、ECサイトに入金します。
- ECサイト
    - ユーザからの注文と銀行からの入金を受け、配送会社に出荷指示を出します。
- 配送会社
    - ECサイトから出荷指示を受け、ユーザに商品を届けます。

これらの関係者はあらかじめ決められた前提条件を守りながら作業を行います。

- 注文
    - ユーザの居住証明を確認し、ECサイトが自治体の署名付き年齢（誕生日）をリクエストします。
- 送金
    - 銀行の支払い証明を確認し、ECサイトが配送会社に出荷指示を出します。 
- 配送
    - ECサイトからの出荷指示を確認し、配送会社が自治体の署名付き住所をリクエストします。

前提条件に使用された証明や指示の内容です。

##### 居住証明
ユーザが当該自治体の管理区域に居住していることを証明するドキュメントです。自治体が公表するアカウント(DID:Issuer)から発行され、ECサイトによって購入者の購入適正の検証に使用されます。クレジットカードで言えばのカード作成時の信販会社からの審査と同等です。

##### 支払い証明
ユーザが銀行に対してECサイトへ送金指示を出したこと証明するドキュメントです。ユーザーの支払いが済んだかどうかは問題ではなく、銀行がお金の流れを責任を持つことの意思表明でもあります。証明書ではなく実際のステーブルコインなどの送金トランザクションである可能性もあります。

##### 出荷指示
ECサイトが配送会社へ商品出荷を指示するドキュメントです。配送会社は一連のトランザクションをトレースすることでユーザを特定し、住所情報の開示をユーザにリクエストします。リクエストを受け取ったユーザECサイトからの出荷指示の存在を確認した後、住所情報を配送会社に伝えます。すべての作業がブロックチェーン上で完結しているのでシステムをまたぐようなトレーサビリティ構築の必要がありません。

### アグリゲートトランザクション


Symbol from NEMなどでは上記のようなトランザクションを一括にまとめて一つのブロックに詰め込むことが可能です。

```js

ユーザ.aggregate[
  ユーザ.Transfer{message:"{注文No:12}"}->ECサイト,
  ユーザ.Transfer{mosaic:{dyen:1980}}->銀行,
  銀行.Transfer{message:"支払い証明"}->ユーザ,
  ECサイト.Transfer{message:"出荷指示"}->配送会社,
  ユーザ.Transfer{message:"居住証明"}->配送会社
]

```

これらのトランザクションを一つにまとめることで、仲介者が情報を集めている間に利害関係者の状態が変わってしまう（例えばキャンセルや期限切れ、残高枯渇、引っ越しなど）、という現実社会においてバグを生み出しやすく、システム設計上非常に実装コストのかかる箇所を回避することができます。

### さいごに

分散型アイデンティティの考え方をネットショッピングに取り入れてみました。これは個人情報保護の観点のみならず、昨今頻発する大手企業のクラウド障害などによって、自分に関する情報なのに必要な時に取り出せない、といったトラブルからも回避できるようになると考えます。生殺与奪をつかさどる自分に関する情報を一か所に集めない仕組みは今後より重要な役割を担っていくことになるでしょう。

ちなみに、「お金を一か所に集めない仕組み」をいち早く実践した投げ銭機能付きブログnemlogというものがありますのでこちらもご参考ください。

[お金を一か所に集めない仕組み - nemlog](https://nemlog.nem.social/blog/2929)

みなさん、よいクリスマスを！
TrailheadでPlaygroundを新規作成する

## 本記事について
本記事では、Trailheadで勉強中の私がつまづいた基本の操作についてメモしています。
基本的に自分の覚え書きなので、用語や解説などは端折っていることご了承ください。
※Trailhead とは
Salesforce のサービス・機能をはじめさまざまなコンテンツを自己学習できる学習環境プラットフォームです。

## 最初のPlayground は自動で作成される
Trailheadにサインアップした時点で、環境は１つ作成されます。

モジュールでハンズオンChallengeがある場合、Challengeの下部にPlaygroundを起動するためのリンクが表示されています。
![スクリーンショット 2020-12-22 14.28.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/972039/b5e10235-346b-08dc-50c0-c166d1f67608.png)
起動をクリックすると、検証環境が立ち上がります。
自動で作られてすぐにいじれるなんて、すごいですよね。感動しました。

## 2こめ以降の環境を作りたい
Trailheadで学習を進めるうちに、「このモジュール用に新しくTrailhead Playgroundを作成することをおすすめしますよ」的なメッセージが。

調べたところ、ハンズオンChallengeで正しく判定してもらえない場合もあるようなので、ぜひとも新しくPlaygroundをつくっておきたい。

が。新しい環境ってどうやってつくるのだろう。
「プロファイル」や「設定」を探してみましたが、それらしきものはありませんでした。

## Playgroundの作成や一覧は、Challenge下部の環境名から遷移できた
結局、こちらのTrailheadに書いてありました。
<a href="https://trailhead.salesforce.com/en/content/learn/modules/trailhead_playground_management/create-a-trailhead-playground">Create a Trailhead Playground</a>

Playgroundを起動するためのリンク欄で、「起動」ではなく環境名の方をクリックします。
![スクリーンショット 2020-12-22 14.28.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/972039/b5e10235-346b-08dc-50c0-c166d1f67608.png)
（上記の画像で言うと、「My Trailhead Playground 1」と書いてある方をクリックします）
すると、現在持っているPlayground一覧と新しいPlaygroundを作成できるリンクがポップアップで出てきました。わーいよかった。

なんですぐ気づけなかったんだぁぁ

と悔しさも残しつつ、<a href="https://trailhead.salesforce.com/en/content/learn/modules/trailhead_playground_management/create-a-trailhead-playground">Create a Trailhead Playground</a>を読んでも直感的にわかりにくかったので、意外と彷徨う方もいるのではないかなと思いました。

## 追記：アカウントのメニューからも遷移できた
アカウントのアイコン＞ハンズオン組織　からも一覧に遷移できました。
Jupyter Lab のターミナルをいい感じにする

Jupyter Lab でターミナルを起動すると、こうなる。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/c36b0815-70d5-3546-5d2d-6abc6e141a1c.png)

きっつい。。。

フォントが横に長くて見づらい。
あとできればターミナルは黒背景であって欲しい。(趣味)

これをいい感じにするには、 `Settings` > `Terminal` から User Preferences を変更する。(設定ファイルを直接書き換えてもいい)

``` json:~/.jupyter/lab/user-settings/@jupyterlab/terminal-extension/plugin.jupyterlab-settings
{
  "fontFamily": "Monaco",
  "theme": "dark"
}
```

macOS なのでフォントは Monaco を指定しているが、ここは好きにすればよい。

設定を変更すると、こうなる。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/ce4b8752-b46d-26fd-07b7-374e6748070a.png)

いい感じになった。
【初心者】PHPで素数を出力する

# 素数を出力する
今回は、私が今持っている知識だけで、素数を出力できるのか考えた。
範囲を決めないと無限に出てきてしまうので、ひとまず1より大きくて10より小さい素数を出力できるか考えた。
結果は以下の通り。

```php
// 2よりも大きくて10よりも小さい数字それぞれを、同じ範囲のそれぞれの数字で割り切れる数字を抽出
    for ($i = 2; $i <= 10; $i++) {
        for ($j = 1; $j <= 10; $j++) {
            if ($i % $j === 0) {
                $nums[$i][] = $j;
            }
        }
    }
// 抽出した数字の中で、1と自身の数字でのみ割り切れる数字を抽出（割り切れた数字の数が2のもの）
    for ($i = 2; $i <= 10; $i++) {
        $count = count($nums[$i]);
        if ($count === 2) {
            $n_num[] = $i;
        }
    }
// 個数を数えて出力
    $n_count = count($n_num);
    for ($i = 0, $i < $n_count, $i++) {
        echo($n_num[$i])." ";
    }
// 以下出力結果です。
2 3 5 7 
```
結論としては、無事、1より大きくて10より小さい素数を出力することができました。これが、100より小さい場合でも対応はできていたので、問題ないと思う。
目的を持ってプログラムを書いてみると、自分にできることとできないことが明確になるので、もっと色々知識を身につけたいを思えた。

恐らく、今日私がやってみた方法は、あくまで私が今持っている知識で記述することが可能なのか、というテーマがあったので、本来ならば圧倒的に効率的な記述があるのだと思う。
Spring Boot Mybatis SQLのスネークケースカラムとキャメルケースのマッピング

SQLのカラム名はスネークケースでマッピング先のjavaはキャメルケースの場合、
mybatisで自動的にキャメル→スネークに変換してくれる設定。

# 結論

### 方法1

私はこれを使ってます。

```yml:application.yml
mybatis:
  configuration:
    map-underscore-to-camel-case: true
```

### 方法2

```properties:application.properties
mybatis.configuration.map-underscore-to-camel-case=true
```

### 方法3

```yml:application.yml
mybatis:
  config-location: classpath:/mybatis/mybatis-config.xml
```

```xml:mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>
```


# 参考実装

```java:Todo.java
class Todo {
    private Integer id;
    private String statusNm; // このフィールドに status_nm の値を入れたい
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getId() {
        return this.id;
    }
    public void setStatusNm(String statusNm) {
        this.statusNm = statusNm;
    }
    public String getStatusNm() {
        return this.statusNm;
    }
}
```

```java:TodoListMapper.java
@Mapper
public interface TodoListMapper {
    /**
     * リストを検索する。
     * @return TODOリスト
     */
    List<Todo> selectList();
}
```

```xml:TodoListMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hellospring.mapper.TodoListMapper">
  <select id="selectList" resultType="com.hellospring.domain.Todo">
    SELECT
      id
     ,status_nm
    FROM
      todo
  </select>
</mapper>
```

# 仕組み

MyBatisはスネークケースのカラム名をキャメルケースに変換し、キャメルケースに対応するsetterを呼び出してくれる。
ちなみにORACLEだとテーブル名やカラム名は大文字に揃えるが、大文字でもOK。

`status_nm` → `setStatusNm()`を呼び出す。
`STATUS_NM` → `setStatusNm()`を呼び出す。
要件の変更から製品ライフサイクル管理を参照してください

![微信图片_20201222105258.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/957964/0ef50345-5b3d-c8d1-31cd-ab8bd4a84945.jpeg)

ソース:https://wiki.mbalib.com/
 「要件」と「製品ライフサイクル」は、製品管理における2つの非常に重要な概念です。プロダクトマネージャーとして、仕事の大部分は彼らの周りで行われていますが、私たちの日常の仕事では、私たちは常にこれらの2つのタスクを独立して見て実行することに慣れていますが、実際には、これら2つの間に密接な関係がありますタスク。今日は、両者の関係についてお話します。
 議論を始める前に、製品ライフサイクルの概念を簡単に復習しましょう。通常、市場参入から上場廃止までの全工程を製品ライフサイクルと呼び、一般的に導入期間、成長期間、成熟度の4段階を含みます。サイクルごとに異なる製品戦略を採用し、異なるサイクル。
 実際、最終的な分析では、製品ライフサイクル管理は各サイクルを判断し、対応する戦略を策定することです。同時に、要件管理は製品のプロセス全体を通じて実行されることもわかっています。したがって、要件フェーズと製品ライフサイクルフェーズが必要です。接続された部分では、重要な問題が発生しました。この接続をどのように判断するかです。
最初に例を見てみましょう。

 LEDカラーテレビは、省エネ、環境保護、高解像度により、市場の主流になっています。しかし、LEDカラーテレビが発売されたばかりのときは、価格が比較的高かった。そのようなカラーテレビを購入できる消費者はまだ少数ですが、一部の消費者はまだ進んで行きます。この種の製品を購入するのはアーリーアダプターです。この段階で、消費者がこの種の製品を購入したいのであれば、基本的に選択肢は多くありません。

 しかし、LEDカラーテレビ技術の継続的な開発と継続的なコスト削減により、わずか数年でLEDカラーテレビは徐々に「キャベツ化」され、消費者はますます多くの選択肢を持っています。この段階で、消費者がそのような製品を購入したい場合、最終的な決定を下す前に、慎重に考え、さらに研究する必要があります。

 LEDカラーテレビの普及とパフォーマンス指標の継続的な改善に伴い、これらの製品を早期に購入した消費者はアップグレード要件を持ち始め、初期の購入経験と好みに基づいて新製品を購入しました。

 しかし、カラーテレビ技術の発展と消費者の視聴体験への新たな期待により、消費者は市場で新しいカラーテレビを探し始めています。これにより、液晶カラーテレビに代わるLEDカラーテレビのサイクルが生まれましたが、今では3Dカラーテレビが通常のLEDカラーテレビに取って代わり始めたなど、新しいカラーテレビ技術となっています。

この例では、最初に製品ライフサイクルの観点から分析します。

 LEDカラーテレビが市場に参入したばかりのとき、それは製品ライフサイクルの導入期間でした。LEDカラーテレビの開発に伴い、成長期に入り、大々的に普及し、成熟期に入り、ようやく衰退期に入りました。もちろん、LEDが衰退期に入ったとは言えません。

では、このプロセスで要件はどのように変化しますか？

 最初に導入期間を見ると、この段階で、消費者はLCDカラーテレビの欠陥に対する新たな視聴期待を持っていることがわかりますが、消費者はどのインジケータが含まれているかについて明確ではありませんが、カラーテレビ会社はカラーテレビの後にLEDを発売しています。彼らは、省エネ、グリーン、高解像度をセールスポイントとして使用し、オリジナルのLCDカラーテレビや新しいテレビを購入した消費者を引き付けました。

 現時点では、消費者は、視聴体験の向上を望んで、漠然としたニーズしか考えていません。このようなニーズには明確な好みはありませんが、既存のユーザーエクスペリエンスを向上させるためだけのものです。したがって、そのようなニーズは「一次要件」と呼ばれます。
技術の進歩とコストの削減により、ますます多くの企業がこの市場に参入し、消費者はこれらの製品に注目し始めています。したがって、消費者にとって、そのような製品を購入したいのであれば、彼らは市場に出ているはずです。あなたはより多くの選択肢を持つことができます。同時に、企業は、消費者の多様なニーズに対応し、パフォーマンス指標を継続的に改善し、生産コストを継続的に削減するために、新しい品種とモデルを導入し続けます。この段階では、このタイプの要件は「選択的要件」と呼ばれます。

 LEDカラーTVの普及に伴い、初期の購入者は交換の必要性を持ち始めました。現時点では、早期購入の経験とブランドの好みに基づいて選択を行います。この段階でのニーズは「反復ニーズ」と呼ばれます。
 同様に、消費者の視聴に対する要求が高まり続けるにつれて、当然、新しい要件が出現します。
 「要件」と「製品ライフサイクル」の関係を簡単にまとめます。
 製品ライフサイクルの導入期間では、消費者の要件は「主要な要件」です。
 製品ライフサイクルの成長期間中、消費者の要件は「選択的要件」です。
 製品ライフサイクルの成熟段階では、消費者の要件は「反復的な要件」です。

 製品ライフサイクルの不況期では、消費者の要件は「新しい要件」です。
 製品ライフサイクルのさまざまな段階でのこの種の要件の変化は、FMCG業界では特に明白です。では、実際の仕事で両者の関係を知ることの意味は何でしょうか。
 もちろん、製品ライフサイクル管理の最大の難しさは、製品がどの段階に入るのかを事前に決定することです。ステージの評価に現在使用されている指標には、「売上高、成長率、単価、ユーザーの購入意向、競争」などがあります。状況：ディーラーの意欲;利益の見通し」。要件と製品ライフサイクルステージの関係がわかっていれば、それを別の指標として使用して、要件変更の観点から製品ライフサイクルステージを評価できます。また、製品マネージャーは要件の変化に非常に敏感である必要があります。
 同様に、製品ライフサイクルの評価をツールとして使用して、製品ライフサイクルの段階の変化から要件の変化や種類を評価することもできます。

実際、製品管理では、製品ライフサイクルと要件の2つのタスクが関連しているだけでなく、多くのタスクが関連しています。プロダクトマネージャーとして、これらのタスク間のつながりを見つけ、協力的な協力関係を築くことができれば、実際の仕事に大きなメリットがあります。
UICollectionViewにLongPressGestureRecognizerで長押しをつける

長押ししたセルに任意の操作ができます。

こちらの記事を元にしています。
https://ofsilvers.hateblo.jp/entry/uicollectionview-and-long-press

```swift

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(onLongPressAction))
    longPressRecognizer.allowableMovement = 10
    longPressRecognizer.minimumPressDuration = 1
    self.collectionView.addGestureRecognizer(longPressRecognizer)
```

```swift
@objc func onLongPressAction(sender: UILongPressGestureRecognizer) {
        let point: CGPoint = sender.location(in: self.collectionView)
        let indexPath = self.collectionView.indexPathForItem(at: point)
        if let indexPath = indexPath {
        switch sender.state {
        case .began:
            print(indexPath)
        default:
            break
        }
    }
}
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
IOPS、スループット、レイテンシについて

# 背景
ネットワークの基礎的なところですが、簡潔な説明が少ない & 忘れがちな内容なため書きました。


# 目次
・IOPSとは
・スループットとは
・IOPSとスループットの最適化
・レイテンシとは
・スループットとレイテンシの関係

# IOPSとは
「ストレージが1秒あたりに処理できるI/Oアクセスの数」

# スループットとは
「単位時間あたりの処理能力（データ転送量）」
つまり、一定時間内にどれだけの量のデータを転送できるかという能力。
8Mbps = 8Mbit / 1s = 1Mbyte / 1s = 「1秒間に1MBのデータ転送ができる」ということ。

# IOPSとスループットの最適化
ディスクのスループットが大きければアプリケーションのパフォーマンスが必ず上昇するというわけではない。
- 小さいサイズのファイルを数多く書き込み/読み込みするような場合、`スループット`よりも`IOPS` の数値を重視した方がパフォーマンスが上がりやすい。
- 一度の書き込み/読み込みサイズが大きい場合、`スループット`を重視した方がパフォーマンスが上がりやすい。

# レイテンシとは
「処理や転送の際にかかる一回毎の遅延時間」
デバイスに対して、データ転送などを要求してから、その結果が返送されるまでの遅延時間。

# スループットとレイテンシの関係
- 連続して大量のデータを処理する場合は、`スループット`の性能が処理速度に深く関係する。
- 一方、双方向的に短いデータを取り扱い、応答を待ってやり取りするようなもの（通話やゲームなど）においては、`スループット`よりも`レイテンシ`が処理速度に深く関係する。
ToCとToBのUX改善の違い

みらい翻訳 Advent Calendar 2020には初登場の @gale_0420 です
UXディレクターとしてユーザ視点に立った機能改善を担当しています。
今回はこれまでUXデザイン分野を担当してきて感じる、ToCプロダクトとToBプロダクトのUX改善の違いを書いていきたいと思います。


ToCプロダクトの場合

ToCプロダクトとは、一般ユーザに対して価値提供を行うプロダクトをここでは指します。つまり、法人向けではないという意味です。
ToCプロダクトでは、基本的に今までの僕の経験上では、データ分析やユーザヒアリングを通してアジャイルな開発プロセスが適しているかなと思います。

つまり、企画検討はライトに行いリリースしてユーザのフィードバック(多くはプロダクト上での行動ログ)を通じPDCAを回していくというようなイメージです。
ToCプロダクトの特徴は、基本的にはマクロに改善していけば概ね改善されていくため、大抵はデータ分析による改善で大丈夫かなと感じています。

ToBプロダクトの場合

一方で、ToBプロダクトの場合はデータ分析ももちろん必要ですが、それだけでは足りず、顧客ヒアリングを徹底して行うことが重要になります。
理由としてはいくつかあります。
１つは、ToBの場合はプロダクトを使う人はビジネスシーンで使っているため、急に使い方が変わったりすると業務に支障が出るためです。
業務中も忙しいため使い方を理解するために時間を使うことも難しいですし、現場が混乱します。

また、法人の場合だと往々にしてビッグクライアントという存在があり、基本的には改善の方向性は合っていたとしても、特定のビッグクライアントには特殊な事情で何かが不適な場合にもハレーションのリスクになり得ます。

そのため、顧客ヒアリングを徹底してマクロかつミクロに最適な改善を行えているかを事前に確認する工程がとても重要になるかなと思います。

まとめ

まとめると、ToCプロダクトでは高速な改善が適している一方で、ToBプロダクトでは必ずしもそうではなく徹底した顧客ヒアリングも重要になります。何かするかも重要ですが、何かを生み出すためのプロセス自体の改善もまたとても重要です。引き続き、この部分の検討も行なっていく予定なので進展があればこちらで思考開示していきたいと思います。
Nuxt.js のサンプル (JSON の取り込み）

こちらと同様のことを Nuxt.js で行ってみました。
[Vue.js のサンプル (JSON の取り込み）](https://qiita.com/ekzemplaro/items/1d71020dfbc06b8a6adb)
入力のJSONは、同じ形式のものです。

実行結果
>![nuxt_dec22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/30554b88-0ab0-21e1-7213-e85de8393141.png)

プロジェクトの作成

```bash
npx create-nuxt-app proj01
```

pages/index.vue を次のように変更します。

```vue:pages/index.vue
<template>
  <section class="container">
      <h2>{{title}}</h2>

<table>
<tr v-for="(value,key) in cities">
    <td> {{key}} </td>
    <td> {{value.name}} </td>
    <td> {{value.population}} </td>
    <td> {{value.date_mod}} </td>
</tr>
</table>
	<hr>
	<pre>{{now}}</pre>

 </section>
</template>

<script>

import cities from '@/static/cities.json'


export default {
	data: function(){
	return {
		title: '栃木県の都市',
		now: 'お待ち下さい...',
		cities: cities,
		};
	},

	created: function (){
		setInterval(() =>{
	var d = new Date();
	this.now = d.getHours()
		+ ':' + d.getMinutes()
		+ ':' + d.getSeconds();
	},1000);
	},
};
</script>

<style>
.container {
	padding: 5px 10px;
}
h2 {
	font-size: 30pt;
	color: green;
}

p {
	padding-top:5px;
	font-size: 20pt;
	color: cyan;
}

pre {
	padding: 10px;
	font-size: 18pt;
	color: blue;
}

hr {
	margin:10px 0px;
}

</style>
```

```json:static/cities.json
{
  "t0921": {
    "name": "宇都宮",
    "population": 57214,
    "date_mod": "2012-4-12"
  },
  "t0922": {
    "name": "小山",
    "population": 31857,
    "date_mod": "2012-7-15"
  },
  "t0923": {
    "name": "佐野",
    "population": 94167200,
    "date_mod": "3920-7-28"
  },
  "t0924": {
    "name": "足利",
    "population": 31764,
    "date_mod": "2012-2-22"
  },
  "t0926": {
    "name": "下野",
    "population": 65792,
    "date_mod": "2012-9-12"
  },
  "t0927": {
    "name": "さくら",
    "population": 36251,
    "date_mod": "2012-3-21"
  },
  "t0928": {
    "name": "矢板",
    "population": 52186,
    "date_mod": "2012-7-26"
  },
  "t0929": {
    "name": "真岡",
    "population": 26857,
    "date_mod": "2012-10-2"
  },
  "t0930": {
    "name": "栃木",
    "population": 41893,
    "date_mod": "2012-12-20"
  },
  "t0931": {
    "name": "大田原",
    "population": 45289,
    "date_mod": "2012-2-7"
  },
  "t0932": {
    "name": "鹿沼",
    "population": 92354,
    "date_mod": "2012-5-17"
  },
  "t0933": {
    "name": "那須塩原",
    "population": 81567,
    "date_mod": "2012-6-19"
  },
  "t0934": {
    "name": "那須烏山",
    "population": 72158,
    "date_mod": "2012-8-14"
  }
}
```

サーバーの実行

```bash
yarn dev
```

ブラウザーで、http://localhost:3000/　にアクセス。
Mobile Blazor Bindings を使用したWindows版アプリケーションでタイトルバーを小さくする方法

# 概要
Mobile Blazor Bindingsを使用したWindows版アプリケーションのタイトルバー(下の画像の青い部分)の主張が激しいので、タイトルバーを小さくする方法について

* タイトルバーを小さくする前
![HoloViewer_2020-12-22_13-40-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74640/17615faf-002c-7697-724d-a3f0eaf5ffeb.png)

* タイトルバーを小さくした後
![HoloViewer_2020-12-22_13-41-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74640/7e7e5e5a-6236-3d49-6fae-79c3a661a2e4.png)

# 結論
PART_TopAppBar要素の高さを0にするとタイトルバーが表示されなくなる。

# 詳細
App.csのMainWindowクラスにWindows版アプリケーションの設定が書かれているのでそこで設定を変更する。

タイトルバーはPART_TopAppBarという名前で要素が設定されているので、その要素の高さを0にする。
また、アプリケーション名を表示したい場合は、PART_System_Title要素のテキストを変更することでアプリケーション名をウィンドウの左上に表示できる。
PART_System_Title要素はPART_CommandsBar要素の中にあるので、名前で検索すればOK。

2つの処理をまとめるとこんなコードになる。

```C#:App.cs
public class MainWindow : FormsApplicationPage
{
    // 省略

    protected override void OnActivated (EventArgs e)
    {
        base.OnActivated(e);

        var topAppBar = Template.FindName("PART_TopAppBar", this) as Xamarin.Forms.Platform.WPF.Controls.FormsAppBar; ;

        if (topAppBar != null)
        {
            topAppBar.Height = 0;
        }

        var commandsBar = Template.FindName("PART_CommandsBar", this) as System.Windows.Controls.Grid;

        if (commandsBar != null)
        {
            var titleTextBlock = commandsBar.FindName("PART_System_Title") as System.Windows.Controls.TextBlock;

            if (titleTextBlock != null)
            {
                titleTextBlock.Text = Application.MainPage.Title;
            }
        }
    }
}
```

# 終わり
記事を書いてる途中で、この問題ってBlazorじゃなくてXamarinの範囲ではとか思ったけど、ひとまず記事にはBlazorタグを付けておく
TexstudioによるBibtexコンパイル

Texstudioユーザーに向けて

#はじめに
Bibtex自体は非常に便利ですが、如何せん何度もコンパイルする必要があって面倒だ。一度コンパイルした後に.bibファイルの内容を変更してそのままコンパイルしても更新されないのが不便だったので何とかする方法を探してみた。

#方法
複数コンパイルをF5を一回押せば済むように設定すればよいので
[オプション]⇒[Texstudioの設定]⇒[ビルド]⇒[ビルド&表示]のところレンチマークをクリックすると画像のようなウィンドウが出現する。

![figure1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/582711/c5a75f4d-232d-3b36-2a6c-fa4817e5f198.png)

コマンドリストのように途中でBibtexを挟んでやるとそこで.bibファイルを読み込む作業が入るので更新されるというわけである。おそらくそうでない場合は、.auxファイルを読み込んでしまうので更新されない。多分。

#最後に
一旦できてしまうと初歩的なことに見えてしまうが、こういったことが全然わからんので備忘録として残しておく。
expressで、req.bodyがundefined になる件の解消

# エラー
#####① body-parser未指定
これは、あるpostリクエストで走る処理です。

```controller.ts
routeAction: async (req: Express.Request, res: Express.Response) => {
    console.log(req.body) // undefinedが返る。。
}
```
適切なbodyを込めてpostリクエストすると、以下のようなエラーが。
(node:42936) UnhandledPromiseRejectionWarning: ValidationError: set validation failed: title: Path `title` is required.
(個人的に)必須設定にしていた`title`パラメータがbodyに入ってないよ、と言われたので、じゃあ何が入ってるんだとreq.bodyを出力してみると、
なんとreq.body自体がundefined..
適切なbodyをリクエストで込めているのに。

#####②body-parser指定したが、指定タイミングミス
https://expressjs.com/en/4x/api.html#req.body
恐らくexpressで受け取れる形でリクエストに込めたbodyがうまくパースされて無いのではということで、
expressにbody-parse設定してみたが解決せず。.

```main.ts
import Express from 'express'

const app = Express();// create server
app.use('/', routeAction);// パス指定
// この行を追記
app.use(Express.json());// body-parser settings

// start server
const port = 3000;
app.listen(port, () => {
    console.log('server start');
});
```

# 解決方法: body-parserをパスより前に指定する。
どうやら、パース設定はパス指定時に確定されてしまうようでした。
ということで、パス指定前にbody-parserを設定することで解決。
ドキュメントから根拠は探せてはいないのですが。。

```main.ts
import Express from 'express'

const app = Express();// create server
// パス指定より前に指定する。
app.use(Express.json());// body-parser settings
app.use('/', routeAction);// パス指定

// start server
const port = 3000;
app.listen(port, () => {
    console.log('server start');
});
```