OmniAICreator/Qiita-1.07M huggingface dataset:
Viteですべてのscssファイルに共通の変数を読み込ませる

## 結論
`vite.config.ts`の`css.preprocessorOptions.scss.additionalData`にお好みのscssファイルを指定してあげれば、すべてのscssで指定したscssのコードを読み込んでくれる。

## 詳細
### 環境
    "sass": "^1.52.3",
    "sass-loader": "10",
    "typescript": "^4.6.4",
    "vite": "^2.9.9",
    "@vitejs/plugin-react": "^1.3.0",
React + ts , CSS Modules, scss で書いていく。

### 具体的なコード
vite.config.tsは次のようになっている。
``` vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import * as path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  css: {
    modules: {
      scopeBehaviour: 'local',
    },
    preprocessorOptions: {
      scss: {
        additionalData: `@import "@/assets/scss/index.scss";`,
      },
    },
  },
  resolve: {
    alias: {
      '@/': path.join(__dirname, './src/'),
    },
  },
})

```

`src/assets/scss/index.scss`が次のようになっているとする。
```src/assets/scss/index.scss
$main-color: #e98a1d;
```
このとき、例えばコンポーネントのスタイリングを記述する際に次のように書けば`$main-color`を正しく読み込むことができている。
```sec/components/Button/Button.modules.scss
.button {
  background-color: $main-color;
}
```
ディレクトリトラバーサル とは

## 勉強前イメージ

トラバーサルって横断とか横切りだけど、ディレクトリを横切る？？

## 調査

### ディレクトリトラバーサル とは

webサーバの非公開のディレクトリにアクセスを行う攻撃方法です。
webサーバの中でも公開している箇所はごく一部でその他のディレクトリは公開を許可していません。
その許可していないディレクトリにアクセスを行う攻撃方法ですが、公開しているディレクトリから横断するという意味で
ディレクトリトラバーサルと呼ばれています。

典型的にはパラメーターなどで外部からファイル名の指定をしてアクセスする場合に攻撃対象になります。
相対パスで親ディレクトリなどへアクセスを行います。
`../` の指定で一階層上のディレクトリへ移動できるので、それを利用してパスワードを見られたり
他の必要なディレクトリやファイルを削除される場合があります。
また、機密情報の漏洩で社会的な損失の可能性もあります。

そうならないために、相対パスでの指定をなくすか
または、相対パスのチェックやハッシュ化などを行うことでディレクトリトラバーサルを防ぐことが出来ます。

## 勉強後イメージ

よく聞くけど、こういう言葉あるって知らなかった

## 参考

