OmniAICreator/Qiita-1.07M huggingface dataset:
ゼロトラストのディープダイブ(6)-SSE(Security Service Edge)

[前回] [ゼロトラストのディープダイブ(5)-クラウドセキュリティの全体像](https://qiita.com/mingchun_zhao/items/f34966ca138c90fdbc12)

## はじめに

今回は、クラウド・セキュリティの四つの技術に含まれる、SSEの勉強です。

## その前に、いままでのあらすじ

### ゼロトラスト(Zero Trust)

- 背景
    - リモートワークにより、社員用PCが従来の多層防御の外に出てしまった
    - PCを守るものは、セキュリティ対策ソフトが中心に
    - この状況にサイバー攻撃者が付け込み、フィッシング/マルウェアメール、VPN脆弱性を狙った攻撃を仕掛けるようになった
    - 企業は、すべてのアクセスに対し信頼せず安全性を検証/制御する、ゼロトラスト・セキュリティモデルへの転換を迫られた

- ゼロトラストモデルのアーキテクチャ
    - セッション単位でアクセスユーザーと利用デバイスが信頼できるか確認
    - ユーザーに対し、最小権限の原則に基づくアクセス制御を設定すること
    - マイクロセグメンテーションにより、それぞれのサーバー・アプリケーションを個別保護

上述要件に基づいた新しいセキュリティの考え方がSASE。

### SASE(Secure Access Service Edge)

ネットワーク機能とセキュリティ機能を統合した、クラウドネイティブなアーキテクチャ。
SASEは製品やソリューションではなく、複数の製品やソリューションを組み合わせたもの。

- 目的
    - 従来の企業ネットワーク中心の境界型セキュリティ防御から脱却
    - クラウド型エッジを境界とした、全体を俯瞰できるセキュリティ対策

- 機能
    - すべての機能はサービスとしてクラウドから提供される
    - すべての機能を単一のダッシュボードから一元管理できる
    - オンプレミス環境との接続を維持するためのネットワーク要件も存在(SD-WANなど)

- 構成要素
    - CASB(Cloud Access Security Broker)
    - SWG(Secure Web Gateway)
    - ZTNA(Zero Trust Network Access)
    - SD-WAN(Software Defined Wide Area Network)
    - FWaaS(Firewall as a Service)

- SASEの問題点
    - 完全な統合フレームワークの実現には、複数ベンダー製品の統合や新たな投資が必要
    - SASEモデルへの完全移行は、ハードルが高く時間がかかる

そのため、ガートナー社が提唱したSASEへの新たなアプローチが、SSE(Security Service Edge)。
SASEのセキュリティ機能のみ切り離したもので、高度に統合されたセキュリティプラットフォーム。

## SSE(Security Service Edge)が生まれた背景

- Web/クラウドサービス/プライベートアプリケーションへのアクセスを保護するため、効率的なセキュリティ運用が必要
- そのため、データ/ユーザー/エンドポイントの保護機能をネイティブに備えたプラットフォームが必要
- 専用のクラウドプラットフォームから提供される、ネットワークセキュリティサービスの融合がSSE

## SSEの中核機能

- SWG(Secure Web Gateway)
    - プロキシ経由のセキュアなWebアクセス
    - インターネットやWeb、クラウドアプリケーションへのアクセスを保護
    - ユーザアクセスのコンプライアンス維持を支援
    - クラウドプラットフォームへの高速なローカル接続が必要
- CASB(Cloud Access Security Broker)
    - APIおよびプロキシ経由のセキュアなSaaSアクセス
    - SaaSアプリケーションへの接続を保護
    - クラウドのアプリとデータを管理し、機密データの損失を防止することで、コンプライアンス維持
    - すべてのデータを1箇所で管理し、ポリシーコントロールを簡素化
- ZTNA(Zero Trust Network Access)
    - プライベートアプリケーションへのセキュアなリモートアクセス
    - オンプレミスのデータセンターやクラウドで稼働するプライベートアプリケーションへの接続を保護
    - 従来のVPNを必要とせず、安全なリモートアクセスを可能にする
    - 攻撃対象領域を少なくすることで、リモートユーザのセキュリティを強化

## SSEのメリット

- SSEの導入により、ユーザーはどこからでもインターネットやクラウドへのセキュアなアクセスを利用できる
- IaaSまたは自社データセンターの業務アプリケーションへ、インターネットを通じてアクセス可能
- 専用のクラウドプラットフォームからサービスとして提供される

## SASE vs. SSE

- SASEは、単一クラウドプラットフォーム上にセキュリティとネットワーク技術を集約させる
    - ゼロトラストに基づく安全なネットワークを実現するフレームワーク
    - 本社と拠点間の通信をスター型につなぐことで耐障害性を担保
        - ただし、ネットワーク更改にコストがかかる
    - クラウドサービス利用はネットワークを介さず、直接インターネット接続可能
        - ローカルブレイクアウト方式
- SSEはSASEのセキュリティ機能部分により構成される
    - Web/クラウドサービス/プライベートアプリケーションへのアクセスを保護
    - アクセス制御/脅威保護/データセキュリティ/セキュリティモニタリング/使用制御などの機能を持つ
    - SASE同様、すべてがクラウドサービスで提供され、複数ベンダーのサービスをAPIにより統合

## おわりに

SSEの基本知識およびSASEとの関連性を理解しました。
次回は、SSPM(SaaSセキュリティ状態管理)を勉強します。
これもクラウド・セキュリティの四つの技術に含まれます。
お楽しみに。

##### [次回] [ゼロトラストのディープダイブ(7)-SSPM(SaaSセキュリティ状態管理)](https://qiita.com/mingchun_zhao/items/f8729d64f5e5faf2b67d)
JavaScriptでキーイベントを発生させる！【jQuery】


　JavaScriptでキーイベントを発生させる方法です。

キーイベントとは、JavaScriptでキーボードからの入力を受け取ることができるオブジェクトで、PCのキーとイベント処理を連動させたい時などに使われます。

例えば

・ここのキーを押したら音が鳴る
・ここのキーを押したら文字が変わる

などと行った処理が可能になります。


キーイベントの種類は以下のようなものがあります。
```
keydown (キーが最初に押されたときに発生)
keyup （キーが装飾キーでなかったときに発生）
keyup （キーを離したときに発生）
```

キーイベントを発生させる、実際のコードの初歩的な書き方がこちらです。
```JavaScript
$(selector).on("keydown",function(e){
              //処理
});
```

そして、キーイベントのコードの例はこちらです。
```javascript
$(window).on("keyup", function(e){
       if(e.keyCode == 78){
           audio.play(); }
});
```
こちらは「J」のキーを押したら特定の音が出る仕組みになっています。



keyCodeというのは、各キーに番号が割り振られていて、その番号を用いてキーを指定します。
各キーのキーコードはこちらで簡単に調べることが可能です。

https://web-designer.cman.jp/javascript_ref/keyboard/keycode/

JavaScriptでゲームを作成する時など、PCのキーと連動させることで遊びの幅が広がりそうですね！






記事を執筆するにあたって、今回こちらの記事を参考にさせていただきました。

https://9-bb.com/jquery-10/
[備忘] Laravel RelationクラスインスタンスをBuilderクラスインスタンスへ変換

個人メモのレベルなのでご容赦ください。


## Eagerロードの可読性と汎用性問題
Laravel リレーション
https://readouble.com/laravel/6.x/ja/eloquent-relationships.html#has-many-through

リレーションを後付け的にする場合、以下の書き方をしている。
Eagerロードの制約ネストが深くなったり複雑になる場合にこれを使うのが良い。

```php
$user->posts()->where('active', 1)->get();
```
または、推奨されるケースとは異なるが、load関数も近い役割。
```php
$user->load('posts');
```

## BuilderとRelationの型問題
この際、制約が複雑な場合、リレーション先のモデルのスコープメソッドを使うときに以下のように書けば良いと思われるが、
```php
$user->posts()->active()->get();

// loadの場合・・・結局ネストが深くなってしまうのと、コールバックの保守が少し大変(?)
$user->load(['posts' => function ($query) {
    $query->active();
}]);
```

```php
public function scopeActive(Builder $query): Builder
{
    return $query->where('active', 1)
}
```

この場合にscopeActiveの引数に渡される$queryはHasMany(extends Relationなので、もといRelation)クラスのインスタンスである。
scopeActiveの引数に型制約を入れている場合、`expected Builder, class HasMany given.`と怒られてしまう。
（入れていなくても不健全であるし、そもそも動く保証もない。）

## ソースコード
Laravelのソースコードを読むと、
```php
class HasMany extends Relation
{
    public function __construct(...省略)
    {
        ...省略)
        parent::__construct($query, $child);
    }
}
```

```php
abstract class Relation
{
    /**
     * The Eloquent query builder instance.
     *
     * @var \Illuminate\Database\Eloquent\Builder
     */
    protected $query;

    public function __construct(Builder $query, ...省略)
    {
        $this->query = $query;
        ...省略
    }

    ...省略...

    /**
     * Get the underlying query for the relation.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function getQuery()
    {
        return $this->query;
    }
}
```

## 対処法

RelationクラスのgetQuery関数を使う。（直でqueryアトリビュートへアクセスすることもできそうだが・・・）
```php
$user->posts()->getQuery() // ここでBuilderになる
    ->active()->get();

// loadの場合・・・結局ネストが深くなってしまうのと、コールバックの保守が少し大変(?)
$user->load(['posts' => function (HasMany $relation) {
    $relation->getQuery()->active();
}]);
```

※ テストはしていない。
railsでNoMethodError: undefined method `silence'と言われたエラーの対応方法

こんにちは。[virapture株式会社](https://virapture.com)の[もぐめっと](https://mogmet.com)です。

本日はトラブルシュートな記事になります。

## 問題 

railsで開発していたところ、pumaを使ったrailsのログ出力をdockerでそのまま出力したいと思って設定したら下記のエラーが出てしまいました。

```
#<NoMethodError: undefined method `silence' for #<Logger:0x0000aaaaf4db96e8>>
```

というエラーがでて画像が表示されなくなってしまいました。


## 解決法

調べたら下記に答えがあった。

https://github.com/rails/sprockets-rails/issues/376

早速config/environments/development.rbのファイルを修正した。

```development.rb
config.logger = Logger.new(STDOUT)
```

としていたところを

```development.rb
config.logger = ActiveSupport::Logger.new(STDOUT)
```
に変えたら動いた。

## まとめ

ActiveSupport::Logger.newを使ってloggerは設定しよう！

最後に、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/
【Linux】ユーザ作成・削除方法

# 概要
Linuxサーバにおける基本的なユーザ作成・削除方法について忘備録として記載する。

# 前提
基本的にはrootユーザかつbashで各コマンドを実行している前提です。

# ユーザの作成(ホームディレクトリも同時に作成)
```shell
# ユーザ作成にはuseraddコマンドを使用する
# -mオプションは、同時にホームディレクトリを作成 -sオプションはログインシェルを指定
useradd -m {ユーザ名} -s {ログインシェル(フルパス)}
```

```shell
# 例：ユーザ「sample_user」の作成
useradd -m sample_user -s /bin/bash

# /homeディレクトリ配下を確認
ls /home/

# => 作成したユーザ名のディレクトリが作成されている
```

# ユーザのパスワードを設定
```shell
# ユーザのパスワード設定にはpasswdコマンドを使用する
passwd {ユーザ名}
```

```shell
# 例：ユーザ「sample_user」のパスワードを設定
passwd sample_user

# => 新しいパスワードの入力が求められる
```

# ユーザの削除(ホームディレクトリも同時に削除)
```shell
# ユーザ削除にはuserdelコマンドを使用する(-rオプションは、同時にホームディレクトリを削除)
userdel -r {ユーザ名}
```
```shell
# -rオプションはユーザ削除と同時にユーザのホームディレクトリを削除する
userdel -r sample_user

# /homeディレクトリ配下を確認
ls /home/

# => 作成したユーザのホームディレクトリが削除されている
```
ARKitでオブジェクトを積み重ねてみる


### お馴染みのViewContainerを作りARViewを描画する

```swift
struct ARViewContainer: UIViewRepresentable {
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        let boxAnchor = try! Experience.loadBox()
        arView.scene.anchors.append(boxAnchor)
        return arView 
    }

    func updateUIView(_ uiView: ARView, context: Context) {}
}
```

###  tapGestureを付与する

```swift
extension ARView {
func enableToGesture() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapGesture))
        self.addGestureRecognizer(tapGesture)
    }
}
```

### タップした位置にARオブジェクトがあるかないかで処理を分ける。

```swift
@objc private func didTapGesture(recognizer: UITapGestureRecognizer) {
        let tapLocation = recognizer.location(in: self)
        guard let rayResult = self.ray(through: tapLocation) else { return }
        let results = self.scene.raycast(origin: rayResult.origin, direction: rayResult.direction)
//中身があったらARObjectをタップしたことになる。なかったらその位置にARobjectを配置する。
  if let firstResult = results.first {
　　　　　
 } else {
//  
}
```


### オブジェクトを置くメソッドを作成
```swift
private func placeCube(at position: simd_float3) {
        let mesh = MeshResource.generateBox(size: 0.3)
        let material = SimpleMaterial(color: .blue,
                                      roughness: 0.3,
                                      isMetallic: true)
        let modelEntity = ModelEntity(mesh: mesh,materials: [material])
        modelEntity.generateCollisionShapes(recursive: true)
        let anchorEntity = AnchorEntity(world: position)
        anchorEntity.addChild(modelEntity)
        
        self.scene.addAnchor(anchorEntity)
    }
```

### 処理を分けた中身を書く

```swift
 if let firstResult = results.first {
            
            // ARオブジェクトをタップした場合 positionで値を取ってきて
            var position = firstResult.position
            // その上に乗っける。
            position.y += 0.3 / 2
            placeCube(at: position)
        } else {
            // ARオブジェクトがない場所をタップした場合。
            // 新しいオブジェクトを置く。
            let results = self.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .any)
            
            if let firstResult = results.first {
                
                let position = simd_make_float3(firstResult.worldTransform.columns.3) // SIMD3<Float>
                placeCube(at: position)
            }
        }
