OmniAICreator/Qiita-1.07M huggingface dataset:
React NavigationでStackとModalを混在させる

### 目的
StackNavigatorとModalを混在させたい。

普通のStackがあり、そこでModalを開いてModalの中でStackで遷移していく。

具体定期にいうと
グロナビのそれぞれをModalで開いて、その中で画面遷移する

というイメージを実現したくなった。

### 結果

以下で説明あった。

https://reactnavigation.org/docs/nesting-navigators#nesting-multiple-navigators

流れは

- 複数のStackを読み込むためのRootとなるStackを用意 (createStackNavigator()1個)
- 必要なStackの数だけ、createStackNavigator()を実施
- 必要なStackのNavigationをfunctionで返すようにして
- RootStackをmodalモードにしてそれぞれのfunctionの戻りをcomponentに設定する
- 合わせて[options={{ headerShown: false }}]を設定しないと、ヘッダーが二重に出る。


という感じ。

以下例

```javascript

import React from 'react';
import HomeScreen from './screens/HomeScreen'
import ProjectListScreen from './screens/ProjectListScreen'
import ProjectEditScreen from './screens/ProjectEditScreen'

//navigation
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

const RootStack = createStackNavigator();
const HomeStack = createStackNavigator();
const ProjectStack = createStackNavigator();

export default function App() {

  //stack1
  const HomeRoute = () => (
    <HomeStack.Navigator initialRouteName="Home">
      <HomeStack.Screen
        name="Home"
        component={HomeScreen}
      />
    </HomeStack.Navigator>
  )
  
  //stack2
  const ProjectRoute = () => (
    <ProjectStack.Navigator initialRouteName="ProjectList">
      <ProjectStack.Screen name="ProjectList" component={ProjectListScreen} />
      <ProjectStack.Screen name="ProjectEdit" component={ProjectEditScreen} />
    </ProjectStack.Navigator>
  )

  return (
    <NavigationContainer>
      <RootStack.Navigator
        initialRouteName="Home" mode="modal"
      >
        <RootStack.Screen
          name="Home"
          component={HomeRoute}
          options={{ headerShown: false }}
        />

        <RootStack.Screen
          name="Project"
          component={ProjectRoute}
          options={{ headerShown: false }}
        />

      </RootStack.Navigator>
    </NavigationContainer>
  );
}


```

### 補足
ここをみると
https://reactnavigation.org/docs/nesting-navigators#best-practices-when-nesting

あまりネストはおすすめされてない様子。単純に複雑になっていくから。
Routingを整理したいなら、全部stackでいいから変数側で塊を作ったほうが良いと。

最初に考えた画面遷移も、なんとなくやりたかったけど、機能的には無くても問題ないし...全部stackでいいっちゃいいから。
複数のstackの塊だったら、tabナビゲーションでも良いかも。
エラー「None of PyTorch, TensorFlow >= 2.0, or Flax have been found.」の対処

こんなエラーが出ました。
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.

#環境
centOS7
python2.7.5
pip20.3.4
pip3のpip 21.0.1

#対処
・tensorflowのインストール
pip install tensorflow==バージョン（2.0以上）
・pytorchのインストール
pip install torch

私の場合tensorflowをインストールするときにpip3でもインストールしたためこのエラーが出ました。
調べたところ、pip3ではtensorflowのバージョンが2.0以上だったのに対して、pipは2.0以下でした。pipのtensorflowをremoveしたところうまくいきました。
【GitHub】gitのブランチ名をmacターミナルで表示させる

## gitのブランチ名をmacターミナルで表示させる

```
$ vim ~/.zshrc
```

```~/.zshrc
# git-promptの読み込み
source /Library/Developer/CommandLineTools/usr/share/git-core/git-prompt.sh

# git-completionの読み込み
fpath=(~/.zsh $fpath)
zstyle ':completion:*:*:git:*' script ~/.zsh/git-completion.bash
autoload -Uz compinit && compinit

# プロンプトのオプション表示設定
GIT_PS1_SHOWDIRTYSTATE=true
GIT_PS1_SHOWUNTRACKEDFILES=true
GIT_PS1_SHOWSTASHSTATE=true
GIT_PS1_SHOWUPSTREAM=auto

# プロンプトの表示設定(好きなようにカスタマイズ可)
setopt PROMPT_SUBST ; PS1='%F{green}%n@%m%f: %F{cyan}%~%f %F{red}$(__git_ps1 "(%s)")%f
\$ '
~
```

ターミナルを開き直して完了！

## Macのターミナルのユーザー名の変更
以下を実行
```~/.zshrc
export PS1="%1~ %# "
```
デフォルトに戻す場合
```~/.zshrc
export PS1="%n@%m %1~ %# "
```

## 参考
- Macのターミナルのユーザー名の変更
https://qiita.com/yosyosyoyoyo/items/f72d2df0deb120cf1e5f
WSLにEnsembl Variant Effect Predictor (VEP) をインストールしてみた

