OmniAICreator/Qiita-1.07M huggingface dataset:
PowerApps 委任問題を回避するFilter関数の使用例



##前置き
PowerAppsでFilter/LookUp/Searchなどの関数を何気なく使用していると委任の警告が出ることがよくあります。データソースの規模が小さいうちは問題ありませんが、2000行を超えると問題になるので委任の警告が出ない（委任可能な）Filter関数の使用例を紹介します。

:::note info
前提としてデータソースはSharePointListを使用することを想定します。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/72014b05-105c-0702-8690-3895ab644c27.png)


##委任について

委任って何？という方は下記サイト様で分かりやすく説明されています。

https://ippu-biz.com/development/powerplatform/powerapps/delgate001/


##本記事で使用するSharePointList
本記事では都道府県/氏名/性別/年齢/職業の5つの列を持つSharePointList（リスト名：`SampleList`）を例に説明します。必要に応じて読み替えて利用ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/d5ca86c5-fdcf-425e-f04a-f8501a36335f.png)

##事例①：特定の1列を対象に完全一致フィルタをかける
テキストボックス(`TextInput1`)に任意の文字列を入力させ、完全一致する氏名をもつ行だけを絞り込みます。最も基本的な形です。

    Filter(SampleList,氏名=TextInput1.Text)
↓氏名が`山田`の人だけが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/ad7260a9-cdb2-6ed0-324a-c0fa3c09efff.png)


##事例②：特定の1列を対象に前方一致フィルタをかける
完全一致では実用上使いづらいので、前方一致で絞り込めるようにします。

    Filter(SampleList,StartsWith(氏名,TextInput1.Text))
↓氏名が`山`から始まる人（山田、山本、山岸）が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/d855b31a-8449-415c-eaee-695c3f857980.png)


##事例③：特定の1列を対象に部分一致フィルタをかける
:::note warn
部分一致はSearch関数を使用する必要がありますが、2021/10/1時点でSharePointListでのSearch関数は委任をサポートしていないので、委任の警告を回避することはできません。
※もし回避方法をご存じの方がいればコメントいただけると幸いです。
:::
##事例④：複数列を対象に前方一致フィルタをかける
事例①②では氏名でしか絞り込めませんでしたが、他の列でも絞り込めるようにします。

    Filter(SampleList,StartsWith(氏名,TextInput1.Text)||StartsWith(都道府県,TextInput1.Text)||
                      StartsWith(性別,TextInput1.Text)||StartsWith(職業,TextInput1.Text))
↓都道府県で絞り込んだり、職業で絞り込んだりできる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/78564d04-aa26-227d-67d3-9e570eeb967d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/7a729b6c-a4fe-eee5-04ff-520502eefd92.png)

##事例⑤：複数列のAND条件で前方一致フィルタをかける
2つのテキストボックス(`TextInput1`,`TextInput2`)を使って、複数列（ここでは氏名と都道府県）のAnd条件で絞り込みます。

    Filter(SampleList,StartsWith(氏名,TextInput1.Text),StartsWith(都道府県,TextInput2.Text))
↓氏名が`山田`かつ都道府県が`三重`の人が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/a2988a34-7d4b-b39e-d806-04ad5e59762e.png)

##事例⑥：複数列のOR条件で前方一致フィルタをかける
2つのテキストボックス(`TextInput1`,`TextInput2`)を使って、複数列（ここでは氏名と都道府県）のOr条件で絞り込みます。

    Filter(SampleList,StartsWith(氏名,TextInput1_5.Text)|| StartsWith(都道府県,TextInput1_6.Text))
↓氏名が`佐藤`の人と都道府県が`三重`の人が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/b55104b7-50eb-81b1-9274-d010037e32d1.png)

##事例⑦：数値列で値の大小のフィルタをかける
テキストボックス(`TextInput1`)に任意の数値を入力させ、年齢が入力値以上の行だけを絞り込みます

    Filter(SampleList,年齢>=Int(TextInput1.Text))
↓90歳以上の人だけが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307669/da64bd17-0b7b-8fce-300e-accc6262ff93.png)
Ruby Kaigi Takeout 2021 に参加してきました

Ruby Kaigi Takeoutに参加したので遅まきながらレポートを完結に書きました。
私の経歴としては学生時代は趣味でコードを書いていて新卒で入った会社でRuby on Railsでの開発を1年半ほど経験（継続中）で今に至るといった感じです。

今回は初日から最終日まで参加して特に印象深かった発表を3つほどご紹介したいと思います。

## TypeProf for IDE: Enrich Dev-Experience

https://www.slideshare.net/mametter/typeprof-for-ide-enrich-development-experience-without-annotations

Ruby3から追加されたRBSを利用して型推論でautocomplete、型エラーの報告、RBSの自動生成などができるVSCodeプラグインの話でした。

個人的に便利だと感じたのはRBSの自動生成で、Ruby3のRBSの発表を見たときに別ファイルに型定義を書いておくのは若干めんどくさいのではないかと感じていたのでぜひ使ってみたい機能です。

TypeProf for IDE自体は開発途中でまだまだ課題もあるそうです。
例えばTypeProfには「require先もパースしにいくので遅い」という欠点があり、それに対する解決策は現状、

- RBSを書く（定義があると静的解析コストが減る）
- アプリケーションをコンポーネントごとに分ける

の２つでした。
これでは開発者側で対応しなければいけなくなるので、TypeProf for IDEは1秒以上かかる解析は打ち切るという設計にしたそうです。

静的解析ツールなどは普段つくることがないのであまり自分にはない視点や課題についてのお話だったので興味深い発表でした。

またRubyMineがRBSを割とちゃんと対応し始めていたのを横目に見ながら羨ましがっていたVSCodeユーザーなので、個人的にはこの発表の内容は嬉しかったです！最後のKeyNoteでもMatzさんから今後Ruby3.1等で開発体験に注力していくとの発表があったので今後が楽しみです。

セットアップ手順（開発途中）: https://gist.github.com/mame/86234de6a58352b9f994e0f8a6d6fbc2


## PRK Firmware: Keyboard is Essentially Ruby

https://slide.rabbit-shocker.org/authors/hasumikin/RubyKaigiTakeout2021/

「キーボードは実質Rubyである」というユニークな題名に惹かれて聞きに行きました。
こちらはRubyに関する機能のお話ではなく、Rubyで作られたキーボードファームウェアのお話です。
私はキーボードを自作したりするので特に印象深かったです。

キーボードを自作する際にはProMicro等のマイコンにファームウェアをインストールしてキーコンフィグを行います。主流なファームウェアとしてはQMK Firmwareなどですが、こちらはC++でキーコンフィグを書くことになります。

私個人としては普段使っているRubyでキーコンフィグができるというのは大変便利に感じました。
またキーボード内のマイコンでRubyを処理するRubyモードの紹介などもありWindowのメモ帳でもRubyのコードを書いて実行する様子をデモしており、「キーボードは実質Rubyである」とタイトル回収をしていました。

PRK Firmwareは通常の自作キーボードに付属するProMicroでは動作しないようなので、動作対象のSparkfun Pro Micro RP2040を手に入れるのに一手間掛かりそうですが、入手でき実際に試してみようと思います。

https://github.com/picoruby/prk_firmware



## Ruby, Ractor Quic

https://slide.rabbit-shocker.org/authors/unasuke/rubykaigi-takeout-2021/

RactorというRuby3で導入された並列・並行処理のための新機能の中でQuic（HTTP3）を使用できるか試してみたという発表でした。

大変親切な発表で、

- TCP/UDPの違いと使い分けについて
- Quicについて
- Quicのパケットの中身について

などを詳しく説明されており、大変わかりやすい内容になっていました。

説明の後検証用のアプリでパケット通信をRubyで行ってみたという内容で発表されていたのですが、残念ながらRactor内でOpenSSLが使用できず断念されていました。（RDocを見る限り頑張ればできそう）

Ractor自体がまだ発展途上であり、またRactorサポートなGemがまだ少ないのでまだまだサービスで使ったりできる状況ではないようです。

また余談ですがRactorは今後はGoのgoroutineのようなM:Nモデル（複数(N)のカーネルスレッドに 複数(M)のユーザスレッドを対応させたもの）にしていく予定だったりと仕様が変わっていくようです。


# まとめ

全体的にRuby3で追加されたRBSやRactorなどの機能やJITコンパイラはもちろん、開発体験を向上を主眼における発表が多かったです。主にVSCode関連の話が多かったので、VSCodeユーザーとしてはとても嬉しかったです。

当初はRactorやRBSの話をメインに聞きに行こうと思っていたのですが、個人的に特に印象に残った話はキーボードを自作するので「PRK Firmware: Keyboard is Essentially Ruby」でした。
前からRubyでキーコンフィグが書ければ良いなと思っていたので、是非試したいです。

Ruby Kaigiに参加するのは今年が初めて、かつオンライン開催となってしまったので、そう遠くないうちにオフラインでの参加できればと思います。

末筆ではございますが、閲覧して頂きありがとうございました！
Swift：開発中のMarkdown解析パッケージをもう少しテストしやすくする

