OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでjsonの読み込みと書き込みする

jsonデータをPythonで扱う方法について勉強したのでまとめ


## jsonとは？
jsonデータは複数の言語で利用可能な共通フォーマット
CSVやXMLといったものも同じようデータフォーマットとして用いられるが、それらのフォーマットと比較してjsonは読み書きしやすいという特徴がある。
外部ファイルとしてPython内で利用する変数の保存などに利用可能。

## Jsonの読み込み
### jsonファイルを準備
これを準備しないと始まらない。
まずはローカルにjsonファイルを作成します。
バナナとリンゴについて記述したデータ

```sample.json
{
 "food1":{
"name":"banana",
"color": "yellow" ,
"price": 200
},
"food2":{
 "name": "apple",
 "color": "red" ,
"price": 100
}
}
```

### jsonファイルの読み込み
jsonモジュールをインポートします。
```python:
import json
```

### jsonファイルを開く
jsonファイルを開きます

`sample.json`の箇所はファイルパス
`r`は読み込みである事を示しています。

:::note info
Pythonでファイルを開くときに、変数名に`f`が使われることが多いようだが、何でも構わない。
:::
```python:
f = open('sample.json', 'r')
```
### jsonファイルの読み込み
load関数を使って、開いたファイルを「jsonファイル」として読み込みます。
読み込まれたデータのタイプは`辞書型`となります。
```python:
dict_json = json.load(f)
```

### jsonファイルのプリント
jsonデータをプリントしてみる。
問題なくプリントされていれば読み込み成功
一つ目はTypeの表示。`dict`型になっている
二つ目はデータの全表示
三つめがKeyを利用して特定のデータだけを抽出

```python:
print("type_name--------")
print(type(dict_json))
print("json_all--------")
print(dict_json)
print("json_pick--------")
print(dict_json['food1']['name'])
```
```
type_name--------
<class 'dict'>
json_all--------
{'food1': {'name': 'banana', 'color': 'yellow', 'price': 150}, 'food2': {'name': 'apple', 'color': 'red', 'price': 100}}
json_pick--------
banana
```

### jsonファイルを閉じる
opneしたファイルはcloseメソッドを使って閉じる必要がある
```python:
f.close()
```

## Jsonの書き込み

### 内容の書き換え
Jsonの書き込みを行う前に、データの中身を書き換えてみる
name : banana →　peach に
color : yellow　→　pink　に書き換え
```python:
(dict_json['food1']['name'])="peach"
(dict_json['food1']['color'])="pink"
```
### 内容のプリント
先ほどのプリント分を実行すると中身が書き換わっている事がわかります。
```
type_name--------
<class 'dict'>
json_all--------
{'food1': {'name': 'peach', 'color': 'pink', 'price': 150}, 'food2': {'name': 'apple', 'color': 'red', 'price': 100}}
json_pick--------
peach
```
### Jsonファイルを開く
`sample_2.json`の箇所はファイルパス
`w`は書き込みである事を示しています。
ファイルが存在しなければ新規作成、存在していれば上書きして保存されます
今回は別名ファイルとして``sample_2.json``を指定。

```python:
new_json = open('sample_2.json', 'w')
```

### Jsonファイルを書き込む（dump)
dumpという関数を使って書き出します
json.dump(``引数1``（書き込みたいデータ）、``引数2``（保存先））
```python:
json.dump(dict_json, new_json)
```

指定のパスにjsonファイルが生成されます
データを開いて下記が記述されていれば成功。
```sample_2.json
{"food1": {"name": "peach", "color": "pink", "price": 150}, "food2": {"name": "apple", "color": "red", "price": 100}}
```

### インデントを利用しデータの視認性を向上する（dump)
第三引数の``indent``を利用すると視認性が向上します。
json.dump(``引数1``（書き込みたいデータ）,``引数2``（保存先）,``引数3``（indent）,）
```python:
json.dump(dict_json, new_json, indent=3)
```
```sample_2.json
{
   "food1": {
      "name": "peach",
      "color": "pink",
      "price": 150
   },
   "food2": {
      "name": "apple",
      "color": "red",
      "price": 100
   }
}
```

## その他
jsonのデータをstr文字列として変換することができる。
使途がわからないが「pythonでjson」と検索すると、たいていの記事でこちらに関しての記述があるので、ニーズがあるものだと思われる。
データは``辞書型``　→　``str型``に変換される。

```python:
json_str = json.dumps(dict_json)
```

文字列に変換されたデータは``辞書型``ではなくなるため、下記のようなKey指定でのデータの取得ができなくなる
```python:
print(dict_json['food1']['name'])

TypeError: string indices must be integers
```
Party Relationship Group NPSP


+ [How to Examine the Latest Features and Capabilities of Salesforce Nonprofit Cloud in 2023 ](https://prudentconsulting.com/blogs/how-to-examine-the-latest-features-and-capabilities-of-salesforce-nonprofit-cloud-in-2023/)

Life Events, Actionable Relationship Center, Accounting Subledger, and Timeline help streamline the business process. Nonprofit Cloud uses Person Accounts and **Party Relationship Groups**. Person Accounts allow you to record people as contacts on an account and even as accounts, and **Party Relationship Groups** allow you to draw connections between individuals and organizations. 

ライフ イベント、実用的なリレーションシップ センター、会計補助元帳、およびタイムラインは、ビジネス プロセスの合理化に役立ちます。Nonprofit Cloud は、個人アカウントと当事者関係グループを使用します。個人取引先を使用すると、人々を取引先担当者として、または取引先として記録することができ、当事者関係グループを使用すると、個人と組織の間のつながりを描くことができます。 

+ [NPC パーティ関係グループと関連オブジェクト(?)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007GGCT7SAP)

Party Relationship Groups が NPSP Affiliations に似ているというあなたの説明は正しいと思います。しかし、NPC はそれをもう少し進めて、ARC (Actionable Relationship Center) タブの下にそれらの表現を視覚的に表示するようです。まだチェックしていない場合は、「Manage Relationships Between People and Organizations」というトピックに関する Trailhead モジュールがあります。

当事者関係グループの記録は、記録を明確にするためだけの所属ではありません。これらはアカウントに対する MD 関係を持ち、世帯に関する追加情報を保存するためのものです。これらは PRG リスト ビューから作成します - [新しいグループ] ボタンをクリックすると、便利なウィザードがポップアップします。アフィリエーションは、NPC におけるアカウントの連絡先関係に相当します。


アカウントとアカウントの関係については、クライアントの仕事から思いつく例をいくつか挙げます。

+ スポーツ財団。同じプログラムの部門を運営する密接に関連する組織が存在することもあります。これは親子アカウント構造ではありません。これらは独自のアカウントと連絡先情報をすべて持っているピア組織ですが、一方はあるサイトで学校内プログラムを運営し、もう一方は同じサイトで放課後プログラムを運営しています。時には機材を調整したり共有したりすることもあります。  
+ 家族の基盤を家庭に。 

-------------------

+ [New Nonprofit Cloud - Party Relationship Group Question](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UuOjvSAF)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/fc63230f-04b6-abf4-483f-524ae8e95793.png)

:::note
- remember to turn on Contacts to Multiple Accounts under Setup :) 
- 
 - [設定] で [複数のアカウントへの連絡先] をオンにすることを忘れないでください :) 
:::

+ [Missing Contact 'Role' field prevents creating new Party Relationship Group](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007W5kHvSAJ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ff8fd129-1a48-558d-6ae6-e47ad831e95c.png)
新米パパが子育てしながら情報処理安全確保支援士試験に合格した話

無事に令和5年秋期、情報処理安全確保支援士試験に合格したので合格体験記を書きます。

:::note info
まず、子育てしながら試験合格ができたのは完全に応援してくれた妻のおかげです。
本当にありがとうございます…！
:::

勉強方法の試行錯誤などがわかるよう、落ちた春期についても言及していきます。

# 私のスペック
勉強開始時点（令和5年、2023年1月）
+ 理系院修士卒（電気）
+ アラサー
+ 転職したて
+ セキュリティ分野はほぼ未経験
+ 子供1人目が爆誕してすぐ
+ IPAの下位資格（基本情報技術者、応用情報技術者）は未所持

# 受験背景
+ セキュリティに関連するソフトを扱う会社に転職したので、セキュリティ分野の理解を深めたいと思ったため
+ そろそろ三十路なのでIPA資格を何も持ってないことに恥ずかしくなってきたため（個人の感想）
+ 共働きが始まりもっと忙しくなる前に資格を取っておきたい
+ 逃げ恥の星野源には負けたくなかったため（？？？！？！）

# 受験戦略
まず、私の状況では午前1からのバトルになります。その分、勉強時間を多く確保する必要がありますので、最大2回での合格を目指しました。

情報処理安全確保支援士はご存知の通り、年2回実施です。春期に午前1免除を確実に取りワンチャン合格をねらい、取りこぼしたら秋期で確実に落とすといったよくある戦法です。

また、秋期からは午後1、2が統合されるため易化を期待してました。
結果としては合格率は例年通りでしたが。。

