OmniAICreator/Qiita-1.07M huggingface dataset:
Linuxで動作しているアーキテクチャの確認を行う方法

# はじめに

あれ？これ、なんのマシンで動かしてたっけ？ m1 macだったっけ？ あれ？

そうだ、アーキテクチャ調べたらわかる

# 環境

- Ubuntu 22.04

# 確認方法

```terminal
$ uname -m
aarch64
```

```terminal
$ uname -m
x86_64
```

# おまけ

- m1 mac + ubuntu 22.04 arm

```terminal
$ uname -a
Linux host1 5.4.0-150-generic #167-Ubuntu SMP Mon May 15 17:36:35 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux
```

- ubuntu 22.04 x86_64

```terminal
$ uname -a
Linux host2 5.15.0-73-generic #80-Ubuntu SMP Mon May 15 15:18:26 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
```

# さいごに

かんたんでしたね
Ruby optparse コマンドラインからオプション指定してプログラムを動かす

# はじめに

コマンドラインのオプションを扱うライブラリoptparseについてまとめます。

optparseを使うことで、以下のようにRubyプログラム実行時にオプションを追加することが出来ます。

~~~
ruby sample.rb -a 10
~~~

<br>

https://docs.ruby-lang.org/ja/latest/library/optparse.html


# 使い方

~~~sample.rb
require 'optparse'
opt = OptionParser.new

opt.on('-a') {|v| p v } # オプション'-a'追加

opt.parse!(ARGV)
p ARGV # => オプション'-a'の入力した値が表示される
~~~

:::note warn
オプション'-h'と'--help'はデフォルトで登録されているようです。
:::


`$ ruby sample.rb --help` または `$ ruby sample.rb -h`を実行すると登録されているオプションが確認できます。

~~~
$ ruby sample.rb -h 

[実行結果]
 => Usage: sample [options]
 => -a 
~~~

:::note info
説明文を追加するには
opt.on('-a', 'ここに説明文を書いてください')
:::


## パラメータの入力を強制する

> OptionParser#on メソッドのオプション定義で末尾に何かを書くと、そのオプションは引数を受け付けることの指定となります。

~~~
opt.on('-a VAL') # VALを追加

$ ruby sample.rb -a
# パラメータを省略して実行するとエラー
# missing argument: -a (OptionParser::MissingArgument)
~~~

## パラメータの入力が必須でない場合
> オプションの引数が必須でないことを示すには、" [" を付けます。
~~~
opt.on('-a [VAL]')

$ ruby sample.rb -a
# => nil
     []
~~~

# 参考ページ

https://maku77.github.io/ruby/io/optparse.html

https://qiita.com/bachikori/items/24b2a8aa8c48e89a24ad
Cognos Analytics の「Query Studio」「Analysis Studio」「Workspace」はいつまで使える？

# Cognos Analytics の「Query Studio」「Analysis Studio」「Workspace」はいつまで使える？
という質問を最近受けて回答しましたので、共有しておきます。

Cognos Analytics 11.2.4までとなります。
Cognos Analytics 12では、いよいよ使えなくなるという事ですね。

こちらのCognos Analytics 11.2.4の発表レターに記述があります。
**IBM Cognos Analytics with Watson 11.2.4 は、長期サポートを提供し、機能セットを強化し、パフォーマンスを向上させます**
https://www.ibm.com/common/ssi/ShowDoc.wss?docURL=/common/ssi/rep_ca/7/760/JAJPJP22-0467/index.html

<抜粋>
バージョン 11.2.4 (長期サポート) は、 IBM Cognos Query Studio、 IBM Cognos Analysis Studio、および IBM Cognos Workspace を含む最終リリースです。 Cognos Query Studio、 Cognos Analysis Studio、および Cognos Workspace のサポートは、現行リリースをもって終了となります。

こちらもご参照ください。
**Analysis StudioやQuery Studioとレポートやダッシュボードの機能比較**
https://www.ibm.com/docs/en/SSEP7J_11.2.0/pdf/as_qs_compare.pdf

**Analysis StudioやQuery Studioのレポートへの一括変換**
https://www.ibm.com/docs/ja/cognos-analytics/11.2.0?topic=reporting-bulk-conversion-queries-analyses

# 2023/6/8 追記
Cognos Analytics 12がリリースされ、マニュアルにしっかり記載されました。
**Deprecated and removed features in 12.0.x**
https://www.ibm.com/docs/en/cognos-analytics/12.0.0?topic=new-deprecated-removed-features-in-120x

# 2023/12/21 追記
Cognos Analytics 11.2.4までという話ですが、Cognos Analytics 11.2.4 FP2ではQuery Studio等がツールとして表示されず使用できないようです。
本当に最終バージョンは、11.2.4のFP無しという事のようなので、ここは注意が必要です。
Nukeの使い方 (ver.12.0ではNuke.loadImageが使えない)

# Nukeで画像を読み込みたいっ！
### 【背景】
題名からもある通り、Nukeは画像を読み込んで表示するライブラリなのですが、ネットを漁って使い方を調べると、
``Module 'Nuke' has no member named 'loadImage'``
(NukeにはloadImageメソッドが存在しないよ)
と言われる。
同僚に「なんで？」と聞いたら、「アプデで消えた」という返事をもらった。