前回、[SwiftでMarkdownを解析してオブジェクトツリーに変換する](https://qiita.com/sYamaz/items/1a29a2cb5b3207ad87dc)という記事を作成しましたが、今回はその続きです。

尚、前回記事で「レンダリングはしてくれるけどオブジェクトツリーにしてくれるパッケージあまりないな...」と言いましたが大抵のSwiftのMarkdownレンダリング系パッケージは

`text`-->`node tree`-->`html`

のような変換過程を辿っていることがわかりました。つまり今Tryしていることはいわゆる「車輪の再発明」ということです。勉強になるからいいかと割り切ってます

# 問題点

「とりあえず動くもの！」ということで前回はとりあえずif分岐をひたすらしていましたが流石にテストし難いです。

```swift
/// 以下はイメージです
func parse(text:String){
  while(全文字探査するまで){
    if(H1の場合){
    }
    else if(H2の場合){
    }
    // 中略。無限にelse if...
    else if(コードブロック("```")の場合){
    }

    1文字進める、または処理済みの所まで進める()
  }
}

```

# 変更

Markdownの要素（`# H1`や`**strong**`,...)ごとにシンプルなテストができるようにしたいです

### Markdown要素ごとの解析処理の分化

[前回記事](https://qiita.com/sYamaz/items/1a29a2cb5b3207ad87dc)で述べているように、この開発中のパッケージではMarkdownの各種要素をそれぞれインライン要素、ブロック要素とみなしています。それぞれの要素ごとにParserを作成するイメージでクラス分離していってます。

（紫で塗りつぶされているのは`protocol`)


![Untitled Diagram.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088399/f59184c8-a462-1c72-16fb-45e87bf8ac39.png)

`BlockParserDelegate`も`InlineParserDelegate`もそれぞれ、解析結果のオブジェクトと、まだ解析していないMarkdown文字列を返します。

#### BlockParserDelegate

```swift
import Foundation
public protocol BlockParserDelegate{
    func parse(_ text:String, closure:(String)->[MDInline]) -> (nextText:String, node:MDBlock?);
}
```

#### InlineParserDelegate

```swift
import Foundation
public protocol InlineParserDelegate{
    func parse(text:String) -> (nextText:String, node:MDInline?)
}
```

このProtocolの実装クラス`StrongParser`

```swift
import Foundation
public class StrongParser: InlineParserDelegate
{
    public func parse(text:String) -> (nextText:String, node:MDInline?){
        if(text.starts(with: "**")){
            // scan
            let subStartIndex = text.index(text.startIndex, offsetBy: 2)
            let subText = text[subStartIndex...]
            if let end = subText.range(of: "**"){
                // text between ** and **
                let content = subText[..<end.lowerBound]
                
                return (String(subText[end.upperBound...]), MDStrong(String(content)))
            }
        }
        
        return (text, nil)
    }
}
```

`StrongParser`では以下のようなイメージです

```swift
let parser = StrongParser();

let result1 = parser.parse(text: "**bold**text")

// result1.nextText -> "text"
// result1.node -> MDStrong(text:"bold")

let result2 = parser.parse(text: "texttext")

// result2.nextText -> "texttext"
// result2.node -> nil

```

# 結果

この変更によってMarkdown要素ごとのテストが可能になりました。あとは呼び出し側のクラスがテスト済みのそれらをうまく使うだけです。

---

今回の記事の内容を適用したまだまだ改善の余地が大きいMarkdown解析Githubリポジトリ

https://github.com/sYamaz/MarkdownAnalyzer
Moralis フリー archive node アクセスサービスで QuickSwap の USDC/JPYC 流動性ペア残高の履歴を取得するメモ

## 背景

税金計算とか裁定取引とかで Matic チェーンのアーカイブノードにアクセスしたい...
Infra とか QuickNode の archive お高い... $250/month
(quicknode は 10 回/month まで archive node call 無料ではるが, 少なすぎ)

自身で archive node 建てるのもめんどいし...

https://moralis.io/how-to-connect-to-polygon-nodes/

Moralis というサービスが出てました.

https://www.reddit.com/r/polygonnetwork/comments/oealfx/how_to_connect_a_free_full_archive_polygon_node/

今の所(2021/10/03) 500 万回/day まで無料とあります. いずれ有料化されるかなとは思います.

## 使う

エンドポイント変えるだけなので, 他は Infra みたいな感じで使えます.

Python web3 で Uniswap の流動性ペアの残高を取得するメモ(最新ブロックのみ)
https://qiita.com/syoyo/items/d4db214903bd0105247c

を参考にして, QuickSwap の USDC/JPYC 流動性ペア残高の履歴を見てみます.

```python

import json
from decimal import *

from web3.auto import w3
from web3 import Web3,HTTPProvider
#import web3.eth

from eth_account.messages import encode_defunct

web3 = Web3(HTTPProvider('https://speedy-nodes-nyc.moralis.io/<your_id>/polygon/mainnet/archive'))
blockNumber=web3.eth.blockNumber
print(blockNumber)

lp_addr=Web3.toChecksumAddress('0x205995421c72dc223f36bbfad78b66eea72d2677') # QuickSwap USDC/JPYC

# https://polygonscan.com/address/0x205995421c72dc223f36bbfad78b66eea72d2677#code
abi = json.loads(open('abi.json').read())

contract = web3.eth.contract(address=lp_addr, abi=abi) #, bytecode=router_bytecode)

print("decimals", contract.functions.decimals().call())
print("totalSupply", contract.functions.totalSupply().call())
print("token0 addr", contract.functions.token0().call())
print("token1 addr", contract.functions.token1().call())

# Recent one
print("reserves(token0, token1, blocktime): ", 
contract.functions.getReserves().call())

# At specific block #
blocknum=15796396
print("reserves(token0, token1, blocktime): ", contract.functions.getReserves().call(block_identifier=blocknum))

```

```
19796932
decimals 18
totalSupply 1965833802783266745
token0 addr 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
token1 addr 0x6AE7Dfc73E0dDE2aa99ac063DcF7e8A63265108c
reserves(token0, token1, blocktime):  [202515937252, 23942787504421634745737625, 1633266720]
reserves(token0, token1, blocktime):  [23924006905, 3045627439797363538382766, 1623877364]

```

Voila :tada:

とりあえず blockid 変えて 15796396 https://polygonscan.com/block/15796396  = この記事を書いているときから 108 日前にしても残高変化あるので, アーカイブノードアクセスできているのがわかります!
(帰ってくる blocktime は unix timestamp)

happy 税金計算 and 裁定取引!
オブジェクト指向についてメモ

#オブジェクト指向
よくりかいしていないのでメモです。

##オブジェクト
？ブロック

##カプセル化
その機能だけで動くようにする。
？ブロックの機能はほかの機能を変更したとしても動くように

##メソッド
classの中にある、関数を使った処理
###関数
何かを処理などして返す

##プロパティ
オブジェクトが持つ属性
愛知県の市区町村をRと色々なデータを使って可視化してみた②

## はじめに
以前作成した以下の記事で、愛知県を市区町村ごとに分けた地図を描画してみました

#### 愛知県の地図を作成した記事
https://qiita.com/zumi0/items/4b8df477d9b62008064e

#### 愛知県の市区町村をRと色々なデータを使って可視化してみた①
そして前回は、人口と昼間人口比率のデータを使って愛知県の市区町村ごとに色分けしたコロプレスマップを作ってみました。

https://qiita.com/zumi0/items/bfc9046c7a4a3dcc6ee4

今回は前回とは違うデータを使ってみようと思います。

## 今回使うデータ
今回は以下のデータを使ってみようと思います。

- 市区町村の総面積
- 市区町村の居住地面積
    - 今回は居住地面積比率(=居住地面積/総面積)として利用
- 市区町村の森林面積
    - 今回は森林面積比率(=森林面積/総面積)として利用

