どうも社家畜です。

今回はdockerでの出来事を備忘録として書いておきます。多分転職できたとしたらすぐに出てくるエラーだと思い一応残しておこうかなと。

 

 

復習がてら講座の課題を2週目しようとdocker-compose up-dをしたところ

こんなエラーが・・・

 

AI先生に丸っと翻訳してもらった結果、

 

「今回作ろうとしているコンテナでlaravel_appっていう名前が競合しているよ」

 

という内容でした。

 

一般的な現場の対応の傾向

1. 既存のコンテナを削除する

  • 多くの場合、まず既存のコンテナを削除します。
  • 理由は、既存のコンテナとの競合を避けるためです。
  • docker-compose downやdocker rmコマンドで削除し、新しい設定で再デプロイします。

2. docker-compose.ymlの名前を変更する

  • 既存のコンテナと競合している場合に、新規のコンテナで名前を変えることもありますが、
  • 基本的には既存の競合を解消→削除してから、新しい設定で立ち上げる方針が優先されることが多いです。

なぜそうなるのか

  • シンプルに競合解消できるため。
  • 既存のコンテナを削除して、新しい設定で再起動する方が、管理も分かりやすいからです。

まとめ

  • 確率が大きいのは:
    既存のコンテナを削除して、新しい設定のコンテナを作るです。

 

docker-compose.ymlの内容は簡単に言うとレシピみたいなもので(解釈が間違っていたらごめんなさい・・・)ここに書かれている内容でコンテナを立ち上げますよということらしい。

 

同じコンテナでdocker-compose  up-dをすると、docker-compose.ymlに設定されている名前を使って立ち上げようとするので、そりゃあ同じ名前になるわなと・・・

 

ならば今回はコンテナ削除で試してガッテン!

 

docker rm fe77b1dab2925f3cb9dac9fde1c0bd8a4b4d81e42a341d78df2e82b02dde71f4

 

上の画像の""で囲まれているやつをはりつけてエンター!

 

そしてdocker-compose ps-aで保存されている内容を確認すると・・・

 

やる前

やった後

4つある中で一番下が消えてる!!

 

成功しました。

 

これでもう一度docker-compose buildをしてup-dをしてみると

 

いや次は㏈かよ・・・

 

docker stop laravel_db

起動しているかもしれないので止めて

 

docker rm laravel_db

Laravel_dbを単体で消す

 

これでもう一度docker-compose up-dをしてみると・・・

 

薄々思ってはいたけど今度はadminerか・・・

ってかこれはもしかしてbuildしたせいで正規のコンテナなのに1回目のコンテナと2回目のコンテナが同じ名前でbuildしたからなったのかも・・・

 

docker-compose down

で今いるdocker-compose.ymlの管理しているイメージをすべて停止!削除!

おお!停止して消えていくぅううう!

 

一応docker ps -aで確認っと・・・

少なくなってる!adminerがなんか恐いけど大丈夫でしょ!

 

いやダメなんかーい!!!!

 

downして、adminerが残った状態にしました。

個別で

docker rm adminer

を消しました。

 

全てupになった!

 

ローカルホストにアクセスするとnot found!!

やっと成功しました。

良かった・・・

 

まとめ

・docker-compose.ymlはコンテナのレシピ!

・一度up-dしたら最後はdownしといたほうがいい!(エラーがでたコンテナだけ消しても同じレシピで立ち上げたら二重に立ち上がるので結局は別でエラーがでる!)

・downしても消えない奴は個別にrmで消す!

・違うymlでのbuildだったら競合しない!

 

 

いやー長かった・・・

 

 

 

 

1    $input_count = (int)trim(fgets(STDIN));
2    $data = trim(fgets(STDIN));
3    $datas = explode(" ", $data); // ★1
4    $out_count = (int)trim(fgets(STDIN));
5    $position = trim(fgets(STDIN));
6    $positions = explode(" ", $position); // ★2
7
8    foreach ($positions as $position) { // ★3
9        $output = $datas[$position] -1 ; // ★4
10    }
11         echo $output, "\n"; // ★5

 

 

 

 

