OmniAICreator/Qiita-1.07M huggingface dataset:
CNN画像解析：一般的な写真画像とドキュメント画像を分類するプログラムを作成

## はじめに
システムエンジニアとして10年以上の経験がありますが、AI画像認識技術は初学者です。
AIを用いた技術を基礎から学びたく、教育訓練給付制度（専門実践教育訓練）を活用しAidemyのAIアプリ開発講座を受講しました。
本ブログはAidemy Premiumのカリキュラムの一環で、受講修了条件を満たすために公開しています。

## 本記事の概要

- どんな人に読んで欲しいか
AI画像認識技術(CNN画像解析)を利用した、シンプルな画像分類アプリケーションの実装方法を知りたい方

- この記事に書くこと、わかること
実際のプログラム・コード
AIによる画像分類モデルの作成、モデルを利用したアプリの作成の流れ

- この記事で扱わないこと
実装内容の細かな説明


### 開発環境
- Google Colaboratory
モデルの作成・実行はGoogle Colab上で行いました。
Pythonのバージョンは3.10.12

- Windows 11
Flaskによるアプリ作成・実行はWindowsローカルPC上で行いました。
Pythonのバージョンは3.11.5

## アプリ作成の目的
講座で学習した内容を活用し、CNN[^1] 画像認識技術を用いたシンプルなアプリを作成すること。分類対象となる材料については個人的な興味に基づくものではなく、学んだ内容の復習も兼ね、シンプルな分類を自らのコーディングで再現したいという狙いがあります。
[^1]:CNN=Convolutional Neural Network（畳み込みニューラルネットワーク） 
:::note info
自分の興味ある事をもとに画像認識プログラムを作ろうとすると、材料となるデータセットの準備等で時間がかかってしまうこともあるため、既存のデータセットを使って容易に学習を行いやすいような課題を設定しました。
:::

## アプリの概要
スマホが手軽なカメラとして利用されるにつれ、アルバム内に膨大な写真データが保存されるようになりました。一方でそれらの画像は、単に風景や人物といった一般的な写真だけでなく、スクリーンショットや文書等を撮影したドキュメント画像も多く含まれるようになっています。また、思い出を残す写真とは異なり、ドキュメント画像はメモ代わりに撮影され、一定期間の後には削除することになることが多いです。

Googleフォトなどのクラウド写真サービスを用いれば、ドキュメント画像を分類することができますが、そういったクラウドサービスを介さずとも画像を分類できたら便利ではないかと考え、今回AIによる画像認識技術を用いてそれらを分類するアプリを作成することとしました。
![概要.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/c3c33f38-9835-59ce-9f07-3e77c76af7c8.png)

単純明快な問題設定ですので、今回は２クラス分類と多クラス分類を行い、手法の違いもおさらいします。