こちらのデータはどれも2014年度のもので、[政府統計の総合窓口（e-Stat）](https://www.e-stat.go.jp/)からダウンロードしました。

## 描画

```r
# 各種パッケージの読み込み
library(tidyverse)
library(jpndistrict)

# 愛知県の地図を描くためのデータ
aichi <- jpn_pref(23)

data <- read_csv("./area_data.csv") %>% # e-StatからダウンロードしたCSVの読み込み
        mutate(area_code = as.character(area_code), # aichiとdataを結合するために、型変換
               resident_area_ratio = resident_area / area, # 総面積における居住地の比率を算出
               forest_area_ratio = forest_area / area) # 総面積における森林面積の比率を算出

# 地図データと面積データを結合
aichi_joined <- inner_join(aichi, data, by = c("city_code" = "area_code"))

# 市区町村の居住地面積比率のデータを描画
g_resident_area <- ggplot(aichi_joined,aes(fill = resident_area_ratio)) + # 居住地面積比率で色分け
                   geom_sf() +
                   theme_gray(base_family = "Osaka") + # フォントを指定
                   theme(axis.text = element_blank(),axis.ticks = element_blank()) + # 軸をきれいにする
                   labs(title = "市区町村別の居住地比率",fill="居住地比率") # グラフのタイトルなどを指定

# 市区町村の森林面積比率のデータを描画
g_forest_area <- ggplot(aichi_joined,aes(fill = forest_area_ratio)) + # 森林面積比率で色分け
                 geom_sf() +
                 theme_gray(base_family = "Osaka") +
                 theme(axis.text = element_blank(),axis.ticks = element_blank()) +
                 labs(title = "市区町村別の森林面積比率", fill = "森林面積比率")

```

## 結果
### 居住地面積比率
居住地面積比率のデータを使って作成したコロプレスマップは、以下です。

![スクリーンショット 2021-10-03 21.35.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/4494b528-6734-1ce2-b60e-88a2de3a0f09.png)

愛知県の西部は居住地面積比率が高いです。西部は名古屋市など都市部のため居住地面積比率が高い結果になりました。個人的には知多半島や渥美半島の居住地面積比率が高いのは知りませんでした。有料道路のあたりはそのような感じはしませんでしたが空港もあったりするので、みていた部分は一部に過ぎないことですね。勉強不足でした。

### 森林面積比率
さきほどは居住地面積比率のデータを使ってコロプレスマップを作成しました。次に森林面積比率を使ってコロプレスマップを作ってみます。おそらく、居住地面積比率の結果と真逆になることが予想されますが、結果はどのようなものでしょうか？

![スクリーンショット 2021-10-03 21.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/a48aabbf-5c49-0e0c-faa3-3c5ea8e54d04.png)

予想通り、さきほどと逆の結果になりました。愛知県東部が森林面積比率が高い結果になりました。

## さいごに
今回は居住地面積比率と森林面積比率のデータを使って、コロプレスマップを作成してみました。今後も他のデータを使って、可視化していこうと思います。
HTMLをはじめからやり直してみる①

久しぶりの投稿になります。
学習の記録をこちらに残していきます。

#HTMLの仕組み
##●タグ
　HTMLでは、テキストをタグで囲むことで、テキストが「見出し」や「リンク」など役割を持たせることができる。

##●見出し
　`<h1>テキストテキスト</h1>`
　など、大きさ別に`<h1>〜<h6>`まで要素が存在する
　※h→heading(見出し)の略

　`<h1>`が一番大きな見出し、
　`<h6>`が一番小さな見出し。

　なお、テキストの最後には</h1>のように終了タグ（バックスラッシュ入り）で囲むこと

##●段落
　段落は`<p>`要素
　p=paragraph（段落）の略
　見出し以外の文面は`<p>`要素を使う

　　例）`<h*>`要素で見出しの大きさや重要性で使い分け
　　　　`<p>`要素は本文などで使用

##●コメント
　`<!— テキスト　テキスト —>`　のように
　`<!— —>` で囲まれたテキストはブラウザに表示されない
　メモとして使うことができる

##●リンク
　テキストに対してリンクを設定するには
　`<a>`タグを使用する

　1.リンクを貼るテキストを決める
　　`<a>Google </a>` これで実際に表示されるのは「Google」のみである

　2.リンクを作成
　　`<a>`タグのテキストに対し、URLを指定するには `href`属性を追加する
　　`<a href=“URL“>`のように記述。
　　URL部分に実際のURLを指定する。

例）　`　<a href=“https://www.google.com“>Google</a>`

　　URLは”　” で囲むことを忘れない。
	
##●画像を表示する
　画像は`<img>`タグを使用
　これはテキストがないため、終了タグは不要
　
　src属性のURL部分に画像のリンクを指定する
	`<img src=“URL”>`

##●リスト
　　・HTML
　　・CSS
　　・PHP
　　などのようなリストを作成する場合には
　　`<li>`タグを使用する。

　　例）	`<li>HTML</li>`

　　`<li>`タグは囲む要素によって種類が変わる
	・先頭に黒点	`<ul>`タグ
	・数字で連番　`<ol>`タグ

　　例)
	`<ul>`
		`<li>HTML</li>`
		`<li>CSS</li>`
		`<li>PHP</li>`
	`</ul>`

##●入れ子（ネスト）
　要素を要素で囲むことを「入れ子（ネスト）」という
　囲む方の要素（ul）を親要素
　囲まれる方の要素（li）を子要素という

##●インデント
　入れ子構造の時は、子要素をインデント（字下げ）することでその親子構造を明確にする
　行の先頭でtabキーを押すことでインデントできる

　※インデントしなくても親子構造は成立するが、構造が見づらく修正などが必要になった際に、発見までに無駄時間がかかってしまう
CI/CDとは何かを勉強する

# 前置き
CI/CDってよく聞くけど、他人説明できるほど知らなかったので勉強しました。
ググった内容を自分なりにまとめた記事です。
より詳しく知りたい方は、下記の参考文献を読んでみてください。

