OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerのイメージを掴む

## はじめに

今まで触れたことのなかったDockerについて、自分なりにまとめました。
チーム開発で同じDockerを知らないだろうチームメイトのために書いたものでもあるので、かなり初学者向けだと思います。

# Dockerとは

パソコン上で例えばSwichを動かせるエミュレーターのようなもの。パソコンの中で別のマシンを起動するようなもので、これを「仮想化」という。

Dockerは仮想環境を作成するためのプラットフォーム。

## Dockerで仮想環境をつくるメリット

- Aの環境で動いたのにBの環境では動かない、ということが無くなる
- 開発環境で動いたのに本番環境では動かない、ということが無くなる
- 開発環境と本番環境を合わせやすい
- 開発環境のセットアップが簡単になる

## Dockerの基本的な仕組み

イメージとコンテナがDockerの基本。イメージからコンテナを生成する。

### Dockerイメージ

- コンテナの元になるテンプレート
- OSや実行するアプリケーションや設定をまとめたもの

### Dockerコンテナ

- Dockerイメージを元に作成される
- OSとアプリケーションが動く実行環境

## Dockerの操作手順

### 1.イメージを取得、ビルドする

Dockerレジストリからイメージの取得、またはDockerfileからビルドする

ビルドとは、ベースとなるイメージに対して何かしらの手を加えて、独自のイメージをつくり出すこと。

開発環境では、ベースのまま使うことは無い。

### 2.コンテナを生成、起動する

## Dockerfileとは
イメージを作成するレシピ（設計書）。
このDockerfileを使ってDockerイメージをビルド（作成）すると、そのイメージをもとにコンテナを起動することができる。

## Docker Composeとは

開発環境においてコンテナは、RubyやPHPなどのアプリケーションが動くコンテナと、データベースのコンテナなど、複数必要となる。

Docker Composeは複数のコンテナを定義し実行するツールである。定義をymlファイルに書くと、一つのコマンドで複数のコンテナを管理できる。
ARC074 - F - Lotus Leavesの最大流でスタートから同じ行、列の頂点に直接、容量INFを流すとWAになる理由

# スタートから同じ行、同じ辺にINFの辺を貼るとWAになる
https://atcoder.jp/contests/arc074/tasks/arc074_d
スタートの頂点から同じ行、同じ辺にINFの辺を貼ると以下の図の場合にWAになります。
![safdsfafsad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/76fd8750-fb1c-e775-d27f-acbc9db18204.png)

Sと蓮を繋ぐINFの辺で、Sではない方のただの蓮を削除したら1回削除してそれで終わりなのに、辺がINFのせいでただの蓮の両端の辺に1が流れてしまい、答えが2になります。ではどうしたらいいのでしょうか？

# 各行、各列ごとにリーダーのような頂点を追加する
例えば二つの蓮があって、(i,j)=(2,3)と(2,4)の蓮があるとします。このときi=2が同じなので、この二つの蓮同士からはお互いに移動できます。となるとこの二つの蓮を容量1の辺で繋ぐことになるのですが、ここで二つの蓮を繋ぐのではなく、i=2を代表する頂点のようなもの作成します、以降この頂点をリーダーとして呼びます(ユニオンファインドのリーダーと同じ意味ではないです、ユニオンファインドだと存在している頂点の一つをリーダーとしますが、この場合は新しい頂点を作成しそれをリーダーとしています)。
そしてこのリーダーに対してそれぞれの蓮を容量1の辺で結ぶと以下のようになります。

![asfsafsaasf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/16d1b01d-940f-4172-0906-03abe06f29c7.png)

さてこれをした意味はあるのでしょうか？ではここでスタートの頂点を用意してみます。スタートの蓮を(2,5)とします。このスタートの頂点からリーダーに対してINFを結んでみます。

![dasdadsa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/bc8ea757-40df-9fcc-0cde-c03566cfb11a.png)

すると各蓮に対して容量1の辺を結ぶことができました。ここで先ほど正しく最大流が動かなかった場合のグラフをこのグラフに繋げてみます。j座標は具体的に書いていませんが、同じ横軸にあったらj座標は同じと思ってください。(無駄な頂点を削除しています)

![sdafsafdafsa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/5e21418e-8aad-d853-9eda-18fcd50e1b3d.png)

こんな感じになります。説明のために最大流が正しく動かなかったグラフを90度回転しています。
さて、この場合最大流はどうなるでしょうか？緑色の線で動きを書いてみるとこんな感じになります(下に進んでいますが上に進んでも同じです)

![dsfafafasf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/85b9ca59-fa13-4675-2183-d9fe6426c7b4.png)

というわけで1という正しい答えが出ていることがわかりました。実際に実装する際はiだけでなく、jに対してもリーダーを作成します。また、スタートとゴールの蓮を二つにわけて、「ただの蓮」と「スタートまたはゴールの蓮」として別々に管理すると実装が楽になります。なぜうまく動くのか理解できていないので説明を省きますが、各蓮の座標を持たずに、リーダー同士を辺で結ぶことにより頂点数を(H+W+2)個で済ませることができます。例えば(2,3)と(2,4)の蓮なら、i=2が同じなので、j=3とj=4のリーダーを容量1の辺で結びます。フランちゃんによるとリーダーの頂点同士を結ぶことで、辺を取り除く問題にできるみたいです。
https://twitter.com/flandre_comp/status/1414285916449886209


ちなみにリーダーのような頂点を持たずに移動できる蓮同士を全て辺で結ぶとTLEするらしいです、理由が理解できていないので見なかったふりをします。
https://drken1215.hatenablog.com/entry/2020/01/29/011100

# おわりに
参考にしたツイート https://twitter.com/flandre_comp/status/1414285916449886209
イメージとして最小カットのとき「容量1の辺は削除できる」「容量INFは削除することができない」と覚えるといいかもしれません、今回の問題だと辺ではなく頂点を削除する問題ですが、リーダーを使えば辺に言い換えられるらしいのでほぼ同じ感じな気がします。

最後にACしたコードを張っておきます。
https://atcoder.jp/contests/arc074/submissions/52148443
Kindle for PCで本の章別の位置情報の番号のファイルを読みだして、ランダムに章別に自動で読み上げるPGM

<h3>Kindle for PCで本の章別の位置情報の番号のファイルを読みだして、ランダムに章別に自動で読み上げるPGM</h3>

Kindle for PCで本の章別の位置情報の番号のファイルを読みだして、ランダムに章別に自動で読み上げるPGMを作りました。

<hr>
使い方

以下のように本の章毎の位置No.を書き出したファイルを用意してから、
PGMを実行して読み上げを開始します。

page-headPositions1.txt
第一章の位置Noの番号
第二章の位置Noの番号
...

<hr>
プログラム内容

```powershell
$source = @"
using System;
using System.Runtime.InteropServices;

public static class WinApi
{
    [DllImport("kernel32.dll")]
    public static extern bool Beep(int freq,int duration);
}
"@
Add-Type -TypeDefinition $source

#SendKeysを使うため、System.Windows.Forms名前空間読込
Add-Type -AssemblyName System.Windows.Forms

#読み上げ用章別位置情報ファイルを読み込み
$arr = Get-Content "C:\hoge\hon-yomiage-text\page-headPositions1.txt"
#echo $arr

#読み上げないページ
$notYomiagePages = @(92,2235);

#何ページ分繰り返すか
$CountLength = 30


#一ページ当たり読み上げに何秒かかるか
$YomiageSecondByOnePage = 100 

 [WinApi]::Beep(440, 5000)

$page = 1

echo "ランダム読み出し開始"
#この間にトップ画面をkindleにする
Start-Sleep -s 10
echo "Start"

$firstFlg = $true

$prev1 = 0;

for($i=0; $i -lt $CountLength; $i++){

    $idx = Get-Random -Maximum ($arr.Length-2) -Minimum 0
    $pos1 = $arr[$idx]
    if($pos1 -eq　$prev1){]
        continue
    }

    $notYomiageFlg = $false;
    for($j=0; $j -lt $notYomiagePages.Length; $j++){
        if($pos1 -eq $notYomiagePages[$j]){
            $notYomiageFlg = $true
            break
        }
    }

    if($notYomiageFlg -eq $true){
        continue
    }else{
      $pos2 = $arr[$idx+1];
      $YomiagePageCount = $pos2 - $pos1
      $YomiageTotalSeconds = $YomiagePageCount * $YomiageSecondByOnePage
    }

    [System.Windows.Forms.SendKeys]::SendWait("^g")
    Start-Sleep -s 2

    [System.Windows.Forms.SendKeys]::SendWait("{TAB}{TAB}{TAB}{DOWN}{TAB}")
    Start-Sleep -s 4

    $startPos = $pos1;
    [System.Windows.Forms.SendKeys]::SendWait($startPos)
    Start-Sleep -s 2
    echo $startPos

    [System.Windows.Forms.SendKeys]::SendWait("{ENTER}")
    Start-Sleep -s 2

    [System.Windows.Forms.SendKeys]::SendWait("{LEFT}")
    Start-Sleep -s 2

    if($firstFlg -eq $false){
        #読み上げ機能をいったんオフにする
        [System.Windows.Forms.SendKeys]::SendWait("^t")
        Start-Sleep -s 2
    }else{
        $firstFlg = $false
    }

    #読み上げ機能を開始する
    [System.Windows.Forms.SendKeys]::SendWait("^t")
    Start-Sleep -s 2
    Start-Sleep -s $YomiageTotalSeconds
    #Start-Sleep -s 10

    $prev1 = $startPos

}

 [WinApi]::Beep(440, 5000)

```
アニメ調の絵を書く（DALL-E 3)

