OmniAICreator/Qiita-1.07M huggingface dataset:
KivyでYes No Popupを作る

# 概要
はい・いいえを聞くダイアログが欲しかったので、使いまわしやすいような形で作りました。
![Demo](https://github.com/Take-Me1010/Yes-No-Popup/blob/main/image/demo.JPG?raw=true)

# コード
[git](https://github.com/Take-Me1010/Yes-No-Popup)にも置きました。

```__init__.py
'''
    a simple Yes/No Popup
    LICENSE : MIT
'''
from kivy.uix.popup import Popup
from kivy.properties import StringProperty

from kivy.lang.builder import Builder
Builder.load_string('''
#<KvLang>
<YesNoPopup>:
    FloatLayout:
        Label:
            size_hint: 0.8, 0.6
            pos_hint: {'x': 0.1, 'y':0.4}
            text: root.message

        Button:
            size_hint: 0.4, 0.35
            pos_hint: {'x':0.1, 'y':0.05}
            text: 'Yes'
            on_release: root.dispatch('on_yes')
        
        Button:
            size_hint: 0.4, 0.35
            pos_hint: {'x':0.5, 'y':0.05}
            text: 'No'
            on_release: root.dispatch('on_no')

#</KvLang>
''')

class YesNoPopup(Popup):
    __events__ = ('on_yes', 'on_no')

    message = StringProperty('')

    def __init__(self, **kwargs) -> None:
        super(YesNoPopup, self).__init__(**kwargs)
        self.auto_dismiss = False
    
    def on_yes(self):
        pass
    
    def on_no(self):
        pass


if __name__ == '__main__':
    from kivy.app import App
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.button import Button
    
    class TestApp(App):
        def __init__(self, **kwargs):
            super(TestApp, self).__init__(**kwargs)
    
        def build(self):
            self.pop = pop = YesNoPopup(
                title='Popup !',
                message='OK ?',
                size_hint=(0.4, 0.3),
                pos_hint={'x':0.3, 'y':0.35}
            )
            pop.bind(
                on_yes=self._popup_yes,
                on_no=self._popup_no
            )
            root = BoxLayout()
            btn = Button(text='open')
            root.add_widget(btn)
            btn.bind(on_release=lambda btn: self.pop.open())
            return root

        def _popup_yes(self, instance):
            print(f'{instance} on_yes')
            self.pop.dismiss()

        def _popup_no(self, instance):
            print(f'{instance} on_no')
            self.pop.dismiss()

    
    TestApp().run()

```

結構シンプルです。on_yesとon_noイベントにそれぞれの場合の処理を行うコールバック関数を渡せばよいでしょう。
カスタマイズも容易なので、いろいろな場面で使えそう、、かも？
WireShark LUA PluginでMavLink通信プロトコルを解析

WiFiなどで通信されているMavLinkメッセージをWireSharkで解析する時、MavLinkのバイナリ形式のデータ構造を確認することができますが、大変です。

WireShark MavLink LUA Plugin (mavlink.lua)を使用することで簡単にMavLink通信プロトコルをデコードした中身を確認することができます。

[バイナリ形式のMAVLinkデータ構造](https://qiita.com/k-koh/items/9e9c1694dbb5a2a4117a)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/2773da78-1aa1-5286-aeff-74821d4f505a.png)

# WireShark MavLink LUA Plugin導入手順

- mavlink.zipをダウンロード

[mavlink.zip](https://github.com/DroneEngineerTeaParty/Drone_technology_usage/files/2765304/mavlink.zip)をダウンロードします。

mavlink.zipを解凍してmavlink.luaが展開されます。

- mavlink.luaをWireshark\pluginsに格納

「ヘルプ」| WireSharkについて　より「グローバルLuaプラグイン」のパスをクリックします。

mavlink.luaを/usr/lib/x86_64-linux-gnu/wireshark/pluginsにコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/52005fcc-5321-e969-3ef7-7624c8dbbf93.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/f4667079-c98c-df1b-260f-e8758fb3c134.png)

- WireSharkを再起動

- DataをMAVLINK PROTOでデコードを設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/1cd7db03-072a-8754-d64c-f46ac44628c5.png)

MAVLINK_PROTOを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/d7fe7443-31bc-b7a3-89f8-6816e816cfe3.png)

- デコードしたMAVLINK PROTOのデータ中身が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/4915f55c-91a3-9bc7-bd6e-361eb341d21b.png)
Linux ユーザー系コマンド

## ユーザーを変更したり、権限系のコマンド

```:rootユーザーに切り替え(カレントディレクトリはそのまま)
sudo su
```
```:rootユーザーに切り替え(rootユーザーのホームディレクトリへ移動)
sudo su -
```
```:ユーザーの所属グループを変更する
# 基本形

usermod オプション必須 グループ名 ユーザー名

# user1ユーザーのセカンダリーグループをにgroup1を追加する
usermod -a -G group1 user1
```
```:対象ファイルの所有権を変更する
chown 変更ユーザー名 対象ファイル

# グループ名も変更する場合

chown 変更ユーザー名:変更グループ名 対象ファイル

# ディレクトリの所有権を変更する場合

chown -R 変更ユーザー名 対象ディレクトリ
```


```:対象ファイルの扱える権限を変更する
chmod 権限 ファイル名
```
権限の表示方は２通り

#### パターン１　数字で表現
```:権限表現
1 実行権限のみ
2 書込権限のみ
3 実行+書込権限
4 読込権限のみ
5 読込+実行
6 読込+書込
7 読込+書込+実行
```

```:例
chmod 654 testfile.txt

ls -l
total 0
-rw-r-xr--  1 user  group  0 10 15 21:04 testfile.txt
```

※上記は権限は所持ユーザーが読込と書込できて、グループが読込と実行できて、その他は読込だけという権限に変更した場合。

#### パターン２ 文字で表現

```:ユーザー表現
u →　ユーザー
g →　グループ
o →　その他
a →　全ユーザー
```

```:権限表現
r 読込
w 書込
x 実行
```

```:変更表現
+ 現状から追加する
- 現状から削除する
= 直接結果を指定
```

```:例__全ユーザーを読込、実行権限有に変更する
# chmod a=rx testfile.txt
# ls -l
total 0
-r-xr-xr-x  1 user  group  0 10 15 21:10 testfile.txt
```


```:パスワードを設定、更新する
passwd ユーザー名 #ユーザー名を省略すると自身のパスワードを変更
```
使っているLaravelを6.x→8.xへアップデートしたときのメモ

# はじめに

当方のメインサイトはLaravelで作られているのですが、トップページに1行しか無い寂しいサイト。そろそろ本格的に作ろうということでしたが、結構色々ありまして…最初、laravel/uiをインストールしようとしたら、laravelのバージョンが古すぎて入れないというのがきっかけで、バージョンアップしようということにしました。

# 背景

当方のサイトは、開発環境としてローカルマシン上でDockerを使って構築、本番環境にGithub(プライベートリポジトリ)を介して適応しています。

# 取り急ぎバージョンアップ

取り急ぎ着手しなければとなったのはLaravelのバージョン。
調べてみると、6.17という結構古いものでした。

```
root@78e089450650:/var/www# php artisan --version
Laravel Framework 6.17.1
```

# Composerのアップデート

しかも、Composereを使ってみると「バージョンが古すぎる！」というメッセージが出ていました。

![composer_エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101034/2289827f-486a-a05b-d22c-5920574d9a55.png)
手始めに、Composerをアップデートします。

```
root@***:~# curl -sS https://getcomposer.org/installer | php
All settings correct for using Composer
Downloading...

Composer (version 1.10.15) successfully installed to: /root/composer.phar
Use it: php composer.phar

root@***:~# mv composer.phar /usr/local/bin/composer
root@***:~# composer --version
Composer version 1.10.15 2020-10-13 15:59:09
```

これで、Composerのアップデートが出来ました。

# 6.x -> 7.x へのバージョンアップ

基本的に、Qiitaの記事で書かれている内容で対応できました(サイトの中身がほとんど無いので変更点は少なかった模様)。