# 使用教材
+ [徹底攻略　情報処理安全確保支援士教科書(２０１９年版) 通称：登録セキスペ](https://amzn.asia/d/itxhoDy) ブックオフ 中古 220円
+ [情報処理安全確保支援士「専門知識+午後問題」の重点対策 2020](https://amzn.asia/d/1d8eGvr) メルカリ 中古 750円
+ [うかる！ 情報処理安全確保支援士 午後問題集[第1版] ](https://amzn.asia/d/dMvFq9M) Kindle 2090円
+ まさるの勉強部屋(YouTube)
+ 過去問道場(応用情報技術者、情報処理安全確保支援士)
+ 過去問たち

# 春期の学習と結果
### 学習の流れ
試験3ヶ月前に学習開始
1. 徹底攻略を一周読む
1. 過去問道場で午前対策
1. 午後過去問を解く
1. うかる！を読む

:::note warn
午前から対策を始めるのは典型的な負けパターンです
:::

### 学習時間
春期のグラフ
70hくらい
![Screenshot_20230415-231857.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303978/2565f323-f9b4-39c7-86a8-a65c13b5a06c.png)
![1000017406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303978/fcb9fbd7-8332-3564-4f97-caa9588f4326.png)

### 結果
ご覧の通りの爆散
午前1免除はいただけましたが、午後2の採点を受けられなかったので勉強不足です。
![Screenshot_20230629-120829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303978/14d3d1ce-0e4b-bcee-3de9-2e7fac213742.png)

### 反省とオプション
+ 午前対策に時間をかけすぎ
 → 次は直前に軽く流す
+ 過去問午後2をちゃんと解いてた
 → 解かないで読む
+ 過去問解説を理解できてなかった点が多くあった
 → 重点対策を買い足す
+ 午後1選択問題を途中変更した
 → 問題選択の戦略を立てる
+ うかる！が読み終わらなかった
 → ペース配分を調整

# 秋期の学習と結果
### 学習の流れ
試験2ヶ月前に学習開始
1. 重点対策を一周やる
1. 午後1過去問をひたすら解く
1. 重点対策の出題頻度が高い問題をやる
1. 過去問道場で午前2を流す
1. うかる！を読む

### 学習時間
30hくらい。内訳は割愛
![1000017407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303978/4992067c-f0ab-a2f3-cee2-3c6e08c8c0d7.png)

### 結果
合格しました。めでたしめでたし
![Screenshot_20231221-120331.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303978/bb125843-c90b-74ff-8b80-d4a3b0b5cef8.png)
午後は問4が話題でしたが、私は問2、3を選択しました。
支援士的国語力には自信がなかったので、記述が多い大問は避けました。

## 学習方法まとめ
:::note info
1. 午前対策は直前に行う
1. 問題演習を中心に学習
1. 午後2は解かない
1. 解説が詳しい参考書を使う
:::

# 学習時間の確保について
基本的に日中は仕事と家事子育てなので、子供が寝たあとに学習を行っていました。
テレワークが主体ということもあり、1日に2時間くらいは自由な時間が取れました。

# まとめ
セキュリティ分野未経験からだいぶ話がわかるようになりました。
また、IPAの高度を持っていることで自信にもつながり、本試験に合格できて良かったです。

学習期間な合計6ヶ月、総学習時間は約100hなので凡人のそれですが、日々研鑽を怠らず精進していきたいと思います。

本記事が皆様の学習の参考になれば幸いです。
【小ネタ】GitHub.comの経過時間表記をJSTに変換するブックマークレットを作ってみた

リポジトリに書かれているものがそのままなのですが、GitHubの公式サイトの`2 days ago`のような表記を日本時間の`2023/12/31 16:43:01`という表記に変換するブックマークレットを作って公開したのでQiitaでもお知らせです。

https://github.com/Priarts/github_time_JST_bookmarklet

動作確認はMacのChromeだけでやっています。もし他のブラウザで動かなかったらごめんなさい。

あとChrome拡張で、ページに来たらいきなり変換するのを作ろうかと思ったのですが、`2 days ago`は別に良いけど`5 years ago`だと、いつやねん！って思って変換したくなるとかもありそうだったと思ったので、ブックマークレットで作っています。

n番煎じかもしれませんが、良かったら使ってみてください🙏🏻
PHPでのSQL文の実行時の注意 - 備忘録(´・ω・｀)

# 何この記事
その名の通り備忘録。
みんなが知っているSQLインジェクション対策で同じように間違えないように、、、
# 短い本編
初心者と経験者と分けて説明します。
今回使うテーブルにはサザエさん一家を使います。
テーブル名：Family
| ID | Name |
|:-|:-|
|1|フグ田サザエ|
|2|磯野波平|
|3|磯野フネ|
|4|フグ田マスオ|
|5|磯野カツオ|
|6|フグ田タラオ|
|7|磯野ワカメ|
|8|タマ|

### 初心者
PHP触りたてほやほやの人が書きそうな文
```PHP
$ID = 1;
$sql = "SELECT*FROM `Family` WHERE ID = '" . $ID . "';";
$stmt = $dbh->query($sql);
```
おや？SQL文が簡単そうですね。では、実行してみましょう。
#### 結果
| ID | Name |
|:-|:-|
|1|フグ田サザエ|

IDが1の人がヒットしました。さて、皆さんはお気づきかもしれませんが、この文では攻撃が簡単にされてしまうんです。
では、攻撃をしてみましょうw
```PHP
$sql = "SELECT*FROM `Family` WHERE ID = '" . $_GET['format'] . "';";
$stmt = $dbh->query($sql);
```
先ほどの`$ID`を消してGET関数で取得してみましょう。
この時に攻撃を仕掛けます。
```URL
https://exsample.com?format=1; DROP TABLE Family
```
#### 結果
| ID | Name |
|:-|:-|
|1|フグ田サザエ|

Q. あれ攻撃できたのかな？
A. 出来てます。(ΦωΦ)
PHPMyAdminでテーブルを確認すると、
. . . テーブルがない。( ;∀;)

サザエ一家がお亡くなりになった？！
説明すると、SELECTした後にDROPしたのでテーブルがなくなる仕組みになっています。
じゃあどうすればいいのさ！初心者は考えました。
妄想↓
> 変数の空白をなくせばいいんじゃね？
>> でも、Blog投稿とかしたいのに空白なくすのは嫌だなー。

初心者：諦めるか！
経験者：PHPに愛はあるんか！
初心者：あるっちゃある . . .
経験者：なら、我についてこい！
おっと、経験者が何か答えを出してくれるそうです。
### 経験者
:::note alert
攻撃されやすい書き方
:::
```PHP
$sql = "SELECT*FROM `Family` WHERE ID = '" . $_GET['format'] . "';";
$stmt = $dbh->query($sql);
```
:::note info
攻撃されにくい書き方
:::
数値を入れたい場合
```PHP
$sql = "SELECT*FROM `Family` WHERE ID = :ID ;";
$sql->bindValue(':ID', 1, PDO::PARAM_INT);
$sql->execute();
```
文字列を入れたい場合
```PHP
$sql = "SELECT*FROM `Family` WHERE Name = :Name ;";
$sql->bindValue(':Name', 'フグ田サザエ', PDO::PARAM_STR);
$sql->execute();
```
さて、違いがわかると思いますが、`bindValue()`と`PDO::`を使って実行文ではなく普通の文字列または数値として扱ってくれます。あら、うれしいわ♡
ふつうに関数も
```PHP
$sql->bindValue(':Name', $_GET['format'], PDO::PARAM_STR);
```
として入れることができます。
### まとめ
最初は文字列を結合して実行文を完成させるということで実行していました。しかし、これでは攻撃されやすいので、文字列として受け入れるようにしました。
みなさんも、攻撃には気を付けてください。(ΦωΦ)
Youtube Musicでまとめてdislike(低評価)をするスクリプト

### 動機

Youtube Musicを使っていると、聞きたくない曲(特定アーティストの曲)がそれなりに自動で再生されてしまうので何とかしたい
フィードバックとしてdislikeボタンがあるが、それを何度も押してもそのアーティストの曲は普通に流れてきたりする。特に顕著なのが協調フィルタリングでおすすめされそうなファンベースが近いアーティストで、全曲dislikeでもしないと普通に自動再生に入ってきてしまう
1個1個手でやってもいいが、途中でめんどくさくなった

### コード
1回やるだけなら、対象のアルバムやアーティストの曲リストのページでChromeの開発者コンソールからこのコードを貼り付けるだけで良い。1.5秒毎に1曲dislikeを付けていく。

```
document.querySelectorAll('yt-button-shape#button-shape-dislike button[aria-pressed="false"]').forEach((button, index) => {
    setTimeout(() => {
        button.click();
        console.log(index);
    }, 1500 * index);
});
```

注意点としては現時点(2024/1/4)でdislikeボタンは押しても反映されないことがあるので、処理が終わったらリフレッシュして再度これを走らせる必要がある。このスクリプトの問題ではなく、手で押しても失敗したりする。特に間隔を開けずに連続で押すと起きやすいので1.5秒とかなり長めの遅延を付けている。
曲数が多い場合は一番下までスクロールしてから走らせないと漏れが出る

いちいち開発者コンソールを開くのも面倒な場合は以下のTampermonkeyスクリプトをインストールする
右上にdislikeボタンが出るので押せば文字が変化していく
直接インストールはこちらから

https://greasyfork.org/ja/scripts/483807-youtube-music-dislike

```
// ==UserScript==
// @name         Youtube music dislike
// @namespace    http://tampermonkey.net/
// @version      2024-01-04
// @description  Youtube Musicでまとめてdislike
// @author       You
// @match        https://music.youtube.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    var newButton = document.createElement('button');
    newButton.textContent = 'まとめてdislike';

    newButton.addEventListener('click', function() {
        document.querySelectorAll('yt-button-shape#button-shape-dislike button[aria-pressed="false"]').forEach((button, index) => {
            setTimeout(() => {
                button.click();
                newButton.textContent = 'まとめてdislike#' + (index+1);
                console.log(index);
            }, 1500 * index);
        });
    });

    var targetElement = document.querySelector('.ytmusic-nav-bar .settings-button');
    targetElement.parentNode.insertBefore(newButton, targetElement.nextSibling);
})();
```

全曲dislikeしても新曲が出たらまた自動再生に入ってしまうリスクはあるが、まあ仕方ない。後はSpotifyに移行するくらいしか選択肢がないが、ローカルの曲をアップロードできないので厳しい
もうちょっと自動再生の候補まともにしてくれませんかね・・・
Gmail から iCloud にメールを転送する: 究極のガイド

<p>「こんにちは、私は Gmail アカウントを長い間使用しています。 次に、選択した Gmail メールボックスを iCloud アカウントに転送する必要があります。 無料のソリューションを探しましたが、適切なソリューションが見つかりませんでした。 すべての添付プロパティを含む電子メールを Gmail から iCloud アカウントに転送する方法はありますか? 助けてください。"</p>

<p>あなたもそのような仕事をしたいと考えている人の一人ですか? 答えが「YES」であれば、心配する必要はありません。</p>

<p>今日の チュートリアルでは、情報を失わずに Gmail メールを iCloud に転送するための最良のソリューションを提供したいと思います。</p>

<p>それでは、ガイドを最後まで読み続けてください…</p>

<h2>Gmail から iCloud アカウントにメールを転送するのに最適なアプリのご紹介</h2>
<p>この作業は「<a href="https://forensiksoft.com/jp/email-backup.html"><strong>メールバックアップソフト</strong></a>」を使えば簡単に行えます。 これは、問題なく Gmail から iCloud アカウントにデータを転送できる、柔軟で信頼性の高い最良のツールです。 このツールを使用すると、ユーザーはバッチまたは選択したメールボックスを iCloud アカウントに転送できます。</p>

<p>さらに、このタスクにはそのような手続きはありません。 以下に示す簡単なクリックを数回行うだけです。</p>

<h2>Gmail を iCloud アカウントに転送する簡単な手順</h2>
<ul>
<li>まず、Windows マシンにツールの無料デモ版をダウンロードします。 このフリーウェアは、投資する前に使用することをお勧めします。 このデモ版では、ツールの全体的な機能と動作を確認できます。</li>
<li>次に、アプリケーションを適切にインストールし、「開く」ボタンをクリックします。</li>
<li>指定されたオプションから [アカウントの追加] オプションを選択します。</li>
<li>Gmail アカウントのログイン資格情報を入力し、「追加」ボタンをクリックします。</li>
<li>ツールは、左側のパネルで Gmail のメール フォルダーの分析と読み込みを開始します。 次に、データを転送する必要があるメールボックスを確認してください。</li>
<li>次に、保存オプションとして IMAP を選択します。</li>
<li>電子メール アドレス、パスワード、IMAP サーバー、IMAP ポート番号などの必要な認証情報を入力します。最後に、「バックアップ」ボタンをクリックして、Gmail メールボックスを iCloud アカウントに転送するプロセスを開始します。</li>
</ul>

<p>プロセスが完了したら、iCloud 電子メール アカウントにログインして、結果のデータを確認します。</p>

<h3>サードパーティ製アプリケーションを選択する理由</h3>
<p>Gmail メールを iCloud アカウントに手動で転送することを考えている場合、これは不可能です。 このタスクを手動で実行する方法はありません。</p>

<p>安全で正確な結果を得るには、サードパーティのアプリを使用することをお勧めします。 前述のツールは、多くの IT 管理者によって強く推奨されているアプリケーションの 1 つです。 このアプリケーションを使用すると、頭を悩ませることなく、安全で正確な結果を簡単に得ることができます。 また、このツールは非常に多くの先進的で魅力的な機能を提供します。</p>

<ul>
<li>Gmail to iCloud ツールには、あらゆる種類のリスクやバグが 100% ありません。</li>
<li>非常にシンプルなグラフィカル ユーザー インターフェイスが提供されます。</li>
<li>Gmail から iCloud アカウントに電子メールを正確に転送できます。</li>
<li>このタスクを実行するためにサポート アプリケーションをダウンロードする必要はありません。</li>
<li>Gmail アカウントのデータを同時に一括転送する機能。</li>
<li>また、データ転送中にすべての電子メール プロパティを維持します。</li>
<li>Windows オペレーティング システムのすべてのエディションと互換性があります。</li>
<li>ユーザーが要件に応じてデフォルトの言語を変更できるようにします。</li>
<li>技術者ユーザーも非技術者ユーザーもこのアプリケーションを簡単に操作できます。</li>
<li>添付ファイル付きの Gmail 電子メールを iCloud に転送することをサポートします。</li>
<li>無制限の Gmail メールボックスを無制限に iCloud アカウントに転送できます。</li>

<h3>最後の言葉</h3>
<p>上記のガイドでは、簡単なクリックで Gmail メールを iCloud アカウントに転送するための最良のソリューションの 1 つを提供しました。 推奨アプリを使用すると、Gmail アカウントのデータをほとんど失わずに一括転送できます。 また、提案されたアプリケーションは、Gmail メールをすべての添付情報とともに転送するのに役立ちます。</p>

<p>ご提案が必要な場合は、メールでご連絡ください。 いつでも喜んでお手伝いさせていただきます</p>
デイリースクラムがうまくいかない話

こんにちは。Kaneyasuです。
最近、スクラムを勉強しています。
私が目指しているスクラムでの役割はスクラムマスターです。

早速チームを組んでスクラムをやってみているのですが、わかってはいましたが難しいですね。
苦労しているポイントは多数ありますが、今回の記事ではデイリースクラムに関する悩みに焦点を当てます。

# デイリースクラムとは

デイリースクラムとは、スクラムチームのメンバーが毎日行う15分程度のミーティングです。
デイリースクラムの詳細は、[スクラムガイド]([デイリースクラム](https://scrumguides.org/docs/scrumguide/v2020/2020-Scrum-Guide-Japanese.pdf))を読んでみてください。

私たちはデイリースクラムで、以下の3つの質問に答えるというルールを設けていました。

- 昨日実施したこと
- 今日実施すること
- 困っていること

ここから先は、私たちがデイリースクラムをやっていて悩んだことを書いていきます。

# デイリースクラムの時間になっても人が集まらない

私たちのスクラムチームは、スクラムマスターが私で、プロダクトオーナー1人、開発者3人という体制です。
開発者は運用・保守も担当しており、スクラムに対して専任ではありません。
専任でないのは今やってるスクラムの優先度が低いからですね。

この体制で、朝、始業直後にデイリースクラムをやってみたのですが、人が集まらない！
不参加自体はやむを得ないことですが、当日になって不参加となるのは望ましくないと考えています。

突発的な仕事は発生するものですから、マナー云々とかは問題視していません。
問題と感じたのは、当日になって不参加になること＝計画が立てれてない、不確定要素が多いというところです。

スクラムマスターとして、不確定要素を取り除くために開発者のスクラム以外の業務を見える化し、調整することを手助けすべきかと思っていますが、仕事はこれだけではないので慎重に考えています。
他のプロジェクトに過干渉する形になってしまえば逆効果になると思うので。

対策として、デイリースクラムの時間を変えてみたりしましたが、最終的には確実に人が集まる時間帯を探すと始業前か夕方になってしまい、明らかにこれは違うなということで、デイリースクラムの時間帯自体は始業直後のままにしました。

# 15分以内にデイリースクラムが終わらない

デイリースクラムは15分以内に終わらなければならないというルールがあります。
正直なところ、スクラムを始める前は15分なら大体あまると思っていました。
スクラムメンバーがまだ少ないですからね。
ですが、実際にやってみるとすぐ過ぎてしまうことがわかりました・・・。

デイリースクラムの中で議論が発生するとあっという間に15分を超えてしまいます。
議論自体は悪くないんですが、たいていの議論は1対1でやっているので、他のメンバーはただ待っているだけになってしまいます。
こうなってくると、開発者の中でデイリースクラムに対して、やたら時間がかかるもの、自分には関係ないもの、面倒なもの、という印象が強くなってしまいます。
この辺りが、デイリースクラムの不参加が増える原因にもなっていたのかなと思っていて、自分のファシリテーション不足を反省しています。

対策として、先に全員の報告を済ませて、質問・相談がある人は、デイリースクラムの後に別の場所で議論するようにしました。
時間を守ることで予定を立てやすくする、議論に参加していない人に配慮するのを大事にしたいと思います。

# Slackでデイリースクラムをやる

上述の2点を踏まえて、デイリースクラムをどうするかを考えてみて、現在はSlackでやっています。
Slackのスレッド機能を使って、デイリースクラムの時間になったら、スレッドを立てます。
スレッド上で各開発者に下記質問事項の回答をしてもらいます。

- 昨日実施したこと
- 今日実施すること
- 困っていること

正直なところ、Slackでデイリースクラムをやるのは、少々抵抗がありました。
顔が見えなかったり、言葉のニュアンスが伝わらないとかないだろうがと思ったのですが、今のところ困っているところに対し議論も発生しているので、機能はしていると思っています。

これでよいのか？というのは今も感じていますが、状況から見るに現時点ではこのやり方がベターなようです。

# 現状のデイリースクラムに足らないもの

本記事を書いていて気づいたのですが、現状の私たちのデイリースクラムには各人のタスクに対して会話する仕組みはありますが、ゴールに対して会話する仕組みがありませんね。
具体的にはバーンダウンチャートやカンバンを見て、何かコメントするようなルールを設けていません。

スクラムマスターが一方的にそこにコメントするのもどうかと思うので、交代制にするか？と思っていますが、これはもう少し考えてみたいと思います。

# まとめ

つらつらと現時点のデイリースクラムの悩みについて書いてみました。
今私が思うのは、以下の通りです。

- デイリースクラムは、時間を守らないと、メンバーが時間がかかるものと認識するようになる
- デイリースクラムで、議論をし過ぎると、メンバーが面倒なものと認識するようになる
  - これをくり返すると、デイリースクラムの不参加率が上がる可能性がある
- 現時点ではSlackでデイリースクラムをやるのがベター（というこれが限界）
- デイリースクラムは、ゴールに対して会話する仕組みも必要
- デイリースクラムの不参加率が高かったのは、他の業務も含めて対策を考える必要がある
  - ただし、仕事はこれだけではないので慎重に

またスクラムを進めて感想が溜まったら記事にしたいと思います。
本記事がスクラムで同じような悩みを持っていとの励み？になったら幸いです。
【Blender】モデルのポリゴン数の表示を表示する方法

# はじめに
3Dモデルのポリゴン数は少ないほうが軽量化する事ができるので、
Blenderで作成した3DモデルをUnityやVRChatで使用する事を想定すると、
なるべく軽量化したほうが良いかと思います。
本記事ではBlenderで3Dモデルのポリゴン数を確認する方法を紹介します。

# ポリゴン数とは？
三角形（3つの頂点や辺で囲まれた1つの平面）の数のことです。


# 統計情報の表示
Bleder画面右上の「オーバーレイ」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/660cf45d-331a-ea4a-a69b-e85d4248f849.png)


「統計」のチェックボックスに✅を入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/788f2bb7-8c3c-c9b9-ae82-a79c36dd6048.png)

Bleder画面左上に頂点、変、面、三角形面といった情報が表示されます。
この中で三角形面がポリゴン数を表しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/adcb8aec-89e1-4b23-bd59-9ab96bbb3749.png)


# 参考
https://creator.cluster.mu/2023/01/11/blender-3dweight/
VScodeにplatform io を入れて使いたかったけどエラーが出た話

--- 
### vscodeでplatformioをインストールして使用した際にうまくいかなかったこと。

platformioをvscodeに入れてプロジェクトを作成
試しにESP32に書き込んでみる
 ```
FileNotFoundError: [Errno 2] No such file or directory:
```
ここでエラーが発生

#### ディレクトリが存在しない、または存在する場合でもアクセス権がないというエラーが出た。

あるのに…

main.cppを見ると#include <Arduino.h>でエラーが発生してる
![スクリーンショット 2023-11-28 16.16.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532768/bd1c74e5-40a2-389b-222e-e0774154065b.png)

####  「****includePathを更新してください」みたいなエラーが出た****


調べたら似たような記事が出てきたので参考にさせてもらう
https://qiita.com/okashi_ageruyo/items/a0c243d3b681c9dc89db

コンパイラ　パスをgccに変更してみる
![スクリーンショット 2023-11-28 16.21.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532768/30e852bc-49a3-f8b1-5b91-da1caf01a6c4.png)
エラーは変わらなかった



もう少し調べると近いことが起こっている記事を発見した
https://kainokikaede.hatenablog.com/entry/2021/04/22/222352
以下本文中から抜粋

#### 「このエラーが発生する原因は、最近の [macOS](http://d.hatena.ne.jp/keyword/macOS) には `/usr/include` が存在しないのにもかかわらず [VSCode](http://d.hatena.ne.jp/keyword/VSCode) （もしくは PlatformIO もしくは [C/C++](http://d.hatena.ne.jp/keyword/C/C%2B%2B) extension）が `/usr/include` を読みに行っているからだと思われる。」
らしい

pathを出力してみる
```
$ xcrun --show-sdk-path
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
```

出力されたpathを貼り付け
![スクリーンショット 2023-11-28 16.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532768/1894ef04-b77d-c358-523c-999494cb9e8b.png)
こんな感じに変更

それでもエラーが取れない

Ardiuno.hがそもそも生成されてないかも？
確認してみた

```
ls /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ | grep "Ardiuno.h"
```
やっぱりなかった

プロジェクト作成時に/usr/includeに<Ardiuno.h>が生成されるかも？


もう一度プロジェクト作成から始めてmain.cppを確認した
![スクリーンショット 2023-11-28 16.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3532768/ebf480e4-15d6-8d85-206b-cfed73e63010.png)
エラーが消えてる

ビルドも通った




# まとめ
正しいpathを設定使用！！

# 参考
https://qiita.com/okashi_ageruyo/items/a0c243d3b681c9dc89db

https://kainokikaede.hatenablog.com/entry/2021/04/22/222352
SQL join

```SQL
SELECT
    T.da,
    split_part(T.ticker, ' ', 1) as ticker,
    T.weight,
    M.name,
    P.cl
FROM
    portfolio_weight AS T
JOIN LATERAL (
    SELECT cl, da, ticker
    FROM price
    WHERE da = T.da
) AS P ON T.ticker = P.ticker
LEFT JOIN
    name_table AS M ON P.ticker = M.ticker
WHERE
    T.STRATEGY_NAME = '{strategy_name}'
ORDER BY
    cl DESC;
```
能登半島地震の航空写真の一枚画像を作る方法

国土地理院が能登半島地震の航空写真を地理院地図へ公開していた。
[地理院地図での可視化例](https://maps.gsi.go.jp/#17/37.396467/136.901816/&base=pale&ls=pale%7C20240102noto_wazimanaka_0102do%7C20240102noto_suzu_0102do%7C20240102noto_wazimahigashi_0102do%7Cseamlessphoto&blend=0000&disp=11111&vs=c1g1j0h0k0l0u0t0z0r0s1m0f0&vs2=f0&sync=1&base2=std&ls2=std%7C20240102noto_wazimahigashi_0102do%7C20240102noto_wazimanaka_0102do%7C20240102noto_suzu_0102do&blend2=000&disp2=1111&lcd2=20240102noto_suzu_0102do)

本記事では、Pythonを使って、地図タイルを一枚のGEOTIFF画像にする方法を記載する。

主に下記記事を参考にした。

https://qiita.com/nokonoko_1203/items/5c32c22b92bb72e7770c

```python:必要ライブラリのインポート
import subprocess
import glob
from tqdm import tqdm
from tile_operator.operate import TileOperate, file_to_bounds
```

範囲の指定方法は、上で引用している記事中にも書いてある通り、https://geojson.io/ を使うと良い(本記事での変数名はfile_path)。
```python:取得する範囲を指定
file_path = "./wajima.geojson"
bbox = file_to_bounds(file_path).bounds()
print(bbox)

to = TileOperate(
    bbox=bbox,
    zoom_level=18,
)

to.set_tile_list()
tile_list = to.get_tile_list()
print(len(tile_list))
```
地図タイルのURLは下記を参照(本記事での変数名はtile_url)。
https://maps.gsi.go.jp/development/ichiran.html#t20240102noto_wazimahigashi_0102do
```python:地図タイルを取得
tile_name = "20240102noto_wazimanaka_0102do"
tile_url = f"https://cyberjapandata.gsi.go.jp/xyz/{tile_name}" + "/{z}/{x}/{y}.png"

for tile in tqdm(to.tile_list):        
    to.download_tile(tile_url, tile[0], tile[1], output=f"./{tile_name}")
    tile_path = f"./{tile_name}/18/{tile[0]}/{tile[1]}.png"
    to.tile_to_geotiff(tile_path)
```

```python:取得した地図タイルから一枚の画像を作成
files = []
for y_name in tqdm(glob.glob(f"./{tile_name}/18/*")):
    files = files + glob.glob(f"{y_name}/*.tif")
command = ["gdal_merge.py", "-o", f"./18.tif", "-co", "BIGTIFF=YES"] + files
subprocess.run(command)
```

作成例
![18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282333/8be4e857-9cbe-dae7-4bf9-fd59e0d5aaa4.jpeg)
図の上側は輪島市「朝市通り」の周辺で、広範囲に全焼していることが分かる。

https://www3.nhk.or.jp/news/html/20240103/k10014307881000.html


本記事が何かのお役に立てば幸いです。
Eclipseパッケージエクスプローラのディレクトリを分解する方法


# 設定方法
パッケージエクスプローラの「…」から
「Package Presentation」→ 「Flat」 Or 「Hierarchical」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658170/d73b6cdc-be39-768b-d066-f0bbb3d2b2a8.png)

## Flat
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658170/71691378-e75b-0f7a-501d-f95018e24c78.png)

## Hierarchical
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658170/add555e6-861e-3589-a802-7aee5f4be763.png)
ReactでYoutubeの埋め込みをするときにレスポンシブに対応したい