# 序文
気を付けないと、すぐ西洋人の写実的な画像になってしまうので。
忘備録

# 成果物
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/6b657029-dd73-4d48-2d35-7f5178844b07.png)

# prompt
```text:prompt
夏のカフェの風景
女性が夏の日差しの中、開放的な屋外カフェに座っている様子を描いてください。彼女は軽やかな夏ワンピースと サングラスを着用し、冷たい飲み物を楽しんでいます。
周りには緑豊かな公園が広がり、木々や花々に囲まれた明るく活気に満ちた雰囲気です。女性は穏やかな笑顔を浮かべ、視線は遠くを見つめています。
全体的に陽気で生き生きとした印象を与える夏らしいイメージをお願いします。鮮やかな色使いと、太陽の光が差し込む開放的な構図がポイントになります。
プライバシーに配慮し、特定の個人が判別できないようなイラスト調の描写をお願いします。
```
のあと

```text:prompt
画調はいいですね。すごい西洋な感じなので、普通の日本の夏にしてもらえますか？背景、服は同じでいいのですが、髪やサングラスを変えるだけでいいと思います。
```
## 感想
この１枚しか作れていないので、奇跡の一枚だと思います。
DALL-E については、著作権的な縛りが本当にきびしいので、最初からアニメ調というのが使いづらいところもあります。

# まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130729/ad5a3c3d-d708-56ac-c1f2-9dd13c532c6f.png)
この感じを再現したいのだけど、全然できません。
わたせせいぞう風といえれば、簡単な気がする。
bcpコマンドに関して

皆さんこんにちは
今回はbcpコマンドについて説明していきます。

bcpコマンドでできることは、データベースにアクセスしてデータをエクスポートできたり、
逆にインポートして一括で登録することができます。

特に、画像データなど容量の重いデータをエクスポートしたりインポートしたりするときに便利です。

では、実際にbcpコマンドの構成を見てみましょう。

まずは、データをエクスポートする場合
bcp [データベース名].[スキーマ名].[テーブル名] out C:\(任意の位置).csv -c -q -U "ユーザー名" -P "パスワード" -S "(自分のDBのIPアドレス) -t ","

次に、データをインポートする場合
bcp [データベース名].[スキーマ名].[テーブル名] in C:\(任意の位置).csv -c -q -U "ユーザー名" -P "パスワード" -S "(自分のDBのIPアドレス) -t ","

以上が、今回自分が使用したbcpコマンドになります。
普段自分はエクスポートやインポートする際、SSMSの標準機能を用いてやっていましたが、画像ありのデータの場合すごく時間がかかったり、できない事象が発生しました。
そこで、今回bcpコマンドを使用したところ、一瞬でできたのでぜひ使ってみてください。
Dart：Class modifiers のドキュメントを読む ~ mixin~


# Mixin classの使い方

- 前提
    - abstract classが存在する

あるクラス（インスタンス）に、abstract　classが持つ抽象メソッドの他に、別のクラスの持つメソッドも使わせたい場合に　Mixinが便利。


例えば、Animal classを作成する。
Animal classには、すべての動物が行う行為であるBreathを定義する。

そして、動物の種類によって、行うことができる・できないが別れる行為（吠える、泳ぐ、飛ぶ）など
をmixin classとして定義する。

犬クラスを作成するときには、Animal classを継承させるとともに　Bark(吠える) classをmixinすることで、犬クラスでは、　犬クラス内でBreath()とBark()を定義せずに、呼び出すことができる。


```
abstract class Animal{
  void Breath(){
     print("breath);
  }
} 

mixin Bark{
 void bark() => print("Bark");
}

```

Mixin classを使いたいときは　with をつける。

```
class Dog extends Animal with Bark{}

main(){
  var dog = new Dog();
  dog.breath();
  dog.bark();
}
```


## 参考
https://www.youtube.com/watch?v=VlG-K14YMe0
Haskellにおける関数の適用と呼び出しの違い

## 背景

昨日、Twitterで「Haskellの関数の呼び出しなどの表記方が初心者にはちょっと難しい」のようなことを言ったところ「Haskellで関数の`呼び出し`ってしたっけな」というものがあった

関数は`呼び出す`ものというイメージがあったため気にせず`呼び出す`という言葉を使ったが、正しくはなんなのかを調べることとした

## 関数型プログラミングにおける関数

Haskellの関数は以下のような特徴を持ちます：

- 副作用を持たない（参照透過性）
- 同じ入力に対して常に同じ出力を返す
- 変数に代入したり、引数として渡したり、関数から返すことができる

このような特徴を関数が持つことで、数学的な関数としての意味合いが強く、`適用`と表現するようだ

## 関数の`適用`

Haskellでは、関数を適用するために引数を関数名の後に空白で区切って記述します。例えば、`f x`は関数`f`に引数`x`を適用することを意味します

以下は、Haskellでの関数適用の例です：

```haskell
add :: Int -> Int -> Int
add x y = x + y

result = add 3 5
```

ここでは、`add`関数に引数`3`と`5`を適用し、その結果を`result`に代入しています

## 関数の部分`適用`

調べていく中で、部分適用という言葉も目にしました。部分適用とは、関数に必要な引数の一部だけを与えて、残りの引数を受け取る新しい関数を作成することです

例えば：

```haskell
add5 = add 5
result = add5 3
```

ここでは、`add`関数に引数`5`を部分適用することで、新しい関数`add5`を作成しています。`add5`関数は、追加の引数を1つ受け取り、その引数に`5`を加算します

## まとめ

Haskellにおいては、関数を「`呼び出す`」というよりも「`適用する`」という表現が一般的であるとわかりました

大元を完全に理解はできていないが、`数学的な関数と同様に利用できること`、`数学の影響を強く受けている`ことから`数学の関数を適用するをそのまま使っているのではないか`と考えた

:::note warn
違ってたらコメント下さい！！
:::
配列をコピーする時の注意点

# はじめに
　Atcoder004 - Cross Sum（★2）の問題を解いている時、自分の考えている処理と異なる処理が行われた。具体的には、2次元配列をコピーする際、コピーする元の配列まで変化してしまうというエラーが発生した。自分の学習のメモとして、記事を書いた。
# コード
```ruby
#1次元配列の場合
a = [1,3]
b = a.dup
b[0] = 2

print a #[1, 3]
print b #[2, 3]

#2次元配列の場合
c = [[1,2],[1,3]]
d = c.dup
d[0][0] = 2

print c #[[2, 2], [1, 3]]
print d #[[2, 2], [1, 3]]
```
# 解説
　1次元配列の場合、配列をコピーしたものの要素を変更しても、元の配列は変化しない。しかし、2次元配列の場合、配列をコピーしたものお要素を変更すると、元の配列も変更されてしまう。
　原因は、dupやcloneなどの配列を複製するコマンドは浅いコピーであることだ。浅いコピーの場合、コピー元の配列も変更する場合が生まれてしまう。今回のように多次元配列をコピーして、コピーした配列の要素を変更するとコピー元も変更されてしまうようだ。
　深いコピーをする場合、Marshalモジュールを使えばできるらしい。ただ、Marshalモジュールで複製できないオブジェクトもあるようだ。

（補足）
　今回のAtcoderの問題はdupなどのコピーコマンドは使わず、transposeコマンドを使うことで問題を解くことができた。
 # 終わりに
 　コピーコマンドを使用しても、コピー元の配列が変更されてしまうことがあるのを学んだ。他のプログラミング言語を学ぶ時にも、活きそうな知識だと感じた。
ABC348回答メモ

# 0.はじめに
　先週は用事があり超久しぶりに参戦できず、1週ぶりのABC。
 A～Cは順調でしたが、Dが解けず、E・Fを見ても太刀打ちできず
 3問ACのみとなりました。
 すこしさぼったので勘が鈍ったのか実力なのかわかりませんが
 盛り返していきたいと思います。
 それでも、レートは-19と微減で924となりました。


# 1.A - Penalty Kick
　ペナルティキックの精度がある意味すさまじい高橋君。
 まぁ、文字列を作ると言うところが珍しいかなと思いつつ
 空の答え文字列ansを準備して、iを1～Nまで回し
 iが3の倍数ならx違うならoをansに足していき
 最後にansを出力してACとなりました。
 
　https://atcoder.jp/contests/abc348/submissions/52062078


# 2.B - Farthest Point
　D問題辺りで出てきたら、TLE回避策が大変そうだなーという問題。
 Bなので、制約も緩いため、総当たりで何とかなりました。
  競技プログラミングにありがちなユークリッド距離を求める際には
 √までは計算しないという鉄則を守りつつ、各点毎に全点の組み合わせ中
 距離が最大かつ、点の番号が一番小さい番号を問題通りに求めて
 ACとなりました。