```
react nativeのheaderにボタンを設置する ～Screenのoptionのいじり方

# 概要
- BottomTabやStackのScreenのoptionでheaderLeft, Rightにreact Nodeを置ける。
- navigation.setOptionsを使えばcomponent上で設定することもできる。

公式ドキュメント

https://reactnavigation.org/docs/header-buttons/

# Stackの場合の例
```
const Stack = createStackNavigator

<Stack.Navigator>
  <Stack.Screen
    name='Hoge'
    component={HogeScreen}
    options={{
      headerRight: () => (ここにReact Nodeを入れられる)
    }}
  >
</Stack.Navigator>
```

BottomTabもStackの部分が変わるだけで同じように作れる。

# navigationを使いたい場合
ここではnavigationとroutesを使える。
```
options={({navigation, route}) => {
  headerRight: () => (ここにReact Nodeを入れられる&naigation, routeも使える)
}}
```

# component上で設定したい場合
component上で作っているonPressのfunctionだったり、component上の変数をheaderのボタンから操作したい場合もあるかと思います。
その場合はnavigator.setOptionsというものが使えます。
```
const YourScreen = ({navigation}) => {
  useEffect(() => {
    navigation.setOptions({ここにoptionsを入れられる})
  }, [])

  return ...
}
```
のようにすればマウント時にheaderのButtonを設定したりできますし、もちろん他のイベント時に使うこともできます。

例えばヘッダー上の「編集ボタン」を押すと、ヘッダーとスクリーンの表示が切り替わる機能なんかはよく見かけますが、そのような機能の作成時に有効です。
hetemlというレンタルサーバーにLaravelをDeployerでデプロイしたときの設定

## hetemlというレンタルサーバーにLaravelをDeployerでデプロイしたときの設定

Laravelを使うレベル感の人はAWSなどが多いだろうと思いますが
hetemlというレンタルサーバーの情報は少ないので記しておきます。

```php:deploy.php
<?php
namespace Deployer;

// vendor/bin/dep deploy production

require 'recipe/laravel.php';
// require 'recipe/npm.php';
// Config

// Project name
set('application', 'super_cms');

set('repository', 'git@github.com:sasasa/super_cms.git');

set('git_tty', false);
set('release_use_sudo', false);
// set('use_sudo', false);
add('shared_files', ['.env']);
add('shared_dirs', ['storage']);

// Writable dirs by web server
add('writable_dirs', ['bootstrap/cache', 'storage']);
// add('writable_dirs', []);
set('allow_anonymous_stats', true);

set('deploy_path', '/home/users/2/sasasasa/{{application}}');

set('release_name', function () {
    return (string) run('date +"%Y%m%d%H%M%S"');
});


// Hosts
host('ssh-sasasasa.heteml.net')
    ->IdentityFile('~/.ssh/bitbucket/id_rsa')
    ->stage('production')
    ->user('sasasasa')
    ->set('http_user', 'HetemlUser')
    ->set('deploy_path', '/home/users/2/sasasasa/{{application}}')
    ->port(2222)
    ->set('branch', 'main')
    ->addSshOption('StrictHostKeyChecking', 'no')
    ->addSshOption('UserKnownHostsFile', '/dev/null')
    ->set('writable_use_sudo', false)
    ->set('writable_mode', 'chmod')
    ->set('shell', '/bin/bash -ls');

// Tasks
task('deploy', [
    'deploy:info',
    'deploy:prepare',
    'deploy:lock',
    'deploy:release',
    'deploy:update_code',
    'deploy:shared',
    'deploy:vendors',
    'deploy:writable',
    'artisan:storage:link',
    'artisan:view:cache',
    'artisan:config:cache',
    // 'artisan:optimize',
    'deploy:symlink',
    'deploy:unlock',
    'cleanup',
]);

task('build', function () {
    run('cd {{release_path}} && build');
});


// [Optional] if deploy fails automatically unlock.
after('deploy:failed', 'deploy:unlock');

// shared/.envを.env.{stage}で上書きする
task('overwrite-env', function () {
    $stage = get('stage');
    $src = ".env.${stage}";
    $deployPath = get('deploy_path');
    $sharedPath = "${deployPath}/shared";
    run("cp -f {{release_path}}/${src} ${sharedPath}/.env");
});
after('deploy:shared', 'overwrite-env');

// Migrate database before symlink new release.
before('deploy:symlink', 'artisan:migrate');

```
Markdown記事中の$文字表示のあれこれ

# 概要<br>
Markdownで記事を書くときに、\\$を記述する必要があり、そのまま記述してもうまく表示されませんでした。結論から言いますと、\\$の前に\をふたつ続けて書くとうまく表示されます。


# 試してみたケース
## (1)一行にひとつの$を書いたケース(成功例)
``` :記述例
この行は$・・・・の行です。