[Laravel 6.x→7.xバージョンアップ](https://qiita.com/A-Kira/items/439cbcb001d71f3a3557)

この記事を基にファイルを編集、`composer update` かけることで7.xにアップデートできます。

```
root@***:/var/www# composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 12 installs, 58 updates, 3 removals
  - Removing symfony/debug (v4.4.4)
  - Removing jakub-onderka/php-console-highlighter (v0.4)
  - Removing jakub-onderka/php-console-color (v0.2)
  :
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
49 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

root@***:/var/www# php artisan --version
Laravel Framework 7.28.4
```

念の為、`npm install` -> `npm run dev` しておいたほうがいいと思います。

# 7.x -> 8.x へのバージョンアップ

基本的に、以下のサイトで書かれている内容で対応できました（サイトの中身がほとんどなかったため、`composer.json` の依存性のみを設定すればOKでした）

```
root@***:/var/www# composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 6 installs, 23 updates, 1 removal
  - Removing phpunit/php-token-stream (3.1.1)
  - Installing graham-campbell/result-type (v1.0.1): Downloading (100%)
  - Updating vlucas/phpdotenv (v4.1.8 => v5.2.0): Downloading (100%)
  :
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
71 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

root@***:/var/www# php artisan --version
Laravel Framework 8.10.0
```

# バージョンアップのコツ

対応を端折らずに、1バージョンずつ上げることをお勧めします（6.x -> 7.x -> 8.x）。

# 最後に

開発環境で動作を確認したら、Githubにソースをpush、本番環境でpullして `composer update` -> `npm install` -> `npm run production` すれば、両方の環境でバージョンを揃えられると思います。
Swiftでcosxの近似値を求める

## なぜSwiftなの？

Swiftは環境構築などする必要がなく,MacかiPadがあれば[Playgrounds](https://apps.apple.com/jp/app/swift-playgrounds/id1496833156?mt=12)をインストールするだけで使うことができる。
また,Playgroundsには**ステップ実行**や**ゆっくり実行**という機能があり,for文やwhile分をステップごとに実行し,実行されている時の値の変化を確認することもできる。
さらに,**ビューア機能**を使えば変数の変化の様子を勝手にグラフ表示してくれる。
![2020-10-14 11.16のイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/3f40f66a-ab98-7ef8-49ec-8bec9a137f2d.jpeg)

## cosx のマクローリン展開

$cosx$をマクローリン展開すると,

$$
cosx=1-\frac{x^2}{2!}+\frac{x^4}{4!}-⋯+\frac{(-1)^nx^{2n}}{(2n)!}+⋯
$$
と表されるのであった。この記事では$sinx$の近似値をプログラミングを使って求めていく。(言語はSwift)ipadでも大丈夫。

## 1.変数を用意する

マクローリン展開は何回でも微分できる関数$f(x)$を$x$の冪乗関数の級数の展開式の和で近似させるものであるのであった。この記事では$sinx$の値を`sum`として,`sum`にだんだん値を加えていく。

```swift
var sum = 0
print(sum)    //0
sum += 1
print(sum)    //1
```

また,近似する$x$を入れる定数も用意しなければならない。この時近似する値として$\pi/6$や$\pi/3$などの値を用いたいので,$\pi$が使えるよう`import Foundation`を書いておく。

```swift
import Foundation
var sum = 0
let x = Double.pi/2
```

さらに,項として更新され続ける変数を用意する。

```swift
var item = x
```

第一項は定数と同じになるので,`x`を入れておく。

最終的なコードは以下のようになる。

```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = Double.pi/2
var item = x
```



## 2.x=π/2として,第二項までコーディングする

コーディングをする上で小さな値から始めることや具体的な値で試行錯誤することは重要だと思う。(個人の見解)。この記事でもその理念に則り$x=\frac{\pi}{2}$として第二項まで,つまり

$$
cosx=1-\frac{x^2}{2!}
$$
までコーディングする。



```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = Double.pi/2
var item = 1

sum += 1
sum += -(x*x)/Double(2*1)
```

`sum`に$1$を加え,次の行で$-\frac{x^2}{2!}$を加えている。

最後に真値と比較する`print`文を加える。

```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
var x = Double.pi/2

sum += 1
sum += -(x*x*x)/Double(3*2*1)

print(sum)//近似値0.9248322292886504
print(sin(Double.pi/2))//真値1.0
```

`Double(2*1)`としているのはInt型をDoule型に変換しているのだが,この記事では本質的な部分ではないので説明は割愛。



## 3.一般化しやすいように工夫する

さっきは第二項を$-\frac{x^2}{2!}$としたが,これでは項数が増えるたびに$x$を増やさなければならない。項数が増えても短くコーディングすることができるように工夫を加える。



```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = Double.pi/3
var item = 1

sum += item

for i in 1 ..< 3{
    item *= -(x*x)/Double((2*i)*(2*i-1))
    sum += item
}

print(sum)//近似値0.525479753410744
print(cos(Double.pi/3))//真値0.5
```



## 4.項数をふやす

一般化することによって項数を増やしても対応できる。



```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = Double.pi/3
var item = 1.0

sum += item

for i in 1 ..< 6{
    item *= -(x*x)/Double((2*i)*(2*i-1))
    sum += item
}

print(sum)//近似値0.499999999639
print(cos(Double.pi/3))//真値0.5
```



第6項までの近似,つまり

$$
cosx=1-\frac{x^2}{2!}+\frac{x^4}{4!}-\frac{x^6}{6!}+\frac{x^8}{8!}-\frac{x^{10}}{10!}
$$
ではほとんど誤差が無いことがわかる。

## おまけ
一般化するときは表にすると捉えやすい。

![](https://storage.googleapis.com/zenn-user-upload/uyqlkfh0s2pmk7ykqkjb91n11jyt)
X-Forwarded-Forは複数入りうる

タイトルで伝えたいことの大半を消化してしまっている気もしますが、HTTPヘッダの`X-Forwarded-For`は、複数のIPアドレスが並ぶことがありえます。

## `X-Forwarded-For`とは

リバースプロキシを介してリクエストを処理する場合、プロキシされた先のサーバで見えるIPアドレスはプロキシサーバのものになってしまい、リクエスト元がわからないという事態になります。

そこで慣習的に用いられているのが`X-Forwarded-For`で、リクエストの本来のIPアドレスをこのヘッダに入れます。

## 多段プロキシの場合

サーバの外側にクラウドサービスのロードバランサーを入れて、サーバはnginx+Pumaで構築する、というようなことをやると、Pumaへのリクエストはロードバランサーとnginxで2回プロキシされてやってくることになります。

この場合、`X-Forwarded-For`の中身は`<client>, <proxy1>`のように、クライアントのIPアドレスが先頭に来るように並びます。

## まとめ

`X-Forwarded-For`に何がどれだけ来るかはサーバ構築の状況に依存するので、複数対応を忘れていたとしても動くことも考えられますが、逆に何かでサーバを入れ替えたときに動かなくなることも考えられますので、`X-Forwarded-For`を扱うときは注意が必要です。

## 外部リンク

* [X-Forwarded-For - MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Forwarded-For)
フェイルオーバーテストとは

障害テストは、システムの復元力テストの一種であり、その主な使命は、アプリケーション内と他のソフトウェアベースのシステムに依存しない要因（機器、ネットワークなど）の両方から発生した誤動作に抵抗するソフトウェアの能力を判断することです。
このタイプのテストは、調査の対象が次のとおりであるため、テストを実行するための非常に特殊な（他のテストと比較して）アプローチがあります。
•データ処理が中断されたときのソフトウェアの動作。
•ネットワークが失われたとき。
•電源がオフになっているとき（クライアント側またはサーバー側）。
•メディア接続の喪失。
その結果、ソフトウェアが障害から回復する能力に対する上記の影響に基づいて、さまざまなテストシナリオが開発されています。
誤動作シミュレーションでは、データ損失の程度（許容範囲内かどうか）と、すべてのトランザクションとその実行ステータスをログに記録するシステムの能力の両方が評価されます。 (もっと。関数は https://fin-test.net/services/system-resiliency-testing/?utm_source=linkbilder より引用）
Windowsでping/tracertするためのファイアウォール設定

Windowsでping/tracertするとデフォルトでは疎通しません。
これはファイアウォールで落とされているからで、ルールを追加することで通過させることができます。
PowerShellを開き、下記のコマンドを実行します。

```powershell
New-NetFirewallRule -DisplayName "Allow ICMPv4-In" -Protocol ICMPv4
```

IPv6の場合は

```powershell
New-NetFirewallRule -DisplayName "Allow ICMPv6-In" -Protocol ICMPv6
```
ApacheでShift_JISを表示したい


# 準備

```bash
# docker run --privileged -p 8080:80 --rm centos:centos7 /sbin/init
# docker exec -it `docker ps -q` /bin/bash
```

```bash
[root@388335783ce8 /]# yum install -y httpd
[root@388335783ce8 /]# systemctl start httpd
[root@388335783ce8 /]# mkdir /var/www/html/sjis
[root@388335783ce8 /]# vi /var/www/html/sjis/index.html <- Shift-JISのテキストを置く
```

```html:/var/www/html/sjis/index.html
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>Shift_JIS</title>
</head>
<body>
日本語が化けないことを期待
</body>
</html>
```

# 対処

ヘッダーに`charset=UTF-8`が設定されているため、ブラウザはmetaタグより優先するため文字化けする。

```bash
[root@388335783ce8 /]# curl localhost/sjis/ -I
Content-Type: text/html; charset=UTF-8
```


```txt:/etc/httpd/conf.d/sjis.conf
<Directory /var/www/html/sjis>
    AddDefaultCharset Off
</Directory>
```

```bash
[root@388335783ce8 /]# systemctl reload httpd
```

```bash
[root@388335783ce8 /]# curl localhost/sjis/ -I
Content-Type: text/html
```
javascriptのLocalStorage を使ってお気に入り機能を自作してみた ②実装編-基盤作り-

# どうも7noteです。プラグインより多機能なお気に入り機能を作成。前回の続き

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/jsfavorite-2/
webpack使った外部参照用jsの生成

## 概要
node管理されていないシステムで、nodeのライブラリを使いたかったので試行
※jaconvを使いたかった

## 手順
ソース（下に記載）のように定義すると、

```
npm run build
```

でconvert.jsが生成され

```
<script src="convert.js" />
```
で入れれば

```
common.toHanAscii(str);
```
みたいに使える。

ポイントはwebpack.config.jsのlibrary
（optimizationはなくてもいけるはず）


## ソース
webpack.config.js

```
const path = require('path')
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
    entry: path.resolve(__dirname, "index.js"),
    output: {
        path: path.resolve(__dirname, 'modules/system/assets/js/common'),
        filename: 'convert.js',
        library: 'common',
        libraryTarget: 'var',
    },
    optimization: {
        minimize: true,
        minimizer: [new TerserPlugin({
            terserOptions: {
                // ecma: 6,
                compress: false,
                output: {
                    comments: false,
                    beautify: false
                }
            }
        })]
    },
}

```

index.js

```
export function toHebon(str) {
    const jaConvert = require('jaconv');
    return jaConvert.toHebon(str);
}
export function toHanAscii(str) {
    const jaConvert  = require('jaconv');
    return jaConvert.toHanAscii(str);
}
export function toHiragana(str) {
    const jaConvert  = require('jaconv');
    return jaConvert.toHiragana(str);
}
export function toZenKana(str) {
    const jaConvert  = require('jaconv');
    return jaConvert.toZenKana(str);
}

export function toConv(str) {
    str = this.toZenKana(str);
    console.log(str);
    str = this.toHiragana(str);
    console.log(str);
    str = this.toHebon(str);
    console.log(str);
    str = this.toHanAscii(str);
    console.log(str);
    return str;
}

```

package.json

```
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
  },
  "devDependencies": {
    "jaconv": "^1.0.4",
    "terser-webpack-plugin": "^4.2.3",
    "webpack": "^5.1.0",
    "webpack-cli": "^4.0.0"
  }
}

```

## まとめ
一応これで使えましたが、回りくどかったので、他にもっと簡単なやり方あったら知りたい所です。

あと、このライブラリ化したソースも、require('jaconv');がfunction毎に入れてて綺麗じゃないので、良い書き方あったら知りたいなって感じです。

単純にライブラリをグローバル的に入れて使えると良いなと思いました。
（やり方悪かったのかもですが、最初変数にrequire入れてそれやろうとしたらできなかったので）


## 参考
[webpackでグローバル変数を定義する](https://www.it-swarm-ja.tech/ja/javascript/webpack%E3%81%A7%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E5%A4%89%E6%95%B0%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%99%E3%82%8B/825969180/
)
Laravel7タグ付き投稿記事の検索機能（リレーション）

#やりたいこと
タグを付けて口コミを投稿することができるサイトを作っています。その投稿のタイトルや本文、タグを対象に検索する機能を実装します。検索自体は難しくないかもしれませんが、複数テーブルにまたがるデータを全て検索する必要があるので、ほんの少し厄介でした。でも想像していたより簡単にできました。

#前提
データベースは下記の通り、多対多、お互いbelongsToManyのリレーションになっています。
reviews：投稿
tags：タグ
review_tag：中間テーブル

ちなみに
uses：reviewsテーブルと一対多の関係になっている。

環境：Laravel 7

#実装！
##ビュー１（検索画面）
今回のアプリはヘッダーのコンポーネントに検索を作りました。iタグはFontawesomeの検索虫眼鏡です。

```html:header.blade.php
<form action="{{ url('/search')}}" method="get">
  <i class="fas fa-search"></i>
  <input id="header-search-text" type="search" name="keyword" placeholder="キーワードで検索">
</form>
```
ボタンは付けませんでしたが、ユーザーがEnterを叩くと送信されます。
URLはmethod属性を`get`にすることで、`?`をセパレータとして、action属性のURLに続けて生成してくれます。参考→[https://developer.mozilla.org/ja/docs/Web/HTML/Element/form](https://developer.mozilla.org/ja/docs/Web/HTML/Element/form)

##ビュー２（検索結果表示）
かなり簡素化してますがコーディング例を下に書いておきます。
親レイアウトとして、views/layouts/myapp.blade.phpを用意しています。
head内、titleタグに`@yield('title')`というディレクティブを仕込んでいます。
Bladeレイアウトはこちらで→**[Laravel7継承レイアウトの基本を図解してみた](https://qiita.com/kakudaisuke/items/39eb4a80945d08cc1d67)**

```html:search.blade.php
@extends('layouts.myapp')

@section('title')
「{{$keyword}}」の検索結果
@endsection

@section('main')
<h1 class="main-title">「{{$keyword}}」の検索結果</h1>
@foreach ($reviews as $review)
 <h2>{{$review->live_date}} {{$review->title}}</h2>

 @foreach ($review->tags as $tag)
 <a>{{$tag->tag_name}}</a>
 @endforeach

 <p>{{$review->text}}</p>     
 <span>by {{$review->user->account_name}}さん</span>
<span>{{$review->created_at}}</span>

  @endforeach
  {{ $reviews->links('vendor.pagination.bootstrap-4')}}
@endsection

```
##ルート
```php:web.php
Route::get('search', 'SearchController@search')->name('search');
```


##コントローラ
```php:SearchController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use App\Review;
use App\Tag;
use App\User;

class SearchController extends Controller
{
    public function search(Request $request)
    {

        $keyword = $request->input('keyword');
        if (!empty($keyword))
        { 
            $reviews = Review::where('title', 'like', '%' . $keyword . '%')
            ->orWhere('text', 'like', '%' . $keyword . '%')
            ->orWhereHas('tags', function ($query) use ($keyword){
                $query->where('tag_name', 'like', '%' . $keyword . '%');
            })
            ->paginate(10);
        } else {
            return redirect('/');
        }

        return view('reviews.search', [
            'keyword' => $keyword,
            'reviews' => $reviews
        ]);
    }
}
```
個人的にポイントは下記です。

* まずwhereメソッドでreviewテーブルのtitleフィールドで検索かける
* orWhereメソッドでtextにも検索かける
* orWhereHasでreviewテーブルにとって多対多の関係にあるtagsテーブルにアクセスし検索をかける
* where、orWhere、orWhereHasの第２パラメータにlike検索の条件設定をする
* %記号で前後に検索キーワードの前後に何があってもOKなので、その検索キーワードが引っかかるようになります
* %を''で囲うのはwhereがパラメータ結合に対応していないため

#おしまい
もしご指摘やご質問、うまくいかなかったなどしたら、お気軽にコメントください！
python-pptxでA4サイズ

pythonでパワポ報告書を(自動)生成するための小技

`python-pptx`ではインチで扱うのが便利。
なので、A4サイズ==11.69 inch x 8.27 inchを使う。

(python-pptxは長さにEnglish Metric Units (EMU)という単位を使っている。これをインチ変換するメソッドが、pptx.util.Inchesである。）

```python
from pptx import Presentation
from pptx.util import Inches

prs = Presentation()

prs.slide_height=Inches(11.69)
prs.slide_width=Inches(8.27)

prs.save("./hoge.pptx")
```

これで、一応作れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/6a3b5f48-e656-9a87-2593-4911c58100ec.png)

ここに、タイトルのスライドレイアウトと白紙のスライドレイアウトを貼り付けるなら、

```python
from pptx import Presentation
from pptx.util import Inches

prs = Presentation()

prs.slide_height=Inches(11.69)
prs.slide_width=Inches(8.27)

# タイトルスライド
title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)

title = slide.shapes.title
subtitle = slide.placeholders[1]
title.text = "Hello, World!"
subtitle.text = "python-pptx was here!"

# 白紙のスライド
blank_slide_layout = prs.slide_layouts[6]
slide = prs.slides.add_slide(blank_slide_layout)

prs.save("./hoge.pptx")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/5f744283-bfcf-408a-305c-6d7c43bb352d.png)


となる。

# 参考
[python-pptx 0.6.18 documentation](https://python-pptx.readthedocs.io/en/latest/user/quickstart.html#add-textbox-example)
Laravel php　アウトプット

# __constructメソッド,authorizeResourceメソッド
### __constructメソッド
PHPのクラスでは、__constructメソッドを定義すると、クラスのインスタンスが生成された時に初期処理として特に呼び出さなくても必ず実行されます。
### authorizeResourceメソッド
authorizeResourceメソッドの第一引数には、モデルのクラス名を渡します。
(なお、第一引数に渡したArticle::classは'App/Article'という文字列を返すので、第一引数には直接'App/Article'を渡しても構いません)
第二引数には、そのモデルのIDがセットされる、ルーティングのパラメータ名を渡します。
![スクリーンショット 2020-10-15 11.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663122/392fa27b-305e-9780-0b5d-cc2fbf3f6050.png)
「cannot import name xxx」の時の対処法【Python】

はじめまして、ますみです！

[![自己紹介.png](https://www.umi-mori.jp/wp-content/uploads/2023/02/introduction_banner_2-2048x533.png)](https://bit.ly/banner_intro_masumi_creator_qiita)


importの段階で以下のようにコケるバグ（`ImportError: cannot import name 'convert'`）があったため、本記事ではその対処法を紹介します。
この記事では、`docx2pdf`というパッケージについて話していますが、他のパッケージでも同様のバグが生じるため、そのような方々のためにもなったら、幸いです。

```python:

Traceback (most recent call last):
  File "docx2pdf.py", line 5, in <module>
    from docx2pdf import convert
  File "/Users/xxx.py", line 5, in <module>
    from docx2pdf import convert
ImportError: cannot import name 'convert'
```

# 対処法
結論から言うと、docx2pdfというパッケージをインポートしようとしているのに、Pythonのスクリプト名を`docx2pdf.py`という名前にしていたのが原因でした。予約語は変数として使えないのと似たバグで、用いるパッケージ名は、ファイル名としては使えないということです。

そのため、ファイル名を`docx2pdf.py`から`main.py`に変更したら、無事実行することができました。

# 最後に
最後まで読んでくださり、ありがとうございました！
いかがだったでしょうか？

この記事を通して、少しでもあなたの学びに役立てば幸いです！

:::note info
【仕事の相談はこちら】
お仕事の相談のある方は、下記のフォームよりお気軽にご相談ください。

[問い合わせフォームはこちら](https://forms.gle/G5g1SJ7BBZw7oXYA7)

もしもメールでの問い合わせの方がよろしければ、下記のメールアドレスへご連絡ください。

info*galirage.com（*を@に変えてご送付ください）

🎁 「生成AI活用の無料相談券」もしくは「生成AIの社内ガイドライン（無料PDF）」を『公式LINE』で配布中 🎁
『生成AIを業務に活用したいけど、どうしたらいいかわからない』といった声を多くいただきます。

Galirageでは公式LINEにて、チャットやオンライン会議で「完全個別の生成AI活用無料相談会」を実施しております！
（期間限定で実施しているため、ご興味ある方はお早めに以下のLINE公式アカウントをご登録ください^^）
https://lin.ee/rvz6lMN

※ 予告なく、キャンペーンを終了する可能性がございますが、ご了承ください。

【業務内容】
具体的には、以下のお仕事を中心に受け付けております！（[詳しくはこちら](https://galirage.notion.site/Galirage-AI-c2f3945fafb0433d8d2fd03e56927fd8)）
1. 受託開発（例：生成AIを使った社内システムの開発）
2. コンサルティング（例：技術戦略のアドバイス）
3. 講演（例：社内研修、イベント登壇）

※ 特に「生成AIを使ったシステム開発のご依頼」が多く、ご好評いただいております。

【これまでの相談事例】
以下のようなご相談が多くあります。

🔑 機密情報を漏洩させないための、生成AIのシステム構築をお願いしたい。
🤖 自社データを用いたFAQチャットボットの作り方を知りたい。
💡 ChatGPTを、自分たちの事業にどのように活かせるか、アドバイスやアイデアが欲しい。
:::
# おまけ
エンジニアの仲間（データサイエンティストも含む）を増やしたいため、公式LINEを始めました🎉

「**一緒に仕事をしてくれる方**」「**友だちとして仲良くしてくれる方**」は、友だち追加をしていただけますと嬉しいです！（仲良くなった人たちを集めて、「ボードゲーム会」や「ハッカソン」や「もくもく会」もやりたいなと考えています😆）

とはいえ、みなさんにもメリットがないと申し訳ないので、特典を用意しました！

友だち追加後に、アンケートに回答してくれた方へ「**エンジニア図鑑（職種20選）**」のPDFをお送りします◎

https://lin.ee/hFUN4TL

[![](https://www.umi-mori.jp/wp-content/uploads/2023/10/line_banner_v2.png)](https://lin.ee/hFUN4TL)
Dockerの概要（初学者向け）

# はじめに
Dockerは多くのIT開発企業で導入されている技術です。
エンジニアを目指す方の多くは今後使用することとなるため、学習した内容を簡単にまとめようと思います。

# Dockerとは？
一言で言うと、環境構築を楽にさせるものです。
通常、アプリケーションを開発する際は、環境構築から始まります。
環境構築をする時はいくつものパッケージをダウンロードします。
その際、エラーが出て、トラブルシュートしたりと大変な作業となり、
これをチームメンバー全員が行うことになります。
また、開発環境、テスト環境、本番環境でも環境構築を気に掛ける必要があります。
Dockerではコンテナを起動するだけで環境構築が完了するため、環境構築が非常に楽になります。

# コンテナとは？
通常、コンテナと言うものは内部にものを入れることができる容器のことです。
Dockerでのコンテナは、自身のPCやサーバーに多数作成でき、開発環境や実行環境、パッケージ、ライブラリをインストールすることができる箱のようなものです。
コンテナの中で作業したり、コンテナを使ってスクリプトを動かすことができます。
一つコンテナを作れば、それを誰かに渡したり、テスト環境や本番環境に渡したりすることができます。

# コンテナの作り方
Docker file　=>　Docker image　=>　コンテナ

Docker fileを作成し、そこからDocker imageを作成します。
このDocker imageからコンテナを作成することができます。

# Docker Hub
多くのパッケージはDocker Hubの中に用意されています。
Gitで言うGit Hubのようなものです。
Docker imageをpublicで管理する時にDocker Hubを使い、
Docker imageをpullすることで、コンテナを作成することができます。

# 参考
Udemy
>かめれおん講師　「米国AI開発者がゼロから教えるDocker講座」
>>https://www.udemy.com/share/103aTRAEAdd1pTTHoC/

有料ですが、初学者の私にも非常に理解しやすかったです。

# 最後に
本投稿が初学者の復習の一助となればと幸いです。
元自衛官実務未経験から受託開発企業から内定もらうまで

今回の記事はタイトル通り実務未経験から企業から内定もらうまで私がどんなことをしたのかを紹介します。
予め言いますがこれが私個人の経験からですのであくまで参考に、、、

#大まかな筋道
海軍将校になりたくて海自入る->こんな仕事もう嫌ｧｧｧ
↓
辞めた
↓
なんか稼げる仕事ないかな、、、（Youtube漁る）
↓
プログラミングって結構稼げるんだ
とりあえずエンジニア界隈でイケてたKB○Yさんを見習ってFlutterを独学で勉強
↓
挫折
↓
プログラミングスクール通う
なんとなくiOSコースを受講
割とできそうだった
↓
友達の大学生は就活真っ最中で自分も仕事したいと焦る
勉強会やスクールのメンターと話たりしてどんな方法が稼ぐのに最適か調べた
エンジニアとして一番稼げるのは個人で案件を獲得するいわゆるフリーランサー
じゃあiOSの案件ってどんなのあるの
実務経験者募集がほとんど。応募してみてもやっぱダメみたい。
自分がどんなことできるのかアピールできるものが必要->ポートフォリオ
これを宣伝してアピールできないかな
↓
ムリだった、、笑
じゃあ仕事するか。技術磨いてまた挑戦しよう。1ヶ月間だけ就活しようムリなら東京出て頭下げまくってお願いしよう
↓
ここでも実務経験が必要なとこがほとんど。
エージェントやポートフォリオ作っても書類選考も通れない
通れても御堅い企業やSlerとか。もっと自由な働き方したい
↓
Indeedでたまたま上にでできた企業に応募。
とりあえず面接へ。
良さげな雰囲気、後日面接。なんとその後会食がしたいと連絡。
7割受かったと喜びいざ当日。面接というか企業情報を聞いただけその後焼肉奢ってもらった。
無事内定。


#実際こんな感じ
よくこの職場で働きたいからこの言語で勉強みてみようって目にしますが、実際自分の行きたい会社に入れるのなんて奇跡に近いってか奇跡w
全てタイミングと運でしかなく就活中は「本当に会社行けんのか」って不安でしかたなかった。
先が見えない違業界からの転職ってこんな大変なんだって思い知らされましたね、、、
でも絶対どっか雇ってくれるところはあるし、技術がなくてもなんとかなるって精神はほんとに大事でしたね。

毎日４通は違う企業にメールしてたしフレームはあったけどちゃんと毎回違う志望動機でした。（簡単そうに見えて４つ書くのに企業研究含め３、４時間かけてましたね💦）
送っても返事は帰って来ないことがほとんどだし心折れかけましたw

#こんなことしてみては、、、？
私の失敗からこれからエンジニアを目指す方に聞いて欲しいのは、なぜエンジニアを目指しているのか明確にすることですね。
まずprogateとかオンラインスクールに入る前に考えて欲しいです。
エンジニアになって何がしたいのか、どんなエンジニアになっていたいか、本当にエンジニアになりたいのか。など

私がエンジニアを目指したのは、この職業が稼げると思ったからです。
実際に稼いでいる方はいますし情報社会で職業がなくなることはほぼないです。
勉強会やエンジニアの方とお話しした中で感じたのは、エンジニアとして稼ぐにはプログラムと〇〇です。
この〇〇はマーケティングや営業、企画や人脈、、、など様々。
どんなものでもどんな人でもチャンスは巡ってます。
でもどんな才能があってめちゃくちゃプログラミングができてもコミュ障じゃ売れないんです。

何が言いたいかというと目標がないとやっていけません。
あの人になりたいとかこれがしたいからとかも大事ですが、一番大事なのは「この夢はプログラミングがないとできないわ」って明確な目標。
これめちゃくちゃ難しいです。
でもこの目標があれば面接で強いし挫けかけても立ち直れると思います。
僕はこれを考えるまで苦労しました。

#最後に
これをみているみなさんがなってよかったと思えるエンジニアになれるよう願っています。
手を動かすのも大事ですが、休憩も大事です。
かのワンピースのミホークも
![B-sQQnNW0AEy8kz.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679429/18d5cce4-746d-6ffc-4fe0-fc6f4c2fc9ce.jpeg)
って言ってます。
休みながらやっていきましょう。。。。



------------------
めんどくさくて確認してないので誤字脱字や脈絡のない文章であるかと思いますが、そっとコメントで教えてあげてください。
もしくは、見て見ぬふりでお願いします( ˘ω˘)ｽﾔｧ

------------------
化学反応でルンゲクッタ

#ルンゲクッタ法
オイラー法に比べて良い近似解を与える(?)数値解法
やっていることはオイラー法の発展形なので恐れる必要はない



##ルンゲクッタ法の解法
次の漸化式を解く
$h$は刻み幅、$ \ f(t, y)=\frac{dy}{dt}  $である

```math
y_{n+1}=y_{n}+\frac{h}{6}(k_{1}+2k_{2}+2k_{3}+k_{4}) \\
```
ただし、

```math
\begin{align}
k_{1}&=f(t_{n},y_{n})=-ky_{n} \\
k_{2}&=f(t_{n}+\frac{dt}{2},y_{n}+\frac{dt}{2}k_{1})=-k(y_{n}+\frac{dt}{2}k_{1})　\\
k_{3}&=f(t_{n}+\frac{dt}{2},y_{n}+\frac{dt}{2}k_{2})=-k(y_{n}+\frac{dt}{2}k_{2}) \\
k_{4}&=f(t_{n}+dt,y_{n}+dtk_{3})=-k(y_{n}+k_{3})
\end{align}
```
#化学反応のシミュレーション
物質Aが一次反応で消失していく場合を考える

```math
\frac{d[A]_{n}}{dt} = -k[A]_{n}
```

上記の化学反応に当てはめると、$k$は次のように表せる

```math
\begin{align}
k_{1}&=f(t_{n},y_{n})=-k[A]_{n} \\
k_{2}&=f(t_{n}+\frac{dt}{2},y_{n}+\frac{dt}{2}k_{1})=-k([A]_{n}+\frac{dt}{2}k_{1})　\\
k_{3}&=f(t_{n}+\frac{dt}{2},y_{n}+\frac{dt}{2}k_{2})=-k([A]_{n}+\frac{dt}{2}k_{2}) \\
k_{4}&=f(t_{n}+dt,y_{n}+dtk_{3})=-k([A]_{n}+k_{3})
\end{align}
```
pythonコードはこうなる

```python:runge.py
A=1
log=[A]

for _ in range(step):
    k1=-k*A
    k2=-k*(A+k1/2*h)
    k3=-k*(A+k2/2*h)
    k4=-k*(A+k3*h)
    A=A+h/6*(k1+2*k2+2*k3+k4)
    log.append(A)
```



#結果
以下のコードを実行

```python:main.py
import math
import matplotlib.pyplot as plt

#初期値・定数記述
A=1
AA=1
AAA=1

h=3
k=0.5
step=10

log=[A]
log2=[AA]
log3=[AAA]

for _ in range(step):
    A=A*(1-k*h)
    log.append(A)

    AA=AA*(1-k*h/2)/(1+k*h/2)
    log2.append(AA)

    k1=-k*AAA
    k2=-k*(AAA+k1/2*h)
    k3=-k*(AAA+k2/2*h)
    k4=-k*(AAA+k3*h)
    AAA=AAA+h/6*(k1+2*k2+2*k3+k4)
    log3.append(AAA)

plt.plot([i for i in range(step+1)],[math.e**(-k*t*h) for t in range(step+1)],label="Exact_solution")
plt.plot([i for i in range(step+1)],log,label="Euler")
plt.plot([i for i in range(step+1)],log2,label="Modified-Euler")
plt.plot([i for i in range(step+1)],log3,label="runge")
plt.legend()
```

![ダウンロード (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476342/46e9eccb-e048-3754-a205-7c9f9fddc126.png)

オイラー法は誤差がでかくなりすぎて発散しかけてる
修正オイラー法とルンゲクッタ法の性能差を知りたいならもっと複雑な式の方がよさそう

#まとめ
前回のオイラー法に続いてルンゲクッタ法をやった
よく分からないけど陽的に解くにはこれが最強?
画像を複数件保存・表示する


##実装したい事

画像実装機能は実装済みで、複数件の写真を保存・表示させる。

###1.モデルのアソシエーション変更
変更前

```
class Scene < ApplicationRecord
  belongs_to :user
  has_one_attached :image

 省略

end
```

変更後

```
class Scene < ApplicationRecord
  belongs_to :user
  has_many_attached :images

 省略

end
```

###2.コントローラーの変更

変更前

```
class ScenesController < ApplicationController

  def new
    @scene = Scene.new
  end

  def create
    @scene = Scene.new(scene_params)
    if @scene.save
      redirect_to root_path
    else
      render :new
    end
  end
  def show
    @scene = Scene.find(params[:id])
  end

  private
  def scene_params
    params.require(:scene).permit(:name, :user_name, :comment, :image).merge(user_id: current_user.id)
  end
end
```

変更後

```
class ScenesController < ApplicationController

  def new
    @scene = Scene.new
  end

  def create
    @scene = Scene.new(scene_params)
    if @scene.save
      redirect_to root_path
    else
      render :new
    end
  end
  def show
    @scene = Scene.find(params[:id])
  end

  private
  def scene_params
    params.require(:scene).permit(:name, :user_name, :comment, image: []).merge(user_id: current_user.id)
  end
end
```

##3.ビューの変更
###投稿ページ
変更前

```
  <%= form_with model: @scene, local: true do |f| %>
   <div class="img-upload">
      <div class="weight-bold-text">
        現場画像
        <span class="indispensable">必須</span>
      </div>
      <div class="click-upload">
        <p>
          クリックしてファイルをアップロード
        </p>
          <%= f.file_field :image, id:"item-image"%>
      </div>
    </div>
省略
<% end %>
```

変更後

```
 <%= form_with model: @scene, local: true do |f| %>
   <div class="img-upload">
      <div class="weight-bold-text">
        現場画像
        <span class="indispensable">必須</span>
      </div>
      <div class="click-upload">
        <p>
          クリックしてファイルをアップロード
        </p>
          <%= f.file_field :image, multiple: true , id:"item-image"%>
      </div>
    </div>
省略
<% end %>
```

###閲覧ページ
変更前

```
省略
<%= image_tag image %>
省略
```

変更後

```
<% @scene.image.each do |image| %>
  <%= image_tag image %>
<% end %>
```

![写真.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/793046/e08fe33c-34ea-c4b3-1b4e-22628246effb.png)

上記の変更点で、複数件の写真の投稿・表示が可能となりました。

##今後について

写真の表示方法が横並びにしているだけなので、間隔を空けながらビューファイルを整理する。
UIAlertViewControllerをpresentで表示中はUINavigationControllerのスタックを更新できない

複数のUIAlertViewControllerがキューイングされたうえで同時にpresentされるようなイベントがあり、その時に表題の仕様を知らずハマりました。

##ハマった一例

~~~.swift
    // ①イベントの例外処理等で呼ばれるアラート
    func showCancelOperationDialog() {
        
        let alertController = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
        // OKアクション
        let defaultAction: UIAlertAction = UIAlertAction(title: "OK", style: .default, handler: { _ in
            
            self.moveToFirstViewController()
        })
        // キャンセルアクション
        let cancelAction: UIAlertAction = UIAlertAction(title: "キャンセル", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        alertController.addAction(defaultAction)
        present(alertController, animated: true, completion: nil)
    }
    
    // ②特定のエラーで呼ばれるアラート
    func showExceptionErrorDialog() {
        
        let alertController = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
        // OKアクション
        let defaultAction: UIAlertAction = UIAlertAction(title: "OK", style: .default, handler: nil)
        // キャンセルアクション
        let cancelAction: UIAlertAction = UIAlertAction(title: "キャンセル", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        alertController.addAction(defaultAction)
        present(alertController, animated: true, completion: nil)
    }
    
    // 特定のViewControllerへ戻る処理
    func moveToFirstViewController() {
        
        guard let firstViewController = self.navigationController?.viewControllers.first as? FirstViewController else {
            
            return
        }
        self.navigationController?.popToViewController(firstViewController, animated: true)
    }
~~~

上記のアラート2種が同時に呼び出され、①`イベントの例外処理等で呼ばれるアラート` -> ②`特定のエラーで呼ばれるアラート`の順で実行された場合、①のOKアクションで`popToViewController`が行われません。正確には呼び出しされているのですが表題の通り、presentで表示中はUINavigationControllerのスタックを更新できないため、画面遷移が行われません。

## 回避策
任意のViewControllerに遷移してからアラートを表示させるようにしました。
例外処理としての画面遷移なので遷移 -> アラート表示の順が好ましいですね。
【TIPS】xcenv と Carthage の連携

Xcodeのバージョンを複数持ち、プロジェクトに応じて切り替えてる場合、いちいち `xcode-select` で切り替えるのも可能ですが面倒くさいので、`rbenv` と同じ感覚でプロジェクトの Xcode バージョンを固定できる [xcenv](https://github.com/xcenv/xcenv) がとても便利です。

ところが、xcenv は直接 `DEVELOPER_DIR` 変数を設定してるのではなく Shims を使ってるので、Shims に対応していない Carthage に適用できません。例えば `xcode-select` で設定してる OS デフォルトの Xcode のバージョンが 12 だけど、このプロジェクトだけ 11 を使ってる場合、`xcenv local 11` でこのプロジェクトの Xcode バージョンを 11 に固定できますが、Carthage はこの設定をそのまま流用できないので、結局 OS のデフォルトである 12 でビルドしちゃうから、Swift Compiler のバージョン不一致でプロジェクトのビルドができません。Carthage も 11 でビルドしたい場合は、下記のように手動で `DEVELOPER_DIR` 変数を Xcode 11 のパス（この例では `/Applications/Xcode 11.app` のパス）を設定してビルドする必要があります：

```bash
$ DEVELOPER_DIR=/Applications/Xcode 11.app/Contents/Developer carthage bootstrap
```

`xcenv` から一応設定してる Xcode のパスを取得できますが、そのまま `xcenv version` を実行すると余計な情報も含まれてしまいます：

```bash
$ xcenv version
/Applications/Xcode 11.app (set by /Path/To/Project/.xcode-version)
```

もちろんこれで `sed` とかで余計な文字列を消してもいいです（というか筆者も最初はそのアプローチでした）が、xcenv のソースコード読んでみたらどうやら [`xcenv version-name` という隠しコマンド](https://github.com/xcenv/xcenv/blob/master/libexec/xcenv-version-name)があることに気づいて、これを実行するとちゃんとパスだけ出力してくれます：

```bash
$ xcenv version-name
/Applications/Xcode 11.app
```

これを使うと、Carthage の実行はこんなふうに実行すればちゃんと xcenv が設定した Xcode のバージョンで実行してくれるのでとても便利です：

```bash
DEVELOPER_DIR=$(xcenv version-name)/Contents/Developer carthage bootstrap
```

p.s.
せっかくなので xcenv にそもそもこれを一時的に設定してコマンド実行する機能あるといいなと思って Issue 上げました：
https://github.com/xcenv/xcenv/issues/20
RDS for Postgresql での ERROR: canceling statement due to statement timeout の対処法

embulk-input-postgresql を用いたデータ吸い出しを行うときに `ERROR: canceling statement due to statement timeout` というエラーが発生することがあります。

```
org.embulk.exec.PartialExecutionException: java.lang.RuntimeException: org.postgresql.util.PSQLException: ERROR: canceling statement due to statement timeout
	at org.embulk.exec.BulkLoader$LoaderState.buildPartialExecuteException(BulkLoader.java:340)
```

psqlにて再現してみましょう。embulk経由と同様に、1分経ったところでクエリが中断されました。
何らかのサーバ側のタイムアウト処理で止められています。

```sql
> psql
psql (10.14 (Ubuntu 10.14-0ubuntu0.18.04.1), server 11.1)
WARNING: psql major version 10, server major version 11.
         Some psql features might not work.
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

test_server=> SELECT
test_server->   ...snip... 
test_server-> FROM
test_server->   foo_bar
test_server-> WHERE
test_server->   ...何か重たいクエリ...
ERROR:  canceling statement due to statement timeout
```

statement_timeout の値を見てみましょう。やはり、1分でした。15分に今回は伸ばしてみます。
マイクロ秒で指定すると読みづらいので、文字列で指定すると楽です。

```sql
test_server=> SHOW statement_timeout;
 statement_timeout
-------------------
 1min
(1 row)

test_server=> SET statement_timeout to '15min';
SET

test_server=> SHOW statement_timeout;
 statement_timeout
-------------------
 15min
(1 row)
```

この設定はembulkには次のように記述します。
before_selectを使うことで、SELECT句と同じトランザクションで実行されます。

```yaml
in:
  type: postgresql
  host: {{ env.DB_HOST }}
  user: {{ env.DB_USER }}
  password: {{ env.DB_PASSWORD }}
  ssl: true
  database: {{ env.DB_DATABASE }}
  default_timezone: UTC
  query: |
    SELECT
      ...
  before_select: SET statement_timeout to '15min';
```

私の場合はリードレプリカにてこの現象を見ました。
何かお役に立てると幸いです。
iPhone 12 まとめ

## 比較

iPhone12Pro/ProMaxはLiDARあり

| Product | RAM | CPU | Size |
| --- | --- | --- | --- |
| iPhone 12 mini | 4GB | A14 Bionic | 5.4 inch | 
| iPhone 12 | 4GB | A14 Bionic | 6.1 inch |
| iPhone 12 Pro | 6GB | A14 Bionic | 6.1 inch |
| iPhone 12 Pro Max | 6GB | A14 Bionic | 6.7 inch |
| iPhone 11  | 4GB |
| iPhone 11 Pro  | 4GB | A13 Bionic |
| iPhone 11 Pro Max | 4GB |
Elasticsearch > Logstash > _ID を任意な値に設定


document_id => に任意の値を設定でOK

```
output {
    elasticsearch { 
        document_id => "%{some_id_field}"
    }
}
```

実際の設定は以下のような感じになる

```
output {
  elasticsearch {
    document_id => "%{some_id_field}" # _IDをsome_id_fieldとする
    hosts => ["http://elasticsearch:9200/"]
    user => "elastic"
    password => "xxxxx"
    index => "some_index"
    ...
  }
}

```



参考

[How does logstash generate '_id' when the outputting to elastic search? - Elastic Stack / Logstash - Discuss the Elastic Stack](https://discuss.elastic.co/t/how-does-logstash-generate--id-when-the-outputting-to-elastic-search/53722)
P5千锋Java教程：059.GitLab 使用-HTTP

看到了这个视频 P5

千锋Java教程：059.GitLab 使用-HTTP

07:41 才知道群组和项目的区别。哎呀，太谢谢老师讲课了，辛苦了。

找了半天看到这个，网上的资料说了半天没看明白，这下子我算是明白了，

而且我项目用的是PM的账号和密码。也是用的TortoiseGit，，老师也是用的这个，这样一看一下子全明白了。

在日本搭建的GitLab的环境，看网站上全是英文，又搞不懂Group和Project的区别。

看了这个视频彻底明白了。。。。。。。。。。。。。。。。！！

 
P5千锋Java教程：059.GitLab 使用-HTTP
 

 

https://www.bilibili.com/video/BV1HJ41197rd?p=5
[vue.config.js]devServerのproxyが動作しない

各所で書かれている方法で、proxyを記述していました。

```javascript
module.exports = {
    devServer: {
        port: 8888,
        proxy: {
            '/api/': {
                target: 'http://localhost:8081'
            }
        }
    }
};
```

久しぶりに起動すると、何故かproxyが動作しない。
`port: 8888` は読み込まれていたので、ファイルの置き場所などが原因ではないみたい。

#### 原因調査
まずは情報が欲しいので、 `logLevel: 'debug'` を仕込みます。

```javascript

        proxy: {
            '/api/': {
                target: 'http://localhost:8081',
                logLevel: 'debug'
            }
        }
```

起動

```
$ npm run serve
```

起動時のメッセージを確認。 Proxyがなんだか怪しいですね。

```
 INFO  Starting development server...
[HPM] Proxy created: [Function: context]  ->  http://localhost:8081
```

ググって辿り着いた様々な記事を見ると、 `[Function: context]` の部分には本来パスルールが入るはずです。

こんな感じ

```
[HPM] Proxy created: /api  ->  http://localhost:3000
```

> 引用 : https://www.yoheim.net/blog.php?q=20170803

次に、 `pathRewrite` を設定するのが良いという方法を見つけた

> 引用 : https://forum.vuejs.org/t/devserver-proxy-in-vue-config-js-not-working/87316

早速やってみる。頭に `^` を付与し、pathRewriteにて外したものを定義する

```javascript
        proxy: {
            '^/api/': {
                target: 'http://localhost:8081',
                logLevel: 'debug',
                pathRewrite: { "^/api/": "/api/" }
            }
        }
```

この状態で起動。proxyが動いていそうです。

```
[HPM] Proxy rewrite rule created: "^/api/" ~> "/api/"
```

アクセスしてみる。proxyが動作しました。

```
[HPM] GET /api/get_user_list?user_id=1 -> http://localhost:8081
```
Java の Stream で List を List<String> に変換するサンプルコード

```java
// List に入れる要素のクラス
public class MyData {

  public final String name;
  public final Integer age;

  public MyData(String name, Integer age) {
    this.name = name;
    this.age = age;
  }

  public String getMyInfo() {
    return name + "(" + age + ")";
  }
}
```

```java
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class Main {

  public static void main(String[] args) {

    // データを構築
    List<MyData> list = new ArrayList<>() {
      {
        add(new MyData("Alice", 88));
        add(new MyData("Bob", 8));
        add(new MyData("Carol", null));
        add(null);
      }
    };

    // 変換例1
    List<String> list1 = list.stream() // Stream オブジェクトを生成
      .filter(Objects::nonNull)        // 要素が null のものを排除
      .map(MyData::getMyInfo)          // 要素ごとに文字列を生成
      .collect(Collectors.toList());   // List 化
    System.out.println(String.join("\n", list1));

    // 変換例2
    List<String> list2 = list.stream()                // Stream オブジェクトを生成
      .filter(Objects::nonNull)                       // 要素が null のものを排除
      .map(mydata -> mydata.name + ": " + mydata.age) // 要素ごとに文字列を生成
      .collect(Collectors.toList());                  // List 化
    System.out.println(String.join("\n", list2));

    // 変換例3
    List<String> list3 = list.stream() // Stream オブジェクトを生成
      .filter(Objects::nonNull)        // 要素が null のものを排除
      .map(mydata -> {                 // 要素ごとに文字列を生成
        if (mydata.age == null) {
          return mydata.name;
        } else {
          return mydata.name + ": " + mydata.age;
        }
      })
      .collect(Collectors.toList());   // List 化
    System.out.println(String.join("\n", list3));
  }
}
```

Java 15 (AdoptOpenJDK 15+36) による実行結果。

```
$ javac *.java
$ java Main
Alice(88)
Bob(8)
Carol(null)
Alice: 88
Bob: 8
Carol: null
Alice: 88
Bob: 8
Carol
```

参考: [Stream \(Java Platform SE 8 \)](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html)
GithubのBLM活動について【Github】

はじめまして、ますみです！

[![自己紹介.png](https://www.umi-mori.jp/wp-content/uploads/2023/02/introduction_banner_2-2048x533.png)](https://bit.ly/banner_intro_masumi_creator_qiita)


流れるように新しいレポジトリを作成した後、add/commitし、最後にpushしようとしたところ以下のようなエラーが出て、コケてしまいました、、、。

```zsh:
% git push origin master
error: src refspec master does not match any
error: failed to push some refs to 'https://github.com/Masumi-M/xxx'
```

# 原因究明
まずbranchを`git branch -a`により、表示してみましょう。

```zsh:
% git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
```

驚いたことに、branchがmasterではなく、`main`に、、、？
どうやら2020年10月からデフォルトブランチが`master`から`main`になったらしいです。

# デフォルトブランチ変更の背景
ちなみに、Githubがこの変更を導入した背景には、**Black Lives Matter（BLM）**があり、**master**は、**マスター・スレーブ**を連想するため、mainに変更されたそうです（納得感もあって、素敵な活動ですね😭）。

# 対処法
そのため、以下のようにmainにpushすれば一件落着です！

```zsh:
% git push origin main
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 8 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 10.76 KiB | 10.76 MiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To https://github.com/Masumi-M/xxx
   51929ba..cf7f284  main -> main
```

# 最後に
最後まで読んでくださり、ありがとうございました！
いかがだったでしょうか？

この記事を通して、少しでもあなたの学びに役立てば幸いです！

:::note info
【仕事の相談はこちら】
お仕事の相談のある方は、下記のフォームよりお気軽にご相談ください。

[問い合わせフォームはこちら](https://forms.gle/G5g1SJ7BBZw7oXYA7)

もしもメールでの問い合わせの方がよろしければ、下記のメールアドレスへご連絡ください。

info*galirage.com（*を@に変えてご送付ください）

🎁 「生成AI活用の無料相談券」もしくは「生成AIの社内ガイドライン（無料PDF）」を『公式LINE』で配布中 🎁
『生成AIを業務に活用したいけど、どうしたらいいかわからない』といった声を多くいただきます。

Galirageでは公式LINEにて、チャットやオンライン会議で「完全個別の生成AI活用無料相談会」を実施しております！
（期間限定で実施しているため、ご興味ある方はお早めに以下のLINE公式アカウントをご登録ください^^）
https://lin.ee/rvz6lMN

※ 予告なく、キャンペーンを終了する可能性がございますが、ご了承ください。

【業務内容】
具体的には、以下のお仕事を中心に受け付けております！（[詳しくはこちら](https://galirage.notion.site/Galirage-AI-c2f3945fafb0433d8d2fd03e56927fd8)）
1. 受託開発（例：生成AIを使った社内システムの開発）
2. コンサルティング（例：技術戦略のアドバイス）
3. 講演（例：社内研修、イベント登壇）

※ 特に「生成AIを使ったシステム開発のご依頼」が多く、ご好評いただいております。

【これまでの相談事例】
以下のようなご相談が多くあります。

🔑 機密情報を漏洩させないための、生成AIのシステム構築をお願いしたい。
🤖 自社データを用いたFAQチャットボットの作り方を知りたい。
💡 ChatGPTを、自分たちの事業にどのように活かせるか、アドバイスやアイデアが欲しい。
:::
# おまけ
エンジニアの仲間（データサイエンティストも含む）を増やしたいため、公式LINEを始めました🎉

「**一緒に仕事をしてくれる方**」「**友だちとして仲良くしてくれる方**」は、友だち追加をしていただけますと嬉しいです！（仲良くなった人たちを集めて、「ボードゲーム会」や「ハッカソン」や「もくもく会」もやりたいなと考えています😆）

とはいえ、みなさんにもメリットがないと申し訳ないので、特典を用意しました！

友だち追加後に、アンケートに回答してくれた方へ「**エンジニア図鑑（職種20選）**」のPDFをお送りします◎

https://lin.ee/hFUN4TL

[![](https://www.umi-mori.jp/wp-content/uploads/2023/10/line_banner_v2.png)](https://lin.ee/hFUN4TL)
# 参考文献

https://www.gizmodo.jp/2020/06/github-to-remove-master-and-slave-coding-terms-widely-s.html

https://japan.zdnet.com/article/35155289/
簡単にコストを節約して Web サイトを構築する方法

ブログと言えば、WordPress がとても有名で、WordPress で企業サイトを構築しているところもあるほどです。しかし、WordPress の運営をした経験がある方ならご存知の通り、WordPress は運用・維持の手間が非常にかかります。

そこで、今回は、簡単にコストを節約して Web サイトを構築する方法についてご紹介したいと思います。

## WordPress の課題

### セキュリティ

ブログと言えば、WordPress と言われるほど、シェアのある WordPress ですが、それゆえ、攻撃の対象にもなります。WordPress の提供側も脆弱性への対策を行っていますが、こういったことはいたちごっこになりがちですし、そもそも、脆弱性への対策がされた場合でもアップデートが必要になります。

### アップデート

WordPress 自体のアップデートに加えて、プラグインのアップデートも自動的にできるようになっています。しかし、WordPress の運営をした経験がある方ならご存知の通り、プラグインの相性というものがあります。私自身、アップデートをした結果、自分の管理している WordPress のサイトを真っ白（＝表示エラー）にした経験があります。

## 課題をまとめると

* シェアがあるために攻撃の対象になりやすい
* アップデートの際に、プラグインとの相性問題で、自動アップデートすることが実質できない

## WordPress の課題への対策

対策として、エンジニアの間では、以前から利用が広まっているのが静的サイトジェネレーターによるサイト構築です。

## サイトをどこで運用するか？

まっさきに思いつくのは GitHub ですが、[こちら](https://docs.github.com/ja/free-pro-team@latest/github/working-with-github-pages/about-github-pages/)にある通り、コストを節約しようと思うと、パブリックにしなければなりません。

パブリックでも差し支えないならいいのですが、実業務（＝プロダクション環境）など要件によってはパブリックでは困るときがあります。

そういった場合に候補になるのが、[Blob Storage](https://azure.microsoft.com/ja-jp/services/storage/blobs/?WT.mc_id=AZ-MVP-5001601) です。

実業務（＝プロダクション環境）でも使っていますが、特に困ったことに遭遇したことはなく、コストの大幅削減を享受して助かっています。

使い方は[公式サイト](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-static-website/?WT.mc_id=AZ-MVP-5001601)に詳細かつ画像付きで具体的に書いているのでそちらをご覧ください。

## 参考
* [Azure Blob Storage | Microsoft Azure](https://azure.microsoft.com/ja-jp/services/storage/blobs/?WT.mc_id=AZ-MVP-5001601)
* [Azure Storage での静的 Web サイト ホスティング | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-static-website/?WT.mc_id=AZ-MVP-5001601)
[基本情報技術者試験]ユークリッドの互除法のアルゴリズムをPythonで書いてみた。

# 概要
- 基本情報技術者試験の午後の試験でアルゴリズムがあります。過去問を解いても理解ができません…。実際にアルゴリズムをPythonで書いて、理解を深めていきたいと思います。

- まず最初は**ユークリッドの互除法**のアルゴリズムから書いてみます。

## ユークリッドの互除法
#### アルゴリズム
  - 二つの整数の大きい方から小さい方を引くことを、両者が等しくなるまで繰り返す。等しくなった値が最大公約数である。
  - GCMはGreatest Common Measure（最大公約数）

#### コード
```Python
# ユークリッドの互除法で最大公約数を求めるGCM関数
def GCM(A,B):
    # 繰り返し処理
    while A != B: # AとBが等しくなるまで繰り返す
        print("A=",A,"B=",B) # 途中の結果
        # 分岐処理
        if A > B: # AがBより大きいなら
            A = A - B # AにA-Bを格納する
        else:
            B = B - A # BにB-Aを格納する
    return A

print("実行結果：",GCM(84,60))
```
#### 実行結果
```
A= 84 B= 60
A= 24 B= 60
A= 24 B= 36
A= 24 B= 12
実行結果： 12
```

# まとめ
- 頭で考えるだけよりも、実際にプログラムを書いたほうが理解が深まった。
- 次回はうるう年のアルゴリズムを書こうかな

# 参考
- こちらの本のCHAPTER3 01ユークリッドの互除法を引用または参考にしました。
[情報処理教科書 基本情報技術者試験のアルゴリズム問題がちゃんと解ける本 第2版](https://www.shoeisha.co.jp/book/detail/9784798150468)
[Laravel] 残りのキューの数を調べる

Laravelでその時のキューの数を調べるには次のようにする。

```php
Queue::connection('キュー名')->size();
```

数の内訳について、バックエンドにRedisを使っている場合は[こちら](https://github.com/laravel/framework/blob/8.x/src/Illuminate/Queue/RedisQueue.php#L73)にある通り、通常のキューに加え:delayedと:reservedが付くキューも含まれる（下記参照）。

```php
    /**
     * Get the size of the queue.
     *
     * @param  string|null  $queue
     * @return int
     */
    public function size($queue = null)
    {
        $queue = $this->getQueue($queue);

        return $this->getConnection()->eval(
            LuaScripts::size(), 3, $queue, $queue.':delayed', $queue.':reserved'
        );
    }
```
[framework/RedisQueue\.php at 8\.x · laravel/framework](https://github.com/laravel/framework/blob/8.x/src/Illuminate/Queue/RedisQueue.php#L73)

:delayedと:reservedとは、mpywさんのQiitaにあるようにそれぞれ遅延ジョブとリトライジョブ用のキューである。

> queues:キュー名:delayed は発火時刻をスコア，値をジョブペイロードとする ZSET（ソート済みセット型）であり，以下のような処理が行われている。

> queues:キュー名:reserved に関しても同様で，こちらは遅延ジョブではなくリトライジョブが対象になる。発火時刻を算出するパラメータとして queue.connections.redis.retry_after で設定した秒数が用いられる。

[【Laravel】 Redis Queue Worker のソースコードリーディング \- Qiita](https://qiita.com/mpyw/items/74fdf9c57138d04e3023)

---

ちなみに`queues:キュー名`はリスト型となっているが、`queues:キュー名:delayed`はソート済みセット型となっている。中身を見たり数をカウントするRedisのコマンドは次の通り。

* 数のカウント
    * `llen queues:キュー名`
    * `zcard queues:キュー名:delayed`
* 中身を見る
    * `lrange queues:キュー名 0 -1`
    * `zrange queues:キュー名:delayed 0 -1`