　https://atcoder.jp/contests/abc348/submissions/52074476


# 3.C - Colorful Beans
　問題文はややこしいですが、辞書を使えばそこまで難しくない問題でした。
 最後の出力がキーも出力だったらややこしいかな・・・とも思いましたが
 まぁ、それほどでもなく、Bの方が難しいくらいでした。

 【実装】
 　1.Nをインプット
 　2.空辞書Dを定義
 　3.以下N回繰り返し
  　-1.A,Cをインプット
  　-2.Cが辞書にある場合
   　  D[C]にD[C]とAのうち小さい方をセット
  　-3.Cが辞書にない場合
   　  D[C]にAをセット
 　4.辞書Dの値の中から一番大きい値を出力 

　https://atcoder.jp/contests/abc348/submissions/52079628

# 4.D - Medicines on Grid
　1時間くらい試行錯誤しましたがダメもとで提出した結果が
 AC25、WA3、TLE13、RE12とやっぱり駄目でした。

 単純にスタートからの探索ではなく、薬毎の探索を最後に組み合わせる方法が
 解説にあったので、そちらを試してみようかと思います・・・。時間が出来たら・・・。

以上
フォルダとキーワードを指定してExcelブックを検索して新しいシートに出力する

# 使用用途
設計書の名称が長く紛らわしい上にバージョン管理がファイル名の後ろについている。
仕様書の名称が業務のJOB名でクラス名や機能名ではないから探しづらい。
しかもシートがやたらと分けられていて20シート超えていて探しにくい。
そんな時に使える（と思って作成

# 参照シート（シート名：検索シート）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758592/97b09a8e-0009-a066-2c5c-efd63518f6b5.png)

# ソース

```deleteFile
Sub SearchExcelFilesForKeywords()
    Dim keywordSheet As Worksheet
    Dim searchSheet As Worksheet
    Dim keywordRange As Range
    Dim folderPath As String
    Dim keyword As Variant
    Dim filename As String
    Dim ws As Worksheet
    Dim excelFile As String
    Dim wb As Workbook
    Dim cell As Range
    Dim found As Boolean

    ' キーワードが入力されているシートを取得
    Set keywordSheet = ThisWorkbook.Sheets("検索シート")
    
    ' キーワードが入力されているセルの範囲を取得
    Set keywordRange = keywordSheet.Range("A2:A" & keywordSheet.Cells(keywordSheet.Rows.Count, "A").End(xlUp).Row)
    
    ' 検索結果を出力する新しいシートを作成
    Set searchSheet = ThisWorkbook.Sheets.Add
    searchSheet.Name = "検索結果" + Format(Now(), "YYYYMMDD_HHMMSS")

    ' 検索結果のヘッダーを設定
    With searchSheet
        .Cells(1, 1).Value = "キーワード"
        .Cells(1, 2).Value = "ファイル名"
        .Cells(1, 3).Value = "シート名"
    End With
    
    ' 指定フォルダのパスを取得
    folderPath = keywordSheet.Cells(2, "B").Value
    
    ' 指定フォルダ内のすべてのExcelファイルを検索
    excelFile = Dir(folderPath & "\*.xlsx")
    Do While excelFile <> ""
        ' Excelファイルを開く
        Set wb = Workbooks.Open(folderPath & "\" & excelFile)
        
        ' 各シートを検索
        For Each ws In wb.Sheets
            ' シート内の各セルを検索
            For Each cell In ws.UsedRange.Cells
                ' キーワードが含まれているかどうかをチェック
                For Each keyword In keywordRange
                    If InStr(1, cell.Value, keyword.Value, vbTextCompare) > 0 Then
                        ' キーワードが見つかった場合、検索結果を出力
                        searchSheet.Cells(searchSheet.Cells(searchSheet.Rows.Count, "A").End(xlUp).Row + 1, 1).Value = keyword.Value
                        searchSheet.Cells(searchSheet.Cells(searchSheet.Rows.Count, "B").End(xlUp).Row + 1, 2).Value = excelFile
                        searchSheet.Cells(searchSheet.Cells(searchSheet.Rows.Count, "C").End(xlUp).Row + 1, 3).Value = ws.Name
                        found = True
                        Exit For
                    End If
                Next keyword
                If found Then Exit For
            Next cell
            If found Then
                found = False
            End If
        Next ws
        
        ' 次のExcelファイルを検索
        excelFile = Dir
        wb.Close False
    Loop
    
    ' メッセージボックスを表示
    MsgBox "検索が完了しました。", vbInformation
    
    ' メモリの解放
    Set keywordSheet = Nothing
    Set keywordRange = Nothing
    Set searchSheet = Nothing
    Set ws = Nothing
    Set wb = Nothing
    Set cell = Nothing
End Sub
```
# 出力結果
検索するキーワード名を表示対象のファイルとシート名を絞り込めるので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758592/e0271927-8ab9-164a-f6a8-8dc090965826.png)

仕様覚える間もなく仕様書を探して調べる必要がある場合に使えると思う。
エンジニア転職して2年が経ちました


他業種からエンジニア転職組であり30代後半からの挑戦でしたが、エンジニアとして、まる2年、フリーランスになってからは半年ほど経ちました。

仕事であるからには、めんどくさいと思うことも多々ありますし、時には、自分の無能さに絶望したり、なるほど分からんとか、まあ、いろいろと有りますが、それらまるまるひっくるめて、エンジニアという仕事が、面白いと感じます。

エンジニアとしての生存戦略とかキャリア論とか、つらつらと考えたりする毎日ですが、結局は、面白いことやってきたいし、エンジニアが面白いから、続けられてると思います。

1年後もエンジニア続けてられますようにということで、今後、挑戦していきたいことなんかも記録として残しておきたいと思います。

今のところ以下の3つ。

- 今アサインしているプロダクトを成長させる
プロダクトオーナーシップを持つことは仕事を失わないことに直結するのでより高い視座でものごとを考えられるようになりたいです。

- 個人開発で収益をあげられるようなプロダクトを創出する
リスクマネジメントの観点から収益源を分散させるという意味合いで、あるといいなあと思います。

- 法人化する
節税の意味合いが強いですが、ある程度スケール出来るなら従業員を雇うなりしても良いかも知れません。

そんな訳で2024年度も無事にエンジニアやってけますように。
【Git】Git rebaseについて

今回は「git rebase」について投稿します。
gitで悪戦苦闘することの1つに、git rebaseがあると思います。
そんなrebaseについて振り返ってみました。

# 1: git rebaseとは？
- 今までコミットしてきた"複数のブランチ"を「一直線の道筋にして、整える」コマンドです。

```git:gitコマンド
git rebase
```
■例
例えばmainブランチと、featureブランチの2つがありました。
- mainブランチには、「コミット履歴が3つ」あります。
- featureブランチには、「コミット履歴が2つ」あります。

2つのブランチがあることにより、ブランチは枝分かれしていますね。

**枝分かれで進めている最中に、「mainブランチに、featureブランチを取り込んで履歴を一直線に綺麗にしたい。」と思いました。**

そこで使うのが「git rebaseコマンド」です。
```git:featureブランチにいる状態で、下記を入力。
git rebase main
```

■結果
「mainブランチに、featureブランチ」が統合されます。
- mainブランチに「featureブランチ」が移動します。
- "以前のfeatureブランチ"は消滅しています。
    - つまり…「mainブランチの最新コミットに、featureブランチとそのコミットが、新しく追加されるのです。」



## <font color="Red">**2: 注意事項**</font>
**git rebaseコマンドは「Git Hubにプッシュしたコミットをrebaseすることだけは注意しましょう。一度pushしたらそれ以降はgit rebaseを使わないことが安全です。」**
⬇︎
なぜなら、再度pushできなくなるからです。具体的に言うなら「Git Hubのpush履歴がごちゃごちゃになる」からです。

他のメンバーがpushできなくなったりするので、要注意ですね。

## 初めての投稿でしたが…
中々時間がかかりました…。
打つ内容を考えて、Qiitaに記載して合計1時間30分くらいですね…。
次はもう少し記載する時間を短くしたいなと思います。メモ帳などに隙間時間で書いていた方が良さそうです。
Xcode Cloud のPackage.resolvedエラーについて

# 背景
SPMを導入し、Xcode Cloudでアーカイブしようとしたところ下記のエラーが発生。

# エラー内容
![スクリーンショット 2024-04-07 19.33.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951091/ec19b43a-ec45-5d3d-04fb-827ac28f0068.png)

error: Could not resolve package dependencies: Package.resolved file is corrupted or malformed; fix or delete the file to continue: unknown 'PinsStorage' version '3' at '/Volumes/workspace/repository/.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved'.

# 実行環境
日付: 2024年4月7日
Xcodeバージョン: Xcode 15.3
macOSバージョン: macOS Sonoma 14.1.1 (23B81)

# エラーの対応方法
![スクリーンショット 2024-04-07 19.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951091/9fc0128b-0351-9b78-af21-e9448535f6c1.png)

