OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonを使ったポケモン種族値の絞り込み検索

ポケモン対戦でトリックルームを使用できるポケモンを探したいと思ったのですが、どのポケモンを使用するか迷っていました。
まず、トリックルームを使用する際に後行になるので相手からの攻撃に耐えられるポケモンが良いかなと思い種族値で素早さが低くて、防御や特防が高いポケモンを探したいと思いました。そこでcsvデータからプログラミング言語のPythonを使って絞り込んで検索しようと思いつきました。

#事前に準備すること
・ExcelまたはNumbersのインストール
・Anacodaのインストール
・PythonとPandasのインストール


#手順 
① csvファイルのダウンロードと作成
ポケモンの種族値のcsvファイルは下記のURLからダウンロードできます。
https://www.kaggle.com/abcsds/pokemon
このcsvファイルは７-８世代ポケモンのデータが入力されていません。また、英語表記なのでポケモンの名前も英語名になっているので多少扱いにくいところもあります。


８世代のポケモン(剣盾内登場ポケモン)は下記のURLからデータをコピーして若干手間がかかりましたが、Excel上で表を整えてcsvファイルにしました。
https://wiki.ポケモン.com/wiki/種族値一覧_(第八世代)


② Pythonで種族値の絞り込み
まずcsvファイルからデータを読み込んでみます。インストールしたcsvファイルのアイコンをドラッグして画面の左のファイルリストに入れます。次に以下のコードをAnacodaのJupyterLabで入力してみます。


```Python
import pandas as pd
df = pd.read_csv("Pokemon.csv")
df
```

すると画面上で以下の図のようにリストが表示されると思います。




<img width="1154" alt="スクリーンショット 2020-06-16 14.47.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473924/65194e68-135d-6e4e-062f-8ef79376dee4.png">





次に伝説を除いたエスパータイプのポケモンを絞り込んでみたいと思います。次のコードを入力してみます。


```Python
df.loc[(df.Legendary == False) & (df["Type 1"] == "Psychic")]
```

すると以下の画面のように伝説以外のエスパータイプのポケモンのリストが表示されたと思います。

<img width="1262" alt="スクリーンショット 2020-06-16 14.52.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473924/837d0fb3-7aff-0c91-4964-a8ac30f6d9d1.png">


そして、先ほどの絞り込んだリスト結果を引き継いでさらに防御種族値が６０以上で素早さが６５以下のポケモンを検索するために以下のコードを入力します。


```Python
df = df.loc[(df.Legendary == False) & (df["Type 1"] == "Psychic")]
df.loc[(df.Defense >= 60) & (df.Speed <= 65)]
```

入力した結果、かなり絞り込めたと思います。

<img width="1262" alt="スクリーンショット 2020-06-16 15.01.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473924/8b571d2b-2036-4456-3b79-f4a269da5fc9.png">



最後に以下のコードを入力して防御種族値を降順に並び替えれば終了です。


```Python
df = df.loc[(df.Defense >= 60) & (df.Speed <= 65)]
df.sort_values(by = ['Defense'], ascending = False)
```

<img width="1262" alt="スクリーンショット 2020-06-16 15.04.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473924/be159541-bd92-bdc1-2783-ffd0d3c23d26.png">


まとめると、以下のコードを入力すれば簡単に結果が出てくると思います。


```Python
import pandas as pd
df = pd.read_csv("Pokemon.csv")
df = df.loc[(df.Legendary == False) & (df["Type 1"] == "Psychic")]
df = df.loc[(df.Defense >= 60) & (df.Speed <= 65)]
df.sort_values(by = ['Defense'], ascending = False)
```


#最後に
英語名だとポケモンがわかりにくかったのでURLからコピーしたリストで作成した日本語名のcsvファイルも読み込んで同様に絞り込んでみました。ファイル名をPokemon_data.csvにして下記のコードを入力すると結果が出てきます。


```Python
import pandas as pd
df = pd.read_csv("Pokemon_data.csv")
df = df.loc[(df.伝説 == False) & (df["タイプ1"] == "エスパー")]
df = df.loc[(df.防御 >= 60) & (df.素早さ <= 65)]
df.sort_values(by = ['防御'], ascending = False)
```

<img width="1261" alt="スクリーンショット 2020-06-16 15.37.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473924/651ef10e-82bb-10ce-8049-684389f38d49.png">



わかったことはブリムオンとムシャーナは素早さが同程度に低くて防御と特防も高かったのでトリックルームを使うポケモンの候補になると自分の中で解釈しました。


他にもゴーストタイプでトリックルームが使えるポケモンもいたりするので同様にコードを入力して探してみるのもいいかもしれません。


#あとがき

Pandasを使ったコードの練習は下記のURLで勉強できます。プログラミングの勉強の参考にすると良いと思います。

https://www.kaggle.com/learn/pandas
【日本語化】 i18n rails 楽々日本語化　viewの表示のみ

##【ゴール】
viewだけ日本語表示へと切り替え


##【メリット】
■　UIの向上
■　日本語なので可読性向上し、開発効率化


##【開発環境】
■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7

##【実装】

####アプリケーション作成

※　touchでfileを作成

```mac.terminal
$ rails new japoanese
$ rails g controller homes index
$ cd config/locale
$ touch ja.yml
```

※下記追記後 bundle install

```gemfile.追加
gem 'rails-i18n', '~> 5.1' 
```

※ホーム画面へhomes/indexを!!

```routes.rb
root 'homes#index'
```

※インデント要注意、

```locale/ja.yml
ja:
　homes:
    index:
      title: '題名'
      name:　’名前’
      text:　’文章’

## modelが関連すると書き方少し変化します。下記みたいな感じです。。。

  activerecord:
    models:
      user: "ユーザー"
      attributes:
        user:
        name: "名前"
        age: "年齢"
  
```

※**下記重要**

```config/application.rb
config.i18n.default_locale = :ja #追加
```


※ja.ymlで定義」したものを引っ張ってきます。

```homes/index.htmnl.erb

<h2><%= t '.title'%></h2>
<h2><%= t '.name'%></h2>
<h2><%= t '.text'%></h2>

```

以上！！

##【合わせて読みたい】

■もっと詳しい記事
https://qiita.com/shimadama/items/7e5c3d75c9a9f51abdd5

■エラーメッセージ
https://qiita.com/tanaka-yu3/items/63b189d3f15653cae263

■rails メソッド　初学者者向け
https://qiita.com/tanaka-yu3/items/89abad875187494bec53
netstatでプロセス名も表示

netstatコマンドの-oオプションで接続に関連付けられたプロセスIDが表示されますが、プロセス名を別途調べる必要があるため、プロセス名も一緒に表示するスクリプトです。

```powershell:netstat_extenction.ps1
# netstat プロセス名も表示
#
# コマンドプロンプトで実行
# CMD> powershell -NoProfile -ExecutionPolicy Unrestricted .\netstat_extension.ps1
# [D] 実行しない(D)  [R] 一度だけ実行する(R)  [S] 中断(S)  [?] ヘルプ (既定値は "D"): r
#
# PowerShellで実行
# 1. 実行ポリシーを変更
#   PS> Set-ExecutionPolicy RemoteSigned⇒yes
# 2. 実行
#   PS> .\netstat_extenstion.ps1
# 3. 実行ポリシーを戻します
#   PS> Set-ExecutionPolicy Restricted⇒yes

$netstat = netstat -aon | Select-String -Pattern "(TCP|UDP)"
$ProcessList = Get-Process
foreach ($data in $netstat)
{
    $SpltArry = $data -split " "
    $PD = $spltArry[$spltarry.length - 1]
    $pn = $ProcessList | Where-Object {$_.id -eq $pd } | select processname
    $SpltArry[$SpltArry.length - 1] = $PD + " " + $PN.processname
    $SpltArry -join " "
}
```
[メモ]ElectronアプリでDevToolsを開くと勝手にダークテーマになる時の対応

# 症状

Windows10でダークテーマで開発をしているとき、Electron9のアプリでDevToolsを開くと、アプリ全体にダークテーマがかかってしまう。