<h1> はじめに

Youtubeの埋め込みをしたのですが、レスポンシブに対応するのに困ったのでまとめていきます。

# 問題

`react-player`と`react-youtube`のどちらかを使って、
モバイルのときは指定した高さと幅
それ以外は幅を100%

という条件にしたかったのですが、なぜか大きさが変わらなかったり、大きさは変わるがプレイヤーの中は変わらない現象が起きました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f61ceb9a-e807-6c04-7a3f-1e14835f78a9.png)

# 解決方法

結果的には`react-player`のwidthとheightを指定することで解決しました (classNameで調節していたのでだめでした)

```tsx
        <ReactPlayer
          url={videoUrl}
          className="md:hidden"
          width={"343px"}
          height={"192px"}
        />
        <ReactPlayer url={videoUrl} className="hidden md:block" />
```

# おわりに

なんとか解決できたので壁は超えた感じがしました
CythonでPythonコードを高速化する。

# 1.初めに

Cythonを利用して、自分が書いたNumpyコードをどこまで高速化できるかを確認します。

# 2.Cythonと評価関数の準備

## 2.0. Cythonのインストール
Cythonをインストールします。
```bash:setup
pip install Cython
```

## 2.1. Pure Pythonの評価関数
評価用の関数を作成します。0からNまでの和を計算する単純な関数です。
純粋なPythonで関数を作成します。
```python:test_function.py
def sum1(n):
    sum = 0
    for i in range(n):
        sum += i
    return sum
```