エラーメッセージに示されているように、Package.resolvedファイルのバージョンが不明なものになっており、このエラーはバージョン3のPinsStorageが不明ということで発生しているようです。

Package.resolvedファイルはSwift Package Managerによって生成される依存関係の記述ファイルです。このファイルが壊れたりバージョンが不明なものになったりすると、ビルドエラーが発生します。

対応方法としては、Package.resolvedファイルのPinsバージョンを確認し、適切なバージョンに変更することが必要です。具体的な手順は以下の通りです。

①Package.resolved内のPinsバージョンを確認します。
②バージョンが3になっている場合、バージョン2に変更。
③変更後、Xcode Cloudでビルドを再実行します。

![スクリーンショット 2024-04-07 19.40.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951091/c4c01d10-8b7b-aa91-a156-c84fad56ad56.png)

同じエラー内容の場合はこれで解決するはずです！
まだ開発初心者なので、他にも違うアプローチがあれば教えてください:bow_tone1:

## 参考記事 
https://toyboy2.medium.com/package-resolved-file-is-corrupted-or-malformed-fix-or-delete-the-file-baeb572863fc

## 追記 (2024/4/10)
Xcode CloudでのXcode Version　: 5.3
Package.resolved　Pins Version: 3

上記のように最新のバージョンに合わせてテストしてみました。

![スクリーンショット 2024-04-09 7.27.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951091/a0afa448-022a-4992-2ac8-9affc69b90e2.png)

大量のエラーが発生します...
こちらの内容については、アッキーさんという方が記事を書いていただいているので、
詳しい説明は割愛しますが、バージョンを最新にするとエラーが起こるというXcode Cloudのバグのようです。

https://zenn.dev/akkii/scraps/8aa0cfe74a7111
vim の折りたたみ機能は実用に耐えない

# 概要
普段の開発で vim を利用しておりますが、業務でPHPの1ファイルで6000 ~ 7000行ほどプログラムを触った際に異常な遅さを体験したので、そのログを残す

# 環境
CPU: Apple M1 Max
Memory: 64GB
OS: Mac OS X 14.2.1
Vim: 9.0
PHP: 8.0

# 状態
PHP のファイルを開いた時、インサートモードに変更した時、インサートモードを抜けた時に体感1秒位のラグを感じる

# vim の設定
検証時はプラグインを全て無効にしており、下記内容を全てコメントアウトすることで速度が改善されたためVimの折りたたみ機能が特別遅いものだと判断

* PHPファイルはMethod名が表示されるレベルに設定
* インサートモードに入る際に `foldmethod` を `manual` に変更
* インサートモードから戻る際に `foldmethod` をもとに戻す
    * これは入力しながら解析すると入力のラグが大きく使い物にならなかったため設定

```vim:.vimrc
autocmd FileType php setlocal foldmethod=syntax foldlevel=1 foldnestmax=3
let php_folding = 1

" Insert Mode では foldmethod を manual に設定する
autocmd InsertEnter * if !exists('w:last_fdm') | let w:last_fdm=&foldmethod | setlocal foldmethod=manual | endif
autocmd InsertLeave,WinLeave * if exists('w:last_fdm') | let &l:foldmethod=w:last_fdm | unlet w:last_fdm | endif
```

# 結論
`foldmethod=syntax` で数千行のプログラムを扱うと、モード切替がストレスになるレベルの遅延が発生する
そのため折りたたみ機能は使わないようにしたが、実際に速度解析や設定の比較を行ったわけではないので、ストレスを感じない設定が見つかったら利用してみたいと思う
ちなみに `foldmethod=indent` も `fondmethod=syntax` ほどではないがストレスを感じた
`foldmethod=manual` であれば使っても良いのかもしれないが、数千行レベルのコードを手動で設定することはないので、有っても無くても変わらないと判断したため折りたたみ機能自体を無効化した
30秒で読める Python のデコレータの基礎

デコレータは関数を返す関数として作ります。

```py
from typing import Callable
def deco(f: Callable) -> Callable:
    ...
    return wrapper
```

関数にデコレータをつけると、関数が置き換わります。

```py
def just_print():
    print("ha.")
just_print()  # just_print が呼ばれる。

@deco
def just_print2():
    print("haha.")
just_print2()  # wrapper が呼ばれる。
```

wrapper の中では通常、第一引数で受け取った関数を実行します。

```py
# ... の中身
    def wrapper():  # 必要に応じて引数 *args, **kwargs
        # ~~~ 前処理 ~~~
        retval = f()
        # ~~~ 後処理 ~~~
        return retval
```

以上。

# おまけ

関数を返せばいいのでクラスでも書けます。クラス変数とかインスタンス変数が使えて便利？（煩雑？）

```py
from typing import Callable
class Deco():
    @staticmethod
    def deco(f: Callable) -> Callable:
        ...
        return wrapper

@Deco.deco
def just_print3():
    print("hahaha.")
just_print3()  # Deco.deco の wrapper が呼ばれる。
```

クラスを装飾するデコレータを書くこともできます。

```py
def class_deco(c: Type) -> Type:
    class wrapper_class(c): ...
    return wrapper_class
```
ブロックチェーンを使って持ち運び可能なレンタルポケットWi-Fiサービスを導入する可能性


## 導入
ふとコンビニのレンタル充電器を見て、「セキュリティの問題があるけど、ポケットWifiもコンビニでレンタルできたらいいな（ブロックチェーンでセキュアにして）と思ったので、考えを以下にまとめてみました。

つまり、**「持ち運び可能なレンタルWi-Fiサービスにブロックチェーン技術を適用するというアイデアについて」です。
衝動的に書いてるので、もし既出のアイディアであったりしたらごめんなさい。
まずは先入観なしに考えたことを書いてみます。


## 技術的側面

### デバイスの管理とトラッキング

ブロックチェーンは、レンタルされるWi-Fiデバイスの追跡に理想的なツールです。各デバイスにはユニークなIDを割り当て、レンタルの開始から終了までの全てのアクションをブロックチェーン上に記録します。これにより、デバイスの現在地（現在地を改竄されない）や利用状況を正確に把握することができ、紛失や不正利用のリスクを減らすことが可能です。

### 決済処理

ブロックチェーンベースのスマートコントラクトを利用することで、ユーザーがサービスを利用した期間に応じた料金を「自動的」に支払うシステムを実現できます。これにより、透明性が保たれ、ユーザーやサービス提供者間の信頼関係が強化されます。
まさにスマートコントラクトの真骨頂ですね！

### ユーザー認証

ブロックチェーンを活用したユーザー認証システムは、セキュアなログインプロセスを実現し、サービスの安全性を高めます。各ユーザーにデジタルIDを割り当てることで、認証情報の偽造や盗難を防ぎます。

## セキュリティ的側面

### データの不変性

ブロックチェーンの特性上、一度記録されたデータは改ざんが不可能です。これにより、全ての取引履歴が正確に保存され、後からの改竄を防ぐことができます。

### 分散型ネットワーク

ブロックチェーンは分散型ネットワークであるため、サービスの稼働性が高く、攻撃に対する耐性があります。これにより、より安定したサービス提供が可能になります。

### プライバシー保護

プライバシー保護のための技術（例えばゼロ知識証明）をブロックチェーンシステムに組み込むことで、ユーザーの個人情報を保護しながらサービスを提供できます。

## 実装の課題

- **スケーラビリティ:** ブロックチェーンの処理速度やトランザクションの容量には限界があり、これが大規模なサービス展開の障害となることがあります。
- **ユーザーインターフェース:** 従来のアプリケーションに慣れているユーザーにとって、ブロックチェーンベースのシステムは使いづらい可能性があります。ユーザーフレンドリーなインターフェースの開発が重要です。
- **規制と法律:** ブロックチェーンと暗号通貨に関する法律は国によって異なります。今のところ日本ではどんな法律に触発するのかは思いついておりません。

## 結論

持ち運び可能なレンタルWi-Fiサービスにブロックチェーン技術を導入することで、透明性、セキュリティ、利便性を大幅に向上させることが可能です。技術的およびセキュリティ的な面で多くのメリットがありますが、実装にはいくつかの課題が伴います。
第1章 モデリングとUML-02 一般的な間違いは

人体はシステムです。
人の機能には歩く、跳ぶ、投げる、泳ぐなどがありますが、人の構造を設計する際には、機能から直接デザインにマッピングして「歩行器官」、「跳躍器官」、「投げる器官」と得られるわけではありません。
人の器官には目、耳、心、肺、肝臓、胃、骨格、皮膚などがあります。これらの器官は人の機能と一対一で対応しているわけではなく、システムの機能を完成させるために互いに協力する際、機能との関係は多対多です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759949/416560db-b738-ec08-0471-168e5436abcc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759949/ca09ff8a-07b1-7154-2b3f-b51f2a77c37f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759949/16e50cb3-d70c-a178-ec3a-867bf5b113b5.png)

ソフトウェア開発では、要件から直接設計にマッピングすると、大量の重複したコードが生成され、コストが増加します。一方、設計から要件を定義すると、偽の「要件」が生成され、売上が減少します。どちらの場合も、利益が減少します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759949/71563db0-f8ab-bede-5424-0954be96c42e.png)

