OmniAICreator/Qiita-1.07M huggingface dataset:
[WordPress]WordPress環境をDockerでちゃちゃっと作るよ

# そろそろ新人とかが配属されたんじゃね？
役に立つか微妙な社内研修が終わって、ようやく各プロジェクトに本配属されて来る時期かと思います。
先輩方からしたら「新人ガチャ」、新人たちからしたら「プロジェクトガチャ」と「先輩ガチャ」なところではありますが、どうですか？ちゃんとSSRとかURとか引けましたか？
まぁ新人ガチャについては、今はN（ノーマル）とかR（レア）とかでも、育成次第でいくらでも化ける可能性があるので、先輩方はしっかり育成・調教・プロデュースしてあげてください。
自分は先輩ガチャ的にはどのレア度なのだろう？？？

最長3年ぐらいでプロジェクトガチャはリセマラしたいところではありますが、人生最初のプロジェクトはプロジェクトのフローを勉強するいい機会なのでとりあえずやりきってみるといいかなと思います。
※他のプロジェクト行った時に如何に恵まれていたか・クソだったかがよく分かるから
※自分は飽き性なので同じプロジェクトに3年が限界、早く下に引き継いでとっとと別のことしたい

# WordPressの環境を作るよ
そんなわけで自分のところにも一時的ではありますが新人が配属されて、WordPressでHPを作るよプロジェクトが始まったわけで。
まず全く知識がない状態での環境構築で、無駄な時間と環境別な問題に引っかかってほしくないというのもありDockerDesktopを使ってちゃちゃっと作りました。


## Dockerに食わせる設定ファイル（即席
DBの名前とかログイン情報はとりあえずローカルでの作業のためベタ書きで適当にしてます
※envとかで設定値しちゃうと教えること増えるので
```yaml:docker-compose.yml
version: '3.1'

services:

  wordpress:
    image: wordpress:6.5.4-apache
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db #DBコンテナの名前を指定
      WORDPRESS_DB_USER: wp_user #DBのログインユーザ名
      WORDPRESS_DB_PASSWORD: wp_pass #DBのログインパスワード
      WORDPRESS_DB_NAME: wp_db #WordPress用のDB名
    volumes:
      - ./wpHtml:/var/www/html

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wp_db #WordPress用のDB名
      MYSQL_USER: wp_user #DBのログインユーザ名
      MYSQL_PASSWORD: wp_pass #DBのログインパスワード
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - wpDb:/var/lib/mysql

volumes:
  wpDb:
```

## Docker起動
VSCodeとかでymlのあるフォルダを開いて、ymlを右クリックでCompose Upを選択するよ。
※プラグイン（拡張機能）でDocker関連を選択してること
![画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/996378/502ad986-ad8a-5dca-a6e1-b91c65493a40.png)

## ブラウザからアクセスアクセス
[ローカルのWPログイン画面(http://localhost:8080/wp-login.php)](http://localhost:8080/wp-login.php) にアクセスすれば、初回表示の設定画面が開くので、後はWPの管理者情報を登録して終わりです。

# ね、簡単でしょ？
ローカル環境にMySQLやらApacheやら入れなくてもWordPressの環境は簡単に作れますが、
WordPress入れてからが本番な感じなので新人さんには頑張ってもらいたいところです！
エンジニアのやる気を引き出す！効果的なフィードバックとリアクションの秘訣

# エンジニアのアウトプットをもっと引き出すために

エンジニアとして働いていると、自分のアイデアや成果をどんどんアウトプットすることが大事ですよね
でも、続けるのはなかなか難しいものです
そこで今回は、エンジニアのアウトプットをもっと引き出すためのヒントをお伝えします！

## 小さなアウトプットにも反応しよう

日々のちょっとしたアウトプットも、しっかりと認めてあげることが大事です
どんなに小さなことでも反応があると、やる気がアップします！

- **いいねを押す**: 簡単にできるリアクションです。すぐに相手に「見たよ！」と伝えられます
- **お礼コメントをする**: 「ありがとう」と一言添えるだけで、相手はうれしくなります
- **深掘りする**: その内容についてもっと質問したり意見を言ったりすることで、相手のモチベーションが上がります
- **拡散する**: X（旧Twitter）でリポストするなど、他の人にもシェアしてあげましょう
    - 他の人にも共有することで、認められる機会が増えます

例えば、同僚が新しいツールを紹介してくれた場合、ただ「ありがとう」と言うだけでなく、「これを使ってどんなことができるの？」と質問してみたり、自分で試してみて感想を共有することで、相手もさらに深い情報を提供してくれるようになります

## 積極的なフィードバックをしよう

アウトプットに対して積極的にフィードバックすることも大切です
指摘や改善点だけでなく、良かった点も忘れずに伝えましょう！

- **ポジティブな表現を使う**: なるべく前向きな言葉を選ぶように心がけましょう
- **相反する意見は丁寧に**: 相手を否定せず、自分の意見をそっと伝えることがポイントです
    - 相手を論破したり、意見を否定したりしてはだめです！
    - 相手の考えを尊重しながら、自分の意見を伝えることが大切です

例えば、コードレビューの際に「ここを修正する必要があります」と言うだけでなく、「この部分のアプローチはとてもクリエイティブですね。ただ、こうするとさらに良くなるかもしれません」といったフィードバックをすると、相手は自分の努力が認められたと感じ、さらに改善しようという意欲が湧きます

## PRレビューもポジティブに

Pull Request（PR）のレビューでも、ポジティブなフィードバックを忘れないようにしましょう
つい指摘ばかりに目が行きがちですが、良かった点にも触れることで、相手のやる気が一層高まります

- **具体的な良い点を指摘する**: 「この部分のリファクタリングは素晴らしいです」と具体的に良い点を挙げると、相手は何が良かったのかを理解しやすくなります
- **建設的な指摘をする**: 「ここはもう少しこうするとさらに効率が良くなると思います」といった、改善のための具体的な提案をすると良いです

自分もついつい指摘ばかりになりがちですが、これからはもっとポジティブな視点でフィードバックすることを心がけたいと思います！

# まとめ

エンジニアのアウトプットを促進するためには、努力を認め、積極的にフィードバックすることが欠かせません
小さなリアクションから始めて、エンジニアリングコミュニティ全体のモチベーションを高めていきましょう！
あなたの一言が、誰かの次の素晴らしいアウトプットを引き出すきっかけになるかもしれません

なお、これらはあくまで個人的な意見です
科学的なエビデンスがあるわけではありませんが、参考になれば幸いです
【Android開発】Kotlin入門 Androidのディベロッパーガイドの分かりにくいところを書き直す#3

[アクティビティのライフサイクル](https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ja)
#### 知らないこと
アクティビティのライフサイクル 
ライフサイクルのパラダイム
ライフサイクルのコールバック
onCreate()
onStart()
onResume()
onPause()
onStop()
onDestroy()
onSaveInstanceState() 
アクティビティ間の移動
アクティビティを連携させる

#### アクティビティのライフサイクル 
+ アクティビティが生成されてから破棄されるまでの、一連の状態遷移のこと
+ それぞれの状態で、コールバックメソッドが呼び出される

ライフサイクル コールバックを適切に実装すると、アプリで次の事態を回避できる
+ アプリの使用中にユーザーが電話を受信したり、別のアプリに切り替えたりするとクラッシュする
+ ユーザーが実際に使用していない場合に、貴重なシステム リソースが消費される
+ ユーザーがアプリを離れてから後で戻ると、ユーザーの進捗状況が失われる
+ 画面が横向きと縦向きの表示を切り替えている間に、クラッシュする、またはユーザーの進捗状況が失われる


#### ライフサイクルのパラダイム
+ 基本的な考え方のこと
+ すべてのライフサイクル メソッドを実装する必要はない
+ それぞれを理解し、アプリがユーザーの期待どおりに動作するように実装することが重要
#### ライフサイクルのコールバック
+ Activity クラスには 6 つのコールバック（onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()）が用意されている

#### onCreate()
+  アクティビティが初めて作成されるときに呼び出される
+  UIの初期化、データの読み込みなどを行う
+  以前の状態を復元する必要がある場合にsavedInstanceStateを使用する

#### savedInstanceState
+ アクティビティの以前の状態が保存されている Bundle オブジェクト

#### Bundleオブジェクト
+ Androidにおいて、様々な種類のデータを一時的に保存したり、異なるコンポーネント間で受け渡ししたりするためのオブジェクト

#### onStart()
+ アクティビティがユーザーに表示される直前、呼び出される

#### onResume()
+ アクティビティがユーザーからの操作を受け付ける状態になると呼び出される

#### onPause()
+ アクティビティがフォアグラウンドからバックグラウンドに移動するとき、呼び出される

#### onStop()
+ アクティビティがユーザーへ表示されなくなるときに呼び出される

#### onDestroy()
+ アクティビティが破棄される直前に呼び出される

#### アクティビティの状態とメモリからの退避
+ RAM を解放する必要がある場合、システムはアクティビティではなく、プロセスを強制終了する
+ システムがメモリを解放するためにアクティビティを直接強制終了することはない

#### 一時的な UI の状態の保存と復元
+ (回転やモードの切り替えで)アクティビティは破棄される
+ ユーザーはUIの状態が同じままであることを想定るするので、一時的なUIの状態を保持する必要がある
+ ViewModel、 onSaveInstanceState()、またはローカル ストレージを組み合わせて復元する

#### インスタンスの状態
+ システムが以前の状態を復元するために使用する保存済みデータを、インスタンスの状態という
+ 保存済みデータとは、Bundle オブジェクトに格納されている Key-Value ペアのコレクションのこと
#### アクティビティ間の移動
+ 別のアクティビティからのアクティビティの開始、アクティビティの状態の保存、アクティビティの状態の復元などがある
範囲オブジェクト

# 範囲オブジェクトとは
範囲オブジェクトとは、「〇から〇まで」のような、値の範囲を表すオブジェクトのこと。

## 作成方法
1から10までの場合以下のように表す。
```
a = 1..10
a.include?(10)
=> true
```
include?メソッドで確認すると、10まで範囲に含まれていることがわかる。
10を含めたくない場合は、「.」の数を3つにすることで範囲を10未満にすることができる。
```
a = 1...10
a.include?(10)
=> false
```

# 使用例
〇以上〇以下や、〇以上〇未満を判定したい時は、不等号を使用するよりも、範囲オブジェクトを使用した方がシンプルに記述することができる。


```
def number_of_people(num) 
  1 <= num && num < 10
end
```
↓
```
def number_of_people(num)
  (1...10).include?(num)
end
```
Claudeに画像を入力した時のコストについて

# Claudeに画像を入力した時のコストについて

詳細は公式HPより

https://docs.anthropic.com/en/docs/build-with-claude/vision

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/11c921c3-e1c0-68e8-0e67-1707e6a40009.png)


# 参考

https://qiita.com/Subara3/items/d690823cf4f42d9fb0d1

https://azure.microsoft.com/ja-jp/pricing/details/cognitive-services/openai-service/
便利ツール3選

# Starship
:::note
**ターミナルを見やすく・より多くの情報を表示してくれるサービス**
導入も簡単です。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/3e5e56ba-cc63-c48f-563b-636f84c322d5.png)