# Variant Effect Predictor (VEP)について
Variant Effect Predictor (VEP)は、ゲノムから得られたバリアントについて
アノテーションするためのソフトであり、ヨーロッパ分子生物学研究所の欧州バイオインフォマティクス研究所(EMBL-EBI）が開発しています。

# インストール方法
VEPのインストール方法については、[説明ページ](https://asia.ensembl.org/info/docs/tools/vep/script/vep_download.html#installer) を参照してください。
Dockerも提供されているので、これが便利かと思います。
この記事は、WSLにVEPをマニュアルでインストールした際に詰まったところを備忘録的に書いたものです。
まずは、WSLをインストールして起動してください。

# マニュアルインストールに必要なライブラリの事前準備

ライブラリをインストールする前に、おまじない

``` 
sudo apt-get update 
```
次に、必要なライブラリとPerlのCPANモジュールをインストールします。
gcc, g++, make

```  
sudo apt-get install build-essential 
```
Perl version 5.10 以上
　すでにPerl 5.30が入っていました。
次に、PerlのCPANモジュールをインストール

``` 
cpan App::cpanminus 
```

これでPerlモジュールをCPAN(モジュールの集積所)から取れるようになるので、
Archive::Zip, DBD::mysql, DBIの3つを以下のコマンドでインストールします。

```
 cpan Archive::Zip
 cpan DBD::mysql 
 cpan DBI 
```


自分の環境では、DBD::mysqlをインストールしたときに
> 'YAML' not installed, will not store persistent state
> Configuring D/DV/DVEEDEN/DBD-mysql-4.050.tar.gz with Makefile.PL
> Can't exec "mysql_config": No such file or directory at Makefile.PL line 89.
> 
> Cannot find the file 'mysql_config'! Your execution PATH doesn't seem
> not contain the path to mysql_config. Resorting to guessed values!

とエラーが発生しました。　
YAMLとmysql_confgが無いと言っているので、
YAMLは

```  
cpan YAML
``` 
と打って、インストールします。
mysql_configは [このサイト](https://techglimpse.com/cant-exec-mysql_config-makefile-solution/)を参照して、
以下のコマンドでインストールできました。

```
sudo apt-get install libmysqlclient-dev 
``` 

その後、もう一度、
``` cpan DBD::mysql ```
とすると、先ほどエラーの出ていたインストールできました。

# インストール
あとは、インストールのインストラクションに従って、

``` 
git clone https://github.com/Ensembl/ensembl-vep.git
cd ensembl-vep
perl INSTALL.pl
```
とします。この時、以下のメッセージが出ることがありますので、
> ERROR: Unable to unpack file ./Bio/tmp/release-1-6-924.zip without Archive::Extract or tar/unzip/gzip

Archive::ExtractをCPANから取ってきます。

```
cpan Archive::Extract
```

この後、再度 INSTALL.plを実行したところ、
> Attempting to install Bio::DB::HTS and htslib.
> If this fails, try re-running with --NO_HTSLIB
> bzlib.h, lzma.h library header(s) not found in /usr/include. Please install it and try again.
> (or to skip Bio::DB::HTS/htslib install re-run with --NO_HTSLIB)

と出ましたので、 Bio::DB::HTSをインストールします。

``` 
cpan Bio::DB::HTS
```
でもって、

```
perl INSTALL.pl
```

とすると、HTSLibが無いというエラーが出るので、
[このページ](https://asia.ensembl.org/info/docs/tools/vep/script/vep_download.html#installer)を参照してHTSLibをインストールする、もしくは、HTSLibのインストールをあきらめて

```
perl INSTALL.pl  --NO_HTSLIB
```
としてインストールを進めてください。(HTSLibは、bgzipで圧縮されたFASTAファイルの読み取りの時間短縮に用いられるものですので、大量のバリアントデータをさばかない人には不要かと思います。)
HTSLibをインストールする際にも、XML::Parserなどでエラーが出ることがあるかもしれませんが、
都度、

```
cpan XML::Parser
```
とすることで不足しているモジュールをインストールすれば解決すると思います。


# 最後に
なんでDockerがあるのにマニュアルインストールをしているの？と聞かれそうですが、
Windows home買っちゃってDockerがうまく動かないんです（泣）
〜を含むという表現をif文で使いたい時


フラグを立てて判定しましょう。

もし現金が含めれている時フラグを一度でも通過すればフラグの値が変わります。

そして処理が終わった時に

        if flg{
            やりたい処理１
        }

みたいな感じでやれば含まれたときの処理ができます。

含まれたっていう表現がないので結構詰まりました。

ただフラグを立てすぎるとどこのフラグかわからないみたいなことになるみたいです。

参考までに
git clone時にssh秘密鍵を指定する

```
git -c core.sshCommand="ssh -i ~/.ssh/YOUR_RSA" clone git@github.com:YOUR_NAME/YOUR_REPO.git
```

参考
https://stackoverflow.com/questions/4565700/how-to-specify-the-private-ssh-key-to-use-when-executing-shell-command-on-git
Elixirの革新的ライブラリ「Nx」をMacでも動かしてみた

Elixirで機械学習/ディープラーニングができるようになるライブラリ「[Nx](https://github.com/elixir-nx/nx/tree/main/nx)」をMacで動かしてみました。この記事は、@piacerex さんの投稿 [Elixirでディープラーニング①：革新的ライブラリ「Nx」の導入](https://qiita.com/piacerex/items/db33fbe80751fdd30e48) に触発されたものです。

# 検証環境

- macOS Big Sur
  - MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)
  - CPU: 2.3 GHz クアッドコア Intel Core i5
  - Memory: 16 GB 2133 MHz LPDDR3
  - Graphics: Intel Iris Plus Graphics 655 1536 MB
- Elixir 1.11.3
- Erlang 23.2.5

余談ですが、私はElixir含めバージョン切り替えが必要なものはすべて [asdf](https://github.com/asdf-vm/asdf) でインストールしています。Macユーザならhomebrewでasdfをインストールできるので、特に躓くことはないかと思います。

# NXのインストール

手順は元記事とまったく同じです。まずはMixプロジェクトを作成します。

```
$ mix new nx_review
$ cd $_
```

Nxをdepsに追加します。

```elixir:mix.ex
defmodule NxReview.MixProject do
  use Mix.Project
…
  defp deps do
    [
      {:nx, "~> 0.1.0-dev", github: "elixir-nx/nx", sparse: "nx"}
    ]
  end
…
```

依存ライブラリをインストールし、コンパイルしてみましょう。

```
$ mix do deps.get, compile
* Getting nx (https://github.com/elixir-nx/nx.git)
remote: Enumerating objects: 71, done.        
remote: Counting objects: 100% (71/71), done.        
remote: Compressing objects: 100% (60/60), done.        
remote: Total 6158 (delta 24), reused 27 (delta 9), pack-reused 6087        
==> nx
Compiling 17 files (.ex)
Generated nx app
==> nx_review
Compiling 1 file (.ex)
Generated nx_review app
```

Windowsではコンパイルに失敗するようですが、Macでは問題なくコンパイルできました 🎉

# 実行

iexで行列と微分を試してみます。

```elixir
$ iex -S mix
iex> matrix = Nx.tensor( [ [ 0.123, 0.456 ], [ 0.789, 1.234 ] ] )
#Nx.Tensor<
  f64[2][2]
  [
    [0.123, 0.456],
    [0.789, 1.234]
  ]
>
iex> matrix
#Nx.Tensor<
  f64[2][2]
  [
    [0.123, 0.456],
    [0.789, 1.234]
  ]
>
iex> Nx.divide( Nx.exp( matrix ), Nx.sum( Nx.exp( matrix ) ) )
#Nx.Tensor<
  f64[2][2]
  [
    [0.135520130365152, 0.18907054376721744],
    [0.26378125835705013, 0.4116280675105804]
  ]
>
```

正常に動いて元記事と同様の結果が出力されました。

# 最後に

Nxを試してみたリポジトリをGitHubに置いているので、よければご覧ください。
https://github.com/mokichi/nx_review
RでReal estate valuationの基礎分析

# はじめに
UCI 機械学習リポジトリの[Real estate valuation](https://archive.ics.uci.edu/ml/datasets/Real+estate+valuation+data+set)データについて基礎分析を行ったので、そのまとめをつらつらと書いていく。データの加工は行わずに基礎統計量の算出と可視化を行っていく。

# データの読み込みと概要の確認

xlsxのデータを読み込み、その概要を`str`関数でチェックする。ついでに必要なパッケージを読み込んでおく。

```R:コード
library(openxlsx)
library(dplyr)
library(ggplot2)
library(GGally)

df <- read.xlsx("./Real_estate_valuation_data_set.xlsx")
str(df)
```

```:出力
'data.frame':	414 obs. of  8 variables:
 $ No                                    : num  1 2 3 4 5 6 7 8 9 10 ...
 $ X1.transaction.date                   : num  2013 2013 2014 2014 2013 ...
 $ X2.house.age                          : num  32 19.5 13.3 13.3 5 7.1 34.5 20.3 31.7 17.9 ...
 $ X3.distance.to.the.nearest.MRT.station: num  84.9 306.6 562 562 390.6 ...
 $ X4.number.of.convenience.stores       : num  10 9 5 5 5 3 7 6 1 3 ...
 $ X5.latitude                           : num  25 25 25 25 25 ...
 $ X6.longitude                          : num  122 122 122 122 122 ...
 $ Y.house.price.of.unit.area            : num  37.9 42.2 47.3 54.8 43.1 32.1 40.3 46.7 18.8 22.1 ...
```

# 統計量の算出
`summary`関数でも出力できるが標準偏差などが無いので、その項目を作っていく。

```R:コード
classes <- df %>% summarise_all(class) %>% t()
classes
```

```:出力
                                       [,1]     
No                                     "numeric"
X1.transaction.date                    "numeric"
X2.house.age                           "numeric"
X3.distance.to.the.nearest.MRT.station "numeric"
X4.number.of.convenience.stores        "numeric"
X5.latitude                            "numeric"
X6.longitude                           "numeric"
Y.house.price.of.unit.area             "numeric"
```

No まで numeric 判定になっていることが気になるが、まぁ大きく支障はないと考え次に進める。全変数がnumericなので、特にフィルタもかけることなく統計量を計算していく。

```R:コード
means <- df %>% summarise_all(mean) %>% t()
vars <- df %>% summarise_all(var) %>% t()
sds <- df %>% summarise_all(sd) %>% t()
qs <- df %>% summarise_all(quantile) %>% t()
colnames(qs) <- c("min", "q14", "median", "q34", "max")
is.nas <- df %>% is.na %>% as.data.frame %>% summarise_all(sum) %>% t()
is.not.nas <- nrow(df)-is.nas

Statistics <- data.frame(
  classes=classes,
  is.nas=is.nas,
  is.not.nas=is.not.nas,
  means=means,
  vars=vars,
  sds=sds,
  qs
)

write.csv(x=Statistics, file="summary.csv")
```
これで統計量をsummary.csv に出力した。エクセルで表を少し直すとこんな感じになる。
![Summary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/16ac1098-f03f-fbc9-17f3-d93a2cc679e3.png)

# pairplot の作成
各項目の相関、散布図、ヒストグラムを確認するためpairplotを作成する。これも関数で1行で実装できる。非常に便利。

```R:
ggpairs(df)
```
![R_pairplot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1077734/d5d2e2ee-a0c2-69ea-a2ee-b4686b9e0dbd.png)


# 参考文献
[【Rメモ】多変数の関係性を視覚化する関数（パッケージ）まとめ](https://qiita.com/h_kobayashi1125/items/46bc28a26f888d03cee3)
OCI Vaultで電子署名を行う

OCI Vaultでは、RSAの鍵に対応しているので、デジタル署名をすることが可能です。ここではOCI CLIを利用した手順を紹介します。REST APIやJava,Python,.NetといったOCI SDKなどでも同様の操作が可能です。


- VaultにRSAのキーを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/3a188f2b-00c5-fbdb-c732-0457e41b13a5.png)


```
#デジタル署名をするファイルのメッセージダイジェストを取得。ここではbash_profileファイルを対象にしてみます
$ openssl sha256 .bash_profile
SHA256(.bash_profile)= b409c002d01b605d1587ff85af898e26550da8682bb0321af74e1009368df408

#デジタル署名の実行
oci kms crypto signed-data sign --key-id RSAキーのOCID  --message "メッセージダイジェスト"  --signing-algorithm 署名アルゴリズム --endpoint 暗号エンドポイントURL

$ oci kms crypto signed-data sign \
 --key-id ocid1.key.oc1.iad.bfqcupa5aaeuk.abuwcljrgnub2puol6vsmfbqzfrficwiv7uityihguw25wwdzbf455qcc7nq \
 --message "b409c002d01b605d1587ff85af898e26550da8682bb0321af74e1009368df408" \
 --signing-algorithm  SHA_224_RSA_PKCS_PSS \
 --endpoint https://xxxxxxxx-crypto.kms.us-ashburn-1.oraclecloud.com

#結果　signatureがデジタル署名
{
  "data": {
    "key-id": "ocid1.key.oc1.iad.bfqcupa5aaeuk.abuwcljrgnub2puol6vsmfbqzfrficwiv7uityihguw25wwdzbf455qcc7nq",
    "key-version-id": "ocid1.keyversion.oc1.iad.bfqcupa5aaeuk.aumnmavw3rqaa.abuwcljrhvhnzcfgh7k5uqetk74mlrku34igesose2wyl47cb7kqop2nue3a",
    "signature": "VOuHEvUA+YORNVtxm6GE18VsEEAW7/z6QbcZNqUFfHQ8HJPHloNym7Am/iaYC0uWyoAtNfiV2or1f884XAw7hhMYZ7LUylDwuI3wmCpuBAx6vLVUnIYKiJtSiu6DK9O+NlR92yuB3H695GxXTwl5MQnM8USwU1Hfju0fcRCnVvHTIRbV/xFkz6kdgmzJGgVwvS6ac/+hG1ELbBKdU/WhyzSDa+ZkfTnuJqzD+kBUpfkyPjqKdPUBqCYMYHJwQzy6bj05igrZbBnhzmoOHiUQ28TWb2/y1OFN8rNnZkHbX6W+NLBV22EOUYVe5OAZoKrMIRTZfRjX2ltfbXtDkM3EBw==",
    "signing-algorithm": "SHA_224_RSA_PKCS_PSS"
  }
}


#デジタル署名の検証
oci kms crypto verified-data verify --key-id RSAキーのOCID --message "メッセージダイジェスト"　--signature デジタル署名 --signing-algorithm  署名アルゴリズム --key-version-id デジタル署名実行時のkey-version-id

$ oci kms crypto verified-data verify \
 --key-id ocid1.key.oc1.iad.bfqcupa5aaeuk.abuwcljrgnub2puol6vsmfbqzfrficwiv7uityihguw25wwdzbf455qcc7nq \
 --message "b409c002d01b605d1587ff85af898e26550da8682bb0321af74e1009368df408" \
 --signature "VOuHEvUA+YORNVtxm6GE18VsEEAW7/z6QbcZNqUFfHQ8HJPHloNym7Am/iaYC0uWyoAtNfiV2or1f884XAw7hhMYZ7LUylDwuI3wmCpuBAx6vLVUnIYKiJtSiu6DK9O+NlR92yuB3H695GxXTwl5MQnM8USwU1Hfju0fcRCnVvHTIRbV/xFkz6kdgmzJGgVwvS6ac/+hG1ELbBKdU/WhyzSDa+ZkfTnuJqzD+kBUpfkyPjqKdPUBqCYMYHJwQzy6bj05igrZbBnhzmoOHiUQ28TWb2/y1OFN8rNnZkHbX6W+NLBV22EOUYVe5OAZoKrMIRTZfRjX2ltfbXtDkM3EBw==" \
 --signing-algorithm  SHA_224_RSA_PKCS_PSS \
 --key-version-id ocid1.keyversion.oc1.iad.bfqcupa5aaeuk.aumnmavw3rqaa.abuwcljrhvhnzcfgh7k5uqetk74mlrku34igesose2wyl47cb7kqop2nue3a \
 --endpoint https://xxxxxxxx-crypto.kms.us-ashburn-1.oraclecloud.com

#結果
{
  "data": {
    "is-signature-valid": true
  }
}
```
[OCI Vaultに暗号化キーをインポートする](https://qiita.com/western24/items/06271c09a17e566661e8)
[OCI CLI Command Reference](https://docs.oracle.com/en-us/iaas/tools/oci-cli/2.21.1/oci_cli_docs/index.html)
レビュープロセス

# 見積もり
タスク洗い出し
↓
★レビュー

# 実装
実装
↓
★プルリクレビュー
↓
マージ

# テスト
テスト仕様書作成
↓
★テスト仕様書観点漏れレビュー
↓
テスト

# リリース
リリース計画書作成
↓
★レビュー
↓
リリースノート作成
↓
★レビュー
↓
リリース
laravel sail でadminerを使う

#結論
https://qiita.com/59e592291982460/items/a2e8e738c8ff7230b894
注意点：はじめて、sail upする前に.envのDB_PASSWORDを設定しておく。
adminerは、パスワードが設定されていないとログインできない

①`docker-compose.yml`の`services`に以下を追加する。

```yml
adminer:
    container_name: adminer
    hostname: adminer
    image: adminer
    restart: always
    ports:
        - 8080:8080
    depends_on:
        - mysql
    networks:
        - sail
```

②`sail up`をする。
③`http://localhost:8080/`にアクセス。
④`ログイン画面`は以下のように設定

 - `サーバ`はmysql（servicesのmysqlのサービス名）
 - `ユーザ名`はroot
 - `パスワード`は自分で設定したもの
【Linux】パーミッションを分かりやすく説明したい

## はじめに
Linux と書きましたが、MacOS でも大体一緒です。
初心者向けにできるだけ分かりやすく説明したいと思います。

環境構築をしたりするときに以下のような謎のコマンドを見て

~~~
$ chmod 777 foo.text
~~~

「権限の変更をしてるらしいが、 `777` ってどういう意味?」と思ったり

`ls -l` を実行すると

~~~
$ ls -l sample.rb
-rw-r--r--  1 taro  staff  176  2 18 12:00 sample.rb
~~~

`-rw-r--r--` ってなんだ..?

ということがあると思います。


## パーミッションとは何か

パーミッションとは

**所有者・グループ・それ以外** が ファイルやディレクトリに対して **読取・書込・実行**
を行えるかどうかの許可があるかどうかです。

※所有者とは何か、グループとは何かなどについてはググってみてください。
※ディレクトリの読取・書込・実行 とは何? ってなった方もググってみてください、ここでは割愛します。

例えば...

>**所有者** は **読取・書込・実行** 全てがができる
**グループ** は **読取・実行** だけができる
**それ以外** は **読取** だけができる

などです。

ちなみに上記の例でいうとファイルの権限は `-rwxr-xr--` や `754` と表されます。


## 謎の記号 `-rwxr-xr--` や `754` についての説明

### `-rwxr-xr--`(アルファベット + ハイフン形式)
こちらについてはなんとなく想像つくかもしれません。

`r` が読取、 `w` が書込、 `x` が実行を表しています。

こちらを分解すると以下のようになります。

|1文字目|2~4文字目|5~7文字目|8~10文字目|
|-|-|-|-|
|ファイル or ディレクトリ|所有者|グループ|それ以外|
|- (ファイル)|rwx (読・書・実)|r-x (読・実)|r-- (読)|

この表を見ればもう大丈夫だとは思いますが、一応解説します。

1文字目はファイルかディレクトリかを表しています。ファイルの場合は `-` 、ディレクトリの場合は `d` で表されます。
もし上記がディレクトリの権限だったら `drwxr-xr--` になります。


### `754`(数字３桁形式)

こちらについては初見では全く想像がつかないと思います。

こちらも分解してみましょう。

|1文字目|2文字目|3文字目|
|-|-|-|
|所有者|グループ|それ以外|
|7|5|4|

この表のようになります。

所有者 → グループ → それ以外の順で表現しているのは `-rwxr-xr--` の形式の場合と一緒ですね。

しかし、

「いやいや、数字一桁だけで読取・書込・実行それぞれの権限が表せるのかよ...」

と思った方もいるかもしれませんが...

**読取**を`4`、**書込**を`2`、**実行**を`1`としてその和で表現すると表せます。

例えば...

7 の組み合わせは 4 + 2 + 1 の一通りで 権限は **読取・書込・実行** となります。

6 の組み合わせは 4 + 2 の一通りで 権限は **読取・書込** となります。

5 の組み合わせは 4 + 1 の一通りで 権限は **読取・実行** となります。

こんなふうに **読取**を`4`、**書込**を`2`、**実行**を`1`と定義してその和で表すことで、数字一桁でも3つの権限の表現ができるんですね。

## 覚えるコツ(余談)

自分は、
「読み書き実行4・2・1!、読み書き実行4・2・1! ~ 」と繰り返し唱えたら1分ほど覚えました。

※ 特に覚えなくてはならないわけではないですが、よく使うので覚えるのをおすすめします。

## 練習問題

`644` の所有者・グループ・それ以外のそれぞれの権限は何か?

（※答えはググってください!）
Javascriptで1~99までの配列を作る

[1,2,3,......,98,99]という配列が必要になったので作ってみる。

# 方法１　全部書く

```javascript:app.jp

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 61, 62,
63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 
84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99];
```
とっても素朴。

# 方法２　ループ処理

## （１） whileを用いる
```javascript:app.jp

const numbers = [];
let number = 1;
while(number < 100) {
    numbers.push(number);
    number += 1;
}
```
空の配列に１から９９まで追加
## （２） forを用いる
```javascript:app.jp
const numbers = [];
for (number = 1; number < 100; number += 1){
  numbers.push(number);
}
 ```
同上

# 方法３　Arrey.fromを用いる
Arrey.from関数なるものがあって、これにより一発でいけるようだが、一見して理解できなかったのでまた学習が進めたあとの宿題としておきます。
Nuxt.jsでハンバーガーメニュー実装

# Nuxt.jsでハンバーガーメニュー実装

## 各ファイルの記述例

toggle用の要素`class="header__toggle_open"`と開閉するメニュー`class="header-nav`を用意する
※クラス名は自由です。その他のファイルの該当部分と一致させるようにしてください

```vue:compunents/Header.vue
<template>
  <header class="header">
    <div class="header-container">
      <span class="logo">Title</span>
      <div class="header__toggle_open bg-img" @click="$store.commit('toggleMenu')" :class="{'is-active': $store.state.isMenuActive}"></div>
      <ul class="header-nav" :class="{'is-active': $store.state.isMenuActive}">
        <li class="header-nav__list"><a class="header-nav__list-link" href="/">ホーム</a></li>
        <li class="header-nav__list"><a class="header-nav__list-link" href="/about">会社詳細</a></li>
        <li class="header-nav__list"><a class="header-nav__list-link" href="/blog">ブログ</a></li>
        <li class="header-nav__list"><a class="header-nav__list-link" href="/price/">プラン・料金</a></li>
        <li class="header-nav__list"><a class="header-nav__list-link" href="/contact">お問い合わせ</a></li>
      </ul>
    </div>
  </header>
</template>
```

当てているCSSは以下の通りです。これだとメニューが右にはみ出して、その幅分ブラウザが横にずれるので、htmlとbodyに`overflow-x: hidden;`を付与してずれないようにしています。
※他に上手いやり方があったら教えてください🙇‍♂️

```scss:*.scss
.header__toggle_open {
  cursor: pointer;
  width: 24px;
  height: 24px;
  background-image: url(../images/svg/memu.svg);
  z-index: 999;

  &.is-active {
    background-image: url(../images/svg/close.svg);
  }
}


.header-nav {
  // 親要素に position: relative;
  // html, bodyに overflow-x: hidden;
  background-color: $bgcolor-main;
  color: $font-color-sub;
  display: block;
  left: 100%;
  padding: 50px 20px;
  position: absolute;
  top: 0;
  width: 100vw;
  height: 100vh;
  z-index: 1;
  transition: 0.3s left;

  &.is-active {
    left: 0;
    transition: 0.3s left;
  }
```



`store/index.js`をstore内に作成し、以下の通り記述する
たぶんコピペで動くはず

```js:store/index.js
import Vuex from 'vuex'

const store = () => new Vuex.Store({
  state: {
    isMenuActive: false
  },
  mutations: {
    toggleMenu (state) {
      state.isMenuActive = !state.isMenuActive
    },
    resetMenu (state) {
      state.isMenuActive = false
    }
  }
})

export default store
```

ここまでだと、ページ遷移後もメニューが開きっぱなしになるので、`pages`フォルダ内の全てのvueファイルに下記を追記する

```vue:pages/**/*.vue
<template>
  // 省略
</template>

<script>
export default {
  fetch ({store}) {
    store.commit('resetMenu')
  }
}
</script>
```

## 最後に
あくまでも自分用のメモです
上手くいかないなどあれば教えてください

もっといい方法があればご教授ください🙇‍♂️
Db2:スキーマの差異を見つけたい

# 背景と状況
本番用データベースとテスト用データベースとでテーブルのスキーマが異なっていることはありませんか。列幅が違う、列の並びが違う、列が不足している等です。テーブルが300くらいあると比較するのが大変です。
# やりたいこと
異なるデータベースのスキーマを比較して違いを見つけたい。要はテーブルを比較してレイアウトの違いを確認したい。
IBM Db2 V11.5 Windwosで確認しています。
# やり方
Db2のシステムテーブルからスキーマ情報を取得してテキストファイルに出力、テキスト比較ツールで比較します。

1. SQLを作るSQL
2. スキーマ情報をファイルに出力
3. テキスト比較ツールで比較

# SQLを作るSQL
まずはテーブルの一覧を取得してテーブルごとにスキーマ情報をファイルに出力するSQLを作成します。比較対象から外すテーブルをwhere条件で指定しています。

```sql:Table_SYSCAT.sql
SELECT 'EXPORT TO ' 
       || Rtrim(tabname) 
       || '.txt of del ' 
       || 
' select TABNAME, COLNAME, TYPENAME, LENGTH, NULLS from  SYSCAT.COLUMNS where TABNAME = ''' 
|| Rtrim(tabname) 
|| '''  order by COLNO;' 
FROM   syscat.tables 
WHERE  TYPE = 'T' 
       AND tabschema = 'DB2ADMIN' 
       AND tabname not LIKE 'ADVISE_%' 
       AND tabname not LIKE 'EXPLAIN_%' 
       AND tabname not in  ('OBJECT_METRICS')
ORDER  BY tabname; 
```

以下のコマンドでSQLを作成します。out.sqlというファイルが作成されます。
`db2 -txf Table_SYSCAT.sql -z out.sql`

```sql:out.sql
EXPORT TO MST_TBL_CURRENT.txt of del  select TABNAME, COLNAME, TYPENAME, LENGTH, NULLS from  SYSCAT.COLUMNS where TABNAME = 'MST_TBL_CURRENT'  order by COLNO;                                                                                                                                                                                                                                  
EXPORT TO MST_TBL_NEW.txt of del  select TABNAME, COLNAME, TYPENAME, LENGTH, NULLS from  SYSCAT.COLUMNS where TABNAME = 'MST_TBL_NEW'  order by COLNO;                                                                                                                                                                                                                                          
EXPORT TO SND_TBL.txt of del  select TABNAME, COLNAME, TYPENAME, LENGTH, NULLS from  SYSCAT.COLUMNS where TABNAME = 'SND_TBL'  order by COLNO;                                                                                                                                                                                         

```
テーブルごとにスキーマ情報をファイルにエクスポートするSQLです。

# スキーマ情報をファイルに出力
以下のコマンドを本番用データベースとテスト用データベースとでそれぞれ実行し、別々のフォルダーにスキーマ情報をエクスポートします。
`db2 -tvf out.sql`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698263/d43d795c-678f-4230-dc84-906d6eb8436b.png)

# テキスト比較ツールで比較
フォルダーごとテキスト比較ツールで比較します。例では、[WinMerge](https://winmergejp.bitbucket.io/ "WinMergeのウェブサイトへ")を使って比較しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698263/ce700a70-d2cf-22e4-372f-4d2ecb5b6bec.png)
テーブルのレイアウトをファイル比較しているので違いがあれば色が変わって一目瞭然で発見できます。この例ではすべて同じです。
ファイルをクリックして中身を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698263/1c1c55f7-da05-14cd-7ecf-31b8b15d1884.png)
テーブルごとに列名、型、列幅、ヌルの許容を比較することになります。
動的計画法を理解したい

#動的計画法
与えられた問題に対して部分問題に上手に分割し、メモ化しながら与えられた問題を解く方法のことを言います。解決できる問題の幅が広いが習得するのが難しいです。問題の分解方法に注目して練習を積み重ねます。
###AtCoder Educational DP Contest A-Frog 1  [問題](https://atcoder.jp/contests/dp/tasks/dp_a)
N個の足場があって,i=(0,1,2,3,4...,N-1)番目の高さはh_iで与えられます。最初0番目の足場にカエルがいて、以下のいずれかの行動を繰り返してN-1番目の足場を目指します。
・足場iから足場i+1へと移動する(コストは|h_i-h_{i+1}|)
・足場iから足場i+2へと移動する(コストは|h_i-h_{i+2}|)
カエルがN-1番目の足場にたどり着くまでに要するコストの総和の最小値を求めてください。
####example
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/839966/d620d00a-db69-a67c-48e1-9a2411fbab5a.png">
N=8,h=(3,4,9,5,10,8,5,12)
カエルは「次の足場に行く」と「1個飛ばした足場に行く」という2つの選択肢があります。
足場間の移動を「矢印」で、その時のコストを「重み」として表現します。
そうすると、以下のように問題を書き換えることができます。
__問題__
頂点0から頂点7まで移動するとき、たどった各辺の重みの総和の最小値を求めてください。
``この問題を7つの問題に分けます。``
__問題0__:0に移動する時の重みの総和の最小値を求めなさい
__問題1__:0→1に移動する時の重みの総和の最小値を求めなさい
__問題2__:0→2に移動する時の重みの総和の最小値を求めなさい
__問題3__:0→3に移動する時の重みの総和の最小値を求めなさい
__問題4__:0→4に移動する時の重みの総和の最小値を求めなさい
__問題5__:0→5に移動する時の重みの総和の最小値を求めなさい
__問題6__:0→6に移動する時の重みの総和の最小値を求めなさい
__問題7__:0→7に移動する時の重みの総和の最小値を求めなさい
#解説
「1つ進んだ時の重みをp」「2つ進んだ時の重みをq」とすると
問題0の解は、進んでいないので0
問題1の解は、問題0の解+p
問題2の解は、(問題1の解+p)と(問題0の解+q)を比較した時の小さい方
問題3の解は、(問題2の解+p)と(問題1の解+q)を比較した時の小さい方
問題4の解は、(問題3の解+p)と(問題2の解+q)を比較した時の小さい方
問題5の解は、(問題4の解+p)と(問題3の解+q)を比較した時の小さい方
問題6の解は、(問題5の解+p)と(問題4の解+q)を比較した時の小さい方
問題7の解は、(問題6の解+p)と(問題5の解+q)を比較した時の小さい方

これを最小コストの配列dpを使って表すと

問題0の解は、dp[0]=0
問題1の解は、dp[1]=dp[0]+p
問題2の解は、dp[2]=min((dp[1]+p),(dp[0]+q))
問題3の解は、dp[3]=min((dp[2]+p),(dp[1]+q))
問題4の解は、dp[4]=min((dp[3]+p),(dp[2]+q))
問題5の解は、dp[5]=min((dp[4]+p),(dp[3]+q))
問題6の解は、dp[6]=min((dp[5]+p),(dp[4]+q))
問題7の解は、dp[7]=min((dp[6]+p),(dp[5]+q))

これをコードにすると

```c++

#include <bits/stdc++.h>
using namespace std;
const long long INF=1LL<<60;

int main(){
    //入力
    int N;
    cin>>N;
    vector<long long> h(N);
    for (int i=0;i<N;++i)cin>>h[i];

   //重みの最小値を格納する配列dpを定義
    vector<long long> dp(N,INF);
    dp[0]=0;

    for(int i=i;i<N;++i){
        if (i==1)dp[i]=abs(h[i]-h[i-1]);
        else dp[i]=min(dp[i-1]+abs(h[i]-h[i-1]),dp[i-2]+abs(h[i]-h[i-2]));
    }
    cout<<dp[N-1]<<endl;    
}
```
Swiftで数字の桁数をゼロ埋めする方法


            format: "%04d",欲しい変数名)

String(format: "%04d", 1)       // -> 0001

上記のように数字をそのまま入れることも可能です。

0埋めって言うから、先頭に0を入れて入力してレビュー出したら、formatを使えと言われたので、こちらを使いました。

レビューもオッケーでした。
laravel sailでbrowser-syncを使う、sail yarn watchを動かす

#解決法
以下のように、laravel.testのportsに3000を追加しました。

```yml
services:
    laravel.test:
        build:
            context: ./vendor/laravel/sail/runtimes/8.0
            dockerfile: Dockerfile
            args:
                WWWGROUP: "${WWWGROUP}"
        image: sail-8.0/app
        ports:
            - '${APP_PORT:-80}:80'
            - '3000:3000' ###ここを追加しました
        environment:
            WWWUSER: "${WWWUSER}"
            LARAVEL_SAIL: 1
        volumes:
            - ".:/var/www/html"
        networks:
            - sail
        depends_on:
            - mysql
            - redis
 ```

#問題点
laravel sailで作ったアプリにbrowserSyncを使用しようとしました。
しかし、`sail yarn watch`実行時に表示される`http://localhost:3000`にアクセスしても何も表示されない。

#実行ファイル
```js
// webpack.mix.js
const mix = require("laravel-mix");

mix.browserSync("laravel.test");
```
デブサミ2021 参加レポート「エンジニアのためのメンタルヘルスマネジメント＜秋葉原のゲーマー心療内科医からのメッセージ＞」

# Developers Summit 2021
 
この記事は、2021/02/18-19に開催された[Developers Summit 2021](https://event.shoeisha.jp/devsumi/20210218/)のレポートです。
 
# チーム参加してきました
  
[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム5人中、4人で参加して、その場で実況しつつ、記事も作っています。
 
# 登壇者
鈴木 裕介さん

# エンジニアとメンタルヘルス
エンジニアのメンタルリスクは平均の3倍とも

# ストレスとは
もともと物理学の用語で、物体から影響を受け、歪んでしまうこと。
これは人間にも当てはまる。

# ストレスにさらされると、身体にどんな影響があるのか
1.副腎皮質の増大
2.リンパ組織の肥大化
3.胃腸の潰瘍

# ストレスの3段階
1.警告反抗期
・やばいと感じる
2.抵抗期
・気持ちは大丈夫と思う（体は身構えている）
3.疲弊期
・やっぱもうダメ

# ストレスが問題になるのはストレス反応が自覚されないから
目に見えないものなので、自覚しにくい

# ストレス反応
### 心理面でのストレス反応
・イライラしたりする
### 行動面でのストレス反応
・些細なミスが増える
### 身体面でのストレス反応
・体に不調を覚える

# "morning headeache"は鬱のサイン
朝の頭痛の30%は鬱が原因

# 不調はまず「体のサイン」に気付くのが大事
食欲不振や、睡眠障害など。冬などは仮眠傾向が増える。

# 主な心理的ストレッサー
**カタストロフィ**
**ライフイベント**
**デイリーハッスルズ**

# ストレス・マグニチュード
様々なライフイベントに点数をつけ、１年間で累積150点で約50%の人が、
累積300点で約80%の人が鬱になる。

# 注意すべきは「デイリーハッスルズ」
日々の積み重ねなので、気づきにくい。
些細なことの積み重ねは、心身的にダメージを与える。

# デイリーハッスルズの代表「腰痛」
・腰痛対策に大事なのは「体操」
・前傾姿勢による、負債の積み重ね

前傾姿勢によってずれた「髄核」を、
体を後ろにそらすことで元に戻す。

# 腰痛の意外な「危険因子」
・職場での対人関係のストレスが強い
・仕事に対する満足度が低い
・上司のサポートがない
など
メンタルヘルスの低下で、アドレナリンなどの分泌が減り、
痛みに過敏になる。

# 同じような刺激でも、それがストレッサーにならないこともある
ストレッサーには個人差がある

# 個性によってストレッサーは異なる
A.凝縮性（こだわりの強さ、責任感）
・自由がない、行動制限など
B.受容性（やさしさ、面倒見の良さ）
・過度な期待をされたときなど
C.弁別性（白黒つける、合理性）
D.拡散性（枠から飛び出る力、攻め）
E.保全性（枠を維持する力、守り）

# エンジニアに多い因子「弁別性」
無駄なく合理的に判断し進めようとする
「証拠は？」「要は？」が口癖で、無駄やリターンが嫌い

# 「受容」vs「弁別」のミスコミュニケーション
「受容」と「弁別」はミスコミュニケーションが多い
日本人の上位55%が「受容性」、上位22%が「弁別性」

# ストレスマネジメントの本質は「コーピング」
ストレスに対応する意図的に行う「自分助け」の行動。
コーピングレパートリーは多ければ多いほどいい。

### ポイント
気力・体力が低い時は「小粒な」コーピングを使う。
あらかじめコーピングリストを作る。

# まとめ
・エンジニアはメンタルヘルスリスクが高い
・メンタル不調のサインとして、体の不調に注意
・変化はすべからくストレスである
・デイリーハッスルズに注意

# 感想
自分が認識していなくても、ストレスを感じていることがあることが分かった。
一度、自分が本当に大丈夫なのか見直してみるのもいいのかもしれない。
【Rails】Herokuのエラー「The Ruby version you are trying to install does not exist on this stack.」を解決する

#課題

Rubyバージョン2.6.5で開発したアプリがHerokuのstack20ではデプロイできない![スクリーンショット 2021-02-19 13.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864210/c3d8de68-9cc2-5bb6-5fcc-3168aa141d9e.png)

#仮説

エラーメッセージにもあるようにHerokuのstackを18に変更すれば解決できるのでは？

#####1. Herokuにログインする

```:Terminal
$ heroku login
```

#####2. stackを18に変更してみる

```:Terminal
$ heroku stack:set heroku-18

 ›   Warning: heroku update available from 7.47.4 to 7.47.13.
 ›   Error: Missing required flag:
 ›     -a, --app APP  app to run command against
 ›   See more help with --help
```

しかしエラーが２つ出てしまった。。
【エラー①】Warning: heroku update available from 7.47.4 to 7.47.13.
【エラー②】Error: Missing required flag:

#####3. エラー①の対処法（Herokuのアップデート）

```:Terminal
$ heroku update

heroku: Updating CLI from 7.47.4 to 7.47.13... done
heroku: Updating CLI... done
Updating completions... done
```

#####4. エラー②の対処法

```:Terminal
$ heroku stack:set heroku-18 --app [Herokuのapp名]

Setting stack to heroku-18... done
```

これでHerokuのstackを18にすることができました！！
この手順で掲題のエラーは解決することができました！！
xerrorsのerrorチェックの判定方法

### はじめに

開発でgoのテストを書いているときに
errorチェックのテストの書き方の使い分けについて話が出たのでひとつの考え方として残しておく。

また、errorのパッケージとして`golang.org/x/xerrors`を使用している。

### 概要

単純にエラーの種類を判断するだけでいいのであれば、`xerrors.Is()`の結果を`assert.True()`に渡してチェックする。
Is()はbaseとなるerrorが両者で一致していればtrueになるので厳密なチェックにはならない。

具体的なエラーの内容までを見るのであれば、エラー文字列まで見ないといけないので
`assert.EqualError()`を使用する。


### テスト対象のコード

```golang

package main

import (
	"golang.org/x/xerrors"
)

var baseDBErr = xerrors.New("db error")
var baseCacheErr = xerrors.New("cache error")

func main() {
	handler()
}

// テスト対象のfunc
func handler() error {

	if false {
		return err1()
	}
	if false {
		return err2()
	}
	if true {
		return err3()
	}
	return nil
}

// DB系のエラー
func err1() error {
	return xerrors.Errorf("t_user取得失敗: %w", baseDBErr)
}

// キャッシュ系のエラー
func err2() error {
	return xerrors.Errorf("マスターA取得失敗: %w", baseCacheErr)
}

// キャッシュ系のエラー
func err3() error {
	return xerrors.Errorf("マスターB取得失敗: %w", baseCacheErr)
}
```

### テストコード

```golang

package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"golang.org/x/xerrors"
)

func TestHandler(t *testing.T) {
	fail := map[string]struct {
		wantErr    error
		wantStrErr string
	}{
		"テストケースA": {
			wantErr:    baseCacheErr,
			wantStrErr: "マスターB取得失敗: cache error",
		},
	}

	t.Run("失敗", func(t *testing.T) {
		for tt, tc := range fail {
			t.Run(tt, func(t *testing.T) {

				err := handler()
				// キャッシュエラーかどうかは判断できるが、マスターAかBどちらの処理のエラーなのかがわからない
				assert.True(t, xerrors.Is(err, tc.wantErr))
				// 厳密なチェック(文字列をチェック)
				assert.EqualError(t, err, tc.wantStrErr)
			})
		}
	})
}
```
デブサミ2021 参加レポート「19-A-3 OpenShift Ready、エンジニア視点によるデジタル変革への備え」

# Developers Summit 2021

この記事は、2021/02/18-19に開催された[Developers Summit 2021](https://event.shoeisha.jp/devsumi/20210218/)のレポートです。

# チーム参加してきました
  
[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム5人中、4人で参加して、その場で実況しつつ、記事も作っています。

# 登壇者

大西彰さん
Twitter/LinkedIn：oniak3
  
**URLに残る仕事をしよう**

# 1. エンジニア視点のデジタル変革の世界観

### サブスクリプション型ビジネスへの変化

- 所有意欲が低いデジタルネイティブ世代  
- 好きな時にすぐに利用できるサービス  
- 常に新しいバージョン  
- サービスレベルに応じた契約  

### DX：デジタルに変えることの重要性

- 無駄な時間を省く
- 判断するのに要する時間を最小にする
- どこからでもアクセスできるようにする

日本においては、労働人口減少問題に対処する点で、特にAIへの期待が高まっている

### お客様と共に未来を描くDeveloper

テクニカルに独りよがりにならないように未来を描いていければと思っている。

### デジタル化＝アプリ開発と運用

デバイス、API、サービス、AI、Data

# 2. Redhat OpenShift への向き合い方

今やOpenShift Readyな状態。
OpenShiftを味方につけると、皆さんの未来も変わっていくのではないか？

### 仮想マシン、コンテナ、Operator

Red Hat Openshift 上に乗せられるもの

1. ネイティブアプリ（OpenShift Virtulization上）
2. コンテナ化したアプリ
3. コンテナ化したアプリ＋Operatorによる自律的な運用管理

### 環境を作って、触ってみて、未来を考える

手軽に触る方法：

- IBM Tech/Developer Dojo
参加無料

- Red Hat Developer
Developerサブスクリプションで公開されているものが無償で利用できる

- Red Hat CodeReady Containers
Windows, Mac, Linux にインストール可能
パソコンの部品を買ってきて、パソコンを買ってきて、そのうえでCodeReady Containersを動かすのがおすすめ  

# まとめ

サブスクリプションの時代
デジタルに変えることの重要性が高まっている

Red Hat OpenShift まずは体験から

アプリの力で日本の未来を変えよう!

# 感想

OpenShift にしばらく触れていないうちに、新しい機能や技術が追加されていて、改めてOpenShiftを触ってみよう！と思えるセッションでした。未来をつくるという思いのもと仕事されていることが良いなと思いました。
【C#】偏りが少ないランダムな数字を出力するプログラム

#はじめに
作ったプログラムをテストする際に何かとランダムデータが必要になってくる。
しかし、備え付けのライブラリでランダムデータを作っても偏りが酷くて困ってしまう。
どうにかして偏りが少ないランダムデータを作ることはできないものか…ということで、C#でランダムデータ生成プログラムを作成してみた。

#サンプルプログラム
```C#:Sample.cs
using System;
using System.IO;

class Sample
{
    public static void GenerateRandomData()
    {
        string DataPath = @"C:\Folder\RandomData.csv";

        Console.WriteLine("データを生成します。");
        FileStream fs = System.IO.File.Create(DataPath);
        fs.Close();

        using (StreamWriter sw = new StreamWriter(DataPath))
        {
            int RoopCount = 0;

            //TickCountで取得した、コンピュータを起動してからの経過時間をミリ秒単位で取得し、ランダムデータ生成のSeed値とする
            int Seed = Environment.TickCount;
            Random rnd = new Random();

            //ランダムデータ生成件数
            int MaxRoop = 100;


            while (true)
            {
                //ループカウントが生成件数の設定値に到達したらループ終了
                if (RoopCount >= MaxRoop)
                {
                    break;
                }

                //普通のランダムクラスのインスタンスを生成
                Random SeedRoopCountRondom1 = new Random();
                //上限値を適当に設定し、数値をひとつ取り出す
                int SeedRoopCount1 = SeedRoopCountRondom1.Next(200);
                //上限値の分だけループ
                for (int i = 0; i < 200; i++)
                {
                    //ランダムクラス「rnd」にSeed値をインクリメントしたものを与えてインスタンス生成
                    //ここでループを繰り返してSeed値を与えることで、よりランダム性のある数値を作ることができる
                    rnd = new Random(Seed++);

                    //普通のランダムクラスから取得した値とループカウントが同じになればループ終了
                    if (i == SeedRoopCount1)
                    {
                        break;
                    }
                }

                //ランダムデータとして取り出したい範囲の値を設定
                int value = rnd.Next(1, 100000);
                //51ミリ秒待つのがポイント(根拠は正直あまりない…)
                //ここで待機時間を入れないとマシンの性能によってはSeed値に規則性が生まれてしまい、ランダムデータが規則的な間隔で出力されるため
                System.Threading.Thread.Sleep(51);
                //csvにデータを書き込みする
                sw.WriteLine(value);

                RoopCount++;
            }

            Console.WriteLine("データ出力完了");
            Console.ReadKey();
        }
    }
}

```

***

出力されたcsvのデータを分布図にまとめてみると、こんな感じになる。
![Sample](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/789979/55dd494b-2de0-ee58-670f-74e24708d80d.png)
イイ感じではないだろうか？
【備忘録】Teratermマクロを使ったSSH接続の自動化


__はじめに__
-
仕事柄、Teratermを使ったCLIの操作が多く
毎日、端末にログインするのめんどくせーから生まれたのが経緯です。
ttlファイルを実行するだけで勝手にログインできたので非常に楽。

__対象__
-
・日々の同じ作業を自動化したい人
・自動化の一端を感じ取ってみたい人

自動化っていうのかこれ...

作ってみました
-
下記でログイン可能

```connect.ttl
connect '192.168.2.203 /ssh /auth=password /user=shj /passwd=********'

```
ちなみにttlファイルを実行する際は、teratermのフォルダ内にある
teramacroファイルに紐付ける必要ある。

__認証方法__
-
```
パスワード認証： /auth=password
チャレンジレスポンス認証： /auth=challenge
公開鍵認証： /auth=publickey /keyfile=公開鍵ファイル名
```
/auth=のあとを変更することで端末ごとの認証にも対応可能。
ネットワーク機器だと単純なパスワード認証が多いが
VMware社のESXiだとチャレンジレスポンス認証でないとログインできない。


__参考までに__
-
下記コマンドをttlファイルに追記すれば
自動的にログイン後にコマンドを投入可能。
定型的なログ取得を自動化させることも可能です。

```
; コマンド「show version」を実行
sendln 'show version'

;プロンプト「switch#」が返ってくるまで待つ
wait 'switch#'

;次のコマンド「show running-config」を実行
sendln 'show running-config'
```

参考URL
-
https://teraterm.jp/?p=37
https://qiita.com/iguru/items/eed60bc1d969a6a0000c

改訂履歴
-
2020/2/19　初版作成
IBMCloud MFAの解除(IDベースのMFA)

#目的
MFAデバイスの紛失などでログインできなくなった場合、
ポータルを利用して自分で解除できるようになったので、MFAタイプ毎にやり方を記載する。

* IDベースMFA(すべてのユーザ用のMFA):本ページ
* アカウントベースMFA(個人用):作成中：うまく動作しない模様

それぞれの詳細は[こちら](https://cloud.ibm.com/docs/account?topic=account-types&locale=ja)を参照

#設定場所と状態の確認
まずは、解除前の状態を確認してみる
[**管理**] -> [**アクセス(IAM)**] -> [**設定**] -> [**編集**]をクリック
![貼り付けた画像_2021_02_19_9_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/98033980-7ee5-b4db-0702-98a8d4c27b4e.png)

現在は、[非フェデレーテッド・ユーザー]のログイン対してMFAを要求している状況であることがわかる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/fb1a9c81-566c-aaa3-866c-e0cd53e75952.png)

#MFA変更セルフポータルの設定
この操作は、MFAタイプに関わらず共通の操作
セルフポータルのログインし、本人確認用の検証方式として、**SMS/Eメール/音声電話**から2つを決定し、
あらかじめ登録する必要がある。その後、MFAのリセットが可能となる。

はじめに、下記ページにアクセスする
[IBMCloud My Security](https://iam.cloud.ibm.com/mysecurity/)

ログインページが開くので、リセットしたアカウントでログインする
[**IBMid**]を入力 -> [**次へ**]をクリックする
![貼り付けた画像_2021_02_19_10_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/7e1c24f7-8bf1-5a04-a7b8-cb038b882b5e.png)

本人確認の登録ページが開く
[**開始**]をクリックする
![貼り付けた画像_2021_02_19_10_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/c5ab6f4c-254c-a965-cbd9-6a9ac0eec889.png)

##二要素認証登録(一回目)
次のページで、検証方式を選択し、選択した方式の値を入力する
今回は検証方式を[**Eメール**]とし、[**Eメールアドレス**]を入力、[**送信**]をクリックする
![貼り付けた画像_2021_02_19_9_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/b02df635-b050-553c-544d-cdf632f9f377.png)

下記の様にメールが来るので、[**セキュリティーコード**]を入力し、[**完了**]をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/47ce9cde-72d4-842e-991b-3346bc0b9565.png)
![貼り付けた画像_2021_10_25_11_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/c4912e48-6ae8-6d9c-b2de-76b421c8ecf6.png)


##二要素認証登録(二回目)
再度、一回目と同じ認証方式で問題ないが、同じ電話番号や、Eメールアドレスは利用できない。
今回は検証方式を一回目と同じ[**Eメール**]とし、<font color="Red">**一回目とは異なる**</font> [**Eメールアドレス**]を入力、[**送信**]をクリックする
![貼り付けた画像_2021_10_25_11_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/807bd555-6ad6-4632-5013-ebb0956565ce.png)


再度、[**セキュリティコード**]を入力し、[**完了**]をクリックする

#IDベースMFAのリセット
二回目の認証が正常に進むと、下記の様にポータルページが表示される

アカウントに設定されたMFAを解除するには、[**Security Level**] -> [**Show accounts**]をクリックする
![貼り付けた画像_2021_02_19_10_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/293859b4-9fa4-cf1f-7bd1-b83ae31eb3d8.png)

[**Manage your own account**]をクリックする
![貼り付けた画像_2021_02_19_10_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/0677f084-a1c4-8ed3-3f01-2593e891ca83.png)

設定されているMFAタイプがわかる
![貼り付けた画像_2021_02_19_10_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/98c0709d-0177-b5bb-639e-dab7f1ef9d3e.png)

続けて、MFAを解除したいので、[**None**]を選択し、[**Save**]をクリックして解除完了
![貼り付けた画像_2021_02_19_10_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/2564c27d-9b55-206a-9acc-af5d2e554258.png)

##IDベースMFAの解除における注意点
この操作は基本的にマスターユーザで実施する必要がある。
一般ユーザに解除権限を付与していない限り、実施できない。
解除した場合、全ユーザーのMFAがNoneとなる。
また、OFF->ONした場合でも、セットアップ済みのMFAデバイスはそのまま利用可能。
Railsチュートリアル第３章　herokuへデプロイできないときのエラー対処法（2）

3章　3.1　セットアップ

gitへpushしようとした際、以下のエラーが表示される。

```
ubuntu:~/environment/sample_app (master) $ heroku create
Creating app... !
 ▸    You've reached the app limit of 5 apps for unverified accounts. Delete
 ▸    some apps or add a credit card to verify your account.


```

原因

herokuへは5つしかアプリを保存できないそうです。
すでに5つの枠が埋まっていたために発生した模様。

対策

既存のいらないアプリを消去する
herokuにアクセスしていらないものを確認。
アプリ名を記録。


```
$ heroku apps:destroy --app <いらないファイル名>
```

さらに、確認のためにもう一度いらないファイル名を入力すると削除が完了します。
【初めてのGit】 エラーが出てpush出来ない場合

前提条件
gitをインストールしている。
gitに登録している。

***
###問題
__エラーが出てpush出来ない__
#エラー内容
```ruby
R:\Install\xampp\htdocs\Laravel\tasklist> git push -u origin master
error: src refspec master does not match any
error: failed to push some refs to 'origin'
```
翻訳
error: src refspec master がどのようなものにもマッチしません。
error: いくつかの参照を 'origin' にプッシュするのに失敗しました。

##試したこと
addして

```ruby
git add .
```
commit

```ruby
git commit -m "first commit" -a
```
<font color="Red">__pushするとまたエラー__</font>

```php
R:\Install\xampp\htdocs\Laravel\tasklist>git push -u origin master
fatal: 'origin' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
__翻訳__
fatal: 'origin' が git リポジトリではないようです。
fatal: リモートリポジトリから読み込めませんでした。
正しいアクセス権を持っていることを確認してください
リポジトリが存在することを示しています。

##対応方法

<font color="bule">__.gitフォルダを削除してやり直す__

__プロジェクトフォルダ内の.gitフォルダを削除する__
 　　隠しフォルダを表示しないと見つかりません。

<font color= "gree">__以下、プロジェクトフォルダに移動してコマンド__

:gem:__.gitフォルダを作る__

```
git init
```

:gem:__プロジェクトをaddする__

```
git add .
```

:gem:__コミットする__

```
git commit -m "first commit" 
```

:gem:__リポジトリを指定する__

```
git remote add origin https://github.com/ユーザ名/リポジトリ名.git
```

:gem:__pushする__

```
git push origin master
```


#gitを理解するには時間を要す
情報が多いと、必要な情報を取得するのが大変でした…
DRFのAPIをcurlで良い感じに叩く

今回はDjango Rest Frameworkの勉強として他の方が書いた記事を参考にしてAPIを作成して良い感じにcurlで叩いてみたやり方の共有ということで書いていきます。

## 作業環境

- OS ： MacOS Catalina 10.15.7
- djangorestframework ： 3.12.2
- django ： 3.1.6
- django-filter ： 2.4.0

## 作業手順

まずは[この記事](https://qiita.com/kimihiro_n/items/86e0a9e619720e57ecd8)をみながらAPIを構築していきます。

APIを作ってlocalhostで見れるところまで行けばOKです。

そして簡単ですがAPIを叩いてみましょう。

```
curl -X GET http://127.0.0.1:8000/api/users/
```

```
curl -X GET http://127.0.0.1:8000/api/entries/
```

ちょっと見にくいのでjsonをパースしてくれるパッケージを入れましょう。

```
brew install jq
```

他のOSを使用している方は[jqのインストールガイド](https://www.jenkins.io/doc/book/installing/)を見て各自インストールしてください。

先ほどのcurlコマンドに付け足すと

```
curl -X GET http://127.0.0.1:8000/api/users/ | jq .
```

```
curl -X GET http://127.0.0.1:8000/api/entries/ | jq .
```

こんな感じになると思います。

レスポンスは

```
[
  {
    "title": "test1",
    "body": "ああああああああああああああああああああああああ",
    "created_at": "2021-02-19T11:52:33.634638+09:00",
    "status": "draft",
    "author": 1
  },
  {
    "title": "test2",
    "body": "いいいいいいい",
    "created_at": "2021-02-19T11:52:55.853370+09:00",
    "status": "draft",
    "author": 1
  },
  {
    "title": "test3",
    "body": "うううううううううう",
    "created_at": "2021-02-19T12:03:10.261715+09:00",
    "status": "draft",
    "author": 1
  }
]
```

こんな感じですね。

## まとめ

今回はDRFを使って簡単なAPIを作成してcurlコマンドで叩くところまでやりましたが自分自身知識が足りていないところが多いためかなり雑な説明となってしまいました。

有識者の方のコメントお待ちしております！
vscodeでeexファイルでもemmet

まあ、ここのとおりなんですが

https://marketplace.visualstudio.com/items?itemName=mjmcloug.vscode-elixir

1. vscode-elixirをインストール
2. setting.jsonにつぎを追加

```json
"emmet.includeLanguages": {"HTML (Eex)": "html"}
```

GitHubのイシューに今はEexじゃなくてEExだとかいう話もあったりして動かなかったんですが、単にHTMLとカッコの間に半角スペースが必要だったという...
初めてのRaspberry Pi Pico ⑰ C言語 PWM その2

　前回はPWM信号を作りましたが、とても高い周波数でした。ここでは、LEDのほんわか点灯などに適した500Hzから1kHzの周波数にします。

###前回のプログラムに追加
 GPIO2,3に出力するのは変わっていません。


```cpp
/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

// Output PWM signals on pins 2 and 3

#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include <stdio.h>
#include "hardware/clocks.h"
#include <math.h>

int main() {
    stdio_init_all();  // need when UART 

    printf("\nstart GPIO 2,3\n");

    // Get some sensible defaults for the slice configuration. By default, the
    // counter is allowed to wrap over its maximum range (0 to 2**16-1)
    pwm_config config = pwm_get_default_config();
    // Set divider, reduces counter clock to sysclock/this value
    float div = 3;
    pwm_config_set_clkdiv(&config, div);

    /// \tag::setup_pwm[]
    // Tell GPIO 0 and 1 they are allocated to the PWM
    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(3, GPIO_FUNC_PWM);

    // Find out which PWM slice is connected to GPIO 2 (it's slice 0)
    uint slice_num = pwm_gpio_to_slice_num(2);

    // Set period of 4 cycles (0 to 5 inclusive)
    pwm_set_wrap(slice_num, 5);
    // Set channel A output high for one cycle before dropping
    // pwm_set_chan_level(slice_num, PWM_CHAN_A, 1);
    // Set initial B output high for three cycles before dropping
    // pwm_set_chan_level(slice_num, PWM_CHAN_B, 5);
    // Set the PWM running
    //    pwm_set_enabled(slice_num, true);
    /// \end::setup_pwm[]

    // Load the configuration into our PWM slice, and set it running.
    pwm_init(slice_num, &config, true);

    pwm_set_both_levels(slice_num, pow(2,16)*0.5, pow(2,16)*0.9);
}
```

　分周するdiv変数に3を代入して、configにセットします。

```cpp
    pwm_config config = pwm_get_default_config();
    // Set divider, reduces counter clock to sysclock/this value
    float div = 3;
    pwm_config_set_clkdiv(&config, div);
```

　その変更を有効にし、PWMを動かします。

```cpp
    // Load the configuration into our PWM slice, and set it running.
    pwm_init(slice_num, &config, true);
```

###へんな分周
　divが変です。いろいろ数字を変化させて、オシロスコープでその周波数を読みました。
![pwm201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/69c58f25-e281-326f-ebd3-bbb53db8a09a.png)
　Arduino UNOのようなPWM周波数の500Hzや1kHzに近い設定できるのですが、設定値divと周波数はまったく比例していません。

###ディーティ比
　最後の記述はデューティ比を設定しています。1周期が0から0xffffなので、highになる区間を比率で設定しています。引数はスライス番号、Aチャネル、Bチャネルです。
　GPIO2はスライス0のAチャネル、GPIO3はスライス0のBチャネルに割り当てられています。

```cpp
    pwm_set_both_levels(slice_num, pow(2,16)*0.5, pow(2,16)*0.9);
```

　ぴったりの値が測定できました。
![Screen 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/4a487ca4-25c0-d803-fc65-174a92cc0e54.png)
使ってはいけない `:read-only` 疑似クラス

## はじめに

煽りタイトルです。
実際は単純に汎用的なフォームコントロールのクラスをつくって使いまわしていたら失敗した話です。

何が言いたいかというとセレクタをいろんな要素に使い回す場合は `:read-only` より `[readonly]` にしたほうがいいのかもしれないということです。

## やりたかったこと

以下のような汎用的なクラスをつくってinputやselect要素で使いまわしたかった。
(プロパティは適当です)

```css:CSS
.control {
  background: #fff;
  border: solid 1px #999;
  border-radius: 4px;
}
.control:read-only {
  color: red;
}
```

```html:HTML
<div>
  <input class="control" value="writable value" />
</div>
<div>
  <input class="control" value="readonly value" readonly />
</div>
<div>
  <select class="control">
    <option>selectable value</option>
  </select>
</div>
```

### 期待した表示

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99157/45cb4f02-747a-36d4-1ab8-15b426a44ec5.png" width="166" />

## なにが起きたか

`:read-only` 疑似クラスは `readonly` 属性が利用できないselect要素など(divやspanなどもすべて)マッチするようで、以下のようになりました

### 実際の表示

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99157/c1ec3b32-2014-7440-e0ed-10d07d9dff71.png" width="168" />

## 最終的な実装

`readonly` 属性が指定されているときに表示が変わっていればいいので属性セレクタを使用することにしました。

```css
.control {
  background: #fff;
  border: solid 1px #999;
  border-radius: 4px;
}
.control[readonly] {
  color: red;
}
```
フォームからGAS経由でGoogle Driveに画像を保存する方法(Chrome V8ランタイム対応）

# 解決すること
フォームからGAS経由で画像をアップロードするとファイルが破損して開けないという状況を回避します。

（以下がその情報の記事）
https://qiita.com/TechnoKuRo/items/442d5d9ace73edcb4be7
https://auto-worker.com/blog/?p=865

# やりたいこと
1. 入力フォームから画像を選択
2. JSで画像データをGASの関数に渡す
3. GASの関数がGoogle Driveに保存する

# 実践
本記事では、フォームのコードについては割愛しています。
今回は画像を保存したいので、フォームでは`image/*`のみ許容するようにしました。
ちなみに私は[VuetifyのFile inputコンポーネント](https://vuetifyjs.com/ja/components/file-inputs/)を最近使用しました。

## 1. JS

入力フォームからは以下のような関数を呼ぶようにしておきます。

```js:saveImage
function saveImage() {
    google.script.run.withSuccessHandler(
        (result) => {
            //resultにはGASの戻り値が入ります(今回の例だとtrue）
            //  Net state changed from IDLE to BUSY (処理中)
            //  Net state changed from BUSY to IDLE (完了)
            // とログが出力されますので、完了後に何かしたい場合は
            // ここにその処理を記載します。
        }
    ).saveGdrive(img);
};
```

## 2. GAS

JSから渡されたimgは、
`data:image/png;base64,xxxxxxxxxxxxxxxxxxxxxx...`
というbase64にエンコードされたデータであることを前提としています。

頭の部分に画像の形式があり、xxxxx...の部分が実際の画像データのバッファが含まれています。
下記のソースでは、以下の手順を踏んでいます。

1. 頭の部分のデータから、拡張子とMimeTypeを把握する。
2. 把握後に頭の部分を取り除いて、画像のバッファデータだけにする。
3. GASのUtilitiesサービスを使用して、一旦Decode、再度Blobに変換する。
4. Google Driveに保存する。

```js:saveGdrive
function saveGdrive(img) {
    // IDは、https://drive.google.com/drive/folders/{この部分}
    const GDRIVE_FOLDER_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    const gdrive = DriveApp.getFolderById(GDRIVE_FOLDER_ID);
    const mimeType = {
        'bmp': MimeType.BMP,
        'gif': MimeType.GIF,
        'jpeg': MimeType.JPEG,
        'png': MimeType.PNG,
        'svg+xml': MimeType.SVG,
    };
    const extension = {
        'bmp': 'bmp',
        'gif': 'gif',
        'jpeg': 'jpg',
        'png': 'png',
        'svg+xml': 'svg',
    };
    const ext = img.slice(img.indexOf('/') + 1, img.indexOf(';')); // 拡張子
    const filename = "TEST" + '.' + extension[ext]; // ファイル名
    img = img.replace(/\S*,/, ''); // Buffer取得
    img = Utilities.base64Decode(img); // 一旦Decode
    img = Utilities.newBlob(img, mimeType[ext], filename); // Blobに変換
    gdrive.createFile(img); // Google Driveに保存

    return true;
}
```

これで無事画像がGoogle Driveに保存されます。

# さいごに
今回紹介したコードには、細かなエラー処理を含んでおりませんので、
参考にする際はお気をつけ下さい。

Apps Scriptは2020~2021の境目あたりにエディタが使いやすくなったので、
決してChrome V8ランタイムはオフにせず、
素敵なコーディングライフ（？）を送りましょう！