# 参考文献
[継続的インテグレーション (CI)](https://circleci.com/ja/continuous-integration/)
[CI(継続的インテグレーション)とは？ » CloudBees|テクマトリックス](https://cloudbees.techmatrix.jp/devops/ci/)
[継続的インテグレーションとは? – アマゾン ウェブ サービス](https://aws.amazon.com/jp/devops/continuous-integration/#:~:text=%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AF%E3%80%81%E9%96%8B%E7%99%BA,%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E6%89%8B%E6%B3%95%E3%81%A7%E3%81%99%E3%80%82)
[いまさら聞けない「CI/CD」の意義――GitHubとGitHub ActionsでCI/CDを試してみよう](https://atmarkit.itmedia.co.jp/ait/articles/2107/28/news014.html)
[CD(継続的デリバリー)とは？ » CloudBees|テクマトリックス](https://cloudbees.techmatrix.jp/devops/cd/)
[継続的デリバリーとは - Red Hat](https://www.redhat.com/ja/topics/devops/what-is-continuous-delivery)
[継続的デリバリーとは? – アマゾン ウェブ サービス](https://aws.amazon.com/jp/devops/continuous-delivery/)

# CI (Continuous Integration) とは
- 継続的インテグレーション
- 開発者が自分のコード変更を定期的にマスターブランチにマージし、その後に自動化されたビルドとテストを実行する

## CI で実現すること
- 開発者は1日1回またはそれ以上の頻度でリポジトリにコミットする
- コミットがマージされる前に、自動ビルドと自動テストがトリガーされる
- ビルドやテストに失敗しても素早く検知できる

## CI 登場以前は？
- 開発者が長期間にわたって独立して作業し、作業が完了後初めてマスターブランチにマージ
    - 変更点が多くマージ作業に時間がかかる
    - 小さいバグが修正されずに長期間に渡って累積 → **リリース遅延**

## CI のメリット
- 開発者の生産性を向上
    - 開発者を手動作業から解放
- 短時間でバグの発見、対処
    - 自動テストなので、テスト頻度が上がる
    - バグが後になって大きな問題に発展する前に発見して対処できる
- 更新を迅速に配信
    - 常にビルドが通るリポジトリを維持
    - お客様（ユーザー）に迅速かつ頻繁に更新を配信できる

## CI を実践するために必要なこと
- コードを統合するための共有リポジトリ環境
- コードが正しく動くかを検証する実行可能なテストコード
- テストコードを自動実行できる環境（CI環境）

# CD (Continuous Delivery) とは
- 継続的デリバリー
- コード変更が発生すると、自動的に実稼働環境へのリリース準備が実行される
    - ビルド段階の後にテスト環境またはステージング環境にデプロイされる
    - デプロイ後にシステムテストやUIテストを行う
    - 準備が終わったら運用環境への更新を承認する

## CD のメリット
- リリースプロセスの自動化
    - 開発チームによるコード変更のビルド、テスト、運用環境へのリリースに向けた準備が自動化
- 開発者の生産性を向上
    - 開発者を手動作業から解放
- 短時間でバグの発見、対処
    - CD によってプロセス全体が自動化されるので、自分のコードに付加的な種類のテストを簡単に実行できる
- 更新を迅速に配信
    - CD を適切に実装すると、標準化されたテストプロセスに合格し、デプロイ準備の整ったビルド成果物を常に手元に持つことになる

## CD を実践するために必要なこと
- コードのリリースやデプロイをする実行可能なコード
- リリースやデプロイをするコードを自動実行できる環境（CD環境）

# 自動テストの例
- コード解析
- 単体テスト
- APIテスト
- UIテスト
- 負荷テスト


# CI/CD はなぜ必要？
- 「開発、マージ、テスト、デリバリー（リリース）」を繰り返して、ユーザーからのフィードバックを受け取って改善し続けなければならない
    -  「開発、マージ、テスト、デリバリー（リリース）」を高頻度で回せれば、その分ソフトウェアを改善できる

# Unity 開発で使えるツール例
- Jenkins
- Github Actions
- GitLab CI/CD
- CircleCI
- Azure Pipelines
- Unity Cloud Build
pandasの使い方


最新版は以下に記載しました。
https://hana-shin.hatenablog.com/entry/2023/10/19/224028

#1 pandasとは
pandasとは、データ分析用ライブラリです。
pandasで利用できるデータは、表計算ソフトExcelで扱うような表形式のデータです。
pandasを使うと、Excelなどのファイルから表形式のデータを読み込み、集計、データ抽出、
グラフの表示などが行えます。

#2 環境
VMware Workstation 15 Playerで作成した仮想マシン(1台)を使用しました。

CentOSの版数は下記のとおりです。

```console:CentOSの版数
[root@server ~]# cat /etc/redhat-release
CentOS Linux release 8.3.2011
```

カーネルの版数は下記のとおりです。

```console:カーネルの版数
[root@server ~]# uname -r
4.18.0-240.el8.x86_64
```

さらに、Anacondaをインストールして、Anacondaの仮想環境で各種動作確認をしました。
[Docker](https://qiita.com/hana_shin/items/392bd01be6aff9fc1dd4)や[Kubernetes](https://qiita.com/hana_shin/items/ef1a20239001ac83a78d)のように、既存の環境に影響を与えることなくインストール、削除が
できるので便利だと思いました。
Anacondaのインストール方法は、[Anacondaのインストール方法](https://qiita.com/hana_shin/items/a65d686d0e611884cef4)を参照してください。



#3 事前準備
スシの名前、価格、注文数を記録したcsvファイルを作成します。
なお、`ika`の値段は意図的に空欄にしています。

```console:テスト用ファイルの作成
(base) [root@server ~]# cat sushi.csv
sushi,price,orders
ikura,500,2
aji,400,4
uni,700,2
toro,800,4
ika,,2
saba,200,2
kohada,200,2
```


#4 csvファイルに対する操作

##4.1 csvファイルを読み込む方法(`read_csv`)
csvファイルを読み込むためには、`read_csv`メソッドを使用します。
`read_csv`メソッドの引数には、csvファイルのパスを指定します。
tp.pyとcsvファイルは同じディレクトリにあるので、read_csv('sushi.csv')と指定します。

なお、スクリプト中の`df`はDataFrameを表しています。
Pandasには2つの主要なデータ構造があって、Series（シリーズ）が1次元のデータ、
DataFrame（データフレーム）が2次元のデータに対応しています。


```console:スクリプト
(base) [root@server ~]# cat tp.py
import pandas as pd

df = pd.read_csv('sushi.csv')
print(df)
```


```console:実行結果
(base) [root@server ~]# python3 tp.py
    sushi  price  orders
0   ikura  500.0       2
1     aji  400.0       4
2     uni  700.0       2
3    toro  800.0       4
4     ika    NaN       2
5    saba  200.0       2
6  kohada  200.0       2
```



最新記事は以下に記載しました

https://hana-shin.hatenablog.com/entry/2023/10/19/224028

https://hana-shin.hatenablog.com/entry/2023/09/20/211912

https://hana-shin.hatenablog.com/entry/2023/08/26/200155

https://hana-shin.hatenablog.com/entry/2023/10/26/225050

https://hana-shin.hatenablog.com/entry/2022/02/12/203642
【AdobeXD】③確認ダイログの表示方法

# はじめに
[【AdobeXD】②横スワイプで画面遷移](https://qiita.com/seaka829/items/65c8bdfeaabc65200d9e)の続きです。
今回は、登録などの操作時に表示される**確認ダイアログ**を表示させるデザインの作成手順について記載する。

# 作成手順

## 1. 投稿画面の作成

- 画面Aを投稿画面に修正

![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/08b6953f-5d7c-ae1b-7950-70e890cb43c3.gif)


## 2. 確認ダイアログを作成

- 新規画面を追加
- ダイアログのサイズに調整
- ダイアログを作成

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/482d96ed-948e-f23f-f388-43943881e1b1.gif)


## 3. ボタンタップで確認ダイアログを表示

- プロトタイプ機能でボタンクリック時に確認ダイアログに遷移するよう設定
- タップ時にオーバレイ(画面の上に表示される)されるように設定

![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/fd85b3a2-3d9b-ea31-62ac-e1585c209b89.gif)


## 4. 確認ダイアログクリック時の遷移

- 確認ダイアログのはい、いいえをクリックしたとき、投稿画面に遷移するよう設定
- タップ時に自動アニメーションで遷移するよう設定

![5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/20489e4f-7ff9-6bd2-44e4-fe7d281b92b2.gif)

## 5. プレビューで確認
右上の▶︎をクリック
プレビューで遷移を確認

![6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/e2e5181e-8bd8-9c4e-f737-cb61610ec0c0.gif)
階層構造を維持したままcurlコマンドでアップロードする方法

今日はcurlコマンドで複数のファイルをアップロードする方法を紹介します。
通常curlコマンドはファイルしかアップロード、ダウンロードすることができず、ディレクトリ単位で操作することができません。
そのためディレクトリのアップロードを行う場合は少々工夫が必要となります。
通常ディレクトリ単位でのデータのやりとりにcurlを使用する事があまりないためか需要はないかもしれませんが、例えばArtifactory等のサーバーへ特定ディレクトリ配下のファイルをまとめてcurlで処理したい場合に役に立つと思います。

#Shell中身
シェルの内容は、[前回](https://qiita.com/fy406/items/c058436fc789644708ba)の応用となっています。
以下のシェルを処理対象ディレクトリの一つ上のディレクトリに作成し、そのディレクトリへ`cd`コマンドで移動し、`./<シェルスクリプト名> <対象ディレクトリ名>`の形式で実行すると、対応するcurlコマンドがバーっと表示されます。
`echo`コマンドと`"`を外せばそのまま`curl`コマンドが実行されます。

```
#!/bin/sh

if [ $# != 1 ]; then
 echo "引数を1つ指定してください"
 exit 1
fi

DIRCNT=`pwd | wc -m`
let DIRCNT++
WORKDIR=`pwd`'/'$1
ALLFILES=`pwd`'/'$1'/'*
FINDFILE=`find $ALLFILES -type f`

for NOWFILE in $FINDFILE;
do
 NOWDIR=`echo $NOWFILE | cut -c $DIRCNT-`
 echo "curl -T "$NOWFILE" http://<サーバーのFQDN or IP>/"$NOWDIR
done

exit 0
```

スクリプトの解説は次回行います。
RaspberrPiにSambaで繋ごうとしたらmacOSからは接続不良とエラー: オリジナルの項目が見つからないため、操作を完了できません。

余ってるRaspberryPi3 ModelB(ラズパイ)と外付けHDDを組み合わせて、2017年発行の書籍を参考にNASを作った。
するとWindows10からは共有を確認ができるのに、macOSから接続しようとするとエラーが出て共有できない。
使っているパソコンはmacOS High Sierraバージョン10.13.6。


# 症状 接続不良
別のWindows10パソコンからは共有できているのが確認できるのに、Macパソコンからは Finder->移動->サーバへ接続->smb://(ラズパイのIP)->接続 としても接続できない。

# 解決法 Sambaのユーザー登録をする
Sambaのユーザーを作成しているか確認する。

```console
$ pdbedit -L
```
何も表示されない場合はユーザー登録する。

```console
$ sudo smbpasswd -a ユーザー名(例えばpi)
```
パスワードを入力して完成。
古い書籍にはSambaのユーザー登録の話が載っていなかったけど、いつから登録制になったのだろう。
PC本体とSambaでユーザーのパスワードを分けられるので、セキュリティ的にもよいし分かりやすいパスワードを設定できる意味で便利ではあると思う。


# 症状 クリックするとエラー表示が出る
Finderウィンドウの共有セクションに作成したフォルダ名らしきアイコンは出ているのにクリックすると「オリジナルの項目が見つからないため、操作を完了できません。」と表示される。

# 解決 smb.confのパスに外付けHDDの表示名ではなくパス名を使用する
ラズパイをGUI(画面)でも操作していたため、Sambaの設定ファイルである/etc/samba/smb.confに記述するパスを外付けHDDの表示名をコピペしてで指定していました。
ちゃんとターミナルからpwdなどでパス名を確認して指定すると、うまく行きました。

```console:/etc/samba/smb.conf
[pi_folder]
path = /media/pi/SOTODUKE-HDD  // ←ここ
```

## 該当しなかったが役立ちそうな解決法
macOSではOSのバージョンによっては、System PolicyでNASや共有フォルダでアクセスできないようになっていて許可する必要があるらしい。
ただこの仕様はmacOSバージョン10.13.6以前のシステムには関係がないそう。

* [Mac OS XでNASや共有フォルダにアクセスしようとすると「オリジナルの項目が見つからないため、操作を完了できません。」とエラーが出てアクセスできない YUU MEDIA TOWN@blog](http://www.yuumediatown.com/diary/mt001/archives/024010.html)
* [フルディスクアクセスが表示されない - Appleコミュニティ](https://discussionsjapan.apple.com/thread/250215079)



# 参考
[【Raspberry Pi 3】sambaサーバーが接続できないときのハマリポイントまとめチェック](https://motojapan.hateblo.jp/entry/2017/09/26/083753)
[03] declarative pipeline の使用例 --Pipeline を GitLab で管理する


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/52a393aee1ba57999196|


## 概要

Pipeline の記述を Jenkins WEB-UI 上に直接書かずに、
Git サーバ(SCM)で管理させるための設定をする.

今回は、Git サーバには GitLab を用いた.


## 手順

### 1. GitLab 上に専用リポジトリを作る

リポジトリおよび接続アカウント情報が以下であるものとする.

|項目|値|
|:--|:--|
|リポジトリURL|`https://gitlab.com/foo/pipeline-scm`|
|アカウント| foo |
|パスワード| **** |

　

### 2. Jenkins の Pipeline ジョブ画面で設定をしてやる

Gitサーバ (ここでは GitLab) のアカウントが Jenkins WEB-UI に存在しない場合は、
下図の緑枠から登録すれば良い. (分かり難いが、「Jenkins」などと表示されるものの気にせずクリックすれば良い)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/1c14b147-33ea-f032-b7c6-2c944ebbf83a.png)

　

### 3. ジョブを実行してみる

ログを見ると、ジョブの最初に GitLab から Jenkinsfile を clone している.

　

以上.
【AdobeXD】②横スワイプで画面遷移

# はじめに

[【AdobeXD】①ボタンクリックで画面遷移](https://qiita.com/seaka829/items/ed0e3b05150398bbc7c6)の続きです。
今回は、横スワイプで画面遷移するデザインの作成手順について記載する。

# 作成手順

## 1. ページを示すドットを追加

- 画面下にドットを追加
- 一番左のドットを黒塗りして画面Aを1ページ目とする

![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/c7d9a1d8-a48d-8172-d1dc-3afe9c633ece.gif)


## 2. 遷移先画面の追加

- 遷移先の画面A~Eを追加
- ページを示すドットを画面に合わせて修正

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/c4d31873-0e00-d1d2-2d04-eebb4b32a07e.gif)


## 3. 横スワイプ時の遷移設定

- 画面Aでドラッグしたとき画面Bに遷移するよう設定
- 画面B~Dに関しても同様の設定を実施

![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/4fef0457-9dc8-f69a-bdba-f1f59a303cd0.gif)

## 4. プレビューで確認
右上の▶︎をクリック
プレビューで遷移を確認

![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/38a9f736-5b37-43aa-8095-4e4135bede94.gif)


## おまけ
スマホアプリで確認
![5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/d176e05e-205f-017f-20ac-04934c4ac0fd.gif)
VPNってなんぞや？

##はじめに
こんにちは。
セキュリティとかなんとかで、VPNって用語よく聞くけど、
駆け出しエンジニアの僕にはなんのことやらって感じなんですよね。
ってことでVPNについて調べていきたいと思います。

##対象読者
- 駆け出しエンジニア
- プログラミング初心者
- VPNってなんぞやって方
- VPNに興味がある方

##VPNとは？
インターネット上に仮想の専用線を設定し、特定の人のみが利用できる専用ネットワークです。
拠点に専用のルータを設置し、相互通信を行うことができます。

「Virtual Private Network」の略。

昨今、カフェとか家とかで作業する人が増えているからなおさらセキュリティに気をつけなければならないですよね。そのためにVPN接続!!

また、安全にデータをやりとりするために、下記を設定することができます。
- トンネリング
- 暗号化
- 承認

###トンネリング
データの送信者と受信者の間に仮想的なトンネル（トンネリング）を作り通信を行う。
トンネルをくぐって通れば中身が見えない的なことでしょう。

###暗号化
やりとりするデータを盗聴・改竄できないように鍵をかける。
見られても暗号化されているから平気!的なことでしょう。

###承認
送信者と受信者同士がお互いに正しい相手だと確かめる方法
送信者はあなたですね。そうです私です。的なことでしょう。

##VPNのメリット
- 通信を暗号化し、安全に通信する
- リモートでのネットワークアクセスができる
- 運用コストが低価
- モバイル端末からアクセス可能
- 複数の拠点と接続可能(専用線だとできない)
- 物理的な距離に左右されずLANを構築できる
- アクセスが匿名なので、IPアドレスがバレない

##VPNのデメリット
- 情報漏洩リスクがゼロではない
- 通信速度が遅い場合がある
- 製品によっては高価
- VPNの弱点である拠点の数だけルーター設置・設定のコストがかかる
- マルウェアを検出できない
- バッテリーを多く消費する可能性がある
- 導入期間に時間がかかるケースがある

※マルウェアとはウイルス・ワーム・トロイの木馬・スパムウェアなどの総称。詳しくは[こちら](https://www.ntt.com/business/services/network/internet-connect/ocn-business/bocn/knowledge/archive_19.html)

##VPNを使うタイミング
- ノートPCなどで無料Wifiスポットに接続して作業する場合（カフェとかね）
- 遠距離拠点とLAN構築したい場合
- 会社以外で作業する場合
- スマホやPCでお金を扱う場合
- 海外版の動画サイトを楽しみたい場合

##接続の種類
- 拠点間接続
- リモートアクセス接続

###拠点間接続
オフィスとデータセンターなどの拠点を繋ぐネットワーク。

###リモートアクセス接続
ユーザーが自宅やカフェ、企業のプライベートネットワークを用意できない場所から接続する。

##専用線との違い
専用線はVPNと似ています。

###共通点
特定の人のみが利用できるところ

###相違点
接続できる範囲→専用線は本社と拠点を1対1で繋ぐことしかできない。
　　　　　　　  VPNは拠点と拠点を繋ぐことが可能。
　　　　　　　
##VPNの種類(4種類)
VPN接続は大きく4種類に分類できます。

###インターネットVPN
インターネット回線を利用したVPN。
インターネットに接続できれば接続できるので、低コストで済む。

###エントリーVPN
光ブロードバンド回線と閉域網でネットワークを構築。
特定の人しか利用できないので、セキュリティが担保できる。
低価格。光ブロードバンドを利用するため。ネットワーク速度が遅くなる可能性もある。

※ブロードバンド回線とは、
通信端末とプロバイダーまでを繋ぐ回線のこと。大きなデータを高速で通信できる回線です。

###IP-VPN
大手通信事業者が用意した閉域網を利用したネットワーク。
通信事業者と契約者のみが利用できる閉ざされたネットワークなので、
暗号化せず、セキュリティが担保できる。通信帯域も確保されているので、
安定した通信を行うことができる。

###広域イーサネット
ネットワーク構築における自由度が高いのが特徴。
ITシステム担当が自社に適したネットワーク構築することが可能。
つまり、自由。

##VPNプロトコル
VPNサーバーと通信を安全で高速なものにするための暗号基準。
主に下記のプロトコルの設定が必要。

- IPsec-VPN
- L2TP
- PPTP
- SSL-VPN

###IPsec-VPN
安全の確保。情報が暗号化されているため。内容の漏洩をしない

###L2TP
1つのトンネルで複数のセッションが可能。暗号化の仕組みはない。

###PPTP
IPネットワーク上のある機器から、別の機器まで仮想伝送路を作り、データを送受信するプロトコル。

###SSL-VPN
暗号化する際にSSL技術を用いるVPNの方法。
SSL技術はクレジット情報や個人情報をやりとりする際のプロトコル。

##SD-WAN
VPNの弱点である拠点の数だけルーター設置・設定のコストがかかるという点を解消した代物。
MicrosoftやGoogleのクラウドサービスなどの利用の増加に伴い、
通信速度の遅延や通信経路の確保が課題。
ですが、SD-WANは上記の課題に対して柔軟に対応できる。

VPNの上位互換と捉えて良いのかな？

##Splashtop
リモートデスクトップサービスの「Splashtop」は、VPNと併用せずとも簡単に導入でき、
安全かつ快適なリモートワーク環境を構築できる見たいです。
いろんなサービスがありますねぇ。

https://www.splashtop.co.jp/


##終わりに
個人の趣味でプログラミングしていた時はセキュリティなんて気にしてなかったけど、
会社で作業するときはセキュリティ対策はしっかりしないとなと思うこの頃です。

この事実を聞くと、これまで情報が漏れていなかったことが奇跡に思えてきました。
皆さんもこの機会にVPNを利用してみてはいかがでしょうか？

##参考記事一覧

https://www.nttpc.co.jp/column/network/whats_vpn.html

https://www.jbsvc.co.jp/useful/security/vpn-connection.html

https://japan.norton.com/vpn-8553

https://mixhost.jp/vpn-column/vpn-towa/

https://www.sbbit.jp/article/cont1/36318

https://www.splashtop.co.jp/knowhow/01/
toStringメソッドの実装がToStringBuilderクラスを使えば楽になる


# はじめに

クラスのメンバ変数の値をログに出力する際に、toStringメソッドを実装して各メンバ変数の値を含めてString型の値を返すような実装をしていると思う。
メンバ変数が少ないと楽だが、メンバ変数が多い場合は実装するにも手間がかかる。
そのような場合、ToSTringBuilderクラスを使用するとtoStringメソッドの実装が楽になるのでどのように出力されるのか簡単に試してみる。

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/ToStringBuilder.html

# ToStringBuilderを試してみる

## プリミティブ型のメンバ変数を持つクラス

プリミティブ型のメンバ変数を持つクラスを用意してToStringBuilderを実行してみる。

```java
public class Student {

    int student_number = 0;

    String firstName = null;

    String lastName = null;

    int age = 0;

    public Student(int number, String firstName, String lastName, int age) {
        this.student_number = number;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

}

```

ToStringBuilderを実行するクラスは以下のように実装。

```java
import org.apache.commons.lang3.builder.ToStringBuilder;

public class Main {

    public static void main(String args[]) {
        Student student1 = new Student(1, "tanaka", "test", 13);
        System.out.println(ToStringBuilder.reflectionToString(student1));
    }

}
```

実行すると以下のように出力された。
```
Student@7d417077[age=13,firstName=tanaka,lastName=test,student_number=1]
```

## コレクションクラスをメンバ変数を持つ場合はどのように出力されるのか

プリミティブ型ではなく、コレクションクラスをメンバ変数に持つ場合はどのように出力されるのか確認してみる。

```java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Student {

    int student_number = 0;

    String firstName = null;

    String lastName = null;

    int age = 0;

    List<Integer> historyClass = null;
    Map<String, String> committee = null;

    public Student(int number, String firstName, String lastName, int age) {
        this.student_number = number;
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
        this.historyClass = new ArrayList<>();
        this.historyClass.add(1);
        this.historyClass.add(6);
        this.committee = new HashMap<>();
        this.committee.put("1", "ikimono");
    }

}

```

出力結果は以下のとおり。
コレクションクラスが保持する値も出力されることがわかる。

```
Student@7d417077[age=13,committee={1=ikimono},firstName=tanaka,historyClass=[1, 6],lastName=test,student_number=1]
```

## 出力フォーマットの変更が可能

ToStringBuilderクラスを使ってメンバ変数を出力する際のフォーマットを指定することが可能。
やり方としては、```reflectionToString``` メソッドにスタイルをパラメータとして渡すか、事前に```setDefaultStyle(ToStringStyle style)```でスタイルを設定しておく２パターンになる。

### 出力フォーマットの種類

出力フォーマットはToStringStyleクラスを設定することで変更可能。

[ToStringStyleのJavadoc](https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/builder/ToStringStyle.html)

| 種類 | 説明 |
| ---- | --- |
| DEFAULT_STYLE | デフォルトの出力スタイル。   値をカンマ区切りで出力|
| MULTI_LINE_STYLE | 値を複数行で出力 |
| NO_FIELD_NAMES_STYLE | メンバ変数名まで一緒に出力せずに、値だけ出力（クラス名は出力する）|
| SHORT_PREFIX_STYLE | オブジェクト情報まで一緒に出力せずに出力 |
| SIMPLE_STYLE | 値のみを出力。|
| NO_CLASS_NAME_STYLE | クラス名は出力せずに、メンバ変数名と値を出力 |
| JSON_STYLE | JSON形式で出力 |

# 最後に

ToStringBuilderクラスを活用すれば、toStringメソッドの実装が簡単にできる。
ログにはクラス名まで不要であれば、出力スタイルを変更することで、ログの出力内容の見直しが出来て良いと思った。
今後、ToStringBuilderクラスを活用できたらと思う。
EC2 + Nginx + Unicorn + Mysql よく使うコマンドまとめ

# はじめに
EC2 + Nginx + Unicorn + MysqlでRailsアプリをデプロイした際に、頻繁に使っていたコマンドをまとめてみました。
## 動作環境
・Rails 6.0.4
・Unicorn 6.0.0 
・Nginx 1.20.1
・Mysql 8.0.26

## Nginxコマンド
```sh:ターミナル
$ sudo service nginx start　 # 起動
$ systemctl status nginx.service  # 状態の確認
$ sudo service nginx reload  # リロード
```

## Unicornコマンド
```sh:ターミナル
$ unicorn_rails -c /var/www/rails/(アプリ名)/config/unicorn.conf.rb -D -E production　 # 起動 (各自のunicorn設定ファイルのパスを記述)
$ ps -ef | grep unicorn | grep -v grep  # 状態の確認 

# 以下のように表示されれば起動されています。何も表示されない場合は起動していません。
username  24265     1 27 03:22 ?        00:00:01 unicorn_rails master -c /var/www/rails/(アプリ名)/config/unicorn.conf.rb -D -E production
username  24271 24265  0 03:22 ?        00:00:00 unicorn_rails worker[0] -c /var/www/rails/(アプリ名)/config/unicorn.conf.rb -D -E production
username  24273 24265  0 03:22 ?        00:00:00 unicorn_rails worker[1] -c /var/www/rails/(アプリ名)/config/unicorn.conf.rb -D -E production

$ kill (PID)  # Unicornの停止 (上記の例だとPIDは24265となります。つまり、kill 24265 で停止します。)

[username@ip-10-0-11-209 rails_app]$ RAILS_ENV=production rails c # EC2内でconsoleを起動させる
# この時、Railsアプリがあるディレクトリ内で実行しないと起動しません。この場合はアプリのディレクトリ名がrails_appです。
```


## Mysqlコマンド
```sh:ターミナル
$ sudo service mysqld.service　 # 起動
$ systemctl status mysqld.service  # 状態の確認
$ sudo service mysqld restart  # リロード
```

# おわりに
今回初投稿させていただきました。自分自身、EC2 + Nginx + Unicorn + Mysql でデプロイすることに結構苦労しましたので、今後少しでもみなさんの力になれるように投稿していきたいと思います。よろしくお願いします!

# 参考サイト
以下、デプロイ時にとても参考になった記事です。@naoki_mochizukiさま、本当にありがとうございます。
- [(デプロイ編②)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1)
よく使うショートカット一覧

バックエンドで2年半近く開発をしていて、ブラウザやエディタで作業効率が上がるショートカットをまとめてみました～
既出記事がたくさんあるかと思いますが、その辺はご理解いただきたいですm(__)m

##共通(ブラウザ、エディタ、office系)
| 　　　　キー入力　　　　 | 　　　　できること　　　　 |
|:-:|:-:|
| Ctrl + C  |  コピー |
| Ctrl + V  |  貼り付け |
| Ctrl + A  |  全選択  |
| Ctrl + X  |  切り取り |
| Ctrl + F  |  検索 |
| Ctrl + N  |  新規立ち上げ|
| Ctrl + S  |  保存 |
| Alt + F4  |  立ち上げているアプリ終了 |

基本的なショートカットですね、、僕もこれがないと生きていけません。。。

##ブラウザ
| 　　　　キー入力　　　　 | 　　　　できること　　　　 |
|:-:|:-:|
| Ctrl + Tab  | 複数タブ開いているとき右のタブへ  |
| Ctrl + Shift + Tab  | 複数タブ開いているとき左のタブへ  |
| Ctrl + (数字)  | 複数タブ開いているとき選択されたタブへ  |
| Ctrl + F4  | 選択タブを閉じる  |
| Ctrl + Shift + T | 閉じてしまったタブの復元  |
| Ctrl + L  | アドレスバー編集  |
| Ctrl + Shift + C  | 開発ツール立ち上げ  |
| Ctrl + R または F5 | 画面リロード  |
| Ctrl + P  | 印刷  |
| Alt + ←  | ブラウザバック  |
| Alt + →  | ブラウザを進める(?)...ブラウザバックの逆です。。  |
| F11  | 最大化  |
| スタートキー + Shift + S  | スクリーンショット  |
| Space  | 1画面下に進む(Shift押しながらだと逆です)  |
| /  | 検索窓に飛ぶ  |

僕も結構やっちゃいがちですが、見ているブラウザを```Alt + F4```で閉じて、「やっちゃったー( ﾉД-)」とかなったときに
```Ctrl + Shift + T```はかなり便利で、見ていたタブが復活します。
再起動後とかの見ていたタブの復活にも便利です！

##エクスプローラ
| 　　　　キー入力　　　　 | 　　　　できること　　　　 |
|:-:|:-:|
| スタートキー + E  | エクスプローラ立ち上げ  |
| Ctrl + Shift + N  | 新規フォルダ作成  |
| Ctrl + L  | アドレスバー編集  |
| Ctrl + R または F5 | 画面リロード  |
| Ctrl + ↑(↓) + Space  |  複数ファイル選択したいときにCtrlキー押しながらをSpaceキーで選択できます  |
| Shift + ↑(↓) | 上下にファイル選択  |
| Shift + F10  | 右クリックと同じ  |
| Alt + ←  | 1個前の画面へ  |
| Alt + →  | 1個先の画面へ  |
| Alt + ↑  | 1階層上がる  |
| Alt + ↓  | 1階層下がる  |
| ESC | 実行しようとしたことをキャンセル  |
| F2  | ファイル名変更  |
| F11  | 最大化  |


##その他
| 　　　　キー入力　　　　 | 　　　　できること　　　　 |
|:-:|:-:|
| Ctrl + Shift + Esc  | タスクマネージャー起動  |
| Alt + Tab  | 現在開いているアプリの移動  |
| Shift + home  | エディタ系で現在のポインタ位置からその行の先頭までドラッグした状態に  |
| Shift + end  | エディタ系で現在のポインタ位置からその行の最後までドラッグした状態に  |
| スタートキー  |  スタートメニューが開く  |
| スタートキー + S | スタートメニュー横の検索バーに移動  |
| スタートキー + D  | デスクトップ画面を表示  |
| スタートキー + R  | "ファイル名を指定して実行"を表示  |
| スタートキー + Tab  | ```Alt + Tab```に似ているけど、過去の開いていたファイルなども選択できる  |
| スタートキー + (数字)  | 下のタスクバーのアプリが開けます。 |
| スタートキー + 矢印キー | 開いているアプリの展開や画面の大きさなどを決められます  |

個人的にですが、```Alt + Tab```と```スタートキー + 矢印キー```は結構多用します～

いかがでしたでしょうか、ショートカットを多用して作業効率アップを目指しましょう！
**いいね**や**コメント**などお待ちしております！

読んでいただきありがとうございました(^^)/
Ruby  aliasとalias_methodについて

#aliasとalias_methodとは
この２つはRubyでメソッドに別の名前をつけるためのものです。

#両者の違い

⚫︎```alias```はグローバル変数に別名をつけることができ、キーワードみたいです。
⚫︎```alias_method```とはメソッド名に文字列が使えて、メソッドであるみたいです。

#書き方
 下の参考資料の引用になってしまうのですが、下記が書き方です。

```
alias 新メソッド名　旧メソッド名
alias 新グローバル変数名 旧グローバル変数名
```

```
alias_method 新メソッド名, 旧メソッド名
```

どのように使われるかというと

```memos_controller.rb

  def subtitle
      puts "Ruby学習"
  end

   alias title subtitle　　#キーワードとして実行される

   title  # => "Ruby学習"
# titleはsubtitleのaliasになっているため、subtitleが実行


```


```memos_controller.rb

class MemosController

  def subtitle
    puts "Rails学習"
  end

  alias_method :title, :subtitle  #オーバーライドしたメソッドが呼ばれる
end


MemosController.new.subtitle # => "Rails学習"
# titleはsubtitleのaliasになっているため、subtitleが実行される。


```



⚫︎参考資料
https://techacademy.jp/magazine/18697
https://qiita.com/YumaInaura/items/7ee8d0160c907a1751a7
非同期処理まとめ(swift)

#非同期処理とは
ある処理を実行中に別の処理を止めないこと処理を非同期処理という。
swiftではスレッドを利用して非同期処理を実現する。

スレッド：CPUにおける最小の実行単位。
　　　　　スレッド数はCPUが担当できる仕事の数。

![非同期処理イラスト.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1261100/f20f47c2-d3da-6753-3d7c-5a01c265456c.jpeg)

#どんな場面で非同期処理が必要？
アニメーションやサーバーとの通信など、時間がかかる処理・重い処理などに使用します。




#マルチスレッド処理
通常プログラムはメインスレッドという単一のスレッドから処理を開始するが、別のスレッドを作成して別の処理を実行させることができる。

<font color="Red">!!ただし、iosにおいてユーザインターフェイスに関わる処理は通常メインスレッドで行われる!!</font>


しかし！！マルチスレッドは正しく実行しなければ下記の深刻な問題が発生するので注意。
`①メモリの枯渇`
`②複数スレッドから同一データを更新するなどの不整合・衝突が発生`
`③デッドロック`

#非同期処理を行う３つの方法
`①GCD`
`②Operation,OperationQueueクラスを用いる方法`
`③Threadクラスを用いる方法`

今回は一番簡単なGCDを次の項目でまとめます。

#GCD(Grand Central Dispatch)
GCDは非同期処理を容易にするためのC言語ベースのシステムレベルでの技術。
GCDではキューを通して非同期処理を行うので、直接スレッドを管理することはない。
プログラマが行うのはタスクをキューに追加することだけ。

###ディスパッチキューについて
GCDのキューはディスパッチキューと呼ぶ。次の２つに大別される。

`①直列ディスパッチキュー`
現在実行中の処理を待ってから、次の処理を実行する。

`②並列ディスパッチキュー`
現在実行中の処理の終了を待たずに、次の処理を並列して実行する。

ディスパッチキューを利用するには、既存のディスパッチキューを取得するか、新規のディスパッチキューを生成する必要がる。

###ディスパッチキューの取得

GCDは既存のディスパッチキューとして一つのメインキューと複数のグローバルキューを提供する。

`①メインキュー：メインスレッドでタスクを実行する直列ディスパッチキュー`

```swift:sample
    let queue = DispatchQueue.main
```

`②グローバルキュー：実行優先度を指定して取得する並列ディスパッチキュー`

```swift:sample
    let queue = DispatchQueue.global(qos :.userIntiated)
```

QoS(Quality of Service)：優先度

| 種類 | 名称 |
|:-:|:-:|
| userInteractive  | ユーザーからの入力を元に即座に反映させる必要がある動作用。アニメーションの実行など。  |
| userIntiated  |  ユーザーからの入力を反映させる一般動作用。 |
|  default | デフォルト。明示的に使用すべきではない。  |
| utility  | 視覚的な情報を伴いながらも緊急度が低い動作用。プログレスパーなど。  |
| background  |  数分かかっても問題ない処理などに用いる。 |



#新規のディスパッチキューを生成

並列処理タイプ


```swift:sample
    let queue = DispatchQueue(label :"キュー",qos :.userIntiated, attributes :.concurrent )
```



#タスクの追加

タスクの呼び出しもとがタスクの処理完了を待つかどうかで、２種類の追加方法がある。
`①同期的追加：タスクをディスパッチキューに追加した後、そのタスク完了まで移行しない`

つまり通常と同じ！

```swift:sample
    dispatchQueue.sync{
        print("同期的追加")
    }
```


`②非同期的追加：タスクをディスパッチキューに追加したら、その処理を待たずに次の行へ移行する。`

```swift:sample
    dispatchQueue.async{
        print("非同期的追加")
    }
```


#タスクの遅延実行

設定時間後にタスクが追加される。
呼び出し元で遅延は発生しない。

```swift:sample
    dispatchQueue.asyncAfter(deadline :.now() + 5){
        print("5秒後に処理を実行")
    }
```

#ディスパッチキューの一時停止と再開

```swift:sample
    //一時停止
    dispatchQueue.suspend()

    //再開
    dispatchQueue.resume()
```
Splunk: 複数イベントの統計値を個別のイベントで使用したい時には

Splunk で時々使うのでメモ。

###### 実施環境： Splunk Free 8.2.2

各値について平均値との差を取りたい時等、複数のイベントにおける統計値を個別のイベントで使用したい場合があります。
そのような場合は、 eventstats コマンドまたは streamstats コマンドを使用します。

eventstats と streamstats の違いは、計算に使用するイベントの範囲にあります。
 eventstats は「全てのイベント」を計算に使用するのに対して、 streamstats は「計算しているイベントより前のイベント」を対象とします。
また、 streamstats は window オプションで計算範囲をさらに狭められます。

まあ、正直言葉ではわかりづらいので、以下に例を示します。

```Splunk:Splunk
| makeresults count=5
| eval Number = random() % 10
| eventstats sum(Number) AS SumEvent
| streamstats sum(Number) AS SumStream
| streamstats window=2 sum(Number) AS SumStream2
| fields - _time
```

![スクリーンショット 2021-09-26 14.41.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/05e10b2e-6da3-c487-c2c9-4ac113516c03.png "2つのコマンドの違い")


2つのコマンドの利用用途について、もう少し考えてみます。

 eventstats コマンドは、個別のイベントについて全体との比率や差分を計算するのに使用できます。

```Splunk:Splunk
| makeresults count=5
| eval Rand = random() % 100
| eventstats avg(Rand) AS Average
| eval Diff = Rand - Average
| fields - _time
```

![スクリーンショット 2021-09-26 15.01.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/be189c89-f674-119a-d4b3-f9e717d643c7.png "eventstats")

 streamstats コマンドは、イベント数を数える count 関数と合わせて連番を生成するのに便利です。

```Splunk:Splunk
| makeresults count=5
| streamstats count
| fields - _time
```

![スクリーンショット 2021-09-26 15.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/c162d0e6-d170-6f1b-9555-79e3037c3100.png "streamstats")

この2つはイベントを横断して算出した値を個別のイベントに適用できるため、上手く使用すればサブサーチの回数を減らして検索スピードを上げることができます。
以下の例では、 ID が Null 値であるイベントについて、 ID の最大値より大きい値を連番で付与しています。
サブサーチを使用せずとも、このように複雑なデータ処理が可能となるのです。

```Splunk:Splunk
| makeresults count=100
| eval Number = random() % 20
| eval ID = if( Number > 10, null(), Number)
| eventstats max(ID) AS MAXID
| eval NullCheck = if( isnull(ID), 1, 0)
| streamstats sum(NullCheck) AS PlusID
| eval NewID = if( isnull(ID), MAXID + PlusID, ID)
| fields - _time, Number, MAXID, NullCheck, PlusID
```

![スクリーンショット 2021-09-26 21.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ae0e0961-d1fe-6bf0-bba1-4890326062d4.png "2コマンド組み合わせ")
Ruby reduce(inject)を使用して計算

#　配列の要素をどんどんたたみ込んで計算

配列内の要素を合計する時に、以下のようなコードを書いていた。

```
def sum(array)
  sum = 0
  array.each do |number|
    sum += number
  end
  return sum 
end 
p sum([5, 10, 20])
# => 35
```
初期値 = 0 の設定、イテレートの記述でもっさり。
reduceメソッドを使用すると、sumメソッド内のコードを1行に減らすことができる。

```
def sum(array)
  array.reduce(0) { |sum, num| sum + num }
end
p sum([5, 10, 20])
# => 35
```
さらに、リファクタリングできる。ただし、.reduce(:+)は.sumとほぼ同じなので以下の2つは同じ結果になる。

```
def sum(array)
  array.reduce(:+)
end
p sum([5, 10, 20])
# => 35
```
```
def sum(array)
  array.sum
end
p sum([5, 10, 20])
# => 35
```

### シンボルを使用してメソッド適用
ブロックの代わりにメソッド名を記述するとメソッドが使える

```
p ["b", "c", "d"].inject("abbccdddeee", :squeeze)
# => abcdeee
```
（例）"abbccdddeee"の中から、["b", "c", "d"]をsqueeze（複数文字を一つにまとめる）
>https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/inject.html

>https://docs.ruby-lang.org/ja/latest/method/String/i/squeeze.html
【AdobeXD】①ボタンクリックで画面遷移

# はじめに
AdobeXDを触ったので備忘録程度に操作方法を残す。
今回はAdobeXDでスマホアプリのログイン画面を作成し、
ログインボタンクリック後に画面遷移するデザインの作成手順について記載する。
本記事を読むことでボタンクリック後に画面遷移させる方法を理解できる。

# 作成手順

## 1. ログイン画面の作成

- ユーザ名を入力するテキストボックスを作成
- パスワードを入力するテキストボックスを作成
- ログインボタンを作成

![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/751d71ba-5ff0-d0da-8c0c-8499ccbe1cc3.gif)


## 2. 遷移先画面の作成

- 新規ページ（画面A）の追加

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/5503ce7a-caed-6b18-6692-a62272fe7951.gif)


## 3. 遷移の設定（本記事のメイン）

- プロトタイプ機能で、ログインボタンから画面Aにドラッグ&ドロップ
- 種類を自動アニメーションを選択
- デュレーションを0.6秒に設定

![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/21ac9d13-0360-7a15-5ccd-56d3f1faca6b.gif)


## 4. プレビューで確認

- 右上の▶︎をクリック
- プレビューで遷移を確認

![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/22e03037-b1d7-adc8-e0e9-ed7bb8cef5fb.gif)

## おまけ

なお、iOSやAndroidアプリのAdobeXDで、実際のスマホでプレビューを確認することができる。
![5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/a0b90230-60c7-a913-e723-da5016537958.gif)
RangeUISliderを使用してみる

RangeUISliderとは
UISliderの両端バージョン。↓こんなやつ
![スクリーンショット 2021-10-03 20.28.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/03209662-8d57-0544-70b7-2b9b63f6750a.png)

ステップ1　SPMでRangeUISliderを入れる
SPMでRangeUISliderを検索し、プロジェクトに入れてあげる。

ステップ2　uiviewをstoryboardにのっける。
ステップ３
乗っけたUIViewのclassの部分にRangeUISliderを指定してあげる。
![スクリーンショット 2021-10-03 20.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/70796fa4-799b-36ab-0f48-c3471b04f482.png)
Designableエラーがおきてもきちんと動くのでこうなっていてもOK！！
![スクリーンショット 2021-10-03 20.15.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1474285/7497aadd-7066-f9c1-b5a5-16681e3970cf.png)


ステップ4 IBOutletでコードに落としてあげる

```swift
@IBOutlet weak var levelUISlider: RangeUISlider!
```
ステップ5 RangeUISliderのUIを変えてみる(コードじゃなくて右側のメニューでもできる）

```swift
levelUISlider.leftKnobColor = UIColor.orange//左の丸の色
levelUISlider.rightKnobColor = UIColor.orange//右の丸の色
levelUISlider.rangeSelectedColor = UIColor.orange//左と右の間の選択されている色
```

ステップ５ Delegateメソッドを呼び出してみる

```swift
levelUISlider.delegate = self

.
.
.
使いそうなやつ

Sliderの範囲が変更されているとき maxとminの値をとれる
 func rangeIsChanging(minValueSelected: CGFloat, maxValueSelected: CGFloat, slider: RangeUISlider) {
}
Sliderの範囲の変更が終了したとき maxとminの値をとれる
func rangeChangeFinished(minValueSelected: CGFloat, maxValueSelected: CGFloat, slider: RangeUISlider) {
    }
```
Action名やExtraのKey名はどうやって定義するのがよいか？

Intentに付与するAction名やExtraのKey名をアプリ独自で定義する場合、どういう値を定義すればいいのか、独自なのでどうとでも定義できてしまうため悩んでしまいますよね。
また、外部に公開する場合、アプリ間プロトコルの定義になりますので、一度適用してしまうと変更不可能という、取り返しのつかない設計要素です。将来を見据えて慎重に決める必要があります。

というわけで、どうやって決めればいいのかを説明しようと思います。

# アプリ外部に公開する場合

Intentを使ったインターフェースをアプリ外部に提供し、独自のActionを定義する場合は、他のAction名と重複しないように、**パッケージ名などをプレフィックスとしてつけた名前を定義する**のが良いでしょう。アプリ外部に提供する場合、それが機能を識別するためのIDになりますので、他のアプリで使用される名前と衝突すると問題が発生してしまいますからね。

プレフィックスの後の名前は自由につけて良いです。アプリ内のシンボル名として、ACTION_HOGEHOGEという名前で定義することが多いと思うので、それをそのままつけても良いと思います。

```kotlin
object Constants {
    const val ACTION_HOGEHOGE = "com.android.myapplication.ACTION_HOGEHOGE"
}
```

例えば、Intent.ACTION_VIEWの値は `android.intent.action.VIEW`の用にactionをプレフィックス的に使うように定義されていますね。なので、これに習って

```kotlin
object Constants {
    const val ACTION_HOGEHOGE = "com.android.myapplication.action.HOGEHOGE"
}
```

とするのも良いでしょう。HOGEHOGEをアッパースネークケースとする場合や、クラス名のようにアッパーキャメルケースにする場合もあるようです。Googleが提供している機能でも統一されていないので、アプリ内で混乱しないルールを適用すれば良いと思います。

アプリとしてはAndroidManifestにintent-filterを定義することになりますね。

```xml:AndroidManifest.xml
<intent-filter>
    <action android:name="com.android.myapplication.action.HOGEHOGE" />
</intent-filter>
```

プレフィックスはアプリのパッケージ名で良いと思いますが、識別するのは機能名なので、複数のアプリが同様の機能を提供するような場合は、その機能を提供するライブラリのGroupIDなどを利用した方がよいかもしれません。

参考になるのは、Custom Tabsに対応したブラウザーアプリで使用されるCustomTabsServiceのAction名ですね。サポートライブラリのGroupIDに基づいたプレフィックスがついています。

```xml:AndroidManifest.xml
<intent-filter>
    <action android:name="android.support.customtabs.action.CustomTabsService" />
</intent-filter>
```

ここで気をつけなければいけないのが、**アプリ外部に公開した独自Action名は、一度つけてしまうと変更が不可能である**点です。
アプリ外部から利用してもらうのですから、対応している外部アプリすべてを同時に修正しないと連携機能が動作しなくなってしまいます。どうしても変更する必要がある場合は、リネーム前と後両対応しておき、外部アプリに変更対応をお願いし、対応がすみ、十分に浸透してから～という手順を踏むことになるでしょうが、そこまでしてリネームするメリットがあるとも思えないので変更しないのが通常です。
上記Custom Tabsを提供するライブラリのGroupIDは、androidx.browserという名前に変わっていますが、アクション名が旧ライブラリのプレフィックスのままなのはそういう理由です。

一方、ExtraのKey名については、Manifestに記述される要素ではなく、Action名などのintent-filterに基づくフィルタリングを行った後に参照されるものですね。Action名などの要素ですでに名前空間が分かれている状態ですので、必ずしもプレフィックスは必要なく、わかりやすく、その機能内で重複しない名前なら何でも良いと思います。
EXTRA_HOGEHOGEという名前で定義することが多いと思うので、私はその名前をそのまま使っています。

```kotlin
object Constants {
    const val EXTRA_HOGEHOGE = "EXTRA_HOGEHOGE"
}
```

# アプリ内で閉じている場合

前項と違って、アプリ内に閉じている場合、他のアプリから使うわけでもなく、呼び出し先のComponent名を検索することなく明示的に指定することになりますので、プレフィックスなどをつける必要は無くなります。もちろんつけても問題はありませんが。
アプリ内でグローバルな値として定義しておく必要も無く、呼び出し処理を呼び出し先のクラスに定義するようにすれば、privateな定数で十分ということになります。この辺は以下を参照。

[Activityの起動処理は起動されるActivityで実装すべし](https://qiita.com/ryo_mm2d/items/6100bc2e7883a6d78012)

定義の範囲が広がってしまうと不必要な複雑さを生んでしまうため、アプリ内部だけで利用する場合は、privateな定数として定義できるようにした方が良いですね。

単純にActivityを呼び出すような場合はそれほど制約はありませんが、PendingIntentを使ったりする場合は、前のバージョンのIntentを受け取ってしまう可能性があるため、こちらも同様に一度決めたAction名やExtraのKey名は安易に変更しない方が良いです。

---

以上です。

私が初めて作ったアプリでは外部アプリとの連携機能も作ったのですが、この辺のルールが分からず結構滅茶苦茶な命名をしてしまって後悔しています。参考になれば。
AOJトライに関する知識知見の記録共有（Volume0-0029）


# 概要
Volume0-0029 English Sentence

https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0029

# コード

```
from collections import Counter

def ret_words(str):
    ss = str.split(" ")
    cs = Counter(ss)
    ls = {w: len(w) for w in ss}
    return [cs, ls]

def hoge(*args):
    ret = []
    for arg in args:
        print(arg)
        ret.append(ret_words(arg))
    return ret

print(hoge(
"Thank you for your mail and your lectures"
))
```

# 実行結果
```
Thank you for your mail and your lectures
[[Counter({'your': 2, 'Thank': 1, 'you': 1, 'for': 1, 'mail': 1, 'and': 1, 'lectures': 1}), {'Thank': 5, 'you': 3, 'for': 3, 'your': 4, 'mail': 4, 'and': 3, 'lectures': 8}]]
```