ブランチの絵文字など、Nerd Fontを導入することで真価を発揮します。

Starshipの導入方法・Nerd Fontの導入方法
どちらも以下の記事に記載しています。

https://qiita.com/kohki_takatama/items/6858b23a5d3d9cd3e2da

ターミナルを便利にしたい方は、以下の記事もオススメです。

https://qiita.com/kohki_takatama/items/3051d23bf3c5d5cbeede

# Replit / StackBlitz

:::note
**オンラインでコードを実行できるサービス**
「ちょっと仕様を確認したい」
「簡単なコードを実行したい」
「でも環境構築するのは面倒」
こんなときにオススメです。
:::
![スクリーンショット 2024-06-29 22.14.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/e43b5df5-7c9c-1f8e-ea10-224039fbf57b.png)

## Replit

https://replit.com/

幅広い言語・フレームワークに対応しています。

無料でも十分な性能ですが、有料プランならVMを稼働させ続けることもできる模様。
「AI補完機能」「フォーマット機能」も高いレベルで実装されています。

https://qiita.com/shun-shobon/items/63714f9ae802251c90bd



## StackBlitz

https://stackblitz.com/

Replitと同様のサービスですが、JSに特化しているようです。

例えば、Nuxt.jsはReplitにはなく、StackBlitzにあるものの一例です。

この記事がわかりやすいです。

https://zenn.dev/ame_x/articles/8f82ed64d7a05f

## codic

使ったことはないのですが、刺さる人には刺さるかも。

https://x.com/Kohki_Takatama/status/1804827295175078156

命名を考えてくれるようです。

---
以上、便利ツール紹介でした。
今後も何か見つけたら追記するかも。
【Jetpack Compose】ナビゲーションの連打・同時押しを防ぐ

[Lifecycle 2.8.0](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.0)以降で`dropUnlessResumed` `dropUnlessStarted` というAPIが追加されています。
以下のように画面遷移のコードを囲うことで、ナビゲーションの連打・同時押しを防ぐことができます。

```kotlin
Button(
  onClick = dropUnlessResumed { navController.navigate(SCREEN) }
) {
  // ...
}
```

## 注意点
`dropUnlessResumed`の返り値は `() -> Unit` です。従って次のように書くことはできません。

```kotlin
@Composable
fun ScreenA() {
  Component(
    navigateToB = dropUnlessResumed { /* ... */ }
  )
}

@Composable
fun Component(
  navigateToB: (userId: String) -> Unit
) {
  // ...
}
```

## 内部実装
単純にライフサイクルをチェックしているだけのようです。

```kotlin
@Composable
fun dropUnlessResumed(
    lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
    block: () -> Unit,
): () -> Unit = dropUnlessStateIsAtLeast(State.RESUMED, lifecycleOwner, block)

@Composable
private fun dropUnlessStateIsAtLeast(
    state: State,
    lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
    block: () -> Unit,
): () -> Unit {
    require(state != State.DESTROYED) { "..." }

    return {
        if (lifecycleOwner.lifecycle.currentState.isAtLeast(state)) {
            block()
        }
    }
}
```
TypeExpressTutorial - 4

:::note info
やりたいこと
- `/api/auth/signup` に `GET` でリクエストされたら任意のJSONが返却されるAPIを作る
- `/api/auth/login` に `GET` でリクエストされたら任意のJSONが返却されるAPIを作る
:::

## 全体像
:::note info
処理の順番
1. リクエストを `routes層` で受け取る
1. `routes層` で実際の処理の関数をコールする
1. 処理の関数は `controller層` で記述する
1. signup関数, login関数 がコールされたら任意の JSON が返却される
:::

## Controller
`src/controllers/auth.ts` ファイルを新規で作成する

```src/controllers/auth.ts
import { Request, Response } from 'express'

export const signup = async (req: Request, res: Response) => {
  res.json({ message: 'Signup route' })
}

export const login = async (req: Request, res: Response) => {
  res.json({ message: 'Login route' })
}
```

## Routes
`src/routes/auth.ts` ファイルを新規で作成する

```src/routes/auth.ts
import { Router } from 'express'
import { login, signup } from '../controllers/auth'

const authRouter: Router = Router()

authRouter.get('/signup', signup)
authRouter.get('/login', login)

export default authRouter
```

`src/routes/index.ts` ファイルを新規で作成する

```src/routes/index.ts
import { Router } from 'express'
import authRouter from './auth'

const rootRouter: Router = Router()

rootRouter.use('/auth', authRouter)

export default rootRouter
```

### エントリーファイル（index.ts）への記述
`src/index.ts` ファイルに追記

```src/routes/index.ts
import express, { Express, Request, Response } from 'express'

import { PORT } from './secrets'
import rootRouter from './routes' // <- 追記

const app: Express = express()

app.use(express.json()) // <- 追記
app.use('/api', rootRouter) // <- 追記

app.listen(PORT, () => {
  console.log('Server is running on http://localhost:8000')
})
```
Outlook の Copilot for Sales