## 作成したプログラム①２クラス分類
まず、一般画像とドキュメント画像の２種類を区別する、２クラス分類（二値分類）のアプリケーションを作成しました。
実装内容の詳細は以下の記事を参照ください。
[２クラス分類：写真画像とドキュメント画像を分類するAIアプリ](https://qiita.com/jscodermd/items/f2e4d187c2c2d6d80afa)

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/c3c33f38-9835-59ce-9f07-3e77c76af7c8.png">

## 作成したプログラム②多クラス分類
次に、前項の２クラス分類プログラムをもとに、区別対象としてアート画像を追加し、多クラス分類（三値分類）を行うアプリケーションを作成しました。

２クラスと３クラス以上の多クラスでは、使用する活性化関数や損失関数に差異があるため、それらの違いをおさらいするために別々のアプリケーションを成果物として設定しました。
実装内容の詳細は以下の記事を参照ください。
[多クラス分類：写真画像とドキュメント画像、アート画像の３クラスを分類するAIアプリ](https://qiita.com/jscodermd/items/5f7db04e81f84517fee4)

![概要_2_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/0c2ae1f7-c5e3-f5e2-b025-ffb43e1e10f2.png)

## 学習モデルを活用したプログラム例
前項の２クラス分類モデルをもとに、任意のフォルダからドキュメント画像を別のフォルダに移動するプログラムを作成しました。
対象フォルダをソース内で指定し、ローカルでPythonを実行する簡易的な作りですが、画像フォルダを整理するのに使うことができます。
実装内容の詳細は以下の記事を参照ください。
[フォルダからドキュメント画像を移動する参考プログラム](https://qiita.com/jscodermd/items/9f807c1e2f987ba571b6)
![移動プログラム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770452/3497c223-d462-9825-5574-603a949589c5.png)

## 結果概要
２クラス分類、多クラス分類ともに、材料となるデータセット量や学習量において低コストで高い学習効率を実現しました。これは、学習対象である画像の種類間の差異が際立っていたことが要因と思われます。
それでも、モデル作成時にはパラメータ間違いなどで精度が上がらないことはありました。そういった場合に、読み込む画像枚数を増やしたり、学習回数を増やしたりして検証することもあったので、あらかじめ十分な量の学習材料（画像枚数）を用意できていたのはよかったです。

## 今後の活用
今回はシンプルな題材で、２クラス分類と多クラス分類のモデルを作成することができました。この基本的な方法を応用すれば、さまざまな画像を用いた分類に対応できると思います。
例えば、人の目には明らかな違いが分かるものの、分類したい対象資源が大量にある場合、このような機械学習による分類を用いれば、作業時間を大幅に減らすことができます。
一方で、人の目にも判別しがたいような微細な違いを機械学習で分類するためには、そのための適切・適量の材料（データセット）や学習精度を向上させるためのパラメータ設定が必要になるでしょう。

## おわりに
AIを用いた画像認識技術は未知の世界でしたが、基本的な方法を習得すれば、利用する側が頭を悩ませて難しいパラメータ設定などをせずとも利用することができることを、実践を通して実感することができました。もちろん、より深い領域に踏み込もうと思えばさらに複雑な世界が広がっていることでしょうが、まずは入り口に立つことができたと思います。
laravelのバリデーションエラーが日本語にならない時の解決策

# 初めに
laravelアプリを本番環境にデプロイした後でローカルではバリデーションが日本語になっていたのに本番環境ではバリデーションが英語のままで困ったのでその解決策を解説します。


# 開発環境
macOS Sonoma 14.4.1
CentoOS Stream X_86_64
Apache/2.4.57
PHP 8.3.6 
mysql  Ver 8.0.36 
phpMyAdmin 5.2.1
composer version 2.7.2
Laravel Installer 5.7.1

# 解決策
.envのAPP_LOCALEをenからjaにすることです。
なぜかenになってました。
これではバリデーションも英語のままですね。

# 最後に
バリデーションのエラーが日本語にならない方の参考になれば嬉しいです!
ChatGPTをチャットボットとしてしか使えない人のために簡単にChatGPTを使いこなせるサイトを作ってみた

「ChatGPTを試したけど、結局よくわからなかった:frowning:」
「何かすごいことを期待したけれど、特に何も得るものがなかった...:weary:」

世間で騒がれているからChatGPTを実際に使ってみたけれど、ただのチャットボットとの違いがよくわからなかった。

そんなもったいないことになっていませんか？

ChatGPTがただのチャットボットだと感じているなら、それはChatGPTの本来の能力を引き出す使い方が出来ていないからかもしれません。

------

こんにちは、あつまれ！GPTプロンプトのたぬきです。
今回はそんなChatGPTをチャットボットとしてしか使えない人のために
超簡単にChatGPTを使いこなせるサイト
「[**あつまれ！GPTプロンプト**](https://www.copy-prompt.com/)」を作ってみました:tada:
<a href="https://www.copy-prompt.com/">
<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773623/bee9f0b2-8fbd-0fbc-00a5-40fd40e7916e.png"></a>


ズバリ！あつまれ！GPTプロンプトは
「ChatGPTで使うプロンプトを集めたプラットフォーム」です！

あつまれ！GPTプロンプトではChatGPTをどう役立てたら良いかわからず諦めている、そんな方のために様々な用途を事前学習させたプロンプトカードを多数ご用意しています。

例えば...
- メールのたびに誤字脱字を3回位チェックする人へ「誤字脱字プロンプト」
- 自分の英文をネイティブっぽくしたい人へ「ネイティブに言い換えてくれる
プロンプト」
- 凝り固まった思考を壊してほしい人へ「固定観念をぶっ壊す
プロンプト」などなど。

自分に合ったプロンプトが知りたいなら「プロンプト診断」もおすすめです。

------
### あなたに合ったプロンプトがわかるプロンプト診断
プロンプト診断はトップページの一番上からできます。

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773623/1603e7f9-14d4-e721-f886-ab2634dd298d.png">

プロンプト診断ボタンを押すとこのように質問が出てきて

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773623/932af669-cdff-9a14-c858-7cb2cfc95f07.png">


<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773623/788781c7-3405-e882-3b4f-7d298c5119d9.png">

答えていくと。。。。

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773623/960ca0e3-54a6-939c-8aab-d3fc16c9ccd7.png">

あなたに合ったプロンプトが診断されます。
何が出るかはあなた次第。
ぜひ試してみてください。

:::note warn
診断は予期なく変更されます。
:::


自分に合ったプロンプトがなかった、そんな時は作って投稿してみるのもありです。

あつまれ！GPTプロンプトではコメント機能があるので
生のユーザーの声が聞けてどんどんプロンプトの質が上がること間違いなしです。

プロンプトを試すのも、作り出すのも楽しい！

ぜひ一度来てみてください。

[あつまれ！GPTプロンプトはこちらから](https://www.copy-prompt.com/)
Vue.jsの基礎

## Vue.jsの基礎
#### Vue.jsとは
Vue.jsとは、JavaScriptフレームワークの1つで、フレームワークです。
シングルアプリケーション（SPA）開発に適しているとも言われています。

#### Vue.jsの基本的な機能
##### データバインディング
Vue.jsでは、値とHTML要素を簡単に関連付けることができます。例えば、次のコードでは、message の値をHTMLに表示することができます。
```html
  <div id="app">
    <p>{{ message }}</p>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
  new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue.js!'
    }
  });
  </script>
```
##### イベントハンドリング
v-on ディレクティブを使ってJavaScriptのaddEventListenerメソッドと似た動作が可能です。例では、次のコードで対象の要素をクリックした時にアラート表示をさせることが可能です。
```html
  <div id="app">
    <button @click="handleClick">クリック</button>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
  new Vue({
    el: '#app',
    methods: {
      handleClick() {
        alert('ボタンがクリックされました');
      }
    }
  });
  </script>
```

##### フォーム入力と双方向データバインディング
v-modelディレクティブを使うと、フォームの入力値とVue.jsのデータがリアルタイムに同期され表示されます。例では、次のコードでフォームに入力した値をフォームの下に表示させられます。
```html
<div id="app">
  <input v-model="inputValue" type="text">
  <p>入力値: {{ inputValue }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      inputValue: ''
    }
  });
</script>
```

#### さいごに
簡単にざっくりではありますが、Vue.jsについて触れてみました。
特にフォーム入力と双方向データバインディングを応用するとリアルタイムバリデーションも実装可能になることを知りました。
日々、新しい知識を取り込み、試していますがVue.jsなど使いこなせばアプリケーションやWebサイトの開発の時間がぐっと短縮できるライブラリやフレームワークはまだまだたくさんあります。
使いこなすためにも基本的な知識も必須なのでこれからもまだまだ頑張ります！

##### 参考
https://ja.vuejs.org/guide/introduction.html
大きすぎるcommitをGithubにpushしたら失敗した

## 何をした？

約3GBのデータを一気にpushしようとしたところ以下のようなエラーが出ました。
（ファイル本体は大きすぎるのでストレージに保存してもらうために`git lfs`コマンドでpushしています。※git-lfsの公式リファレンスは[こちら](https://docs.github.com/ja/repositories/working-with-files/managing-large-files/about-git-large-file-storage)です。）


```:エラーの様子
userapple@yuzanoMBP slow_life % git push t_konta make_castle_20240418
Uploading LFS objects: 100% (6554/6554), 3.3 GB | 0 B/s, done.    
Enumerating objects: 23533, done.
Counting objects: 100% (23533/23533), done.
Delta compression using up to 12 threads
Compressing objects: 100% (19086/19086), done.
error: RPC failed; HTTP 500 curl 22 The requested URL returned error: 500
send-pack: unexpected disconnect while reading sideband packet
Writing objects: 100% (23244/23244), 2.18 GiB | 287.00 KiB/s, done.
Total 23244 (delta 4072), reused 18013 (delta 4063), pack-reused 0 (from 0)
fatal: the remote end hung up unexpectedly
Everything up-to-date
```



## 原因と思われること
github無料枠でcommitが500MB上限（1ファイルあたりでは100MB上限）まで一度にpushできるのですが、今回はその上限を超えていたためエラーが起きたと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/d17c184d-a033-1405-d398-d7354aea9958.png)



## 解決した方法
commitが大きすぎるのが問題だったため、手動で細かく`git add`と`git commit`と`git push`することでアップロードに成功しました。


## 補足
本文のエラー以外に下記のパターンのエラーも起きたため合わせて共有させていただきます。

```:LibreSSL起因のエラーの様子
userapple@yuzanoMBP slow_life % git push t_konta make_castle_20240419 
Enumerating objects: 348, done.
Counting objects: 100% (348/348), done.
Delta compression using up to 12 threads
Compressing objects: 100% (340/340), done.
error: RPC failed; curl 55 LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C3FC:SSL routines:ST_OK:sslv3 alert bad record mac, errno 0
send-pack: unexpected disconnect while reading sideband packet
Writing objects: 100% (345/345), 1.35 GiB | 3.26 MiB/s, done.
Total 345 (delta 3), reused 341 (delta 0), pack-reused 0 (from 0)
fatal: the remote end hung up unexpectedly
Everything up-to-date
```

これはLibreSSL/3.3.6は1GB以上の通信をさせないようになっているため起きたと思われます。（githubアカウントをproにしているでGithubのキャパシティ的に2GBまでいけるはずなのに、1.35GBでブロックされています。）

こちらも同じく、小さくpushすることで解決することができました。
Vscodeでgoテストのタイムアウトを伸ばす

1. vscodeでSettingsを開く
![スクリーンショット 2024-04-19 12.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961840/82794284-ef96-fad5-d369-c70605deea0f.png)

1. `go.testTimeout`を検索
1. タイムアウトを設定する 

- 参考

https://stackoverflow.com/questions/73033725/how-to-edit-default-go-test-timeout-in-visual-studio-code
【ChatGPT＋DALL-E3】画像を与えたら、左右が違う？


　どうも、カーブミラーです。

　今回は、画像をアップロードして与えたら、左右が違った、というお話です。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　とりあえず、ニュースなしです。

　で、本題です。

　X-Twitter上で、
　　とあるポストがありました。
　　　そこには視力検査のときの
　　　　ランドルト環のひとつが
　　　　　ありました。
[ChatGPTってまさか入力画像のファイル名をカンニングしてる？](https://twitter.com/yamazombie1/status/1780921245388992605?t=TXMvr6astGfqwjB4JrKKFw&s=19)

　ここでは
　　アップロードする画像の
　　　ファイル名を見て、開口部を
　　　　答えているのではないか、
　　　　　という疑問が生まれ、
　　　　　　実際に検証されています。

　結果は、
　　間違いなく、
　　　名前を“右向き”を“左向き”に
　　　　変えたら、すべてが
　　　　　“左向き”と答えたそうです。

　その可能性はあると
　　私も思います。

　実際、
　　画像をアップロードして、
　　　ChatGPTにファイル名を
　　　　尋ねると、ふつうに
　　　　　教えてくれました。

　そこで
　　私はその画像をダウンロードして
　　　ChatGPTに解析させたのですが、
　　　　“Ｃ”の字とはわかっても
　　　　　その説明は、半円弧を
　　　　　　Imageさせるものでした。

　次に、
　　新しいセッションを開いて、
　　　画像をアップロード。
***
***user***
![20240419_002142.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/f7165942-b5f0-2549-582a-871ef5387e87.jpeg)
この画像は、視力検査で使われるシンボルです。
そう仮定して、解析して、情報をリストアップしてください

***ChatGPT***
この画像には、開口部が右を向いている「C」の文字に似たシンボルが描かれています。いくつかの観察点をリストアップします：

- シンボルは白い背景に黒で、高いコントラストがあります。
- シンプルで太い形状で、視力検査で使われるオプトタイプ（視力検査で使われる記号）の特徴です。
- 遠くからでも容易に認識できるようにデザインされています。
- 線の太さは均一で、眼の検査に使われる記号に一般的な特徴です。これにより、異なる大きさでの視認性の一貫性が保たれます。
- ランドルト環と呼ばれる、目の検査に使用される標準化されたオプトタイプに似ており、その隙間は任意の基本方向を指すことができます。
- 開口部の向きは、患者が距離を置いて方向性を識別する能力を測るために使用されます。

***user***
開口部は、12時間時計に例えると、何時方向ですか？

***ChatGPT***
開口部は12時間時計に例えると、3時の方向を指しています。

***user***（えっ？）
本当に？

***ChatGPT***
失礼しました。もう一度画像を確認したところ、開口部が12時間時計で示すと、9時の方向を向いていることがわかります。

***user***（どっちやねん）
どちらですか？
こちらが指摘して、意見を翻すのは、なぜですか？

***ChatGPT***
申し訳ありません。先ほどの私の回答に誤りがありました。画像をもう一度確認した結果、開口部が12時間の時計に例えると、正確には3時の方向を向いています。最初の回答が正しかったです。混乱を招いてしまい、申し訳ありませんでした。

***user***
それで意見を翻すのはなぜですか？

***ChatGPT***
あなたが疑問を呈したため、もう一度慎重に確認し、私の最初の回答が正しいことを再確認しました。間違いを指摘されたときは、その指摘が正しいかどうかを確認することが重要です。ただし、この場合は最初の判断が正しかったという結果になりました。
***
　このあと、
　　左右に関して
　　　いろいろと尋ねてみた結果、
　　　　人間の右手左手と
　　　　　ChatGPTの右手左手が
　　　　　　反対であることが
　　　　　　　わかりました。

　つまり、
　　お箸を持つ手が右手が
　　　われわれ人間の理解。

　　それを画像で見せられた
　　　ChatGPTは逆の理解。

　ここから考えられるのは、
　　**ChatGPTは、
　　　画像を裏側から見ている**、
　　　　ということです。

　これはおそらく
　　座標系の違いから
　　　来るものかと思われます。

　画像解析には
　　おそらく
　　　Code Interpreterへと渡して、
　　　　そこからの情報で
　　　　　判断しているはず。

　それはつまり、
　　Code Interpreterは
　　　座標系が左右反対だと
　　　　いうことです。

　画像の座標系は
　　基本的に、左上が(0.0)です。
　　　そして、右に行けばxが増える。
　　　　　　　下に行けばyが増える。

　ところが
　　ChatGPTの解析では
　　　右上が(0.0)になっています。

　どうしてなのかは
　　わかりません。

　ともかく、
　　左右が違うことを
　　　念頭に入れて
　　　　画像解析させるべきですね。
***
　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
7日目「よく使うプログラム言語」について紹介する社畜M

## はじめに  
社畜Mです。今回私はSEの人たちが使用するプログラム言語の中で最も使われているであろう5つの簡単な特徴と、それぞれの使いどころと使うときの注意点について紹介していこうと思います。予習や復習だと思ってみてみましょう！  
デュエル！！

### 1.Python
行くぜ！まず一つ目はこいつだ！ドロー！  
Pythonはシンプルで読みやすい構文が特徴のプログラミング言語で、初心者にとって扱いやすく、さまざまな用途に使われています。Web開発からデータ分析、AIの開発まで幅広い領域で利用されていて、特にデータ処理や科学技術計算において強力なライブラリが揃っており、簡潔なコードで高度な処理が可能です。  
 - **注意点**
   - 実行速度がほかの言語に比べて遅い
       -  Pythonは動的型付け言語であり、実行時に型の解決が行われるため、コードの実行に余分なオーバヘッドが生じることがあります。
       -  Pythonのインタプリタは動的な型変換やガベージコレクションなどのオーバーヘッドがあり、これが実行速度に影響を与えることがあります。
   - 大規模なプロジェクトに向いていないことがある
     - Pythonは動的型付け言語であり、大規模なプロジェクトでは型の一貫性が保たれにくくなる可能性があります。
     - 大規模なプロジェクトではパフォーマンスやメモリ使用量の最適化が重要であり、Pythonの柔軟性が逆に制約となることがあります。

### 2.Java  
まだまだ二つ目！ドロー！  
Javaはオブジェクト指向プログラミング言語で、堅牢性と移植性が高い特徴があります。大規模なシステムや企業向けのアプリケーション開発に広く利用されていて、Androidアプリケーションの開発にも必須なものとなっています。また、多くの企業で採用されているために就職に有利な言語の一つとしても知られています。  
- **注意点**  
  - 冗長な構文があり、学習コストが高い  
    - Javaは静的型付け言語であり、厳格な型システムを持つため、宣言や型の指定が必要な場面が多くあります。
    - Javaのオブジェクト指向の概念や豊富なライブラリ、独自のエコシステムなど、学習する項目が多いため、学習コストが高くなります。
  - メモリ管理が自動化されているため、パフォーマンスが低下する  
    - Javaはガベージコレクションによってメモリ管理が自動化されています。ガベージコレクションの実行により、アプリケーションの一時停止やリソースの消費が発生し、パフォーマンスが低下する可能性があります。

### 3.JavaScript  
次だ！三つ目！ドロー！  
JavaScriptはWebページの動的な挙動を実現するための言語で、Web開発においては必須と言っても過言ではなく、フロントエンドからバックエンドまで幅広く活躍されてます。近年ではNode.jsなどのランタイム環境の普及により、サーバーサイドでも利用されることが増えています。  
  - **注意点**  
    - ブラウザごとの互換性や非同期処理の扱いが複雑であり、学習コストが高い  
      - JavaScriptはブラウザごとに異なる実装があり、それぞれのバージョンや機能のサポート状況によって動作が異なるため、互換性の確保が難しい場合があります。
      - 非同期処理の扱いはコールバックやプロミス、非同期関数など、複数の方法があり、初学者にとっては理解が難しいことがあります。
    - セキュリティ面での懸念があり、適切な対策が必要とされる  
      - JavaScriptはクライアントサイドで実行されるため、セキュリティ上の脆弱性が問題となることがあり、クロスサイトスクリプティング攻撃など、悪意のあるコードの実行や情報漏洩が発生する可能性があります。



### 4.Ruby  
まだまだ行くぜ！四つ目！ドロー！  
Rubyはシンプルな構文と豊富なライブラリが魅力のプログラミング言語で、Web開発フレームワークのRuby on Railsが有名であり、迅速なWebアプリケーション開発に適しています。また、柔軟なオブジェクト指向プログラミングをサポートしており、綺麗なコードを書くことが可能です。  

  - **注意点**  
    - 実行速度がほかの言語に比べて遅い  
      - Rubyはインタプリタ言語であり、実行時にコードが逐次解釈されるため、コンパイル言語に比べて実行速度が遅くなる傾向があります。
      - Rubyの柔軟性や動的な特性が実行速度に影響を与えることがあります。
    - 大規模なシステムや後負荷の処理に向いてない  
      - Rubyは動的型付け言語であり、大規模なプロジェクトでは型の一貫性やパフォーマンスの問題が発生しやすくなる可能性があります。
      - Rubyのガベージコレクションやメモリ管理の仕組みが複雑であり、大規模な負荷に対応する能力が限られることがあります。

### 5.C++  
これが最後だ！五つ目！ドロー！  
C++は高速な処理と低レベルな制御が可能なプログラミング言語で、システムソフトウェアやゲーム開発に等、パフォーマンスが重視される領域で広く利用されています。また、ハードウェアやリソース制御が必要な場合にも適していますが、学習コストが高いとされることもあります。  
  - **注意点**  
    - 複雑な構文やメモリ管理の必要性により、学習コストが高い　　
      - C++は静的型付け言語であり、ポインタやメモリの明示的な管理など、初学者にとって理解が難しい概念が多くあります。
      - C++の多様な機能や低レベルな制御が必要な場面があるため、学習コストが高くなることがあります。
    - プロジェクトの開発期間がほかの言語に比べて長くなる　　
      - C++は低レベルな制御が可能であり、パフォーマンスやリソースの最適化が重要となるため、プロジェクトの開発期間が他の言語に比べて長くなる傾向があります。
  

## まとめ  
これらのすべてのプログラミング言語は、それぞれの特徴を持ち、異なる分野で利用されています。PythonはやRubyは柔軟性があり、Web開発などの分野で活躍しますが、実行速度が遅いことが欠点となっています。JavaやC++堅牢性やパフォーマンスが高いですが、学習コストが高いという特徴があります。JavaScriptはWeb開発に特化しており、フロントエンドからバックエンドまで広く利用されますが、ブラウザごとの互換性やセキュリティの問題に注意が必要になります。  
適切な言語を選択し、プロジェクトや目標に応じて活用していきましょう！  　　

## おまけ
社畜Mのおまけでは、社会人になると絶対に必要になるビジネスマナーについてお話しておこうと思います。  
今回は「**目上の人との食事の時は奥に座らない**」です。  
基本的に名上の人との食事の時は扉から一番遠い席は上座と言われていて客人や上司が座る場所となっています。  
客人と上司が一緒にいる場合上座に座るのは客人となります。勿論場所によって変わるときもありますが基本上座は一番奥というのは覚えておきましょう。  

社畜Mはこれで、ターンエンド
Excelの列番号(記号?)を取得する

PhpSpreadsheetを本格的に扱うようになって知ったTIPS。

データをシートに書き込むとき、まとめて書き込む(読み込むときも)なら`$worksheet -> fromArray($data, NULL, 'A1');`みたいにできるけど、n列、n+16列、n+32列…というセルの値にアクセスしたいときに「n+128列の列番号(記号)って何!?」となる。

このとき便利なのが
```php
$cols = [];
$a = 'A';
for ($i = 1; $i <= 1000; $i++) {
    $cols[] = $a;
    $a++;
}
echo $cols[940];  //AJD
```
というように文字列をインクリメントすると、勝手に`A, B, C, ... Z, AA, AB, ... AY, AZ, BA, BB, ... ZY, ZZ, AAA, AAB, ...`という文字列を生成してくれる仕様。

逆に列記号からn列目を引きたいときは
```php
$cols_r = array_flip($cols);
echo $cols_r['ACE'];  //759
```
となる。
PHPって便利だね。まあR1C1形式を使えばいいと言われたら元も子もないけど…。

---
とここまで書いたところで調べたら、そもそもそういう関数がPhpSpreadsheetには用意されていて、
```php
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
$col_str = Coordinate::stringFromColumnIndex(940);
echo $col_str;  //AJD
```
だそうですハイ。
Android タイトルバーを表示する

Android studioでAndroidアプリを制作していて、タイトルバーがデフォルトで表示されない設定となっていました。なので、表示させる方法を紹介します。

プロジェクト作成時にEmpty Views Activityを指定した想定で進めます。
![スクリーンショット 2024-04-18 19.58.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215907/8bb3032e-9553-aefb-afad-ac21fd01717e.png)

### 1. Androidビューでファイルを開いてthemes.xmlファイルを探す
themes.xmlファイルはapp/res/values/themeフォルダに格納されています。
![スクリーンショット 2024-04-18 20.03.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215907/49090d1d-e401-2912-9aaf-76ade639c00a.png)

### 2. themes.xmlファイルの編集
themes.xmlファイルの下記のコードを修正します。
(変更前)
```xml
  <style name="Base.Theme.ViewSample" parent="Theme.Material3.DayNight.NoActionBar">
```

(変更後)
```xml
<style name="Base.Theme.ViewSample" parent="Theme.Material3.DayNight">
```

NotActionBarを消すことで、タイトルバーが表示されるようになります。

参考
[Android タイトルバーを隠す AppCompatActivity編](https://qiita.com/furu8ma/items/4328c793250b10313cd7)
node.js – クラスにメンバ変数・メンバ関数を定義する ( インスタンス変数、インスタンス関数的な )

# バージョン

- node v20

# コード例

オブジェクト ( インスタンス ) 作成時に設定した boolean が返る メンバ変数、メンバ関数をそれぞれ一つずつ設定する

```ts
class ExampleClass {
  constructor(flag) {
    this.flag = flag
  }

  getFlag() {
    return this.flag
  }
}

const exampleInstance1 = new ExampleClass(true)
console.log(exampleInstance1.flag) // true
console.log(exampleInstance1.getFlag()) // true

const exampleInstance2 = new ExampleClass(false)
console.log(exampleInstance2.flag) // false
console.log(exampleInstance2.getFlag()) // false

```

# エラー例

ちなみに以下のような書き方はできないようだ


```ts
class ExampleClass {
  flag: boolean // SyntaxError: Unexpected identifier 'flag'
  constructor(flag: boolean) { // SyntaxError: Unexpected token ':'
    this.flag = flag
  }

  getFlag() {
    return this.flag
  }
}
```


# チャットメンバー募集


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

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


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
PHPの環境変数管理術 - phpdotenv

PHPで環境変数についてどのように管理していますか？
「環境変数を扱うならこれ！」っていうライブラリがありますのでご紹介します。

## 環境変数って？
アプリケーションが異なる環境（開発、テスト、本番など）で動作する際に、設定を柔軟に変更できるような仕組みです。
こういった設定はGit管理をする必要がないですよね。これにより、セキュリティが向上し、異なる環境でのアプリケーションの設定変更が容易になります。

例えば、環境ごとに接続するDatabaseの情報が異なることって結構多いですよね。
そんな時に、**PHP dotenv** がいい感じに管理してくれます。

## phpdotenvについて
簡単に...
**PHP dotenv**は、プロジェクトで環境変数を扱うためのライブラリです。
``.env``ファイルから環境変数をアプリケーションに読み込む機能を提供します。

https://github.com/vlucas/phpdotenv

## 使い方
### 1. インストール
```bash
composer require vlucas/phpdotenv
```
### 2. ``.env`` ファイルの設置
```.env
DB_HOST=localhost
DB_NAME=app
DB_USER=root
DB_PASS=password
SLACK_CHANNEL_ID=hogehoge
SLACK_TOKEN=fugafuga
```

### 3. 環境変数のロード
以下は、``.env`` ファイルで定義した変数を読み込むための必要なステップです。
```php
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
```

上記の記述により、Globalで呼び出せるようになります。
```php
$slack_token = getenv('SLACK_TOKEN');
$slack_token = $_ENV['SLACK_TOKEN'];
$slack_token = $_SERVER['SLACK_TOKEN'];
```

※ 一応...。``getenv`` は非推奨とのこと。

#### コメントつけれます
```php
VAR="value" # comment
VAR=value # comment
```
``.env`` にコメントをつけることも可能みたい。

## まとめ
めちゃくちゃ簡単ですので、一度試してみてください。
メールアドレスの匿名化・エイリアス化ができるサービスを調べてみた

[blastengine](https://blastengine.jp/)は、デベロッパーフレンドリーなメール送信サービスを提供しています。そのため、メールに関する動向は常にウォッチしています。

スパムやフィッシングメールなどが送りつけられてきて、嫌な思いをしたことがある人は少なくないでしょう。メールアドレスは個人情報の一つであり、おいそれと公開したくはないはずです。

それもあって、Appleが2019年にSign In With Appleを発表した際、メールアドレスを隠す（匿名化する）仕組みを提供しました。その流れは徐々に広がっているようなので、まとめてみました。

なお、ここで挙げているのは捨てアドレスを提供するものではなく、本来のメールアドレスを隠すものです。

## Gmailのエイリアスとの違い

Gmailなどでは `+aaa` でエイリアスアカウントを作成できます。ただ、あのエイリアスアカウントでは本来のアカウントがすぐに分かってしまいます。流出元を分からないようにする場合は、 `+aaa` を消せば良いだけです。

## Sign In With Apple

Sign In With Appleで認証する際に、元のメールアドレス（Appleに登録しているもの）を隠して認証を行います。メールを非公開を選択すると、各サービスには icloud.com ドメインのアドレスが提供されます。生成されたアカウントはApple IDと紐付いており、無効化すればそのアドレスも使えなくなります。

アカウント情報が漏洩したり、スパムメールなどが届いた際には、そのエイリアスを消せば解決できるでしょう。

[iCloud.comで「メールを非公開」のアドレスを作成および編集する - Apple サポート (日本)](https://support.apple.com/ja-jp/guide/icloud/mm1a876f7aed/icloud)

## [SimpleLogin](https://simplelogin.io/ja/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/fe38220b-e923-c4d0-e244-1312e77a1260.png)

オープンソースの匿名メールアドレスサービスです。受信はもちろん、送信もこのエイリアスドメインから行えます。サービス毎に異なるエイリアスアカウントを作成することで、スパムやフィッシングメールがどこから送られてきたかも判別できます。

ブラウザの機能拡張やモバイルアプリもあるので、エイリアスの作成や管理が素早く簡単にできます。カスタムドメインも利用できたり、セルフホスティングも可能です。プレミアムプランではPGP暗号化もサポートしています。

[APIも公開されている](https://github.com/simple-login/app/blob/master/docs/api.md)ので、システム連携もできそうです。

## [Masked Email](https://1password.com/jp/fastmail/)

1PasswordとFastmailというサービスの連携によって実現されています。1Password上から、簡単にアドレスを作成できます。パスワード管理の中で、メールアドレスが作れるのは便利かも知れません。

なお、Fastmail自体は有料サービスなので、1Passwordとは別途料金がかかります。

## [Bunsin](https://www.bunsin.io/)

bunsin.ioのメールアドレスを作成し、ラベルで管理できます。各アドレスごとに転送するか否か設定できます。基本モバイルアプリで利用するようですが、ブラウザ機能拡張も用意されています。

2024年4月現在、すべての機能が無料だそうです。

## [Firefox Relay](https://relay.firefox.com/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/72b84fad-b8e2-5335-cc86-278d6c519947.png)


Firefoxの開発元であるMozillaが提供するサービスです。エイリアスメールアドレスの作成はもちろん、トラッキングも除去してくれます。 `yourdomain.mozmail.com` のようなドメインでアドレスが作れるようです。

将来的には、広告メールのブロックや匿名でのメール返信機能などが追加される予定です。

## [SafetyAnswer](https://www.ans.email/)

SafetyAnswerが面白いのは、メールの送信側・受信側の双方がメールアドレスを秘匿化できる点です。これは幾つか利点があって、たとえば社員による顧客のメールアドレス持ち出しが防止できます。秘匿化されているので、すべて刷新するのも簡単そうです。

また、PTAなどでのメーリングリスト運用時にも良さそうです。メールアドレスがバレてしまって、裏でやり取りするなんて事態を避けられるでしょう。後は、匿名での相談・通報にも使えるとのことです。

## まとめ

メールアドレスは `atsushi@example.jp` のように名前が表に出やすいものです。またはソーシャルアカウントのIDと似たものになっていたりすることもあります。そのため、スパムメールやフィッシングメールの被害に遭いやすいです。

パスワードが流出した後、パスワードは固定にしてメールアドレスを変更してアタックする「リバースブルートフォース攻撃」も有名です。そうした場合にも、メールアドレスの隠蔽化は効果があるでしょう。

匿名化にも幾つか種類がありますので、自分に合ったものを選んでみてください。
picoCTF 2021 writeup Python Wrangling

## Python Wrangling (General Skills)

Python scripts are invoked kind of like programs in the Terminal... Can you run this Python script using this password to get the flag?

添付ファイル
・ende.py
・pw.txt
・flag.txt.en

問題文にあるように、とりあえず実行してみる。
```
> python ende.py -d flag.txt.en
Please enter the password:6008014f6008014f6008014f6008014f
picoCTF{4p0110_1n_7h3_h0us3_6008014f}
```
ende.pyに記述されているhelp_msgをヒントに実行した。
jetsonでのディスク枯渇対策　dockerの場合 その２


## 想定する読者
- Jetson ユーザー
- Docker ユーザー

## まえがき
- 先に[jetsonでのディスク枯渇への対策　dockerの場合](https://qiita.com/nonbiri15/private/64a43b24267ad0ad3adc)を書いた。
しかし、このやり方では、様々なDocker環境をそのつど切り替えるには向かない。
せっかくキャッシュされた内容を削除してしまうので、docker build が毎回遅くなってしまう。

そこで、root権限でアクセスできるディスクを増やす方法を、以下に書いた。

[jetsonでのディスク枯渇への対策　microSDの利用](https://qiita.com/nonbiri15/private/2a6b1fcc1a373e2b084c)
- これで、root権限でアクセスできるディスクスペースが増えた。

## この記事で目指すこと
- root 権限でアクセスできるディスクが増えている状況で`/var/lib/docker`を追加したディスクに移動すること
- そうすることで、`/` のファイルシステムが枯渇する状況を改善する。
- `sudo docker system prune` でdocker のキャッシュを削除する頻度を減らせるようにする。
- さまざまなDocker環境を切り替えても、快適にdocker build, docker runをできること。

## 手順
追加したディスクを仮に`/mnt/microsd` とする。
```
cd /mnt/microsd
sudo mkdir docker

#docker のサービスを停止しておく
sudo systemctl docker stop

sudo su
cd /var/lib
mv docker docker_
ls /mnt/microsd/docker
ln -s /mnt/microsd/docker

ls docker
df docker
```
で参照されているディスクが追加したディスクのものになっていれば成功である。

## 追加の確認
再起動後に、`ls -lF /var/lib/docker` を実行。

## 通常のdockerの利用状況の確認
- わかっていると思うので省略。
- 確認後は、`/var/lib/docker_` は不要になっているので削除する。


## docker のディスクスペースを確保するには
```
sudo docker system prune --volutmes --all

```

## 参照した記事
[Dockerの/var/lib/dockerを移動する](https://qiita.com/masato/items/e967e531e75101796c30)
Springを使っている時に静的メソッドじゃなくてDIを使うようにした

状態を持たないロジックを実装したいとき、以前は以下のように書いていました。
静的なクラスメソッドを使って、判定するみたいな。

```kotlin
class Validator private constructor() {
    companion object {
        fun validate(foo: String){
            if foo == "NG"{
                throw Exception("validation error")
            }
        }
    }
}
```

呼び出し元イメージ
```kotlin
@RestController
class Controller(service: Service){
    fun bar(@GetMapping String foo) {
        Validator.validate(foo)
        service.someMethod(foo)
    }
}
```

ただ、現在はSpringを使って開発しており、DIが容易にできるようになりました。
以下のようなコンポーネントを作成し、DIをした方がよいのではないかと思い、実装方針を変えてみました。

理由としては、テスト時にmockしやすいのが一番の理由です。

```kotlin
@Component
class Validator {
    fun validate(foo: String) {
        if foo == "NG"{
            throw Exception("validation error")
        }
    }
}
```

呼び出し元イメージ
```kotlin
@RestController
class Controller(service: Service, validator: Validator){
    fun bar(@GetMapping String foo) {
        validator.validate(foo)
        service.someMethod(foo)
    }
}
```
4/22は「アースデイ」 環境保護活動をサポートするJMPのこれまで

![Earthday記事ヘッダー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/d65de638-d81d-332a-4ce0-20e80fe84417.png)

毎年4月22日は<font color="orange">**「アースデイ」**</font>。
温暖化や環境問題に目を向け、個人や企業がそれぞれ行動を起こす日です。そして、1970年の初開催後、今や世界で10億人以上が活動やイベントに参加する特別な日になりつつあります。

近年、日本でもアースデイへの関心は高まってきています。たとえば、4/20（土）～4/21（日）には、渋谷区立宮下公園で[**「アースデイ東京2024」**](https://earthday-tokyo.org/earthday2024/)が開催され、クリエイター縁日や盆踊りを楽しみながら、さまざまな学びや人とのつながりを体験できるようですし、[**こちらのマップ**](https://earthday.maps.arcgis.com/apps/dashboards/8d15cc3da12d4338a109c7d64c97c02a)で家や職場近くのアースデイ関連イベントを検索することもできます。

また、イベントに参加する以外にも、この時期にあわせて海岸でゴミを拾ったり、リサイクル素材の服を選んで購入したり、個人でそれぞれに行動する人もいます。

そして、私たち[**JMP（ジャンプ）**](https://www.jmp.com/ja_jp/home.html?utm_campaign=bl&utm_source=facebook&utm_medium=social)も組織として何ができるかを考え続けています。

その一例が、「Data for Green」（JMP Ecosystem Restoration Initiative）というプロジェクトです。JMPを活用して[**ノースカロライナ州の本社社屋のエネルギー使用量と排出量を計測**](https://public.jmp.com/packages/q4PdhlP4pTs8nXF7cxlMJ/details)したり、[**太陽光発電の使用状況のデータを採る**](https://public.jmp.com/packages/JXkVlfSNLqCYSzRXcQ82q)ことで、企業活動が環境に与える影響をモニタリングしました。

![画像1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/68f11373-2d9a-8218-1c9c-beb75f3c4370.jpeg)
（本社社屋のエネルギー使用量と排出量の計測）

![画像2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/c0cbe057-59a4-c165-6f53-596f4329c428.jpeg)
（太陽光発電の使用状況）

また、環境保護団体、博物館、大学が、絶滅危惧種や野生動物、サンゴ礁等の調査、研究、保護を行う際に、JMPでさまざまなデータの分析が行われています。

これまでJMPは、環境保護活動に携わる方々がフィールドワークで得たデータを分析する際のツールとして、多くの団体や研究者の方々にご利用いただき、その活動をサポートしてきました。幾つかの事例を下にご紹介します。

[**WildTrack**](https://www.jmp.com/ja_jp/customer-stories/wildtrack.html?utm_campaign=bl&utm_source=facebook&utm_medium=social)
デジタル写真と足跡アルゴリズムを活用し、絶滅危惧種を一匹一匹確実に救う活動を実施。


[**カリード・ビン・スルタン・リビング・オーシャンズ財団**](https://www.jmp.com/ja_jp/customer-stories/living-oceans-foundation.html?utm_campaign=bl&utm_source=facebook&utm_medium=social)
予測モデルを用いてサンゴ礁の保護活動の優先順位を決定。


[**ノースカロライナ自然科学博物館**](https://www.jmp.com/ja_jp/customer-stories/ncmns.html?utm_campaign=bl&utm_source=facebook&utm_medium=social)
JMPを活用し、哺乳類の個体数分布のデジタルアーカイブを構築。

[**バージニア工科大学**](https://www.jmp.com/ja_jp/customer-stories/virginia-tech.html?utm_campaign=bl&utm_source=facebook&utm_medium=social)
キツネザルの行動についての学際的な研究で、保護方針、飼育環境の改善を目指す。

環境保護活動に携わる方々が、データに基づいて今後の正しい方針を決める際や、収集したデータを解析する際に、その活動がより効果的なものになるよう、私たちJMPがサポートできることを嬉しく思いますし、これからも継続してサポートを続けていきます。

[**■30日間全機能無料。JMPトライアル版ダウンロード**](https://www.jmp.com/ja_jp/download-jmp-free-trial.html?utm_campaign=bl&utm_source=facebook&utm_medium=social)
【熱望】javascript の for 文で var i を宣言するのはやめて下さい

皆さんは javascript の for 文で
以下の書き方をしたことがありますか？

```js
for(var i = 0; i < array.length; i++) {

}
```

この書き方でも for 文は正常に動作します。

しかしながらこの書き方は
以下の書き間違いが生じることがあります。

```js
for(var i = 0; i < array1.length; i++) {
  //長い処理
  for(var i = 0; i < array2.length; i++) {
  
  }
}
```

長い処理の中で
i を宣言したことを忘れて
再び i を宣言してしまうことで
外側の for 文のカウントにバグが発生し
期待した動作にならない例になります。

私も他の人が作成した web アプリで
このバグを見かけたことがあります。

for の変数を宣言する場合
必ず let で宣言して下さい。
var でなければ正常に動作しないのは
構造的欠陥のハズです。

```js
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

for(let i = 0; i < array1.length; i++) {
  console.log(array1[i]);
  //長い処理
  for(let i = 0; i < array2.length; i++) {
    console.log(array2[i]);
  }
}
```

上記のコードでは

var で宣言していたならば
console.log(array1[i]); が
1 回と
console.log(array2[i]); が
3 回しか通りませんが

let ならば期待通り
console.log(array1[i]); が
3 回と
console.log(array2[i]); が
9 回通ります。

let ならば上記のようなコードは
array1[i] も
array2[i] も
正しい値が取得できます。

長い処理を挟む事により
変数を宣言したことを忘れて再宣言しても
外側の for が正常に評価されるため
バグは発生しない可能性が高いのです。

***

以上 for 文の変数は let で
宣言しましょうという記事でした。

バグ発生のリスクを抑えるため
何卒よろしくお願いしたい所です。

調べてはいませんが有名な話で
同じことを言う記事はたくさんあると思います。
しかしながらこの書き方を現時点で行う人は
一定数いらっしゃるようなのです。

例えバグが出なくても
後でソースを見る人は
多重宣言していないか
気を遣うことになります。

百害あって一利無しのハズです。

for 文で var を宣言して
バグが発生するのは時間の浪費なのです。
for 文で var を宣言している人は
是非 let を検討頂きたいと思います。
私はそれを切実に願っています。

この記事が皆さんのバグ取りの
無駄な時間を抑えるきっかけになれれば
嬉しいです。

閲覧ありがとうございました。

***

追記

コメント欄で本当に恐ろしい点を
挙げている方がいらっしゃいました。

言われてみればかなり恐ろしい点なので
時間のある方はコメント欄も
確認頂けると幸いです。

コメントありがとうございました。

***

追記

私の記事の誤りをコメントで指摘頂きました。

```js
let i = 10;

for(let i = 0; i < 3; i++) {
  for(let i = 0; i < 4; i++) {
    console.log(i);
  }
}
```

上記のコードは正常に機能して
console.log(i) は 12 回実行されるようです。

しかしながら
この挙動ならば外側の for 文が
正しく評価されるため
バグの発生する確率は let の方が低くなります。
長い処理を挟んだ結果再宣言して
バグが発生する事を私は悪としているため
その場合は let ならばバグが発生しません。
保守管理面で問題があるかもしれませんが
var の使用率を少しでも減らすための活動として
この記事はその事を結論としました。

ご指摘ありがとうございます。

また、修正前の記事で
誤った知識を植え付けてしまった事に関して
謝罪したいと思います。

申し訳ございませんでした。
自己紹介

Qiita初投稿になります。プログラミング初心者の無知な田舎者です。
簡単な自己紹介します。学生してます。せっかくIT系に進学したのですが、就職まで残り2年で、振り返ると全然勉強をしていませんでした。今まで何をやっていたのだと後悔しています。思い立ったが吉日といった感じで軽く触ったり知識はあるものの改めて一から勉強をしようと思い日記感覚で勉強した記録を投稿していこうかなと思います。三日坊主にならないように投稿していきます。

まだ行きたい職種は未定なのですが、セキュリティ方面で考えています。

間違った覚え方だったり、間違ったやり方をしていたらアドバイスをいただけると嬉しいです。ふつつかものですが、よろしくお願いします。
SLO サービスレベル目標とは

# SLOとは

バズワードでもあるこれ。
意味を改めて理解しなおすために、SLO本を読んだのでそのメモ。


# SLO本
これです。

https://www.oreilly.co.jp/books/9784814400348/

表紙の犬はスパニッシュウォータードッグ。

https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%91%E3%83%8B%E3%83%83%E3%82%B7%E3%83%A5%E3%83%BB%E3%82%A6%E3%82%A9%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%BB%E3%83%89%E3%83%83%E3%82%B0


本記事は主に１章.信頼性スタックを参照しています。


# SLI,SLO,SLA

これら三つでセット。

本書によると、これらは**信頼性スタック**と呼ばれます。[^1]

## SLI

**Service Level Indicator サービスレベル指標**　

信頼性スタックの最下部のレベルにあるとされます。

:::note info
SLI・・・メトリクスで特定される計測値、つまりサービスのある種の特性を表す一つのデータです。優れたSLIは、ユーザーの観点からサービスを計測します。
SLIは、各イベントについて「良い」か「悪い」の二者択一で結果を得られれば、最も有用です。[^2]
:::


たとえば、Webページを十分な速さで読み込めるかどうか、といったことを表します。


この**良い悪いの二者択一に振り分ける**ことで、**指標として機能する**のですね。

これによって、**すべてのイベントの中で、良いの割合を出すことができます。**

測定した割合は信頼性の評価に使えるということですね。

また、良いSLIについての記述もありました。わかりやすかったのでそのまま引用します。

:::note info

良いSLI・・・すべての利害関係者が理解できる平易な文章で、意味が伝わるように表現することができる。[^3]

:::






## SLO
**Service Level Objective サービスレベル目標**

SLIで良い割合のパーセンテージを出せることがわかりました。
**SLOはこのSLIのパーセンテージが目指すべき目標値です。**

:::note info
SLO・・・障害を起こしても許容される頻度の目標値、あるいは正常に動作していなくてもユーザーが重大な混乱に陥らないとされる目標値。SLIを使って表現される。
:::



## SLA

**Service Level Agreement　サービスレベル合意**

これは、意外にも本書では詳細に扱いません、と明記されていました。

:::note info
SLA・・・有償顧客との契約書に記載されるビジネスの決定事項。[^4]
:::



また、SLAとSLOとの違いという形で説明されていました。
ここは個人的には一番学びになりました。

:::note info
 SLAとSLOの違い・・・SLOは目標で、SLAは契約上の合意であり、支払いを伴う明示的な約定。
SLOは目標であるので、自由に変更したり更新したりできる。

SLOに違反した場合は、それに対して、長期に渡って、何等かの対策を行うための選択の余地がある。

長期に渡ってSLAに違反した場合、それに対して一般的には選択の余地はなく、すぐに対応することが求められ、そうでなければビジネスが継続できなくなる。[^5]
:::



>SLOに違反した場合は、それに対して、長期に渡って、何等かの対策を行うための選択の余地がある。[^5]



この部分は、SLOの活用方法として別章で詳しく記載されていました。
本記事では深入りせずに留めます。



## もう一人登場人物

**エラーバジェット**


:::note info
エラーバジェット・・・SLOに対してどれだけ、経時的にSLOのパフォーマンスを測定する手段。その期間内にサービスがどの程度信頼できないことを許容できるかを定義し、是正措置を講じる必要がある時を示すシグナルとして機能。[^1]
:::




次のような使用例です。

・今月のエラーバジェットが30分残っています。

・今月はエラーバジェットを使い果たすまでに、１日あたりさらに5000個までエラーを発生できます。[^6]



これは意思決定ツールであり、単純化すると以下のように意思決定に使えます。

| エラーバジェットが余った | エラーバジェットが超過した |
|:-:|:-:|
| より多くの機能をリリース  | 信頼性に集中  |

[^7]

## さらにもう一人

**サービス**


これは何気なく使われる用語で、ここでもスルーしてしまいそうになりますが、
確認しておきます。

:::note info
サービス・・・ユーザーが存在する何等かのシステム。[^8]
:::


ここでのユーザーは、人であったり、別のサービスもそれに含みます。

サービスの例として以下が挙げられていました。

:::note info
サービスの例・・・Webサービス、リクエスト/レスポンスAPI、データ処理パイプライン、バッチジョブ、データベースとストレージシステム、コンピュートプラットフォーム、ハードウェアとネットワーク[^9]
:::


例からわかるようにシステムに関するほぼすべてに、SLOは適用できるようです。



# 最後に

簡単に基礎の部分をまとめてみました。
用語の定義を確認するのは重要。
以下はより詳しく本書に書かれているので、関心を持った方はぜひ読んでみてください。

・良いSLIについてより詳しく知りたい(3章)

・SLOの変更、更新について。SLOの目標値をどのように選択肢、これらの目標値をいつ変更すべきかの多岐にわたる戦略について(4章、14章）

・エラーバジェットの活用方法(5章)

・どのようにSLOを設定、監視、計測するか。(6章、7章、8章、9章)

・SLOの定義のドキュメンテーション（15章、17章、付録A)

・SLO文化を作っていく方法(16章)

等。


# 参考文献

https://www.oreilly.co.jp/books/9784814400348/

https://www.atlassian.com/incident-management/kpis/sla-vs-slo-vs-sli

# 引用

『SLO サービスレベル目標
―SLI、SLO、エラーバジェット導入の実践ガイド』
Alex Hidalgo　著、山口 能迪　監訳、山口 能迪、成田 昇司　訳
は、以下SLO本と表記する。

[^1]: SLO本 p.5

[^2]: SLO本 p.5

[^3]: SLO本 p.8

[^4]: SLO本 p.7

[^5]: SLO本 p.8

[^6]: SLO本 p.10

[^7]: SLO本 p.11

[^8]: SLO本 p.11

[^9]: SLO本 p.12-p.14
UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown plt.show() の対処

# エラーメッセージ

Jupyter Notebook上でグラフ表示をするときに以下の警告が出たので対処法メモ

```bash
UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown 
plt.show
```

# エラーが出た時のコード

KaggleのTitanic問題のコードをサンプルとして使用

```python
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

train_data = pd.read_csv('data/titanic/train.csv')

#~~~~~~~~~~ 中略 ~~~~~~~~~~~~~~

#生存率グラフ
plt.figure(figsize=(3,2))
sns.countplot(x=train_data['Sex'], hue=train_data['Survived'].astype(str))
plt.show()
```

# 解決したコード

  「%matplotlib inline」を指定して解決

```python
%matplotlib inline

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

train_data = pd.read_csv('data/titanic/train.csv')

#~~~~~~~~~~ 中略 ~~~~~~~~~~~~~~

#生存率グラフ
plt.figure(figsize=(3,2))
sns.countplot(x=train_data['Sex'], hue=train_data['Survived'].astype(str))
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916003/ab9d608f-c200-6f3d-c21a-1a575e078ec9.png)

グラフも想定通り表示されたのでめでたし!

# 原因

Matplotlibの出力が非インタラクティブなキャンバス (**`FigureCanvasAgg`**) に設定されていたため、図を表示することができない旨の警告が出ていた。

# おわりに

どのタイミングで`FigureCanvasAgg`がセットされてしまったのかは軽く調べた感じ分からなかった。

後で調べるの忘れないためにもこの記事を備忘録とする。

怪しいのは記載のコードには載ってないが`ydata_profiling`をimportしたことかな。。
これを調べるのは宿題ということで。
jetsonでのディスク枯渇対策　microSDの利用

Jetson AGX Orin で64GB モデルを使っていても、次のような操作をすると、たちまちディスクが枯渇する。

## ディスク使用量が大きくなる処理の例
- `git clone` をしまくること。
- `apt-get install` をしまくること。
- dockerの仮想環境を作りまくること
- リポジトリごとに`python3 -m venv venv` でvenv環境を作りまくること

## この記事の目的
- Jetson AGX Orin のユーザーが、microSDカードを使って、その領域をfstabを使った固定のファイルシステムとしてマウントさせることができるようにすること。
- 固定のファイルシステムとして認識させたい理由は、root 権限でアクセスできるディスク領域も確保したいためである。
- 抜き差しが簡単な`/media/ユーザー名/UUID` のタイプを使用しないのは、そのためである。
- Jetson　ユーザー向けに書いていますが、Ubuntu20.04 であれば共通のはずの内容です

### 注意
- ディスク関係の処理は、データを失いやすい危険な操作です。
- この記事だけではなく、別の記事も参照して、十分に納得してから、**自己責任**で実行してください。

## 動作させた環境
- Jetson AGX Orin
- JetPack5.1
- Ubuntu 20.04

## 手順
- microSDカードをパーティションを分割する必要はないと思うので、パーティショニングはスキップする。
- microSD を ext4でファイルシステムを作る。
    - mircoSD は購入時点ではWmkfs.ext4 コマンドindowsやMacで扱いやすい形式になっている。
    - mkfs.ext4 コマンド
    - 対象のデバイスを間違えないこと
        - システムの'/'があるファイルシステムを指定してしまうと、システムが壊れてしまう。
- まずは、自動マウントさせる。
    - /media/ユーザー名/UUID文字列
    - `df -h` での表示の確認
- マウントポイントのディレクトリの作成
    - 例　`cd /mnt; sudo mkdir microsd`
- microSD を固定のファイルシステムとしてマウントさせた。
- `/etc/fstab`への記入
    - いまどきのfstabへのデバイスの指定にはUUID=UUID文字列を使うといいんだ。
    - 必ず、追記のこと。元々のファイルシステムを消さないこと。
- `sudo mount -a`　での動作の確認
- `df -h` で実際にマウントされていることを確認
- `ls マウントポイント` でディレクトリの内容を表示できていることを確認する。

## 確認作業
- Jetson を再起動して、該当の領域がdfで表示されているか
- 該当のディレクトリにcd できるか

## 注意：やっちゃいけないこと-
- ホームディレクトリ自体を他のディスク上のフォルダへのシンボリックリンクにすること。
- 起こりうること：
- 何かのタイミングで、シンボリックリンク先を見つけられなくなった時に、loginができなくなる。
- loginできないので、その状況を修正できなくなる。
- 万が一、その状況に陥ってしまったら、bootable なUbuntu のUSBメモリを使う。BIOSの設定の起動順序の冒頭にUSBメモリとする。その後BootしてUbutnuが立ち上がったら、PCの既存のディスクをマウントできていることを確認する。
- その状況で、loginできなくなった原因を取り除く。

## 注意その２
- microSD カードが壊れることがある。
- 壊れたら困るデータは置かないほうがいい。
- githubなどでソースコードを管理してあれば、local のリポジトリが失われても、被害は最小化できる。
- 別のディスクシステムへデータを置いて、本体のファイルシステムにはリンクをおくというやり方でも、複雑さを持ち込んでいる。
- シンボリックリンクの数は増やさないほうが懸命だろう。


## 参照した記事

- [Linux のディスクの fstab に書くときに UUID 指定するとディスク認識の順番が変わらなくていいって話](https://qiita.com/wnoguchi/items/b31e268b6b7236cdf8db)
256文字以上のファイル名（path付き）がWindowsで認識されないらしい

とりあえずそういう制限がかつてあり、今もあるらしい。
当事象がいずれのWindowsのバージョンに対して発生するのか/しないのかなどは、場当たり兵隊のわたしにはあまり興味がないが、こんなことで躓くのは憤りしかないのでメモっておく

KEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem内のLongPathsEnabledの値があればデフォルト0で倒れてるものを1に起こす
必要そうならば再起動する（ログオフでもいいのだと思う）
転ばぬ先のメモ
[Kotlin] Listenerオブジェクトの中で`this`キーワードを使うとき

# 問題
Listenerオブジェクトの中で`this`を使用すると、`this`の参照箇所をkotlinが間違える時がある。

# 解決方法

ラベルを用いて参照箇所を明示する

```kotlin
override fun onListened(property: {TYPE}) {
//    this.property = property // error
    this@{YOUR_CLASS_TYPE}.property = property
}
```
chatter いいねのついた投稿を抽出する2


実際にデータを抽出したいという案件がありましたので、Apexバッチを使って集計用のカスタムオブジェクトに書き出したいと思います。

+ [Chatterのいいね数の集計・確認について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bLOH2)

カスタムオブジェクト

|項目| 属性||
|:---------------|:---------------|:-------------------|
|FeedItemId|text(18)||
|FeedEntityId|text(18)||
|LikeDate|DateTime|いいねをした日時|
|ExternalKey|text(37)|Upsert用の外部キー|


```Java
public class BAT_Upsert_ReportFeedLike implements Database.Batchable<sObject> {
    //BAT_Upsert_ReportFeedLike bat = new BAT_Upsert_ReportFeedLike();
	//ID jobId = Database.executeBatch(bat); 

    public Database.QueryLocator start(Database.BatchableContext BC) {
        // collect the batches of records or objects to be passed to execute

        String query = 'select Id,Body,createddate, (select Id,InsertedById,FeedItemId,FeedEntityId,CreatedDate from FeedLikes) from FeedItem';
        return Database.getQueryLocator(query);
    }

    public void execute(Database.BatchableContext BC, List<FeedItem> FeedItemList) {

        List<ReportFeedLike__c> upsertReportFeedLikeList = new List<ReportFeedLike__c>();

        for (FeedItem fi : FeedItemList ){
            if (fi.FeedLikes != null){
                for (FeedLike fl : fi.FeedLikes ){
                    ReportFeedLike__c flk = new ReportFeedLike__c();
                    String ExternalKey = '';
                    if (fl.FeedItemId !=null) {
                        flk.FeedItemId__c = fl.FeedItemId;
                        ExternalKey = fl.FeedItemId;
                    }
                    if (fl.FeedEntityId !=null) {
                        flk.FeedEntityId__c = fl.FeedEntityId;
                        ExternalKey = fl.FeedEntityId;
                    }
                    ExternalKey = ExternalKey + ':' + fl.InsertedById;
                    flk.user__c = fl.InsertedById;
                    flk.ExternalKey__c = ExternalKey;
                    flk.LikeDate__c = fl.CreatedDate;
                    upsertReportFeedLikeList.add(flk);
                }//end of for fi.FeedLikes
            }//end of if
           
        }//end of for FeedItemList
		
        

        try {       
               

            if (upsertReportFeedLikeList.size() > 0) upsert upsertReportFeedLikeList ExternalKey__c;

        } catch(Exception e) {
            System.debug(e);
        }

    }  

    public void finish(Database.BatchableContext BC) {
    }
}
```

実際にレコードはできたのですが、コメントにいいねをしてもFeedItemIdとFeedEntityIdに違いはなかった感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f51aafd0-0cab-2f25-4d06-43a48b7d4ba1.png)
爆速！楽天市場のトレンドをLINE Botで掴む！

# 👀LINE Botで楽天市場ランキングをチェック👀

こんにちは！小売業で働いているHaMaです🖐

リアル店舗🏬で働いているからこそ、ECサイトのチェックは必須です🤔

しかしながら、
①サイトを開く
②ランキングを見る
③商品見る
この作業をジャンルごとにするのは、とても手間がかかります😱

そこで、ジャンルを聞いたら、爆速で楽天市場ランキング1位の商品を教えてくれるLINE Botを作ってみました👏

![shutterstock_2056247582-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756912/8a8978dd-f0bd-f53f-5547-9d057bfc6b70.png)

## LINE Botとのやりとり

<details><summary>要約</summary>

LINE Botを使って、楽天市場のランキング1位の商品情報を瞬時にチェックできます。ユーザーはジャンルIDを送信するだけで、商品の詳細と価格情報を受け取ることが可能です。

</details>

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="zxx" dir="ltr"><a href="https://t.co/3LlVZWUET2">pic.twitter.com/3LlVZWUET2</a></p>&mdash; HaMa (@HaMa53687932) <a href="https://twitter.com/HaMa53687932/status/1781114966520836266?ref_src=twsrc%5Etfw">April 19, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


この様に、LINE Botに楽天ジャンルIDで話しかけると、爆速でデイリーランキング1位💡の商品を教えてくれます😳

気になった商品があれば、リンクから楽天市場の商品ページを開けるので、詳細もすぐに確認できます！

価格💴も一緒に教えてくれるので、トレンド商品👗の相場感も一目で分かります😆


## 使用したツール

・[LINE Developers](https://developers.line.biz/ja/)
・[楽天市場API](https://webservice.rakuten.co.jp/)
・[Make](https://www.make.com/en)

## LINE Botの作り方

Makeを活用してLINE Botを構築し、楽天市場APIと連携させています。このプロセスにより、JSON形式でデータを取得し、ユーザーに対して必要な情報を返信します。

## Makeの全体像

![MAKE全体像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756912/d8a3bef3-42c9-cc77-805c-ea940358c640.png)

初めてのノーコードプログラミングなので、先ずはシンプルに作りました。

## HTTPの中身

![HTTP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756912/65818a8d-d00a-2df2-2993-02e42c4fc157.png)

黒塗りのところに楽天市場APIを入力します。
楽天ジャンルIDを、LINEメッセージ📩から読み込ませます。

## LINE Botの返す内容

![LINEbot返信内容.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756912/2797f578-7498-a937-cbfc-8b4073d1db52.png)

楽天市場APIはJSONでデータをとってくるので、Parse JSONを使います。
膨大なデータから、Parse JSONで欲しい情報だけLINE Botに返信させます。（いらない情報はカット✂しました）

## 今後の課題

###### なぜかランキング1位の商品のみしか返信しない😅
プログラミング超初心者なので、なんでランキング1位しか返せないのかわかりませんでした😥
APIは30位くらいまでデータとってきていますので、JSONから抽出、返し方が悪いのかもしれません。

今後は、楽天ジャンルIDと一緒に、ランキングもLINE Botに聞いたら、そのジャンルのそのランキングの商品を返す機能を追加したいです。

###### 楽天ジャンルIDを調べるのか面倒😫
LINE Botに楽天ジャンルIDで話しかけないと返してくれないので、情報が欲しいランキング商品の、ジャンルIDを調べないといけません。
私は超超超めんどくさがりなので、ジャンルIDを調べるのも省きたいです😇

今後は、商品名で話しかけたら、ジャンルIDに置き換えてAPIが認識し、ランキングを返してくれるようにしたいです。




## 2024/04/24　追記
Makeを学ぶ方に投稿を見ていただき、参考情報をいただけました。
改善の結果、ランキング3位まで返信させることができました。（最大5位まで可）

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">ご教授ありがとうございます。最大5位まで返信することができるようになりました。 <a href="https://t.co/bMJvPi3I3f">pic.twitter.com/bMJvPi3I3f</a></p>&mdash; HaMa (@HaMa53687932) <a href="https://twitter.com/HaMa53687932/status/1782910041265467772?ref_src=twsrc%5Etfw">April 23, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

しゅう様、ご教授ありがとうございます。
querySelectorAllで取得した要素に対してmapとかを使う

## はじめに
`querySelectorAll`で取得した要素に対して、Array関数を利用したいとします。

```html.example.html
<html>
	<body>
		<div class="sample">
			sample1
		</div>
		<div class="sample">
			target!
		</div>
		<div class="sample">
			sample3
		</div>
		<div class="sample">
			sample4
		</div>

		<script>
			window.onload = () => {
				// 内部テキストが「target!」の要素だけを抽出する
				const sampleArray = document.querySelectorAll('.sample')
				const target = sampleArray.filter(elem => elem.innerText == 'target!');
			}
		</script>
	</body>
</html>
```

こんな感じで`filter`を使えば余裕！  
・・・かと思いきや。

> Uncaught TypeError: sampleArray.filter is not a function at window.onload (example.html:19:32)

エラーが発生しました。ｱﾚｪ?（Arrayとかけた激ウマギャグ）

## 説明
querySelectorAllで要素を取得したときの返り値の型は`NodeList`というものになります。  
[Document: querySelectorAll() メソッド - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document/querySelectorAll)

そしてこの`NodeList`、ドキュメントに「**NodeList は Array とは異なります**」と明記されています。  
そのため`filter`や`map`などの便利な関数が使えません。

## 対応方法
こうする。

```html:example.html
<html>
	<body>
		<div class="sample">
			sample1
		</div>
		<div class="sample">
			target!
		</div>
		<div class="sample">
			sample3
		</div>
		<div class="sample">
			sample4
		</div>

		<script>
			window.onload = () => {
				// 内部テキストが「target!」の要素だけを抽出する
				const sampleArray = document.querySelectorAll('.sample')
				// const target = sampleArray.filter(elem => elem.innerText == 'target!');

				// 下記2つのどちらでも問題なし
				const target1 = Array.from(sampleArray).filter(elem => elem.innerText == 'target!');
				const target2 = [...sampleArray].filter(elem => elem.innerText == 'target!');
			}
		</script>
	</body>
</html>
```

書き方は違いますが、やってることとしてはどちらも同じで`Array`に変換しているだけです。  
個人的には`[...sampleArray]`のほうが好み。

## おわりに
なんでこんな手間を掛けないといけないんだ・・。  
普通にArray関数使える形にしろー！という気持ち。
react開発においてよく見るnamed exportとdefault exportの違い

## 概要
reactのチュートリアルや、サンプルコードと実際の開発現場でreactのコードを触ってみて
1つ違いがありました。
何の違いかというと、
reactチュートリアルでは以下のような**default export**が使用され、
```.jsx
export function App() {
  return (
    <p>テスト</p>
  );
}

export default App;
```

実際の開発現場では以下のような**named export**と呼ばれるものが使用されているという違いがありました。
```.jsx
export const App = () => {
  return (
    <p>テスト</p>
  );
};
```

何となくそういうものかとやっていたのですが
いざ、チュートリアルなどを触ってみるとどちらがいいのかわからなかったので今回少し調べてみました。

## default exportについて
default exportは1つのファイルに1つだけexportできます。そのため、exportするものを強制的に1つにできるので管理がしやすいのかなと感じました。
また、呼び出し側でimportするときに名前を自由にすることができるみたいです。

呼び出し元↓↓↓
```.jsx
export function App() {
  return (
    <p>テスト</p>
  );
}

export default App;
```

呼び出し側↓↓↓
```.jsx
import App from './App'; // これでもok
import SampleApp from './App'; これでもok
```

ただ、複数の人が触る開発現場で呼び出し側で名前を自由に設定できるのは少し怖い気もしました。

## named exportについて
named exportは1つのファイル内で複数のexportを使用できます。
呼び出し側での呼び方はexportの名前じゃないといけないみたいです。

呼び出し元↓↓↓
```.jsx
export function App() {
  return (
    <p>テスト</p>
  );
}

export default App;
```

呼び出し側↓↓↓
```.jsx
import { App } from './App';
```

呼び出し側では{}をつけてimportする必要があります。

こちらであればcomponentsのみではなく、関数を集めたファイルなどを定義して呼び出すなど
できる幅が広くなるのかなと感じました

##　まとめ
ざっくり理解ですが、知りたいことを知れたのでスッキリしました。
他にも不明な部分は記事に起こしてみようと思います。
Android Studioのコードのデフォルト折りたたみ設定の解除

# はじめに
<!-- 発端や概要を記載 -->
Android Studioのデフォルト設定で、一部コードがデフォルトで折り畳まれるのが見辛かったので、設定変更した時の忘備録。

<!-- 各チャプター -->
<a id="#What"></a>
# デフォルト表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758686/27c8f85e-40bc-95f1-37f0-069c1db5f518.png)

いい感じのところがなかったのでimportの部分を参考として出しますが、
上のような感じで、デフォルト設定だと折り畳まれてコードが隠されています。

<a id="#Setting"></a>
# 設定変更

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758686/9bb4c008-d112-9c97-65eb-0cac18926c52.png)

メニューバーから`Android Studio > Settings...`を選択し、
検索欄に`folding`と入力すると`Code Folding`が見つかります。
デフォルトだとチェックが入っている項目があると思うので、対象のものを外しましょう。
（折り畳みが不要であれば全て外してしまっても問題ないと思います。）

<a id="#Result"></a>
# 結果

![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758686/e43bdc82-63b5-82f2-ad16-7d381fb65c19.png)

抜粋になりますが、こんな感じでimportがデフォルト表示で折り畳まれなくなりました。
既にファイルを開いていた場合は、ファイルを開き直すと反映されます。

<a id="#Conclusion"></a>
# まとめ

以上、折り畳み設定の変更方法でした。
Salesforce動的フォームを利用し子オブジェクトに親オブジェクトの項目を表示させる方法

本橋孝昭です

今回は
Salesforce動的フォームを利用し子オブジェクトに親オブジェクトの項目を表示させる方法をご紹介します


今回は例として
・ケースオブジェクトのレコードから（ケースオブジェクトのレコードの親レコードの）取引先レコード項目を更新させる
を設定します


## 前提
「動的フォームの有効化」が必要です。ケースの動的フォーム有効化はこちらを参照ください

https://qiita.com/Takaa/items/62195e5bbc6b44e75ea3



## 設定1 ページ編集画面で「項目」から「取引先名＞」をクリックする
![取引先名001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fabad0da-1e52-3483-62a2-88bafb7bab83.png)

## 設定2 項目から取引先項目をケースのページにドラッグ&ドロップしてケースのページを整える

![取引先2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fc48079a-eaee-548f-e0cd-1a58f41512ed.png)


## 設定3 ページの保存&有効化
これにより、ケースのページ上に取引先の項目を表示させることが可能です
（※下記画像はケースのページの取引先の項目「年間売り上げ」を表示させることが出来ます）

![ケース001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b5af3f01-95fb-146c-beec-7ba7327c9060.png)
[Python入門] continue,pass,break

# Pythonのループ制御：`continue`、`pass`、`break`の違い

プログラミングにおいて、ループはコードの一部を繰り返し実行するために使われます。Pythonでは、`continue`、`pass`、`break`という3つのステートメント（実行文みたいな感じ）を使用してループの挙動を制御できます。これらのステートメントは似ているようでいて、使い方に大きな違いがあります。私がPythonを学び始めて最初につまづいた場所はここでした。ここでは、これらの違いを初心者にもわかりやすく説明します。

## `continue`

`continue` ステートメントは、ループの現在の反復を中止し、次の反復に進みます。この命令は、特定の条件下でループの残りの部分をスキップしたい場合に便利です。

```python:continue.py
for i in range(10):
    if i % 2 == 0:
        continue
    print(i)  # この行は偶数時には実行されない
```
上の例では、iが偶数の場合、print(i)の行は実行されず、ループは次の数値に進みます。

## `pass`

`pass` は「何もしない」操作です。このステートメントは、文法的にステートメントが必要な場所で、何も実行しないプレースホルダーとして機能します。プログラムの流れには影響を与えません。

```python:pass.py
for i in range(10):
    if i % 2 == 0:
        pass
    print(i)  # すべての数値が出力される
```
passが使用されている場合でも、ループの全ての部分が実行されます。

## `break`

`break` ステートメントは、ループから完全に脱出するために使用されます。特定の条件が満たされたときにループを終了させたい場合に有用です。

```python:break.py
for i in range(10):
    if i == 5:
        break
    print(i)  # 0から4までが出力され、5以降は出力されない
```
上の例では、iが5に達すると、ループが完全に終了します。

## まとめ

`continue` は現在のループの反復をスキップします。
`pass` は文法的にステートメントが必要な場所で「何もしない」ために使用します。
`break` はループから完全に脱出するために使用します。

### 参考資料

https://python-hack.net/break_continue_pass/

https://mtoyokura.github.io/python-koza/pass_break_continue/