## 2.2. Cython形式の評価関数

Cythonのため、pyxのコードを作成します。結果が大きくなるので、intを使うとoverflowが発生します。そのため、longを使います。

```pyx:test_function_cython.pyx
# test_function_cython.pyx
def sum2(int n):
    #cdef int i, sum = 0
    cdef long long i, sum = 0
    for i in range(n):
        sum += i
    return sum

```


# 3.Cythonコードをビルドする。

このCythonコードをビルドするためのセットアップファイルを作成します。

```python:setup.py
from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("test_function_cython.pyx")
)
```

ビルドを実行して、Cythonモジュールを生成します。

```bash:setup
python setup.py build_ext --inplace

```


## 実行時間の計測

```python:time_measurement_main.py
# https://youtu.be/T-ddo2V1HZE?si=beD-3RBQUSz5ExX0

from test_function import sum1
from test_function_cython import sum2
import time

if __name__ == "__main__":
    N = 10000000

    start = time.time()
    i = sum1(N)
    end = time.time()
    print(f'Pure python time is {str(end-start)} seconds')
    time1 = end-start
    print(str(i))
    print(N)
    start = time.time()
    i = sum2(N)
    end = time.time()
    print(f'Cython time is {str(end - start)} seconds')
    time2 = end-start
    print(str(i))

    print(f'Cython is faster than pure python by {round(time1/time2,0)} times.')
    print(f'Cython is faster than pure python by {round(time1 / time2, 2)} times.')

```