``` 

表示例
この行は$・・・・の行です。
``` :結果 
この場合は正しく表示されます。但し、次の行との間は空白行を
ひとつ入れます。
``` 
## (2)複数行に$を入れたケース(失敗例)
``` :記述例 
複数行に$を入れたケース
複数行に$を入れたケース
複数行に$を入れたケース

``` 

表示結果
複数行に$を入れたケース
複数行に$を入れたケース
複数行に$を入れたケース

``` :結果　 
改行が無いと、上の2行には$がなく、3行目には$があります。
各行に改行があれば$は表示されます。
```

## (3)各行に改行を入れたケース(成功例) 
``` :記述例 
複数行に$を入れたケース

複数行に$を入れたケース

複数行に$を入れたケース
``` 
表示例
複数行に$を入れたケース

複数行に$を入れたケース

複数行に$を入れたケース


``` :結果
各業に改行があると記述どおり$は正しく表示されます。 
```
 
## (4)各行に複数の$があるケース(失敗例)
``` :記述例
複数行に$を入れたケース$$$
複数行に$を入れたケース$$$
複数行に$を入れたケース$$$
``` 
表示例
複数行に$を入れたケース$$$
複数行に$を入れたケース$$$
複数行に$を入れたケース$$$

``` :結果
表示例のように、正しく表示されていません。
``` 
## (5)$の前に\をふたつ続けたケース(成功例)
``` :記述例
複数行に\\$を入れたケース\\$\\$\\$
複数行に\\$を入れたケース\\$\\$\\$
複数行に\\$を入れたケース\\$\\$\\$
``` 
表示例
複数行に\\$を入れたケース\\$\\$\\$
複数行に\\$を入れたケース\\$\\$\\$
複数行に\\$を入れたケース\\$\\$\\$



``` :総合結果
ひつの文章の中に複数の$を記述する場合は、すべての$の前に\\(エスケー
プ文字)をふたつ続けて書くと正しく表示されました。
改行のあるなしは関係ありませんでした。
``` 

# あとがき
いろいろと試行錯誤しましたが、これで、文章の中に$.ajax()の記述することができました。

# 追記

@Nabetani様からコメントがあり、バッククオートで挟む書き方を教えていただきました。
データを入れるだけで簡単にそれなりの予測をするライブラリを作る(2022.5.9)

# 背景：AutoMLを作りたい
機械が得意な事は機械に任せたい私は、データを入れるだけで上手い具合に処理してくれる物を作りたいと思っています。だいぶ前からAutoMLの存在を知っていて、それを理解して作りたいと前々から思っていました。機械的に処理すると言っても、それを作っているのは人間なので結局、人間的な物になるんだと思っています。要は作る人間がどこまで考え抜いているかだけの違いで、単にすごい物を作りたいのか、人間が安全に使える物を作りたいのかに振られやすいと思います。
# 方法：GitHubにあげて使える様にする
今回実装するのは、LightGBMとLabelEncoding, K-Foldです。ライブラリはそのまま使います。メソッドは、1.説明変数と目的変数のリストを抽出する「devide_tr_ob関数」、2.全てのカテゴリカルデータをラベルエンコーディングする「MyLabelEncoding関数」3.データをK-Foldで分割しLightGBMのデータセットに収める「LGBM_K_DataSet関数」4.学習を行う「LGBM_train関数」の4つを用意しました。よろしければ、ご自由にお使い下さると嬉しいです。改善のリクエストなどありましたら大変助かります。
## ライブラリのインストール
GitHubから```git clone```します。
```Python
!git clone https://github.com/ShinyRyo/mymojule.git
```
## データの読み込み
今回はkaggleのspaceship titanicのデータを使わせて頂きます。kaggleのnotebookで実行しています。今回は分かり易くするため3つのカテゴリカルデータを落としています。
```Python
import pandas as pd
data_path="/kaggle/input/spaceship-titanic/"
train=pd.read_csv(data_path+'train.csv')
test=pd.read_csv(data_path+'test.csv')
train1=train.drop(['PassengerId','Name','Cabin'],axis=1)
test1=test.drop(['PassengerId','Name','Cabin'],axis=1)
```
## モデルインスタンスの作成
先程インストール(git clone)した自作モジュールをインポートします。インスタンス名はてきとうです。
```Python
from mymojule.MyLGBM import MyLGBM
a=MyLGBM(train1, test1)
```
## モデルの実行（前処理（ラベルエンコーディング、K-Fold、LGBMデータセットの作成）、学習）
```__call__```関数を使います。ラベルエンコーディング、K-Fold、LGBM.Datasetの処理後、学習を開始します。学習後のモデルはself.lgb_modelに返すようにしています。
```Python
a()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/1e93ba47-7bc4-1cf9-6509-e2bc2f45c43e.png)

## 予測
self.lgb_modelでpredictします。self.lgb_modelに学習済みモデルが返されているので、predictメソッドを使えます。テストデータも前処理した物を使いたいので、self.testを使います。
```Python
pred=a.lgb_model.predict(a.test1)
```
## 後処理
回帰分析のモデルなので、predictはfloatで出てきます。今回のタスクではTrue, Falseの二値分類にしたいです。ここは適当に平均値より大きければTrue、それ以外はFalseにします。
```Python
import numpy as np
pred2=[True if i > np.mean(pred) else False for i in pred]
```

# 結果：2つのコンペに対応しました
回帰問題だけですが、目的通りラベルエンコーディングしてLightGBMで学習出来ました。2つのコンペとは言っても一つは分類問題でしたので、後処理をしました。無事投稿でき、評価も付きました。

# 感想：上手くいかない時は初めからやってみるのに限る
今回はクラスの```__init__```関数と```__call__```関数を理解して実装出来ました。使い方が分かっても、使いこなせるのは別でデバッグにかなり時間がかかりました。1つの方で上手くいっても、別の課題に使うと別の問題が出てきて、エラー場所の特定や対応に苦労しました。ともあれ、自分の作りたい物に近付いてる感じがして楽しくなっています。

# 課題
1. ノーマルなモデルとの差を明確にしていない
1. PyPIに上げてアップデートしていきたい
1. 更新に時間が掛かり過ぎる