しかし、多くのソフトウェア開発者はこれに気づいていません。
よく「このシステムは8つのサブシステムに分かれており、販売サブシステム、財務サブシステム、在庫サブシステムなどが含まれています」という言い回しを聞きますが、これは要件と設計が分かれていない例です。実際、話者は次のように自分の意図を表現すべきです。「このシステムの機能要件は8つの要件パッケージに分かれています」。
要件パッケージはステークホルダーの視点に基づいてシステム機能をパッケージ化したものであり、サブシステム（UMLの用語ではコンポーネント）はシステムの部品の結合度と凝集度に基づいて内部視点から切り分けられたものであり、これらは一対一に対応しません。所謂の「財務子システム」は実際には「会計が使用する機能を1つの要件パッケージにまとめる」ことがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759949/65d297c0-5697-b8ac-029d-70733ac65141.png)
「機能モジュール」とは誤った用語です
二つ目の一般的な要求と設計の混同を示す表現は「機能モジュール」です。
機能（Function）という言葉が情報システムに適用される場合、システムが全体として外部からのリクエストを受けた時に生じるべき効果を記述しています。
モジュール（Module）という言葉が情報システムに適用される場合、システムが分割された後に得られる各構成要素を指しています。
「機能モジュール」という言葉は、「機能」と「モジュール」には直接の対応関係があるという意識を意味し、ある「機能」に属するモジュール、或いはある「機能」を果たすために存在すると考えています。
前述の人体の例を用いると、「機能モジュール」は「歩行器官」、「歩行サブシステム」...のようになりますが、これは誤りです。
「機能モジュール」は連結して使用されるべきではなく、「機能」と「モジュール」の二つの言葉の意味も曖昧です。
例えば、対象システムとしてATMを考えると、「現金引き出し」は「機能」であり、「ログイン」も機能で、「手数料計算」も「機能」ですが、「機能」の範囲はどれくらいなのでしょうか？「モジュール」はコンポーネントですか？それともクラスですか？
そのため、より正確な用語をできるだけ使用するようにします。例えば、ATMを対象システムとして、「現金引き出し」はユースケースであり、「ログイン」はユースケースの一連のステップであり、「手数料計算」はステップで、システム内には「アカウント」クラスが存在するかもしれません……。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759949/354b8a51-d3c3-d870-fabf-e56e2f9ec42a.png)
はじめてのりふろー

豊橋技術科学大学ロボコン同好会，回路班のGavadyです．前回の投稿からかなり時間が空いてしまいました．
今回は，いつもと違ってJLCPCBでPCBAではなく，ステンシルを購入してリフローに挑戦してみました．

# どうして☆今になってリフローを？
以前，部室の整理をしていたところ，完全に漬物石と化したリフロー炉(T-962)を発見しました．そこでふと思ったわけです．「自分でリフローしたらだいぶお金の節約できんじゃね？」と．![DSC_0126 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/4249aa3f-357b-f0e5-929f-98f32e578199.jpeg)

JLCPCBは，とても安価で高性能なプリント基板作成サービスを提供していますが，部品の実装を行うとどうしても送料が高くなってしまいます．実際問題，JLCPCBで実装してもらうと送料やその他費用が掛かってしまいますが，自分で部品実装を行う時間を考えるととんとんな気もします．ま，経験することも大事ってことでリフローにチャレンジしました．
# リフロー☆やり方
## 1.いつも通り基板の設計をする．
今回は，3種類の基板をほぼ同一設計で行います．こうすることで，1種類のステンシルで3種類の基板を作ることができます．
## 2.JLCPCBで発注!
日本語版ページでやります．（新規ユーザー，$60分の無料クーポンもらえるのか．これから電子工作やってみようって思っている人は今がチャンス!!）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/490ad536-d7c0-277d-bfd0-8e971639aca9.png)
ここまではいつもと同じ．ガーバーファイルが入ったzipをポンします．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/920a35a9-ef54-0132-f272-c34fac1dda86.png)
ここからが，いつもと違います．ステンシルのチェックを入れます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/5edd05b3-21d2-0a25-180d-6eb5f7a9c177.png)
ここでポイントですが，サイズのカスタマイズという項目を「はい」にします．そうしないと，360mm×260mmの大きな板が発送されることになり，送料が多くかかってしまいます．
基板の大きさと，マージンを考慮して，60mm×60mmに設定しました．合計金額はこんな感じです．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/58eee372-1229-ac0f-adcb-1d0e0f2e5467.png)
基板が2ドル，ステンシルが7ドルです．
## 3.受け取り
ステンシルのサイズをカスタムしないと，このような大きな箱に入って送られてきます．（初めて見たときは，マジでビビりました．）
![DSC_0124.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/ab17443e-cb4a-d25b-c000-3dc905f868f5.jpeg)

## 4.Let's リフロー
届いたステンシルを使って，ペースト半田をパッドにモリモリします．使わない基板を使って，基板の固定と高さの調整をします．![DSC_0131.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/8259ec78-a159-9efe-0696-6ab027910e79.jpeg)
そして，ヘラ等を使って，ペースト半田をまんべんなく広げます．![DSC_0133.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/6dadd797-a5bc-c789-9b24-1c97c2354011.jpeg)

次に，コンデンサ，抵抗，LED，マイコンの順で載せていきます．この時，ほかの部品をずらさないように注意しましょう．![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/f5f74e94-ee7d-78e3-b85e-6a733caf8252.png)

そして，リフロー炉に入れて3分ほど温めます．設定はこんな感じです．使っているペースト半田が悪いのか，300℃まで加熱しないと半田が溶けないみたいなので，少し温度が高めで，その状態を長くしています．
![DSC_0127.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/3d8416c2-a730-c742-d5a0-16d134441aa3.jpeg)
温め終わってら，部品がずれていたり，はんだがブリッジしていないか確認して完成！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/1e5077cb-a898-b234-42ad-74916171c671.png)

事前の調査で，一度部品を実装した面を裏返して温めても部品が落下しないことが分かったので，安心して両面リフローができました．少しわかりにくいですがこんな感じに両面できています．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586033/f250e569-30a7-a476-7509-591effd559d2.png)


## 5.感想
初めてリフローしてみましたが，結構いいですね．部品を乗せるという作業が少し大変ではありますが，それさえ終わればすぐに使うことができます．部品の実装も，効率化していけばもっと楽になると思います！
Dockerのcontainerがどうあがいても消えない時の対処法(kill、stop、down、-fコマンド無効)

表題の通りです。containerがどうやっても消えず、以下のエラーが表示されました。

```bash
Error invoking remote method 'docker-remove-container': Error: (HTTP code 500) server error - Could not kill running container [container ID], cannot remove - tried to kill container, but did not receive an exit event
```
以下のコマンドを実行すると問題なくcontainerを消すことができました。

```bash
$ killall Docker && open /Applications/Docker.app
```
この`open /Applications/Docker.app`はアプリを再度開くだけなので別にいらないんですが、もし実行できない場合`Docker.app`があるフォルダを確認してください。

よくあるのはアプリがダウンロードフォルダにあるとか...(その場合は`/Downloads/Docker.app`)

お役に立ったなら幸いです😃

#### 参考サイト
https://stackoverflow.com/questions/70434777/cannot-kill-container-container-id-tried-to-kill-container-but-did-not-rece/71474694#71474694?newreg=a127b0d5483745d1b373736e2d1f3d38
brタグ、卒業しませんか？レスポンシブな改行がしたいときは、white-space: nowrap;で！使い方を紹介します。

## スマホとPCで改行位置を変えたい！！
サイトを作っているとき、見出し部分でいつも困っていることがあります。
それは、「**改行位置**」です。
レスポンシブが当たり前なこの時代、スマホの見た目は当然、見やすくしなければいけません。
けど時間が無くて、PC版とSP版の両方を改行し、**brタグでしのぐこともしばしば・・・**:disappointed_relieved:

ですが、新年度も始まったので、そろそろお世話になったbrタグを卒業したいなと思います。:cherry_blossom:
そして今年度の目標は、**SPでも思い通りに改行すること**です:muscle:

### たとえばこんな見た目のとき、困りますよね
さっそく、手を動かして問題に取り組んでみます。

▼**PC版**
見た目に問題は無いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/864d60e1-bc31-9a5a-5db1-566ec1174d97.png)

▼**SP版**
変なところで改行されてしまっています:disappointed_relieved:。
しかも中央位置寄せなので、さらに見た目が変に思えてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/7a741f85-8a34-b3bc-935b-d45869fd73c3.png)

▼**SP版改行したい位置**
ここで改行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/0c94a1c2-a731-4b9c-f1f0-021bd366f311.png)

### 手順
#### 手順1
改行したい言葉をサンドイッチするように、spanタグを入れてみます。
class名は、「SPKaigyou」にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/f3fea679-8d41-2153-1bb3-11fd3cee46bc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/ab766f88-7aed-a5c6-7220-14399e9cc8d9.png)

#### 手順2
**white-space: nowrap;**
をSPにのみ反映させてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/b6945368-a5ad-f5ee-f334-12944cb26b75.png)

#### 手順3
PC版、SP版を確認します。