Cythonのほうが200倍以上速いです。

```bash:result

Pure python time is 0.5340635776519775 seconds
49999995000000
10000000
Cython time is 0.0019910335540771484 seconds
49999995000000
Cython is faster than pure python by 268.0 times.
Cython is faster than pure python by 268.23 times.

```
# 参考文献

* https://www.youtube.com/watch?v=T-ddo2V1HZE&ab_channel=%E6%B9%AF%E3%81%A9%E3%81%86%E3%81%B5%28%E5%8C%96%E5%AD%A6%E3%81%AE%E5%8B%89%E5%BC%B7%29
ログイン時にnvidia-driverの依存関係でupgradeできずにログインできない問題

# 経緯
- 久しぶりに自作PCを立ち上げると、ログイン画面に遷移せず以下のエラーが発生したため、なんとか復旧を試みる
    ``` 
    ** Bluethooth hci0: Malformed MSFT vender event: 0x02
    ```
# 結論
- 得意のnvidia-driverの自動更新による依存関係の崩壊
- 問題が発生しているドライバーの再インストールで解決
    - 参考URL：https://www.nemotos.net/?tag=nvidia
# やったこと
- まずは、よくわからんので、とりあえずttyにctr+alt+F2でログイン
    - おまじないの、sudo apt update & sudo apt upgradeを実行
    - upgrad時に以下のエラーが発生し、'apt --fix-broken install'を推奨されるが解消せず
    ```
    nvidia-dkms-525 : 依存: nvidia-kernel-common-525 (= 525.126.06-0ubuntu1) しかし、525.129.03-0ubuntu0.22.04.1 はインストールされています
    nvidia-driver-525 : 依存: nvidia-compute-utils-525 (= 525.126.06-0ubuntu1) しかし、525.129.03-0ubuntu0.22.04.1 はインストールされています
    ```
    - エラーをよく見ると、すでにインストールされているdriverとupgradeによって更新しようとしているdriverの依存関係の問題でupgradeできていないことが判明
    - あとは、結論のURLに沿って、driverをとってきて強制更新で解決
- 再発防止
    - nvidia-driverの自動更新をOFFにする
        - 参考URL：https://zenn.dev/kn64872/articles/9d52673d254637

# おまけ
- そもそも引越し後に自作PCを起動していなかったので、ネットがつながっていなかったので、ネットからdriver取得ができていなかった
- Wi-Fiの設定をCLIで実施
    - 参考URL：https://kkkw.hatenablog.jp/entry/20220502/1651471611
#
LaraveでCSSをresourcesディレクトリ内に配置する

# はじめに
今まで'***public/css***' ディレクトリ内に配置していたが、'***resources/css***' ディレクトリ内に配置する方法をまとめる

# 開発環境
Laravel 8
Node.js

# '***public***' と '***resources***' ディレクトリの違いについて

| ディレクトリ名 | 説明 |
|:-|:-|
| public | 外部から直接アクセス可能なファイルを格納するための場所 |
| resources | アプリケーションのリソースやソースコードを格納するための場所<br>Laravel Mixなどのビルドツールを使用して最終的な成果物が '***public***' ディレクトリに配置される |

# Laravel Mixの設定
'***webpack.mix.js***' ファイルを編集し、どのCSSファイルをコンパイルし、どのJavaScriptファイルをバンドルするかを指定する
```JavaScript:webpack.mix.js
mix.js('resources/js/app.js','public/js')
   // ...他のJavaScriptファイルを記述
   .postCss('resources/css/app.css','public/css')
   // ...他のCSSファイルを記述
```

# コンパイルとバンドル
Laravel Mixを使ってCSSとJavaScriptをコンパイルおよびバンドルする
```bash:bash
npm run dev
```
もしくは、開発時にファイルの変更を監視して自動的にコンパイルするには、以下のコマンドを実行
```bash:bash
npm run watch
```

# ブラウザでデザインを確認
生成されたCSSファイルは、'***public/css***'ディレクトリに配置されるので、'***asset()***'ヘルパー関数でCSSファイルを読み込む

```html:blade.php
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
```
これにより、CSSファイルがブラウザに提供され、デザインの確認が行えるようになる

# さいごに
なお、'***Javascript***' も '***resources***' ディレクトリ内に配置することができる
今後は基本的に'***resources***'ディレクトリに配置することに慣れていこうと思う
wslでelixir その127

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
LivebookでAtCoderやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/889e1e9b-95d9-acaf-abc2-36e94ad0431b.png)


# サンプルコード

abc245 d
```
defmodule Main do
	alias MyIO, as: IO
	def next_token(acc \\ "") do
		case IO.getn(:stdio, "", 1) do
			" " ->
				acc
			"\n" ->
				acc
			x ->
				next_token(acc <> x)
		end
	end
	def input(), do: IO.read(:line) |> String.trim()
	def ii(), do: next_token() |> String.to_integer()
	def li(), do: input() |> String.split(" ") |> Enum.map(&String.to_integer/1)

	defp output({result, _, _, _}), do: result |> Enum.join(" ")
	defp division(_, {acc, rem, cs, as}) do
		quo = div(hd(rem), hd(as))
		rem1 = Enum.zip(rem, as)
		|> Enum.map(fn {x, a} ->
			x - a * quo
		end)
		[c | cs1] = if Enum.empty?(cs), do: [nil], else: cs
		rem1 = (tl rem1) ++ [c]
		{[quo | acc], rem1, cs1, as}
	end
	defp solve(as, cs) do
		al = Enum.count(as)
		cl = Enum.count(cs)
		rem = Enum.take(cs, al)
		cs1 = Enum.drop(cs, al)
		1..cl - al + 1
		|> Enum.reduce({[], rem, cs1, as}, &division/2)
 		
		|> output()
    |> rev_integer_list()
    |> Enum.join(" ")

	end
	defp rev_integer_list(str) do
		str
		|> String.trim()
		|> String.split(" ")
		|> Enum.map(&String.to_integer/1)
		|> Enum.reverse()
	end
    
	def main() do
    li()
		as = li()
  	cs = li()
  	solve(as, cs)
		|> IO.puts()
	end
end

```