![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90529/9f4bf691-ac08-9bee-9ee6-83e492f0b098.jpeg)
普通に起動したときはなにも起こってない

↓
↓
DevTool起動すると
↓
↓

![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90529/51eb21bd-e626-fb44-df8b-c390dc70504a.jpeg)
なぜか急に、ウィンドウ内までダークテーマが適用される！


# 暫定解決

DevTools内の
Setting(歯車マーク) => Preferences => Theme で "Light" を選択して、アプリを再ビルドする

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90529/f5a3494e-7e16-a4f6-f673-552509be2b27.jpeg)


再ビルド後もアプリのキャッシュのようなとこに"Light"設定が残っており、ダークテーマが適用されなくなる。

![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90529/e4a9d48f-80c2-4998-dc33-c59f945c9459.jpeg)
下位10%のダメなエンジニアにだけ解けないパズルにチャレンジしてみた

タイトルにあるようなパズルが数年前流行ったとのこと、
見つけたのでチャレンジ。

[パズル](http://challenge-your-limits.herokuapp.com/)

まずはブラウザに直接打ち込んでみる。
http://challenge-your-limits.herokuapp.com/call/me
すると、下記のようなテキストが帰ってきた。

```
{"message":"Almost! It's not GET. Keep trying."}
```

なるほどGETではないとのことなので、
POSTでリクエストしてみよう。

curlでやってもいいが、今回はRubyでリクエストを投げてみる。

```ruby
require 'net/http'
uri = URI.parse('http://challenge-your-limits.herokuapp.com/call/me')
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)
response = http.request(req)
puts response.body
#=>{"message":"Great! Please register as /challenge_users"}
```

成功、そして次の課題が、
まずはパスを変えてそのままリクエスト。

```ruby
require 'net/http'
uri = URI.parse('http://challenge-your-limits.herokuapp.com/challenge_users')
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)
response = http.request(req)
puts response.body
#=>{"message":"Validation Error, [:name, \"can't be blank\"]"}
```


パラメータを渡せって指示がきました。
POSTなのでリクエストボディにデータを入れ込む。

```ruby
require 'net/http'
require 'json'
params = {
   name: 'hogehoge'
}
uri = URI.parse('http://challenge-your-limits.herokuapp.com/challenge_users')
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)
req.body = params.to_json
response = http.request(req)
puts response.body
#=> {"message":"Validation Error, [:name, \"can't be blank\"]"}
```


あれ？パラメータが渡せてない、
ここから熟考、、、そしてカンニング。笑

リクエストボディにjson形式でパラメータを入れているのが原因だった。
ボディはjsonでしょと思い込んでいたことを反省、、、


Net::HTTP::Postライブラリにはset_form_dataという便利なメソッドがあり、
引数にhashを渡せば文字列でパラメータをボディに入れてくれます。

```ruby
require 'net/http'
params = {
   name: 'hogehoge'
}
# 省略
req.set_form_data(params)
puts req.body
#=>　name=hogehoge
puts req.body.class
#=>  String
```

そして編集

```ruby
require 'net/http'
params = {
   name: 'hogehoge'
}
uri = URI.parse('http://challenge-your-limits.herokuapp.com/challenge_users')
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)
req.set_form_data(params)
response = http.request(req)
puts response.body
#=> {"message":"Validation Error, [:email, \"can't be blank\"]"}
```
パラメータ指定が永遠に続くとかないよね？
指示通りemailを追加

```ruby
require 'net/http'
params = {
   name: 'hogehoge',
   email: 'hogehogehoge@hogehoge.com'
}
uri = URI.parse('http://challenge-your-limits.herokuapp.com/challenge_users')
http = Net::HTTP.new(uri.host, uri.port)
req = Net::HTTP::Post.new(uri.path)
req.set_form_data(params)
response = http.request(req)
puts response.body
#=> {"message":"Validation Error, [:email, \"is already taken\"]"}
```

uniq: trueかよとか思いつつ、
別のアドレスを入れると成功しました。

```
{"message":"Thanks! Please access to http://challenge-your-limits.herokuapp.com/challenge_users/token/**********  from your web browser."}
```

まだまだ下位10%だなぁと、自分の立ち位置を再確認できたよき機会でした。
POSTに関してリクエストパラメータの入れ込み知識がついたので、1歩前進かな。

日々精進。
Git alias  便利なコマンド

## LINUXの勉強していた時に 「alias」 という存在を知ったが今まで全く恩恵に預かってなかった。ここに来てようやくGitにもaliasとやらを使えるということを知ったので、やり方・登録したaliasを記録


### そもそもaliasってなんやねん
色々と長いコマンドをフルネームで呼ぶのがめんどいから代わりにあだ名的なのを勝手につけて、短い名前で呼んでしまえ！！！的な機能のこと。  
例えば、「**パブロ＝ディエーゴ＝ホセー＝フランシスコ・デ・パウラ＝ホアン・ネポムセーノ＝マリーア・デ・ロス・レメディオス＝クリスピーン＝クリスピアーノ＝デ・ラ・サンティシマ・トリニダード＝ルイス・イ・ピカソ**」っていちいち毎回長い名前で呼ぶのはめんどいよね？？？
（マルクス=アウレリウス＝アントニヌスより長いだ、、、と、、、?!）

そこでaliasという機能を使って、「**パブロ・ピカソ**」と単純な名前で呼び出そう！という感じ。


###  `alias`であだ名をつけてやろう
私自身まだgitに使い慣れていませんが、以下のコマンドはよく使います。
`git checkout`
`git branch`
`git commit`
`git status`

  
  


こやつらをaliasを使ってあだ名をつけてやるにはこんな感じにコマンドを実行

`checkout`を`co`と名付ける

```
$ git config --global alias.co checkout
```
`branch`を`br`と名付ける

```
$ git config --global alias.br branch
```
`commit`を`ci`と名付ける

```
$ git config --global alias.ci commit
```
`status`を`st`と名付ける

```
$ git config --global alias.st status
```
  
  
  
  
ちなみに、名前は自分が分かりやすいようにしたらオッケー。
なんなら「う○こ」みたいでもいいと思う（ごめんなさい）
そうすることで上から順に

```
$ git co
```

```
$ git br
```

```
$ git ci
```


```
$ git st
```

と実行してやることができます〜。




### ピカソの本名並に長いコマンドに使ってあげる

```
$ git log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(bold white)— %an%C(reset)%C(bold green)%d%C(reset)' --abbrev-commit --date=relative --all
```

こんな感じの馬鹿みたいに長いコマンドに対して使うのが効果的なんやねー。
ちなみに上のコマンドはgitの履歴グラフがカラーで表示されるんだよ♬



### 補足
vimで設定ファイルを開いてやって、設定を直接入力することもできるよ。
（vimはマウスを一切使わないエディターのことでっせ。使い慣れたら多分モテる気がするけど、きっと幻想）

```
$ vim ~/.gitconfig
```


```.gitconfig.
[alias]
        co = checkout
        br = branch
        ci = commit
        st = status
        log-color = log --graph --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(bold white)— %an%C(reset)%C(bold green)%d%C(reset)' --abbrev-commit --date=relative --all

```


### まとめ
ショートカットがこの世を幸せにしてくる気がする。
ゼロトラストセキュリティについて参考になった記事一覧

随時追加していきます。


 - [ゼロトラストとは？境界型に対するの仕組みから、事例まで広く解説！](https://locked.jp/blog/what-is-zero-trust/)
 - [VDI（Virtual Desktop Infrastructure）と VPN（Virtual Private Network）と ゼロトラスト の実装 BeyondCorp と](https://ts0818.hatenablog.com/entry/2020/04/09/230512)
 - [米グーグルはテレワークでVPNを使わない、なぜなら「あれ」が危険だから](https://xtech.nikkei.com/atcl/nxt/column/18/00692/031000023/)
 - [BeyondCorp - A New Approach to Enterprise Security](https://mrasu.hatenablog.jp/entry/2018/08/06/003730)
 - [ゼロトラストセキュリティのリーダー企業が語る、実現に必要なポイント3つ](https://active.nikkeibp.co.jp/atcl/sp/b/20/04/09/00170/)
 - [【徹底解説】ゼロトラスト・セキュリティを簡単に実現する方法](https://mbcnet.org/the-ultimate-guideline-to-start-zero-trust-security/)
 - [VPNからゼロトラストネットワークアーキテクチャへの移行を検討](https://mbcnet.org/considering-to-move-zero-trust-network-from-vpn/)
 - [ゼロトラストネットワークアクセス（ZTNA）の実現](https://mbcnet.org/guide-of-ztna-how-can-you-choose-the-security-vendor-and-why/)
 - [コロナウィルスで激変するセキュリティ対策 - ⼈類史に残る変⾰にテレワークで対応するために](https://locked.jp/whitepaper/wp-to-prevent-covid19-from-aspects-of-security_v8.pdf)
 - [[Project Description] Implementing a Zero Trust Architecture](https://csrc.nist.gov/publications/detail/white-paper/2020/03/17/implementing-a-zero-trust-architecture/draft)
 - [Getting Started With a Zero Trust Approach to Network Security](https://www.paloaltonetworks.jp/resources/whitepapers/zero-trust-network-security)
 - [ゼロトラストの実現方法に関するまとめ](https://summary.fc2.com/summary.php?summary_cd=100590484)
LaravelでのファイルアップロードAPIとUnitTest

- Windows 10
- PHP 7.4.5
- Laravel Framework 7.9.2

## アップロードAPI

```php:app/Http/Controllers/ImagesController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class ImagesController extends Controller
{
    public function upload(Request $request)
    {
        try {
            $path = $request->file('file')->store('images');
            return response()->json([
                'path' => $path
            ]);
        } catch (Exception $e) {
            return response($e->getMessage(), 500);
        }
    }
}
```

## テストコード
```php:tests/Feature/ImageFeatureTest.php
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Tests\TestCase;

class ImageFeatureTest extends TestCase
{
    use RefreshDatabase;

    /**
     * @test
     */
    public function upload_success()
    {
        // Data
        $file = UploadedFile::fake()->image('dummy.jpg', 800, 800);

        // Test
        Storage::fake('local');
        $response = $this->json('POST', '/image/upload', [
            'file' => $file
        ]);
        $response->assertOk()->assertJsonStructure(['path']);
        Storage::assertExists($response->decodeResponseJson('path'));
    }
}
```
VSCode で Paste Image トラブルシューティング

Markdown に画像を簡単に貼りたいな・・・ということで定番のプラグイン、Paste Image を使います。

簡単に設定・・・のつもりが、 何故かはまりました。

# 環境

- Ubuntu 18.04 LTS x64
- Visual Studio Code Version:1.43.2
- Paste Image 1.0.4

# 設定

標準では Markdown ファイルと同じ位置に画像ファイルが生成されますが、それをファイルと同じ位置に images ディレクトリを作ってそこに保管するようにします。

    "pasteImage.path": "${currentFileDir}/images"

を設定に書き足します。
オリジナルの記述:

```

{
    "editor.minimap.enabled": true,
    "breadcrumbs.enabled": true,
    "editor.renderWhitespace": "all"
}
```

↓


```

{
    "editor.minimap.enabled": true,
    "breadcrumbs.enabled": true,
    "editor.renderWhitespace": "all"
    "pasteImage.path": "${currentFileDir}/images"
}
```

これで Ctrl + Alt + V で貼り込みデキるはず・・・



# 追加パッケージが必要


貼り込みしようとしたら、xclip が必要というようなメッセージが出ました。

```

$ sudo apt install xclip
```

として、パッケージをインストールしました。

# 貼り込みできない

新しいドキュメントを作って貼り込みしようとしたら、

Before paste image, you need to save current edit file first.

とメッセージが出ました。確かに、まだドキュメント保管していませんでした。

ドキュメントを save して今度こそ。

# Markdown 形式で貼れていない

貼れたけれども、

```

images/2020-06-24-16-01-43.png
```

のような形式になっていません。ドキュメントを保管する時に Markdown 形式になっていませんでした。 拡張子を .md をつけて保管。

```


![](images/2020-06-24-15-52-49.png)

```

の形式で保管されるようになりました。

# 画像がプレビューに表示されない

あれれー？？ とおもってあれこれしましたが、結局プレビューを閉じてもう一度表示したら画像が表示されるようになりました。やれやれ。
【Python】自然数の約数を高速で取得する方法

#はじめに
こちらの記事をご覧頂きありがとうございます！！
2020年6月よりプログラミングデビューした**なかぞん**です！

毎日、AtCorderのA-D問題を最低5問解くことを日課としています。

私の記事では、プログラミング初心者の目線で、
日々の日課を通じて発見した学びや苦労した事、
嬉しかった事などを発信しようと思います。

同じ初心者の方々に学びのある記事になるよう努めて参ります！
上級者の方は温かい目で見守ると共に、
プラスの知恵やアドバイスを是非ともお待ちしてます！

それでは、本日の内容に参ります！！

#問題

本日の学びの元となった問題はこちら

**C - Walk on Multiplication Table**
https://atcoder.jp/contests/abc144/tasks/abc144_c

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658983/67fe60e6-3061-7459-9e48-163cdbb1eace.png)


例題のN=10で考えてみると、iとjの候補は (1, 10) (2, 5)の２つ。
N = i * j を満たすiとjの組み合わせでi + jが最小のものを考えればよいですね。
じゃあ「約数を取得しよう！」と考えたところで、
「あれ？どうすればいいんだっけ」状態に陥る。。。笑

#自然数Ｎの約数はこうやって取得する！！

Nが最大10**12なのでfor文で1から全探索するのは
時間がかかりすぎるので工夫が必要です。

```python:qiita.rb
N = int(input())
divisors = []
for i in range(1, int(N**0.5)+1):
    if N % i == 0:
        divisors.append(i)
        if i != N // i:
            divisors.append(N//i)

divisors.sort()
```

このように√Ｎ（約数の折り返し地点）まで探索すれば
全ての約数は取得できるということがポイントですね。

#最後に
こういうアルゴリズム素で気づける人になりたい。
てか気づけるやつすげえな
IBM Cloud Kubernetes ServiceのContext【メモ】

#はじめに
IBM Cloud Kubernetes Service(IKS)のクラスタを作成してContextを設定したら、トークンがExpireしていると出てきました。
その対処方法のメモです。

#事象
IKSのクラスタ作成後、ドキュメントに沿ってContextを設定した。Contextの設定自体はできているように見えるが、kubectl コマンドを実行すると、"Provided refresh token is expired"と表示され、APIサーバへの接続がエラーになる。

```
% ibmcloud ks cluster config --cluster mycluster-free
OK
mycluster-free の構成は正常にダウンロードされました。

mycluster-free のコンテキストを現在の kubeconfig ファイルに追加しました。
これで、クラスターに対して「kubectl」コマンドを実行できます。 例えば、「kubectl get nodes」を実行します。
% kubectl get node
Unable to connect to the server: failed to refresh token: oauth2: cannot fetch token: 400 Bad Request
Response: {
	"errorCode": "BXNIM0408E",
	"errorMessage": "Provided refresh token is expired"
}
% kubectl config get-contexts |grep mycluster
*         mycluster-free/brpexxxxxxxxxxx          mycluster-free/brpexxxxxxxxxx   aaa@bbb.com/753ba45c582841918c73458c54615f06/iam.cloud.ibm.com-identity   default
```

#対処

プラグインをアップデートして、Contextを再設定した。

##プラグインのアップデート
```
% ibmcloud plugin list
インストール済みプラグインをリストしています...

プラグイン名                           バージョン   状況
cloud-functions/wsk/functions/fn       1.0.39       更新が使用可能です
cloud-object-storage                   1.1.3
container-registry                     0.1.471
container-service/kubernetes-service   1.0.57       更新が使用可能です
% ibmcloud plugin update
リポジトリー 'IBM Cloud' からすべてのインストール済みプラグインのアップグレードを確認しています...

以下のプラグインが、アップグレードに利用可能です。
1 つ選択して続行してください (または Enter を押してスキップします):
1. 'cloud-functions/wsk/functions/fn 1.0.39' から 'cloud-functions/wsk/functions/fn 1.0.41' へ
2. 'container-service/kubernetes-service 1.0.57' から 'container-service/kubernetes-service 1.0.99' へ
3. 上記のすべて
数値を入力してください> 2

'container-service/kubernetes-service 1.0.57' から 'container-service/kubernetes-service 1.0.99' へ更新
バイナリー・ファイルをダウンロードしようとしています...
 21.83 MiB / 21.83 MiB [==================================================================================================================================] 100.00% 3m11s
22888016 バイトがダウンロードされました
バイナリーを更新しています...
OK
プラグインは正常にアップグレードされました。
```

##Contextの再設定

```
% ibmcloud ks cluster config --cluster mycluster-free
OK
mycluster-free の構成は正常にダウンロードされました。

mycluster-free のコンテキストを現在の kubeconfig ファイルに追加しました。
これで、クラスターに対して「kubectl」コマンドを実行できます。 例えば、「kubectl get nodes」を実行します。
% kubectl get node
NAME             STATUS   ROLES    AGE   VERSION
10.144.185.145   Ready    <none>   75m   v1.17.7+IKS
% kubectl version --short
Client Version: v1.16.2
Server Version: v1.17.7+IKS
```

---

IKSは無料プランだと30日でクラスタが削除されてしまいます。前回作成した時は、Kubernetesのバージョンが「1.16.9」で、今回は「1.17.7」なので、その差が影響しているのかなと思っています。
初心者に多いPythonエラー 10選

初めてPythonを学ぶ途端、Pythonのエラーメッセージの意味を理解するのは少し複雑かもしれません。よく見るエラーヒントは下記のようにご参照ください。

#####1）if、elif、else、for、while、class、defの最後に追加するのを忘れた。
エラーヒント：SyntaxError ：invalid syntax
エラーは次のコードで発生します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/90d11409-e95b-54ae-8dd8-f9384f7e1cfd.png)
#####2）「＝」と「＝＝」の使用
エラーヒント：SyntaxError ：invalid syntax
「＝」は代入演算子であり、「＝＝」は比較演算である。エラーは次のコードで発生します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/b41152fa-5f99-dfc0-1180-d6024641c4b8.png)
#####3）forループでlen（）を呼び出すのを忘れた
エラーヒント：TypeError: ‘list’ object cannot be interpreted as an integer
通常、インデックスでlistまたはstringの要素を反復処理します。これには、range（）関数を呼び出す必要があります。 このリストを返す代わりに、len値を返すことを忘れないでください。エラーは次のコードで発生します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/0091c815-1a02-6bbd-c978-fbd18b9c9186.png)
#####4）string値を変更する
エラーヒント：TypeError: ‘str’ object does not support item assignment
stringは不変のデータ型であり、エラーは次のコードで発生します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/e623fd28-83f0-b451-340a-31c283bde8c9.png)
#####5）文字列以外の値を文字列に接続する
エラーヒント：TypeError: Can’t convert ‘int’ object to str implicitly
エラーは次のコードで発生します。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/ca93bc43-a6c1-cef1-0de0-e1de7fde730e.png)
#####6）文字列の最初と最後に「’」を追加するのを忘れた
エラーヒント：SyntaxError: EOL while scanning string literal
エラー次のコードで発生します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/30e673e4-a4ee-0c44-eb69-faf8b041f241.png)
#####7）変数名としてPythonキーワードを使用する
エラーヒント：SyntaxError: EOL while scanning string literal
Pythonキーワードは変数名として使用できません。このエラーは次のコードで発生します：
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/fe2a458f-471a-e9b8-53bf-842f559973b8.png)
#####8）メソッド名のスペルが間違っている
エラーヒント：AttributeError: ‘str’ object has no attribute ‘lowerr’
このエラーは次のコードで発生します：
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/38990e2f-d0ec-33a9-dc2a-91341411e8bb.png)
#####9）参照がリストの最大インデックスを超えている
エラーヒント：IndexError: list index out of range
このエラーは次のコードで発生します：
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/95c11270-547b-14dc-8272-1e008f008393.png)
#####10）range()を使用して整数のリストを作成する
range()は実際にlist値ではなく「range object」を返すことを覚えておく必要があります。
エラーヒント：TypeError: ‘range’ object does not support item assignment
このエラーは次のコードで発生します：
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/c5237007-6a26-8037-5b62-f0f9521f95c6.png)
TypeError: unsupported operand type(s) for /: 'list' and 'float'

###タイトルにあるエラーを解決
##内包表記で作ったリストに定数をかけたところ、エラーが発生。np.array()で括ってnumpyで計算させたら解決![スクリーンショット 2020-06-24 16.10.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468640/c466d100-d729-cec1-aa93-bfe7948fd03c.png)
![スクリーンショット 2020-06-24 16.11.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468640/331f9b9a-9669-7947-704a-ba0f9d44ae39.png)
自分のPCでSSL用鍵ファイル、CSRファイルの作成方法

## 今回作る鍵、CSRファイル
今回作るファイルは以下の4つとなります。
※SSLは単年ごとに更新することが多いため、作成するファイル名には西暦を入れておくことをオススメします。

- 元になる鍵（.key.org）ファイル作成
- パスフレーズも.txtファイルで作成
- PEMフレーズで暗号化解除した鍵（.key）ファイル作成
- CSRファイル（.csr）の作成

### 環境
OS:MacOS
terminal:iTerm2


## opensslのバージョン確認

まずは自分の環境に`openssl`があるかを確認します。

```japanese:
openssl version
```
では、実際にコマンドを叩いてみます。

```japanese:Terminal
$ openssl version
OpenSSL 1.1.1f  31 Mar 2020
```
上記のような結果が返ってきました。

※opensslがない場合はHomebrewからインストール、バージョンアップ、コマンドの有効化をして下さい
参考：[CSR・秘密鍵の生成のために、macにHomebrewとopenSSLをインストールした](https://coquelicot-web.com/magazine/homebrew-openssl/)

## 2048bit の秘密鍵を作成

わかりやすいように、自分のデスクトップに移動してから`opensslコマンド`で鍵ファイルを作成します。

```japanese:Terminal
$ cd /Users/username/Desktop/
$ openssl genrsa -des3 -out sample.com_2020.key.org 2048

Generating RSA private key, 2048 bit long modulus (2 primes)
...+++++
..+++++
e is 65537 (0x010001)
Enter pass phrase for sample.com_2020.key: //任意のパスフレーズ
Verifying - Enter pass phrase for sample.com_2020.key: //任意のパスフレーズの確認
```

`cdコマンド`で自分のデスクトップへ移動し、`opensslコマンド`で、鍵長を`2048bit`で指定して作成しました。
作成の際にパスフレーズを設定するので、今回は`password`として作成しました。パスフレーズの確認も同じです。
デスクトップに`sample.com_2020.key.org`というファイルが作成されていると思います。

この時設定したパスフレーズは`.txt`ファイルにしてバックアップとして保存しておきます。
※バックアップが不要な方はスルーしてください。

## パスフレーズの暗号化解除した鍵（.key）ファイルを作成

作成した`.key`ファイルのパスフレーズを外します。

```japanese:Terminal
$ openssl rsa -in sample.com_2020.key.org -out sample.com_2020.key
Enter pass phrase for sample.com_2020.key:password
writing RSA key
```

簡単な確認方法としては`.org`のファイルと`.key`ファイルを見比べてみてください。
先頭2.3行目の違いがわかるかと思います。


### CSRファイルの作成

作成した`sample.com_2020.key`を元にCSRファイルも作成していきます。

```japanese:Terminal
$ openssl req -new -key sample.com_2020.key -out sample.com_2020.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

-----
Country Name (2 letter code) [AU]:JP //2文字国コード
State or Province Name (full name) [Some-State]:Osaka //所在地の都道府県名
Locality Name (eg, city) []:Osaka-city //所在地の市区町村名
Organization Name (eg, company) [Internet Widgits Pty Ltd]:sample inc. //組織、会社名
Organizational Unit Name (eg, section) []:sales //部署部門名
Common Name (e.g. server FQDN or YOUR name) []:sample.com //ドメイン
Email Address []: //入力不要

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: //入力不要
An optional company name []: //入力不要
-----
```
opensslコマンドを叩くと、CSRに組み込まれる情報の入力を求められます。
必要な情報を入力し完了するとデスクトップに`sample.com_2020.csr`が作成されます。

参考：[[CSR生成] nginx + OpenSSL（新規・更新）](https://jp.globalsign.com/support/csr/532.html)

### できあがったファイルリスト
- sample.com_2020.key.org
- sample.com_2020.key
- sample.com_2020.csr
- sample.com_2020_pass-phrase.txt

できあがった自作のCSRでSSL証明書も購入できますし、鍵ファイルもサーバーへインストールすることでSSL対応することもできます。
インストールについてはもう少し勉強してから書ければなと思います。
Custom URL Schemeを便利に使うためのStruct

Custom URL SchemeのURL文字列をSwift上で使用できるようにパースするための構造体を考えたのでメモ。

想定URL形式: `someApp://home/articleDetail?userId=100&articleId=200&searchText=hoge`

Custom URL Scheme自体の実装はこちらを参照。
[Custom URL Schemeでアプリ内の任意のページを表示する](https://qiita.com/yamataku29/items/67f12142522306c3f86a)

```swift
// DeepLinkHierarchy.swift

struct DeepLinkHierarchy {
    enum TabType: String {
        case home // ※サンプルケース
        case article // ※サンプルケース
        case setting // ※サンプルケース
        case myPage // ※サンプルケース
        case none // ※サンプルケース
    }

    enum ScreenNameType: String {
        case articleDetail
        case archive
        case changeAccount
        case none
    }
    
    var tabType: TabType
    var screenNameType: ScreenNameType
    var query: DeepLinkQuery
    
    init(host tabText: String, query queryText: String) {
        tabType = TabType(rawValue: tabText) ?? .none
        screenNameType = ScreenNameType(rawValue: path) ?? .none
        query = DeepLinkQuery(queryText)
    }
}

struct DeepLinkQuery {
    var userId: Int? // ※サンプルプロパティ
    var articleId: Int? // ※サンプルプロパティ
    var searchText: String? // ※サンプルプロパティ
    
    init(_ query: String) {
        if let userIdText = query.getValue(by: "userId") {
            userId = Int(userIdText)
        }
        if let articleIdText = query.getValue(by: "articleIdText") {
            articleId = Int(articleIdText)
        }
        searchText = query.getValue(by: "searchText")
    }
}

private extension String {
    func getValue(by key: String) -> String? {
        return components(separatedBy: "&")
            .map({ $0.components(separatedBy: "=") })
            .first(where: { $0.first == key })?[1]
    }
}
```

`TabType`と命名しているのは、UITabBarを利用している前提のもと、どのタブをルートとしておくかの判定に利用する想定とした。
また、ルートタブを指定しつつ、遷移先画面を`ScreenNameType`で判別する。

```Swift
// AppDelegate.swift

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let deepLinkHierarchy = DeepLinkHierarchy(host: url.host ?? "", query: url.query ?? "")
        print("tabType: \(deepLinkHierarchy.tabType)")
        print("UserId: \(deepLinkHierarchy.query.userId)")
        print("articleId: \(deepLinkHierarchy.query.articleId)")
        print("searchText: \(deepLinkHierarchy.query.searchText)")
        return true
    }
```


ログアウトプット

```
tabType: home
UserId: Optional(100)
articleId: Optional(200)
searchText: Optional("hoge")
```
Excel便利ショートカット集

# Excel便利ショートカット集

覚えたい順になってるよ（個人差があります）

## 重要
### ファイル類
|Command     |Shortcut   |Memo     |
| --- | --- | --- |
|Open     |Ctrl + O     |    |
|Save     |Ctrl + S     |上書き保存     |
|Save As     |F12    |Ctrl + Alt + Sでない     |
|Newfile     |Ctrl + N     |便利     |
|Close     |Ctrl + W     |便利     |
|Export To Pdf    |Alt + F + E + P     |File + Export + PDF     |
|Print    |Ctrl + P     |PDFもこっちのほうが早い説がある     |
### 基本操作
この辺は覚えてないと呼び出せない

|Command    |Shortcut     |Memo     |
| --- | --- | --- |
|Undo     |Ctrl + Z     |ないと死ぬ系     |
|Redo     |Ctrl + Y     |使用頻度は低めかも     |
|Edit Cell     |F2     |すでに何か入ってるときとかに使える     |
|Find     |Ctrl + F    |重要     |
|Replace     |Ctrl + H     |最重要、検索より使う     |
|Select All     |Ctrl + A     |自動で範囲を決めてくれるのでバンバン使おう     |
|Move Sheets (→)     |Ctrl + Pageup     |地味に便利なので使って自慢しよう     |
|Move Sheets (←)     |Ctrl + Pagedown     |同上     |
|Insert Row And Column     |Ctrl + `     |便利     |
|Delete Row And Column |Ctrl + -|便利|
|Select All(Row)|Ctrl + Space|強い（確信）|
|Select All(Col)|Shift + Space||
|Add Sheet |Ctrl + F11|これから使おう|
|Rightclick Window |Shift + F10| 地味便利系機能、メニューキーでもよし|
|Display Expression|Ctrl + `|編集するときに式を上書きしないように表示しておこう|
|Function Window|Shift + F3|よく使う|
### リボン操作
この辺は表示が出るのでそれに従えばオッケー

|Command    |Shortcut     |Memo     |
| --- | --- | --- |
|Home|Alt + H||
|Auto Fill|Alt + H + Fi + S|覚え方:Home+Fill+(S) オートフィルは+F加算は+L|
|小数点位置|Alt+ H + Zn + 0 Or 9| Zは何でかわからぬ|
|区切り(1,000)|Alt + H + Zn + K | Kugiriです|
|%|Alt + H + Zn + P |よく使う|
|Insert |Alt + N | Insert|
|Table |Alt + N + Zb + V ||
|Image|Alt + N + Zi + P | この辺はよく使うのでziまでは覚えよう|
|Header & Footer|Alt + N + Zt + H1 |奥深くなのでこれでいこう|
ほかに一杯あるけどキリがないので指示に従おう
bowling の physical simulation で Springhead を使ってみた C++ (2)

[前回](https://qiita.com/nomissbowling/items/edd8a81b94ccea70e8f8) の続き。

- PHScene に PHSolid を作成すると physical simulation 対象になるが debug=true のときに表示される。 wireframe と solid 表示を切り替えたり色を付けたり(SetWireMaterial() SetSolidMaterial() GRRenderBaseIf::{reserved_color_name})が可能。 (簡単なデモだとこれでも充分だが texture が貼れないのと debug=false で PHScene が表示されない。)
- debug=false で表示させるには GRMesh 等で vertices に color を付けるか texture (texCoords と texname) を設定する必要がある。
- GRMesh を表示させるには GRScene で GRFrame を作成し(GRScene の world に追加。 parent=NULL (省略時) または parent=grScene->GetWorld() ちなみに world は GRScene の最初の Child として造られている。)、さらに FWSdk の Scene(N) で予め作成した FWObject に PHSolid と GRFrame を bind すると physical simulation と連動してくれる。

![test_Springhead_bowling_4scenes_20200624.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537788/6c0afd57-9f0f-ad64-5fc6-f1254a00c9b0.gif)

ソース[途中経過](https://github.com/nomissbowling/Springhead_test)

(GRMeshDesc で meshd.faces の指定を間違うとコンパイルは通っても実行時に落ちるのはもちろんだが、落ちる場所が不定。new (alloc) で落ちたり delete で落ちたり。結果的に原因は違っていたが meshd.vertices 等の頂点数や GRFrame が多過ぎるのかと思って嵌った。バグを追うのが大変なので meshd の中身をいつでも表示出来る関数を用意した。)

今後の目標
==========

- アプローチからボール投球とARATの制御
- レンコンでボールの軌道を変化させる
- ボールの材質
- ローリングトラックやボール軌道の表示
- ボール通過でレンコンを変化させる
- ボール回収とリターンラック

まだまだ[続く](https://qiita.com/nomissbowling/items/662c08328d779e2432f2)
エラーの解決手順

##仮説と検証を自分なりに掘り下げて分解してみた。

1. 問題の認識（問題であると認識すること。解決すべきテーマであると捉え、解決目標を決める。）
2. 原因調査と分析（問題を起こしている原因を調査する。また解決目標との間にある諸課題を探り出し、関係付けをする。）
3. 解決策の立案	（問題の原因を除去する解決策を考える。または原因となっているものに影響されない解決策を考える。）
4. 解決策の実施（解決策を実行する計画を立てる。確実に実施する。）
5. 結果の評価




###よくわからない用語が何を指しているのかを理解する
（固有名詞とか: webpack, precompileは何しているとか, nodejs, lambda, ロードバランサー）

###それが何に分類されるのかを把握する←(よくわからんのいっぱいあるなー)
（npm, yarn, pyenv, rbenvだったらバージョン管理ツールである。とか、apache, nginx, だったらwebサーバーであるとか）
###エラーの原因を理解する
今回だったらアップデートでwebpackが標準装備になってフロント周りが怪しいとか
閲覧中のWebページのリンクをコピーするBookmarklet

SlackやGithubでリンクを共有する際に面倒だなーと思ったところ、同僚も面倒と思ってたらしいので用意してみました.


![bklet_cp_link.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21086/e860015b-169d-61a9-544e-2a1ed64bc9bd.gif)

- [ブックマークレットの登録方法 - Qiita](https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04)

## cp link
リッチテキストのリンクをクリップボードにコピーします

- タイトルに`#`から始まる数字があればそこのみリンク
- タイトルがない場合はURLがリンク名

```js
javascript:(c=>{const d=b=>c.createElement(b),e=(c,a)=>c.appendChild(a),f=(d,a)=>e(d,c.createTextNode(a)),g=c.body,h=location.href,i=c.title,j=i.match(/(?<=\W|^)(?=\W|$)#\d+/),k=d("span"),l=d("a");l.href=h,j?(f(l,j[0]),f(k,i.slice(0,j.index)),e(k,l),f(k,i.slice(j.index+j[0].length))):(f(l,i||h),e(k,l)),e(g,k),c.getSelection().selectAllChildren(k),c.execCommand("copy"),g.removeChild(k)})(document);
```

<details>
<summary>Show source code</summary>
<div>

```js
((doc) => {
  const createNode = (a) => doc.createElement(a),
    appendNode = (a, b) => a.appendChild(b),
    appendText = (a, b) => appendNode(a, doc.createTextNode(b)),
    body = doc.body,
    url = location.href,
    title = doc.title,
    result = title.match(/(?<=\W|^)(?=\W|$)#\d+/),
    base = createNode("span"),
    anchor = createNode("a");
  anchor.href = url;
  if (result) {
    appendText(anchor, result[0]);
    appendText(base, title.slice(0, result.index));
    appendNode(base, anchor);
    appendText(base, title.slice(result.index + result[0].length));
  } else {
    appendText(anchor, title || url);
    appendNode(base, anchor);
  }
  appendNode(body, base);
  doc.getSelection().selectAllChildren(base);
  doc.execCommand("copy");
  body.removeChild(base);
})(document);
```
</div>
</details>


## cp #link

`cp link` とほぼ同じ. クリップボードにコピーされるのは一部だけになる.
GithubのIssueのリンクとかに使ってます.


```js
javascript:(c=>{const d=(c,a)=>c.appendChild(a),e=(e,a)=>d(e,c.createTextNode(a)),f=c.body,g=location.href,h=c.title,i=h.match(/(?<=\W|^)(?=\W|$)#\d+/),j=(b=>c.createElement(b))("a");j.href=g,i?e(j,i[0]):e(j,h||g),d(f,j),c.getSelection().selectAllChildren(j),c.execCommand("copy"),f.removeChild(j)})(document);
```

<details>
<summary>Show source code</summary>
<div>

```js
((doc) => {
  const createNode = (a) => doc.createElement(a),
    appendNode = (a, b) => a.appendChild(b),
    appendText = (a, b) => appendNode(a, doc.createTextNode(b)),
    body = doc.body,
    url = location.href,
    title = doc.title,
    result = title.match(/(?<=\W|^)(?=\W|$)#\d+/),
    anchor = createNode("a");
  anchor.href = url;
  if (result) {
    appendText(anchor, result[0]);
  } else {
    appendText(anchor, title || url);
  }
  appendNode(body, anchor);
  doc.getSelection().selectAllChildren(anchor);
  doc.execCommand("copy");
  body.removeChild(anchor);
})(document);
```
</div>
</details>


## cp md link
Markdownのリンクをクリップボードにコピーします

```js
javascript:((a)=>{const b=a.createElement("span");b.appendChild(a.createTextNode("["+a.title+"]("+location.href+")"));a.body.appendChild(b);a.getSelection().selectAllChildren(b);a.execCommand("copy");a.body.removeChild(b);})(document);
```

## おまけ
それほど複雑じゃないコードだったので、最初からminifyしたショートコードを書いてたけど、ちょいちょいカスタマイズしたくなったので、[JSCompress](https://jscompress.com/) を使って変換するようにした
ArgoCD セットアップからGitHubログインまで(EKS)

公式ドキュメントのページが分散していてやや探し辛いため備忘用にまとめました。

## 1. [ArgoCDのインストール](https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml)

```sh
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
```

## 2. ロードバランサー設定
LoadBalancerを確認

```sh

kubectl get svc argocd-server -n argocd
NAME            TYPE           CLUSTER-IP        EXTERNAL-IP                                   PORT(S)                      AGE
argocd-server   LoadBalancer   123.456.789.000   xxxxxxxxxx.ap-northeast-1.elb.amazonaws.com   80:30203/TCP,443:30802/TCP   1d10h
```

リスナー構成のデフォルトは443がTCPになっているため、HTTPSに変更
<img width="784" alt="Screen Shot 2020-06-24 at 15.10.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294232/73919e3e-375f-3a42-b189-de06941ed963.png">

## 3. [GitHubにアプリケーションを登録](a93012a4893654dfa9f38aa7bc6d8698-2122045883.ap-northeast-1.elb.amazonaws.com)
![](https://argoproj.github.io/argo-cd/assets/register-app.png)
![](https://argoproj.github.io/argo-cd/assets/oauth2-config.png)

## 4. [SSO有効化とパスワードログインの無効化](a93012a4893654dfa9f38aa7bc6d8698-2122045883.ap-northeast-1.elb.amazonaws.com)

```sh
kubectl edit cm argocd-cm -n argocd
```

```yaml
...
data:
  url: "https://argocd.example.com"
  admin.enabled: "false"
  dex.config: |
    connectors:
      - type: github
        id: github
        name: GitHub
        config:
          clientID: xxxxxxxxxx
          clientSecret: xxxxxxxxxx
          orgs:
            - name: mycompany
              teams:
               - my-team
..
```

設定に問題がなければログイン画面が変化します
<img width="314" alt="Screen Shot 2020-06-24 at 15.02.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294232/8ef168c4-74a2-cd8f-2b80-6fb544e9ef37.png">

## 5. Organization accessの有効化
GitHub組織のオーナーにアプリケーションのアクセスをリクエストします。[(参考)](https://help.github.com/ja/github/setting-up-and-managing-your-github-user-account/requesting-organization-approval-for-oauth-apps)
承認後、GitHubログインが可能になります。

## 6. [ロールの変更](a93012a4893654dfa9f38aa7bc6d8698-2122045883.ap-northeast-1.elb.amazonaws.com)
mycompany:my-teamを管理者にしてみます

```sh
kubectl edit cm argocd-rbac-cm -n argocd
```

```yaml
...
data:
  policy.default: role:readonly
  policy.csv: |
    p, role:org-admin, *, *, *, allow
    g, mycompany:my-team, role:org-admin
...
```

以上
Jupyter labでRおよびRstudioのパイプ演算子ショートカットキーを使う

R notebookで作業する機会が増えてから、R markdownの使い勝手悪いよなあと感じ始め、
notebook的な使い方であればJupyterlabに乗り換えた方が良いのではと思ってトライ。

乗り換えるにあたり、パイプ演算子のショートカットは譲れないポイントだったので設定方法を調べた。

### 環境
macOS 10.14.6
R 3.5.2
Python 3.7 (Anaconda)

##### R側の準備
Rを起動してIRkernelを入れる
依存関係にあるパッケージも自動的に入る

~~~R
install.packages('IRkernel')
IRkernel::installspec()
q()
~~~

##### Jupyter labでRを起動する

new > notebook > kernel選択でRの選択肢が増えていれ成功。
非常に簡単。

##### Jupyter labの拡張機能

日本語の詳しい解説記事（[リンク1](https://qiita.com/canonrock16/items/d166c93087a4aafd2db4)、[リンク2](https://qiita.com/simonritchie/items/88161c806197a0b84174)）
があるので詳細は割愛する。

`variable inspector`を入れるとRstudioの見た目に近くなる。
ただし動作が重くなる原因になるという話も。
`contextual_help`があれば`variable inspector`も別にいらないかもしれない。
他はtocや`jupyterlab-lsp`などお好みで。

# パイプ演算子のショートカットを使う
Rstudioのパイプ演算子`%>%`のショートカットコマンド`⌘ + Shift + M`をjupyter labでも使いたい。
色々調べた結果、[拡張機能でテキスト挿入をコマンド化](https://github.com/ryanhomer/jupyterext-text-shortcuts)した？方のスクリプトを利用させてもらうのが楽だという結論に至る。

~~~sh
jupyter labextension install @techrah/text-shortcuts
~~~

その後jupyter labを起動し、メニューから
`Settings > Advanced Setting Editor > Keyboard Shortcuts > User Preference`
に移動し、下記コマンドをペースト

~~~
{
    "shortcuts": [
        {
            "command": "text-shortcuts:insert-text",
            "args": {
                "text": "%>%",
                "autoPad": true
            },
            "keys": [
                "Accel Shift M"
            ],
            "selector": "body"
        },
        {
            "command": "text-shortcuts:insert-text",
            "args": {
                "text": "<-",
                "autoPad": true
            },
            "keys": [
                "Alt -"
            ],
            "selector": "body"
        }
    ]
}
~~~

なお、[Chromeは⌘ + Shift + Mがデフォルトのショートカットで埋まっていて](https://support.google.com/chrome/answer/157179?hl=ja)、しかも変更が出来ないらしい。
**衝突するのではと考えて下記のように起動ブラウザの変更をしてみたが、結局Chromeでも使えた**。

##### 蛇足
jupyter labで使用するブラウザをsafariに変更したい場合は、

~~~
jupyter lab --generate-config
~~~
で生成されたjupyter_notebook_config.pyの中身を編集。
95行目あたりにの

~~~python
## Specify what command to use to invoke a web browser when opening the notebook.
#  If not specified, the default browser will be determined by the `webbrowser`
#  standard library module, which allows setting of the BROWSER environment
#  variable to override it.
#  c.NotebookApp.browser = ''
~~~

とコメントアウトされている箇所を、

~~~python
c.NotebookApp.browser = u'safari'
~~~

のように編集する。
[`%s`を後ろにつないと上手く行かない](https://qiita.com/nannoki/items/315a12a8700c1ca92da3)という記事もあったが、私の環境では何故かこれでも動作した。
GoogleChatのグループチャットのスレッド一覧リンクを表示するブックマークレット（コピペでOK）

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570700/b29a0e0c-607e-74c6-d07c-97a691742370.png)
#GoogleChatのグループチャットのスレッド一覧リンクを表示するブックマークレット（コピペでOK）

GoogleChatには、
グループチャットでスレッドを作る機能はありつつも、
あくまでチャットなので、一覧化レイアウトがありません。
なので、簡単にログが流れて行ってしまいます。

そこで、今表示しているグループチャットのスレッドを
一覧表示するブックマークレットを作成しました。
需要があるかわかりませんので、使用にも部品取り（何かのヒントに）
にもご活用いただければ幸いです。

**使用方法**
適当なブックマークを作り、そのURLに下記のJavascriptを
貼り付けていただき、GoolgeChatでグループチャットを開き、
このブックマークレットをクリックすれば起動します。

※諸注意：
  PC版Chromeで動作確認しています。
  Googleの仕様が変更となった場合には使えません。
　2020年6月24日現在の仕様となります。

**ポップアップHTMLで一覧表示する版**
`javascript:(function(){links=document.querySelectorAll("c-wiz[data-topic-id]");kekka="";for(i=0;i<links.length;i++){for(z=0;z<links[i].attributes.length;z++){ if(links[i].attributes[z].name=="data-topic-id"){ if(kekka.indexOf(links[i].attributes[z].value) == -1){kekka+="<tr><td style='font-size:10px;'>"+location.href+"/"+links[i].attributes[z].value + "</td><td style='font-size:10px;'>" + links[i].firstElementChild.innerText + "</td></tr>";}else{}}else{}; }} myWindow = window.open("", "myWindow", "width=600,height=400");myWindow.document.write("<table>"+kekka+"</table>");})()`

**コンソールに表示する版**
`javascript:(function(){links=document.querySelectorAll("c-wiz[data-topic-id]");kekka="";for(i=0;i<links.length;i++){for(z=0;z<links[i].attributes.length;z++){ if(links[i].attributes[z].name=="data-topic-id"){ if(kekka.indexOf(links[i].attributes[z].value) == -1){kekka+=location.href+"/"+links[i].attributes[z].value+"\t"+links[i].firstElementChild.innerText;}else{}}else{}; }} console.log(kekka);})()`

##簡易解説
すべてjavascriptです。Jqueryは使いません。
難しい事はしておらず、Googleのコーディング仕様を
把握するのが少し時間がかかるというくらいですw

`links=document.querySelectorAll("c-wiz[data-topic-id]");`
セレクターでスレッドの区切りとなるタグを取得します。

`links[i].attributes`
該当のタグの属性を取得します。

`if(links[i].attributes[z].name=="data-topic-id")`
該当のタグ／属性は複数存在するため、forとifを使って
目当ての属性を抜き出します。
※data-topic-idに、スレッドのIDが格納されています。

`if(kekka.indexOf(links[i].attributes[z].value) == -1)`
.valueで属性の値を取得していますが、
タグが2つずつ存在し重複があるため、「値を格納する変数」の
中をindexOfで確認して、存在しなければ書き出しする事にしました。

`links[i].firstElementChild.innerText`
これは各スレッドに対する最初の書き込みを取得しています。
firstElementChildで最初の子要素を見つけています。
データフレームに格納された複数行テキストの最大文字数を調べる

メモ

<img width="643" alt="スクリーンショット 2020-06-24 15.21.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206657/52d80ad4-e828-d5f8-e839-1b179ac7db6f.png">

```python:
mojisuu = []
for i in range(len(input_data)):
    mojisuu.append(len(input_data.iloc[i,0]))
print(max(mojisuu))
#最大文字数の文章は122文字
```
kotlinプログラムをvscodeで開発・デバッグする

# kotlinプログラムをvscodeで開発・デバッグする

<img width="520" alt="Screenshot 2020-06-25 14.52.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153042/0856bc3b-432a-2383-681b-bc71a971a112.png">

## TL;DR

fwcd.kotlinのextensionをインストールすること

## 概要

多くのQiita記事では、kotlinのプログラムをVSCodeで実行することを説明したが、肝心なデバッグを触れていない。

自分で試し成功した結果を皆さんに共有できれば。(基本Mac向けだが、ほとんどはwindowsと共通する)


## 前提条件

* vscode
* Java(OpenJDK)

上記のインストール手順は省略


## 構築手順

### 1. kotlin と gradle


```shell
% brew install kotlin
% brew install gradle
```

### 2. kotlin sample appの作成

```shell
% mkdir kt-sample-app
% cd kt-sample-app
% gradle init --type=kotlin-application

# 出てくる選択肢は全部デフォルトでOK

# 疎通する
% ./gradlew build

BUILD SUCCESSFUL in 3s
8 actionable tasks: 8 executed
```

### 3. VSCodeの拡張のインストール

```
# 以下のvscode extensionの設定を行う

% mkdir -p .vscode
% vi .vscode/extensions.json

-----以下の内容を入力-----
{
    "recommendations": [
        "fwcd.kotlin",
        "vscjava.vscode-java-pack"
    ]
}

# ここからvscodeを起動
% code .

```

「recommended extensionをインストールしますか」のダイアログが表示されるので、
「Install All」でextensions.jsonに書いた２つのextensionをインストールする

ここまでApp.ktファイルを開けば、syntax highlightとauto compleletionが効くようになる

### 4. ビルド・デバッグの設定

```
% vi .vscode/tasks.json

-----以下の内容を入力-----

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "./gradlew build -x test",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "run",
            "type": "shell",
            "command": "./gradlew run"
        },
        {
            "label": "test",
            "type": "shell",
            "command": "./gradlew test"
        }
    ]
}

```

vscodeのメニュー Terminal -> Run Task... で runなどを選ぶ。
これで、 gradlewのbuild / run / testのタスクを実施できる

最後は、デバッグの設定

```
% vi .vscode/launch.json

-----以下の内容を入力-----

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "kotlin",
            "request": "launch",
            "name": "Kotlin Launch",
            "projectRoot": "${workspaceFolder}",
            "mainClass": "kt/sample/app/AppKt",
            "preLaunchTask": "build"
        }
    ]
}

```

※ mainClassのところは自分のAppに合わせて書き換えてください。

適当にbreakpointを設定して、vscodeのDebugタブ -> Runボタンでデバッグができる


設定済みのkt-sample-appのソースは以下から参照できる：
https://github.com/thunderz99/kt-sample-app
AWS Linux2になってコマンドが変わったのでメモ

AWSでhttpをたてるときLinux2を初めて使ったらLinuxとコマンドが少し違って混乱したのでメモ
httpの場合です。
sudo yum -y install httpd　#httpのインストール
sudo systemctl start httpd　#スタート
sudo systemctl enable httpd　#起動時に有効化
sudo systemctl list-unit-files | grep httpd　#自動起動確認
httpd.service                                 enabled 　#自動起動の確認ができました
httpd.socket                                  disabled
RSpec でメソッド呼び出しの引数をブロックでチェック

RSpec の `expect(foo).to receive(:bar).with(...)` では引数のチェックが[いくつかの方法で可能]( https://relishapp.com/rspec/rspec-mocks/v/3-9/docs/setting-constraints/matching-arguments)だが、ブロックで検証したいケースが結構ある。

with には matcher を渡すことができるので、カスタム matcher を定義してやればよい。
下記の例では Struct の特定の attribute のみ検証している

```ruby
RSpec::Matchers.define :a_valid_argument do
  match {|actual| block_arg.call(actual) }
end

it "should call with valid argument" do
  jon = Struct.new(:name).new("Jon")

  expect($stdout).to receive(:write).with(
    a_valid_argument {|a| a.name == "Jon" },
  )

  $stdout.write(jon)
end
```

なお、`with` による引数の検証は引数ごとに行われるので複数の引数をとるメソッドの場合は、引数ごとに matcher を渡す必要がある。

```ruby
it "should call with valid arguments" do
  jon = Struct.new(:name).new("Jon")
  dany = Struct.new(:name).new("Dany")

  expect($stdout).to receive(:write).with(
    a_valid_argument {|a| a.name == "Jon" },
    a_valid_argument {|a| a.name == "Dany" },
  )

  $stdout.write(jon, dany)
end
```
git連携でDjangoアプリをHerokuを使ってデプロイした場合のプログラム実行方法

## 実行方法

`heroku login`した後、
普段用いるコマンドに`heroku run`をつけることで普段通りに操作ができる。

例えば

```
python manage.py shell
```

をデプロイ済みのコードに対して実行したい場合は、

```
heroku run python manage.py shell
```
を実行する。
PHPMVCのC⇆Vについて(見直し用メモ)

###前提知識
namespace…このファイルここに配置されてますよ〜って書いてるやつ
use…他フォルダにあるクラスを利用可能にしたもの


##ルーティング
・アドレスに対してコントローラーメソッドを指示する。
・$requestのプロパティの情報を飛ばす

```ルート情報記述.php
Route::get(アドレス,関数など);
```

```viewとは.php
view(テンプレート名)
//指定したテンプレートのファイルをロードし、レンタリング(表示できるように整える)して返す
```
特定のアドレスにアクセスした際、何の処理を実行するのかを記述したもの。

```web.php
<?php
Route::get(`/`,function(){
    return view(`welcome`);
});
```
####解説
/にアクセスしたらwelcomeのファイルを戻せ（表示しろ）

###ルートパラメータの利用

```ルートパラメータの利用.php
Route::get(`/〇〇/{パラメータ}',function($〇〇//パラメータの値を受け取る引数){
});
```

```ルートパラメータの利用(例文).php
Route::get(`/hello/{msg}',function($msg){
});
///hello/sampleにアクセスした場合、msgにsampleが代入される。
```

####解説
アドレスのパラメータをルーティング処理の一部として使いたい

###必須パラメータと任意パラメータ
ルートパラメータを利用する際、パラメータを記入されないと処理が実行されないようになっている。
これを必須パラメータと呼ぶ。
しかし、パラメータの変数の最後に「？」をつけることによりパラメータを記入せずとも処理が実行される任意パラメータに変更することができる。

```任意パラメータの利用.php
Route::get(`hello/{msg?}`,function ($msg=`〇〇`)
//〇〇には、パラメータが記入されなかった時に出力される文字列を入れる
```

####解説
パラメータ指定されなくても使われたい

##コントローラ
・ビュー
　∟表示させるものを(return view('ファイル名','配列'))で書く
　∟表示させるものに必要なデータを飛ばす
・データベース

```web.phpに記述するやつ.php
Route::get('アドレス','コントローラー名@メソッド名');
```

##ビュー
実際web上に表示させるもの。

###Blade構文
PHPを用いて見栄えの良いビューを作れるようになるビューテンプレート

####値の表示
```値を埋め込む.html
{{値・変数・式・関数など}}
```

```値を埋め込む(HTMLを機能させたい場合).html
{{!!値・変数・式・関数など!!}}
```

####継承
既存のテンプレート(親)再利用して新しいテンプレート(子)を作成する。
親テンプレートには**section**で子テンプレートに表示する区画を設定する。
子テンプレート側には**section**を表示される**yield**を用いる。

実際にレイアウト表示されるのは子レイアウトである。

```継承方法.php
@extends('フォルダ名.ファイル名')
```

```sectionの使い方.php
@section(名前)
-表示内容-
@endsection
```

```yieldの使い方.php
@yield(名前)
```

####ビューコンポーザ
ビューをレンタリングする時に自動的に実行される処理
これを使えるようにするため、サービス(Laravelの機能強化の仕組み)を動かす必要がありそれを動かすために、**サービスプロバイダー**を使う必要がある。


####サービスプロバイダー
用意されているメソッド
**boot**
アプリケーションが起動する際に割り込んで実行される処理(ブートストラップ処理)
ここにビューと処理を用意することで、コンポーザが呼び出されるようになる。
（実質、コントローラみたいな役割をはたす）

**register**
会員登録の処理など…

```boot利用例文.php
public function boot()
    {
        View::composer(
            'hello.index', function($view){
                $view->with('view_message','composer message!');
            }
        );
```

```新出①.php
View::composer(ビューの指定,関数またはクラス)
```
第1引数には、コンポーザーを利用するビューの設定。
第2引数には、実行する処理を書く

```新出②.php
$view->with(変数名,値);
```

```新出③.php
$view(Viewクラスのインスタンス)
```

**サービスプロバイダへの登録**
サービスプロバイダを作るだけでは作動しない。
app\confungにサービスプロパイダが使えるように登録する必要がある