調べても出てきやがらないので、とりあえず画像を表示したいという方の為に、必要最低限の書き方だけは共有します。(私のNuke歴が10分なので、、)
### 【環境】
**Nuke: ver.12.0**(ここ大事)
## 画像入力の方法
```swift
loadImage(
    with: 〇〇, //画像のURLの文字列 or URL型のurl
    into: ××   // どこへ代入するか
)
```
これで画像の表示ができました。
実際に動いたコードは、
```swift
import Nuke
import NukeExtensions
import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let url =
            URL(string: "https://webusstatic.yo-star.com/bluearchive_jp_web/fankit/162687961120015004/01.jpg")
//                       ↑このままでもいいし、好きなURLに変更してもOK
        loadImage(
            with: url,
            into: imageView
        )
    }
    @IBOutlet var imageView: UIImageView! //ご自身のImageViewとOutlet接続してね
}
//以下コピー不要
//https://bluearchive.jp/fankit/Precautions
```
___
#### 【念の為】
**Nukeは外部から読み込まないと使えない**ので、
SwiftPMとかで**導入しないとダメですよ**。
「``import Nuke``で読み込んどるやんけ」って言ってもダメですからね！
「何言うてるか分からん」って人は、[外部ライブラリを導入している記事](https://qiita.com/pe-pe-engineer/items/49047ecab051952508e9#%E8%83%8C%E6%99%AF)があるので、参考にしてください。
{私がやっていたやり方(エラーの出し方)という目次です}
た だ し、こちらで紹介しているのはNukeではなく、"SwiftLint"という今回の記事とは無関係のものなので、「なんか"SwiftLint"って書いているなぁ」と思った所は大抵
**SwiftLint → Nuke
と読み換えが必要なところです。適宜変更しましょう**。
紹介記事内で「URLで検索する」場面があると思うので、その時は
https://github.com/kean/Nuke
こっちのURLで検索すること。
でなければ**NukeではなくSwiftLintがインストールされる**ので。
![スクリーンショット 2023-06-01 11.33.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3375163/cf552ff0-ab1e-0920-4282-2faee8fe523d.png)
ここまで行けば、Add Packageを押してNuke導入完了です。
___

そして、**ちゃんとOutlet接続が出来ていると**URL先の画像が表示されます。
![スクリーンショット 2023-06-01 10.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3375163/a88428e9-b4ed-65ee-ac52-5021b2e0103a.png)

## 注意
上記の通り、
``loadImage(with: 〇〇, into: ××)``
で画像を表示できることを確認していますが、

これとは別で
``NukeExtensions.loadImage(with: 〇〇, into: ××)``
でも画像表示ができることを確認しております。

「何が違うのか」「どちらの方が良いのか」などの事は分かっていないので、
[英語の公式ドキュメント](https://github.com/kean/Nuke)が読める方は読んでみると良いかもですね。
そしてそれをコメントして頂けるとありがたいですね(強欲)。

## 参考資料
* NukeDemo (NukeのGitHubで紹介されていたやつ)
    * https://github.com/kean/NukeDemo
* Qiita@自分の記事(Nuke導入用)
    * https://qiita.com/pe-pe-engineer/items/49047ecab051952508e9
一括データ読み込みジョブ

設定⇒ホーム⇒ジョブ⇒一括データ読み込みジョブ
に遷移すると処理中と過去７日間で完了済みのデータ連携のジョブ一覧が表示されます。

| 項目名 | 意味 | 備考 |
|:-:|:-:|:-:|
| 状況  | ジョブの状況を表します。  | 例：クローズ、中止など  |
| 演算子  | 操作タイプを表します。  | 例：更新/挿入  |
| オブジェクト  | 連携対象のオブジェクトを表します。  |   |
| 処理済みレコード  | 何件処理されたかを表します。  |   |
| レコードの失敗  | 失敗件数を表します。  |   |

上記以外：ジョブID、実行者、開始時刻、終了時刻、完了までの時間が確認できます。

ジョブIDをクリックすると
ジョブ詳細情報が確認できます。

バッチ:
| 項目名 | 意味 |
|:-:|:-:|
| 要求を表示  | どのようなデータを送信したかを確認可能です。  |
| 結果を表示  | 実行結果、新規か更新か、対象の結果データのIdが確認可能です。  |

※：Idが確認できればそのIdを元に、データを検索しやすくなる。
salesforceレポートに参照関係の項目を追加したいのに、項目が見つからないときの対処法

salesforceレポートに参照関係の項目を追加したいのに、項目が見つからないとき
まずはレポートタイプの情報を確認しましょう
設定→クリック検索（レポートタイプ入力）→レポートタイプをクリック
①現在使っているレポートタイプのオブジェクトのリレーションを確認します。
追加したい項目はそのリレーションに含まれているかどうかを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330192/dfff970d-1bca-a563-6b27-fb1de485887d.png)
②それでもない場合オブジェクトのリレーションの下の「レポートで選択可能な項目」に該当項目がレイアウトに表示されているかどうかを確認します。ない場合は「レイアウトを編集する」ボタンから追加してください。
T-SHIRTS AND JEANS

![moda-jeans-use-criativa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310116/a74e642d-53ad-0251-7ac4-6ddef89b9e6e.jpeg)


Use Criativa: A Maior Fábrica de T-Shirts do Brasil.

Fundada em 2017, a Use Criativa é uma empresa especializada na <a href="https://www.usecriativa.com.br/t-shirt">fabricação de t-shirts</a> e <a href="https://www.usecriativa.com.br/jeans">jeans</a>![comprar-jeans-no-atacado.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310116/b53ae4a1-54be-da53-5f8c-6deefc23a4b0.jpeg)
femininos, voltado para o público de Atacado e Atacarejo. 

Com sede em Goiânia, capital de Goiás, a empresa é conhecida por sua estrutura de fabricação internalizada e pelo seu compromisso com a qualidade dos seus produtos.

Ao longo dos seus cinco anos de existência, a Use Criativa se consolidou como a maior fábrica de t-shirts do Brasil, contando com mais de meio milhão de seguidores no Instagram. Além das t-shirts, a empresa oferece uma linha de roupas fitness, jeans feminino, Pijamas, proporcionando uma ampla variedade de opções para os seus clientes.

CONHEÇA A <a href="https://www.usecriativa.com.br">USE CRIATIVA</a>

A qualidade dos produtos da Use Criativa é resultado do cuidado em cada etapa do processo de fabricação, desde a seleção dos tecidos até o acabamento final. Todos os produtos são fabricados dentro da unidade em Goiânia, o que garante um controle de qualidade rigoroso e a capacidade de atender a demanda do mercado com rapidez e eficiência.

![COMPOSICAO-COM-JEANS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310116/d7a20ea1-cb76-a52b-be1b-d0d1c1a27cb2.jpeg)


A empresa atende clientes em todo o Brasil no formato de comércio 100% online, com entregas realizadas através dos Correios e da transportadora JadLog. Além disso, a Use Criativa mantém um perfil no Instagram (@usecriativa), onde é possível conferir as últimas novidades e tendências em moda feminina.

A Use Criativa tem o compromisso de oferecer produtos de alta qualidade, com preços competitivos e atendimento personalizado aos seus clientes. Com a maior fábrica de t-shirts do Brasil, a empresa é a escolha ideal para quem busca produtos de qualidade, confortáveis e com estilo.
 

![MOLETOM-FEMININO.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310116/cb1e98f0-ddaa-20f7-5a08-bb4ce4ae9deb.jpeg)
Python Tkinter リファレンス

# Tkinter リファレンス

参照ドキュメントのリスト
共通メソッドのリファレンスをするとき[ここ](
https://cercopes-z.com/Python/stdlib-tkinter-widget-methods-py.html)が便利だった

https://cercopes-z.com/Python/stdlib-tkinter-widget-methods-py.html

上でよくわからないときは、[この](https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/index.html)サイトで参照
私が参照したときはメソッドなどがすべて網羅していた

ただし最新バージョンとは異なるので注意

https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/index.html
NuxtでvueのdefineModelを使ってみた

実験的な新機能らしい

まず、vueのバージョンを最新のVue３.３にしておきます。

実験的な機能のためそのままでは使えないので、
使えるようにviteとかの設定を変えないといけない。

Nuxtの場合はこんな感じ

```nuxt.config.ts
export default defineNuxtConfig({
  vite: {
        vue: {
            script: {
                defineModel: true,
                propsDestructure: true
            }
        }
    }
...

```


親のコンポーネントは普通にv-modelする。
```parent.vue
<script lang="ts" setup>
	const count = ref<number>(0);
</script>

<template>
    <p>{{ count }}</p>
	<Child v-model="count" />
</template>

```


子供でdefineModelする。
```child.vue
<script setup lang="ts">
	const count = defineModel<number>();
</script>

<template>
	<p>{{ count }}</p>
    <button @click="count!++">click</button>
</template>

```

　　
v-modelに別名つけたい時はこうするのかな
```typescript
//parent
v-model:sampleName="count"


//child
const count = defineModel<number>('sampleName');
```

　　　
あとオプションとかも色々あるみたいだけどまだよく分からない。



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


https://blog.vuejs.org/posts/vue-3-3


https://github.com/nuxt/nuxt/issues/20881
AWS ElasticBeanstalkのデプロイでAdditional Information: Too many application versions, cannot create a new version for application XXXX

# 概要
ElasticBeanstalkのデプロイ処理で以下のエラーが発生しました

[![Image from Gyazo](https://i.gyazo.com/e5e063aa9afac8140ea03bd29b3e24b0.png)](https://gyazo.com/e5e063aa9afac8140ea03bd29b3e24b0)

# 原因
エラーメッセージの通り、アプリケーションバージョンが多すぎるからです
[![Image from Gyazo](https://i.gyazo.com/4e71cf58f7fadcbc2374b2802bcc0c3e.jpg)](https://gyazo.com/4e71cf58f7fadcbc2374b2802bcc0c3e)

ただ、ElasticBeanstalkを作ってから相当経過しないとここが溜まり切らないので時限爆弾式のエラーです。
すでに担当者がいなかったりして、急なエラー発生にすごくびっくりします

# 対策
簡単にライフサイクルポリシーを設定できます。
[![Image from Gyazo](https://i.gyazo.com/9f3e9721fb70928bfe870503ba466f8f.png)](https://gyazo.com/9f3e9721fb70928bfe870503ba466f8f)

## 設定サンプル
[![Image from Gyazo](https://i.gyazo.com/cea081903b147ab9dd9370c1902fdadd.png)](https://gyazo.com/cea081903b147ab9dd9370c1902fdadd)



デプロイ時は神経使ってるのでこんなことでエラーになってイライラしちゃうのは避けたいです。
S3にアップしたPDFをCloudFrontを経由して開くとPDFがダウンロードされてしまう

# 概要
aws-sdkでS3にアップしたPDFをCloudFrontから表示すると、ブラウザ上で表示されずにダウンロードされてしまいました。
[![Image from Gyazo](https://i.gyazo.com/ded35bfd6c55f57f25b35da4ba8bb07c.gif)](https://gyazo.com/ded35bfd6c55f57f25b35da4ba8bb07c)

# 結論
aws-sdkでS3にアップするときにContent-Typeに「application/pdf」を指定する必要があります。

https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Object.html#put-instance_method

[![Image from Gyazo](https://i.gyazo.com/be9b7225d68933cf73a8c0d1a12b0077.png)](https://gyazo.com/be9b7225d68933cf73a8c0d1a12b0077)

# 設定しないと
Content-Typeが自動で「binary/octet-stream」と設定されるため、URLを開いてもブラウザ内で表示されずにダウンロードされます。
[![Image from Gyazo](https://i.gyazo.com/089cdbacfdc8dbe21e73a35d2cf14461.png)](https://gyazo.com/089cdbacfdc8dbe21e73a35d2cf14461)
[![Image from Gyazo](https://i.gyazo.com/1195114fb64fe7df9ea077b7dd689cbe.png)](https://gyazo.com/1195114fb64fe7df9ea077b7dd689cbe)

# AWS マネジメントコンソールから変更しても反映されない
コンソール画面から手動で変更してもやはりダウンロードされてしまいます。（キャッシュの問題？よくわからない）
[![Image from Gyazo](https://i.gyazo.com/c05d1a8b78a7f2487553988019b50265.png)](https://gyazo.com/c05d1a8b78a7f2487553988019b50265)

ちなみに、S3のオブジェクト詳細画面の右上の「開く」からはブラウザ内で表示されるようになります。
[![Image from Gyazo](https://i.gyazo.com/e96190ada4cb21ecceda2b553ac74113.png)](https://gyazo.com/e96190ada4cb21ecceda2b553ac74113)

# Blob形式でフロントに渡したらLINE内ブラウザでは開けない
aws-sdkを使って、S3のオブジェクトの実態をバイナリで取得し、Blob形式URLを作成して開く方式を最初は取っていました。主要なブラウザでは問題なく開けますが、LINE内ブラウザのようなWebViewでは開けないことが判明し断念しました。

# Content-Dispositionを設定する
ブラウザ内で表示する方法としてContent-Dispositionをレスポンスヘッダにつける記事が出てきます。S3のメタデータにContent-Dispositionをinlineで設定しても何も変わりませんでした。

# サンプルプログラム
ruby on railsで書いたサンプルコードです
```ruby
    def put(path, filename, data, bucket = BUCKET_NAME, overwrite: false, content_type: nil)
      rv = true
      # 冒頭に"/"がある場合は削除する。
      s3_path = path.index("/")&.zero? ? path.sub("/", "") : path
      # 末尾に"/"がない場合は末尾に"/"を付与する
      s3_path += "/" if s3_path != "" && s3_path[-1] != "/"
      # S3の使用可否で分岐
      if S3Service.s3_use?
        rv = false
        begin
          # S3のインスタンスを取得
          s3 = S3Service.s3_instance

          obj = s3.bucket(bucket).object("#{s3_path}#{filename}")
          if overwrite || obj.exists? == false
            # content_typeを指定してputする
            rv = obj.put(body: data, content_type: content_type)
          else
            rv = true
          end
        rescue StandardError => e
          Rails.logger.debug e
        end
      else
------（以下略）----------------------
```
【思考停止】ポートフォリオを作りたいと思ってから50億年経っている。

とりあえずキャリア相談のお姉さんには、「インスタみたいなのが作れればスクール生にも負けませんよ？」と言われた。
どうしよう。自分はなぜ低単価、低需要(デザインを極めたり副業で選ぶのとは別で、本業として)のフロントエンドを選んでしまったのだろうか。半年前の自分を殴りたい。とりあえず、サーバーサイド言語、(所謂バックエンド)は独学して実装するしかない。

#### 【理想】こんなのが作りたい
理想と想定する設計内容を記載したい。

>【使用予定言語】
■ PHP/java　→　未習得だが、必須で使いたい
■ HTML/CSS　
■ jQuery/JavaScript
■ Vue.js
【必須実装内容】
■ 「ログイン」機能
■ いいね機能
■ 検索

###### TOP画面

><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2867756/199c0ebc-a3e3-060e-d765-c18fbf21a23e.png" width="70%">

[参照：ヨルシカ公式HP](https://yorushika.com/)
  - [ ] HBGmenu(洒落てるやつ)【実装したい度：★★★★★】
       - [ ] クリックすると"menu"が"close"になる
       - [ ] open時、半分くらいまで広がる
       - [ ] Menu内にはページ内リンクの記載
       - [ ] リンク文字はホバーすると波線が出て、色が反転する
  - [ ] おしゃれなアイコン【実装したい度：★★★☆☆】
       - [ ] 無理な気がしてきた
  - [ ] とりあえずでかい背景画像【実装したい度：★★★★★】
       - [ ] イラスト屋を活用
  - [ ] 右下にあるSNSアイコンリンク【実装したい度：★★★☆☆】
       - [ ] これにはGitHubとQuiitaとInstaを記載したい。
       - [ ] ダメ人間バレしたら嫌なのでQuiitaはやめておこう
  - [ ] 読み込み中画面に読み込み中の画像表示【実装したい度：★☆☆☆☆】
 

###### 真ん中画面(語彙力)

><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2867756/96b338b6-217a-620a-a67d-f7cfe4906590.png" width="70%">
>
>機能的かつシンプル。内容が多岐に渡っているにも関わらず、分別されたフォルダを手にとるように開けてワクワクする気持ちになる。
リンクもスムーズで、「マジ憧れ」の一言しか出てこない。
今回、こんなにたくさんのタブ実装は難しいが、３つのタブの実装はしたい。

[参照：ゆうちょ銀行HP](https://www.jp-bank.japanpost.jp/)

- [ ] タブで分岐されたページの実装【実装したい度：★★★★★】
    - [ ] トップタブにはグルグル回るやつ【想定難易度：★★★★★(鬼)】
    - [ ] とりあえずタブの切り替えを作る【想定難易度：★★★☆☆】

###### 世の中はすごい人ばかりだ
portfolioを漁っていたら"プログラミングスクール主催のWebアプリバトルイベント"なるものを発見した。
その中で一際気になったのが、「部門賞（サービスクオリティ）」、「オーディエンス賞」２冠の以下の作品だ。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2867756/2eab7645-fe05-d796-1592-1188e8317a81.png" width="50%">

https://dreamdiary-cc83b.web.app/

>「本物の実装力」を育てるプログラミングスクールRUNTEQによる、
Webアプリバトルイベント開幕！
[第3回BATTLE OF RUNTEQ](https://battleof.runteq.jp/)
>
>ここまでの発想力と実装力。。
いずれ追いつきたいものの、３ヶ月以内の実装は。自分に、、できるのか。。。ここで出来ないと言ったら出来なくてもいいやと暗示をかけてしまう。
正直キャリア相談のお姉さんが求めていたのはこれだ。
この「ログイン機能」「イイね機能」、、
確かにインスタに似ている。これをやればいいんですね。、、🔥🔥
(ダメ人間　ノ　ホノオ　ガ　モエアガッタ)

今日から6月。
そう。今日は丸亀製麺お手製「釜揚げうどん」の日。
_釜揚げうどんの日になると釜揚げうどんを食べたくなりそわそわする。_
あらゆるものは終わり、始まり、日々は続いていく。
ダメ人間もこのブラックf**king sweatshopに入ってから一年と数ヶ月。スンデのところで身に余る事象に携わる運びとならせていただいた。
根暗インキャコミュ障口下手猫背クソ野郎にとって、得難い好機。
必死で這いつくばってでもキャッチアップしないと絶対に絶対に絶対に絶対に絶対に絶対に後悔する。

のんびりとはしていられない。甘えは言っていられない。。
今はやりたいことがやれることに、地球が逆回りするくらい本っ当に感謝している。
まず、感謝と、得難い機会であることを忘れず初月走り切りたい。
初学者メモ　「gem ancestry」で多階層データを作る

# はじめに
「'食べ物'→'スイーツ'→'モンブラン'のように階層構造を実現したい」
初学者メモです

# gem ancestryとは
今回は、「gem ancestry」を使用してみました

【参考にさせていただいたサイト】
- https://qiita.com/Rubyist_SOTA/items/49383aa7f60c42141871
- https://github.com/stefankroes/ancestry

# 手順
1. gemインストール
1. モデル記述
1. seedファイル記述
1. データの確認

# 実装
### ①gemインストール
```:Gemfile
gem 'ancestry'
```
bundle install を忘れずに

### ②Genreモデル作成
```
rails g model Genre
```
マイグレーションファイルに記述
```:XXX_create_genres.rb
...省略
t.string :name, null: false
t.string :ancestry
...省略
```
【メモ】ancestryカラムを追加するようです
rails db:migrateを忘れずに

### ③モデル記述
```:genre.rb
has_ancestry
```
この記述が大事

### ④seedファイルの記述
```:seeds.rb
leader = Genre.create(name: '指導者')
elementary_school, junior_high_school, high_school, sports_coach = leader.children.create(
  [
    { name: '小学校' },
    { name: '中学校' },
    { name: '高等学校' },
    { name: 'スポーツコーチ' }
  ]
)

['(小)国語', '(小)算数', '(小)理科', '(小)社会', '(小)体育', '(小)音楽'].each do |name|
  elementary_school.children.create(name: name)
end

['(中)国語', '(中)数学', '(中)理科'].each do |name|
  junior_high_school.children.create(name: name)
end

['(高)国語', '(高)数学', '(高)物理'].each do |name|
  high_school.children.create(name: name)
end

['野球', 'サッカー', 'バスケットボール', '武道'].each do |name|
  sports_coach.children.create(name: name)
end
```
Rails db:seedを忘れずに

### ⑤確認
「Rails c」で「Genre.find(XX)」でデータが入っていることを確認できました！

#### 補足
seedファイルの記述を変更したかったのですが、
```
rails db:seed
```
だけでは上書きされ続けてしまい、
```
rails db:seed:reset
```
だと、そんなコマンドないよと怒られました…
結局、
```
rails db:migrate:reset
rails db:seed
```
で解決！

# まとめ
- ancestryのgemで簡単に階層構造が実現

投稿3回目です
ご指導、ご教授いただけると幸いです！
読書研修ーー「リーダブルコード」の第２部　ループとロジックの単純化

# 第９章　制御フローを読みやすくする
* <strong>条件やループなどの制御フローはできるだけ「自然」にする。コードの読み手が立ち止まったり読み返したりしないように書く</strong>
## 条件式の引数の並び順
| 左側 | 右側 |
|:-:|:-:|
| 調査対象。変化する  | 比較対象。あまり変化しない  |

## if/elseブロックの並び順
* 条件は否定式よりも肯定式を使う。if(!debug)ではなく、if(debug)を使う
* 単純な条件を先に書く。ifとelseが同じ画面に表示されるので見やすい
* 関心を引く条件や目立つ条件を先書く。否定形の条件であっても単純に関心や注意を引く場合もある。先に書いてもいい
## 三項演算子
* 行数を短くするよりも、他人が理解するのにかかる時間を短くする
* 基本的にはif/elseを使おう、三項演算子はそれによって簡潔になるときだけ使う。（条件が簡単なとき）

## do/whileループを避ける
do/whileループの欠点：
* コードブロックを再実行する条件が下にあるのでコードを２回読むことになってしまう。
* 内部にあるcontinue文が紛らわしい

## 関数から早く返す
関数で複数のreturn文よりもクリーンアップコードのイディオム（javaなら、try...finally)を使う
## ネストを浅くする
* 変更するときにはコードを新鮮な目で見る。一歩下がって全体見る
* 早めに返してネストを削除する。特に「ガード節」（関数の上部で単純な条件を先に処理するもの）が便利だ。
* ループ内部のネストを削除する

# 巨大な式を分割する
<strong>巨大な式は飲み込みやすい大きさぬ分割する</strong>
## 説明変数
式を表す変数を使えばいい：
``` 
説明変数使ってない場合：
if line.split(':')[0].strip() == "root":
...

usernameは説明変数として使う場合：
username = line.split(':')[0].strip();
if username == "root":
...
```
## 要約変数
式を説明する必要ない場合でも、大きなコードの塊を小さな名前に置き換えて、管理や把握を簡単にする変数は要約変数と呼ぶ。

## ド・モルガンの法則を使う
* not (a or b or c) = (not a) and (not b) and (not c)
* not (a and b and c) = (not a) or (not b) or (not c)
* ド・モルガンの法則を使って否定形減らせる
    * 例：
        * if(<strong>!(file_exists && !is_protected)</strong>) 
                       => if(<strong>!file_exists || is_protected)</strong>)
## 短絡評価の悪用
ブール演算子は短絡評価を行うものが多く、便利だけど、悪用すると複雑なロジックになってしまう。
他人見やすいため、短い「頭がいい」コードに気をつけます。

## 巨大な文を分割する
式の分割と同じような文を分割する。
何回も登場してる長い文は要約変数として関数の最上部に抽出すればいい

<strong>利点：
* タイプミスを減らす
* 横幅が縮まるので読みやすい
* クラス名を変更することになれば、一箇所を変更すればいい

## 式を簡潔にするもう１つの創造的な方法ーーマクロ
マクロを頻繁に使えと言ってるわけじゃない。
利点：簡潔で読みやすい
欠点：見つけにくいバグが潜り込んでしまう可能性ある

# 変数と読みやすさ
## 変数を削除する
コードが読みやすくならない変数を削除：
* 役に立たない一時変数
* 中間結果（タスクはできるだけ早く完了するほうがいい）
* 制御フロー変数（時差のプログラムに関係のあるデータは含まれない）

## 変数のスコープを縮める
 * 変数のことが見えるコード行数をできるだけ減らす
     * グローパル変数を避ける
     * メンバ変数（ミニグローパル）「格下げ」
     * 定義の位置を下げる（変数を定義は変数を使う直前に移動すればいい）
     * 言語によってスコープの決め方は違う
## 変数は一度だけ書き込む
* 変数を操作する場所が増えると、現在値の判断が難しくなるので変数の変更箇所はできるだけ少なくしたほうがいい。
PostgreSQLのシーケンス確認と設定

## 1.シーケンスの一覧を取得

SELECT * FROM pg_sequences;
→シーケンス名（sequencename）が取得できる

## 2.シーケンスの現在値確認

select last_value  from '対象のシーケンス名' ;
例：select last_value  from test_record_id_seq ;

## 3.シーケンス1つ進める

select nextval ('対象のシーケンス名'); 
例：select nextval ('test_record_id_seq'); 

## 4.シーケンスの値を設定

select setval ('対象のシーケンス名',設定値); 
例：select setval('test_record_id_seq', 160);
rinnaの人間の評価を利用したGPT言語モデルをDatabricksで動かしてみる

どんどんオープンLLMが出てきて嬉しいです。試してみます。

https://rinna.co.jp/news/2023/05/20220531.html

モデルはこちら。

https://huggingface.co/rinna/japanese-gpt-neox-3.6b-instruction-ppo

それなりに大きいクラスターが必要でした。メモリ384GBのGPUクラスター`g5.24xlarge`で。

```
%pip install sentencepiece
```
```
dbutils.library.restartPython()
```

あとは、サンプルの通りです。

```py
prompt = [
    {
        "speaker": "ユーザー",
        "text": "コンタクトレンズを慣れるにはどうすればよいですか？"
    },
    {
        "speaker": "システム",
        "text": "これについて具体的に説明していただけますか？何が難しいのでしょうか？"
    },
    {
        "speaker": "ユーザー",
        "text": "目が痛いのです。"
    },
    {
        "speaker": "システム",
        "text": "分かりました、コンタクトレンズをつけると目がかゆくなるということですね。思った以上にレンズを外す必要があるでしょうか？"
    },
    {
        "speaker": "ユーザー",
        "text": "いえ、レンズは外しませんが、目が赤くなるんです。"
    }
]
prompt = [
    f"{uttr['speaker']}: {uttr['text']}"
    for uttr in prompt
]
prompt = "<NL>".join(prompt)
prompt = (
    prompt
    + "<NL>"
    + "システム: "
)
print(prompt)
```
```
ユーザー: コンタクトレンズを慣れるにはどうすればよいですか？<NL>システム: これについて具体的に説明していただけますか？何が難しいのでしょうか？<NL>ユーザー: 目が痛いのです。<NL>システム: 分かりました、コンタクトレンズをつけると目がかゆくなるということですね。思った以上にレンズを外す必要があるでしょうか？<NL>ユーザー: いえ、レンズは外しませんが、目が赤くなるんです。<NL>システム: 
```
```py
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-ppo", use_fast=False)
model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-ppo")

if torch.cuda.is_available():
    model = model.to("cuda")

token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        do_sample=True,
        max_new_tokens=128,
        temperature=0.7,
        repetition_penalty=1.1,
        pad_token_id=tokenizer.pad_token_id,
        bos_token_id=tokenizer.bos_token_id,
        eos_token_id=tokenizer.eos_token_id
    )

output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
output = output.replace("<NL>", "\n")
print(output)
```

おおー、すごい！！
```
それはコンタクトレンズによる目の刺激や乾燥が原因である可能性があります。また、コンタクトレンズが目の周りの筋肉を緊張させることによって、目に痛みが生じることがあります。これらの問題を軽減するためには、眼鏡をかけることがおすすめです。これにより、コンタクトレンズによる目の刺激を減らすことができます。また、定期的に目を洗うことも重要です。これにより、コンタクトレンズによる目の刺激を減らすことができます。

```
![Screenshot 2023-06-01 at 10.42.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/104cb53c-a831-bef9-df76-79f5ba3ed9ae.png)

もっと色々試してみます。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Ansibleで(/etc/cron.x)のカスタムモジュール作成

```playbook
- name: Rename cron files
  hosts: your_host
  vars:
    ctRHEL:
      CsdUX_rhelvup_cron.d:
       -  0hourly: "有効"
          nmon-restart: "無効"
  tasks:
    - name: Rename files based on status
      rename_cron_files:
        cron_file: "{{ item.key }}"
        path: "/etc/cron.d"
        status: "{{ item.value }}"
      loop: "{{ lookup('dict', ctRHEL.CsdUX_rhelvup_cron.d[0]) | dict2items }}"
```


```python
#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule
import os

def run_module():
    module_args = dict(
        cron_file=dict(type='str', required=True),
        path=dict(type='str', required=True),
        status=dict(type='str', required=True)
    )

    module = AnsibleModule(
        argument_spec=module_args,
        supports_check_mode=True
    )

    cron_file = module.params['cron_file']
    path = module.params['path']
    status = module.params['status']

    original_file = os.path.join(path, cron_file)
    backup_file = original_file + '~'

    changes_made = False
    error_occurred = False
    error_messages = []

    if status == "有効":
        if os.path.exists(backup_file):
            if module.check_mode:
                module.exit_json(changed=True)
            try:
                os.rename(backup_file, original_file)
                changes_made = True
            except Exception as e:
                error_occurred = True
                error_messages.append(str(e))

    elif status == "無効":
        if os.path.exists(original_file):
            if module.check_mode:
                module.exit_json(changed=True)
            try:
                os.rename(original_file, backup_file)
                changes_made = True
            except Exception as e:
                error_occurred = True
                error_messages.append(str(e))

    if error_occurred:
        module.fail_json(msg='Error(s) occurred during execution: ' + ' '.join(error_messages))
    else:
        module.exit_json(changed=changes_made)

def main():
    run_module()

if __name__ == '__main__':
    main()
```

renameのモジュールがあればいいのにな
タスクの割当先にグループが表示されない


ヘルプを見ると割当先にグループもあるらしいけど、私の環境にはないんですな。

+ [Lightning Experience 内の複数のユーザ、公開グループ、およびキューへの新規 ToDo の割り当て](https://help.salesforce.com/s/articleView?id=000380133&type=1)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/65e2c091-d063-edb3-e706-d3862fd1c9b7.png)

これを読むと

setup -> activity settings -> "enable group tasks" please

とのことですが、設定を見るとちゃんと有効かされてますね。
試しに一度オフにして再度オンにしてみましたが変化なしです。

+ [Group Not Showing Up in Task "Assigned To" Field](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A98vgSAB)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8bdc0692-2e03-2f10-a943-a9c41f81289c.png)

まぁ、別にToDoは使ってないので問題はないのですがなんでだろうな。環境が壊れているのか？


念のためプレイグランドを見ると... なんとこっちはあるよ、　無料の環境にはあって有料の環境にはない。なんということだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3545d280-e39d-0a12-35ba-930e18908342.png)
phpのarray_walkのcallbackで参照渡しの変数を使う

array_walkのcallbackのargに参照渡しができない。
以下のようにclosureを参照渡ししたらうまくいった。
```
<?php

$a = [ 'a'=>1,'b'=>-2,'c'=>3 ] ;

$sum=0;
array_walk($a, function($v,$k) use (&$sum){ $sum += abs($v); echo "{$k}:{$sum} ";});
echo "\n{$sum}\n";
```

実行結果
```
$ php aw.php
a:1 b:3 c:6 
6
```
Apache TinkerPop Gremlin DB とは



Apache TinkerPop Gremlin(以下、Gremlin)は、グラフデータベースを操作するためのプログラミング言語です。

グラフデータベースとは、ノード（点）とエッジ（辺）と呼ばれる概念を用いてデータを表現するデータベースのことを指します。


そんなGremlinの基本的な概念を見ていきましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/4d9a3c4c-62af-c0a5-6475-aee5d21b59c8.png)


## Gremlinの基本

Gremlinは、Apache TinkerPop プロジェクトの一部として開発されています。
Apache TinkerPopは、グラフデータベースのためのフレームワークで、様々な種類のグラフデータベースに対応しています。Gremlinはこのフレームワークの中で、データ操作を行う言語として使用されます。

https://tinkerpop.apache.org/

## Gremlinの使用方法

Gremlinは、グラフの中のノードやエッジを選択し、それらに対する操作（作成、更新、削除等）を行うための命令を提供します。

例えばこのような命令があります↓

- `g.V()`: グラフ内の全てのノードを選択します。
- `g.E()`: グラフ内の全てのエッジを選択します。
- `.addV('label')`: 新たなノードを追加します。
- `.addE('label')`: 新たなエッジを追加します。

## Gremlinの特徴

Gremlinの大きな特徴の一つは、その柔軟性です。


それは、様々な種類のグラフデータベースで使用することができます。また、Gremlinはオープンソースであるため、誰でも自由に使用、改良することができます。

## まとめ

Gremlinは、グラフデータベースを操作するための強力なツールです。

その使い方は初めての方には少し複雑に思えるかもしれませんが、理解すればデータの構造をより深く理解し、データ操作をより効率的に行うことができます。
事業戦略分析手法


# 3C分析

- Customer(顧客)
- Competitor()
- Company

# SWOT分析

- Strength(強み)
- Weaknesses(弱み)
- Opportunitues(機会)
- Threats(脅威)

# PEST分析

マクロで見る(世の中で～)
PEST分析、SWOT分析と併用して使う

- Politics
政治的要因
- Economy
経済的要因
- Society
社会的要因
- Technology
技術的要因 

# PPM分析

経営資源をどのように分配するか決定する手法


|成長率\占有率|低|高|
|---|:----|:----|
|高|問題児|花形|
|低|負け犬|金なる木|
Atomic Design【初心書🔰】

Atomic Designは、ウェブデザインと開発のフローを改善するための方法論です。

この手法はブラッド・フロストによって提唱され、それ自体が生物学の原理に基づいています。
それでは、具体的な例を交えてAtomic Designについて見ていきましょう。

## Atomic Designとは？

Atomic Designは、インターフェースデザインを5つの異なるレベルで考える方法を提供します。それらは以下の通りです：

1. **Atoms（アトム）**
2. **Molecules（モレキュール）**
3. **Organisms（オーガニズム）**
4. **Templates（テンプレート）**
5. **Pages（ページ）**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/cd08361a-c830-9b6e-376e-8da8f03604d6.png)
出典：https://snowball.digital/blog/intro-to-atomic-design

これらの各レベルがどのように動作するのか、具体的な例を見てみましょう。

## 1. Atoms（アトム）

アトムは、デザインシステムの最小単位です。これらはボタン、インプットフィールド、パラグラフ、見出し、リンクなど、一つ一つのUI要素を指します。

例：ボタン（アトム）

```html
<button>Click me</button>
```

## 2. Molecules（モレキュール）

モレキュールは、アトムを組み合わせて作られます。例えば、フォームフィールド（ラベル、入力フィールド、ボタンなど）はモレキュールと考えることができます。

例：検索フォーム（モレキュール）

```html
<form>
  <label for="search">Search</label>
  <input id="search" type="text">
  <button>Submit</button>
</form>
```

## 3. Organisms（オーガニズム）

オーガニズムは、モレキュールやアトムを組み合わせて作られます。これらは特定の部分（例えば、ヘッダー、フッター）を形成します。

例：ヘッダー（オーガニズム）

```html
<header>
  <h1>Site Title</h1>
  <nav>
    <ul>
      <li><a href="#">Link 1</a></li>
      <li><a href="#">Link 2</a></li>
      <li><a href="#">Link 3</a></li>
    </ul>
  </nav>
  <form>
    <label for="search">Search</label>
    <input id="search" type="text">
    <button>Submit</button>
  </form>
</header>
```

## 4. Templates（テンプレート）

テンプレートは、オーガニズム、モレキュール、アトムを組み合わせて作られ、特定のレイア

ウトパターンを示します。これらは実際のコンテンツを持たず、代わりにプレースホルダーやダミーテキストが使用されます。

例：ブログ記事のテンプレート

```html
<main>
  <header>
    <h1>Blog Title Placeholder</h1>
    <p>Author Placeholder</p>
    <p>Date Placeholder</p>
  </header>
  <article>
    <h2>Section Placeholder</h2>
    <p>Text Placeholder</p>
  </article>
  <footer>
    <button>Like</button>
    <button>Share</button>
  </footer>
</main>
```

## 5. Pages（ページ）

ページはテンプレートに実際のコンテンツを注入したものです。これは具体的なウェブサイトのページを指します。

例：ブログ記事のページ

```html
<main>
  <header>
    <h1>My Awesome Blog Post</h1>
    <p>By John Doe</p>
    <p>Published on January 1, 2023</p>
  </header>
  <article>
    <h2>Introduction</h2>
    <p>This is the start of my awesome blog post...</p>
  </article>
  <footer>
    <button>Like</button>
    <button>Share</button>
  </footer>
</main>
```

これらがAtomic Designの基本的な概念です。
Azure OpenAI Serviceのレスポンスが爆速だった件

[こちらの記事](https://qiita.com/lazy-kz/items/32e8e7c86bdce67beb48#%E5%8B%95%E4%BD%9C%E9%80%9F%E5%BA%A6)に応答速度が速いということが記載されていたので、早速Azure環境を用意して実際に検証してみました。
今回は単純にAPIの応答速度のみを検証してみました。

## 検証方法
VSCodeの[REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)の拡張機能を使ってAzure OpenAIとOpenAIのAPIをそれぞれ実行してみるというものです。
Azureのリージョンは`East US`を選択しました。
ChatGPTのバージョンはともに`gpt-3.5-turbo`にしています。

```
### Azure OpenAI Service
POST https://<あなたの環境>.openai.azure.com/openai/deployments/gpt-35-deploy/chat/completions?api-version=2023-03-15-preview
Content-Type: application/json
api-key: <API キー>

{
  "messages": [
    {
      "role":"user",
      "content":"走れメロスを140文字で要約してください。"
    }
  ]
}

### OpenAI
POST https://api.openai.com/v1/chat/completions
Content-Type: application/json
Authorization: Bearer <API キー>

{
  "model": "gpt-3.5-turbo",
   "messages": [
    {
      "role":"user",
      "content":"走れメロスを140文字で要約してください。"
    }
  ] 
}
```

それぞれ実行するとレスポンス内容の差異はありませんでした。

```json:Azure OpenAI Service
{
  "id": "chatcmpl-xxxxxxxxxxxxxxxxxxxxx",
  "object": "chat.completion",
  "created": 1685578236,
  "model": "gpt-35-turbo",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "ティラノス王に反抗した男の無実を証明しようと、友人のセリヌンティウスを助けるため、自分が罪をかぶって死刑になる決意をするメロス。逃げる道を捨て、彼は死を受け入れ、セリヌンティウスの成功を願いつつ、絶望的な運命に向き合う。自由のため、信頼と献身のため、彼の人生は永遠の光を放っている。"
      }
    }
  ],
  "usage": {
    "completion_tokens": 166,
    "prompt_tokens": 24,
    "total_tokens": 190
  }
}
```

```json:OpenAI
{
  "id": "chatcmpl-xxxxxxxxxxxxxxxxxxxxxxxx",
  "object": "chat.completion",
  "created": 1685578127,
  "model": "gpt-3.5-turbo-0301",
  "usage": {
  },
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "メロスが妹を助けるために罪を背負わされ、処刑される前に友人のセリヌンティウスと出会い、セリヌンティウスが自分の身代わりになってくれた結末が悲劇的に描かれる。友情、正義、自由をテーマにした夏目漱石の一篇。"
      },
      "finish_reason": "stop",
      "index": 0
    }
  ]
}
```

## レスポンス結果
上記検証環境にてそれぞれ5回ずつ実行してみました。結果は以下の通りで、Azure OpenAI Serviceが平均的に上回っており、爆速で返ってくることがわかりました。

|利用API|1回目|2回目|3回目|4回目|5回目|平均|
|:--|:--|:--|:--|:--|:--|:--|
|Azure OpenAI|4,566ms|4,377ms|6,127ms|4,904ms|4,933ms|4,981ms|
|OpenAI|7,706ms|11,410ms|9,933ms|11,215ms|8,917ms|9,836ms|

## まとめ
Azureは2023/06/01現在、申請フォームにて申請する必要があり環境構築に少し苦労しますが、それに引き換えレスポンス速度が圧倒的に速いので、積極的にAzure OpenAI Serviceを使っていきたいと感じました。

システム化のご検討やご相談は弊社までお問い合わせください。

https://www.i-enter.co.jp
【Python CLI】青空文庫のXHTML本からEPUBに変換するツールを作った

# 初めに
自分のCalibre Webインスタンスを設定した頃に、青空の本を集めたかったから、そのようなツールを探していました。AozoraEpub3を見つけましたが、自分のLinuxシステムにインストールできなかったので自作ツールに決めました。

とても簡単なツールであり、URLからXHTMLを変換することができます。`request`モジュールがURLをデータになり、そして `bs4` を使って知らないHTMLタグを除く、題名の情報を集めることができます。最後に、 `ebooklib` が全ての情報（作家、題名）をepubファイルになります。自分のKindleがちゃんと表示できます。

使った外部モジュールは `ebooklib` と `bs4` だけです。

もしかして、他のサイトも変換できますが、青空文庫の本だけが試しました。

# 機能
`-t`と`-y`が縦書きと横書きの設定です。 デフォルトは縦書き。
`-o`プログラムの出力ファイルの設定です。

```
$ pyaozora -y -o 吾輩は猫である.epub "https://www.aozora.gr.jp/cards/000148/files/789_14547.html"
```

URLは作品の図書カードのXHTML版リンクです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2956358/4a98fb60-09fe-3d22-f48b-b4cb9fe81194.png)

# ソースコード
https://github.com/ymndoseijin/pyaozora
WSL2 の Ubuntu に最新の Neovim を入れる

## ざっくり結論

apt だと最新版がインストールできていませんでした。
snap を使うことで最新にできました。
snap を使うために systemd を有効にする必要がありました。


## 背景
WSL2の Ubuntu に Neovim を入れています。ある日、こんなエラーを吐いていました。

![Ubuntu 2023-05-30 09.34.21.png ‎- フォト 2023-05-31 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/ac8e90fd-0755-f2b7-ffb8-e71edb328eb0.png)

プラグインの[Telescope.nvim](https://github.com/nvim-telescope/telescope.nvim) は NeoVim のバージョンが最新の 0.9.0 でないと動作しないようです。
私は Telescope.nvim でファイルを探してコーディングしています。Telescope.nvim が使えないのは死活問題ですので解決していきます。

## 対応したこと

解決するには Neovim を 0.9.0 にする必要があります。私は NeoVim を apt でインストールしています。
ただ[公式に書いてあるように](https://github.com/neovim/neovim/wiki/Installing-Neovim#ubuntu) PPA でインストールする必要があります。（今気づいたのですが、Neovim チームではメンテしないって書いてありますね…）

![Installing Neovim · neovim_neovim Wiki - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/e3e7f027-91c8-81f3-cdc9-c70ae4dbb2fe.png)

[stable](https://launchpad.net/~neovim-ppa/+archive/ubuntu/stable)  版は2023/5/31 時点で 0.7.2 しかインストールできません。


ということで別の方法を検討することにしました。ググると [AppImage で最新の Neovim を使う手段がありました。](https://zenn.dev/temple_c_tech/articles/upgrade-nvim)

使えはするんですが、また最新に更新するときが面倒そうです。
そこで「うーん」となっていたところに、「[snap](https://snapcraft.io/docs) じゃダメなんです？」と先輩社員よりアドバイスをもらいました。

私は snap は使ったことが無かったのですが、調べてみた感じだと結構簡単そうだったので snap でやってみることにしました。
`snap -h` を実行するとヘルプが見れたので、snap 自体はデフォルトで入っていそうです。(私の環境は Ubuntu 20.04.6 です。） 

![Ubuntu 2023-05-30 10.15.02.png ‎- フォト 2023-05-31 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/bb9f169c-e966-7c37-4a36-84aa5c7e67a3.png)

[公式にも snap のインストール方法が書かれています。](https://github.com/neovim/neovim/wiki/Installing-Neovim#snap)

ということで snap install を実行したところ下記のエラーが発生しました。

```
error: cannot communicate with server: Post http://localhost/v2/snaps/nvim: dial unix /run/snapd.socket: connect: no such file or directory
```

[いろいろと調べたところ](https://zenn.dev/dozo/articles/625052a4c397b8)、 snap は systemd というものに依存しているようです。つまり snap を使うためには systemd を使えるようにする必要があります。

幸いなことに WSL2 は systemd に対応しています。下記の記事を参考にさせてもらい、 systemd を有効にしました。

https://crieit.net/posts/systemd-supported-in-wsl

そして今一度、snap install を実行して Neovim を入れたところ 0.9.0 がインストールできました！
![Ubuntu 2023-05-31 17.16.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/cdeda307-a273-7b40-aa2e-0a3c3ca930ca.png)

これで Telescope.nvim も使えて快適 vim ライフが続けられそうです。
先人達の記事にも大変助けられました。ありがとうございます。

## 参考記事一覧

https://zenn.dev/temple_c_tech/articles/upgrade-nvim

https://github.com/neovim/neovim/wiki/Installing-Neovim#snap

https://zenn.dev/dozo/articles/625052a4c397b8

https://crieit.net/posts/systemd-supported-in-wsl
MacでTerraformがマルウェア認定された

久々にTerraformを使おうとしたらこちらでレポートされている事象に。

https://discuss.hashicorp.com/t/terraform-0-13-5-being-flagged-as-malicious-on-macos/53096

バージョンを上げることで解決できました。

tfenvが必要なのでインストールしようとしました。

https://spacelift.io/blog/terraform-version-upgrade

が、エラー。

```
Error: Cannot install tfenv because conflicting formulae are installed.
  terraform: because tfenv symlinks terraform binaries
```

こちらにあるように、先にterraformをunlink

https://kamatimaru.hatenablog.com/entry/2020/05/21/040106

```sh
brew unlink terraform
```

```sh
brew install tfenv
```

```sh
tfenv intall 1.4.6
```

これで動くようになりました！
【早い！安い！うまい！】VSCode+WSL+Dockerで簡単に開発環境構築

## 三種の神器
今や**WSL**,**Docker**,**VSCode**は使えて当たり前という雰囲気になってきたので、初心者のためにすごく~~適当~~簡単に導入手順をまとめたよ
**卍最強の環境卍**を構築するため以下の4ステップで解説するよ
1. [WSL2の導入](#1-wsl2の導入)
2. [Dockerの導入](#2-dockerの導入)
3. [VSCodeの設定](#3-vscodeの設定)
4. [使ってみる](#4-使ってみる)

## 1. WSL2の導入
そもそもWSLって何？という方もいらっしゃると思いますが、**Windows内でLinux環境を使うことができるぜ**ということだけ覚えておけばOKです
導入についてはPowerShellで以下コマンドを実行するだけ！
```powershell:powershell
wsl --install
```
インストールしたらPCのスタートメニューからUbuntuを開き、ユーザ名とパスワードを設定しよう
(Ubuntuを開くだけでユーザ名とパスワードを作成するための入力が求められます)

WSLを真面目に知りたい方はこちら↓
https://learn.microsoft.com/ja-jp/windows/wsl/about
導入についての公式ドキュメント↓
https://learn.microsoft.com/ja-jp/windows/wsl/install

## 2. Dockerの導入
Dockerについてはすっごい雑な説明をすると**アプリケーションの環境(コンテナ)を簡単に構築/共有するためのツール**という感じです

Dockerを使うと主に以下のメリットがあるよ
* 独立した環境が簡単に建てられる
* Dockerfile(コンテナを立てるための設計図のようなもの)で管理できるため環境の共有が簡単になる
* 壊れても立て直しが容易

WSL上で以下コマンドを実行すれば入るよ

```shell:WSL
sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo usermod -aG docker $USER
```
Dockerを真面目に知りたい方はこちら↓
https://docs.docker.jp/get-started/overview.html
導入についての公式ドキュメント↓
https://docs.docker.com/engine/install/

## 3. VSCodeの設定
VSCode本体のダウンロードはここ↓
https://code.visualstudio.com/
起動後に拡張機能のタブから「Remote Development」をインストール

## 4. 使ってみる
今回はめちゃくちゃシンプルなPythonだけの環境を構築するぜ☆
まずWSLのターミナルで適当な作業用ディレクトリに移動して以下コマンドでVSCodeを起動しよう
```shell:WSL
code .
```
「ctrl + shift + p」を押したらコマンドパレットが表示されるので「Reopen in Container」を押しましょう
そして「Python 3」->「3.11」を選択してから「OK」を押したらビルドが始まります！
![4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124426/a43ef4bd-e37f-3873-6967-6a2b518efbf9.png)
ビルドが完了するとコンテナに接続された状態でVSCodeが再起動するよ
左下がDev Containerになっていたら完了だぜ
![4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124426/c519eec3-2991-652d-04d6-45aa866a91d4.png)
vscodeが勝手に生成したdevcontainer.jsonについてはコンテナの構成や設定についてのファイルです
Dockerfileの指定や環境構築後にインストールする拡張機能などを指定できるぜ

## 最後に
**いいね、ストック 感謝します**🙏
RxSwiftを学ぶ①SubjectとObservableの違い

## はじめに
swift学習中の初学者です。
RxSwiftを学ぶ中で、詰まった点や理解できなかった点について、備忘録と理解の整理のために記事にしていきたいと思います。


## この記事を読むにあたって
詳しいRxSwiftについての説明等はここでは行いません。
あくまで私が学習していてうまく理解ができなかった部分のみ記事にしています。
初学者のため、誤っている点等あれば教えていただけたら嬉しいです。

## SubjectとObservableの違い

### Subjectは観察する側にも観察される側にもなれる
この意味が全然理解できませんでした。
Observableもsubscribe(購読)できるのになぜObservableは観察者となれないのか。
これを理解するために、まずSubjectとObservableの違いについて書きたいと思います。

Subjectにできてobservableにできないこととして、「通知を受け取る」ということ
・Subject

```swift
 let subject = PublishSubject<Int>()
subject.onNext(1) // エラーにならない
```
・Observable
```swift
let observable = Observable.from([1, 2, 3])
observable.onNext(4) // エラーになる
```

通知を受け取れないということは、observableは観察者となることができない。
subjectは通知を受け取ることができて、かつ自身も通知を発行することができるため、
これが「subjectは観察する側にも観察される側にもなれる」という意味と理解できました。

ちなみに、サンプルコードなどでよくある

```swift
 Observable.of("A", "B", "C", "D")
        .subscribe(onNext: { element in
            print(element)
        })
        .disposed(by: disposeBag)
```
というコードを見て、私はこのObservableは通知受け取ってるんじゃないか、
観察者になってるやんと思ったのですが、
あくまでこのObservableが発行した通知をクロージャに渡しているだけなので、Observable自身は観察者ではないという理解で落ち着きました。

### Observableの必要性
ということはSubject使った方がいいじゃん、Observable使う必要あるのかなと思い調べたところ、
Observableは後から変更できないため「読み取り専用」として機能するということでした。
データの安全性と一貫性を保証することができるため、変更の必要がないところでの予期せぬ変更等を防ぐことができます。

必要に応じてSubjectとObservableを使い分けた方がいいと理解しました。



## 最後に

最後まで読んでいただきありがとうございます！
今後もRxSwift学習中に詰まった点を書いて行きたいと思います。
DockerでGUI環境のUbuntu + pythonをサクっと構築する

## 背景
検証環境等をubuntu-server等で構築しているときに、出力がGUI出ないといけない場合が時たまある。そういった場合、その”少し必要”に対してわざわざubuntuにVNCを構築するのは馬鹿らしい。そこで今回はコンテナでサクっとGUI環境を立ち上げる



## 手順
### Dockerfileの作成

```
nano Dockerfile
```
```
FROM akarita/docker-ubuntu-desktop
RUN apt-get -y update && apt-get -y install nano python3-pip
```

### Docker-compose.ymlの作成
```
nano docker-compose.yml
```
```
version: '3.3'
services:
    docker-ubuntu-desktop:
        ports:
            - '6080:6080'
        build: .
        container_name: 'guiubuntupy'
        working_dir: /root/
        volumes:
            - ./work:/root/Desktop
        
```


アクセス方法
```
http://X.X.X.X:6080/vnc.html
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/d877fe0a-2ccc-949c-a735-a8d2dc9e8fd8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2738475/48a07a3b-e42a-b3d0-e5f0-8df7d222a9c3.png)
すごすぎる。。。。




##### 参考文献
https://genchan.net/it/virtualization/docker/13063/

##### Dockerイメージ参照元
https://qiita.com/takahashiakari/items/f096e5bcdfecf3d5ba90
GoogleChromeでChatGPTから応答がこない

# はじめに

普段からChatGPTを用いて開発を進めていますが、突然質問をしても解答が返ってこなくなりました。そこでネットを調べても同じような問題が起きていなかったのでまとめます

# 問題

質問をなげても解答が全く返ってこなくなりました
そこでスマホブラウザで同じアカウントで質問したところ返ってきました

ブラウザの履歴やキャッシュを消しても症状は変わらず、firefoxならうまくいきます

# 解決方法

私はGoogleの拡張機能で「**Superpower ChatGPT**」を利用しており、その拡張機能をアンインストールすることで使えるようになりました

https://chrome.google.com/webstore/detail/superpower-chatgpt/amhmeenmapldpjdedekalnfifgnpfnkc?hl=ja

# おわりに

ChatGPTが使えないなら開発あとでいいやというほどに依存していることに気づきました
なかったときにどのように開発していたかを忘れてしまいそうです

# 参考

https://chrome.google.com/webstore/detail/superpower-chatgpt/amhmeenmapldpjdedekalnfifgnpfnkc?hl=ja
【iterm2】矢印キーをよく使う人向けショートカット設定

## 概要
Macのターミナルエミュレータである`iTerm2`のキーボードショートカット設定についてお話しします。
`iTerm2`を利用している皆さんにとって、日々の開発作業をよりスムーズに、効率的に行えるようになるかと思います。
それでは、具体的な設定方法を見ていきます。

## ショートカットの設定方法
まず、iTerm2を開き、メニューバーから設定をクリックして設定ダイアログを開きます。次に、「Profiles」>「Keys」>「Key Mappings」の順にタブをクリックして進みます。

ここには、すでに設定されているキーマッピングの一覧が表示されます。「+」ボタンをクリックして新しいキーマッピングを追加するか、既存のキーマッピングをダブルクリックして編集します。

たとえば、「単語の先頭に移動」（⌥``←）のコマンドを設定する場合は、`Send Escape Sequence`アクションを選択し、エスケープシーケンスとしてEsc+b(Esc+の箇所にb)を入力します。ここでEsc+という記述は、特定のエスケープシーケンスを送信することを指すみたいです。
※エスケープシーケンスとは、特殊な操作を実行するための一連のキャラクターのことで、通常はエスケープキャラクター（'Esc'）で始まります。

また、エスケープシーケンスの他に、ヘックスコード（16進数）を送信するショートカットを設定することも可能です。これには、`Send Hex Codes`アクションを選択します。

### ショートカット一覧
以下に、僕が設定している一部のショートカットの設定例を挙げます。
このリストを参考に、自分がよく使うコマンドに対してショートカットを設定してみてください。

- ⌥ + ← : 単語の先頭に移動 - エスケープシーケンス `b` を送信
- ⌥ + → : 単語の終わりに移動 - エスケープシーケンス `f` を送信
- ⌘ + ← : 行の先頭に移動 - ヘックスコード `0x01` を送信
- ⌘ + → : 行の終わりに移動 - ヘックスコード `0x05` を送信
- ⌥ + ⌫ : 単語の先頭まで削除 - ヘックスコード `0x17` を送信
- ⌘ + ⌫ : 行全体を削除 - ヘックスコード `0x15` を送信

## 注意点
ヘックスコードを入力する際には、16進数の表記法を使用します。
そのため、入力する数字や文字は0-9またはA-Fの範囲であることを確認してください。

## まとめ
この記事では、iTerm2のキーボードショートカットの設定方法について解説しました。
自分はずっとVScodeのターミナルを使っており、VScodeではこの矢印での移動ができたのですが、iterm2でできなくてずっと悩んでいたのですが、今回その方法を発見してかなり快適なりました！

この記事が皆さんの一助となれば幸いです。それでは、Happy Coding!
チートシートをいつもお手元に

船井総研デジタルのよもぎたです。

今回はポエム寄りのTipsのご紹介です。お許しください。

「チートシートって何？」という方のために念のために説明しておくと、「早見表」「カンニングペーパー」のようなものです。「どんなもの？」「どうやってつくるの？」「どうやって手に入れるの？」という方は、Qiitaに先人たちがいろいろ記事を投稿してくださってるので、[チートシートタグ](https://qiita.com/tags/%e3%83%81%e3%83%bc%e3%83%88%e3%82%b7%e3%83%bc%e3%83%88)や[CheatSheetタグ](https://qiita.com/tags/cheatsheet)の記事をご覧ください。

# 結論
チートシートをPDFで作成して余ってるタブレットやスマホで常時表示させて視界の隅に置いておくとよいと思います。

# 発端
「チートシート、いつでも見られるようにしたいな。コレ（先代のFireタブレット）使えばいいんじゃない？」と思ったのがキッカケです。

# 準備するモノ
* PDFを作成できるソフトウェア
* PDFを表示できるタブレットかスマホ
* タブレットスタンドかスマホスタンド
* PDFファイルをタブレット・スマホに転送する手段

# 手順
概要だけご説明します。Qiitaのユーザーさんならお好みのソフトウェアでサクッとできると思います。

## チートシートPDFファイルを作成する
まずは表示したいチートシートを用意します。自分で作成してもよいし、ネットの海から漁ってきてもよいし、漁ってきたものを自分が使いやすいようにアレンジしてもよいでしょう。

作成時のポイントは、表示させたい端末の画面に合わせた縦横比にすることくらいでしょうか。
PDFファイルにまとめるメリットは、ひとつのファイルを表示させておいて、複数のチートシートをスワイプ操作で切り替えられることです。逆に、これが出来ればPDFファイルにこだわらなくてもよい、極端な話、1枚表示出来ればよいならJPEGやPNGといった画像ファイルでも構わないと思います。

私はExcelでベースになる表を作成して、PowerPointに貼り付けて成形してPDFにエクスポートしました。

## チートシートPDFファイルを目的の端末に転送する
ここは皆さんの環境にあわせて適宜やってください。ネット／クラウドサービス経由でも、有線接続でもSDカードでもかまいません。

## 端末でチートシートPDFファイルを表示させる
これも、ご利用の端末で使えるアプリとファイル形式に合わせてお好みでやってください。

この時、アイドル状態でも画面が消灯しないように設定します。セキュリティの観点で好ましい状態ではありません。必要のないアプリを削除したり、専用アカウントを作ってログインしたり、ブラウザのキャッシュやログイン情報を消したり…出来る限り気を使ってください。

ここが、余剰端末でやる理由です。

## 端末をお好みの場所に置く
デスクにモノがあふれている人（私です）は頑張って場所を確保しましょう。

# 実際にやっている例
実際にやっている例を写真に撮ろうとしたところ、不審なおっさんが映りこんでいて、ネット上に公開するのは不適切と判断いたしましたので、掲載は見送らせていただきます。

# 課題
私物を利用することになるので、オフィスではやりにくい、会社によっては許されない可能性があるのが課題ですね。これは環境依存なので私にはどうしようもありません。この課題にぶち当たってしまった方が周囲のご理解を得られるよう祈ります。

それと、あまりにも古い機材を利用する場合、ネットに繋げるのがためらわれるとか、バッテリーの持ちが心配、といったところでしょうか。前者はPCとの有線接続やSDカードなどを使ってファイルを移動させることで、手間はかかりますが回避できます。後者は、これまたひと手間かかりますが、電源を常時接続しておけばよいでしょう。

# 蛇足
こんなネタ、業務時間内には書けないよ・・・。

最後までお読みいただきありがとうございました。これに懲りず、引き続きよろしくお願いいたします。
暗号化, base64エンコード, URLエンコードについて改めて調べてみた

# 経緯
業務で、`DB内レコードの値を暗号化→別サイトに対するGETリクエストのURLパラメータとして設置` という処理を追加したのだが、「あれ、暗号化する必要あるよな。base64エンコードしたりURLエンコードも必要だろうけど、これってなんのためにするんだっけ。。。」みたいになったので、改めて調べてみた。

＊ここではあくまでURLパラメータ実装に関する暗号化、エンコードに限定して記載する

# 暗号化

### 用途

一般的にどのユーザーがどのユーザーと関係があるのかや、ユーザー情報(名前、メールアドレス、住所など)などの個人情報をパラメータにすると、URLに読み取れる情報が含まれることになる。読み取り/悪用を避けるために、内容が容易にバレない形に書き換えてURLパラメータにすることが求められる。


### ちょっと脱線
今回、暗号化方式はAES-256-CBC方式を採用したのだが、AES(1)-256(2)-CBC(3)のそれぞれの値が何を示すかも、ざっと調べてみた。

(1)Advanced Encryption Standardの略で、日本語に訳すと「先進的暗号化標準」。無線LANなどに用いられる暗号化アルゴリズムの一つ。アメリカ国立標準技術研究所により政府標準として認められている。共通鍵暗号。

(2)256ビットのキーを使用してプレーンテキストまたはデータを暗号に変換する、の意

(3)1つ前の暗号文ブロックと平文ブロックのXOR（排他的論理和）をとり、そのXORの値を暗号化を行うモード。ECBもよく見かけるが、ECBの場合同じ平文が複数存在したら、それらの平文は同じ値の暗号文ブロックに変換されてしまう欠点がある。CBCにはそのような欠点はない。

暗号化アルゴリズム(1)-ビット数(2)-モード(3)という三要素で表現されてるよう。

また、今回phpでの実装だったのですが、[openssl_encrypt](https://www.php.net/manual/ja/function.openssl-encrypt.php)メソッドで簡単に暗号化できて便利だなーと感じた。


# base64エンコード
### 用途
base64はバイナリ形式からテキスト形式へデータを変換するエンコード形式。データ変換に際し64進数を利用し、64個の英数字を用いるためにこの名称。暗号化されたデータはバイナリ形式で得られる。バイナリ形式では人間が理解できる形式ではないので、人間にも理解しやすいように記述されたテキスト形式へbase64エンコードを用いて変換する。暗号化の一つと認識されている事例も散見されるが、あくまで形式変換の一種である。


# URLエンコード
### 用途

URLの文字列データが空白文字や一部の記号(「$」、「#」など)、全角文字などを含んでいると正しく送信されない可能性があるため、それらの文字をエスケープする必要がある。それがURLエンコード。

#まとめ
・暗号化 
→ 値を内容がわかりにくく安全性の高い形に変換
・base64エンコード
→ バイナリ形式をテキスト形式に変換
・URLエンコード
→ に含めることができない文字を

という感じだろうか。なんとなく「URL作るときゃエンコードやろ」くらいに使ってたのですが、内容を知るとなるほどなという感じ。まだまだ知らないことがたくさんあるなー。
php習熟度テスト

# 1. 知識問題(18)


## 1.1 (1)
配列と連想配列の主な違いはなんですか？

## 1.2 (1)
forループにおける、continueの意味はなんですか？

## 1.3 (2)
関数の中のコードは下記のうちどのタイミングで実行されますか？
該当するものをすべて答えよ

a. 定義したとき 
b. 引数を与えられたとき 
c. 関数名の後に（）を記載したとき

## 1.5 (1)
hoo クラス に bar() という名前の関数があるとすると、関数を利用する際は
どの用に呼び出せばよいでしょうか？

## 1.6 (2)

下記の各行の出力を答えよ。

``` python
substr("kabushikigaisyawalker", 1, 2);
substr("kabushikigaisyawalker", 0, 3);
```

## 1.7 (3)
エスケープ文字とはなんですか

## 1.8 (1)
エスケープ文字の \n と \t はそれぞれ何を表しますか

## 1.9 (1)
文字列の先頭や末尾の空白文字を取り除く方法を答えよ。

## 1.11 (3)
```php 
function a() {
    echo "a";
}

function b() {
    echo "b";
    return "b";
}

function c() {
    // print(c)
    echo "c";
    echo b();
}

echo "c";
a();
c();
```
上記を実行したときの出力を答えよ


# 2 応用問題 (42)

## 2.1 (30)

下記のプログラムについて、下記の問に答えよ

```php5
function g($arr) {
    $n = count($arr);
    for ($i = 1; $i < $n; $i++) {
        $key = $arr[$i];
        $j = $i - 1;

        while ($j >= 0 && $arr[$j] > $key) {
            $arr[$j + 1] = $arr[$j];
            $j--;
        }

        $arr[$j + 1] = $key;
    }

    return $arr;
}

```

### 2.1.1 (10)

下記の用に実行した結果場合の出力を回答せよ

```php5
$numbers = [9, 5, 1, 3, 8, 4, 7, 2, 6];
$x = g($numbers);
print_r($x);
```

を呼び出した場合の返り値を記載せよ。

### 2.1.2 (20)
g($arr)の役割を30字程度で簡潔に説明せよ。


# 3. 実技 (40) 

## 3.1 (10)

連立方程式を解くプログラムを作成せよ 
下記２式の連立方程式を解くとして、

$$ax + by + c = 0$$

$$dx + ey + f = 0$$

a, b, c, d, e, f を引数とし、解であるxとyをreturn するものとします。 

```python
function(a, b, c, d, e, f){
	...
	return x, y
}
```
ただし、連立方程式が解を持たない場合(null, null)をreturnするものとする。


## 3.2 (20)

モンテカルロ法を用いて円周率を求めていきます。
正方形と、それに内接する円を想定し、ランダムに点を打ち込むことで、正方形と円の**面積比**を求めることができます。 
ここで測定された比を下記とする。

$$ 正方形の面積:円の面積 = A:B \cdots (式1)$$
また正方形の辺長を 2a とすると、 

$$ 正方形の面積 =4a^{2} \cdots (式2)$$

$$ 円の面積=πa^{2} \cdots (式3)$$


式1,2,3 より、 円の面積を用いてπの値を求めることができる。

$$ π = 円の面積/a^{2} \cdots (式3)$$

すなわち、プログラムによって円の面積を近似することができれば、円周率を求めるプログラムを作成することができる。




### 3.2.1 (2)
下記は-1~1 を条件を満たす、ランダムな少数を出力する関数である。
下記において、 100で割り算をしている理由はなにか。

```php
function generateRandomFloat() {
    return mt_rand(-100, 100) / 100; // -1から1の範囲の乱数を生成
}
```

### 3.2.2 (3)
3.1.1 の 関数を利用し、下記の条件をみたす座標(x, y)を連想配列で出力する関数を作成せよ。
$$ -1 < x < 1 かつ  -1 < y < 1  $$

出力例：
```php
["x" => 0.21, "y" => -0.28];
```

### 3.2.3 (10)
2.1.2 で作成した座標が、内接円の中にあるか判定する関数を作成せよ。
円の式は下記である。
$$ x^2 + y^2 = 1 $$

### 3.2.4 (5)
2.1.3 で作成した判定を 10000回実行して、
内接円の中にあると判定された点の数を集計し、円周率を推定せよ。

# 3.3 (10)

数値の引数 n をひとつ持ち、以下の特徴を持つ関数 f(n)、g(n)を作成し、
g(5), g(396), g(3913) それぞれの結果を出力せよ。

**関数 f(n)** 
n が 偶数なら n/2 を戻り値とする。
n が 奇数なら 3*n +1 を戻り値とする。

**関数 g(n)** 
n を f(n)に渡し、結果を出力(echo)する。 
更に、結果が1であれば処理を終了し、
1以外の値であれば結果を再度 g(n) に渡し、再起的に呼び出す。