# 実行結果

```
{["1 2\n2 1\n12 14 8 2\n", "1 1\n100 1\n10000 0 -1\n"], ["6 4 2\n", "100 -1\n"]}
-- TEST 0 --
OK
-- TEST 1 --
OK

```


以上。
セコム安否確認サービスのメールをLINEへ通知する

### はじめに
所属会社ではセコムの安否確認サービスを利用して安否確認を行っています。
私は自分のスマホのGmailへ案内が届くように設定しています。
しかし、Gmailは1日でかなり多くのメールが届くことと、発信条件が日本全国が対象となっており、今回のように自分の地域でも揺れれば気づくのですが、遠い地域などではニュースなどを見ていないと気づかず、メールを見落とすことがありました。
そのため、よく使うLINEへ通知できないかとGAS経由でLINEに通知することにしました。

### Gmail側設定
自分はわかりやすいように「セコム安否確認」というタグをメールにつくようにしました。
差出人と差出メールとの組み合わせで取りこぼしがないよう設定

### GAS側の設定
Gmailでセコム安否確認というメールが来たら実行されます。
内容は本文全文そのまま転載のため、安否確認の返信はLINEからリンクを開けばいいので、メールの見落としもなくスムーズになるかと思います。

実行後にはメールを既読に変更し、新着メールとの区分けをすることで
重複通知がLINEに行かないようにさせています。
またトリガー実行は５分毎

Gmail 1/2 10:21　→　LINE  1/2 10:24
Gmail 1/2 17:19　→　LINE  1/2 17:19
Gmail 1/3 10:58　→　LINE  1/3 10:59

時間もこのような形で動いてます。
この時間はご自由に変更ください。


### GASのコード

```
var lineToken = "AAAAAAAAAA"; //ここにはご自身のLINE Notifyのトークンを入れてください

function send_line(Me) {
    var payload = { 'message': Me };
    var options = {
        "method": "post",
        "payload": payload,
        "headers": { "Authorization": "Bearer " + lineToken }
    };
    UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}

function fetchContactMail() {

    var ISREAD_LABEL = GmailApp.getUserLabelByName('セコム安否確認');
    var strTerms = 'label:セコム安否確認 is:unread';

    var myThreads = GmailApp.search(strTerms);
    var myMsgs = GmailApp.getMessagesForThreads(myThreads);

    var valMsgs = [];
    for (var i = 0; i < myMsgs.length; i++) {
        var subject = myMsgs[i].slice(-1)[0].getSubject() || "(No subject)";
        var body = myMsgs[i].slice(-1)[0].getPlainBody().slice(0, 600) || "(No body)";
        var from = myMsgs[i].slice(-1)[0].getFrom() || "(No from)";

        valMsgs[i] = "\n■" + subject + "\n" + body + "\n" + from;
    }

    myThreads.forEach(function (t) {
        t.addLabel(ISREAD_LABEL);
        t.markRead();  // 追加：既読にする
    });

    return valMsgs;
}

function main() {
    var new_Me = fetchContactMail();
    if (new_Me.length > 0) {
        for (var i = new_Me.length - 1; i >= 0; i--) {
            send_line(new_Me[i]);
        }
    }
}
```

### 最後に
今回の地震で複数回発信がありましたが、社内では
どこまでが返信済で、どこまでが未返信かわからなくなった、という方がいました。
Gmailを既読にしてしまうのが難点かもしれませんが、
トークルームをこれ専用にしてLINEから直接返信可能なので、LINEの通知で対応するようにすれば、返信忘れ防止に役に立つかもしれませんね。
AWS Lambdaのローカル環境構築メモ

# 初めに
新しいWin11のPCにlambdaのローカル開発環境作ることになったのでメモとして残す。
※Hyper-V上に作成したまっさらなWindows11の仮想マシンに入れたものです。


# Pythonインストール
ここからインストーラ落とす。今回は3.12.1を入れる

https://www.python.org/downloads/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/c8e3d152-440e-00b9-b190-640ad237802a.png)

チェック入れてInstall Now
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/e81c982c-3cfb-a34d-6a20-80a8150383de.png)

Disable path length limitが出るが何もしない（今回はそこまで深い階層パスになることがない想定なので）
何もせずCloseする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/3b27c2f0-edd3-1f9f-a25c-8a609265c729.png)

# Visual Studio Codeをインストール
ここから落とす

https://azure.microsoft.com/ja-jp/products/visual-studio-code

特に変更するところもないので、そのままセットアップウィザードの通りに進める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/c4142edd-b348-73a0-4521-75f02eaa34a0.png)


# Docker Desktop for Windowsをインストール
ここからDocker Desktop for Windowsのインストーラを落とす

https://docs.docker.com/desktop/install/windows-install/

チェック入れてOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/312369a3-6642-1486-91bf-15f2cd1e2300.png)

インストール後再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/4176afbb-d20d-454e-17bb-8debe58a3723.png)

# Gitをインストール
この記事の通りに入れる（先人の知恵に感謝）

https://qiita.com/T-H9703EnAc/items/4fbe6593d42f9a844b1c

# AWS CLIをインストール
ここからv2のインストーラを落としてくる

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

特に変更せずそのまま入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/1a9f46dc-b2d9-4be0-a1cd-8f15a49a878d.png)

# AWS SAM CLIをインストール
ここからインストーラを落とす

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html

特に変更とかせずそのまま入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/488c30d9-7f8c-56cb-9bf0-9f22c4d944b3.png)

# VSCodeにpythonを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/f6b9e3db-5c67-f29a-a156-b7339e608dd6.png)

# VSCodeにAWS Toolkitを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/105c9658-d504-b0da-7f3c-cab3c688c4d1.png)

# IAMユーザの作成
AWSのコンソールに入り、新しくユーザを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/8cd06064-8aab-a690-ce99-43c1286d4dc0.png)

# アクセスキーを作成する
作成したユーザのアクセスキーを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/cab72609-6de8-6cf8-b6ef-347532df2da8.png)

# VSCodeのAWS toolkitでユーザの設定をする
VSCodeの左のメニューからAWSを選択し、Explorerを選択する。
IAM Identity Centerは今回作成してないので、IAM Roleを使う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/d3dba252-cc77-59f2-9879-eb2cde836c93.png)

先ほど作成したアクセスキーを使用してプロファイルを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/a2e0ee77-1cf4-b495-f92e-d76b8b025096.png)

Connectedを表示されればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/ae798463-f2d4-2603-c00a-ca8a8bfc1e5e.png)

とりあえずここまで
2024年初投稿

すっかりご無沙汰してしまいました。
まずはあけましておめでとうございます。
２０２４年、目標達成のため日々精進します。


元旦から続く悲しいニュースが続いて心が疲弊してます。
しばらくはデジタルデトックスし勉強に励みます。
Qiitaを更新していない期間、勉強していなかったので…
（勉強しなければ更新も書けない）


新年、気を引き締め直して参りましょう！！
どうぞよろしくお願いいたします。
読みづらい見づらい dict や JSON を pprint できれいにみよう。インストール不要

大きい dict や JSON って見づらいですよね。そういうときは、まず pprint の使用をおすすめします。

## 長い dict や JSON の例

なにも考えずに `print(data)` とすると横長になってとても読みづらい……。

```JSON
{"glossary": {"title": "example glossary", "GlossDiv": {"title": "S", "GlossList": {"GlossEntry": {"ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": {"para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"]}, "GlossSee": "markup"}}}}}
```


## [pprint](https://docs.python.org/ja/3.12/library/pprint.html) を使うと読みやすくなります

`from pprint import pprint` したあとに `pprint(data, width=176)` とします。 width の値は程よい値を探してください。

```
{'glossary': {'GlossDiv': {'GlossList': {'GlossEntry': {'Abbrev': 'ISO 8879:1986',
                                                        'Acronym': 'SGML',
                                                        'GlossDef': {'GlossSeeAlso': ['GML', 'XML'],
                                                                     'para': 'A meta-markup language, used to create markup languages such as DocBook.'},
                                                        'GlossSee': 'markup',
                                                        'GlossTerm': 'Standard Generalized Markup Language',
                                                        'ID': 'SGML',
                                                        'SortAs': 'SGML'}},
                           'title': 'S'},
              'title': 'example glossary'}}
```

## pprint のいいところ

* ライブラリの新規インストール不要
* print に一文字足すだけなので簡単に pprint に差し替えられる

## pprint のよくないところ

* 何度もネストしている構造だと、横長になりすぎて見づらくなる


## pprint の ドキュメント

https://docs.python.org/ja/3.12/library/pprint.html
Dockerを使用したActivepiecesのインストール

Dockerを使用したActivepiecesのインストール
SQLite3とメモリキューを使用したシングルDockerイメージのデプロイメント

ActivepiecesをDocker Composeを使用して簡単にセットアップする - 個人利用やテストに理想的で、SQLite3およびメモリ内キューを使用します。本番環境（企業向け）では、PostgreSQLおよびRedisを使用し、Docker Composeのセットアップを参照してください。

Activepiecesを迅速に起動するために、ActivepiecesのDockerイメージを使用します。以下の手順に従ってください：