指摘事項

  1. ★1: $datas の要素が文字列のまま explode(" ", \$data) の結果は、数値の文字列 "1", "2", "3" などが入った配列になります。これを\$datas[\$position] のようにインデックスとして使う場合、PHPが自動的に数値に変換してくれますが、\$datas の中身自体も数値にしておいた方が、後々の処理で混乱しにくいです。 array_map('intval', ...) を使うと良いでしょう。

  2. ★2: $positions の要素も文字列のまま これも ★1 と同じ理由です。$positions の各要素は「何番目か」を示す数値として使うので、array_map('intval', ...) で数値に変換しておきましょう。

  3. ★3: ループ変数名と外の変数名が同じ \$position という変数が、\$positions = explode(" ", \$position); の行で使われた後、foreach (\$positions as \$position) でループ変数としても使われています。これはPHPの構文上問題ありませんが、コードを読むときに混乱を招く可能性があります。ループ変数は \$_p や $b_value など、別の名前に変えることをお勧めします。

  4. ★4: インデックスの計算と取り出す値が間違っている ここが一番重要な間違いです。

    • $datas[$position] で配列 \$datas から値を取り出そうとしています。ここまでは良いのですが、\$position は B_i の値、つまり「何番目か」(例: 1, 2, 3)を直接指しています。
    • PHPの配列は 0から始まるインデックス です。「1番目」の値はインデックス 0 に、「2番目」の値はインデックス 1 にあります。
    • したがって、\$position (1から始まる番目) をインデックスとして使うには、\$position - 1 とする必要があります。
    • さらに、$datas[$position] - 1 と書くと、取り出したAの値そのものから1を引いてしまっています。問題は「AのB_i番目の値」なので、取り出した値をそのまま出力する必要があります。

    正しい書き方は、$datas[(int)$position - 1] です。 ($position が文字列から数値に変換済みであれば (int) は不要ですが、安全のため付けています。)

  5. ★5: echo がループの外にある foreach ループの外で echo $output すると、ループの中で output に代入された最後の値しか出力されません。 問題の要求は「各 i について、i 行目に A の B_i 番目の値を出力してください」なので、各 B_i の処理が終わるたびに echo する必要があります。echo は foreach ループの中に入れるべきです。

 

 

$nを読み取る

 

array_mapを使い文字列を配列にする

その時下記にあるようにtrimをして、explodeで半角スペースで区切り、intvalで整数にする

 

forで$nまでのループ処理をする

 

下記のrangeを使い1からarray_mapで処理した$mを[$i]までの配列を作る

 

implodeでrangeで作った配列を半角スペースで区切り、最後は改行をして出力

 

 

 


 array_map('intval', explode(' ', trim(fgets(STDIN))));

 1. `fgets(STDIN)`  
- 標準入力から1行の文字列を読み取る
- 例:`"2 4 3\n"` という文字列

 2. `trim(...)`  
- 文字列の前後の空白や改行を取り除く
- 例:`"2 4 3"`

 3. `explode(' ', ...)`  
- スペース `' '` を区切りとして、文字列を分割し、配列にする
- 例:`["2", "4", "3"]`

 4. `array_map('intval', ...)`  
- 配列の各要素に対して `intval()`(整数に変換)を適用
- 例:`[2, 4, 3]`

 range(1, $M[$i]);`

 1. `$M[$i]`  
- 配列 `$M` の i 番目の要素を表す、例:`2` や `4`

 2. `range(1, $M[$i])`  
- 1から `$M[$i]` までのすべての整数の配列を作る
- 例:  
  - `$M[$i] = 2` のとき → `[1, 2]`  
  - `$M[$i] = 4` のとき → `[1, 2, 3, 4]`

 全体の動きのまとめ

1. 最初の行は標準入力から複数の数値を受け取り、それを整数の配列 `$M` に格納している
2. そして `range()` は、その中の任意の `M_i` に対して、「1 から M_i までのすべての整数」を配列として作っている

---

 補足
- このコードは「入力から数値列を作り、それぞれの M_i に対して「1 から M_i までの数列」を生成するための準備」
 

 

 

 

 

入力される文字列を整数にしてN行までの直角三角形にする

 

forでN行までのループ処理を書く

 

N行までの列をforで上の$iを使ってループさせる

ifで半角スペースと$iになったら改行する条件分岐にする

 

反省

・はじめは全ての行は1から出力と考えており、どうやって次の列に行ったらいいかわからなかったが、難しく考えずに反対から考えると階段になっていたので、そこで改行させることに時間がかかってしまった。見方を変えることが大事。

 

1           1

1 2        2 1 

1 2 3    3 2 1 

       

 

 

最初に2つの数字が半角スペースで入力されるのでexplodeを使い半角スペースで区切る

forで最初の数値分の1~N個までを繰り返して出力

ifで半角スペースと終わりで改行を入れる

 

新しくforで次の数値分1~M個までを繰り返して出力

上と同じく半角スペースと終わりで改行を入れる

 

反省

・forではN個M個なので

<=

だがifでは最後は改行を入れるので

<

のみにすること

比較演算子の理解

 

 

intvalで整数にしてNを読み込む

 

前半のループはforで1~N/2個までを表示させる

その中でifを使い、半角スペースを入れて出力する

ループの最後は改行にする

 

後半のループはN/2+1個~N個までを表示させる

前半と同じように半角スペースを入れて出力

最後は改行

 

反省

・IF文の理解を高めること

・後半の$iは1ではなくN/2+1から始めないと前半の続きにはならない