[Copilot のまとめに戻る](https://qiita.com/Keiji_otsubo/items/cd25b318bf5789170ad3)



+ [Copilot for Sales 機能の概要](https://learn.microsoft.com/ja-jp/microsoft-sales-copilot/functional-overview)

Microsoft Copilot for Sales は、営業チームの生産性を最大化し、より多くの取引を成立させ、Microsoft Outlook、Microsoft Teams、その他の Microsoft 365 アプリなど日常的に使用するツールに Sales Insights と次世代 AI を導入するために設計された AI アシスタントです。

Copilot for Sales は、Salesforce Sales Cloud と Microsoft Dynamics 365 Sales に接続し、他の販売ソリューションに接続するように構成できます。 Copilot for Microsoft 365 は、Copilot for Sales に含まれており、組織がワークフロー全体の生産性向上からより広範囲に恩恵を受けるのに役立ちます。

+ [Copilot for Sales の購入](https://learn.microsoft.com/ja-jp/microsoft-sales-copilot/buy-license)

Microsoft Copilot for Sales は、Microsoft 365 にある販売者向けの AI アシスタントです。これは販売ソリューションに接続し、生産性ワークフロー全体に次世代の AI および CRM プラットフォームのアップデートと分析情報をもたらします。 サブスクリプションはユーザーごとにライセンスが付与され、Copilot for Microsoft 365 へのアクセスが含まれます。


+ [Outlook で Copilot for Sales をインストールする](https://learn.microsoft.com/ja-jp/microsoft-sales-copilot/install-viva-sales-as-an-integrated-app)


# エラー

+ [OutlookのCopilot for Sales](https://qiita.com/Keiji_otsubo/items/22178c1b143aa8f49beb)
+ [OutlookのCopilot for Sales設定のOAuth 認証時エラー](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epx4a)

:::note alert
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-store
{
  "error": "invalid_grant",
  "error_description": "ip restricted"
}
:::


:::note
エラーメッセージだけから考えると接続アプリケーションの中でIPアドレスの制限が書けられているようです。

https://www.useparagon.com/integration-error-solutions/salesforce-ip-invalid-grant-ip-restricted

MuleSoftの場合もやはり接続アプリケーションの設定を確認するように回答されています
https://help.salesforce.com/s/articleView?id=001122068&type=1

これは、ちょっとエラーの内容が違いますね。
https://learn.microsoft.com/en-us/troubleshoot/sales-copilot/setup-installation-and-sign-in/oauth2-authorization-flow-failed-for-service
:::

+ [OutlookのCopilot for Sales設定のOAuth 認証時エラー](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epx4aSAA)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/da5b82c3-3956-409c-5883-5509ca92031c.png)

:::note
以下の設定を確認してみてください。

MSさんのヘルプ資料なので、うまくいくかもしれません。

ステップ 6: Microsoft Power Platform に接続されているアプリが Salesforce でブロックされていないことを確認する

Copilot for Sales は、Salesforce CRM に接続するために Power Platform コネクタを使用します。 Copilot for Sales ユーザーに対してコネクタが有効になっていることを確認します。
https://learn.microsoft.com/ja-jp/microsoft-sales-copilot/deploy-viva-sales-sf
:::

+ [401 when making a http callout from flow for MS Dynamics](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000J6f92)
数式入力条件の選択リスト項目を含むレコードトリガーフローをデバッグすると、内部エラーが発生します。

[Flowに関するまとめページに戻る](https://qiita.com/Keiji_otsubo/items/55ebc9c634a3216f3990)

---------

+ [既知の問題の解決：数式入力条件の選択リスト項目を含むレコードトリガーフローをデバッグすると、内部エラーが発生します。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PjRUP)

https://issues.salesforce.com/issue/a028c00000p5goIAAQ/when-debugging-a-record-triggered-flow-with-picklist-field-in-formula-entry-criteria-throws-internal-errors


選択リストではないですが、レコードタイプでも似たような現象ですね。

+ [トリガーフローのエントリ条件で参照関係にあるオブジェクトのレコードタイプを取得する数式項目を使用するとエラーとなる](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmHqx)
【備忘録】インカメラ/アウトカメラの切り替え

# インカメラ/アウトカメラの切り替え

セレクトボックスを使って、ユーザーがインカメラとアウトカメラを選択できるようにします。

~~~HTML:HTML
<select id="cameraSelect">
  <option value="user">インカメラ</option>
  <option value="environment">アウトカメラ</option>
</select>
~~~

1. getUserMediaを呼び出す際に、facingModeオプションを指定します。
2. セレクトボックスの値が変更された時、選択されたカメラに応じてfacingModeに"user"（インカメラ）か"environment"（アウトカメラ）を設定します。
3. 新しいconstraintsでストリームを取得し、ビデオ要素のソースに設定し直します。

~~~javascript:JavaScript
let cameraSelect = document.getElementById('cameraSelect');

cameraSelect.addEventListener('change', async () => {
  let constraints = {
    video: {
      facingMode: cameraSelect.value
    }
  };

  stream = await navigator.mediaDevices.getUserMedia(constraints);
  video.srcObject = stream;
});
~~~

ユーザーがセレクトボックスでカメラを切り替えると、インカメラとアウトカメラが切り替わるようになります。

ただし以下の点に注意が必要です。
- カメラの切り替えはスマホなどでのみ使用可能です。
- 対応していない端末（PCなど）ではfacingMode: "environment"を指定してもインカメラが使われます。
- 一部の古いブラウザではこの機能に対応していない可能性があります。
- ユーザーにカメラの使用を許可してもらう必要があります。
中間テーブル(多対多の関係性)を理解する

# はじめに
多対多のテーブル構造について分かったようでわかっていなかったので深堀していこうと思います。

# 概要
SNSなどで一般的な投稿に対して複数のいいね！がつくような仕様のテーブル構造を考えます。
ER図は以下。

```mermaid
erDiagram
users ||--o{ posts: ""
users ||--o{ likes: ""

posts ||--o{ likes: ""

users{
  integer id PK
  string name
  string email
}

posts{
  integer id PK
  string header
  string body
  integer user_id FK
}

likes{
  integer id PK
  integer user_id FK
  integer post_id FK
}


```

# 分解して考える
これだけで理解できれば問題ないのですが、「？」となった人、読み進めてください。

まず、ユーザーには「投稿をするユーザー」と「いいねをするユーザー」がいますが、実際には同じユーザーが両方の行動を行います。
今回は「いいね！」という行為に絞って話を進めていきます。

- ユーザーは複数の投稿にいいねをすることができる
- 投稿は複数のユーザーからいいねを受け取ることができる




この状態では、usersテーブルとpostsテーブルの間には1対多の関係が存在します。しかし、ユーザーと投稿の間には「いいね」を介した多対多の関係があります。この多対多の関係を管理するために、中間テーブルとしてlikesテーブルを使用します。

likesテーブルは、user_idとpost_idの2つの外部キーを持ち、ユーザーがどの投稿にいいねをしたかを管理します。これにより、ユーザーと投稿の間の多対多の関係を効率的に追跡することができます。

# 図解する

図解すると以下のようになります。

## 投稿するユーザー
```mermaid
erDiagram
users ||--o{ posts: ""

```
![スクリーンショット 2024-07-04 11.07.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743559/c00ebd0d-fc45-0048-90b9-bb75d0167454.png)

## いいねをするユーザーと投稿につくいいねの関係

```mermaid
erDiagram
users ||--o{ likes: ""
posts ||--o{ likes: ""
```
![スクリーンショット 2024-07-04 11.07.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743559/399e72f8-b3cd-a4dc-0825-44cc2113d19d.png)

# データ例
## users テーブル

| id | name  | email              |
|----|-------|--------------------|
| 1  | Alice | alice@example.com  |
| 2  | Bob   | bob@example.com    |

## posts テーブル

| id | header | body      | user_id |
|----|--------|-----------|---------|
| 1  | Post 1 | Content 1 | 1       |
| 2  | Post 2 | Content 2 | 2       |

## likes テーブル

| id | user_id | post_id |
|----|---------|---------|
| 1  | 1       | 2       |
| 2  | 2       | 1       |
| 3  | 1       | 1       |

このデータ構造により、ユーザーAliceがPost 2とPost 1にいいねをし、ユーザーBobがPost 1にいいねをしたことがわかります。つまり、中間テーブル（likes）は多対多の関係を管理しています。

# まとめ

中間テーブル（likes）を使用することで、「ユーザー」と「投稿」の間の多対多の関係を管理できます。これにより、各ユーザーがどの投稿にいいねをしたか、各投稿にどのユーザーがいいねをしたかを効率的に追跡できます。

# 参考

以下、参考にさせていただきました！
[やさしい図解で学ぶ　中間テーブル　多対多　概念編](https://qiita.com/ramuneru/items/db43589551dd0c00fef9)
TypeExpressTutorial - 3

:::note info
やりたいこと
- 環境変数の値を取得する
:::

<details><summary>全体像</summary>

1. [プロジェクトを作成する](https://qiita.com/yk-graph/items/b5f0551cb368fb86c50c)
1. [Mysql + prisma でDBを構築する](https://qiita.com/yk-graph/items/02333bd99b625dbcc49d)
1. [環境変数を設定する](https://qiita.com/yk-graph/items/e37cd011c6da3feb93d2)
1. [APIを作成する](https://qiita.com/yk-graph/items/e5b52a4d35cd43d95f7a)
1. [ユーザー登録とログインを実装する](https://qiita.com/yk-graph/items/dd093a286377843441e1)
1. [オリジナルのエラーハンドリングを構築する](https://qiita.com/yk-graph/items/fb47753e55986bafdb1d)
1. [zod を使ったバリデーションを構築する](https://qiita.com/yk-graph/items/84214e03a6119523ac18)
1. [エラーハンドリングのリファクタリング](https://qiita.com/yk-graph/items/8951b710158eb1a20eb7)
1. [認可の処理を実装する](https://qiita.com/yk-graph/items/3e43974a6685ff94a304)
1. [10]()
1. [11]()
1. [12]()
</details>

## dotenvのインストール
```zsh
$ npm install dotenv
```

## 環境変数を呼び出すためのファイルを設定
.evnファイルに環境変数を定義
```.env
DATABASE_URL="mysql://root:password@localhost:3306/type-express-db"
PORT=8000
```

secrets.ts ファイルを作成する
```src/utils/secrets.ts
import dotenv from 'dotenv'

dotenv.config({ path: '.env'})

export const PORT = process.env.PORT
```
`secrets.ts` ファイル内で環境変数を取得して export し、任意のファイルから参照できるようにする

```src/index.ts
import { PORT } from './secrets'

app.listen(PORT, () => { // <- 変更
  console.log(`Server is running on http://localhost:${PORT}`)
})
```
フローで自動レイアウトではなくフリーフォーム モードにしないと解決できない問題:完了アイコン　(The "Done" icon) 




+ [「ビジネス ロジックの追加」を実行して「Flow Builder で自動化」フィールドを開始しようとしているときに、キャンセルと完了のオプションが見つからず、完了をクリックしないと先に進んで処理を完了できません。どうすればよいか提案してください。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmHZX)

:::note
Please select free-form

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7e5abff5-a68b-2f6d-48b3-fc0b1b8630e4.png)

:::


# 既知の問題 Winter24

+ [Add Business Logic - Automate with Flow Builder - No DONE フローの仕様が変わった](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007MZv2m)

:::note
Done button will be visible in Free-from mode not in auto layout please switch the flow in Free-from.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9c9cb6e2-546d-ddd6-db3e-6be066543140.png)


完了ボタンは、自動レイアウトではなくフリーフロム モードで表示されます。フローをフリーフロムに切り替えてください。
:::
OpenSSHの脆弱性調査 バージョン確認方法

「OpenSSHの脆弱性 CVE-2024-6387についてまとめてみた」
https://piyolog.hatenadiary.jp/entry/2024/07/02/032122

↑の記事の通り、OpenSSHの脆弱性が騒がれていた。（ランサムウェアのニュースでグループ内も敏感になっているみたい）
各環境のVMのバージョンの確認を最優先で行ってくださいという話になった。

### バージョン確認方法
```
ssh -V
または
rpm -q openssh-server
```

参考
https://qiita.com/fukuchan-senpai/items/ea08e3f790280c454499
https://www.famlog.jp/article/745
WinAuthを使ってSalesforceにログインする


具体的な手順については以下のサイトに詳しく書かれているので参考になります。

+ [Salesforceで多要素認証の設定をする](https://qiita.com/talomina/items/73172fa2c23af155d650)

気になる質問があります。

+ [Salesforceへログインする際、WinAuthの番号認証が必要な場合と必要でない場合があります。自分も一時期は毎回ログインの際に認証をしていましが、ある日を境に認証無しでログインができるようになっておりました。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmIISSA2)

この機能を使うと入力はどうなるんだろうか？

+ [生成したワンタイムパスワードを自動でコピーできる機能があります。](https://mp-faq.gmo-pg.com/s/article/F00055)


https://www.nyusatsu.e-hyogo.jp/www/contents/1664194226514/simple/mfa_tejun.pdf

# 関連の質問

+ [MFAの併用について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000E98uNSAR)
+ [WinAuthの設定時刻ずれについて](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000KdwXSSAZ)

# ワンタイムパスワードの仕組み

+ [【図解】ワンタイムパスワードの仕組みとは？認証方式やトークンを解説](https://corp.capy.me/blog/id-access-management/2022/06/one-time-pw-mechanism/)

トークンがその時刻に生成するパスワードのアルゴリズムを認証サーバーで共有していて、パスワードが一致すれば認証が成立する仕組み
Raspberry Pi OS 2024-07-04 Release-note 翻訳

（追記：2024/10/28に、Raspberry Pi OS 2024-10-22 がリリースされています）
https://qiita.com/utaani/items/50733742afffb4cf9540

 https://downloads.raspberrypi.com/raspios_armhf/release_notes.txt

2024-07-04:   
  * pipanel - 2つ以上のデスクトップのカスタマイズが可能
  * pipanel - labwc のカスタマイズを追加
  * gui-pkinst - インストールを指定されたパッケージのみに制限するためのホワイトリストを追加
  * pixflat-theme - labwc のテーマ設定を追加
  * pishutdown - デスクトップを閉じるためにpkillを本来の使い方に戻す
  * piclone - 潜在的なバッファオーバーフロー脆弱性を修正（実際には決して起こらないはずの脆弱性）
  * lp-connection-editor - タスクバーのダイアログアイコンを修正
  * rp-prefapps - Raspberry Pi Connect を追加し、SmartSim を削除
  * piwiz - Raspberry Pi Connect を有効/無効にするページを追加
  * wf-panel-pi - メインメニューを小さな画面に合わせるように制限
  * wf-panel-pi - タスクバーのダイアログアイコンを修正
  * wf-panel-pi - タスクバーボタンのキーボード処理とアイコンのハイライト表示を修正
  * raspberrypi-ui-mods - labwc の設定を追加
  * raspberrypi-ui-mods - 新しいタッチスクリーンのサポートを追加
  * raspberrypi-ui-mods - Pi 5 のハードウェア電源キーを上書きするために systemd-inhibit を使用するように修正
  * rc-gui - 代替キーボードレイアウトの設定を追加
  * rc-gui - Raspberry Pi Connect のスイッチを追加
  * arandr - DSIディスプレイ向けの明るさコントロールを追加
  * arandr - 仮想ディスプレイを検出するためのより信頼性の高い方法に変更
  * raspi-config - キーボードオプションの設定を追加
  * raspi-config - PCIe速度の設定を追加
  * raspi-config - Raspberry Pi Connect のスイッチを追加
  * wayvnc - 仮想ディスプレイの扱いが向上
  * wayvnc - 暗号化サポートの改善
  * GTK-3 - コンボボックスにキーボードショートカットを追加する
  * pcmanfm - 2つ以上のデスクトップのカスタマイズが可能
  * pcmanfm - 特定のドラッグアンドドロップ操作でのクラッシュや動作の一貫性が失われるバグを修正
  * raspberrypi-sys-mods - バックライトの変更を許可するudevルールを追加
  * raspberrypi-sys-mods - swapファイルのサイズを増やす
  * raspberrypi-sys-mods - initramfs スクリプト内のパスからシンボリックリンクを削除
  * wayfire - 複数の Xwayland ウィンドウを開いたときにクラッシュする問題を修正
  * wayfire - ウィンドウのない領域をタッチしたときのタッチスクリーンのバグを修正
  * wayfire の代替として labwc コンポジターがインストールされており、raspi-config で有効にできる
  * さまざまな小さなバグ修正と調整
  * Chromium が 125.0.6422.133 に更新されました
  * Firefox が 126.0 にアップデートされました
  * Raspberry Pi ファームウェア 3590de0c181d433af368a95f15bc480bdaff8b47
  * Linux カーネル 6.6.31 - c1432b4bae5b6582f4d32ba381459f33c34d1424
LPIC101を勉強していた頃のメモ

BIOSとUEFIの違い



* BIOS
    * Basic Input Output Systemの略
    * 入出力基本システム
    * キーボードやハードディスクなどのデバイスを制御する、もっとも基本的な制御プログラム
    * コンピュータのマザーボードや拡張カードのフラッシュROMに書き込まれている
    * BIOSのインターフェースを利用して、OSやアプリケーションはハードウェアにアクセスする
    * いろいろな役割
        * OS起動のためのプログラムをディスクから読み込んで実行
        * デバイスの動作を設定
        * 基本的な入出力を制御する
* UEFI
    * Unified Extensible Firmware Interfareの略
    * BIOSとの違い
        * 一部OSの起動ドライブ容量制限がない
            * BIOSは2TBまで
        * GUIベースのセットアップ画面が利用できる
* BIOSとUEFIで共通して設定できること
    * ハードウェアクロック
        * 日付や時刻
    * ディスクドライブや各種デバイスのパラメータ
    * キーボードの使用/不使用
    * 電源管理
    * 起動ドライブの順序
    * デバイスへの割り込み要求の割当
        * 割り込み要求: IRQ Interrupt Request
    * 各種デバイスの使用/不使用

デバイス情報



* デバイスファイルとは？
    * ハードウェアのアクセスを抽象化する
    * すべてのハードウェアはデバイスファイルとして表される
    * Linuxはデバイスファイルの読み書きを通じてハードウェアにアクセスする
    * /devディレクトリ以下に表示される
    * udevという仕組みで自動的に作成される(後述)
* /procディレクトリとは
    * Linuxカーネルが認識しているデバイスに関する情報の一部を表示する
    * /procディレクトリ以下のファイルは実体のない仮想的なファイル
    * 主なファイル
        * /proc以下の主なファイル
            * /proc/cpuinfo: CPU情報
            * /proc/interrupts: IRQ情報
            * /proc/ioports: I/Oアドレス情報
            * /proc/meminfo: メモリ情報
            * /proc/bus/usb/*: USBデバイス情報
            * /proc/bus/pci/*: PCIデバイス情報
* PCIデバイスとは
    * Peripheral Component Interconnectの略
    * コンピュータのマザーボードに差し込んで特定の機能を追加する拡張カードのひとつ
    * PCIバスで通信を行う
        * コンピュータ内部で装置感を結ぶデータ伝送路の規格の一つ
        * 主にCPUと周辺機器などを接続するためのもの
    * 情報を表示するためには lspci コマンドを利用する
        * -vオプション: 詳細な情報
        * -vvオプション: もっと詳細な情報
* USBデバイス
    * Universal Serial Busの略
    * 周辺機器を接続するために普及している規格
    * 最大127台までのUSBデバイスを接続可能
    * 情報表示のためのコマンドは lsusb
        * -vオプション: 詳細に表示
        * -tオプション: USBデバイスの階層構造をツリー状に表示
* デバイスドライバ
    * ハードウェアを利用するために必要な制御プログラム
    * Linuxシステムに最初から搭載される汎用のドライバ=クラスドライバ がある
    * Linuxでは、カーネルの一部(カーネルモジュール)として提供されている
    * 必要なデバイスドライバをカーネルに取り込むことを「ロードする」という
    * ロードされているカーネルモジュールを確認するコマンドは lsmod
    * 必要なデバイスドライバは自動的にロードされる
    * 手動でロードする場合に利用するコマンドは modprobe
        * modprobe [デバイスドライバの名前] でロードする
* udevとは
    * Userspace DEVice managementの略
    * デバイスファイルを自動的に作成する仕組み
    * 仕組み
        * デバイス(ハードウェア)が接続されるとカーネルが検知する
        * /sysディレクトリ(sysfs)以下にデバイス情報を作成
            * /procディレクトリと同様に仮想的なファイルシステムである
        * udevデーモン(udevd)がデバイス情報を参照
        * /devディレクトリ以下にデバイスファイルを作成する
        * このとき、/etc/udev/rules.dディレクトリ以下の設定ファイルが利用される
            * memo: 中身を見る
* D-Bus
    * Desktop Busの略
    * アプリケーション間でやり取りを行うための機構
    * D-Busによりアプリケーションからデバイスを利用できるようになる
* 参考情報
    * [Linux教科書 LPICレベル1 第5版](https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC%E3%83%AC%E3%83%99%E3%83%AB1-%E7%AC%AC5%E7%89%88-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B00ESXY9GG)
    * [PCIカード(PCIデバイス)とは](https://e-words.jp/w/PCI%E3%82%AB%E3%83%BC%E3%83%89.html#:~:text=PCI%E3%82%AB%E3%83%BC%E3%83%89%E3%80%90PCI%20card%E3%80%91PCI,%E3%81%AF%E3%80%8CPCI%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E3%80%82)
    * [PCIバスとは](https://e-words.jp/w/PCI%E3%83%90%E3%82%B9.html)
AWS WAF でメンテナンスモードの開始・解除を実現する  ( +特定のIPアドレスだけはアクセスを許可する )

# 概要

サービスメンテナンス中に、レスポンスコード `503 Service Temporarily Unavailable` と、メンテナンス表示用のHTMLをユーザーに返したい

# ALBとの比較

ALBでやる欠点は

- 構成によってはALBで実現しようとすると作業が煩雑だったり、困難だったりする。
- 特定のIPアドレスだけ許可しようとしても、1ルールあたりのIPアドレス設定の上限があり、やりづらい。
- 1ルールの中でレスポンスヘッダが指定できないので、キャッシュコントロールがしづらい。

思い出してほしい。ALBは「バランサー」である。

メンテナンスモードに限らず、WAFでもALBでも実現できる動作はあるが、あくまでALBはパスに対してのリソースの振り分けに徹した方が良いと思った。

# WAFの設定手順

## STEP 1 . WAFにカスタムレスポンスを作成しておく

**AWS WAF > Web ACLs > ACL名 > Custom Response Bodies** から

- 文字化けしないようにHTMLで文字コード系の指定をしておく
- キャッシュが問題にならないようにキャッシュコントロールのmetaタグを指定しておく

```html
<!DOCTYPE html>
<html lang="ja">
<head>
 <meta charset="UTF-8">
<meta http-equiv="content-language" content="ja">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<title>メンテナンス中 </title>

</head>
<body>
ただいまメンテナンス中です
</body>
</html>
```

## STEP 2. WAF ルールの追加

### 登録開始

**AWS WAF > Web ACLs > ACL名 > Rules > Add my own rules and rule groups** を選ぶ

![CleanShot 2024-07-03 at 14 18 50@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/c19fc915-a2a3-4bc5-8c0c-e9b4221e9f47)

### Actions の指定

- Blockを選ぶ
- カスタムレスポンスを利用する
- レスポンスコードは503
- ヘッダに `Cache-Control` `no-cache` を指定する ( メンテナンスモードを解除しても、ユーザ端末のキャッシュによって解除されていないように見えるのを防ぐ )


<img width="618" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/b1d4b42c-9b02-4bd5-b377-9037f5bc91a1">

### ルール同士の優先順位を決めてSaveする

設定すべき優先順位は構成による

## STEP 3. 特別に許可するIPアドレスの設定

必要な場合は、STEP2と同じWAFのルールに、メンテナンスモードでもアクセスできるIPアドレスを設定する

まずは事前にWAFでIPセットを登録しておく


単一のIPセットを許可する場合は
「リクエストのIPアドレスが、IPセット1のものでない場合」にルールを適用するという条件を設定すれば良い

![CleanShot 2024-07-05 at 08 10 35@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/fcd35bf1-5c6d-4f3c-a09f-e4a72f9294d4)

複数のIPセットを許可対象にする場合は
「リクエストのIPアドレスが、IPセット1のものでなく、なおかつ、IPセットのものでもない2場合」にルールを適用する条件を設定すれば良い

![CleanShot 2024-07-05 at 08 05 57@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/e46707cb-d48f-456e-ac60-f7c90df9be8b)

## STEP 4. WAF ルールの削除

メンテナンスが終わったらWAFのルールを削除するだけ

## STEP 5. 再度メンテナンスモードにする時

AWSからの直接登録だと、メンテナンスをする時に1回ずつが面倒だと思うが、どうするか


### JSONで設定する

JSONでルールを保持できるようなので、それを次の登録時にも使うと良いだろう

ただし今回のようにAWS上の他のリソース (カスタムレスポンスのBODYやIPセット)も参照する形だと、ひとつのAWSアカウントのJSONは、他のAWSアカウントの環境では使えないので注意

<img width="1512" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/403b5820-e530-44c1-9c0e-40908b16375b">


### 優先順位で工夫する

ルール自体は削除せず保持したまま、他のルールとの優先順位の入れ替えでも簡単な切り替えを実現できるかもしれないが、未検証



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
注文商品レコードが作成されたことをトリガーに起動するレコードトリガーフローのデバックでレコードを選択できない



+ [トリガーのデバッグ失敗について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epy7KSAQ)

不思議ですね、確かめてみると注文番号で検索すると注文商品は表示されますが、クリックしても選択できませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ead707a6-a38f-5696-9d4a-78a17cb10035.png)


少々調べてみると既知の問題がありましたね。

+ [How to debug an OrderItem in flow?](https://salesforce.stackexchange.com/questions/367684/how-to-debug-an-orderitem-in-flow)
+ [Lightning lookups to Order Product entity does not work if using the default compact layout](
https://issues.salesforce.com/issue/a028c00000gAwwvAAC/lightning-lookups-to-order-product-entity-does-not-work-if-using-the-default-compact-layout)

 
:::note
In a Lightning Lookup, when performing a lookup search for Order Product record, the record cannot be selected if using the default compact layout because the Order Product Number field is not part of the default compact layout.

Lightning Lookup で注文商品レコードの検索検索を実行するときに、デフォルトのコンパクトレイアウトを使用している場合、「注文商品番号」項目がデフォルトのコンパクトレイアウトの一部ではないため、レコードを選択できません。
:::

どうもデフォルトのコンパクトレイアウトの注文商品番号という項目がないので、機能しないようなことが書かれています。

そこで、カスタムのコンパクトレイアウトを作成して注文商品番号を追加してみると、やはり検索は注文番号（注文商品番号）でしかできませんが、この項目をクリックするとちゃんとレコードは選択できました。

どうもフローのデバックではコンパクトレイアウトを参照しているようですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9b678e73-faec-342e-c14b-0fd100cde4f2.png)

同じような事象に遭遇したら、コンパクトレイアウトを疑うのがいいのかもしれません。
自働採番型というのがポイントなのだろうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a703eaf0-c916-2a21-d56f-968301d1b08d.png)
robots.txtファイルを使用してAIクローラーをブロックする方法

# はじめに
AWSは、アメリカを拠点とするAIスタートアップの[Perplexity](https://ja.wikipedia.org/wiki/Perplexity)に対して、クロールを望まないウェブサイトのコンテンツをクロールしていた件について、調査を開始しました。

https://wired.jp/article/aws-perplexity-bot-scraping-investigation/

上記WIREDのブログ記事を踏まえて、WIREDはrobots.txtのファイルを使用してPerplexityのクローラーをブロックしているのにもかかわらず、Perplexityは非公開のIPアドレスを使用してサーバーにアクセスし、過去3カ月間に少なくとも数百回もスクレイピングしていたことが追求されています。

2024年も生成AIに関して話題が尽きませんが、本記事ではrobots.txtファイルを使用してAIクローラーをブロックする方法について記載しています。

## OpenAI
OpenAIでは、Webクロールとブラウジング用に2つのユーザーエージェントが存在し、それぞれ独自のCIDRとIPアドレス範囲があるため、ご注意ください。

### Bot
[GPTBot](https://platform.openai.com/docs/gptbot)のユーザーエージェントによって、クロールされたWebページは、将来のモデルを改善するために使用される可能性があります。

[ChatGPT-User](https://platform.openai.com/docs/plugins/bot)については、プラグインによって使用されます。このユーザーエージェントは、ChatGPT ユーザーに代わって直接アクションを実行するためにのみ使用され、自動的にWebをクロールするためには使用されません。

GPTBotのIPアドレス範囲は、[gptbot-ranges.txt](https://openai.com/gptbot-ranges.txt)から確認できます。ChatGPT-Userについては、[IP egress ranges](https://platform.openai.com/docs/plugins/bot/ip-egress-ranges)をご参照ください。

以下は、筆者が運用しているWebサーバのアクセスログよりGPTBotからアクセスされた出力例です。

```console
52.230.152.148 - - [04/Jul/2024:11:26:52 +0900] "GET /robots.txt HTTP/1.1" 200 77 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.2; +https://openai.com/gptbot)"
```

### robots.txt
OpenAIをブロックするためには、`robots.txt`ファイルに以下の設定を追加します。

```text
User-agent: GPTBot
Disallow: /
User-agent: ChatGPT-User
Disallow: /
```

## Perplexity
Perplexityは、Webクローラーを使用してインターネットから情報を収集し、検索エンジン用にインデックスを作成します。

https://www.wired.com/story/perplexity-is-a-bullshit-machine/

### Bot
[PerplexityBot](https://docs.perplexity.ai/docs/perplexitybot)の情報を基に識別できます。

IPアドレス範囲は、[perplexitybot.json](https://www.perplexity.ai/perplexitybot.json)から確認できますが、Perplexityは`robots.txt`ファイルを無視してファイアウォールを回避していたとのことです。

[perplexitybot.json](https://www.perplexity.ai/perplexitybot.json)で公表していないIPアドレスを持つサーバ上で稼働している自動Webブラウザーを使用していたと言われています。

### robots.txt
Perplexityをブロックするためには、`robots.txt`ファイルに以下の設定を追加します。

```text
User-agent: PerplexityBot
Disallow: /
```

## Google
2023年9月28日、Webパブリッシャー向けに、コンテンツへのアクセスを制御する機能として、Google-Extendedが提供されています。

- [An update on web publisher controls](https://blog.google/technology/ai/an-update-on-web-publisher-controls/)

### Bot
Googleクローラーとフェッチャーが使用するユーザーエージェントは、[Google クローラーとフェッチャーの概要（ユーザー エージェント）](https://developers.google.com/search/docs/crawling-indexing/overview-google-crawlers?hl=ja)から確認できます。

Googleについては、BotをブロックするためのCIDRやIPアドレス範囲の情報を提供していません。

### robots.txt
GeminiアプリとVertex AIをブロックするためには、`robots.txt`ファイルに以下の設定を追加します。

```text
User-agent: Google-Extended
Disallow: /
```

# おわりに
生成AIを使うことも大事ですが、許可なくデータを使用してモデルをトレーニングされないようにするための知識を身に付けておくことも重要です。

なお、robots.txtはクローラーの巡回を制御するための方法になるため、クローラーによってはPerplexityの様に無視するクローラーも存在するため、必要によってはファイアウォールの設定などの検討が必要です。

## 参考
- [robots.txt の概要](https://developers.google.com/search/docs/crawling-indexing/robots/intro?hl=ja)
vi、ご存知ですか？

## エディタ何を使ってますか？

----
## viとは
- 誤解を恐れずに言えば、キーボードショートカット**しかない**テキストエディタ
- 行指向、つまり行単位での操作が基本

----
## とっつきにくさの理由
- あまりに特殊な操作系！
- ターミナルで使うことが前提なだけに、見た目では使い方がわからない！
- タスク指向の塊！

・・・だが、使えるようになると圧倒的な効率を発揮する

----
## vi(m)を使わざるを得ない局面
- Linux：Linux組み込みのエディタは多くの場合vi系
  Linuxが嫌われる理由の半分はこれだと思っています（本気度50%）

----
## viの利点
- コーディング向きの機能が多い
  コーディングは編集している時間より移動している時間の方が長かったりする
- 速さ：マウスが不要／行指向／数々の編集操作　などで編集効率が上がる
  これが欲しくてvi系を使う
- 柔軟なカスタマイズ性

----
## これだけ知っておけばとりあえず大丈夫な操作
- モード：移動モードと編集モード
- 移動モード時
  k：上に移動
  j：下に移動
  h：左に移動
  l：右に移動
- 編集モードに入る
  i
- 編集モードから抜ける
  ESC
- 保存
  (移動モードにて):w<Enter>
- 終了
  (移動モードにて):q<Enter>
- 保存せずに終了
  (移動モードにて):q!<Enter>

----
## Windowsで使うには
- GVim
- Netvim

----
## 正直、日本語の入力には向きません！
- 普段使いのエディタとしては厳しい
- 威力を発揮するのはコーディング
  Visual Studio CodeやVisual Studioのキーバインド（ショートカット設定）をvim風にすることが可能！

----
# 最後に
UI設計は、タスク指向ではなくオブジェクト指向で！と言っているのに、viを進めるのはダブスタじゃないか！という批判はあると思います。
それは甘んじて受け入れましょう。だってviを練習すると明らかに世界が変わるから、仕方ないです。

興味のある方はぜひ、騙されたと思って一度練習してみてください。
もし「やっぱり騙されたじゃん！」となったときは・・・全力で謝ります。
LeetCode挑戦日記：Day28

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 649. Dota2 Senate

Dota2の世界には、RadiantとDireという二つの党派があります。

Dota2の上院は、これら二つの党派から来る上院議員で構成されています。
上院はDota2のゲームに変更を加えるかどうかを決めたいと考えています。
この投票はラウンドベースで行われます。
各ラウンドで、各上院議員は以下の二つの権利のいずれかを行使できます：

1. **他の上院議員の権利を禁止する**: 上院議員は、他の上院議員がこのラウンドおよび以降のラウンドで全ての権利を失うようにすることができます
2. **勝利を宣言する**: 上院議員は、投票する権利を持つ上院議員が全て同じ党派から来ていることを確認した場合、勝利を宣言し、ゲームの変更を決定することができます

各上院議員の党派を表す文字列`senate`が与えられます。
`'R'`と`'D'`の文字はそれぞれRadiant党とDire党を表します。
この文字列のサイズは`n`で、`n`は上院議員の人数です。

ラウンドベースの手続きは、与えられた順序で最初の上院議員から最後の上院議員まで進みます。
この手続きは、投票が終了するまで続きます。
権利を失った上院議員は、この手続き中にスキップされます。

すべての上院議員は十分に賢く、自分の党派のために最善の戦略をとると仮定します。
最終的にどの党派が勝利を宣言し、Dota2ゲームの変更を決定するかを予測してください。
出力は`'Radiant'`または`'Dire'`とします。

## 素直に解いてみる

### 考え方

1. `senate`文字列の先頭から確認する
1. 各党派毎の権利が残っている人を配列に入れ、権利がなくたった人をその配列から取り除く
1. どちらかの党派だけになったらレスポンスを返す

### コーディング

```typescript
function predictPartyVictory(senate: string): string {
    const senators = senate.split('');
    let radianter = senators.filter((senator) => senator === 'R').length;
    let direr = senators.length - radianter;

    let radiantBannedCounter = 0;
    let direBannedCounter = 0;

    while (radianter && direr) {
        const senator = senators.shift();
        if (senator === 'R') {
            if (radiantBannedCounter) {
                radiantBannedCounter--;
                radianter--;
            } else {
                direBannedCounter++;
                senators.push(senator);
            }
        } else {
            if (direBannedCounter) {
                direBannedCounter--;
                direr--;
            } else {
                radiantBannedCounter++;
                senators.push(senator);
            }
        }
    }

    return (radianter) ? 'Radiant' : 'Dire';
};
```

### 結果

Runtime：71ms
Beats 69.70%

Memory：54.28MB
Beats 55.05%
perplexi　概要調査　入門編

# perplexityとは

https://www.perplexity.ai/

Perplexity AIは、最新の自然言語処理技術を活用した対話型AI検索エンジンです。以下にその主な特徴をまとめます
1. 日本語対応: 質問と回答を日本語で行うことができます
1. アカウント不要: ログインや登録なしですぐに利用可能で、手軽に使えます
1. **最新情報の提供**: OpenAIのGPTモデルとMicrosoft Bingの検索機能を組み合わせ、最新データに基づいた回答を生成します
1. **出典の明記**: 回答には情報源が明記されるため、ユーザーは提供された情報の信頼性を確認できます
1. 無料利用: 基本機能は無料で利用でき、有料プランではさらに高度な機能が利用可能です
1. **多様な用途**: 日常生活での情報検索から、ビジネスでのリサーチまで幅広く活用できます

Perplexity AIは、使いやすさと高度な機能を兼ね備えた革新的なAI検索ツールとして、情報収集や問題解決の新たな手段として注目を集めています。

## 出典の明記がされている
私は、Perplexityの一番の魅力は最新情報を提供してくれる点だと思います。例えば、pandasの処理を早くしたいときにPerplexityに質問すると、速度改善に関する具体的な回答と、その回答のもとになった出典元も一緒に表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647606/8c54e09b-6e32-a0af-e6f3-e667e92538b8.png)

ここが、ChatGPTとの違いだと思います。ChatGPTに聞いてみると、写真のように回答されるもののその出典元はわからないようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647606/6f3ca99a-36f3-da97-05ef-a1068662424c.png)

出典の明記されることで**AIからの誤情報（ハルシネーション）の判断ができるようになりました。**

## 最新情報の提供
個人的に、出典元の明記に加えて、最新情報が提供される点がPerplexityの大きな魅力だと思います。
例えば、「今週のAI関連のトップニュースをいくつか教えて」と聞くと、写真のように最新の情報を教えてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647606/3db89ed0-e83b-e2ad-a958-8c36f3e81458.png)

また、技術関連の情報だけでなく、「今週末、東京でデートにお勧めなイベントを教えて」と聞いても、素敵なイベント情報を提供してくれます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647606/1038910a-831b-dd0a-3b16-9765526c3520.png)


## 無料版と有料(Pro)版の違い
Perplexityには無料版と有料版の機能があります。
- 無料版
    - 日本語での質疑応答
    - 出典元の記載
    - ファイルの分析（制限有）
    - 画像生成（制限有）
- 有料版
    - **AIモデルの選択が可能（Gemini,GPT-4など）**
    - ファイルの分析（無制限）
    - 画像生成（無制限）

制限はあるものの、無料版でも有料版の機能の一部が利用可能です。まずは無料版を試してみて、必要に応じて有料版に切り替えるのが良いでしょう。 有料版の価格は、ウェブ版で月額20ドルです（本記事執筆当時）。iOSやAndroidの価格は異なる場合があるため、利用するデバイスに応じて確認してください。

https://www.softbank.jp/mobile/service/perplexity-ai/

※ソフトバンク、ワイモバイル、LINEMOのユーザーは、有料版を無料で利用できるキャンペーンも実施中です。該当するユーザーはこの機会に試してみるのも良いかもしれません。




## 最後に
従来の検索エンジン（Google検索など）では、検索ボックスに単語を入力し、表示されたサイトから目的の情報を探す作業が必要でした。しかし、これからはPerplexityを使うことで、検索ボックスに単語を入力するだけで、AIが検索結果をまとめて提供してくれます。これにより、効率的に情報を取得できるようになり、時間と労力を節約することができます。ぜひ、新しい検索体験をお試しください。
【Laravel11】Roach PHPの  The current node list is empty. エラーについて

# はじめに

こんにちは、エンジニアのkeitaMaxです。

今回はRoach PHPを使用していた時に`The current node list is empty.`というエラーが出た時の話をします。

# エラー内容について

スクレイピングを実行した時に以下のエラーが出ました。

```
The current node list is empty.
```

実際のコードは以下のような感じです。

```
$subtitle = $response
    ->filter('main> div:nth-child(2) p:first-of-type')
    ->text();
```

サンプルと同じですが、指定しているURLを修正したので、`'main> div:nth-child(2) p:first-of-type'`ここでしている要素では` ->text()`がとれずにエラーになってしまっているようです。

# 解決策

解決策は簡単で、エラーが出ている箇所が以下のようにInvalidArgumentExceptionをthrowしているため、エラーをキャッチしてあげれば解決します。

```
throw new \InvalidArgumentException('The current node list is empty.');
```

具体的には以下のようにします。

```php
try{
    $title = $response
        ->filterXPath('descendant-or-self::main/div[2]//p[1]')
        ->text();
    yield $this->item([
        'title' => $title ?? '',
    ]);
}catch(InvalidArgumentException $e){
    echo($e);
}
```


# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！
削除したランディングページを復元する方法




+ [Pardot Lightning アプリのランディングページを復元する方法](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000HmcymSAB)

:::note
新しいランディング ページ ビルダーは Pardot ではなく Salesforce にあるため、どこかにあるとすれば Salesforce のごみ箱にあるはずです。これをテストしたところ、これらの種類のランディング ページは「削除済み」フラグが付けられた状態でデータベース内にありますが、ごみ箱には表示されず、復元できないことがわかりました。
:::

+ [Restoring deleted version of a classic landing page](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epyCZSAY)
WEBサービスの防災訓練のすゝめ

## 防災訓練概論

以前東証一部の大手企業に勤めていた際、地震や火事を想定して、防災グッズやヘルメットが社員一人ひとりに配られたり、定期的に各部署から1人が実際に火事などを想定して避難するなどしていました。

が、今回お話したいのは、「WEBアプリケーションの防災訓練」です。どんな災害を想定しているかと言うと

- なんか知らんけど、サービスがダウンしている
- ランサムウェアにサービスを乗っ取られた
- DDos攻撃でサイトに繋がりづらくなった
- 新人が間違った操作で本番のデータ、本番環境を壊してしまった
- 重大なセキュリティホールが見つかり、意図しない個人情報が閲覧出来てしまった
- 新しい機能をリリースしたら、バグだらけで、ユーザーがお怒り
- etc

### そもそも防災とは

災害対策基本法によると、防災とは「災害を未然に防止し、災害が発生した場合における被害の拡大を防ぎ、及び災害の復旧を図ることをいう」と定義されています。

WEBサービスの災害も、未然に防ぐ事が出来れば理想ですが、防ぎようのない攻撃や、人災・人的ミスは必ず何かしらの形で起きます。ですので、WEBサービスにおける防災では、万が一の事態を想定して、**被害の拡大を防ぎ、及び災害の復旧を図る**がその目的となります。

災害が起きた時、

- サービスがいつまで経っても復旧しない
- 個人情報が流出し続ける
- 新たに怒り出すユーザーが現れる
- 復旧作業に失敗して、二次災害(破壊的なデータ損失)が発生する

などの事態を未然に防ぐことが防災です。

### 防災訓練とは

リアルな防災訓練と基本は同じです、緊急事態を想定して、実際の動き方を実践します。

- どうやって避難するのか？
- 防災グッズはどこにあるのか？
- 防災グッズはどう使うのか？

と同じ様に

- どうやってバグ前の状態に戻すのか？
- サーバのログやヘルスメーターはどこにあるのか？
- 万が一の時の手順書はどこにあるのか？
- 手順書通りに本当にできるのか？

を事前に展開、開発環境を使って実演、不手際や不足を洗い出し、対策を講じることで、いざという時に備える事がまさに防災訓練といえます。

## 防災訓練のこころえ4選

リアル防災訓練のこころえや、実際にWEBの防災訓練を通じて、私は以下の4つが大事という結論に至りました。


1. **役職・部署を問わず、多くの人が参加せよ**
1. **明確な目的・目標を定めよ**
1. **具体的な災害状況を設定せよ**
1. **シナリオを変えよ**

### 1.部署・役職問わず、多くの人が参加せよ

災害が盆暮れ正月に起きて、防災訓練に参加した人が誰も居ない…みたいなケースは十分想定されます。その際、「本番環境に入れません」「インフラの事わからないので、操作出来ません」と、管理者や防災訓練を受けた人が来るのを指を加えて待っているだけ、という状況がまさに最悪です。

#### 管理者不在の罠
サービスをよく理解している担当者、管理者だけが参加しておけば…みたいな甘い気持ちはNGです。かならず、その人たちが不在な状況を想定して、より多くの人が参加しましょう。

#### 部署の壁の罠

災害は部署を跨ぎます。サービスが別だから分からない、自分たちの部署の範囲だけ防災訓練をすればよいというわけではありません。部署間横断で必ず行いましょう。

#### トップダウンの重要性
他部署の防災訓練に積極的に参加する企業文化が無い、なんてこともあるでしょう。故に、上位マネージャーがトップダウンで「絶対に参加しろ」と伝える事が非常に重要になります。


### 2.明確な目的・目標を定めよ

避難訓練は、参加者が「当事者意識」を持ち、積極的に訓練に取り組む必要があります。故に、訓練自体にはっきりとした目標を定めておく必要があります。訓練前に「プラン通りで対処できるかの確認」「操作マニュアルに不備がないかの確認」「初参加が実際に手を動かし、知識や経験を積む」「ログを取得、読めるようにする」などの訓練の目的を設定し、参加者に伝えておくと、より効果の高い訓練になります。

#### 惰性で参加しない為の工夫
目的・目標を設定せず、ただ単に話を聞いてオシマイ、だといざという時に本当に役に立ちません。実際に手を動かしたり、過去に訓練を受けた人には講師役をお願いするなども効果的です。

### 3.具体的な災害状況を設定せよ

防災訓練の質を上げるためには、具体的な災害状況の設定が不可欠です。曖昧な内容では、参加者も当事者意識を持って、訓練に取り組むことができません。サービスは利用状況、感染の有無、原因が不明かあたりがついているか、などの被害状況は、より具体的に設定しておきましょう。それによって、より具体性のある防災訓練が実現できます。

#### 過去に起きた災害のトレース

過去に起きた災害があれば、訓練には取り込んでおきましょう。その時に実際に行った作業をトレースし、当時のトラブルを再発しないかなど見直すことで、実際の訓練の成果が可視化出来ます。

#### ダブルチェック・声出しの重要性

災害状況を具体化することで、より具体的なアクションや操作が明確になります。その際、ダブルチェックで、声を出して行うは二次災害を防ぐ上で非常に重要です。

### 4.シナリオを変えよ
毎回同じシナリオで防災訓練を行えば、参加者は積極的に訓練に取り組みづらくなります。訓練ごとに、起きたサービス、災害の内容を変えることで、より効果のある防災訓練が実現します。他部署の環境を実際に操作することで、サービスの構成や、使っているインフラなどの理解もすすみ、組織全体の知識レベルが上がることにも寄与します。

## 具体的な取り組みの例の紹介

#### 切り戻し対応
- シナリオ
    - リリースに致命的なバグを仕込んでしまった
- 災害状況
    - その機能があることで、重要な別の機能が使えなくなった状況
    - ユーザーからクレームが入り、返金騒動に発展しそう
- 目的・目標
    - 1つ前のバージョンのリリースに本番環境を戻す
    - 上記操作を全員が出来るようにしておく


#### サービスの強制ダウン
- シナリオ
    - サーバ内にトロイの木馬やランサムウェアが入り込んだ
- 災害状況
    - サービスは生きている
    - サービスサーバが利用可能な状態、ネットワークにつながった状態だと、被害が拡大する
- 目的・目標
    - サービスサーバを落とす
    - サービスサーバより前、ロードバランサ時点で、メンテナンス画面を掲示する
    - 手順書やプラン通りで対処できるかの確認
        - ※サービスによってロードバランサの種類がちがったりして、共通手順が機能しなかったりする

#### 原因究明の高速化
- シナリオ
    - サービスがダウンしているが、原因が不明
    - 実は異常トラフィックが発生しており、サーバのリソースが足りなくなってしまっている
- 災害状況
    - サービスが断続的にアクセス不能になっている
    - 直近週間は特にリリースをしておらず、安定稼働している
- 目的・目標
    - 原因究明を若手エンジニアも出来るようにする
    - ヘルスログの場所、見方を知ってもらう
    - 実際に操作して、ログの画面まで行ってもらう
MonoBrickを選ぶメリット

# EV3 OSとは
EV3には様々なOSが存在します。
デフォルトOSを除き、世の中に存在するサードパーティ製のEV3 OSはSDカードにOSデータを入れ、起動するものです。

サードパーティ製のEV3 OSを利用する理由は主にこんな感じです。
1. 慣れた言語でコーディングできる。
2. 動作によってはデフォルトOSより速い。
3. デフォルトOSにはない機能が存在する。
4. ~~(EV3の大会などで)つよつよに見える。ドヤれる。~~

じゃあ実際にどのOSがいいのかということで、いろいろなOSを実際に使ってみました。
| OS | 言語 | 特徴 |
| -- | ---- | ---- |
| [デフォルト](https://afrel.co.jp/product/ev3-introduction/) | ブロック | 速度が速く、プログラムが楽 |
| [ev3dev](https://www.ev3dev.org/) | Python, Java, Go, C, etc | 言語数が豊富だが起動が遅い |
| [EV3RT](https://dev.toppers.jp/trac_user/ev3pf/wiki/WhatsEV3RT) | C | コンパイル言語だから起動、動作が速い |
| [MonoBrick](http://www.monobrick.dk) | C#, F#, IronPython | Monoをベースに.NET  Frameworkが動く |
| [leJOS](https://lejos.sourceforge.io) | Java | 機能が充実している |

# なぜMonoBrickなのか
## 利点
### 起動時間
まず起動時間が速く、1分で起動します。いつもデフォルトOSを使っている人にとっては遅いでしょうが、ev3devが3分ほどかかるのでいつもev3devを使っている人にはとても速く感じます。
1分というのはサードパーティ製のEV3 OSの中では、平均より少し早いぐらいでしょうか。
でもev3devユーザーが多いので利点とします。
### メニュー
MonoBrickではプログラムの中からメニューを呼び出すことができます。
これにより、プログラムのランチャーなどが作りやすくなります。また、同時にキーボードも表示できるます。
### フォント
他のEV3 OSではフォントは最低限のデザインでしかありませんが、MonoBrickのフォントは大きく読みやすくなっています。
## 欠点
### 開発終了
MonoBrickは既に更新されていません。MonoBrickの最新バージョンは2015年です。これは各OSの最終更新がev3devが2020、EV3RTが2021なのをみると、非常に古いです。更新されていないと問題も発生するものなので、嫌な人は他のOSを使いましょう。
### Bluetooth
MonoBrickでは基本的にBluetoothが使えません。詳しく説明すると2016年にEV3のBluetoothの規格が変更され、MonoBrickでは動かなくなりました。
### 機能
メニューがこれでもかというほど最小限です。できることがほとんどありません。
メニューの操作性が悪いです。一番上から一番下にワープされません。いちいち下ボタンを連打する必要があります。
【ポエム】43インチモニタを縦置きにしたら生産性が爆上がりした件

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/f5bc192d-4bdf-5d05-5426-e865613a96d6.png)](https://www.freepik.com/free-photo/vertical-computer-screen-office-surroundings_2436928.htm)


# 背景
- 4K 43インチモニタは中古で1万円代から手に入る時代になってきた
- ASUS [Zenbook Pro 14 Duo OLED](https://pc.watch.impress.co.jp/docs/column/hothot/1571233.html)、[VAIO Vision+ 14](https://pc.watch.impress.co.jp/docs/column/hothot/1604348.html)みたいな製品も出てきた
- みんなモニタを横より縦につなげたほうが良いのに気づいてきた

# 解像度
- 縦に長めの21インチモニタが3枚つながってる感じになる
- それぞれのウインドウサイズは2160x1280だからフルHDよりちょい大きめ
- 最近のノートで主流になってきた1920x1200みたいな解像度で使える


# 生産性のメリット
- 縦長のPDFとかWordがめちゃくちゃ見やすい
- Webサイトももちろん見やすい
- たぶんコードとかプレビューウインドウの分割も広く使えると思う

# 健康のメリット
- 首を横に振るより縦のほうが無理がなさそう？
- 姿勢が良くなる

# システムのメリット
- Win11で3分割がカンタンになったこともある
- Win10だとこの機能がないので厳しいです
- Macはどうなのでしょうね
-![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/d13d2a8b-097f-53fa-261f-2bb3787676b5.png)

# デメリット
- デカい。職場に置いたらかなり目立つ。
- 常に姿勢をよくしないといけないので疲れる（健康とのトレードオフ？）
- 机は低め、椅子は高めにして真ん中のウインドウの視線くらいに調整する必要がある
- Web会議用の画面投影は、そのまますると相手からなにこれと言われてしまう（たぶん）
- その場合はノートPCをつなげばいいと思います

# なぜ43インチから？
- 43インチより小さいと、19インチモニタ×3相当以下になり、DPIが小さくなって結局拡大125%とかに拡大しないといけなくなります。
- そうすると本来の目的とは遠のいてしまいます（フルHDよりは広いですが）。

# まとめ
- 生産性爆上がりはちょっと言い過ぎかもしれませんが（もともと高くないので💦）。
- 伝統的なフルHD一枚のモニタとは作業範囲が比較にならないのは事実です。
- デザインやプログラムのプロの方は2枚を縦置きにされてみてもいいかもしれませんね。


# ポエム
- 職場でもこういうのが許可されてみんなでハッピーになれればよいのですけどねー。
- 「みんなお古のちっちゃいノートPCでがまんしてるんだ！」みたいなタコつぼ化は、日本の労働環境では確かにあるのかもしれません。
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/02356b1e-804b-ab99-dab8-9e84473d9f6e.png)](https://www.freepik.com/free-photo/close-up-adult-woman-working-office_20033752.htm)
- 社員の福祉が生産性につながることが分かっている経営者ほど、16GBのPCとかのIT投資にも熱心だと思います（主観）。
- 「みんなで気合いれていこう！」より4Kモニタをさっくり配ったほうが売り上げ上がったりする時代なのかも。


# さいごに
- デカすぎて目立つ？だったら社員全員43インチにユーしちゃいなよ。
- [バランスボールを職場に導入](https://www.intellim.co.jp/rintellim/rintellim_20130528.html)したところも最初は奇異に映ったでしょうし。既成概念なんて案外そんなもんです。


# 追記
- すでにやってるとこありました。
https://assets.bwbx.io/images/users/iqjWHBFdfxIU/iLp.WOEx77Rc/v2/-1x-1.jpg
浮動小数点数の誤差は怖いよって話

### はじめに
コンピュータで浮動小数点数を用いて演算した場合，ちょくちょく誤差が発生することがある．

たとえば，2.104136という数字を1000000回足した場合と，2.104136に1000000を掛けた場合では，演算結果が異なる．

どれくらい結果に違いが出るのか，見てみましょう．

### ちょっとプログラムを書いて試してみます

```Python
# 2.104136を1000000回足す
sum = 0.0
for i in range(1000000):
    sum += 2.104136

# 2.104136に1000000を掛ける
product = 2.104136 * 1000000

# 結果を表示（小数第10位まで）
print("2.104136を1000000回足した結果: {:.10f}".format(sum))
print("2.104136に1000000を掛けた結果: {:.10f}".format(product))
```


### 実行結果

実行したらこんな感じでした．
"2.104136を1000000回足した結果"と"2.104136に1000000を掛けた結果"では，0.0000318480も差分が出てしまうということですね．怖いですね！

```
C:\test>python fudo_test.py
2.104136を1000000回足した結果: 2104135.9999681520
2.104136に1000000を掛けた結果: 2104136.0000000000
```
放置サービスの痛い思い出

# これはなにか？

個人で作っていたWebサイトや、昔業務で運用していたサービスなど、メンテナンスせずに放っておいたことによってのちのち痛い思いをした話になります。

# 何がおきたのか？

昔勤めていた会社では、`非注力`をいう言葉がありました
どういうことかと言うと、そこまで手（人的コスト）はかけられないけど、売上があるので終了することはできないサービスになります
そのため、ほぼ放置状態となりますが、何かあれば対応するということになります:warning:

放置期間が長ければ長いほど、対応コストはどんどん高くなります

セキュリティーパッチが当たっていない
OS・アプリケーションがEOLを過ぎている
アップデートしようにも、段階的にアップデートしないと最新版にならない
メジャーバージョンが変わって動作しないメソッドがある
Gitなどでコード管理してデプロイする環境とかあったのに動かない

結果的に、今動いている環境を直接編集して、その場を乗り切る感じになります
エイヤーのぶっつけ本番です

## どうしてこうなるのか

理由はいろいろあると思います
- サービスを作った人が異動・退職された
- ドキュメントはあるが、古文書みたいになってしまっている
    - ドキュメントはあるが、どこにあるか忘れてしまった
    - ドキュメントがない
- ドキュメントに書いてある通りに環境が作れない
    - ローカル環境で動作環境が作れない
- デプロイの仕方が分からない
    - どうやら秘密鍵のようなファイルが必要だけど見つからない

などなど

総じて言えるのは、人の手が入らないサービスはノウハウが途絶えるということです

## こうならないために……

サービスが運用されているということは、なんらかのプラットフォーム上で、なんらかのミドルウェアの上で、なんらかのプログラムが実行されているわけです

### ノウハウを途絶えさせない

よい解決方法に巡り合っていないです:sob:
現時点の担当者が、劣化することなく次につなげていくしかない気がします
そして、最低限の手をかけられる状態を作れるためのドキュメントやアプリケーションのアップデートをする

### 動作している環境の情報をキャッチ

非注力ながらでも、情報の取得は必要になります

- 稼働しているプラットフォームの情報をキャッチ
- プログラムを動作させているミドルウェアの情報をキャッチ
- 利用しているプログラムの情報をキャッチ

もしかしたら他サービスが同じ環境でとかで、ある程度情報共有してもらえれば補えるところはあると思います

# 最後に

作ったサービスは、終了を迎えるまで放っておかず、手をかけてあげましょう
最低限、手をかけられるように掛け合ってみて、説得してみる

サービスに愛をもって接してあげましょう
ラブ＆ピース:v:
Javaで「文字列から開始と終了インデックスを指定して部分文字列を取得する」の動作を確認してみた

# 概要

Javaで「文字列から開始と終了インデックスを指定して部分文字列を取得する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/string/index7.html

# 実装

以下のファイルを作成しました。
```JSample7_1.java
class JSample7_1{
  public static void main(String[] args){
    String msg = "東京都港区赤坂";

    System.out.println(msg.substring(3, 5));
    System.out.println(msg.substring(5, 7));
    System.out.println(msg.substring(3));
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample7_1.java 
$ java JSample7_1 
港区
赤坂
港区赤坂
```

# まとめ

何かの役に立てばと。