**前提条件**
ActivepiecesをDocker Compose経由でセットアップするためには、GitとDockerがマシンにインストールされている必要があります。

**インストール**
Dockerイメージをプルして実行する
以下のコマンドでActivepieces Dockerイメージをプルし、コンテナを実行します：

```
docker run -d -p 8080:80 -v ~/.activepieces:/root/.activepieces -e AP_QUEUE_MODE=MEMORY -e AP_DB_TYPE=SQLITE3 -e AP_FRONTEND_URL="http://localhost:8080" activepieces/activepieces:latest
```

**Webhook URLの設定（トリガーに重要、公開IPがある場合はオプション）**
注：デフォルトでは、ActivepiecesはWebhook用に公開IPを使用しようとします。個人のマシンで自己ホスティングする場合は、Webhookがインターネットからアクセス可能であるようにフロントエンドURLを設定する必要があります。

オプション：localhostでWebhook URLを公開する最も簡単な方法は、ngrokのようなサービスを使用することです。ただし、本番用途には適していません。

ngrokをインストールする
以下のコマンドを実行します：

```
ngrok http 8080
```

上記のコマンドラインでAP_FRONTEND_URL環境変数を置き換えます。

**アップグレード**
以下の手順に従ってください：

**ステップ1：データのバックアップ（推奨）**
アップグレードを進める前に、アップデートプロセス中に潜在的なデータ損失を避けるために、Activepiecesデータをバックアップすることを常に良い習慣とします。

現在のActivepiecesコンテナを停止する：Activepiecesコンテナが実行中の場合、以下のコマンドを使用して停止します：

```
docker stop activepieces_container_name
```

Activepiecesデータディレクトリのバックアップ：デフォルトでは、Activepiecesのデータはホストマシンの~/.activepiecesディレクトリに保存されています。以下のコマンドを使用して、このディレクトリを安全な場所にバックアップします：

```
cp -r ~/.activepieces ~/.activepieces_backup
```

**ステップ2：Dockerイメージの更新**
最新のActivepieces Dockerイメージをプルする：Docker Hubから最新のActivepieces Dockerイメージをプルするには、以下のコマンドを実行します：

```
docker pull activepieces/activepieces:latest
```

**ステップ3：既存のActivepiecesコンテナを削除する**
現在のActivepiecesコンテナを停止して削除する：Activepiecesコンテナが実行中の場合、以下のコマンド

を使用して停止して削除します：

```
docker stop activepieces_container_name
docker rm activepieces_container_name
```

**ステップ4：更新されたActivepiecesコンテナを実行する**
最新のイメージを使用して、更新されたActivepiecesコンテナを、初期設定時に使用したのと同じコマンドで実行します。activepieces_container_nameを新しいコンテナの希望する名前に置き換えてください。

```
docker run -d -p 8080:80 -v ~/.activepieces:/root/.activepieces -e AP_QUEUE_MODE=MEMORY -e AP_DB_TYPE=SQLITE3 -e AP_FRONTEND_URL="http://localhost:8080" --name activepieces_container_name activepieces/activepieces:latest
```
2024年を記念して2024をjsで素因数分解してみる

## はじめに
なんと2023年が終わり2024年になってしまいました。
ということで2024を素因数分解します。

## 目的
ここでは任意の2以上の自然数に対して素因数分解(ついでに素数判定も)を行うプログラムをjsで作成します。

## 実装方法
今回は速度は気にせず、巨大な数に対する素因数分解も少ないと考えているので、最も単純な素朴法(試し割り法)を用いていきます。
ρ法や篩法は伸びしろとして取っておきます。

## 実装
~~~ javascript
document.getElementById("number").addEventListener("change", () => {
  primeFactorization(BigInt(document.getElementById("number").value));
  document.getElementById("number").value = "";
});

function primeFactorization(compositeNum) {
  if (compositeNum <= 1) {
    console.log("2以上の数を入力してください。");
  } else {
    let primeFactors = [];  //約数を格納する配列
    let calcCompositeNum = compositeNum;  //計算用の変数に代入

    //2で割り切れる間2で割る
    while (!(calcCompositeNum % 2n)) {
      calcCompositeNum /= 2n;
      primeFactors.push(2);
    }

    /*
      対象の数(除算後の数)の平方根(※1)まで、3以上の奇数(※2)で割り切れるかみる
      (※1)約数は平方根を対称として、既出の組み合わせとなるため
        ex) 1 * 100 = 100
            2 * 50 = 100
            4 * 25 = 100
            5 * 20 = 100
            10 * 10 = 100
            20 * 5 = 100
            25 * 4 = 100
            50 * 2 = 100
            100 * 1 = 100
      (※2)2より大きい偶数は2の倍数であるため奇数のみの処理
    */
    for (let i = 3n; i * i <= calcCompositeNum; i += 2n) {
      while (!(calcCompositeNum % i)) {
        calcCompositeNum /= i;
        primeFactors.push(i);
      }
    }

    //平方根以上の約数を格納
    if (calcCompositeNum > 1) primeFactors.push(calcCompositeNum);

    //約数を2個しか持たない(1と自身のみ)のは素数
    if (primeFactors.length == 1) {
      console.log(`${compositeNum}は素数です`);
    } else {
      console.log(`${compositeNum}は合成数です`);
      console.log(compositeNum + "=" + primeFactors.join("*"));
    }
  }
  return;
}
~~~

## 結果
~~~ :入力1
2024
~~~
~~~ :出力1
2024は合成数です
2024 = 2*2*2*11*23
~~~
***
~~~ :入力2
0
~~~
~~~ :出力2
2以上の数を入力してください。
~~~
***
~~~ :入力3
8635844967113809
~~~
~~~ :出力3
8635844967113809は合成数です
8635844967113809 = 89652331*96325939
~~~
***
~~~ :入力4
7365373222715531
~~~
~~~ :出力4
7365373222715531は素数です
~~~

## おわり
今回は速度度外視で素因数分解をしていきました。
無事素因数分解することができましたが、速度が非常に遅く、そこが改善点です。
試し割り法以外にもアルゴリズムは沢山あるので、これを機に速度の観点から素因数分解を考えていきたいですね。
【PowerShell】関数内の標準出力は戻り値になるのか？

# はじめに

先日に職場で「PowerShellの（関数内での）標準出力は戻り値として扱われる」という話を聞きました。
return文以外も戻り値として扱われるというのが話だけでは理解できなかったので、実際にコードを作って試してみました。


# 作成したコード

* 以下のコードを実行してみると、return文が無いにもかかわらず、`Write-Output`の結果がそのまま戻り値として扱われていることが分かりました。
* `Write-Output`のリファレンスを見ると以下のように書かれていましたが、このコマンドの結果が戻り値として扱われるケースがあるとは書かれていませんでした。

> 「指定したオブジェクトをパイプラインに書き込みます。 パイプラインの最後のコマンドの場合 Write-Output は、オブジェクトがコンソールに表示されます。」