▼PC版　
見た目に変化はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/e267821e-176b-9e74-9621-b9964e573bf1.png)


▼SP版
おお〜ちゃんと改行できました:v:　さっきより違和感は無くなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638020/fdc24403-8747-16e9-1f9a-3d649e0434be.png)

## 改行には、　white-space: nowrap;　がおすすめ
実装してみて、「な〜んだ、こんなにカンタンなら、もっと早く知っていればよかった:neutral_face:」というのが、今回の感想です。
ほかにも、やってみたら以外とカンタンだったというｃｓｓ、たくさんあるかもしれないですね。
今年度は、手を出していないｃｓｓに挑戦してみたいなと思いました。
ABC347備忘録【C~D】

## C - Ideal Holidays
### 問題
https://atcoder.jp/contests/abc347/tasks/abc347_c

### 考えたこと
周期性があるので何日目にいることを仮定するかは自由です。周期性を考慮した後の日にちに対して最小値を基点として、他の点との距離を求めて休日としていくことが可能か判定していきました。文字だけではわかりずらいので、図で考えていきましょう。以降では入力例２に対して$D$を変えて考えていきます。

 図１は距離を求めれば周期性によりスライドすることができ、それにより休日内に収まるか判定できることを表しています。
 
![zu1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631672/4c9623fd-7533-c478-9f32-5a2200f28ed0.png)

図２は距離には２種類あることを表していて、こちらも周期性によりスライドをすることができます。距離11のままではすべて平日と判定しまいますが、距離4のほうではすべて休日にすることが可能です。

![zu2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631672/9ef15ec5-2704-9447-aeec-01d507aec177.png)

図３はどちらの距離に対しても最大距離間は全点を網羅するということを表しています。なので、基点から２種類の最大距離、max_dist1, max_dist2をもとめ、これらの小さいほうをスライドさせて休日の範囲内に収まっているか判定すればよいことがわかります。

![zu3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631672/93ed141e-adb4-185f-7f58-1c5b852f36ea.png)


### ACコード
``` c.py
n, a, b = map(int, input().split())
D = list(map(int, input().split()))
# 周期性を考慮し、日にちを変換。重複を削除
D_set = {d % (a + b) if d % (a + b) != 0 else a + b for d in D}

# 最小の日にちを基点とした
min_d = min(D_set)
D_set.remove(min_d)

max_dist1, max_dist2 = 0, 0
for d in D_set:
    dist = d - min_d
    max_dist1 = max(max_dist1, dist)
    max_dist2 = max(max_dist2, a + b - 1 - dist)

print("Yes" if min(max_dist1, max_dist2) < a else "No")
```


## D - Popcount and XOR
### 問題
https://atcoder.jp/contests/abc347/tasks/abc347_d

### 考えたこと
$popcount(X)$と$popcount(Y)$間に差をつけるのは、２進数に変換した$C$が$1$の時のみです。なので、２進数に変換した$C$が$1$の場所をすべて通過した後、$popcount(X)$と$popcount(Y)$は等しくなっており、それぞれ$a$と$b$以下でなければなりません。

条件を確認後、$popcount(X)$と$popcount(Y)$が$a$、$b$に達していない分、$(1, 1)$をつけ足していきます。

### ACコード
``` d.py
a, b, c = map(int, input().split())

bin_c = bin(c)[2:]
n = len(bin_c)
X, Y = ["0" for _ in range(n)], ["0" for _ in range(n)]

for i in range(n):
    if bin_c[i] == "1":
        if a >= b:
            X[i] = "1"
            a -= 1
        else:
            Y[i] = "1"
            b -= 1

if a < 0 or b < 0 or a != b:
    exit(print(-1))

for i in range(n):
    if a == b == 0:
        break
    if bin_c[i] == "0":
        X[i] = "1"
        Y[i] = "1"
        a -= 1
        b -= 1

if 60 - len(X) >= a:
    X = ["1"] * a + X
    Y = ["1"] * a + Y
    print(int("".join(X), 2), int("".join(Y), 2))
else:
    print(-1)

```
JavaとSpring Bootの内容を理解メモ

# Spring Boot
Java での Web アプリケーション開発を簡略化するオープンソースフレームワークです。
Spring Framework（Springともいう） をベースに、開発を迅速化するための機能が追加されています。
## メリット
- XMLファイルの設定は、pom.xmlで自動生成される
pom:Project Object Model
- @で始まるアノテーションにより、コード量を減らせる
Annotation：注釈
@Controller:リクエストを受け取るクラス
@RequestMapping("/fortune")：リクエスト/fortuneで動くメソッド
- Eclipseで導入が簡単 

# Java Maven
Java プロジェクトのビルド、管理、依存関係管理を容易にするツールです。
Apache Software Foundation によって開発され、オープンソースソフトウェアとして無料で利用できます。

# プロジェクト構成
Spring Boot プロジェクトは、以下の構成になっています。

pom.xml: プロジェクトの設定ファイル
src/main/java: ソースコード
src/main/resources: 設定ファイル、リソース
src/test/java: テストコード
次のX曜日のY時を取得。の最もシンプルなコード #Swift

# 次の日曜日を取得する

## Calendar - nextDate(after: matching: matchingPolicy: )
``` swift: サンプルコード
let now: Date = .now
let calendar: Calendar = .current

let sunday = 1

let nextSunday = calendar.nextDate(
  after: now, matching: DateComponents(weekday: sunday), matchingPolicy: .nextTime
)

print("now: \(now)") /// now: 2024-04-07 08:24:26 +0000,
print("nextSunday: \(nextSunday!)") /// nextSunday: 2024-04-13 15:00:00 +0000

```

## 引数
### after: Date　
日付探索の基準値を指定。サンプルコードでは ```Date.now``` で今を基準値とした。
### matching: DateComponents
日付探索の対象値を指定。サンプルコードでは ```DateComponents(weekday: 1)``` で日曜日を対象値とした。
### matchingPolicy: Calendar.MatchingPolicy
日付探索のアルゴリズムを指定。サンプルコードでは ```Calendar.MatchingPolicy.nextTime``` で次に存在する時刻を返すアルゴリズムとした。

# 次の日曜日午前10時を取得する
## Calendar - dateComponents(_: Set < Calendar.Component >, from: Date) 

``` swift: サンプルコード
let now: Date = .now
let calendar: Calendar = .current

let sunday = 1

let nextSunday = calendar.nextDate(
  after: now, matching: DateComponents(weekday: sunday), matchingPolicy: .nextTime
)

var _nextSunday10AM = calendar.dateComponents([.year, .month, .day, .hour, .weekday], from: nextSunday!)
_nextSunday10AM.hour = 10

let nextSunday10AM = calendar.date(from: _nextSunday10AM)

print("now: \(now)") /// now: 2024-04-07 09:14:51 +0000
print("nextSunday10AM: \(nextSunday10AM)") /// nextSunday10AM: 2024-04-14 01:00:00 +0000
```

## 引数
### _: Set < Calendar.Component >
日付変換の単位を指定。サンプルコードでは ```[.year, .month, .day, .hour, .weekday]``` で 年 / 月 / 日 / 時 / 週 を単位とした。
### from: Date
日付変換に使う日付を指定。サンプルコードでは ```nextSunday``` で次の日曜日（先ほど計算済）とした。


----

以下の記事が古かったので最新に書き換えた。

https://qiita.com/yosshi4486/items/4d902e428d2879a65107
printf()の中で'?'を利用してtrueかfalseを判定する方法(三項演算子)

# ネタバレあるよ
https://atcoder.jp/contests/abc343/tasks/abc343_a

# この記事を書いた理由
このブログは、三項演算子の概念にまだ馴染みがない方、もしくはこれまでif-else文のみで条件分岐を書いてきた方に特におすすめです。
シンプルな'?'を利用して真偽値を判定できるので一度使い方を覚えれば、一行で解決できる可能性が広がります。

# 読者層
・三項演算子(?)の使い方に不慣れな方： printf()で簡単に真偽値を判定する方法を学べます。
・コードを見ることで学びたい方： 他の人の書いたコードから学ぶことの大切さを知っているけども中々見れない方の背中を押します。
・過去の自分に向けて： もし私がこの問題を解く前に知っておきたかったことを、同じ悩みを持つ方々と共有します。


# ACまでのポイント
(問題を見ながら読んでみてね)
・変数 A と B の和により、出力する整数を判定する。
・出力する整数は0〜9の範囲 && 変数 A と B の和以外の整数。
・問題文の制約の3行目に、変数 A と B の和が9以下であると記述があるので和が9と同じであれば、0を出力、それ以外は変数 A と B の和に+1をしたものを出力するというプログラムを書きました。

# ACしたコード
```C
#include <stdio.h>
int main(void){
    int a;
    int b;
    
    scanf("%d%d",&a,&b);    
    // printf("%d %d\n",a,b);    
    
    int result = a + b;
    if(result == 9){
        printf("0\n");
    } else {
        printf("%d\n",result + 1);
    }
    return(0);
}
```
# 参考にした解答(感謝)
https://atcoder.jp/contests/abc343/submissions/50767683

https://atcoder.jp/contests/abc343/submissions/50769506