# 関連
[GitHubから自作モジュールを使ってみる](https://qiita.com/tan0ry0shiny/items/70da22955b44b8c03829)
[自作モジュールをPyPIに登録する](https://qiita.com/tan0ry0shiny/items/c04ccdf840d198d2759e)
react nativeのButtonのスタイルを変更できないという話

# 概要
Button内の文字のスタイルは変更できないし、marginをつけたりもできず、空白を作るのにも別のコンポーネントで囲う必要がある。
→Touchable Opacity + Textなら割と自由に変更できる。

# Buttonコンポーネントはスタイル変更がほとんどできない
react nativeにもとからあるButtonも、emotion/nativeのstyled.Buttonも同じで、あらゆるスタイル変更が効かなくて困った。
```
const StyledButton = styled.Button`
  margin: 5%;
  color: red;
  background-color: blue
`
```
こんな風に書いてもうんともすんとも言わない、、、

# 解決策
Buttonコンポーネントに求められているのはonPress要素の設定なので、それさえできれば他ので問題ない。
それを解決してくれるのが、同じくonPressを設定できるTouchableOpacityコンポーネント
```
<StyledButton onPress={yourOnPress}>
  <StyledText>hoge</StyledText>
</StyledButton>

const StyledButton = styled.TouchableOpacity`
  margin: 5%;
  background-color: blue
`

const StyledText = styled.Text`
  color: red;
`
```
Textと組み合わせればあらゆるスタイル変更が自由自在になる。
Buttonよりこっちの方が拡張性高いみたい。

ありがたい
Excel便利だな

教えてもらったことを記すのコーナーです

ExcelのEXACT関数というものです
文字列Aと文字列Bの比較ができます
```
=EXACT(A1,B1)
```
と書くと、A1セルとB1セルの内容がおんなじか、違うかを比較して下さる感じです

どんな時に使うかというとテスト工程で目視で確認というのがしんどい時に使います

A1セルに設定値、B1セルに実機の値、C1セルにEXACT関数を記載し、エンターキーを押すと、
C1セルTRUE（A1セルとB1セルの値は一緒）かFALSE（A1セルとBセルの値は違う）という結果が出ます
useStateで配列を管理するときの注意 ～中身の変化には気づいてくれない

# 概要
配列の中身の変化だけでは反応してくれない。
→新しい配列としてset○○に入れる必要がある。
配列をスプレッド構文で入れ直してあげればok。

# 想定例

たとえばカテゴリ選択ボタンみたいに、複数ボタンがあって、どのボタンがactivate中かをすべてのボタンについて管理するという場合。
ボタンごとにuseStateを使ってもいいが、コードの長さや拡張性の観点から、すべてのボタンの状態を1つの配列で管理してしまった方が楽。
```
const [isAvtivates, setIsActivates] = useState(Array(buttons.length).fill(true))
```
のような想定。

# 失敗例
```
const onPressButton = (idx: number): void => {
  isActivates[idx] = !isActivates[idx];
  setIsActivates(isActivates);
};
```
これがなぜだめかというと、isActivatesの中身に変更はあるが、isActivatesという配列自体は変わっていないからです。
useStateは配列やオブジェクトの中身の変化までは見てくれず、この書き方だと変化したことに気づいてくれないからだそう。

（詳しい話はこちら：https://ja.reactjs.org/docs/hooks-reference.html#bailing-out-of-a-state-update）

オブジェクトの場合の対応はこちらの記事が参考になります。

https://qiita.com/daitai-daidai/items/5752b308e5e0f9457352

# 正解
```
const onPressButton = (idx: number): void => {
  isActivates[idx] = !isActivates[idx];
  setIsActivates([...isActivates]);
};
```
スプレッドしてしまえば新しい配列に変わるので、実はこの違いだけで解決できる。
Ethereumのアドレス生成過程の理解のためにPythonでハッシュ関数keccak256を試す

# はじめに
仮想通貨のウォレットを持っていると、不規則な長い文字列をよく見ると思います。
Ethereumで使われるアドレスの生成過程について調べている中で、下記のような記述を見つかりました。

1.秘密鍵からECDSAで公開鍵（64バイト）を生成
2.公開鍵をハッシュ関数Keccak-256に通し文字列（32バイト）を得る
3.最初の12バイトを消し20バイトのアドレスになる
4.そのアドレスにprefixの0xを加えることで最終的なアドレスを得る(0x5eD8Cee6b63b1c6AFce3AD7c92f4fD7E1B8fAd9F)

参考：[秘密鍵から公開鍵そしてアドレスが生成されるまでの流れ【仮想通貨】](https://zoom-blc.com/from-private-key-to-address)
keccak256がどのような関数なのか確かめるために触ってみました。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [keccak256とは](#Chapter1)
1. [Pythonによるkeccak256によるハッシュ値の出力](#Chapter2)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# keccak256とは
keccak256はEthereumが用いる標準ハッシュ関数です。
読み方は(ケチャック)と読みます。
keccak256によるハッシュ化はpycryptodomeというライブラリを用いることで実装できるそうです。
https://pypi.org/project/pycryptodome/
今回はGoogle Colaboratoryでkeccak256によるハッシュ関数の出力を行いました。

<a id="#Chapter2"></a>
# Pythonによるkeccak256によるハッシュ値の出力
```python
#ライブラリのインストール
!pip install pycryptodome
```

```python
from Crypto.Hash import keccak
import binascii

keccak256 = keccak.new(data=b'hello', digest_bits=256).digest()
print("Keccak256:", binascii.hexlify(keccak256))
```

出力として下記のハッシュ値が出力されました。
```
Keccak256: b'1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8'
```

<a id="#reference"></a>
# 参考文献
- [秘密鍵から公開鍵そしてアドレスが生成されるまでの流れ【仮想通貨】](https://zoom-blc.com/from-private-key-to-address)
- [リンクテキスト](URL)
JupyterLab で ipywidgets からは popup とか javascript 実行できないメモ

## 背景

JupyterLab で ipywidgets で作ったボタン押したらなんかメッセージ popup したい...

できなかった...

https://stackoverflow.com/questions/60166968/how-to-create-a-popup-in-a-widget-call-back-function-in-ipywidgets

ipywidgets 内だと, javascript など呼べませんでした(log に なんか object が表示されるだけ)

あきらめるしかないです :cry:

## その他

ipywidgets 経由だと, `print` などは log に出ます.

https://blog.amedama.jp/entry/ipywidgets-jupyter-ui

`widget.Output` 使いましょう.
ABC250 記録


# Atcoder Beginner Contest250</FONT>

### A - [Adjacent Squares](https://atcoder.jp/contests/abc250/tasks/abc250_a)
**【思考過程】**
    1. 問題文見てもよく分からなかったので参考の図をみる
2.  隣合うタイルがあれば答えを1足せばいいっぽそうなのでif文4個書く
```diff_c
int main()
{
	[[maybe_unused]]long long int i=0,j=0,h,w,r,c;
    cin >> h >> w >> r >> c;
    if(r-1!=0)
    {
        ans++;
    }
    if(c-1!=0)
    {
        ans++;
    }
    if(c+1!=w+1)
    {
        ans++;
    }
    if(r+1!=h+1)
    {
        ans++;
    }
    cout << ans;
}
```
ごり押し解法になってしまったけどもうちょっと綺麗にかけたかな？まあACしたのでよし。
　　　　
　　　　
### B -  [Enlarged Checker Board](https://atcoder.jp/contests/abc250/tasks/abc250_b)

**【思考過程】**
    1. これも問題文見てもよくわからなかったのでサンプルみる
2. マス目Xを白黒交互に出力すればよさそうなので、カウンタを$A、B$で割った答え(Xを何回出力したか)を2で割った余りで分岐させればよさそう
3. サンプルで試してみて問題なさそうなので提出

```diff_c
int main()
{
	[[maybe_unused]]long long int i=0,j=0,n,a,b;
    cin >> n >> a >> b;
    for(i=0;i<n*a;i++)
    {
        if(i/a%2==0)
        {   
            for(j=0;j<n*b;j++)
            {
                if(j/b%2==1)
                {
                    cout << '#';
                }
                else
                {
                    cout << '.';
                }
            }
        }
        else
        {
            for(j=0;j<n*b;j++)
            {
                if(j/b%2==0)
                {
                    cout << '#';
                }
                else
                {
                    cout << '.';
                }
            }          
        }
        cout << endl;
    }
}
```
　　　　
### C -  [Adjacent Swaps](https://atcoder.jp/contests/abc250/tasks/abc250_c)


**【思考過程】**
    1.  愚直にシュミレートしていっても計算量は大体$2×10^5\$なのでその方針でやってみる 
    2. 数字の場所が次々変わっていくので位置の情報が必要そう。$pair$を作って$first$に数字、$second$に位置を入れてあとからソートすれば行けそうなんで実装して試す
3.あれ？なんか合わない...。ちょっと待てこれじゃ隣の数字がずっと固定になるんだが。pairは情報二つ管理できてもアクセスはできないんだね...（ここまで15分ぐらい）。というわけで位置を管理する配列をつくる（実装に大体45分）
```diff_c
int main()
{
	[[maybe_unused]]long long int i=0,j=0,n,p[210000],p1[210000];
    cin >> n >> q;
    rep(i,201000)
    {
        p[i]=i;
        p1[i]=i;
    }
    for(i=1;i<=q;i++)
    {
        cin >> x;
        if(p1[x]!=n)
        {
            c=p[p1[x]];
            p[p1[x]]=p[p1[x]+1];
            p[p1[x]+1]=c;
            p1[x]++;
            p1[p[p1[x]-1]]--;
        }
        else
        {
            c=p[p1[x]];
            p[p1[x]]=p[p1[x]-1];
            p[p1[x]-1]=c;
            p1[x]--;
            p1[p[p1[x]+1]]++;
        }
    }
    for(i=1;i<=n;i++)
    {
        cout << p[i] << " ";
    }
}
```
解法はすぐに思い浮かんだけど実装に時間がかかりすぎた...。
ややこしい実装は紙に書いて整理してからやったほうがよさそう。~~これ書いてるとき頭爆発しそうだったし~~
コンテストが終わってタイムラインを見ていたら、どうやらこういう問題はmap(データの紐づけができる)を使うと楽らしい。名前だけ知ってるけど全然勉強してないからやっとかないとなあ。

最終結果：3完600点、93分31秒、3593位、パフォーマンス673
レート変動：500→518（+18）

600パフォが続く日々。今回は実装でつまずいたのがよくなかったかな。思考を整理して紙に書く癖をつければ700ぐらい出せそうな気がする。D問題も見た感じ解けそうではあったし、Cが茶色下位程度ならA~Cまで30分ぐらいで解いてDを考える時間をつくっていきたい。
【基本情報技術者】クライアントサーバシステム

基本情報技術者試験の分野「クライアントサーバシステム」についてご紹介いたします。
## クライアントサーバシステム
コンピュータを**サーバとクライアントに分け役割分担をして分散してデータ処理をして運用する仕組み**のことです。 サービスを要求するクライアントとサービスを提供するサーバで構成します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/466e6b7e-2819-ed27-d89b-c46ae4b7b357.png)
**・3層クライアントサーバシステム**
3層クライアントサーバシステムとは、クライアントサーバシステムの機能を**プレゼンテーション層、ファンクション層、データ層**の3つに分けて構成されたシステムを指します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/709f58f4-f456-5511-1661-4718b2f5dd3e.png)
**・ストアドプロシージャ**
クライアントサーバシステムにおいて、データベースにアクセスするときに、クライアントとサーバ間の通信負荷が問題になります。その解決策が、ストアドプロシージャで、**利用頻度の高い命令群をあらかじめサーバ上に用意しておくこと**で、負荷の軽減ができる。
## サーバの仮想化
サーバの仮想化は、**1台の物理サーバ上で複数の仮想的なサーバを動作させたり、複数の物理的なマシンを一つのサーバとして扱ったりするための技術**です。物理サーバの台数を減らして、設置スペースやハードウェアのコストを削減することができます。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655909/14e3a286-d579-3d8f-9ee0-63c9ccf15a6a.png)

**・仮想化の形態**
| 名前 | 説明 |
|:-------:|:--------|
|**ホスト型**|ホストOS上で仮想化ソフトウェアを動作させ、その上で別のゲストOSを動かす。|
|**ハイパバイザ型**|ハードウェア上でハイパバイザという仮想ソフトウェアを動作させ、その上で複数のゲストOSを動かす。クラウドサービスで採用されており、自由度は高いが他のマシンに移行しにくい。|
|**コンテナ型**|OS上にコンテナエンジンという管理ソフトウェアを動作させ、その上でコンテナと呼ばれる実行環境を動作させる。OSは共通のため自由度は高いが、移行性は高い。|
## シンクライアント
クライアントサーバシステムの一種で、**サーバ上でアプリケーションやデータを集中管理することで、クライアント端末には必要最低限の機能しかもたせないシステム**のこと。Thin(シン)には、「薄い」という意味があります。シンクライアントシステムを実装するための仕組みの一つに、**VDI**があります。

**・VDI**(Virtual Desktop Infrastructure)
**クライアント端末のデスクトップ環境を仮想化されたサーバ上に集約して、サーバ上で稼動させる仕組み。**
通常クライアント側で行う処理をサーバ上で行い、**利用者のクライアント端末には、サーバ上で実行されているデスクトップ環境の画面だけが転送**されていく。
チーム開発でのgitの使い方、流れまとめ

今まで基本独学でやってきたけど、チーム開発をする機会に恵まれたので、改めてそこで必要な流れをまとめました。
自分のメモ代わり。

# チーム開発でのgitの流れ

## 1.リモートのdevelopを取ってくる
初めてならclone。
以降はpull。
developブランチにいることは確認しておきましょう。

## 2.ローカルで作業ブランチを切って移動
現場で命名規則があれば従いましょう。

### 作業ブランチ切り忘れて開発しちまった！
addしてなければ大きな問題はない。

https://qiita.com/k6i/items/edc69a806095e4fc489c


```
git checkout -b yourBranchName
```
などで移動してしまえば問題ない。

## 3.開発したらaddする
```
git add -A
```
どこのブランチにいるかは確認しておきましょう。
心配なうちはstatusも見とくといい。

### addを戻すには、、、
https://qiita.com/yukure/items/89562e5eb1d03995dc5b

ご心配なく、ちゃんと戻せます。
最初はちょっとドキドキしますが、addを取り消すだけなら書いたものが消えてしまうとかでもないので安心して取り消しましょう。

## 4.commitする
```
git commit -m "your message"
```
で良い感じのメッセージをつけてあげましょう

### commitを戻すときは、、、
https://qiita.com/shuntaro_tamura/items/06281261d893acf049ed

こちらもresetでできます。
resetはオプションによってすることが全然違うので気を付けつつ、使いながら覚えましょう。

## 5.リモートの最新状態を取ってくる
まだpushはしません。
自分が開発している間に他の人も進めてるかもしれないからです。

作業ブランチにいる状態で、
```
git pull --rebase origin develop
```
とすれば、pullとrebaseを一気にやってくれます。
ここでconflictがあったら解消してまたcommitです。

## 6.リモートにpush
conflictがなくなったらpushしちゃって大丈夫です。
```
git push origin yourBranchName
```
ですね。
作業ブランチにpushして、developやmain（master）にはpushしないようにしましょう。

## 7.プルリクエストを出す
github上での操作です。
ちょうど今pushしたのが来ていると思うので、画面に従ってプルリクエストを作りましょう。

## 8.コードレビューを受ける
プルリクエストをつくったら連絡するなりしてコードレビューを受けましょう。

### 修正があれば3〜6をして更新する
修正し、add、commit、（rebase）、pushです。修正点がなくなるまで繰り返しましょう。

github上のプルリクエストのcommitsを見て、pushしてきた最新のcommitがちゃんと反映されているかは見ておくといいです。
ちゃんと来ていたら再度レビューしてもらいましょう。

## 9.developにmergeする/してもらう
現場によると思います。
自分でするならプルリクエストのページからマージボタンを押すだけです。

## 10. 1に戻って繰り返す

# まとめ
- remoteの最新状態を取得
- 作業ブランチを切る
- add, commit
- rebase
- push
- pull requestを作成
- レビュー&修正（修正をpush）
- merge
- 最初に戻る
【Laravel】外部キーがデフォルトでないリレーションの定義

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 外部キーがデフォルトでないリレーション定義
通常は```Eloquent```が```GiftHistory```モデルに```user_id```カラムがあると想定するが、
今回のように外部キーがデフォルトと違う場合は、```belongsTo```メソッドの2番目の引数としてカスタムキー名を渡す。


```app/Models/GiftHistory.php
public function giver(): BelongsTo
{
	return $this->belongsTo(User::class, 'giver_id');
}

public function receiver(): BelongsTo
{
	return $this->belongsTo(User::class, 'receiver_id');
}
```

コンソールで実行するとリレーションで取得できるようになる。
```
GiftHistory::first()->giver()
=> Illuminate\Database\Eloquent\Relations\BelongsTo

GiftHistory::first()->receiver()
=> Illuminate\Database\Eloquent\Relations\BelongsTo
```

## 参考

https://readouble.com/laravel/9.x/ja/eloquent-relationships.html
react nativeで横並び、折り返し、等間隔の配置を実現するときにハマったこと nth-childもgapもだめ

webのreactと同じノリで書こうとしたら、ネイティブアプリの洗礼を受けた話。

# 基本、前提
普通にcssで実装するなら、、、

- 横並び→flex-directionのraw
- 折り返し→wrapを設定
- 等間隔→space-around、space-between、もしくはgap

この辺を使えばよさそうです。

# space-around、space-betweenの問題
wrapした時に行ごとに等間隔にしてしまって不恰好になる。
例えば5個の要素があって、1行に3つごとおきたい場合、
```
.list-wrapper {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.list-item {
  width: 30%;
}
```
などとすると3個の行と2個の行に分かれる。
その時3個は等間隔になるが、2個はその2個で等間隔になるので、5個の間隔がバラバラになってしまう。
（この場合1行目は間隔5％だけど、2列目は30％空いてしまう）

結論：wrapと組み合わせるならspace-around、space-betweenは使わない方がいい。

# 解決1（失敗）
gapを使おう
https://developer.mozilla.org/ja/docs/Web/CSS/gap
```
.list-wrapper {
  gap: 1em; 
  gap: 10px 20px; // 縦 横
}
```
のようにすると自動的に間隔を付けてくれる。
（もちろん端にはつけず、要素の間だけつけてくれる）

## react nativeでgap使えない問題
やってみたらエラーでてどうやら使えないものだということを悟った、、、

# 解決2（失敗）
widthとmarginだけで解決しよう

例えば3分割したいなら、
30% 5% 30% 5% 30%で分ければ良いので
```
.list-item {
  width: 30%;
  &:not(:nth-child(3n)) {
    margin-right: 5%;
  }
}
```
という実装ができる。

## react nativeでnth-child使えない問題
何とこっちも使えない。
エラーが出るのではなく、単純にnth-child部分が無視された表示になった。
どうやらnth-childのみならず、last-childとかも含めて使えないらしい。

ということでそれにあたるロジックを自分で書く必要があった。

# 解決3（成功）
今回はstyled-componentsでの実装。

ロジックはcss内に書くこともできるのかもしれないが、なんか上手くいかなかったのでjsx/tsx内で解決した。

方針としては解決2と似ていて、nth-childの代わりにmap時のkeyに使われるidxを使って分岐させる処理を書く。

まずはnth-childしたかったcomponentにmarginRightというpropsを追加。
```
{datas.map((data, idx) => {
  return (
    <YourStyledComponent marginRight={idx % 3 === 2 ? '0%' : '5%'}>
    </YourStyledComponent>
  )
})}
```
と三項演算子で分岐処理を実装。
idxは0スタートなので、こうすることで3n番目の要素のみmarginRightを0にできる。

これをstyled componentで受け取る。
```
const YourStyledComponent = styled.View<{marginRight: string}>｀
  width: 30%
  margin-right: ${({marginRight}): string => marginRight}
｀
```
これでいけました。
pythonでパッケージのVersion確認

パッケージ，ライブラリ，モジュールのバージョン確認の方法をいつも調べてるので，めもってゆく～

### ターミナルでpythonを起動した場合
1. import hogehoge
1. hogehoge.__version__を表示する（printなど）

```python:terminal（numpyの場合）
~/ python 
>>> import numpy
>>> print(numpy.__version__)
```
### pipを使う場合
- listでパッケージ名とバージョンを一括表示
```terminal:terminal
pip3 list
Package         Version
--------------- -------
cycler          0.11.0
fonttools       4.33.0
kiwisolver      1.4.2
matplotlib      3.5.1
numpy           1.22.3
packaging       21.3
Pillow          9.1.0
pip             22.0.4
       ...
```
*自分の環境ではpip3でしたが、環境によってはpipかもです。
- showで特定のパッケージのバージョンを確認
```terminal:terminal
pip3 show hogehoge
```
自分はpipが手軽なのでよくそれを使います。
他にも見つかれば随時追加していきます。
システムの信頼性評価

## システムの評価特性
<b>信頼性・可用性・保守性・保全性・安全性の頭文字の<font color = blue>RASIS</font>がある。
<font color = blue>(R)信頼性</font> - 要求された機能を、規定された期間実行する特性
<font color = blue>(A)可用性</font> - 要求されたサービスを、提供し続ける特性
<font color = blue>(S)保守性</font> - 故障時に容易に修理できる特性
<font color = blue>(I)保全性</font> - 情報の一貫性を確保する特性
<font color = blue>(S)安全性</font> - 情報漏洩や紛失、不正使用を防止する特性。
## システムの評価指標
### MTBF
<b><font color = blue>平均故障時間</font>のこと。システムが故障してから、次に故障するまでの時間。
### MTTR
<b><font color = blue>平均修理時間</font>のこと。システムが故障して、修理に要する時間。
### 稼働率
<b>システムが正常に動作している時間の割合。
MTBF ➗（MTBF + MTTR）で求まる
## 複数システムの稼働率
### 直列システムの稼働率
<b>AとBがあるとすると、全体が稼働するのは二つとも正常な時
稼働率は、AとBの稼働率を乗算すると求まる。
### 並列システムの稼働率
<b>AとBがあるとすると、全体が稼働するのは、少なくとも一方が稼働しているとき。
稼働率は1-(1-a)(1-b)で求めれる。
## バスタブ曲線
各装置の故障率と時間の関係性をグラフにしたときの形。
<b>偶発故障期間に定期検査などで、摩耗故障期間までの時間を延長できる。
![glossary_bathtub001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/7b78647f-4789-089e-81ed-c502e9e5c039.jpeg)
&&・||「ウチらってさぁ。よく誤解されんだよね…」【JavaScript】

## はじめに
最近まで、JavaScriptで使う論理演算子「&&」と「||」の意味を正確に理解していないことにようやく気づいたWEBエンジニアのmasakichiと申します。

すでに同じようなQiita記事もたくさんありましたが、個人的にかなり大事な基礎だと感じたため、僕みたいな初級エンジニア同士にも知って欲しいと思い、改めて記事にしてみました。

## &&の意味
例えば、下記のような条件式があったとする。

```javascript
let a = true;
let b = true;

if(a && b){
  alert("This is true") 
}else{
  alert("This is false");
}
//This is true
```

`&&` はここでは「`true`, `false` という真偽値の論理積(AND)」として利用されていますが、 `&&` はこれだけの用途ではなく、JavaScriptでは気をつけるべき挙動があります。

以下MDNの解説

>この演算子は左から右に向けて評価した際に最初の偽値のオペランドに遭遇したときにはその値を、またはすべてが真値であった場合は最後のオペランドの値を返します。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND

説明が難しいですが、要するに

2022/5/9 テキスト修正
- 左の値から順番にtruthyかfalsyかを確認
- 確認した左の値がfalsyならその時点で左の値を返却して終了
- truthyなら右隣の値を返却

falsy な値は、undefined, null, false, 数値0(0や0.0), 空文字列("")があります。

※@shiracamus さんにご指摘いただき上記修正いたしました。ありがとうございます！

ということ。

![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/8afb9a1e-955f-1c6b-a705-46271b0d4b88.jpeg)


ちなみに、以下のように&&でつなぐ値が増えても流れは同じ。
左から順番にチェックしていき、最終的にfalse値か、一番右の値（下記の場合cの値）を返却する

```javascript
let a = true;
let b = true;
let c = true;

if(a && b && c){
  alert("This is true") 
}else{
  alert("This is false");
}
//This is true
```


## | | の意味
同様に「または」の意味として捉えられがちな論理演算子`||`も考え方は一緒。

ただ、`&&`とは反対に 左の値確認していったときに**falsyなら右の値を返す**というふうになります。

![image2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/3fd8e327-0663-d783-095a-00c666231624.jpeg)

## 応用例〜Booleanを返さない論理演算子〜
上記の理屈を理解すると例えば下記のようにinputエリアに何も入力されなかったときに変数に入れたい値を1行で実装することができる

**ポイントは、論理演算子「&&」や「||」は必ずBooleanを返さなくてもいいということ**

```html
    <input type="text" id="inputName">
    <button id="button">ボタン</button>
    <script>
        const button = document.getElementById("button");
        const inputName = document.getElementById("inputName");
        button.addEventListener("click",()=>{
            const name = inputName.value || "noName";
            console.log(`こんにちは、${name}さん`);
        });
    </script>
```

![image3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006362/f02d9625-0753-89fa-1a79-adc57335cbf0.jpeg)
BizRobo! Desktop Automationのストリームポートについて

Desktop Automationがデフォルトで使用するストリームポート49999はDesktop Automationサービスが起動しているだけではLISTENING状態になっていない。

ロボット等が接続に来た時にNode.exeのプロセスが起動してLISTENING状態になる。
また、接続が切れれたときNode.exeのプロセスが終了してLISTENING状態ではなくなる。

そのため、Test-NetConnection等でポート状態を確認してもNGになるので注意。
lessコマンドに関する面白い権限昇格

Hack The Box Traverxecにて。

`less`コマンドに関するとても面白い権限昇格があったのでメモっておきます。

# 現状

次のコマンド**だけ**なにもパスワードを入力せずに実行できる：

```
sudo journalctl -n5 -unostromo.service
```

実行した様子：

![execjctl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659122/9c491470-5ae0-2d30-6419-298f6da9cb81.png)

ゴールは、ユーザdavidからrootへ権限昇格すること（ただしdavidのパスワードは不明）。

# 実際に権限昇格してみる

以下のコマンドはどれも実行時にパスワードを求められる：

```
sudo journalctl -n3 -unostromo.service
sudo journalctl -n5
sudo journalctl -n 5 -unostromo.service
sudo journalctl
```

また、その結果をパイプに渡しても

```
sudo journalctl -n3 -unostromo.servic | less
sudo journalctl -n3 -unostromo.servic | cat
```

パイプより後のコマンドはdavid権限なのでprivescには無意味。

<br><br>

ふつう`journalctl`コマンドを引数なしでやるとページャ（`less`コマンドを使った状態）で表示される：
![pajer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659122/65841af5-ad4e-a551-1c57-5984fef77995.png)

この`less`コマンド実行状態で、`!/bin/sh`と入力すればシェルが起動する。

これを念頭において、davidからrootへの権限昇格を考える。

改めて、今（root権限で）次が実行出来る：

```
sudo journalctl -n5 -unostromo.service
```

`-n5`というのは**5行だけ表示という意味**（上の画像参照）。

だから普通に実行すれば上の画像のようにただ結果が5行分表示されるだけ。

要は、この`sudo journalctl`をページャ表示（つまりroot権限での`less`コマンド実行）させて、そこで`!/bin/sh`とすればrootシェルが得られる。


どうするか...


答えは、**ウィンドウを小さくしてページャ表示されるようにする**。

つまり、**ウィンドウの高さを5行分表示出来ない高さにしてやれば**ページャ表示される：
![getpajer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659122/699f2641-73a5-9e46-3961-a90bce203642.png)


あとはこの状態で`!/bin/sh`と打ち込んでroot権限のシェルがとれる。
システムの性能評価

## システムの性能指標
<b><font color = blue>スループット</font> - 単位時間あたりに処理される仕事の量。
<font color = blue>ターンアラウンドタイム</font> - 利用者が処理依頼をしてから、結果の出力が終了するまでの時間。
<font color = blue>レスポンスタイム</font> - 利用者が処理依頼をしてから、端末に結果が出るまでの時間。
### ベンチマークテスト
<b>システムの使用目的に合った標準的なプログラムを実行させ、その測定数値から処理性能を相対的に評価する方法。
<font color = blue>SPECint</font> - 整数演算の性能
<font color = blue>SPECfp</font> - 浮動小数点の性能
<font color = blue>TCPベンチマーク</font> - トランザクション処理を測定。磁気ディスクの入出力、DBMSの性能まで含め評価。
## MIPS
<b>１秒間に実行される命令数を百万単位で表したもの。
### 命令ミックス
<b>よく使われる命令をピックアップしてセットにしたもの
品質を継続的に上げ続ける方法

## はじめに
SREやフィールドエンジニア、運用保守エンジニアはプログラミングだけではなく本番環境へのデプロイや設定変更などのオペレーションを行うことも多いと思います。

本記事ではオペレーション品質を向上をし続けるために実践していることを5つのトピックにまとめました。細かく上げれば他にもいっぱいありますが、大きな要素を主に記載します。

１．練習・研修環境の充実
２．OJTの属人化脱却
３．インシデントもヒヤリハットも全部拾う
４．問題管理及び問題解決を継続的に行う
５．継続的教育

## １．練習・研修環境の充実

どんな業務でも練習できるなら練習して本番に臨めるに越したことはありません。容易に練習できる環境が整っていれば本番で本来の力も発揮しやすくなるでしょう。

##### ・壊してもすぐに元に戻せる環境
初級者はどうしても多くの失敗をしますので、その都度環境構築していたら大変です。壊してもすぐに元に戻せる、または何回でも同じことを繰り返し練習できる環境を準備し、トレーニングできる機会を増やしました。
##### ・使いたいときにすぐに使える環境
ちょっと空いた時間に練習したいとか、急に人が増たときなど都度練習環境を準備していると間に合わないため、いつでもすぐに使える環境を一定数準備しています。

※DBも含んだ環境のためDockerのようにモダンな仕組みではなく、仮想サーバのイメージバックアップを使ってます。(2022/05現在）

## ２．OJTの属人化問題からの脱却

OJTは業務を覚えるうえでよい方法だと思いますが、最大のデメリットとしてOJTトレーナーによって教える内容や教え方が異なり、その結果新メンバーの理解度や習熟度にも差が出てくる場合があります。このデメリットを解消するため以下の対策を実施しています。

##### ・OJT内容の標準化
研修が終わった後OJTを行いますが、複数いるOJTトレーナーに完全に任せてしまうと教え方にばらつきがでてしまいます。そのため、必ず教えるべきことをチェックリスト化し、新メンバーに必要事項を必ず伝えられるようにしています。
##### ・一人前とみなす基準の明確化
OJTトレーナーが新メンバーを一人前とみなす基準もあいまいになる可能性があるため、こちらもチェックリストを作り新メンバーが1人前となった基準をそろえ、誰がOJTトレーナーになっても一定のスキルがついたことを評価できるようにしました。

※こういった仕組みを整えることにより、OJTの属人化や品質のばらつきが発生しにくくなりました。

## ３．インシデントもヒヤリハットも全部拾う

##### ・報告しやすい仕組み、運用ルールの策定
作業報告のフォーマットやヒヤリハットの原因などMECEでわかりやすく、記入しやすいように整備し適時ブラッシュアップ。また、毎週かならず報告日を設けることによって報告漏れを防止します。

##### ・心理的安全性の確保
ヒヤリハットはインシデントや重大障害の種になるので、報告を積極的に推奨します。日ごろからヒヤリハットの報告を推奨することにより、インシデントの報告を報告しやすい体制を作り、原因を個人ではなく仕組みにあるという前提で問題解決に対する協議を行います。

※仕組みの簡素化や心理的安全性は全員が満足するように完全になるのは難しいですが、日々心掛け続けることを意識しています。

## ４．問題管理及び問題解決を継続的に行う

##### ・問題解決の方針をメンバーで協議
３で報告されたインシデントやヒヤリハットをRedmineでチケットとして管理し、関係者で再発防止の検討を行います。この際に大事にしているのは問題の本質が何なのかを見極め決して個人の問題にしないことです。仮に知識不足が原因の問題があった場合は、研修コンテンツの不足もしくは知識不足でも問題発生させないために手順書を修正できないか、と考えるようにします。

##### ・問題の分類を適切に行い、再発防止策を決める
関係者で協議し、汎用的な再発防止が必要の場合は手順書やチェックシートの修正、教育コンテンツへの追記を行うなどの対応を行います。また、個別環境ごとの特殊事情の場合は個別環境の管理情報へ追記するなどの方針を決めます。

##### ・問題解決状況をウォッチし継続的にリーダーやマネージャーがフォローする
問題解決状況はRedmineチケットを、リーダーやマネージャーが定期的にチェックし、進捗が良くない場合はフォローしたり担当の見直しなどを行います。

※ここはリーダーやマネージャーがどこまで徹底できるかという管理側の意思がかなり大事だと思ってます。

## ５．継続的教育

###### ・トラブルリカバリーハンズオン研修
どれだけ手順やチェックシート詳細化しても、想定外の事象は起こりトラブル発生をゼロにすることはできません。そのためトラブル事例を再現した環境を準備しトラブルリカバリーのハンズオン研修を行っています。

###### ・よくあるトラブル集をまとめ、1年に2回復習する機会を作る
Pマーク研修や避難訓練のようなものをイメージしていただくとわかりやすいと思いますが、エンジニア全員が定期的に受講する定期教育としてよくあるトラブル集ヒヤリハット集をまとめ、年に２回復習する機会を設けています。この際には座学だけではなくテストも実施することにより理解度チェックを行います。

※スポーツでもなんでも同じですが、エンジニアも基本は大事なので定期的に初心を振り返れるようにしました。技術的な内容ではなくよくある見落としや油断などを共有しています。

## その他
インシデント数/率やヒヤリハット数/率を可視化し品質が継続的に向上していることをメンバーや社内他部門にも実感として持てるようにしています。

## まとめ
どれも特別なことではなく当たり前のことばかりですが、こういった地道な活動を続けることによって担当者が入れ替わってもオペレーション品質を維持し続けられるように心がけています。
RAIDと信頼性設計

## RAID
<b>複数の磁気ディスクを組み合わせ、一台の仮想的な磁気ディスクとして扱うことで、アクセスの高速化や高信頼性を実現する。

RAIDの種類↓
<b><font color = blue>RAID0</font> - データをブロック単位に複数の磁気ディスク分散して書き込む(<font color = blue>ストライピング</font>)
<font color = blue>RAID1</font> - 磁気ディスク2台に同じデータを書き込む(<font color = blue>ミラーリング</font>)
<font color = blue>RAID3</font> - データをビット/バイト単位に複数の磁気ディスクに分散して書き込む。また、一台の磁気ディスクにパリティを書き込む
<font color = blue>RAOD4</font> - データをブロック単位に複数の磁気ディスクに分散して書き込む。また、複数の磁気ディスクにパリティを書き込む。

※パリティ - 磁気ディスクが故障した時に、データを修復するための情報
## 信頼性設計
システムの信頼性を向上させる設計手法
### フォールトアボイダンス
<b>構成要素の信頼性を高め、故障そのものを回避する設計。
### フォールトトレランス
<b>構成要素を冗長化して、故障が発生しても必要な機能は維持する設計。
また、システムが部分的に故障しても全体として必要な機能は維持するシステムのことを<font color = blue>フォールトトレランスシステム</font>という。
### フェールセーフ
<b>システムの一部が故障しても、危険が生じないような構造や仕組みを導入する設計。
故障した時は安全第一。
### フェールソフト
<b>故障が発生した場合、一部のサービスレベルを低下しても、運転を継続する設計。
### フールプルーフ
<b>人が誤った操作や取扱いができないような構想や仕組みを、システムに組み込む設計。
### エラープルーフ
<b>エラーの原因を除去し(<font color = blue>排除</font>)、人が行なっていた作業をシステム化し(<font color = blue>代替化</font>)、複雑な作業を簡単にする(<font color = blue>容易化</font>)。
さらに、異常を検知したら知らせ(<font color = blue>異常検出</font>)、ミスの影響範囲を最小限に抑える(<font color = blue>影響緩和</font>)
VueでsetIntervalを使用し、DOMに渡ってきたparameterを更新

`setInterval`を`mounted`内で呼んで`express`で取得してきた`parameter`を受け取りDOMを更新させる為に使用したコードです。
```api/index.ts
import express from 'express'

const handler = express()

handler.get('/parameters/:hogeId', parameters.get)
```
```api/parameters/index.ts
import { Request, Response } from 'express'
import { Hoge } from '../../lib/db'

export const get = async (req: Request, res: Response) => {
  res.json(await Hoge.findByPk(req.params.hogeId))
}
```
こちらを`Vue`の`script`内の`mounted`で呼びます。
```pages/index.vue
<template>

</template>

<script lang="ts">
import { setInterval } from 'timers'

@Component
export default class hoges extends Vue {
  async mounted() {
    this.parameter = await this.$axios.$get(
      `/api/parameters/${this.$nuxt.$route.params.hogeId}`
    )
    setInterval(async () => {
      this.parameter = await this.$axios.$get(
        `/api/parameters/${this.$nuxt.$route.params.hogeId}`
      )
    }, 5000)
  }
</script>
```
一度は、普通に呼び出し次から５秒毎に描画させています。序盤の方で`timers`から`import`せずに何度も実行して出来なくて苦戦しました。
RailsにReact Railsを導入する

手順をメモ書きしておきます。

# Gemfileに下記の記述を追加

```Gemfile
gem 'react-rails'
```

# ReactRailsの初期化
```ターミナル
rails g react:install
```


# React コンポーネントの作成
react-rails には、React Component 定義を生成してくれる generator があるため、
それを使用して Component を作成します。

```ターミナル
rails g react:component 任意のコンポーネント名
```

コンポーネント作成時、任意のコンポーネント名の後に「Props」と「Propsの型」を指定することもできます。

```
rails g react:component StoreInfo storeName:string
```

コマンドを実行すると
app/javascript/components直下にコンポーネントが作成されます。

上記のコマンドで作成されたコンポーネント
```StoreInfo.jsx
import React from "react"
import PropTypes from "prop-types"
class StoreInfo extends React.Component {
  render () {
    return (
      <React.Fragment>
        Store Name: {this.props.storeName}
      </React.Fragment>
    );
  }
}

StoreInfo.propTypes = {
  storeName: PropTypes.string
};
export default StoreInfo
```
CSSで「丸」を作ってみよう

<h2>HTMLの作成</h2>
ブロック要素を作り、任意のclassを設定します。<br>
今回はmaruというclassを設定しました。

```HTML:HTML
<div class="maru maru1">●</div>
<div class="maru maru2">★</div>
<div class="maru maru3"></div>
```

<h2>CSSの設定</h2>
.maru に border-radius: 50% を指定すれば「丸」の完成です。


```CSS:CSS
.maru{
    width: 160px;
    height: 160px;/* 縦横同じサイズのブロック指定 */
    margin: 30px;
    border-radius: 50%;/* 50%指定で丸が完成 */
    animation: roll 5s linear infinite;
}
.maru1{
    background-color: #25c7c9;/* ベタの「丸」 */
}
.maru2{
    background: linear-gradient(#25c7c9, #a530ff);/* グラデーションの「丸」 */
}
.maru3{
    background: repeating-conic-gradient( #25c7c9 0 15deg, #e1f1e9 15deg 30deg);/* 放射状の「丸」 */
}
@keyframes roll {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
```

<h2>サンプル</h2>

<p class="codepen" data-height="330" data-theme-id="dark" data-default-tab="result" data-slug-hash="eYVJzYL" data-user="renault1124" style="height: 330px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/renault1124/pen/eYVJzYL">
  Untitled</a> by renault1124 (<a href="https://codepen.io/renault1124">@renault1124</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<h2>おまけ</h2>
あんまり簡単に「丸」が完成してしまったので、「丸」を回転させてみました。
<ol>
<li>keyframes の roll（任意）にアニメーションを指定</li>
<li>.maru に roll を割り当ててアニメーションの時間や動き方を指定（今回は5秒で一定の速度）</li>
</ol>
これで回ります。

<h3>ベタの「丸」では回転させてもわからない</h3>
「丸」にグラデーションをつけてみた！<br>
「サンプル」真ん中の「丸」はグラデーションがついているので回っているのがかすかにわかります。<br>
もっと回っているのがわかるように右の「丸」には放射状のグラデーションを設定しました。<br>
こちらは、repeating-conic-gradient　を設定するだけでOK！<br>
任意の角度と色を入れたら360°繰り返されます。
<br><br>
以上です。
クライアントサーバシステム

## 集中処理と分散処理
<b>一昔前は、一台の高性能のコンピュータにデータや処理を集中させる<font color=blue>集中処理</font>が主流だった。
現在は、多くのコンピュータをネットワークで接続し、データや処理を分散させる<font color=blue>分散処理</font>がある。こちらの方が多く採用されている。
## クライアントサーバシステム
<b>クライアントとサーバでデータや処理を分散させる分散処理。サービスを要求する<font color=blue>クライアント</font>とサービスを提供する<font color=blue>サーバ</font>で構成されている。
一つのサーバに複数の機能を持たせたり、一つの機能を複数のサーバに分散させることも可能。
サーバは必要に応じて、処理の一部を別のサーバに要求するクライアント機能を持つこともできる。

![1418_018a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/b614c874-1031-7b1f-723b-0593b82ad9c5.jpeg)

### 3層クライアントサーバシステム
<b>論理的にプレゼンテーション層・ファンクション層・データベース層の3層構造に分離したアーキテクチャ。
![3soukurasaba2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/88ee56db-ae6e-e045-c06d-1c5ff6641ff6.gif)


### ストアドプロシージャ
<b>クライアントサーバシステムにおいて、クライアントとデータベース間のSQL文の通信負荷の重さの解決策で、利用頻度の高い命令群をあらかじめサーバ上に用意しておくこと。

## サーバの仮想化
<b>一台の物理サーバ上で複数の仮想的なサーバを動作させたり、複数の物理的なマシンを一つのサーバとして扱ったりするための技術。
### 仮想化の形態
<b><font color=blue>ホスト型</font>
<font color=blue>ハイパバイザ型</font>
<font color=blue>コンテナ型</font>

### ライブマイグレーション
<b>ある物理サーバで稼働している仮想サーバを停止することなく別の物理サーバに移動させる技術

### スケールアップとスケールアウト
<b><font color=blue>スケールアップ</font>は、個々のサーバのCPUやメモリなどを増強することでシステムの性能を向上させること
<font color=blue>スケールアウト</font>は、サーバの台数を増やすことで、システムの処理能力を向上させること。分散しょりではこちらが適している。
## シンクライアントシステム
<b>クライアントサーバシステムの一種で、サーバ上でアプリケーションやデータを集中管理することで、クライアント端末には必要最低限の機能しか持たせないシステムのこと。
テレワークが普及する中で、情報漏洩対策として注目されている。
### VID
<b>クライアント端末のデスクトップ環境を仮想化されたサーバ上に集約して、サーバ上で稼働させる仕組み。
### NAS
<b>ネットワーク(LAN)に直接接続する磁気ディスク。
【React】ReactDOM.render is no longer supported in React 18とかなんとかでるときの処方箋

こんなwarningがでる。

```
ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new
```

## 結論

```react
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';


// const container = document.getElementById('root');
// const root = createRoot(container);
// root.render(<App />);


const container = document.getElementById('root');
if (container) {
    const root = createRoot(container);
    root.render(<App />);
}


// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
```

こうするといい。

参考：
https://zenn.dev/kohski/articles/create-react-app-error-v18

※↑記事だと、if文でcontainerの中身をチェックしていないけど（2022年5月時点）、typescript使ってるとエラーになるためnullかどうかを判別する必要あり。
Swagger Editorをローカルに落として開く

# 概要

- Web上で提供されている[Swagger Editor](https://editor.swagger.io/)に会社で開発しているOpenAPIのyamlを記載することに抵抗があったためローカルにSwagger Editorを落として開く方法をまとめる。

# 方法

1. 下記にアクセスする。
    - [https://github.com/swagger-api/swagger-editor](https://github.com/swagger-api/swagger-editor)
1. コードをcloneする。
1. cloneしたコードの中にある「index.html」をブラウザで開く。

    ![swagger-editor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/375c0fb6-5436-064f-396d-4cfd969d8e77.png)

1. 自分のみ閲覧できるSwagger Editorがブラウザで起動する。

    ![Swagger_Editor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7d5da2e8-b672-85b0-9ae0-805db0033bb5.png)
【コマンド実践】sed


# はじめに
Linuc Level1の取得に向けて勉強をしているので、コマンドのまとめをメモとして書きます。
取り上げるコマンドの一言説明、コマンド、コマンドのちょっと詳しい説明、実行結果を載せています。

# 解説
## sedコマンドとは
> ファイルや標準入力の内容を編集して表示する

→文字列を一部置換したり、全部置換したり、行を削除したり、文字を置換したりして表示できるコマンド


# 実践
## 準備
test.txtを作成
```bash
~$ cat test.txt
text1 text1.5
text2 text2.5
text3
text3.5
text4
text5
```
## 文字列の一部を置換
`sed s/文字列1/文字列2/ ファイル名`

各行最初に現れる文字列1だけを文字列2に置き換える
＊ 文字列2の後の/を忘れないこと
```bash
~$ sed s/text/T/ test.txt
T1 text1.5
T2 text2.5
T3
T3.5
T4
T5
```

## 文字列の全部を置換
`sed s/文字列1/文字列2/g ファイル名`

全ての文字列1を文字列2に置き換える
```bash
~$ sed s/text/T/g test.txt
T1 T1.5
T2 T2.5
T3
T3.5
T4
T5
```

## 特定の文字列を含む行を削除
`sed /文字列/d ファイル名`

文字列が含まれる行を削除する
一致不一致は部分一致で判断される（例ではtext3を指定し、text3.5の行も削除される）
```bash
~$ sed /text3/d test.txt
text1 text1.5
text2 text2.5
text4
text5
```

## 行番号をしていして削除
`sed 行番号1,行番号2d ファイル名`

行番号1から行番号2までの行を削除
```bash
~$ sed 1,3d test.txt
text3.5
text4
text5
```

## 文字を置換する
`sed y/文字1文字2.../文字1'文字2'.../ ファイル名`

文字1を文字1'に、文字2を文字2'に置き換える
```bash
~$ sed y/x,1/s,6/ test.txt
test6 test6.5
test2 test2.5
test3
test3.5
test4
test5
```

## オプション
### 編集コマンド（上記で説明したもの）を2つ以上組み合わせる
`sed -e 編集コマンド1 -e 編集コマンド2 ... ファイル名`


```bash
$ sed -e s/text/T/ -e s/T/TT/g test.txt
TT1 text1.5
TT2 text2.5
TT3
TT3.5
TT4
TT5
```

### 編集コマンドをファイルに記述し、ファイルを読み込む
`sed -f コマンドファイル（.sed） ファイル名`
＊編集コマンドを記述するファイルの拡張子は.sed、編集コマンドのみを記載する
```bash
~$ cat command.sed
1,3d
```

```bash
~$ sed -f command.sed test.txt
text3.5
text4
text5
```
【Rails】actionmeilerのsubjectをi18nで日本語化する

# 初めに

`Rails`でメールの件名を `i18n` で設定する方法を忘備録として残しておきます。

## 環境

- Rails 6.1.4

- Ruby 2.7.4

# 日本語設定

`ja.yml`に日本語を追加することで`subject`を設定できます。
また、引数を与えて動的に変更することもできます。

## user_mailer.rb

```ruby:user_mailer.rb
class UserMailer < ActionMailer::Base
  def welcome
    # mail(to: '宛先' ,suject: '件名')
    mail(to: '宛先')
  end

  def signin(user)
    mail(to:'宛先', subject: default_i18n_subject(user: user.name))
    # 引数を与える場合はdefault_i18n_subjectを利用する
  end
end

```

## ja.yml

```yaml:ja.yml
ja:
  user_mailer:
    welcome:
      subject: '件名'
    signin:
      subject: "%{user}さん, ようこそ！"

```

# まとめ

日本語だけならこのような対応は必要ないですが、英語などの多言語に対応するときに必要になるので覚えておく必要があります。

## 参考

[[初学者]Rails の i18n による日本語化対応](https://qiita.com/shimadama/items/7e5c3d75c9a9f51abdd5#%E5%BC%95%E6%95%B0%E3%81%82%E3%82%8A)

[Rails 国際化(i18n) API - Rails ガイド](https://railsguides.jp/i18n.html)
Maintain Your Administrator Certification for Spring '22(Salesforce Certified Administrator更新)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/2edd46d5-c07c-8a86-816d-429681cf12e0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/01621679-d1a5-dac7-c99c-422e94ae8265.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424429/1728fc30-761b-db85-bc67-257d57410a03.png)