OmniAICreator/Qiita-1.07M huggingface dataset:
【IBM Security Verify】セルフレジストレーションにreCAPTCHAを追加する

# はじめに

少し前になりますが、2022年6月のアップデートで、[ユーザー・インターフェースを使用した reCAPTCHA の管理](https://www.ibm.com/docs/ja/security-verify?topic=integrations-managing-recaptcha-through-user-interface)が追加となりました。

ユーザーのセルフレジストレーションに reCAPTCHA が追加できることを確認してみました。

# 1.reCAPTCHA にサイトを登録

新規でreCAPCHAにサイトを登録します。
https://www.google.com/recaptcha/admin/create

IBM Security Verifyでは、reCAPCHA V3のみサポートされているためV3で登録します。

![qiita (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/5ba48489-bafc-6bf9-b5c6-4225a97cc286.png)

![qiita (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/40c1ebce-f02a-2a15-42b7-3a290d8baca7.png)

# 2.IBM Security VerifyでのreCAPTCHA 統合の構成
管理者画面の統合-reCAPTCHA メニューで、reCAPTCHA のサイトキー/シークレットキーを登録します。
![qiita (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/74060965-cf98-6220-b8e9-5cbc77d7b684.png)

# 3.ユーザー登録フローの構成
ユーザー登録フローを新規作成します。
![qiita (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/578d4ba5-75f1-4a8e-a28d-b77da6f04784.png)
![qiita (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/b8a1cfab-8fe5-37f2-d69b-d087cee80b56.png)

「ユーザーが人間であることを確認してください。」オプションをチェックし、メソッドに先ほど登録したreCAPTCHA を指定します。
![qiita (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/5bc149ba-7846-8aeb-039b-42f9e1c867d4.png)

登録フローの設定を行い、フローを公開します。


# 4.動作確認
作成した登録フローのURLにアクセスします。
画面右下にreCAPTCHAが表示されていることが確認できました。
![qiita (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/e6e3037f-1737-08cc-0b82-e95564b071f1.png)

# 最後に

セルフレジストレーションにreCAPTCHAを追加する機能についてご紹介いたしました。
多言語FizzBuzzチャレンジ10日目:Java

## これまでのまとめ
https://qiita.com/tenteko/private/fc52f7aec63ba5f67854

https://qiita.com/tenteko/private/ca9813f0982370d0c901

https://qiita.com/tenteko/private/bc808ba59f6993019045

https://qiita.com/tenteko/private/74aa4c422196cb5cdeac

https://qiita.com/tenteko/private/ea22bd19360333f9ca85

https://qiita.com/tenteko/private/ec2f7c2f99229a55a7aa

https://qiita.com/tenteko/private/237556777f5c5546af6e

https://qiita.com/tenteko/private/264e4aca8a2ee6761a6c

https://qiita.com/tenteko/private/6e86fa0eeed9d24805ab


## 本日のお品書き
きました、メジャーどころ…!
いろいろな書籍の例でJavaのコード自体は見かけたことがありますが、書いたのは今回が初めてです。

## FizzBuzz
```java
public class FizzBuzz {
    public static void main(String[] args) {
        if (i % 15 == 0) {
            System.out.println("FizzBuzz");
        } else if (i % 3 == 0) {
            System.out.println("Fizz");
        } else if (i % 5 == 0) {
            System.out.println("Buzz");
        } else {
            System.out.println(i);
        }
    }
}
```

- たとえ使わなくても`main`には`String[] args`を引数として明示的に設ける必要がある(ないとコンパイル時に怒られる)

## おまけ：実行方法
JDKをインストール済みなら簡単にコンパイル、実行が可能でした。（とは言ってみましたが、このチャレンジをするまでJavaがコンパイル型なのかインタプリタ型なのかもちゃんと知りませんでした…無知！）

```shell
# edit FizzBuzz.java (including FizzBuzz class)
javac FizzBuzz.java
# FizzBuzz.classが生成される
java FizzBuzz
```
【IBM Security Verify】一定期間ログインしていないユーザーを自動的に無効化する 

# はじめに

少し前になりますが、2022年6月のアップデートで、[一定期間 非アクティブなユーザーを無効化する機能](https://www.ibm.com/docs/ja/security-verify?topic=providers-configuring-global-settings)が追加となりました。

この機能がリリースされる前は、以下のような機能を組み合わせて運用スクリプトを開発・ユーザーを無効化するといった対応が必要でした。
- [IBM Security Verify API で ユーザーの最終ログイン日を取得する](https://qiita.com/fitz/items/a59ccae07a0c877c4b8e)
- [IBM Security Verify API で 複数ユーザーのアカウントを一括無効化する](https://qiita.com/fitz/items/93e10a02f87b8a1607c8)


今回はSCIMフィルターを設定し、特定グループに所属しているユーザーという条件を追加して、ユーザー無効化を確認してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/4a51f895-999e-7f77-c421-0590c0c723d3.png)


# 1.グループ作成/ユーザーの追加

以下の種類のユーザーをグループに追加します。
- 作成されてから一度もログインしていないユーザー
- 最終ログインから60日以上経過しているユーザー
![qiita (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/6c1f67c6-97f1-a101-4dd4-82b7da39cb83.png)
![qiita (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/137a11f9-3237-8857-eb8e-e1144ed7697a.png)
![qiita (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/c1af7477-cb12-b598-4b6c-fc5e77357767.png)



# 2.自動アカウント・クリーンナップの設定

①自動クリーンナップを有効化して、60日非アクティブなユーザーを無効化するように設定します。
![qiita (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/ea0548ee-7359-7c35-dd31-153533a035e5.png)


②testgroupに所属しているユーザーを対象とするため、SCIMフィルターを追加します。
グループはグループ名（displayName）ではなく、idを指定します。

```
memberOf eq "755000H6NC"
```
![qiita (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/cf59e456-8180-aee2-5e73-d6afc668203d.png)


# 3.結果
日本時間の21:00に自動アカウント・クリーンナップが行われました。
いずれのユーザーも無効にかわりました。
- 作成されてから一度もログインしていないユーザー
- 最終ログインから60日以上経過しているユーザー
![qiita (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/0cd78271-1aef-ef3a-5f1b-7d7346b70e67.png)
![qiita (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/6c228aeb-c04b-93f7-e6b5-4163a1b59119.png)

# 最後に

一定期間ログインしていないユーザーを自動的に無効化する機能についてご紹介いたしました。
多言語FizzBuzzチャレンジ9日目:F#

## これまでのまとめ
https://qiita.com/tenteko/private/fc52f7aec63ba5f67854

https://qiita.com/tenteko/private/ca9813f0982370d0c901

https://qiita.com/tenteko/private/bc808ba59f6993019045

https://qiita.com/tenteko/private/74aa4c422196cb5cdeac

https://qiita.com/tenteko/private/ea22bd19360333f9ca85

https://qiita.com/tenteko/private/ec2f7c2f99229a55a7aa

https://qiita.com/tenteko/private/237556777f5c5546af6e

https://qiita.com/tenteko/private/264e4aca8a2ee6761a6c

## 本日のお品書き
ついに来ました関数型言語…! はじめてF#を触ってみます。
ただ現時点ではいろいろこねくり回した関数型の真髄みたいな記述はできません…。
慣れたら面白そうなんですけどね。

## FizzBuzz

```fsharp:main.fsx
let fizzbuzz = function
| n when n%15=0 -> printfn "FizzBuzz"
| n when n%3=0 -> printfn "Fizz"
| n when n%5=0 -> printfn "Buzz"
| n -> printfn "%d" n

List.iter fizzbuzz [1..100]
```
- `|`は関数内のパターンマッチ
    - パターンとして使えるものがいろいろある。今回は変数`n`。`n`の値に対する場合分けとしてwhenを導入している。
    - https://learn.microsoft.com/ja-jp/dotnet/fsharp/language-reference/pattern-matching
- `List.iter $1 $2`で、`$2`の配列に対して`$1`をそれぞれ実行している


## おまけ：実行方法
今回はdotnetコマンドを使ってスクリプトファイルを実行するようにしました。対話式など、そのほかの使い方もあるようです。

```shell
# edit main.fsx
dotnet fxi main.fsx
```

https://learn.microsoft.com/ja-jp/dotnet/fsharp/tools/fsharp-interactive/


dotnetコマンドでは他にもプロジェクトを作成する方法もありそうです。今回は簡単なFizzBuzzなので上記の方法で問題ありませんでしたが、もう少し複雑なことをやろうと思ったら下の方法が良いのかもしれないですね。

```shell
dotnet new console -lang F# -o fizzbuzz -f net6.0
cd fizzbuzz
# edit Program.fs
dotnet run
```

https://dotnet.microsoft.com/ja-jp/learn/languages/fsharp-hello-world-tutorial/intro
2022/11/05主にITとかセキュリティの記事

約3カ月ぶりに「Emotet」が攻撃再開 - 「信頼できる場所」で警告回避
https://www.security-next.com/141138

「Apache Flume」に脆弱性 - アップデートや回避策の実施を
https://www.security-next.com/141112

ランサム被害で個人情報流出の可能性、データは復元 - JA大潟村
https://www.security-next.com/140997

DV被害者情報が加害者に流出、一時的な制限解除がそのままに - 薩摩川内市
https://www.security-next.com/141051

Weekly Report 2022-11-02号
https://www.jpcert.or.jp/wr/2022/wr224301.html

中小企業サイバーセキュリティ対策PR動画を公開しました！(11/2)
https://web.pref.hyogo.lg.jp/press/20221102_11611.html

≪緊急開催≫「ランサムウェアの脅威と対策」
急増 ～ 被害件数は一昨年の約4倍、巧妙化するランサムウェア対策の最前線 ～(11/30開催)
https://bunshun.jp/articles/-/58263?ref=special

シノプシス、セキュア開発成熟度モデル(BSIMM)の調査レポートBSIMM13（日本語版）を公開(11/2)
https://www.nikkei.com/article/DGXZRSP643360_S2A101C2000000/

Nash Squared：経済的混乱にもかかわらず、世界の技術支出は15年超で3番目の速度で拡大－世界最大級のデジタル部門指導者調査で判明(11/3)
https://japan.cnet.com/release/30797971/?ref=rss

DX時代到来！未曽有のリスクに備える「サイバーセキュリティ保険」とは？その概要と加入のメリット(11/3)
https://gentosha-go.com/articles/-/46767

SNSいじめ（ネットいじめ）の問題点と学校に求められる対応(11/3)
https://www.kyoiku-press.com/post-250549/

「トランプは正しかった」TikTokめぐるリスク対応で＝米民主有力議員(11/3)
https://www.epochtimes.jp/2022/11/122898.html

OpenSSLの脆弱性が発見される(11/3)
https://note.com/kingston_inc/n/ne3389228db11

StarlinkをGPS衛星のように使うハック(11/3)
https://hardware.srad.jp/story/22/11/01/1452245/

大阪の総合病院がサイバー攻撃受けランサムウェア感染　しかし止めてはいけない「デジタル化」(11/2)
https://news.yahoo.co.jp/articles/c3cdda9731a22c57939812f374bb6ae6064baeba

サイバー攻撃受けた病院の電子カルテ完全復旧、吉村知事「しばらく時間かかる」(11/1)
https://news.yahoo.co.jp/articles/601c414d76b92f5d7580aa567bf4481c0e35ccda

サイバー攻撃_大阪急性期・総合医療センター(11/2)
https://s-bi.com/wp_diary/kou/2022/11/02/post-75225.html

【速報】「ランサムウェア」サイバー攻撃受けた病院　「紙カルテ」使って祝日明けのあさって一部手術再開へ　大阪急性期・総合医療センター(11/2)
https://news.yahoo.co.jp/articles/2c1b32ddeea35f714197ef71e5bda274c83dd7e5

システム更新できない経営難の会社や団体はシステムやパソコンを入れるな(11/4)
https://www.orangeitems.com/entry/2022/11/04/000000

キーボードに残った「指の熱」　そこからパスワードが盗まれる(11/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100113/102700094/?ST=nxt_thmit_security

千葉県南房総市の小中学校にサイバー攻撃、VPN装置の管理者IDが悪用される(11/4)
https://xtech.nikkei.com/atcl/nxt/column/18/01157/110100073/?ST=nxt_thmit_security

自動車のサイバー対策、ウクライナ侵攻でユーザー意識に変化(11/4)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/07325/

Chromeで増え過ぎたパスワードとブックマークを整理、乗り換え時の移行も楽々(11/4)
https://xtech.nikkei.com/atcl/nxt/column/18/02235/102000003/

Microsoftアカウントのパスワードを忘れた、連絡先未登録でも再設定する方法(11/4)
https://xtech.nikkei.com/atcl/nxt/column/18/02229/101700003/

通信障害の周知広報は悪評だらけ　ルールづくり始まるも課題山積(11/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100110/102700092/

グーグルが新サービスを大量発表　「深読み」記者が注目したトップ3(11/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100111/102700086/

プログラミング言語は単なる道具　しかし通常の道具とはかなり違う(11/4)
https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100112/102700052/

サイバー攻撃者に盗まれたデータはどこにいく？(11/3)
https://news.mynavi.jp/techplus/article/20221103-2502207/
【ngrok】Webhookの通知先をローカル環境にできませんか？

# Webhookの通知先をローカル環境にできませんか？
後輩ちゃん「ローカル環境に外部サービスからのWebhookを受け取りたいんです」
後輩ちゃん「いろいろ試してみましたがうまくいかず、、、」

すずこ「そんな時は、**ngrok**を使おう！」

## 目次
1. [Webhookとは](#webhookとは)
1. [やりたいこと](#やりたいこと)
1. [ngrokとは](#ngrokとは)
1. [実際に使ってみた](#実際に使ってみた)
1. [まとめ](#まとめ)

## Webhookとは
:::note info
Webhook
* アプリケーションから別のアプリケーションに対して、リアルタイムな情報提供を実現するための仕組みのこと
* イベント発生をトリガーとして、データを送信するため、ポーリングを違って必要最低限の通信でデータのやり取りができる
:::

すずこ「開発時のWebhookの受け取り先をローカル環境にしたいんだね」

すずこ「ローカル環境のWebサーバーを外部公開する必要があるので、少々面倒くさいけど、」
すずこ「ngrokというツールを使うことによって、簡単に実現できるようになるよ！」

## やりたいこと

![webhook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2654832/a5678f83-1c69-514a-329f-002bb0759fcf.png)


## ngrokとは
> Serve Web Apps with one command
> ngrok is the programmable network edge that adds connectivity,
> security, and observability to your apps with no code changes
> コードを変更することなくアプリに接続性、セキュリティ、可観測性を 追加するプログラム可能なネット> ワーク エッジです。

[引用](https://ngrok.com/)

すずこ「簡単に言うと、ローカルサーバ（ローカルホスト）に外部から直接アクセスすることを可能にするツールのことだよ」

## 実際に使ってみた
すずこ「実際に使ってみて、便利さを体感してみよう」

1. [ngrok公式サイト](https://dashboard.ngrok.com/get-started/setup)からパッケージをダウンロード
    **※無料サインアップが必要です**
    **※OSに応じたパッケージをダウンロードする**
    **※コマンドもOSによって異なります。下記例はLinuxの手順です**

1. パッケージを展開
    ```
    $ tar -xvzpf ngrok-xxxxxxxxx.tgz
    $ ls
    ngrok ngrok-xxxxxxxxx.tgz
    ```
1. アカウントを接続
    ```
    ngrok公式サイトにアクセスし、ログインするとtokenが発行されている。
    $ ./ngrok config add-authtoken xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    ```
1. 起動する
    ```
    ポート番号はご自由に
    $ ./ngrok http 3000
    ngrok                                                                                                                           (Ctrl+C to quit)
    
    Visit http://localhost:4040/ to inspect, replay, and modify your requests
    
    Session Status                online
    Account                       suzuko (Plan: Free)
    Version                       3.1.0
    Region                        Japan (jp)
    Latency                       -
    Web Interface                 http://127.0.0.1:4040
    Forwarding                    https://b595-126-126-250-90.jp.ngrok.io -> http://localhost:3000
    
    Connections                   ttl     opn     rt1     rt5     p50     p90     
                                  0       0       0.00    0.00    0.00    0.00    
    
    ```
1. アクセスしてみる
    Forwardingに表示されているURLにアクセス
    今回はlocalhost:3000にポートフォワーディングしているため、http://localhost:3000 の内容が表示されればOK！
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2654832/f1cdbe1e-2f77-6dcf-bd9b-387c67fc9c7f.png)
    
    
    **※例として、Forwardingも公開してますが、起動ごとにユニークなキーが発行されるため、記事公開時にはアクセスできません**

## まとめ
後輩ちゃん「こんなに簡単な手順でlocalhostに対し、外部から直接アクセスできるようになるなんて...」

後輩ちゃん「ということは、Webhookのエンドポイントに、ngrokで公開されたURLを登録すればいいんですね！」

すずこ「その通り！そうすれば、Webhookの通知も受け取ることができるよ！」

後輩ちゃん「しかもhttpsまで用意されてるじゃないですか...（歓喜）」
後輩ちゃん「Freeプランでも十分すぎる機能ですね...（大歓喜）」

後輩ちゃん「Webhookのほかにも、色々な使い道がありそうですね！」

---
以上
Guardの自動テストがRunningのまま動かない【Windows・Railsチュートリアル3章】

Cloud9使わずローカル環境で実施していたせいか、チュートリアルに記載の通りに行ってもGuardがうまく動かなかった。
解決策をメモしておく。

# 概要
下記リンク、「3.6.2 Guardによるテストの自動化」に記載されているGuardの初期化、Guardfileの編集を行ったものの、自動テストが完了しなかった。
https://railstutorial.jp/chapters/static_pages?version=6.0#sec-guard

こんな感じで `Running: ～` のあと `[1] guard(main)>` と出たまま動かない。
```
00:52:47 - INFO - Running: test/controllers/static_pages_controller_test.rb
[1] guard(main)>
```
待っていれば結果が出てくるのかな？と思ったが、いつまで経っても何も起こらなかった。

念のため `spring stop` コマンドも実行したが、
```
Spring is not running
```
と言われるだけで、再度 `bundle exec guard` からやり直してみても状況は変わらずだった。

# 環境
OS：Windows10
Railsチュートリアルの版：第6版
コマンドはVSCodeのターミナル（powershell）で実行。

# 解決策
単にspringのパス違いだった。

サンプルからコピペしてきたGuardfileの2行目の
`spring: "bin/rails test",`
を
`spring: "rails test",`
に変えるだけで動くようになった。
```txt:修正前
# Guardのマッチング規則を定義
guard :minitest, spring: "bin/rails test", all_on_start: false do
  watch(%r{^test/(.*)/?(.*)_test\.rb$})
```
```txt:修正後
# Guardのマッチング規則を定義
guard :minitest, spring: "rails test", all_on_start: false do
  watch(%r{^test/(.*)/?(.*)_test\.rb$})
```
`spring stop` する前に `bin/spring stop` したときはエラーメッセージが出たのでパス違いだとすぐ気づけたけど、Guardさんはエラー情報を出してくれなかったから気づくまで時間がかかった。
今後もWindowsで開発していくにあたり、この手のパス違いの問題はよく出てきそうだから留意したい。

# そもそも spring って何なんだ
>Spring は Rails アプリケーションの preloader（プリローダー）の gem です。Rails アプリケーションをバックグラウンドで走らせたままにしておくことにより（pre + load = 前もってロードしておく）、bin/rails や bin/rake コマンドの2回目以降の起動時間が短縮されます。

https://easyramble.com/install-spring-into-rails.html

とのこと。

spring stopしたときSpring is not runningって言われちゃったけど、これってちゃんとSpringが使えていないということなんだろうか……。
開発で役立つAtomの「Teletype for Atom」パッケージ 【リモートワークにオススメ！】

# Teletypeとは
## 遠隔でのチーム開発が可能
### 遠隔で同時にコーディングができるのが特徴
　[Teletype for Atom](https://teletype.atom.io/)は、Googleのドキュメントやスプレットシートのように、複数のユーザでインターネットを返して同時に編集ができる機能です。
　Teletype for Atomは、Atomの拡張機能でパッケージとして無料配布されています。また、開発しているのは、Atomエディタの開発元であるGitHubでAtomとして公開しています。
　Teletype for Atomを使用すれば、企業であればビデオ通話しながら同時に編集や、不明点の確認をしながらの編集が可能です。学生であれば、友人と同時にプログラムの編集が可能です。
　この機能を使用する際に、[GitHub](https://github.com/)のアカウントを使用します。
## 基本情報
公式サイト：[https://teletype.atom.io/](https://teletype.atom.io/)
開発元：[GitHub](https://github.com/)
パッケージ公開元：[Atom](https://atom.io/users/atom)
![スクリーンショット 2022-11-05 1.17.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/ea2a059f-8c6c-a1f3-4719-3998a4c7b8ed.png)


## Peer-to-Peer（P2P)でGitHubのサーバに情報が保存されない
### GitHubのサーバを仲介しないから安心して使える
 Teletype for AtomはPeer-to-Peer（P2P)プロトコルで通信をして、同時編集を可能にしているため、GitHubのサーバを仲介しません。
そのため、GitHubのサーバに開発中のプログラムのコードが保存される心配はありません。
### Peer-to-Peer(P2P)とは
　P2Pモデルとは、P2P、ピア・ツー・ピア（Peer to Peer)のことで、ピアとは利用者、ユーザを指します。利用者同士が直接通信し合うネットワークモデルです。サーバを仲介せづに接続を確立し、通信を行います。

# 導入してみよう
## 手順
今回は、Atomがイストールされている前提とします。
インストールが完了していない方は、[https://atom.io/](https://atom.io/)からダウンロードし、インストールを完了させてください。
### Atomエディタを使用して「Teletype for Atom」パッケージをインストール
１、Setting（環境設定）　＞　Install（インストール）を開きます。
２、Search packagesで「Teletype」を検索します。
３、Install（インストール）をクリックし、パッケージをインストールします。

### コマンドを使用して「Teletype for Atom」をインストール
```command:apmコマンド
 $apm install teletype
```
#
# 使い方
### 1、アイコンをクリック
右下の電波塔のアイコンをクリックします。
![スクリーンショット 2022-11-05 0.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/64afc3ec-b603-f1b3-3a48-3c7429a184ba.png)


### ２、URLを取得する
「share」をオンにすると、上部にURLが表示されます。
![スクリーンショット 2022-11-05 1.01.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/8b265a00-c614-8844-9809-68b847c91ceb.png)

URLをコピし、相手に送信します。
![スクリーンショット 2022-11-05 1.00.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/d4dad7f4-025f-74bc-2c09-b7189f250447.png)


### ３、URLを受け取ったら接続する
　リンクを受け取った側は、鉄塔マークをクリックし、Join a portalをクリックします。
![スクリーンショット 2022-11-05 1.04.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/f7f3a740-38c0-4d77-9443-bc38cbffa8d4.png)

「Enter a　portal URL...」と書かれた入力フォームにURLを貼り付けます。
![スクリーンショット 2022-11-05 1.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/ef683e20-0cfa-285e-8b86-3a595ed6f44a.png)

貼り付けが完了したら、「Join」をクリックして接続しましょう。
接続に成功すると、相手のカーソルが表示されます。
![スクリーンショット 2022-11-05 1.14.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917703/bb6b3ecb-e70a-5ced-dc7c-a76df02f056d.png)
CentOS7でJenkinsをポート番号変えてNginxでリバースプロキシな話

Jenkinsというcronのスゴイやつ(違)を使ってみようとインストールしてみた。
```systemctl start jenkins```で起動したことを確認し（動作確認したとは言っていない）、どうせならNginxが動いているからリバースプロキシ＆サブディレクトリアクセス＆8080というポート番号はなんとなく変えてみたくなったため変更した。
巷で溢れている流れるような手順。そう、/etc/sysconfig/jenkins 変更でね！
```言語:/etc/sysconfig/jenkins
：
JENKINS_PORT="8888"
：
JENKINS_ARGS="--prefix=/jenkins"
```
``` 言語:/etc/nginx/conf.d/jenkins.conf
upstream jenkins {
  server localhost:8888;
}
server {
  listen 80;
  server_name    jenkins;
  location ^~ /jenkins {
    ：
    proxy_pass http://jenkins;
  }
}
```
しかし```http://192.168.1.100/jenkins```で404エラー。

何かミスってるだろうけどどこかが分からない。
巷情報では /etc/sysconfig/jenkins でポート番号とprefixをいじるだけの情報が溢れていて、ディスプレイがドット欠けするくらい見つめても間違っていない。

他人には経緯は興味ないだろうから結論を言うと、systemd が見る jenkins.service のデフォルト設定が効いていて /etc/sysconfig/jenkins の変更なんか何の意味も無かった。
気づくまでの時間は恥ずかしくて言えない。
私の目が節穴なのか、巷情報では見つけられなかった。
あまりにも事例がないので未だに自信は無い。

systemd が見る /usr/lib/systemd/system/jenkins.service を修正してサービス再起動で動作することが確認できた。
が、/usr/lib/systemd/system/jenkins.service を修正するのは御法度（らしい）。
なので元に戻して、

```# systemctl edit jenkins```
で下記のみを記入。
```
[Service]
Environment="JENKINS_PORT=8888"
Environment="JENKINS_PREFIX=/jenkins"
```
上記で /etc/systemd/system/ に jenkins.service.d/override.conf が作成され、/usr/lib/systemd/system/jenkins.service の設定値を上書きしてサービス起動してくれる。（いや、```systemctl restart jenkins```は必要）
ここらへん、/etc/sysconfig/jenkins さんを使ってもうちょいうまくできないものかな。
何か知らない手順があるのかも知れないが。
RBAC、組み込みロール、ロール定義、カスタムロール

●RBAC(Rool-based Access Control)
ロールベースのアクセス制御。
管理グループ、サブスクリプション、リソースグループ、絵リソースといった各スコープに対して「どのユーザーがどのリソースにアクセスできるか」「どのユーザーがどのリソースに対してどの様な操作を実行できるか」をアクセス制御する。

●組み込みロール
代表的な組み込みロール
・所有者　他のユーザーへアクセス付与権・全てのリソースへのフルコントロール権を持つ。
・共同作成者　全てのリソースへのフルコントロールのアクセス権をもつが、他のユーザーへのアクセス権の付与はできない。
・閲覧者　既存のリソースの表示だけができる
・ユーザーアクセス管理者　他のユーザーへのアクセス権の付与と全リソースの表示
・仮想マシン共同作成者　仮想マシンの作成や管理が可能

●ロール定義の構造
アクセス許可のコレクションであり、内容はJSON形式のファイルで定義されている。各ロール定義には名前、ID、説明が含まれる。

●カスタムロール
クミオミロールで組織のニーズを満たすことができない場合は、独自のカスタムロールを作成する。
・既存のロールを複製する方法
・最初から作成する方法
・JSONファイルをアップロードする方法
の３つがある
[python] Webスクレイピング 値取得の完全自動化 -BeautifulSoup-

# はじめに
前回に続き、Webスクレイピングの自動化について、まとめておく
今回は特に株価に注目してWebスクレイピングをした

https://qiita.com/junzai/items/47964a3b7026349191ce

# 環境
windows 10
python version: 3.7.8
Microsoft Edge
Yahoo Finance

# Code
```python
import requests
from bs4 import BeautifulSoup
```


## 情報の自動取得
```python
def Read_Stock_Price(stock_number: list) -> str:
    data = requests.get(f'https://finance.yahoo.co.jp/quote/{stock_number}.T')
    soup = BeautifulSoup(data.content, 'html.parser')

    # htmlより場所を指定
    price_now = soup.find_all('span', class_="_3rXWJKZF")[0].text
    stock_name =  soup.find_all('h1', class_="_6uDhA-ZV")[0].text

    stock = {'name':stock_name, 'price': price_now}
    return stock

stock_number_list = [2484, 7901, 7203, 6758, 9434, 9433]

f_w = open('price.csv', 'w', encoding='utf-8')
for stock_number in stock_number_list:
    f_w.write(f'{Read_Stock_Price(stock_number)["name"]},
                {Read_Stock_Price(stock_number)["price"]} \n')
f_w.close()
```

```:price.csv
(株)出前館, 518 
(株)マツモト, 5,650
トヨタ自動車(株), 2,014.5
ソニーグループ(株), 10,755
ソフトバンク(株), 1,470
ＫＤＤＩ(株), 4,435
```
指定した６つの株に関して自動で現在の株価を取得した


## 応用ー完全自動化
```python
def Read_Stock_Price(stock_number: list) -> str:
    data = requests.get(f'https://finance.yahoo.co.jp/quote/{stock_number}.T')
    if str(data.status_code) == '200':
        soup = BeautifulSoup(data.content, 'html.parser')

        price_now = soup.find_all('span', class_="_3rXWJKZF")[0].text
        stock_name = soup.find_all('h1', class_="_6uDhA-ZV")[0].text

        stock = {'name': stock_name, 'price': price_now}
        print(f'{stock_number} succeded')
        return stock
    else:
        print(f'{stock_number} failed')
        return None


stock_number_list = [ i for i in range(1000, 9999)]

f_w = open('price.csv', 'w', encoding='utf-8')
for stock_number in stock_number_list:
    if  Read_Stock_Price(stock_number) != None:
        f_w.write(
        f'{Read_Stock_Price(stock_number)["name"]}, 
          {Read_Stock_Price(stock_number)["price"]} \n')
f_w.close()
```
```terminal: terminal
6000 failed
6001 failed
6002 failed
6003 failed
6004 failed
6005 succeded
6005 succeded
6005 succeded
6006 failed
6007 failed
6008 failed
...
```
```:price.csv
三浦工業(株), 2,961 
(株)タクマ, 1,213 
(株)ジャパンエンジンコーポレーション, 1,208 
阪神内燃機工業(株), --- 
(株)赤阪鐵工所, 1,430 
ダイハツディーゼル(株), 563 
ＧＭＯ　ＴＥＣＨ(株), 1,670 
弁護士ドットコム(株), 2,949 
テクノプロ・ホールディングス(株), 3,785 
アトラグループ(株), 190 
(株)アドベンチャー, 11,320 
....
```
成功コードが得られたら、情報を保存するように指定した
１個の株価で約0.1秒ほどかかった
マルチスレッドを利用するともっと早くできると思う


# まとめ
株コードは1301から9997番まであるようなので、程よく真ん中の範囲の指定して値を取得したが、予め株コードの情報を取得してからの方が結果的に早く終わった可能性も考えられる


# 関連
https://www.crummy.com/software/BeautifulSoup/bs4/doc/
Kotlin 基礎 -- スコープ関数での処理ブロックの追加

## why

ブロック処理は Kotlin の基礎であり、必須だと気づいたから

---

## 参考

Kotlin サーバーサイドプログラミング実践開発

Page 100 of 495

https://www.amazon.co.jp/gp/product/B091PGXHJY/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

https://www.digitalocean.com/community/tutorials/kotlin-let-run-also-apply-with

---

# 5 つのスコープ関数

with
run
let
apply
also 

これらの 5 つのスコープ関数が有る。

これは関数やインスタンスに追加したり、引数として取ることで拡張できる。

---

## let

https://blog.mindorks.com/using-scoped-functions-in-kotlin-let-run-with-also-apply

一番シンプル。関数に追加すると、その関数の結果を it として扱えるブロックを作成できる。

```kotlin
	fun get1(): Int{
		return 1
	}
	val letTest = get1().let { it + 1 }
	println(letTest)

```

> 2

ここでは 1 を返す関数に let をつけたので
it が 1 として扱われ、1 + 1 で 2 が返ってくる。

前の記事に書いたように、?.let を使うことで null ではない場合のみ実行できる。これによって nullable な値もぬるぽの心配なく安全に扱える。

---

## run 

run では it ではなく this で元の関数の返り値が扱える。

```kotlin
	fun get1(): Int{
		return 1
	}
	get1().run { println(this+1)}
```

> 2

```kotlin
	fun get1OrNull(): Int?{
		return null
	}
	get1OrNull()?.run { println(this+1) }
```

こちらも Null 安全な実行ができる。

---

## with

```kotlin
	fun get1(): Int{
		return 1
	}
	val withTest = with(get1()) { this + 1 }
	println(withTest)
```

> 2

with は引数で関数の結果をレシーバーとして受け取る。
そして次のブロックで this として扱い処理し、返り値とする。

どうみても run の方が使いやすい。

---

## apply

```kotlin
	fun get1(): Int{
		return 1
	}
	val applyTest = get1().apply { this + 1 }
	println(applyTest)
```

> 1

apply はブロックの結果を返さない。
let や with とはそこが違う。

apply を当てた関数が返って来ている。

```kotlin
	data class Dog(var name: String)
	val pochi = Dog("Pochi")
	val applyTest = pochi.apply { this.name = "Hachi" }
	println(applyTest)
```

> Dog(name=Hachi)

name = Pochi として作成した Dog のインスタンスを
apply を使って this.name にアクセスして 
name = Hachi に変更することができた。

---

## also 

```kotlin
	data class Dog(var name: String, var age: Int)
	val pochi = Dog("D",3)
	val alsoTest = pochi.also { it.name = "E" } .also { it.age = 10 }
	println(alsoTest)
```

> Dog(name=E, age=10)


also も apply と同じく本体を返す。
apply と違っていくつでもつなげていくことができる。
広告が実機で表示されない場合の対処法【Unity/AdMob】

# 問題
AdMobのインターステイシャル広告がエディタ上では表示されているが、実機テストでは表示されない

# 環境
・Unity 2021.3.12
・Google AdMob
・テスト用端末: Google Pixel 5a

# 対処法
恐らく上手く広告をロードしてから表示する流れが上手く行っていない。
下記コードのように広告がロードされた際に表示するようにすれば解決した。
```c#
private void RequestInterstitial(){
    ...
    string adUnitId = "ca-app-pub-***********************";
    ...
    interstitial = new InterstitialAd(adUnitId);
    AdRequest request = new AdRequest.Builder().Build();
    //広告表示処理がロード完了後実行されるようにする
    interstitial.OnAdLoaded += (sender, e) => {((InterstitialAd) sender).Show();};
    //広告を読み込み
    interstitial.LoadAd(request);
}
```
# 参考
[【Unity】Unityの画面では表示される広告が実機テストでは出ないときの対処法｜マカロン【ゲーム開発】｜note ](https://note.com/08_14/n/nf68b3985784e)
pg_adminでAmazon RDS for PostgreSQLインスタンスを作成する方法が爆誕していた

## 前提
- AWS CLIのセッティングが完了していること
    - その辺は他のネット記事にゆずります
- pg_admin4.6.15のインストールが完了していること

## 手順
File→Register→Deploy Cloud Instanceを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/aee228c8-8ed6-36fe-cc54-8e7cb6a05538.png)
Amazon RDSを選択してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/b1766ef4-5912-2fde-36db-aa8e63232fa7.png)
Regionやアクセスキー、シークレットアクセスキーを選択してNext
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/b96fab67-46cc-c2fe-6c3e-fb320553f6b3.png)
インスタンス名やPostgreSQLのバージョン、インスタンスクラスやインスタンスタイプをお好きにどうぞ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/9cb8a5c3-8b02-294a-3042-c71f56443a67.png)
ReviewしてFinish
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/f01a9708-2533-1400-e4a4-9334b6ab5d15.png)
作成中はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/874418da-3f15-2d80-6b4d-fc4bbe5153eb.png)
できた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/54678457-653b-5ce2-3402-234fa32dc888.png)
できてる！（マネジメントコンソールの画面）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/6fb84d45-ae6a-e466-8439-e4a10683bbef.png)

Aurora PostgreSQLもお願いしたい。。

## 補足
このままだとAWS上のEC2から接続できないので、接続したい場合はインスタンス画面から、接続するように設定する。Connected compute resourcesから設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367069/adbdbffa-88b7-4879-c957-dba20e52d342.png)



## 参考
https://www.enterprisedb.com/blog/aws-rds-postgresql-deployment-pgadmin-4
ラストのまほう　第14話『デバッガーを整備する』

プログラミングを学ぶ人は、まずデバッガーの使い方を覚えるのがいいと思います。デバッガーで一行づつ実行しながら変数の中身を確認していけばプログラムの動きがイメージしやすいからです。printfデバッグはだいたいどの環境でもできるのでその意味では楽なのですが、ソースレベルでバッグができるに越したことはありません。そういえばGLSLとかprintfデバッグすら無理なので一番つらかった……。

# wasm::trace関数を使う

WASM-4でデバッグプリントを行うには、`trace`関数を呼び出します。Rustの場合は`format!`マクロと組み合わせて

```rust
trace(format!("x: {}, y: {}", player.position.x, player.position.y));
```

みたいな感じにするといいようです。(C/C++のみ、フォーマットと出力を同時に行う`tracef`関数が使えます)

ちなみに、Rust標準の出力関数である`println`とかを呼ぼうとしたら、`note: rust-lld: error: initial memory too small, 66848 bytes needed`とか言われてビルドに失敗しました。よくわかりませんが、まあ`println`は使えないみたいです。

# C/C++ DevTools Support (Rustをサポートしないとは言っていない)

それで開発を始めた当初は`trace`ですべてをしのいでいたのですが、さすがにソースレベルでバッグができないと辛くなってきました。WASM-4ではRustをWASMにコンパイルしてブラウザで読み込みますが、ChromeのDevtoolsを開いて適当に実行を中断すると、普通に生WASMが表示されます。もちろん私はWASMなんて読めるわけがありません。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">生WASM見せられても読めるわけないだろ！<br>いいかげんにしろ！<br>頼れるのはデバッグプリントだけニャンね……（とか言いながら半年後くらいにはなんとなく読めるようになっていそう） <a href="https://t.co/z85O8G4vm9">pic.twitter.com/z85O8G4vm9</a></p>&mdash; Cubbit (@cubbit2) <a href="https://twitter.com/cubbit2/status/1586018072913399808?ref_src=twsrc%5Etfw">October 28, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

というようなことをツイートしていたら、 YutakaAoki3 さんにソースレベルデバッグできるよと記事を教えてもらいました。

https://developer.chrome.com/blog/wasm-debugging-2020/

なんかこの記事見覚えあるなと思ったら、"in particular, for C and C++ apps." とあって **いやC/C++って書いてあるし、これ探してるのと違うやつかな……** と思って冒頭だけ読んでスルーしたような記憶があります。半信半疑ですが、記事にしたがって [C/C++ DevTools Support (DWARF)](https://chrome.google.com/webstore/detail/cc%20%20-devtools-support-dwa/pdcpmagijalfljmkmjngeonclgbbannb) というのをインストールしてみます。

![debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64695/959af5ec-f5f4-f2c8-46d5-d2db5dfae12f.png)

**み゛ょ゛っ゛……！？（衝撃）**　Chromeに拡張をインストールしただけなのに、RustのソースコードがDevtoolsに表示されてソースコードレベルでバッグができています。変数の中身も普通に覗けました。こんなに簡単にできるようになるなんてありがたや。これで寿命が10年は伸びましたね。というわけで、C/C++ DevTools Support (DWARF)という拡張をインストールしようね、というだけの回でした。

# 次回予告

次回からは少しプラットフォーマーっぽいプログラミングをしていきます。

https://qiita.com/hiruberuto/items/65cd3dce0b4d967af8b0
Javaで何か作ってみる(2022/11/04 Day15)

## 今日やった事
- MacデフォルトのGitではなく、HomebrewのGitを使用するように変更した。
- [**Other**](https://github.com/takamatsuryota3/Other)というリポジトリを作成し、そこに既存リポジトリ**LearningRecord**を統合した。
## 参考にしたもの
- [MacにHomebrewからgitをインストールする方法 | Hirooooo’s Labo](https://hirooooo-lab.com/development/install-git-by-homebrew/#index_id2)
- [Gitのバージョンをhomebrewで管理（Mac環境）](https://qiita.com/bakepotate/items/dc457a0046413ce1f965#git%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%A8%E3%83%91%E3%82%B9%E3%82%92%E7%A2%BA%E8%AA%8D)
- [MacのGitのバージョンをアップデート！Homebrewでの管理に切り替える | サイト構築日記](http://memories.zal.jp/WP/blog/20150215_2494.html)
- [macOSのgitをXcode Command Line Tools版からHomebrew版に乗り換えてみた - Qiita](https://qiita.com/306_san/items/3cab1882e3035c646a65)
- [【MacOS】Homebrew経由でGitをインストールする方法 - 独学プログラマ](https://blog.cloud-acct.com/posts/u-homebrew-git-install/)
- [gitリポジトリの統合 - Qiita](https://qiita.com/CORNER/items/2e608f1091f305794f0a)
- [【Git】2つのGitリポジトリを履歴を保持して統合したい - Qiita](https://qiita.com/no_kawai/items/5efe8e47e54ebccd0bf8)
- [Git 別のリポジトリを履歴を残したまま取り込みたい - かもメモ](https://chaika.hatenablog.com/entry/2015/06/04/173401)
- [複数のGitリポジトリを一つにまとめる - Qiita](https://qiita.com/hellscare/items/bad5021964f529d6f690)
## 所感
- HomebrewのGitを使用する為の設定に時間がかかった。  
&rarr;HomebrewのGitを使用する為に、**bash_profile**にパスの設定する必要があるのだが、最初に参考にしたサイトに、 
```
# HomebrewのGitを使うパス
export PATH=/usr/local/bin/git:$PATH
```
と書かれており、その通りに記載しても反映されず、ターミナルを再起動したり、Mac自体を再起動したりしても反映されず、  
他のサイトで書かれていた、以下の内容で設定したところ、
```
export PATH=/usr/local/bin:$PATH
```
HomebrewのGitを使用するようになった。どうやら、gitをパスとして指定していたのがまずかったみたい。
- GitHubの整理に向けて、既存リポジトリを統合する方法が出来るようになったので良かった。

## 明日の予定
- 明日でGitHubの整理を終わらせたい。
- Javaの勉強も再開したい。
【GAS】HTMLとコードとスプレッドシート間の値渡し

# はじめに
こんにちは。[rendaman0215](https://twitter.com/rendaman0215)です。

GAS、便利ですよね。
さくっとhtmlとバックエンドのコード書いて、デプロイすると秒でWebサイトが作れます。
そんなGASで開発している中で、
`HTML` と `GAS` と `スプレッドシート` の間で値を渡し合う方法をまとめました。

# HTML -> GAS
シンプルにGAS側で定義した関数をhtml側のjavascriptで呼びだしてあげると値を簡単に渡せます。

## コード
```javascript
async function sampleFunc(name) {
  await google.script.run
   .withSuccessHandler(function(name){
      // 成功した時の処理
    })
    .{GAS上の関数名}(name);
}
```

# GAS -> HTML
GASからhtmlに値を渡すには、GAS上の`doGet()`関数にて、テンプレートに値を定義しておくことで、テンプレートを評価する際に値が埋め込まれます。
```javascript
function doGet() {
  var t = HtmlService.createTemplateFromFile('index.html');
  t.message="Hello";
  return t.evaluate();
}
```
```html
<body>
  <h1><?=message ?></h1>
</body>
```

## クエリパラメータを使う
GASを用いて開発していても、動的に内容を変更したいことがあります。そんな時はクエリパラメータを使いたいですね。
GASでクエリパラメータを使いたい時、注意しなければならないのはhtml側のjavascriptでクエリパラメータの取得処理を入れても使えないということです。
GASではhtmlは、GASが用意した箱にiframe上で埋め込まれているだけです。
よって大元のGAS側でクエリパラメータを取得する必要があるため、以下の方法で値を渡していきます。

1. `doGet()`関数内で`let param = url.searchParams`などでパラメータを取得する
2. t.param = param　などでパラメータをhtmlに渡す
3. html側のhtmlやJSに`<?=param ?>`と記載することで、渡されたあたいを使用する。

# スプレッドシート -> GAS
## コード
GAS上で以下のようなコードを記載することで可能です。
```javascript
async function getUser(name, age) {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = ss.getActiveSheet()
  await val = sheet.getRange(行,縦列).getDisplayValue();
}
```
## 解説
`SpreadsheetApp.getActiveSpreadsheet()`関数はその名の通り、GASに紐づくスプレッドシートを指定します。
また、`getActiveSheet()`関数では、アクティブなシートを指定します。
最後に`getDisplayValue()`関数で値を取得することができます。


# GAS -> スプレッドシート
## コード
GAS上で以下のようなコードを記載することで可能です。
```javascript
async function setUser(name, age) {
  const ss = SpreadsheetApp.getActiveSpreadsheet()
  const sheet = ss.getActiveSheet()
  await sheet.appendRow([name, age])
}
```
## 解説
`SpreadsheetApp.getActiveSpreadsheet()`関数はその名の通り、GASに紐づくスプレッドシートを指定します。
また、`getActiveSheet()`関数では、アクティブなシートを指定します。
最後に`appendRow()`関数で値を追加することができます。


# HTML -> スプレッドシート
残念ながらHTMLからスプレッドシートを直接更新する方法は今のところありません。
上記の方法を組み合わせてGASを挟むことで実現可能です。
（情報持っている方いらしたら提供いただけると:bow:）

# スプレッドシート -> HTML
残念ながらスプレッドシートからHTMLに直接値を渡す方法は今のところありません。
上記の方法を組み合わせてGASを挟むことで実現可能です。
（情報持っている方いらしたら提供いただけると:bow:）
【QGIS】地理院地図とシェープファイルを表示する

## はじめに
この記事は#30DayMapChallenge2022 4日目の記事です。
テーマはColour Friday: Greenです。
QGISを使って森林地域データのシェープファイルを地図上に表示してみます。

![image](https://raw.githubusercontent.com/tjukanovt/30DayMapChallenge/main/images/flyers/30dmc-2022.png)

https://30daymapchallenge.com/

## QGISとは
フリーでオープンソースの地理情報システム
ほとんどのUnixプラットフォーム、Windows、macOS上で動作する

## シェープファイルとは
Esriが提唱したGISデータフォーマット
地物の位置や形状、属性情報を持つベクターデータを格納できる
複数のファイルから構成されており、必須のファイルはshp, shx, dbfの3つ

## 地図表示
既にインストール済みのQGIS（バージョン3.22.3）を使います。
QGISを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/13c801a9-4ba2-7996-cb45-16f32c999cd1.png)

今回は背景地図として、地理院地図を表示してみましょう。
左側の「ブラウザ」パネルから、XYZ Tilesを右クリックして、「新規接続」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/2ec4c1db-41a3-4643-a76e-6c450fa1e955.png)

「XYZ接続」画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/91bc9d06-7c9c-5155-b591-b9abd3eb3d4c.png)

名前にはレイヤ名を入力します。今回は「地理院地図（淡色）」 と入力しました。
URLは、[地理院地図のサイト](https://maps.gsi.go.jp/development/ichiran.html)から好きなベースマップを選びます。
今回は淡色地図を使うので、「https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png」 を入力しました。

入力できたら「OK」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/b0fa1a9c-288d-62f3-e8c1-108e375f74fd.png)

左側の「ブラウザ」パネルから、XYZ Tilesの左の▶をクリックすると、先ほど追加した地理院地図のレイヤが表示されます。
レイヤ名をダブルクリックすると地図が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/cfe7b22a-b8c6-d1e8-ce1e-d543fe38fcda.png)


## シェープファイル表示
国土数値情報から岐阜県の森林地域データをダウンロードします。
https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-A13.html

zipファイルを解凍します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/868109d1-82bf-c8dd-59f8-d96423bf417d.png)

shpファイルを選択して、QGIS上にドラッグ&ドロップします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/06ba4589-3909-6ee0-4421-232ac6b35416.png)

シェープファイルを表示できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/1802961f-09e1-fc53-b333-34a7d11ea31f.png)

## スタイル変更
森林っぽくみせたいので色を変えてみます。

レイヤを右クリックして「スタイル」＞「シンボルを編集」 をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/3ea9050e-53b1-0fe0-264e-7df529eba5ef.png)

色を好みの色に変更して、「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/a9af1a0c-689d-9093-6468-fd8f66ed68aa.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/b4e6a56a-45aa-76e1-c140-1732694e3d22.png)

緑色で森林を表示できました(^o^)丿


塗りつぶしの設定も変えられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/93024d9d-892c-fbca-88b4-8608870262d6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/775db666-dd6c-43f7-3d16-df64d32cb889.png)

Green！！

## 参考文献
https://docs.qgis.org/3.22/ja/docs/user_manual/

https://www.esrij.com/gis-guide/esri-dataformat/shapefile/

https://nlftp.mlit.go.jp/ksj/other/QGIS_manual.pdf
Railsでバージョン指定してのプロジェクト作成に失敗した時の対処法

# 課題

Rails 6.1.4.4でプロジェクト作成しようと

```
rails _6.1.4.4_ new project_name
```

を走らせるが以下のようなエラーが出力される。

```
`find_spec_for_exe': can't find gem bundler (>= 6.1.4.4) with executable bundle (Gem::GemNotFoundException)
```

# 仮説

以前はこれでプロジェクトを作成できていたのですが、以前沼に嵌った時にRailsのバージョンを消去した記憶がうっすらあったのでその時に6.1.4.4を削除していたかもしれない。

# 解決方法

- Rails 6.1.4.4を再度インストール

```
gem i -v 6.1.4.4 rails
```

で解決しました。

以下の記事が参考になりました。

https://qiita.com/tanakayo/items/7b85261924eca1a5a3d6

# 結論

必要なバージョンがインストールされていなかっただけでした。

なかなか同じ状況に陥る人はいないかもしれませんが、同様のエラーが出た場合に参考になれば幸いです。
簡単Elixirシリーズ  ~ Elixir プログラム実行の色々な方法 ~

# 簡単Elixirシリーズ 
## ~ Elixirプログラム実行の色々な方法 ~

この記事は「[Elixir Advent Calendar 2022](https://qiita.com/advent-calendar/2022/elixir)」1日目の記事です
東京にいるけどFukuokaexのYOSUKEです。

簡単 Elixirシリーズでは小ネタをサクッと書いていこう。というコンセプトで作っていきます。

今回は、elixirのプログラムの実行をする色々な方法を知る。という小ネタ（そう、この記事はサクッとがコンセプトW）

## mix を使った場合
まずは、mix プロジェクトで作成をして行きましょう。

```bash
mix new hello
cd hello
```

hello.exのファイルの中身を以下のように書いています。

```lib/hello.ex
defmodule Hello do

    def call(name) do
        "Hello #{name}"
    end

end

IO.puts Hello.call("YOSUKE!")
```

コンソールから実行
```bash
elixir lib/hello.ex
Hello YOSUKE!
```

iexから実行
```elixir
iex> c "lib/hello.ex"
Hello YOSUKE!
[Hello]
```

iexを起動と同時に実行する
```bash
iex  lib/hello.ex
Hello YOSUKE!
Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
```

mix コマンドを利用して実行する
```bash
iex -S mix
Compiling 1 file (.ex)
Hello YOSUKE!
```

iexを起動後に rコマンドとモジュール名で実行（ちなみに、こちらはモジュールを書き換えた際にiexを再起動せずに反映させたい時にも便利です。
```elixir
iex> r Hello
Hello YOSUKE!
{:reloaded, [Hello]}
```

PS. mix プロジェクトで作成した場合には、```r``` コマンドではなく、```recompile```で再反映させる事もできます。

```elixir
iex> recompile
Compiling 1 file (.ex)
Hello YOSUKE!
:ok
```

## mix を使わない場合

基本的にはmixで利用できるものと同じも多いので、ここでは、　mix を使わずに実行する際に、mixを使った場合との差分のみ紹介します。

### 使えないもの
こちらは使えないです。
```elixir
iex -S mix
```
こちらも使えないです。
```elixir
iex> recompile
Mix is not running. Please start IEx with: iex -S mix
:error
```
### ひと工夫が必要なもの
そして、こちらも実はこのままでは使えません。一工夫が必要です。
```elixir
iex> r Hello
```

r コマンドを利用できるようにするには、一旦、lib/hello.ex をコンパイルしておく必要があります。

```elixir
elixirc lib/hello.ex
```
こちらを実行し、 ```Elixir.Hello.beam``` ファイルが存在するルート上でのみ利用できるようになります。
```elixir
iex> r Hello

Hello YOSUKE!
{:reloaded, [Hello]}
```

ということで、コンパイルが必要なexファイルの様々な実行方法でした。
【初心者向け】過去1年間の学習に使用した4つメモアプリ・ツールについてまとめました

# はじめに
著者は実務未経験者になります。
直近の1年間でAWS認定資格(CLF/SAA/DVA)を取得していますが、
勉強のために使用したメモアプリやツールなどを紹介させていただきます。

いろいろなメモアプリを試しては、別のアプリに変えるといったことを繰り返して、
時間を無駄にしていたので、懺悔も込めて記事にしました。

# 記事の対象者
- プログラミング学習を始めたばかりの初心者
- アウトプット用のメモアプリを検討中のエンジニア

# ツール紹介
## Notion
**タスク管理やメモなど大体のことはできるメモアプリ**

https://www.notion.so/ja-jp/product?utm_source=google&utm_campaign=14877655427&utm_medium=125922091617&utm_content=552465064290&utm_term=notion&targetid=aud-840164194020:kwd-312974742

- 筆者も現在はこちらのアプリを使用中
- ブラウザ版・PC版・モバイルアプリ版あり
- マークダウン形式やPDF形式でエクスポート可能
- データベース形式でまとめることが可能
![スクリーンショット 2022-11-04 22.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287339/bd321f73-05e7-cb6b-9c94-219c0963ba87.png)

## Github
**説明不明のエンジニアプラットフォーム**

https://github.co.jp/

- 下記の記事を参考にして「TIL」としてメモアプリとして運用
[Githubのリポジトリ「TIL」を使って小さなアウトプットを習慣化する](https://qiita.com/nemui_/items/239335b4ed0c3c797add)
- 学習履歴が「草」として表示されるのはモチベーションにつながる
![スクリーンショット 2022-11-04 22.18.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287339/c1444d23-3113-9e0e-9ba7-e82bd64ef0f4.png)
- リポジトリの公開範囲を設定でる。（privateやpublic）
- Issuesでスレッド形式のメモにできる
![スクリーンショット 2022-11-04 22.24.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287339/d68e2308-2719-7991-f276-e932a81a2959.png)

## Qiita
https://qiita.com/

- エンジニアに関する知識を記録・共有するための投稿サービス
- 利用者は多いので、公開設定の記事へレスポンスは個人的にかなり早い

## Zenn
**エンジニア情報共有サービス**

https://zenn.dev/

- Qiitaと類似したサービス
- スクラップ機能がQiitaとの最大の差異。GithubのIssuesと同じようにスレッド形式のメモ
- スクラップは基本的に非公開設定できないので注意
![スクリーンショット 2022-11-04 22.29.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287339/8cc52fdf-31a1-ed54-c01b-d14993d8c5b0.png)

# 終わりに：1年前の自分にアドバイスするなら
「はじめに」でも述べましたが、基本的にメモアプリの運用については後悔や反省が多いです。
用途や目的を明確にせず、なんとなく「使いやすそうでいいな〜」というノリで決めていました。その結果、かなりの時間やメモを無駄にしました。

もしも、1年前の自分にアドバイスするなら？
**メモの内容を公開するかどうかで判断する**

完全に個人用なら気軽に使えるNotionを、
転職PRなどで利用する予定ある場合はGithub・Qiita・Zennをおすすめします。
エラーメッセージについて

## 初めに
エラーメッセージの実装の仕方について簡単に記録のために書いておこうと思います。

## viewに記述

 ```app/views/users/_errors.html.erb
<% if @user.errors.any? %>
  <%= @user.errors.count %>件のエラーが発生しました
<ul>
<% @user.errors.full_messages.each do |message| %>
  <li><%= message %></li>
<% end %>
</ul>
<% end %>
```

今回はuesrのeditに部分テンプレートで表示させたいのでこのように記述します。
<%= @user.errors.count %>件のエラーが発生しましたの部分で例えば3件記述の忘れがあれば３件のエラーが発生しましたとviewに表示されるようになります。

## 実際にeditに記述
```app/views/users/edit.html.erb
  <h2>ユーザー情報編集</h2>
    <%= render 'users/errors', user: @user %>
 〜省略〜
```
今回であればuserのeditにエラーメッセージを表示させたいので自分で表示させたい所に部分テンプレートで入れてあげます。
他のページも同様でそのページに沿った記述に変えてあげれば実装できると思います。
実装自体は思ったよりも簡単ではありますが記録として残しておきます。
【備忘録】PyCharm＆Anacondaでインタープリタ設定時「SDKが無効」と怒られた理由が文字コードだけだった話

久しぶりにPyCharm起動。
アップデート。

Anacondaも初めて入れてみて。

# インタープリタの追加時、怒られました
AnacondaのPython3.9を選択。
「Python3.9でPythonSDKをセットアップできません。SDKが無効になっているようです」

# 【無意味】再インストール＆環境設定
Anaconda、PyCharmともに再インストールしてもダメ。

『[PythonとPycharmの環境設定](https://qiita.com/kolife/items/29fcd4bacd237b48b8bf)』
ここを参考にAnaconda非推奨でも環境パスを通してもダメ。

無意味でした。
「Python3.9でPythonSDKをセットアップできません。SDKが無効になっているようです」

# ログ確認
> C:\...\JetBrains\PyCharmCE2022.2\log

配下のPyCharmのidea.logを見ました。

```
WARN - #c.j.p.s.PySdkUtil - Charset windows-31j is not UTF-8, which is likely lead to troubles
INFO - #c.j.p.p.PyPackageManagerImpl - Exit code 1
INFO - #c.j.p.p.PyPackageManagerImpl - Fatal Python error: init_stdio_encoding: failed to get the Python codec name of the stdio encoding
Python runtime state: core initialized
LookupError: unknown encoding: windows-31j
```
# ログ要約
- windows-31j は日本語環境でよく使われる文字エンコーディングでUTF-8ではないことを警告【WARN】
- Exit code 1 は一般的に、何らかのエラーが発生してプログラムが異常終了したという情報【INFO】
- 標準入出力 (stdio) のエンコーディングの Python コーデック名を取得できなかったという情報【INFO】
-  Python の基本的な機能は起動していたけど、初期化して戻した

:::note info
結局
*windows-31j が Python によって認識されなかった*
:::

# 検索
『[PyCharmで Fatal Python error: Py_Initialize: can't initialize sys standard streams LookupError: unknown encoding: windows-31j が発生する場合の対処](https://qiita.com/icoxfog417/items/cf3495115cba49365430)』
解決に繋がる記事でした。

# 修正
> C:\Program Files\JetBrains\PyCharm Community Edition 2022.2.3\bin

配下のidea.exe.vmoptions
に以下を追記しました。
> -Dfile.encoding=UTF-8

# 和解
怒られなくなりました

途中の環境パスはそのままにしちゃってます……
関係あるかどうかは不明。
WSLからWindowsのローカルサーバへHTTPリクエストする

## はじめに
Springの勉強中です。
APIを作成し動作確認をしたときに少し詰まりました。
その解決方法となります。

EclipseでWebアプリケーションを作成し、ローカルに実行すると、http://localhost:8080/でアクセス出来るかと思います。

同様に、API動作確認をWSL上のUbuntuからcurlコマンドで行いました。

```Bash
$ curl -X GET http://localhost:8080/hoge
Failed to connect to localhost port 8080: 接続を拒否されました
```
とエラーを吐かれました。
答えは簡単で、WSLとWindowsはIPアドレスが異なるため、接続できるわけないよね。という結論です。

```Bash
//コマンドプロンプト
> ipconfig
//実行結果のIPv4アドレスを次で使う

//WSL(Ubuntu)
$ curl -X GET 192.168.10.111:8080/hoge
```

これで動作確認できるはずです。
[Ruby] 二次元配列の降順ソート

# 環境

Ruby3.1.2

# やりたいこと

二次元配列（中身は降順に値が入っている配列）を降順ソートしたい。

## コード

```ruby
record_array = [
  [100,50,75,50,50].shuffle,
  [100,95,50,50,50].shuffle,
  [99,95,95,95,95].shuffle,
  [101,1,1,1,1].shuffle,
  [80,75,75,60,60].shuffle,
  [80,75,75,75,75].shuffle,
  [75,75,75,75,75].shuffle]

# 降順に並べる
record_array = record_array.map do |row|
  row.sort.reverse
end

p record_array.sort.reverse

#=>
[[101, 1, 1, 1, 1], [100, 95, 50, 50, 50], [100, 75, 50, 50, 50], [99, 95, 95, 95, 95], [80, 75, 75, 75, 75], [80, 75, 75, 60, 60], [75, 75, 75, 75, 75]]
```

## 具体的な要件

1\.

[100,100]
と
[101,0]
では
[101,0]を優先度高くソートしたい。

2\.

[100,75]
と
[100,95]
では
[100,95]を優先度高くソートしたい。

3\.
1\.と2\.の組み合わせから

```ruby
[
    [100,50,75,50,50],
    [80,75,75,75,0],
    [100,95,50,50,50],
    [99,95,95,95,95],
    [75,75,75,75,75],
    [101,1,1,1,1],
    [80,75,75,60,60]
]
```
が
```ruby
[
    [101, 1, 1, 1, 1], 
    [100, 95, 50, 50, 50], 
    [100, 75, 50, 50, 50], 
    [99, 95, 95, 95, 95], 
    [80, 75, 75, 75, 0], 
    [80, 75, 75, 60, 60], 
    [75, 75, 75, 75, 75]]
]
```
この順にソートされること。

## 実装内容

配列のインデックス順にソートが必要があるのでは？と思っていましたが、``<=>``演算子による配列の比較が
```ruby
[100,100] <=> [101,0]
#=> -1
[100,50] <=> [100,75]
#=> -1
```
であり、
[リファレンスのEnumerable#sort](URL "https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/sort.html")に

> ブロックなしのときは <=> メソッドを要素に対して呼び、その結果をもとにソートします。

と記述があるので前処理に比較する配列の中身を降順ソートしておけばいいだけでした（後はreverseメソッドをかけるぐらい）

## 注意事項

ただし、
```ruby
[100] <=> [100,-1]
#=>
-1
```

## 参考

https://qiita.com/takanatsu/items/39cf827aadc7d06bf48c

https://qiita.com/koshilife/items/7be60854b7dde2d48807
mapboxのIControlに引数を渡す

mapbox で地図を見ている時に、基準となる長さを表示しておきたかったのですが、調べた限りではそういったコントロールはありませんでした。
Mapboxでは[自分でカスタムコントロールが作れる](https://docs.mapbox.com/mapbox-gl-js/api/markers/)ようなので、簡易的な距離表示コントロールを作ってみました。

GoogleMapsの距離表示は動的に長さや基準が変わりますが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/3156a46d-909d-d6e5-3a58-09133cddc1c4.png)
今回は手を抜いて
* コントロールは右下に常に同じサイズで表示
* ズーム変更でコントロールの長さに応じた距離を表示
という仕様にしました。

コントロールの引数として長さや距離の単位を渡すには、コンストラクタに当たる部分で
```function DistanceGaugeControl(_options) { this._options=_options; } // _options={ width:200, units:'kilometers' }```
のようにすれば良いようです。

まずはコントロールを下記のように定義し、
```
function DistanceGaugeControl(_options) { this._options=_options; }

DistanceGaugeControl.prototype.onAdd = function(_map) {
    this._map = _map;
    this._width = (this._options?.width??200);
    this._units = (this._options?.units??'kilometers');
    this._gaugeArea = document.createElement('button');
    this._gaugeArea.style="position: relative; width: "+this._width+"px; background: #eee; font-size: 12px;";
    this._gaugeArea.innerText = '?km';
    this._container = document.createElement('div');
    this._container.className = 'mapboxgl-ctrl';
    this._container.appendChild(this._gaugeArea);
    //this._map.addEventListener('mousemove', ()=>{ this._gaugeButton.innerText="moved"; });

    this._map.on('zoom', (e) => { this.calcDist(); });
    this.calcDist();
    return this._container;
};

DistanceGaugeControl.prototype.onRemove = function () {
    this._container.parentNode.removeChild(this._container);
    this._map = undefined;
};

DistanceGaugeControl.prototype.calcDist = function(){
    const coordinate0 = new mapboxgl.Point(0, 0);
    const coordinate1 = new mapboxgl.Point(this._width, 0);
    const lngLat0 = map.unproject(coordinate0);
    const lngLat1 = map.unproject(coordinate1);
    //const distkm = turf.distance(turf.point([lngLat0.lng,lngLat0.lat]), turf.point([lngLat1.lng,lngLat1.lat]), {units: this._units});
    const distkm = lngLat0.distanceTo(lngLat1)*0.001;
    this._gaugeArea.innerText= distkm.toFixed(1)+((this._units=='kilometers')?"km":"ml");
}
```

定義したコントロールを

```
var kmControl = map.addControl(new DistanceGaugeControl({ width:200, units:'kilometers' }),'bottom-right'); // miles or kilometers
```
のようにmap.addControlに渡せば表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/a6edbbd3-4559-19b8-6874-9a8baa44dba8.png)
```'bottom-right'``` を ```'bottom-left'``` にすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/e31fd401-2fef-3393-831d-43e6608181bd.png)
ちゃんとmapboxのロゴを避けて左下に表示されます。賢い！
【Next.js 13】Yarn PnPとApp Dirを有効にするとビルドが失敗する問題とその対処法

## はじめに

これは執筆時点でのNext.js v13.0.1で生じる問題です。今後のアップデートで修正される可能性があります。

## 状況

Yarn PnPを使用してパッケージを管理していて、なおかつ`appDir`をtrueにするとビルド時にエラーとなりビルドに失敗してしまいます。

```console
$ yarn build
warn  - You have enabled experimental feature (appDir) in next.config.js.
warn  - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
info  - Thank you for testing `appDir` please leave your feedback at https://nextjs.link/app-feedback

warn  - `enableUndici` option is unnecessary in Node.js v18.0.0 or greater.

> Build error occurred
Error: EROFS: read-only filesystem, open '/node_modules/next/dist/server/initialize-require-hook.js'
    at makeError$1 (/Users/shun_shobon/tmp/my-app/.pnp.cjs:958:24)
    at EROFS (/Users/shun_shobon/tmp/my-app/.pnp.cjs:985:10)
    at ZipFS.prepareWriteFile (/Users/shun_shobon/tmp/my-app/.pnp.cjs:2820:13)
    at ZipFS.writeFilePromise (/Users/shun_shobon/tmp/my-app/.pnp.cjs:2791:55)
    at /Users/shun_shobon/tmp/my-app/.pnp.cjs:3912:26
    at /Users/shun_shobon/tmp/my-app/.pnp.cjs:4136:81
    at ZipOpenFS.getZipPromise (/Users/shun_shobon/tmp/my-app/.pnp.cjs:4243:22)
    at ZipOpenFS.makeCallPromise (/Users/shun_shobon/tmp/my-app/.pnp.cjs:4136:23)
    at ZipOpenFS.writeFilePromise (/Users/shun_shobon/tmp/my-app/.pnp.cjs:3909:23)
    at VirtualFS.writeFilePromise (/Users/shun_shobon/tmp/my-app/.pnp.cjs:3219:24) {
  code: 'EROFS'
}
```

このエラーは`next dev`を実行した場合には起こらないため、気づきにくいです。
どうやら[ビルド中にライブラリのコードを書き換えようとするため](https://github.com/vercel/next.js/blob/ef73798e4557a8f203f814afe0908e041b2792b2/packages/next/build/index.ts#L317-L324)に生じるエラーのようです。この問題に関しては[Issue](https://github.com/vercel/next.js/issues/42427)を通して報告済みですが、執筆現在は特に返信はありません。

## 対処法

`yarn unplug`コマンドを使用してnextをunplugします。

```
yarn unplug next
```

コマンド実行後は`next build`でのビルドに成功するはずです。