# 三項演算子を利用するメリット
・C言語においてはbool型を利用しないということは"#include <stdbool.h>"を記述する手間を省ける
・三項演算子は式なので直接変数に代入したり、他の式の中で利用できる
・ACしたコードで書いたような条件分岐で分岐するよりコードが読みやすくなる

# 三項演算子を使ってACしたコード
```C
#include <stdio.h>
int main(void){
    int a, b;
    scanf("%d%d", &a, &b);
    printf("%d\n", (a + b == 9) ? 0 : a + b + 1);
    
    return(0);
}
```
# そもそもbool型ってなんだっけ？
・真偽値を判定できる
・C言語においてはstdbool.hというヘッダファイルをインクルードすることで bool、true、false という名前で扱えるようになる

# 最後に
・提出時間が早い方を中心に回答を拝見したおかげで三項演算子に触れてみようと思えました。
・他の方の回答を見るのをちょっと面倒に感じるかもしれませんが、ぜひ見てみてください。やってみるとブログも書こうと思えたので良かったです！

# 参考にした記事(感謝)
https://www.freecodecamp.org/japanese/news/c-ternary-operator/

https://daeudaeu.com/c-bool/
AWS Lambdaがデプロイ後必ず一回失敗する原因がわかったけど解決できなかった

## 背景
趣味で、DiscordだけでTRPGができるbotを作っています。
（元々はslackの内輪向けbotだったのですが）
構成は、AWS Lambda＋API Gateway+Dockerコンテナ内Pythonです。
元々はLambdaのPythonのWebテキストエディターで書いていたのですが
色々問題があったら変えて行くうちにDockerで管理するのが一番楽になってしまいました。

そんなLambdaで作ったアプリがデプロイ後、一回だけ失敗する状況に悩まされていたのですが
結局解決できなかった事を記載します。


## 問題の発生
手製のスクリプトでLambdaのコンテナイメージの更新していました。
それまで色々なデプロイパッケージを使っていてlambrollがとても使いやすかったのですが
コンテナ環境になった時に手製のスクリプトに変えました。

```:sh
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin ${accound_id}.dkr.ecr.ap-northeast-1.amazonaws.com
docker build --platform linux/amd64 -t ${tag} .
${tag}:latest
docker push ${accound_id}.dkr.ecr.ap-northeast-1.amazonaws.com/${tag}:latest
aws lambda update-function-code  --function-name ${function_name} --image ${account_id}.dkr.ecr.ap-northeast-1.amazonaws.com/cocbotkp-d:latest
```

毎回エラーが発生するので、 `update-function-code` が動作中なんだろうと考え
update中なら待つように以下のコードを加えました。

```:sh
STATUS="InProgress"

while [ "$STATUS" == "InProgress" ]; do
  RESULT=$(aws lambda get-function --function-name cocbotkp-discord-docker)
  STATUS=$(echo $RESULT | jq -r .Configuration.LastUpdateStatus)

  if [ "$STATUS" == "Successful" ]; then
    echo "Update successful."
    break
  elif [ "$STATUS" == "Failed" ]; then
    echo "Update failed."
    exit 1
  else
    echo "Update in progress..."
    sleep 3
  fi
done
```

これで初回失敗に悩む事はなくなっただろう、と思ったのですがまだエラーが続きました。

## IGWの問題？

そんな時、たまたま外部リクエストとの通信のログを見たところ、初回起動時のみ必ず404が発生していました。
discord botの同一エンドポイントに投げているのに、初回だけ404が発生しているのです。
なんとなくAPI-GWで問題が発生しているのかと思っていたのですが、Lambda内部でのエラーだったのです。
IGWかNAT GWかわかりませんが、なにかがアタッチする前にLambdが利用可能になっていたのです。

## 最初の一回は必ず失敗する、以上！

じゃあ404を受け取ったら再度リクエスト送るようにしよう。
そう思ってコードを変えたのですが、discord botのエラーは変わらずでした、
問題は、discord botは処理が長くなる場合、deferred_responseを送って
応答を待ってもらわないといけないのですが、deferred_response自体も404で送る事ができなかったのです。

deferred_responseだけを送るLambdaを作るなど、プロダクションだと方法はあるのですが
趣味だしいいか・・・と思って一回目のエラーは見守る事にしたのでした。

同じように、Lambdaを更新した後すぐの挙動に悩む人が出ないように。。。
C#でのQRコード生成の実装【ZXing.Net】

C#でQRコードを生成する方法を解説します :camera:

## ZXing.Net
QRコードを生成するパッケージ。ライセンスは、`Apache-2.0`です。

Nugetパッケージマネージャーから検索するか、以下のコマンドでインストールします。

```bash
dotnet add package ZXing.Net --version 0.16.9
```

## Windows Formでの実装例
シンプルにボタンをクリックしたらQRコードが作成されるだけの実装です :sunny:

```cs
using ZXing;
using ZXing.QrCode;

private void button1_Click(object sender, EventArgs e)
{
    string URL = "https://qiita.com";
    var bitmap = GenerateQRcode(URL);

    pictureBoxQR.SizeMode = PictureBoxSizeMode.CenterImage;
    pictureBoxQR.Image = bitmap;
}

/// <summary>
/// QRコード生成
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
private Bitmap GenerateQRcode(string URL)
{
    var writer = new BarcodeWriter
    {
        Format = ZXing.BarcodeFormat.QR_CODE,
        Options = new QrCodeEncodingOptions
        {
            Height = 200,
            Width = 200,
            Margin = 1
        }
    };

    return writer.Write(URL);
}
```

ボタンをクリックすると、QRコードが生成されます。
<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482880/ae28baf0-eb3f-9afa-178c-96ac19acbe8e.png" alt="QRコード実装">

## QRコードの読み取り
反対に、QRコードからコンテンツを読み込むことも可能です。

```cs

/// <summary>
/// QRコード読み取り
/// </summary>
/// <param name="filePath"></param>
private void ReadBarcode(string filePath)
{
    var reader = new BarcodeReader(); 
    var barcodeBitmap = (Bitmap)Image.FromFile(filePath);
    
    var result = reader.Decode(barcodeBitmap);
    
    if (result != null)
    {
        var decodeType = result.BarcodeFormat.ToString(); // "QR_CODE"
        var contentText = result.Text;                    // "https://qiita.com"
    }
}
```

どちらの実装も簡単に使えそうです。