* なお、`Write-Host`はコンソールに出力するだけなので、戻り値としては扱われていませんでした。
* また[こちらの記事](https://trend-desk.com/archives/876)を見ると、「returnに指定したオブジェクト」「標準出力の結果」「Addメソッドの結果」の3つが戻り値に含まれると書かれていました。
  * `Add`した結果も戻り値に含まれると、さらに問題がややこしくなりそうですね...

```powershell:test5.ps1
function PrintMessage() {
    Write-Host "Print"
    Write-OutPut "Message"
    & PrintMessage2
}

function PrintMessage2() {
    Write-OutPut "PrintMessage2"
}

$retVal = PrintMessage
Write-Host ("retVal: " + $retVal)
```

```text:実行結果
Print
retVal: Message PrintMessage2
```

# 余計な戻り値を生じさせない改善案

## Out-Nullを組み合わせる

* パイプラインで`Out-Null`コマンドを呼び出すと、`Write-Output`の出力を非表示にするのと同時に、戻り値に入り込むのも防げます。
  * 以下の例は`Write-Output`と組み合わせていますが、実際には`Add`した結果が戻り値に入り込まないようにする時に使うのが良いと感じました。

```powershell:test5.ps1
function PrintMessage() {
    Write-Host "Print"
    Write-OutPut "Message" | Out-Null
    & PrintMessage2
}

function PrintMessage2() {
    Write-OutPut "PrintMessage2" | Out-Null
}

$retVal = PrintMessage
Write-Host ("retVal: " + $retVal)
```

```text:実行結果
Print
retVal:
```

## Write-Hostに切り替え

* `Write-Output`から`Write-Host`に切り替えて、戻り値に影響を及ぼさないようにした上でコンソールに出力することができます。
  * `Write-Output`の結果が戻り値となってしまう問題を解決するには、これが最も現実的な解決策だと思われます。

```powershell:test5.ps1
function PrintMessage() {
    Write-Host "Print"
    Write-Host "Message"
    & PrintMessage2
}

function PrintMessage2() {
    Write-Host "PrintMessage2"
}

$retVal = PrintMessage
Write-Host ("retVal: " + $retVal)
```

```text:実行結果
Print
Message
PrintMessage2
retVal:
```

# 参考URL

* [Write-Output - Microsoft Learn](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/write-output?view=powershell-7.4)
* [PowerShellの関数の戻り値に関する2つの問題 - Trend Desk](https://trend-desk.com/archives/876)
asusnCTF writeup

# 一位だった
優勝したらしい"のどかは"です

全完者の順位でいったら最初は19位くらいだったので(しおさんが最速優勝でしたね、絶対に追いつけない"スピード"を持っていた)、即解き全完でなく大喜利で勝った訳ですが、まあCTFerはふざけた回答するのも得意になるべきということで、ここは有り難く優勝を喜びたいと思います。(多分普通にIPPONは救済枠だから良いやってやらなかった人も多かったのかも知れませんが)

正直writeupはもう既に出てるsatokiさんとkumama_nuiさんのwriteupで自分の解法は網羅されるのでこれを読む必要はないです。画像も用意するの面倒でやってないので

## 大喜利解説
多分、こっちの方が気になりやすいんじゃないかと思ったので先に書いちゃいます

大喜利は早めに送れば閲覧されるだろうというのと、普通にworldとアイドル3につまずく雑魚だったのでIPPONを初日の前半あたりで送り初めました。

### python100
pythonとえばインデントということで、数々のperl使いやC言語、C++er、javascriperを苦しめたであろうインデントの強制力(ワンライナー出来るように結構緩和されたけど)をネタに、インデントでプログラミング出来る(実質ホワイトスペースと突っ込みが来ましたね)を送りました。どうせ皆、プログラミングに触れると難読言語界隈が好きになり(bfとか)反応するのでこれは一発頼りでそのまま放置してたら普通に通ってました。

### パスワード
最初は普通に『ハッシュ値』(passwordのハッシュ値を送った訳ではない)とかありきたりな回答をしてたんですが、他の回答者の雰囲気的に空パスワードや人間由来のネタがウケていることを知り(あと状況説明よりそのまんまの方がウケるっぽいこと知り)、環境変数にパスワードを保存してるというある意味で頭が良いんだか悪いんだか分からない状況を説明する『$PASSWORD』を提出したら通りました。

### フィッシング
デジタル大臣は今は有能そうな人だった気がするので、この回答は違う気がしますが確か前はスマホもあまり使ったことがない人だったので『スマホで困った時に見ておくべきチェック要項10選』これも一発で通ったのでまあ、運が良かったです

## writeup
見なくて良いwriteupです

### welcome
アンケート、ようこそは共に見て入力しただけです

### misc
kumama_nuiさん、satokiさんと同じ解法なので省略。管理徹底は20回くらい入力し直してキレてました。

### Crypto
cryptoと言いつつ計算はしません。古典暗号にも現代暗号にも分類されないんじゃないか…？と思いましたがsha256の理論自体はとてもcryptoなのでもしかしたら初期状態復元とかで戻すみたいな解法もあるのかも知れません。
アイドルは動画コメント、アイドル2はアスースン・オンラインさんが用意してくれたのか[crackstation](https://crackstation.net/)に入力したら出てくるのでそれで。
アイドル3が何やっても分からなくてテンパってましたがSatokiさんのwriteupにある通り一部ニュースサイトは検索ワードのsha256をインデックスに使ってるらしく日本語のrainbowtableになってるので検索にかければ良いだけでした(皆、数分で解いてた

### Reversing
バイナリアンではないので、脳内解きは出来なくて悔しかったですが、まあ普通にサイトと電卓でなんとかなるものでした。アセンブリにまでいけば結構自明な処理しかないので足し算と引き算するだけです。
[cyberchef](https://cyberchef.org)にはdisassemblerもついてるということでそれで解こうとしましたが、操作性と合ってるのか分からないのでオンラインのdisassemblerを検索、サイトはSatokiさんのwriteupと同じものに辿りついてました。

### OSINT
まあ、検索するだけですね。kumama_nuiさんはこの段階でかなり~~ネトスト~~してて、こいつと友達で本当に大丈夫かなって思いましたが、杞憂でありたいですね。スマホで全完を自分に強いていたのでtiktokが検索出来なくて泣いていましたが、[匿名検索](https://urlebird.com/anonymous/)があったり、PC版リクエストすれば検索出来そうだったのでそれで普通に検索しました。full_weak_engineerで検索するだけでworldは出てくるのに日本語や類似だけで探すことで検索せずに何とかたどろうとして時間を大分溶かしました。

ちなみにyoutu○eのガベコレサブチャンネルはちゃんとガベコレの話をしてくれるんでしょうかね、私気になります。

# 完走した感想
以上が東京工業大学出身、芸人のアスースン・オンラインさんのCTFに参加した備忘録でした。~~Twitter~~ Xで見かけて荒らすかっていう気持ちでパッと参加しましたが解く能力が足りなくてTop20という成績だったのにIPPONで逆転するというどこのギャグ漫画なんだというCTF経験をしましたが、まあ芸人魂のあるCTFだから面白いやつが正義というCTFだったということかも知れません。これから私はCTF力が底を尽きたので大喜利で食っていきます。

最後に
アスースン・オンラインさん楽しいCTFを開催頂き有り難うございました。
また参加して笑ってくれた皆さまもどうぞ良いCTF生活と新年度をお過ごしくださいませ。(色々ありますが笑って楽しく生きましょう
LPIC102の内容から業務で使えそうなコマンド③

本記事は、勉強したことのアウトプット（メモ）です。
LPIC102を勉強中のため、試験内容から使ったことあるコマンドや使ってみたいコマンドをまとめました。
以下記事の続きです。

#### 現状
- web系エンジニアやっています。
- LPIC101に合格し、LPIC102の勉強。
- 先日LPIC102を受験し、合格！！

## 参考サイト
- [inux教科書 LPICレベル1 Version5.0対応](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-Version5-0%E5%AF%BE%E5%BF%9C-%E4%B8%AD%E5%B3%B6-%E8%83%BD%E5%92%8C/dp/4798160490/ref=asc_df_4798160490/?tag=jpgo-22&linkCode=df0&hvadid=295678107984&hvpos=&hvnetw=g&hvrand=10026356874543379694&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009292&hvtargid=pla-649269108462&psc=1&th=1&psc=1)
- [ping-t](https://ping-t.com/)
- [Linux教科書 LPICレベル1 スピードマスター問題集 Version5.0対応](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-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version5-0%E5%AF%BE%E5%BF%9C-%E5%B1%B1%E6%9C%AC/dp/4798160857/ref=sr_1_1?adgrpid=56122615434&hvadid=667834322319&hvdev=c&hvlocphy=1009292&hvnetw=g&hvqmt=e&hvrand=9361466665802150923&hvtargid=kwd-334266044763&hydadcr=26605_11772063&jp-ad-ap=0&keywords=lpic+%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC&qid=1694935740&sr=8-1)
## コマンド
### su
一時的に別のユーザになり、作業することができます。
suコマンドに引数を設定しない場合、スーパーユーザ（root）に切り替えることができます。
ユーザ切り替え後、`exit`で元のユーザに戻ることができます。

#### オプション
| オプション | 説明 |
|:-:|:-:|
| -  | 環境変数を引き継がずに変更する  |
| -m  | 環境変数「HOME」「USER」などの内容を引き継ぐ  |
| -s  | 実行するシェルを指定する  |

```linux:bash
#test1に切り替え
$ su - test1
Password: ←test1ユーザのパスワードを入力

#rootに切り替え
$ su
Password: ←rootのパスワードを入力
#
```
### sudo
ユーザを切り替えずに他のユーザやスーパーユーザの権限で、任意のコマンドの操作が可能になります。
一般ユーザにrootのパスワードを周知する必要がない点がメリットです。
#### オプション
| オプション | 説明 |
|:-:|:-:|
| -b  | バックグラウンドで実行する  |
| -l  | 許可されているコマンドの表示  |
| -g  | コマンド実行時のグループ名を指定する  |
| -u  | コマンド実行時にユーザ名またはユーザIDを指定  |

```linux:bash
#許可されているコマンドを表示
$ sudo -l
```
## 参考文献
- https://www.sejuku.net/blog/52175
- https://itc.tokyo/linux/sudo-command/#google_vignette
## まとめ
LPIC102に合格することができました！
学習したことをまとめているだけですが、アウトプットすることで学習したこと以上に理解することができました。
引き続き勉強を続け、記事を更新していけたらなと思っています。
AND+OR Python3編

https://paiza.jp/works/mondai/conditions_branch/conditions_branch__bool_boss

空気を読まないで問題だけ見て考えた答案（汗）

```py
X,Y,Z = map(int,input().split())
if Z >= 10:
    print('YES')
else:
    if X >= 10 and Y >= 10:
        print('YES')
    else:
        print('NO')

```

いや実際問題見たらまず先にZが10以上かどうかを調べないといけないってことじゃんかって思うのだけど、
ORの役割をちょっと考えると
たとえば、AがTrueだったら、BがFalseでもTrueでもOrでつながると全体としてTrueになるんですよね。
さらにPythonだと、<b>andのほうがorよりも優先される</b>性質があるそうです。
だからこれを利用すると、3つ同時に書けちゃうという。もはや優先順位をつける括弧もいりません。
私もなるほどと思いました。

```py
X,Y,Z = map(int,input().split())

if Z >= 10 or X >= 10 and Y >= 10:
    print('YES')
else:
    print('NO')
```