- [ディレクトリトラバーサルとは？4つの有効な対策を解説](https://www.lrm.jp/security_magazine/directory_traversal/)
- [ディレクトリトラバーサル 【directory traversal】](https://e-words.jp/w/%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%83%88%E3%83%A9%E3%83%90%E3%83%BC%E3%82%B5%E3%83%AB.html)
【Power Shell】テスト用_ファイル or フォルダ作成スクリプト

たまにですが、、

テストで大量にファイルを作成する事があり、毎回コマンド作るのが面倒くさかったのでスクリプト作りました。コマンドの復習ついでに備忘残しておきます。

カレントディレクリ内にテスト用のファイルを作成するので、Get-Locationコマンドで現在地を取得します。
フォルダパスを作成したいので、-replaceで置換します。(`n は改行を意味します。)
Set-Locationで作成したフォルダパスを指定して、移動します。

```:Create_Object.ps1
#現在のフォルダパスを取得
$Folder_Pass = Get-Location
$Folder_Pass = $Folder_Pass -replace "Path`n---- "

Set-Location $Folder_Pass
```

今回はConfファイルで引数を定義します。
Create_Object.confを作成して、中身に下記のような記載を行います。


```:Create_Object.conf
#カンマ区切りで、引数を指定します。
#引数に"#"は含めないで下さい。
#引数の順番は(①File or Directory,②ファイル数,③名前)
File,10,test.log
```


作成したCreate_Object.confをスクリプト内に定義します。
Get-Contentコマンドでファイルを読み込み、Select-Stringコマンドで行頭に#がついている行以外の文字列を取得します。-NotMatch　は指定したパターンに一致しない文字列を取得したい場合に使用します。
文字列取得後に、改行を置換します。

```:Create_Object.ps1
#Confファイルの定義
$Conf　= "C:\Test\Config_Powershell\Create_Object.conf"
#Confファイルの読み込み
$Conf_Read = Get-Content $Conf | Select-String -NotMatch "^#"
$Conf_Read = $Conf_Read -replace "`n",""
```

splitを使用して、Conf内で定義していた引数を配列に格納します。

```:Create_Object.ps1
#パラメーターの作成
$Parameter = $Conf_Read.split(",")
```

あとは、ループ文でnew-itemコマンドを回せばOKでございます。
ファイル名の頭に番号を割り振っておきました。


```:Create_Object.ps1

for($i=1;$i -le $Parameter[1]){
    
    $Create_Object = [string]$i + "_" + $Parameter[2]
    New-item -itemtype $Parameter[0] $Create_Object
    $i += 1

}
```

ここまでのコマンドを組み合わせて、スクリプトを実行すればカレントディレクトリ上にファイル or フォルダ が作成されます。

```:Create_Object.ps1
#現在のフォルダパスを取得
$Folder_Pass = Get-Location
$Folder_Pass = $Folder_Pass -replace "Path`n---- "

Set-Location $Folder_Pass

#Confファイルの定義
$Conf　= "C:\Test\Config_Powershell\Create_Object.conf"
#Confファイルの読み込み
$Conf_Read = Get-Content $Conf | Select-String -NotMatch "^#"
$Conf_Read = $Conf_Read -replace "`n",""

#パラメーターの作成
$Parameter = $Conf_Read.split(",")

for($i=1;$i -le $Parameter[1]){
    
    $Create_Object = [string]$i + "_" + $Parameter[2]
    New-item -itemtype $Parameter[0] $Create_Object
    $i += 1

}
```
プロパティ"........."は型'JSX.IntrinsicElements'に存在しません。

## 悩み事
```
import styled from "styled-components";

const Title = () => {
  <titlefont>Hacker News</titlefont>;
};

const titlefont = styled.div`
  color: black;
  font-size: 20px;
  font-weigh: normal;
`;

export default Title;
```
この状態でエラーが発生してしまいました。
内容としては　**プロパティ"........."は型'JSX.IntrinsicElements'に存在しません。** です

## 何が原因であったか
結果として、コンポーネントを大文字から始めないといけないようです。

### 参考先
https://ja.reactjs.org/docs/jsx-in-depth.html

他にもこのようなエラーに注意した方がいい、などあればコメントお願いします。
自作DiscordBotをDiscord.js v13からv14に移行してみた

# 環境
Node.js v18.6.0
Discord.js v13 → v14

# ソースコード
[2na2-Discord(Github)](https://github.com/na2na-p/2na2-Discord)

# 詰まったポイント
[Discordjs.guideの対象記事](https://discordjs.guide/additional-info/changes-in-v14.html)を読みながら作業していました。
1. intentsの指定?で[`GatewayIntentBits.MessageContent`を指定しないと](https://github.com/na2na-p/2na2-Discord/blob/31fea02c49995c775ca39a74c1cbf3b4f9f52214/src/client.ts#L31)メッセージ本文が取れないことに気づくまでやや時間がかかりました

# その他
そろそろまじめにテストコード書きたいんですが、Discord.js採用したブツのテストってどうやったらいいんでしょう。いまいちよくわかってないのでそのうちやってみたいです。
Rails6でrails generate scaffoldすると`Unknown alias: default (Psych::BadAlias)`とエラーが出る

## 結論

Gemfileで`webpacker`のバージョンを `~> 5.0`と指定すればエラーが出なくなる。
なぜかはわからない。

## 詳細
### やりたかったこと
Railsアプリでscaffoldを使ってリソースを作りたかった。

### 環境
- ruby 3.1.2
- rails 6.1.6
- bundle 2.2.17

### やったこと
基本的にRailsチュートリアル第2章に従っています。
1. `rails new toy_app`でアプリを生成、`cd toy_app`で移動
1. Gemfileを下記のように書き換え
1. `bundle config set --local without 'production'`で設定
1. `bundle install`でgemのインストール
1. `rails webpacker:install`
1. `rails generate scaffold User name:string email:string`でリソースを作ろうとする

```　Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '3.1.2'

gem 'rails',      '6.1.6'
gem 'puma',       '4.3.6'
gem 'sass-rails', '6.0.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.11.1', require: false

group :development, :test do
  gem 'sqlite3', '1.4.2'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.7.1'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

gem 'rexml', '~> 3.2', '>= 3.2.5'
gem 'net-smtp'
gem "psych", "< 4.0.0"
gem "matrix"

group :test do
  gem 'capybara',           '3.37.1'
  gem 'selenium-webdriver', '3.142.4'
  gem 'webdrivers',         '4.1.2'
end

group :production do
  gem 'pg', '1.1.4'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

### 期待した挙動
```
invoke  active_record
create    db/migrate/20190820002503_create_users.rb
create    app/models/user.rb
.
.
.
```
と問題なくUserリソースが生成される。

### 実際の挙動
`'visit_Psych_Nodes_Alias': Unknown alias: default (Psych::BadAlias)`
とエラーが出る。

### 解決方法
結論に記載した通り、Gemfileのwebpackerの部分を
```
gem 'webpacker', '~> 5.0'
```
と書き換えてbundle installし直してからやり直すと期待した挙動になる。

なんでなんだろう。
orderメソッドについてまとめ

## はじめに
初心者なりにまとめたものになりますので、間違いにお気づきの方は、お手数ですが、コメント頂けると幸いです。

内容は、Orderメソッドのまとめになります。


## 目次
- orderメソッド の雛形
- orderメソッド 並び順のオプション
- orderメソッドとallメソッド

## orderメソッド の雛形
    変数 = モデル名.order("カラム名")
変数：お好みの変数を定義する
モデル名：並び替えたいテーブルを管理するモデルの名前
カラム名：並び替えさせたいカラムの名前

例.
テーブル名： mail
カラム名：id,  title,  content,  user_id,  created_at,  update_at
mailテーブルのuser_idで並び替えさせたい場合は、以下となります。

    hoge = Mail.order("user_id")

## orderメソッド 並び順のオプション
    hoge = Mail.order("user_id ASC")
    hoge = Mail.order("user_id DESC")
- user_idの後ろにASC, DESCが記述されていますが、以下の意味になります。
-ASC：昇順の意味のオプション（ascendの頭文字ASC）
-DESC：降順の意味のオプション（descentの頭文字DESC）

また、以下の表記は同じ意味を持ちます。

    hoge = Mail.order("user_id DESC")
    hoge = Mail.order(user_id: :DESC)

## orderメソッドとallメソッド
orderメソッドは、モデル内のデータを取得するallメソッドと併記することができる。
N+1の問題を解決するためにincludesを記述することもできる。

    hoge = Mail.all.order(user_id: :DESC)
    hoge = Mail.includes(:mail).order(user_id: :ASC)

## おわりに
私は、allメソッドとorderメソッドを別々に書いていて効かない事があったので、調べてまとめてみました。
- 偉大な参考文献
-orderメソッド
https://qiita.com/iverson3kobe0824/items/91f47eb5ef529e8231ac
-Railsドキュメント
https://railsdoc.com/page/model_order
Joomlaの環境構築していたら、「ERROR: for joomladock_joomladb_1  Cannot start service joomladb」でコケたので直した。

# はじめに

Joomlaの環境構築していたら、「ERROR: for joomladock_joomladb_1  Cannot start service joomladb」でコケたので直した。

# 最終更新日

2022年7月21日

# 環境の情報
OS
Ubuntu20.04

# 公式さまはこちら
https://www.joomla.org/
http://www.joomla.jp/

# 参考さま
https://mebee.info/2020/03/17/post-7561/
https://github.com/docker/compose/releases
https://hub.docker.com/_/joomla
https://linuxhostsupport.com/blog/how-to-install-joomla-4-0-on-ubuntu-20-04/
https://itexpert.tips/ja/joomla-ja/ubuntu-linux%E3%81%ABjoomla%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/
https://qiita.com/terufumi1122/items/8253a47ff24b64455fe5

# 作業


ymlファイルこんな感じで作って、
```
$ cat docker-compose.yml 
version: '3.1'

services:
  joomla:
    image: joomla
    restart: always
    links:
      - joomladb:mysql
    ports:
      - 85:80
    volumes:
      - ./joomladata:/var/www/html
    environment:
      JOOMLA_DB_HOST: joomladb
      JOOMLA_DB_PASSWORD: example

  joomladb:
    image: mysql:5.6
    restart: always
    environment:
      MYSQL_DATABASE: joomla
      MYSQL_ROOT_PASSWORD: example
    volumes:
      - ./mysql:/var/lib/mysql
    ports:
      - "3306:3306"
```
↓
compose upします。
```
$ docker-compose up -d
Creating network "joomladock_default" with the default driver
Pulling joomladb (mysql:5.6)...
5.6: Pulling from library/mysql
```
↓
ふんふん(　･ิω･ิ)♫
↓
バキッ
```
Status: Downloaded newer image for joomla:latest
Creating joomladock_joomladb_1 ... 
Creating joomladock_joomladb_1 ... error

ERROR: for joomladock_joomladb_1  Cannot start service joomladb: 
driver failed programming external connectivity on endpoint joomladock_joomladb_1 (XXXXXXXXXXXXXXXXXXX)
: Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use

ERROR: for joomladb  Cannot start service joomladb: 
driver failed programming external connectivity on endpoint joomladock_joomladb_1 (XXXXXXXXXXXXXXXXXXX)
: Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use
ERROR: Encountered errors while bringing up the project.
```

# こうした

ポートかぶりっぽかったので、ここを変更した。
```
$ cat docker-compose.yml 
    ports:
      - "3307:3307"
```

# そして

再び実行。
```
Joomladock$ docker-compose up -d
Recreating joomladock_joomladb_1 ... done
Creating joomladock_joomla_1     ... done
```
↓
OK！
![Screenshot from 2022-07-21 15-40-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/d101b6d9-169d-4899-0b8b-b831877e0987.png)
vCenterのパスワード(rootなど)を無期限化する方法

https://kb.vmware.com/s/article/2147144?lang=ja でも紹介されているが、

```
root@vcenter-vcs65 [ ~ ]# chage --help
Usage: chage [options] LOGIN

Options:
  -d, --lastday LAST_DAY        set date of last password change to LAST_DAY
  -E, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE
  -h, --help                    display this help message and exit
  -I, --inactive INACTIVE       set password inactive after expiration
                                to INACTIVE
  -l, --list                    show account aging information
  -m, --mindays MIN_DAYS        set minimum number of days before password
                                change to MIN_DAYS
  -M, --maxdays MAX_DAYS        set maximim number of days before password
                                change to MAX_DAYS
  -R, --root CHROOT_DIR         directory to chroot into
  -W, --warndays WARN_DAYS      set expiration warning days to WARN_DAYS

root@vcenter-vcs65 [ ~ ]# chage -I -1 -m 0 -M 99999 -E -1 root
root@vcenter-vcs65 [ ~ ]# chage -I -1 -m 0 -M 99999 -E -1 customerroot
root@vcenter-vcs65 [ ~ ]# chage -l root
Last password change					: Jul 08, 2019
Password expires					: never
Password inactive					: never
Account expires						: never
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7
root@vcenter-vcs65 [ ~ ]# chage -l customerroot
Last password change					: Jul 08, 2019
Password expires					: never
Password inactive					: never
Account expires						: never
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7
```
画像劣化を超解像する　Blind Super Resolution モデル DCLS-SRを使う

# 劣化画像をきれいにしたい

**【画像：input→output】**
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/089a2f3d-0083-4e46-e29d-50cd3e172fd5.jpeg width=400> <img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/e1383cfd-886e-049b-dbc4-bf1d4a083243.png width=400>

これくらいの小さい画像から、上のサイズに４倍のスケールアップしています。

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/089a2f3d-0083-4e46-e29d-50cd3e172fd5.jpeg>

Blind Super Resolutionは、さまざまな画像劣化に対応するための技術です。

# State of Art モデルを使う
Paper with CodeのBlind Super-Resolution on Set5 - 4x upscaling分野でトップのDCLS-SRモデルを使ってみましょう。

https://github.com/megvii-research/DCLS-SR

# 手順

リポジトリをクローン。
Pre-trained Weight をGitHubのリポジトリページから取得します。
**Pytorch==1.6**をインストールします（他のバージョンだとフーリエ変換の関数がうまく使えませんでした）。

```shell:inference.sh
python inference.py -opt "./options/setting2/test/test_setting2_x4.yml" -input_dir input_mages -output_dir output_mages
```

-opt で使いたいモデル（バージョンと、何倍にするか）の設定ファイルを指定し、設定ファイル内の Pre-trained WeightのPathを書き換えます。

# 結果

**【画像：input→output】**
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/d82b7e12-e984-e465-e274-eed603253321.jpeg width=400> <img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/334cbe85-c95e-76ef-d811-7403af23e257.png width=400>

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
最小限 の Kotlin を最短で学ぶ


### 1. 変数

変数は「var」。

```kotlin
var username: String = "some user name"
```

定数は「val」。Java の final と等価。

```kotlin
val API_DELAY_CONSTANT: Int = 100
```

null で初期化するには「?」。 null を利用可能にします。

```kotlin
var myString: String? = null
```

static な定数には「companion object」。

```kotlin
class Animal {
    companion object {
        const val DEFAULT_NUM_OF_EYES = 2
    }
}

animal.numOfEyes = Animal.DEFAULT_NUM_OF_EYES
```

遅れて初期化するには「lateinit」。

```kotlin
lateinit var user: User
lateinit var items: List<String>
```

### 続く

重要な最小限の部分からきちんと学んでいくこと大事。
[👉 最小限 の Kotlin を最短で学ぶ (フルバージョン)](https://android.benigumo.com/20180828/kotlin/)
google colabでSQLを使う


pythonの学習にgoogle colaboratoryはとっても便利だが、下の画像のようにSQLを触ることもわりとお手軽にできる。

<img width="75%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/6ef11b9d-47ca-4b30-632d-ced0df95f96e.png">


:::note
2023/3/3：よりモダンな方法に情報をアップデートした記事を書きました。よろしければこちらのほうをご覧ください。
:::

https://qiita.com/_jinta/items/479355d4709cd30d56c8


# 1. 諸々準備
```sh
!pip install ipython-sql==0.3.9

# サンプルデータのダウンロード・解凍
!wget https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip
!unzip chinook.zip
```

**ipython-sql**という、notebookのマジックコマンドでSQLを実行できるようにするためのライブラリを用いる（https://github.com/catherinedevlin/ipython-sql）。



```sh
%load_ext sql

# DBに接続(chinookは↑でダウンロードしたもの)
%sql sqlite:///chinook.db

# table一覧を出力
%sql select name from sqlite_master where type='table';
```

エクステンションを読み込んで、`%sql` を付けた行でSQLを実行できるようにする。まずDBに接続するのだが、今回用いるSQLiteは一つのファイルで管理されてるので、それを指定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/50a99033-2dfc-7381-8083-dde8bfefb17d.png)
table一覧を出力してる。ちなみに音楽系のデータで、アルバムとかアーティストとかのテーブルがあるっぽい。


# 2. クエリの実行
```SQL
%%sql
SELECT
  *
FROM
  albums
LIMIT 5;
```

`%%sql` コマンドを頭に付けたセルではSQLを実行できる（これが冒頭の写真）。なお、クエリの結果は `_` に格納されており、 `print(_)` で下のような整形された表が出力される。

<img width="65%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/d96fbc18-7732-f025-a94d-689a63f361d6.png">


# 3. pandasへの変換
```SQL
%%sql result << 
SELECT 
    Title,
    Name
FROM 
    albums
INNER JOIN artists 
    ON artists.ArtistId = albums.ArtistId
LIMIT 10;
```
`%%sql variable_name <<` から始めると、結果を変数に格納できる。 それをpandas.DataFrameに変換するには、 `.DataFrame()` とするだけ。

```python
df = result.DataFrame()
display(df)
```

<img width="75%" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/319b03b8-54f5-57b3-c68f-936c815e0c41.png">



# 4. csvからテーブルを作成
pandas経由でsqlite3を使って作成する（のが一番お手軽かと思う）。

```sh
# csvのdownload
!wget https://raw.githubusercontent.com/mcnakhaee/palmerpenguins/master/palmerpenguins/data/penguins.csv
```

```python
import sqlite3
import pandas as pd

df = pd.read_csv('penguins.csv')
with sqlite3.connect('penguins.db') as conn:
    df.to_sql('palmer', con=conn)
```

`sqlite3.connect(DB_path)` でデータベースに接続する。DBが存在すればそれに接続して、しなければ新しいDBが作成される。csvをテーブルにするにはpandasの `DataFrame.to_sql(table_name, connection)` が使える。

 
```
%sql sqlite:///penguins.db
```

１．と同じように作成したDBに接続すれば、さっきと同様にクエリ書いて実行できる。

```sql
%%sql
SELECT
  *
FROM
  palmer
WHERE
  body_mass_g > 3799
LIMIT 3;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665792/ea02b5ee-5ba3-a82f-bdcc-f32557fbaacf.png)


# 最後に
コードはコチラに置いてるので、そのままcolab立ち上げて触ってみたい方はぜひどうぞ！

https://gist.github.com/tanaka-jin/18986bec6f08775f712cdf4ef678ebfa

ipython-sqlは他にも色々機能あって面白そうでした。実務で使うかはあれですが、練習用には割とアリじゃないでしょうか。
WordPressのソースコードを全部ローカルにダウンロードする方法

:::note info
以下の手順を順番に実行してください。
複数の手順書にまたがりますので、ご注意ください。
:::

### TeraTermを使ったサーバログイン手順
https://qiita.com/TITL/items/cc8efece2d707a5c0def

1. 虫眼鏡を起動
2. 「Tera」と入力
3. TeraTerm起動
4. ホスト欄へ入力
5. 「OK」ボタンをクリック
6. ユーザ名、パスワードを設定
7. Authentication methodsを設定
8. ファイルを選択
9. 「OK」ボタンをクリック
10. ログイン成功

### php-fpm再起動手順
https://qiita.com/TITL/items/4b39636e137a694a4779

1.rootユーザになる
2.パスワードの入力

※全部ではなく2までを実施

### さらに以下の手順を実施

①. 以下のコマンド実行

```
tar czf wp.tar.gz /var/www/html/wp
```

②. 以下のコマンドを実行
コマンドの実行結果を確認してください。

```
pwd
```

③.TeraTermのメニュー→ファイル→SSH SCPを選択します。

④.表示されたダイヤログの下段のFrom:に以下を入力します。

```
　　②のコマンドの結果 + / + wp.tar.gz
```

⑤.下段To:の「…」でダウンロード先のお使いのPCの任意のフォルダを参照します。

⑥.「Receive」をクリックします。

⑦. ⑤のフォルダ内に作成された「wp.tar.gz」がWordPressのソースコード全部になります。
物事をシンプルにするための思考法~オッカムの剃刀,KISS,less is more~

## はじめに
「簡潔に説明してよ。」
「話長いよ！」
などと、上司や同僚からお小言をもらうことありませんか？

**でも、短く報告したら、それはそれで怒るくせに...**なんてこともありますよね？

でも、重要なものだけ、シンプルに絞って話せるのがスマートですよね。
この記事では、複雑な物事をシンプルに説明する方法を解説します。

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- 「話が長い」と怒られる人

## 結論
**とにかくシンプルに！**

## オッカムの剃刀とは
オッカムの剃刀とは、14世紀に哲学者が考え出した、物事をシンプルに捉える思考法です。
ある現象を説明するために、大量に出した仮説の中から、本当に必要なものだけを取り出そう、という考え方です。

下記のような具体例で考えてみましょう。

:::note alert
あと1年で未経験からプログラマーに転職したいけど、どうしたらよい？
:::

こんなことをやったらうまくいくのでは？というアイデアが下記の通り。

:::note warn
- 大学時代の友人に相談する
- 妻に相談する
- ポートフォリオを作る
- AWSの資格を取る
- 職務経歴書を書く
- Wantedlyに登録する
- ブログで情報発信する
- プログラミングの本を読む
- etc...
:::

...うーん、多すぎて、何からやったらいいか、わかりませんね！

この中でも、tん食活動に影響が大きそうなものだけに絞ってみましょう。

:::note
- ポートフォリオを作る
- 職務経歴書を書く
- Wantedlyに登録する
:::
3つくらいに絞れば、やれそうな気がしますね！
このように、要素をシンプルにすることが大事です。
大量のアイデアから要素を絞り込む際に活用できるフレームワークは下記の通りです。

https://qiita.com/YutaManaka/items/e6759414d7722a136ed1

https://qiita.com/YutaManaka/items/26f8d142d5d2f3eef459




## KISSとは
プログラミングの世界ではKISSも有名ですね。

Keep It Simple, Stupid. (シンプルにしておけ、バカが。)
Keep It Short and Simple. (短く、シンプルにしておけ。)
の略、と言われています。

コードをできるだけシンプルにすることで、保守性を高めよう、と言う考え方です。

## less is moreとは
「より少ないことは、より豊かなこと」と言う意味の諺です。
建築や服などのデザイン分野で使われ始めた概念です。
単純化することによって、デザインの幅が広がるので、かえって豊かな製品になる、ということです。

コードに関しても、同じことが言えます。
シンプルなほうが、修正を加える際にも簡単ですよね。
「自分が描いているコードは本当に必要なのか？」「後で見た他の人がわかる内容になっているか？」などと常に問うようにしましょう。

## おわりに
物事をシンプルに説明する思考法についてまとめました。
備忘録 LeetCode-141.Linked List Cycle

:::note warn
警告
この記事を読む前に一度自身で解いてみてください．
:::

## はじめに
この記事はアルゴリズム振り返り用メモ，
言語化練習用に作成した記事です．
#### URL
 [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/ )

## 対象者
特になし

## code
``` main.cpp
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        //1つも要素がない場合
        if(head == NULL)return false;
        
        //fast = 2つ先
        //slow = 1つ先
        ListNode* fast = head;
        ListNode* slow = head;
        
        while(fast != NULL && fast->next != NULL){
            //要素更新
            fast = fast->next->next;
            slow = slow->next;    
            
            //一致チェック
            if(fast == slow)return true;
            
        }

        //不一致
        return false;
    }
};
```
## 結果
Runtime: 19 ms, faster than 38.14% of C++ online submissions for Linked List Cycle.
Memory Usage: 8.1 MB, less than 16.55% of C++ online submissions for Linked List Cycle.

## 詳細

![LeetCode-141.Linked List Cycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/59681780-9561-4f5b-7601-73cfee1be099.png)

赤:fastポインタ
青:slowポインタ


要素の数0~10,000

fastは2つ先の要素を
slowは1つ先の要素を
参照する

この2つの要素が一致した場合にtrueを不一致の場合にfalseを
返すアルゴリズムを書く

#### より詳細に
画像上のケースの場合

fastとslowは3から開始する．

ループ処理内では一致orfastがnullになるまで処理を続ける

fastがスタート位置から2つ進め0
slowもスタート位置から1つ進め2
一致していないのでもう一回ループ処理

fastを0から2つ進め2
slowを2から1つ進め0
一致していないのでもう一回ループ処理

fastを2から2つ進め-4
slowを0から1つ進め-4
一致したのでtrueを返して終了

## 参考
[動画](https://youtu.be/kOhQ5bfpq2I)

## おわりに
英語が苦手&LeetCodeに慣れていない事もあって想像以上に苦戦し約40分ぐらいかかりました．
今後の目標としてはこのレベルの問題を10分前後で解くことを目標にコツコツ解いていきます．
Ubuntu20.04 にて、WordPressを環境構築する。

# はじめに

Ubuntu20.04にて、WordPressを環境構築する。

# 最終更新日
2022年7月22日

# 環境の情報
OS
Ubuntu20.04

# 注意
最新の状態を確認して下さい。

# 公式はこちら
https://ja.wordpress.org/
https://docs.docker.jp/compose/install.html
https://docs.docker.jp/compose/wordpress.html
https://docs.docker.jp/compose/reference/up.html
https://docs.docker.jp/compose/index.html#preserve-volume-data-when-containers-are-created


# 前提

docker-composeが、あること確認します。
こんな感じで表示されれば、問題ありません。
```
$ docker-compose --version
docker-compose version 1.29.1, build xxxxxx
無ければ入れてみましょう。
```


# 作業


どこでもいいですが、フォルダを作ります。
試しにデスクトップでも作ってみます。
```
デスクトップ$ mkdir my_wordpress
```
↓
移動します。
```
デスクトップ$ cd my_wordpress/
デスクトップ/my_wordpress$ ls
```
↓
ymlファイルを編集します。

```
デスクトップ/my_wordpress$ vi docker-compose.yml
```
↓
下記の状態にしてください。
```
デスクトップ/my_wordpress$ cat docker-compose.yml
version: '3'

services:
   db:
     image: mysql:5.7
     volumes:

    db_data:/var/lib/mysql
         restart: always
         environment:
           MYSQL_ROOT_PASSWORD: somewordpress
           MYSQL_DATABASE: wordpress
           MYSQL_USER: wordpress
           MYSQL_PASSWORD: wordpress

       wordpress:
         depends_on:

    db
         image: wordpress:latest
         ports:
    "8000:80"
         restart: always
         environment:
           WORDPRESS_DB_HOST: db:3306
           WORDPRESS_DB_USER: wordpress
           WORDPRESS_DB_PASSWORD: wordpress
    volumes:
        db_data:
```
↓
アップしていきます。
```
デスクトップ/my_wordpress$ docker-compose up -d
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
XXXXXXXXX: Pull complete
Digest: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Status: Downloaded newer image for wordpress:latest
Creating my_wordpress_db_1 ... done
Creating my_wordpress_wordpress_1 ... done
```
↓
http://localhost:8000/ へアクセスしてみましょう。
↓
http://localhost:8000/wp-admin/install.php
になりましたでしょうか。
言語設定をお好みでしてみてください。
![Screenshot from 2022-07-15 11-54-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/c12df1b5-4238-3f07-7d98-2f471d949f5f.png)
↓
ようこその設定をしてみましょう。
![Screenshot from 2022-07-15 11-55-46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/f19b7808-a620-6e94-35c6-fbad1e51d9bf.png)
↓
ログインしてみます。
![Screenshot from 2022-07-15 11-58-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/94f2142b-f86c-c5fd-9a27-15a8246848b7.png)
↓
無事に表示されたら、完了です！
![Screenshot from 2022-07-15 12-00-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148394/befc4cb0-212f-43a7-d5c9-56dac7562922.png)
html data- 情報取得方法

class id div 以外、data-属性情報取得方法

=========================================================================
var data_dataNo_array = [];
var data_status_array = [];
var data_info_array = [];

$("td[data-attribute='new_fileNo']").each(function (index) {
    data_dataNo_array.push($(this).attr('data-value'));
});
$("td[data-attribute='new_status']").each(function (index) {
    data_status_array.push($(this).attr('data-value'));
});
$("tr[data-entity='new_info']").each(function (index) {
    data_info_array.push($(this).attr('data-name'));
});

var length = data_dataNo_array.length;

for (var i = 0; i < length; i++) {
    //データアイテム取得する
    var fileNo = data_fileNo_array[i];
    var status = data_status_array[i].substring(9, 18); //{"value:'12344578';exculte:'あいうえお'"} 配列に変更後取得するか、文字列中のサブstringを取得する
    var info = data_info_array[i];
}

=========================================================================
Rails7のActionMailerでメールを送ろうとすると`500 Internal Server Error`が出る

## 結論
Railsのバージョンを7.0.2.4以降にすれば解決します。

Rails 7.0.2.4未満に存在するバグだそうです。
本家のリポジトリに同じようなissueが立っていました。
https://github.com/rails/rails/issues/44161

## 詳細
### 環境
- ruby 3.1.2
- rails 7.0.2.3

### やりたかったこと
[Ruby on Railsチュートリアル](https://railstutorial.jp/)に従ってwebアプリを作ってherokuにデプロイし、本番環境からMailgunを使ってアカウント有効化用のメールを送りたかった。

### やったこと
1.  `rails generate mailer UserMailer account_activation`で、アカウント有効化メールを送るメソッドを持つMailerを作った
1.  `ApplicationMailer`の`default from`を適切なメールアドレスに書き換えた
1.  `app/views/user_mailer/account_activation.html.erb`を編集してメールの文面を作った
1.  アカウントが作られた時にメールが配信されるよう `UserMailer.account_activation(@user).deliver_now`を適切な場所に追加した
1. configファイルに以下のような設定を記述した
1. herokuにデプロイ、[MailGunの設定](https://help.mailgun.com/hc/en-us/articles/217531258)をした
```config/encironments/production.rb
 config.action_mailer.raise_delivery_errors = true
 config.action_mailer.delivery_method = :smtp
 host = '<Herokuサブドメイン名>.herokuapp.com'
 ActionMailer::Base.smtp_settings = {
     :port => ENV['MAILGUN_SMTP_PORT'],
     :address => ENV['MAILGUN_SMTP_SERVER'],
     :user_name => ENV['MAILGUN_SMTP_LOGIN'],
     :password => ENV['MAILGUN_SMTP_PASSWORD'],
     :domain => host,
     :authentication => :plain,
  }
```

### 期待した挙動
アカウントを作るとメールが配信される。

### 実際の挙動
メールは配信されない。
Herokuのログを見ると　`Completed 500 Internal Server Error`と書かれている。

## 補足
どうやらconfigファイルの
`ActionMailer::Base.smtp_settings = {`
の部分が悪さをしているらしく、
`config.action_mailer.smtp_settings = {`
と書き換えれば期待通りの動きをしてくれます。
【Xcode】アプリのアイコンをユーザーが選択可能にする

# はじめに
https://moneyforward.com/engineers_blog/2017/03/29/ios10-3-alternateiconname/

私はこちらの記事を拝見させて頂き、無事実装することができました。
しかし、現在はやり方が少し変わっていたので最新の方法を載せておきます。

やり方はあまり変わりませんがSwiftUIでの記事がなかったので、今回はSwiftUIで実装します

# やり方
① プロジェクトを選択します。
② ターゲットを選択します。
③ 「General」を選択します。
④ 「include all app icon assets」にチェックを入れます。
![スクリーンショット 2022-07-21 22.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/64fbf288-a041-cf8c-ce97-0b6805daea6b.png)

アイコンを設定します。
ちなみにアイコン作成は[これ](https://github.com/onmyway133/IconGenerator)がおすすめです。
|アイコン1|アイコン2|
|-|-|
|![twitter_IIAxzzmz_400x400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/bea2bcbf-bdcc-e349-4542-a6d8994f1fb9.jpeg)|![twitter_nWoyKEtp_400x400.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/238fd621-8f27-45d3-6e20-548e18d25f75.jpeg)|

こんな感じになりました。
初期からある`AppIcon.appiconset`をコピペで複製してください。
![スクリーンショット 2022-07-21 22.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/984326cd-8925-44cd-45f9-99426fbc10de.png)

Xcodeではこのようになっているはずです。
![スクリーンショット 2022-07-21 22.10.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/848fa629-b40e-44c9-026a-2ed9d76b00b8.png)

④が`AppIcon`の赤文字になっています。
これは`AppIcon`から`AppIcon1`にファイル名を変更したのが原因です。
`AppIcon1`を設定してあげます。
![スクリーンショット 2022-07-21 22.11.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ce77c8ee-3cff-41a0-2185-c49120a4594a.png)

```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        List {
            Button("背景白アイコンに変更") {
                UIApplication.shared.setAlternateIconName(nil)
            }
            Button("背景黒アイコンに変更") {
                UIApplication.shared.setAlternateIconName("AppIcon2")
            }
        }
    }
}
```

```swift
// 初期アイコンを設定(AppIcon1)
UIApplication.shared.setAlternateIconName(nil)

// AppIcon2を設定
UIApplication.shared.setAlternateIconName("AppIcon2")
```

# 完成形
![sample_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/bc939ecd-9353-0c74-aec9-66bb422bd016.gif)

# おわり
個人的にはアイコンは固定がいいと思ってる
7/21-7/28の目標

新しいメッセージの部分を開発する。

・新規メッセージを記載
・表示のコンポーネントを作る。
・map関数で回して特定の数表示する
・if>3つ以上なら表示させず。
・もっと見るが押されたらさらに3つ表示する。
WindowsでNode.js+React+TypeScriptの開発環境を作る

## Node.jsをインストールする
既にNode.jsがインストールされている場合でNodistを使用したい場合は
Node.jsをアンインストールしてから、Nodistのインストールを行うこと。

### Nodistのダウンロード
Node.jsのバージョン管理をするためにNodistをダウンロード＆インストール
[Nodist Github](https://github.com/nullivex/nodist/releases)

### nodistコマンドが使用できるようになっているか確認
```
nodist -v
```

### 使用可能なNode.jsのバージョン確認
```
nodist dist
```

### 指定するバージョンのNode.jsのインストール
v14.17.2をインストールする場合
```
nodist + v14.17.2
```

### 指定したバージョンのNode.jsがインストールされているか確認
```
nodist list
```

### 指定したバージョンのNode.jsに切り替え
v14.17.2に切り替える場合
```
nodist v14.17.2
```

### Node.jsに合わせたnpmに切り替え
```
nodist npm match
```

### nodeコマンドとnpmコマンドが使用できるか確認
```
node -v
-> v14.17.2
npm -v
-> 6.14.13
```

## React+TypeScriptテンプレートの作成
以降の手順はアプリフォルダを作成したいところで実行
### Create Reat Appのインストール
```
npm install create-react-app -g
```

### React+TypeScriptテンプレートの作成
```
create-react-app my-react-app --templete typescript
```

### 作成したアプリフォルダへ移動
```
cd my-react-app
```

### アプリの起動
```
npm start
```
HTMLをJavaScriptで操作する仕組み

# はじめに
JavaScriptはフロントエンドまたはクライアントサイドの言語とされており、ブラウザで表示されている画面を操作することができます。
今回、どのような仕組みでJavaScriptがブラウザ上で機能しているかまとめました。

# HTMLがブラウザで表示されるまでの流れ
HTMLは文字の羅列であるため、そのまま表示すると見にくいデータです。そのため、JavaScriptやCSSでHTMLを装飾することで見やすくしています。具体的には文字の色や大きさを変えたり動きをつけたりします。
そのための手順は、
①HTMLをDOMツリーに変換する
②JavaScriptやCSSで装飾する
③ブラウザで表示する
という流れになります。

# HTMLをDOMツリーに変換する
DOM(Document Object Model)とはHTMLを解析しデータを作成する仕組みです。解析されたデータは階層構造となり、これをDOMツリーまたはドキュメントツリーといいます。
HTMLをDOMツリー変換して初めてデータを操作することができます。つまり、データをJavaScriptで操作するためにはHTMLをDOMツリーに変換する必要があります。

# JavaScriptやCSSで装飾する
HTMLをDOMツリーに変換した後JavaScriptやCSSで装飾していきますが、ここではJavaScriptを例にします。
手順は、
①HTMLを取得する
②イベントが発火する
③関数が実行される
という流れになります。

## JavaScriptでHTMLを取得する方法
JavaScriptを使用してDOMツリーからHTMLを取得する方法は、id名、class名、セレクタ名から取得する方法があります。

```JavaScript
//id名がexampleの要素を指定する場合
document.ElementById("example")

//class名がexampleの要素を指定する場合
document.ElementsByClassName("example")

//h1タグの要素を指定する場合
document.querySelectorAll("h1")
```

## イベント発火する方法
JavaScriptはある出来事が起きた後に関数が実行されるようにできています。ある出来事はイベントといい、出来事が起きることをイベント発火といいます。イベントの種類はページをロードすること、取得した要素をクリックすることなど様々あります。
```JavaScript
//取得した要素を変数exampleに代入する
const expample = document.ElementById("example")

//取得した要素expampleがクリックされると関数が実行される
expample.addEventlistener('click', 関数)

//取得した要素expampleにマウスを合わせると関数が実行される
expample.addEventlistener('mouseover', 関数)

//取得した要素expampleからマウスを外すと関数が実行される
expample.addEventlistener('mouseout', 関数)
```

## 実行される関数の例
イベント発火した後は、関数が実行されます。その例を記載します。
```JavaScript
//取得した要素を変数exampleに代入する
const expample = document.ElementById("example")

//取得した要素expampleにマウスを合わせると、expampleの背景が赤く変化する
expample.addEventlistener('mouseover', function(){
  example.setAttribute("style", "background-color:red;")
})

//取得した要素expampleからマウスを外すと、exampleの背景が元に戻る
expample.addEventlistener('mouseout', function(){
  expample.removeAttribute("style", "background-color:red;")
})
```
今日学んだこと

・src>pagesにそれぞれのページを記載していく。
pagesの中はなるべく汚さないようにして最小限の情報だけ書くようにする。

・各ページに対する要素はfetureの中にフォルダを作成して記載する。
futureの中で必要があればcomponentsに分けても良い

・共通のコンポーネントはsrc>sharedの中に記載する。
componentsはボタンとか
layoutにはエラー時のメッセージ表示を行うSnackbarが入っている。


【開発の流れ】
1.src>pagesの中にフォルダを作り、その中にファイルを作る。
2.loginの中のindex.tsxを作ったファイルにコピペする。
3.loginとなっているところの名前を作ったファイル名に直す。
4.featureの中にフォルダを作り、その中にファイルを作る。
5.そのファイル内にガシガシ書いていく。


【豆知識】
・実装が難しいUIが多い時はMaterialUIを導入する必要がある。
・export default memo(関数名)はreactの不用意な再レンダリングを防ぐもの
・const 関数名：FC = () => {
}
export default memo(関数名)
といった流れで書いていく
ターミナル表示の横幅を確認（シェルスクリプト）

こんにちは。
ターミナル（コンソール）表示の横幅について、80桁とすることが多いので、
念のため確認するために、80文字を表示し横幅ぴったりとなりました。

```console
$ ./80.sh 
12345678901234567890123456789012345678901234567890123456789012345678901234567890
```


```80.sh
#!/bin/sh
TOTAL=80; for i in $(seq $TOTAL); do printf "%s" $((i%10)); done; echo
```
PECL でインストールしたパッケージをアンインストールする

# 概要

- PECLにてインストールしたパッケージをアンインストールする方法をまとめる。

# 方法

- 下記コマンドを実行する。

    ```
    pecl uninstall パッケージ名
    ```

- また、インストール済みパッケージ名は下記で一覧で出力する事ができる。

    ```
    pecl list
    ```
Google Classromで自分のクラスの学生リスト取得

Google Classroomで学生ごとの処理をGASでやりたい場合、まず対象クラスの学生情報リストを取得することになります。Classroom APIでは日本語で「クラス」と言っている対象はCourseに該当しますが、面倒なので本稿ではクラス＝コース、の意味でまぜこぜで使います。

基本的には`Classroom.Courses.list().courses`でクラス(コース)のリストを取得し、`name`が対象クラスのクラス名に等しいものについて処理するのが簡単です(コースのidが分かっていれば`Classroom.Courses.get(id)` で一発でとれますが、筆者の知る範囲ではコースidを調べるには結局`list()`で取ってnameの一致でidを特定することになるので、だったらそこもコードに含めてしまえ、ということです)。

ただ、`list()`で返ってくる学生数は固定で30となっているようで、全員の情報を取得するには返ってくるリスト情報に含まれる`nextPageToken`を使って尽きるまで取り続ける必要があります。
Google APIの他のリスト系関数では`maxResults`で上限数を上書きできるものもありますが、どうも`Classroom.Courses`ではそもそもこのパラメータがないらしい…。

で、単純にググってもなかなかこれ！という記事を見つけられなかったので、自分でまとめてみたのが末尾のコードです。というか必要な情報は断片的にあちこちに散らばってるのでそれをつなぎ合わせただけですが。

要点は、`list()`で取得する学生リストには、更に続きがあれば`nextPageToken`が含まれていて、
リストを取りつくしたらnullが返ってくるので、`do { } while()` で`nextPageToken`がnullになるまで回す、というだけです。

んにしても上限30って少ない気がする…。

```JavaScript
function gSLtestByName() {
  let course = 'Google Classroomのリスト取得';
  let students = getStudentListByName(course);

  students.map(function(s) { console.log(s['profile']['name']['fullName']); });
}

function getStudentListByName(target) {
  let studentList = [];
  let courses = Classroom.Courses.list().courses;
  let course = courses.filter(function(c) {return c['name'] === target; })

  let nextPageToken = null;
  do {
    let students = Classroom.Courses.Students.list(
      course[0]['id'],{pageToken: nextPageToken}
    );
    studentList = studentList.concat(students['students']);
    nextPageToken = students.nextPageToken;
  } while(nextPageToken != null);

  return studentList;
}
```
PECL でインストールしたパッケージのファイルを確認する

# 概要

- PECLにてインストールしたパッケージのファイルの場所を出力する方法をまとめる。

# 方法

- 下記コマンドを実行する。

    ```shell
    pecl list-files パッケージ名
    ```

- また、インストール済みパッケージ名は下記で一覧で出力する事ができる。

    ```shell
    pecl list
    ```
PECL でインストールしたパッケージの一覧を出力する

# 概要

- PECLにてデフォルトチャンネルでインストールしたパッケージの一覧を出力する方法をまとめる。

# 方法

- 下記コマンドを実行する。

    ```shell
    pecl list
    ```

- ちなみに本知見は`$ pecl -h`の結果で見つけた。

    ```
    list  List Installed Packages In The Default Channel
    ```
Rails 7.0でないとActiveStorageのvariantに名前をつけられない

# 原因はバージョン
Rails 6.1を使ってるのにRails 7.0向けのガイドを見てました。昨日上司に「バージョン違いに気をつけてね」って言われたばかり！！

教えてもらってなかったらもっとハマってたはず…

# 困ったこと

ActiveStorageを使用して画像を保存することに挑戦していました。[Railsガイド](https://railsguides.jp/active_storage_overview.html#has-one-attached)を読みながら、セットアップや保存処理までは実装できましたが、画像サイズを調整する以下の記述がうまくいきませんでした…。

```ruby
# Railsガイド ActiveStorageの概要 has_attached_oneより引用

class User < ApplicationRecord
  has_one_attached :avatar do |attachable|
    attachable.variant :thumb, resize_to_limit: [100, 100]
  end
end
```

```ruby
undefined method `deep_symbolize_keys' for :thumb:Symbol
```

> 生成される添付可能オブジェクトでvariantメソッドを呼ぶと、添付ファイルごとに特定のバリアント（サイズ違いの画像）を生成できます。
[引用元：Railsガイド ActiveStorageの概要](https://railsguides.jp/active_storage_overview.html#has-one-attached:~:text=%E7%94%9F%E6%88%90%E3%81%95%E3%82%8C%E3%82%8B%E6%B7%BB%E4%BB%98%E5%8F%AF%E8%83%BD%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%A7variant%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%92%E5%91%BC%E3%81%B6%E3%81%A8%E3%80%81%E6%B7%BB%E4%BB%98%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%94%E3%81%A8%E3%81%AB%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%90%E3%83%AA%E3%82%A2%E3%83%B3%E3%83%88%EF%BC%88%E3%82%B5%E3%82%A4%E3%82%BA%E9%81%95%E3%81%84%E3%81%AE%E7%94%BB%E5%83%8F%EF%BC%89%E3%82%92%E7%94%9F%E6%88%90%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)

# 検索
大体自分が引っかかるようなエラーは他にも引っかかってる人がいるので検索してみました。

## まずはエラー文から
[Are active storage named variants still a thing?](https://discuss.rubyonrails.org/t/are-active-storage-named-variants-still-a-thing/77211)を見てバージョンが原因かも、と気づきます。

> I think it’s the other way around, it’s a new feature already visible in the edge guides you linked to, but not yet available in your version of Rails.

## Rails 6.1のガイドを見る

[Railsガイド](https://railsguides.jp/active_storage_overview.html)はRails 7.0向けだったことに気づくも、日本語版はお試し会員や有料会員にならないと古いバージョンのガイドを見れないことがわかりました。

[英語版のRailsガイド](https://guides.rubyonrails.org/index.html)を見てみたら[v6.1.6.1向け](https://guides.rubyonrails.org/v6.1/)が閲覧できたので、うまく動かない記述の箇所があるか探してみました。

## 6.1には書かれてなかった

[6.1.6.1向けのhas-one-attachedの章](https://guides.rubyonrails.org/v6.1/active_storage_overview.html#has-one-attached)には[困ったこと](#困ったこと)で引用した記述例がないことがわかり、Rails 6.1に対応してなかったことが判明…

# まとめ

自分含め、初学者はわからないことが多く様々なところから情報を集めて解決に取り組むと思います。情報を集めるときは __バージョンの違い__ を意識してみるようにしましよう！！
findコマンドでファイル名でファイルを検索する

# 概要

- findを用いてファイル名でファイルを検索する方法をまとめる。

# 方法

- 下記のように記載することでファイル名でファイルを検索する事ができる。

    ```
    $ find 検索対象ディレクトリ -name "ファイル名"
    ```

- 例えばカレントディレクトリ直下のどこかにある`example.txt`を探したい時は下記のようになる。

    ```
    $ find ./ -name "example.txt"
    ```
SQL　評価順序の話

#### はじめに


**SQLは実行順序を念頭に置いて書かなきゃダメ**という自戒の念を込めて、記事を執筆してます。。。
休日にネットに落ちてるSQL練習問題をやるます。

#### SQLの実行順序

まず、はじめにSQLには句毎に実行される順番がある。

```sql:sqlサンプル
SELECT
    hoge,hogehoge,hoge2 
FROM
    A 
WHERE
    hoge > 3;
```

まずはこんなSQL文があるとする。

**この時、SQLはどの句から実行していくのか？**

答えは以下の通り。

```sql実行順序
FROM句→WHERE句→SELECT句
```

**FROM句で対象のテーブルを絞り、WHERE句でレコードを絞り、SELECT句で列を絞る。**


だから、FROM句から実行されていく。
SELECT句から実行してたら、全テーブルのhogeという列を抽出する所から始める訳です。


#### テーブルを結合した時はどうなるの？

```sql:sqlサンプル(結合版)
SELECT
    hoge,hogehoge,hoge2 
FROM
    A
    JOIN B 
    ON A.hoge = B.hoge
WHERE
    hoge > 3;

```

この時の実行順序は以下の通り。
```sql実行順序
FROM句→ON句→JOIN句→WHERE句→SELECT句
```

これも考え方としては、
**FROM句でベースとなるテーブルを抽出し、ON句でテーブルとテーブルを結合するキーを抽出し、JOIN句でテーブルとテーブルを結合して、WHERE句でレコードを絞り、SELECT句で列を絞る。**

ON句→JOIN句でこれから使うテーブルを作るので、WHERE句が行われる前にJOIN句が実行される。


#### GROUP BYはどこで評価されるの？
```sql:sqlサンプル(結合版)
SELECT
    hoge
FROM
    A
    JOIN B 
    ON A.hoge = B.hoge
WHERE
    hoge > 3
GROUP BY
  hoge;

```

GROUP BYを入れた時の評価順序は以下の通り。
```
FROM句→ON句→JOIN句→WHERE句→JOIN句→SELECT句
```

GROUP BYはWHERE句の後で処理がされる。
WHERE句で行を絞った後にグルーピングする為です。

#### どうしてGROUP BYでASが使えないのか？
GROUP BYで列別名が使えないのは、この評価順序の問題だったりします。

**GROUP BYはSELECT句よりも前に実行されます。**

SELECT文で列別名を定義しているので、GROUP BYが実行する段階では列別名は存在しない訳です。

同じくWHERE句でも列別名が使えないのは、そういうことです。

SELECT句よりも後に評価される句ならば、列別名が使えたりします。
例えば、ORDER BYとか。。。

#### 最後に
SQLの評価順序を意識することはとっても大事。
Oracle.DataAccess.dllをungacできない

今回はOracleDBのアンマネージ・ドライバを利用した開発の中で遭遇した事象についてのお話です。

# Problem

OracleDBのODP.NETドライバのアセンブリをグローバル・キャッシュ・アセンブリ（GAC）にインストールするには、アセンブリに付属するコマンド `OraProvCfg.exe` を利用します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/87e31dda-2536-4c96-5c07-44bffa0f9094.png)

コマンドプロンプトを「管理者として実行」して次のようなコマンドを実行します：

```bat
> oraprovcfg /action:gac /providerpath:Oracle.DataAccess.dll
INFO: oracle.dataaccess.dll is registered successfully in GAC.
```

これによりHACにアセンブリが登録されます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/9e004db1-e4a6-2353-69ff-4e34ea940940.png)

では削除はどうでしょう？
公式に案内されているコマンドは次の通り（これも管理者として実行）：

```bat
> oraprovcfg /action:ungac /providerpath:Oracle.DataAccess.dll
INFO: oracle.dataaccess.dll is un-registered successfully from GAC.
```

出力メッセージは「GACからの登録解除に成功した」とのことで、結果は・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/39c5f57e-8f0e-67d9-0b6f-c18fc0a94456.png)

消えません。
環境によるのでしょう。私の環境ではGACからアセンブリが削除できませんでした。


# Solution

Visual Studioに付属する `gacutil.exe` （グローバル・アセンブリ・キャッシュ・ツール）を利用します。
開発者コマンドプロンプトを「管理者として実行」します：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/a729e7c2-925c-ec46-9470-57ac82255179.png)

次のようにコマンドを実行します：

```bat
gacutil /u Oracle.DataAccess
Microsoft (R) .NET Global Assembly Cache Utility.  Version 4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.


アセンブリ: Oracle.DataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64
アンインストール済み: Oracle.DataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=AMD64
アンインストールされたアセンブリの数 = 1
エラーの数 = 0
```

すると、消えました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/d6bbbc06-bf3f-bbab-d3d4-dfad4838fa21.png)
Detectron2をwindowsで動かす

# 前置き
Detectron2というFacebookが開発したAIライブラリがいろいろできて使い勝手が良い。物体認識、インスタントセグメンテーション、キーポイント抽出と姿勢認識など。学習済みモデルが用意されているため、10枚程度のデータでも結構いい結果が得られる。アノテーションはCoco形式で用意すればよいので、[CocoAnotator](https://github.com/jsbroks/coco-annotator)などが使える。

今までColabで動かしてたんですが、ColabではGPU制限に引っ掛かったりGPU性能が足りなくなりつつあったので、ローカルGPUを使うことに。当初は、Jupyterを立ち上げて、Colabのローカルランタイムを使ってたりもしたんですが、Windowsで直接使えたほうがよいなぁと。

[detectron2-windows](https://github.com/DGMaxime/detectron2-windows)というgithubもあったけど、最終更新が2年前で古い。要求されるcudaも古いので、入れるのがめんどう。いろいろ探していたら他にも二つほど、参考サイトを見つけた。

- [Detectron2 による物体検出，インスタンス・セグメンテーション（Detectron2，PyTorch, Python を使用）（Windows 上）](https://www.kkaneko.jp/cc/deepim/detectron2.html)
- [How to Install Detectron2 on Windows 10 or 11 –2021(AUG) with the latest build(v0.5).](https://medium.com/@yogeshkumarpilli/how-to-install-detectron2-on-windows-10-or-11-2021-aug-with-the-latest-build-v0-5-c7333909676f)

ここを参考にしたら最新cudaでdetectron2が動いたので以下にまとめおく。


# 前提
以下の設定・インストールが済んでいる

- git(for windows)
- miniconda
- CUDAは11.7, cudnnは8.4
- [Microsoft build toolのMicrosoft Visual C++](https://visualstudio.microsoft.com/visual-cpp-build-tools/)
  - 私が使ったバージョンはMSVC v142
<img alt="MSVCで入れたもの" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82999/21e092f2-e0b1-97d4-21b9-62be95158249.png" width="40%" align="right">


# 実際の作業
detectron2という名前でAnaconda環境を作っていく。

```
conda create -n detectron2 python=3.7
conda activate detectron2
python -m pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu116
pip install cython
pip install pycocotools
git clone https://github.com/facebookresearch/detectron2.git
```
detectron2/setup.pyの80行目:extra_compile_args["nvcc"]に引数を1行追加する。
```diff_python
                "-D__CUDA_NO_HALF_CONVERSIONS__",
                "-D__CUDA_NO_HALF2_OPERATORS__",
+                "-DWITH_CUDA",
            ]
        else:
            define_macros += [("WITH_HIP", None)]
```
その後、detectron2をインストール。
```
pip install -e detectron2
```
これでセットアップ完了。

以下、テスト
```
pip install opencv-python
cd .\detectron2\tests
wget https://raw.githubusercontent.com/yogeshkumarpilli/detectron2/master/tests/test_window.py
python .\test_window.py
```
Django Formクラスのprefixの紹介

# はじめに

DjangoでFormを使ったviewを作ってて以下のような不便を感じたことはありませんか？
「1つのviewに2つのFormを表示してるんだけど、同じname属性を持ったinputが2つできちゃって、POSTがわかりずらい」
こんな時に役に立つのが、Formのインスタンス作成時に指定できるprefixです

# コードの紹介

## サンプルとして定義したmodels.pyとforms.py

今回はModelFormでサンプルを示すので、事前にmodels.pyとそれに基づいたforms.pyを定義しますね

```python:models.py
from django.db import models

# Create your models here.
class TestModel(models.Model):
    name = models.CharField(max_length=100)

class SampleModel(models.Model):
    name = models.CharField(max_length=100)
```

```python:forms.py
class TestForm(forms.ModelForm):
    class Meta:
        model = models.TestModel
        fields = '__all__'

class SampleForm(forms.ModelForm):
    class Meta:
        model = models.SampleModel
        fields = '__all__'
```

## prefixを使わないviewsの書き方

```python:views.py
class CreateTest(generic.CreateView):
    template_name = 'reg.html'
    form_class = forms.TestForm
    model = models.TestModel

    def post(self, request, *args, **kwargs):
        print(request.POST)
        return super().post(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['form2'] = forms.SampleForm()

        return ctx
```

このviewを以下のtemplateで表示してみます
```html:reg.html
<form method="post">
    {{ form }}
    {{ form2 }}
    <button>submit!</button>
</form>
```

以下のようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705535/05b96239-ccdb-50ed-3c5e-af14f7fd73ac.png)
ふたつのInput要素のname属性が重複してしまっているのがわかりますね
2つのInput要素には「ほげ」「ふが」と順に入力してsubmitボタンで送信してみます

以下のようにとれました
※csrf_tokenの中身は長いので省略してます
```
<QueryDict: {'csrfmiddlewaretoken': [''], 'name': ['ほげ', 'ふが']}>
```

これだとどっちのFormにどっちを渡せばいいかわからないですよね。templateで定義している順番でリストも構成されているので、requesr.POST['name'][0]と指定してあげてもいいですが、またinput要素が追加されてが順番が変わってしまうかもしれません

## prefixを使ったviewsの書き方

こんなときは「name属性の値を変えてしまいたい」と思いますよね。けどModelFormを使っているので、簡単に変えることはできません
そんなときに役に立ちそうなのがprefixです

```python:views.py
class CreateTest(generic.CreateView):
    template_name = 'reg.html'
    form_class = forms.TestForm
    model = models.TestModel
    success_url = 'qiita'

    def post(self, request, *args, **kwargs):
        print(request.POST)
        return super().post(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        ctx = super().get_context_data(**kwargs)
        ctx['form2'] = forms.SampleForm(prefix='test')

        return ctx
```

この状態で構成されるtemplateを見てみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705535/48f3d854-3292-7c19-ad94-4c1e439f9ba4.png)

form2のinput要素のnameが[prefixに指定した文字列-元のname属性名]となりました
これによりrequest.POSTで受け取ると別々の値として受け取ることができます

```
<QueryDict: {'csrfmiddlewaretoken': [''], 'name': ['ほげ'], 'test-name': ['ふが']}>
```

# 結言

prefixを使うと重複した名前をもったinput要素をうまい感じに管理できました
[Power BI Tips]null値が含まれるデータのテーブル表示について

# 背景
Power BIのテーブルは手軽で便利ではあるのですが、ちょっとしたワナがあったりします。
今回は、ID件数とテーブルに表示されている件数が合わないという事象があり、回避するまで少々時間を取ってしまいました。
蓋を開けてみると、原因はなんてことないことではあるんですが。

##### よくあるデータ表
| ID| 項目名| 総販売個数 |
| --- | --- | --- | 
| 1 | Product A | 10| 
| 2 | Product B | 0| 
| 3 | Product C | | 
| 4 | Product D | 20| 

このとき、IDおよび総販売個数は整数で、IDは「集計しない」としておきます。
Product C の総販売個数はnullです。
これをそのままテーブルで表示するようにすると、Product Cが消えることがあります。


<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599035/a14581f8-7929-feff-8593-104cf3a2fa81.png"  width=400>

このとき、カードを追加して「IDのカウント」を表示すると、「4」と表示されます。
テーブルは3行ですので、例えばテーブルをダウンロードした時には、件数とデータが合わなくなってしまいます。

# 回避策
 回避策は簡単で、null値が含まれる項目を「集計しない」にするだけです。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599035/7c96ffdd-9d81-6367-8686-9fc6f1a3a92b.png" width=300> → <img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599035/b1fb6aa0-a50e-65b5-b8c8-3781c0140bcb.png" width=300>

null値を持つ行が表示される一方で、「集計しない」にすることで合計行が表示されなくなります。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599035/016f9058-ca58-f54b-308b-4ef8be448991.png" width=300>

null値が含まれる項目で、合計や平均など計算を伴う表示形式の場合は、null値を含む行はテーブルには表示されません。
複数の項目が該当する場合は、すべての項目について「集計しない」にする必要があります。

データを取り込むときにnullを「0」に変換すればいい話ではあるのですが、例えばある店舗では扱っていない製品であるなど、null自体に意味を持つこともありますので、上記のワナには注意が必要です。
【ShellScript】for文の使用方法

現在業務でシェルスクリプトのプログラムを作成しているので、
for文の使用方法についてまとめます。

## for文の使い方

基本的な使い方は以下のような記載方法です。

```bash
for 変数名 in 繰り返し実行したいリスト
do
  処理
done
```

実際に簡単な処理を書くと以下です。

```bash
for envitem in aaa bbb ccc ddd
do
  echo $envitem
done

```

以下が実行結果です

```bash
aaa
bbb
ccc
dd
```

変数envitemにaaaが渡され、echo $envitemでaaaをechoします。

この処理をbbb ccc dddも繰り返しで実行してます。

## 使用用途

同じ処理を複数に対して実行する際に使用します。

例でいうと
あるファイルを20台のサーバに対して転送する際に使用します。

for文を使わない場合：

```bash
scp testfile.txt examplesv01:/tmp
```

上記を20台実行しなければなりません。（めんどくさいですね、、、）

for文を使うと以下だけで実行できます

```bash
for server in examplesv01 examplesv02 ...
do
  scp testfile.txt $server:/tmp
done
```

ホスト名が連番なら以下のようにできます

```bash
serverlist=(examplesv{01..20})# examplesv01-20までの配列を作成
for server in ${serverlist[@]}
do
  scp testfile.txt $server:/tmp
done

```

## 配列の変数分処理する場合

配列が格納されている変数を使用してfor文で処理する場合は以下のように記載します。

```bash
testlist=(aaa bbb ccc ddd)
for test in ${testlist[@]}
do
  echo $test
done

```

実行結果が以下です。

```bash
aaa
bbb
ccc
ddd
```

[@]を変数名部分に入れる必要があります。

これがない場合は、以下のように最初の部分（aaa）のみが処理されます

```bash
testlist=(aaa bbb ccc ddd)
for test in $testlist
do
  echo $test
done

```

## 補足 zshの場合

先ほどまでの記載部分はbashを想定してます。
しかし、zshの場合は[@]を入れなくても配列分処理されるようです。

```bash
~$ echo $SHELL
/bin/zsh
~$ lists=(aaa bbb ccc)
~$ for list in $lists
for> do
for>   echo $list
for> done
aaa
bbb
ccc
```

私はSESのインフラエンジニアで、今まで3つの現場を経験してますが、
どの現場のサーバも基本的にはbashを使用していたので、
あまり気にすることではないかもしれないですが、
Macbookで作業していたりするとzshを使用しているかと思いますので、
bashの気持ちで書いてると思った通りの処理ができないかもしれないですね。

ちなみにこちらは.shファイルに記載して実行したものではなく、
ターミナル上で実行しているため、zshになってましたが、
.shファイルに記載する場合は、文頭にどのシェルを使用するか記載するので、
基本的にはbashかと思います。

以上です。