## Reference
- [ZXing.Net](https://github.com/micjahn/ZXing.Net/)
掛け算九九での積和試行の最大値

# はじめに
掛け算九九において、7x7=49は特殊な数である。
1から9の数のうち、2つの数（重複を許す）を掛けて十の位と一の位の数を足すという操作を繰り返すことを考える。この操作を0になるまで繰り返したときの試行回数が最大となるのは、7x7のときである。今回はそれをpythonを用いて証明する。

# 問題設定
例えば以下のような感じである。
7x7=49
4x9=36
3x6=18
1x8=08
0x8=00
となるような操作を0まで行う。
この場合、0になるまでに行った試行回数は5回であるが、この場合の時、試行回数が最大になることをプログラムを用いて示す。

# プログラム
以下のようなプログラムを書いた。


```python:kuku.py

import numpy as np

def cal_99(a,b):

  m=a*b
  n=0
  while m > 0:
    m= a*b
    p=m%10
    q=(m-p)/10

    a=q
    b=p

    n=n+1
  return n

n=9

X=np.zeros((n,n))
#print(X)

for i in range(n):
  for k in range(n):
    X[i][k]=cal_99(i+1,k+1)

#print(np.argmax(X))
r= np.argmax(X)+1
print(r)

r1=r%9
r2=(r-r1)/9+1

print('9x9の中で、積→和の操作回数が最大となるものは、 %sx %s の時である' % (r1, int(r2)))


```

これにより、7x7=49のとき、試行回数が最大になることが分かった。
# 解空間のグラフ化
掛け算九九の解空間をグラフ化するために、以下のようなプログラムを作成した。

```python kuku_con.py
import numpy as np
import matplotlib.pyplot as plt

def cal_99(a,b):

  m=a*b
  n=0
  while m > 0:
    m= a*b
    p=m%10
    q=(m-p)/10

    a=q
    b=p

    n=n+1
  return n

n=9

X=np.zeros((n,n))

X1=np.zeros((n,n))
X2=np.zeros((n,n))
#print(X)

for i in range(n):
  for k in range(n):
    X1[i][k]= i+1
    X2[i][k]=k+1
    X[i][k]=cal_99(i+1,k+1)


plt.contourf(X1,X2,X)
plt.colorbar()
plt.savefig("九九試行回数の分布.png")
plt.show()
```
これによって、生成したグラフを以下に示す。

![九九試行回数の分布.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/7e7237aa-4e9e-0bf9-c737-f6d0cfd56c32.png)

このように、7x7のときに試行回数は最大となり、かつ分布はy=xのグラフに対して線対称になることがわかる。



# まとめ
今回のような、整数問題は数式を用いて解析的に解くのが難しく、手当たり次第に解いていく方法が一般には好ましいと考えられる。そのときに考えられる方法がプログラミングによる解法である。総当たりでの探索を行う場合は、計算時間を考慮する必要性が出てくるが、今回のようなケースでは一瞬で解くことができた。
【kotlin】coroutines-coreに含まれている不要なファイルを除外する方法

# はじめに
一昔前まではRxなどを使用されているプロジェクトがちらほらありましたが、現段階ではほとんどがcoroutineを使用する形で置き換わってきたのではないでしょうか？
coroutineを導入する際にcoroutines-coreをgradleへ追記し使用すると思いますが、このcoroutines-coreにはdebug用のリソースファイルが含まれています。
今回は生成されるAPKファイルにdebug用のリソースファイルが含まれないよう除外する方法を備忘録的にまとめたいと思います。

# coroutines-coreのdebug用ファイルを除外する方法
除外する方法は簡単で、gradleのandroidブロックに以下を追加する形になります。

```app/build.gradle
packagingOptions {
    resources.excludes += "DebugProbesKt.bin"
}
```

以上で除外完了になります。

# さいごに
今年もKotlin Festが開催されるようですねー！
5年ぶりにオフラインで開催するようなので、伺う予定です！

https://www.kotlinfest.dev/
JavaScriptを使ってQiitaAPIをたたいてみた

# コードの説明
## 【概要】
JavaScriptを使ってQiitaAPIからデータの抽出を行ったので、そこで学んだことを共有します。
まず、JavaScriptでGETリスエストをQiitaサーバに送る方法ですが、「axios」を採用しました。

## HTML編

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <!-- JavaScriptでGETリクエストを送信するために、axiosを読み込む -->
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  
  <title>Qiita記事_JavaScriptでQiitaAPIをたたいてみた</title>
</head>
<body>
  <!-- ボタンをクリックすると、検索文字で検索が走る -->
  検索：<input type="text"><button>検索</button>

  <!-- index.jsを読み込む -->
  <script src="index.js"></script>
</body>
</html>
```


# JavaScript編 

```JavaScript:index.js
  //  ボタンをDOM操作にするためにbutton要素を取得
const button = document.querySelector('button');

button.addEventListener('click',async function(e){
  // 検索文字に埋め込まれた文字を取得
  const searchvalue=document.querySelector("input").value;
  
  //  GETリクエストのパラメータ作成
  const queryParam = `title:${searchvalue}`;
  const page = 1;
  const perPage = 20;

  //  QiitaAPIにパラメータを埋め込GET送信
  const resqiita = await axios.get(`https://qiita.com/api/v2/items?query=${queryParam}&page=${page}&per_page=${perPage}`);
  
  console.log(resqiita);

  for(let qiitadata of resqiita.data){
  //  QiitaAPIで取得した結果を表示させるための要素を作成  
    const qiitali=document.createElement("li");
    const qiitaa=document.createElement("a");
    const qiitap=document.createElement("p");
 
    let qiitatitle = qiitadata.title;
    let qiitaurl = qiitadata.url;

  // 構成
    document.body.appendChild(qiitali);
    qiitali.appendChild(qiitaa);


  //データ挿入
    qiitaa.href=qiitaurl;
    qiitaa.target="_blank";
    qiitaa.textContent=qiitatitle;
  }
});

}
```

## 実装を終えて
JavaScriptでAPIを使用するための基本的なコードを見てきましたが、
axiosを使用した場合、レスポンスデータがfetchに比べて簡単に処理できるところが良いなと感じました。また、レスポンスデータをJavaScriptでDOMを生成し、リスエストデータに応じてデータを作成する処理を学習できてよかったです。

# 最後に
簡単なコードでしたが、実際に0からコーディングすると、
コードの意味を読むだけ以上に理解できるので、プログラム勉強の際は手を動かしてコードを確認することが大切だと改めて感じました。手を動かしながらコーディングすると、気になった個所に対して、ログを出力して自分の考えが正しいことを確認することができるので、模写からでいいので様々なコードを書いていこうと思います。
もう一つ重要なこととして、
エラーが発生した際は闇雲に手を動かすのではなく、ログやエラーメッセージを確認して、エラー原因を考察することも必要だと考えているので、今後の学習で実践していきたいです。
Python の学習コンテンツを VS Code の Python Interactive Window で楽しむ

# やりたいこと
- Python の学習コンテンツのサンプルコードを自前の環境で実行したい
- とにかく手軽に！

W3Schools や入門書の Python サンプルコードを手元で実行する方法を、手軽さを重視して検討しました。

# やったこと

## VS Code の標準機能 Python Interactive Window

https://code.visualstudio.com/docs/python/jupyter-support-py

すべてここに書いてあります。

### 環境
- Visual Studio Code: 1.88.0
- Python: 3.12.2
- Jupyter: 2024.3.0

### 超簡単
拡張子 `.py` の通常の Python ファイルで `# %%` と追加すると次の `# %%` までが「セル」として認識され、その部分だけ実行できるようになります。

:::note warn
Jupyter 関連のパッケージがない場合はインストールが促されるようです。私は既に環境構築されていたので何もなく開始できました。
:::

```py
# %%
msg = "Hello World"
print(msg)

# %%
msg = "Hello again"
print(msg)
```

ボタンが追加される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/089219c3-ff22-91a2-deef-e95475fedc82.png)

### Run Cell で実行
Window が開かれ、実行結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/d346486a-3b41-c9fd-1e2c-38643753bbfa.png)

### この他にも...

Plot Viewer や Data Viewer など便利そうな機能がまだあります。初学者の友ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/d5d3f461-ed27-fea4-5650-dc08eaf75f9a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/b4846487-653b-867f-6311-723ed544ae61.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107938/69cb3d14-3977-d164-189f-68bc4aa2850e.png)

---

# 余談：いまいちだったソリューション

## Polyglot Notebooks

出たときに飛びついて C# の動作確認・テスト実装に活躍した Polyglot Notebooks ですが、その後 xUnit でテストコードを書き溜めていくようになり使っていませんでした。

https://qiita.com/higege-amdeker/items/976cc66dc5b5d84c9fd5

これでもセルごとの実行はできるのですが、実行のたびに `.ipynb` ファイルの `execution_count` がカウントアップされていき不必要な差分となってしまいました。学習成果のソースコードは GitHub で管理したいと考えていたので、あえなくグッバイとなりました。

## サンプルコードごとにファイルを作って個別に実装

最初これでやってました。ファイルの作成・管理は面倒ですし、実行時にどのファイルか確認したり範囲選択するのが本当に面倒。ワンクリックで実行できる気軽さは最強です。
[PowerShell]別ファイルで定数、変数を定義して読み込んで出力するスクリプト

こんにちは！れーあです。
今回は定数、変数を別ファイルから読み込んでスクリプト内で使用するスクリプトを作っていきます。

それではどうぞ。

## 前提情報
<b> スクリプト実行環境 </b>

```
PS C:\Users\user> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
5      1      19041  4170
```

## スクリプト内容
今回のスクリプトは下記です。別ファイルを用意するので使用するのは2つのスクリプトです。

<b> スクリプト①処理内容： </b>
　定数と変数を定義する。
 　　※定数：固定値、変数：状況によって変化する値

``` PowerShell:Read_env.ps1
# 定数定義
$global:Test_Shell = "Hello, World! My directory is"

# 変数定義
$global:Pass_Shell = pwd
```
<br>

<b> スクリプト②処理内容： </b>
　「Read_env.ps1」ファイルを読み込む。
 　読み込んだ内容をもとに文字列を作成してテキストファイルに出力する。

  ```PowerShell:Main_File_Read.ps1
# 外部ファイルを読み込んで定数、変数を定義する
Invoke-Expression (Get-Content "C:\Users\user\Desktop\Read_env.ps1" -Raw)

# 読み込んだ変数、定数の値を表示させる
Write-Host $global:Test_Shell $global:Pass_Shell
Write-Output "$global:Test_Shell $global:Pass_Shell" > "C:\Users\user\Desktop\export.txt"
```

## 気になる箇所
「$global:」：スコープ修飾子と呼ばれるどこからでも呼び出せる変数、定数を定義することができるようになります。

「Invoke-Expression (Get-Content ~ -Raw」：ファイル内の文字列を読み込んで今回のスクリプトの中で使用することができるようになります。


## 実際に動かしてみた
デスクトップに今回のスクリプトファイル2つともを配置します。
「Read_env.ps1」ファイルは読み込むだけなので実際には手動で実行は行いません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/0ff5e054-9edc-35a3-c43a-abf43d424b23.png)
<br>

「Main_File_Read.ps1」を実行すると、デスクトップ上に「export.txt」が作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/e2bccf16-1d62-f7b8-e42e-b45a49d9c43a.png)
<br>

「export.txt」ファイルの内容を確認すると期待通りの値が出力されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632150/4177771a-0c11-24d6-3f2b-972ff122d946.png)
<br>

## おわりに
というわけで以上です。
内容としてはごく単純なものではあるのですが、別ファイルを読み込んで環境変数を定義するというのは仕事で使用するスクリプトではよく見かける技術だなと思ったので、今回整理のために作成してみました。

## 参考
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-5.1#scope-modifiers

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.utility/invoke-expression?view=powershell-5.1

https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.management/get-content?view=powershell-5.1