OmniAICreator/Qiita-1.07M huggingface dataset:
Cypress[E2E]のTypescript化を作成する

## Table of Contents

```
0. 前提
1. Cypressのインストール
2. Setting Up TypeScript
3. Fix cypress.config.json
```

## 0.前提

`Project Dependencies`

```
"react"
    version "18.1.0"
"react-dom"
    version "18.1.0"
"typescript"
    version "4.6.4"
"vite"
    version "2.9.9"
```

`e2e Dependencies`

```
"cypress"
    version "9.6.1"
"typescript"
    version "4.6.4"
```

## 1. Cypressのインストール

### 1-1. Cypressのインストール

```
$ yarn add -D cypress
```

package.jsonに起動用コマンドを追加

```
"scripts": {
    ...other scripts
    "e2e:open": "cypress open"
}
```

### 1-2. Cypressの基本ディレクトリを作成する


`yarn run e2e:open`を実施すると、project directory以下に`cypress`というディレクトリが作成されます。

```
{project_directory}
    |- cypress.json
    |- cypress
    |- fixtures
    |- integration
    |- plugins
    |- support
```

## 2. Setting Up TypeScript

1.で作成したCypress DirectoryをTypesriptに対応していきます。

### 2-1. Typescriptのインストールとtsconfig.jsonの作成

```
$ yarn add -D typescript   # 入っている場合は不要
$ touch cypress/tsconfig.ts
```

```cypress/tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["es5", "dom"],
    "types": ["cypress"]
  },
  "include": ["**/*.ts"]
}
```

### 2-2. .jsファイルを.tsファイルにrenameを実施する

該当するディレクトリは以下。

```
{project_directory}/cypress
|- fixture
|- integration
|- plugins
|- support
```

`cypress/fixture`

上記についてはjson fileになるので、そのまま残していきます。

`cypress/integration`

sampleのファイルが存在しているだけなので、適当に書き直す

`cypress/plugins`

index.jsについては、jsの記載が残っているためrenameと書き直しを実施していきます。

```cypress/plugins/index.js
module.exports = (on, config) => {
  // `on` is used to hook into various events Cypress emits
  // `config` is the resolved Cypress config
}
```

```cypress/plugins/index.ts
// eslint-disable-next-line @typescript-eslint/no-empty-function no-unused-vars
export default (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {};
```

`cypress/support`

supportについては、`cypress/support/index.js`はそのまま`cypress/support/index.ts`にrename。
`cypress/support/commands.ts`については、丸っと記載を修正します。
簡単なサンプルコードを追加しておきます。

```cypress/support/commands.ts
/// <reference types="cypress" />
declare namespace Cypress {
  interface Chainable<Subject> {
    clickLink(label: string): void
  }
}

Cypress.Commands.add('clickLink', (label: string | number | RegExp) => {
  cy.get('a').contains(label).click()
})

```

## 3. Fix cypress.config.json

最後にlocalで起動するServerを見るように`cypress.json`に記載します。

```cypress.json
{
  "baseUrl": "http://localhost:3000"
}
```

最後に起動して確認。

```
$ yarn dev
$ yarn e2e:open
```

```cypress/integration/sample.spec.ts
describe("", () => {
    it("/", () => {
        cy.visit("")
        cy.location().url().should("include", "/")
    })
})
```

## Refs

[Cypress Installation](https://docs.cypress.io/guides/getting-started/installing-cypress)
[Cypress Typescript](https://docs.cypress.io/guides/tooling/typescript-support#Install-TypeScript)
[Repo](https://github.com/Ntakuya/vite-react-recoil-cypress/tree/feature/cypress-typescript)
progate 整理　メモ

# ログアウト機能を作成する
ログインするときに```session[:user_id]```に代入していたから。
これからidを空にすればいいのかな？
```nil```にしていたことを思い出した。

## ログアウトのリンクを作成
```application.html
.
.
.
        <li>
          <%= link_to("ログアウト", "/logout") %>
        </li>
.
.
.
```
## ルーティングを設定
```　routes.rb
.
.
.
get "logout" => "users#logout"
.
.
.
```
## サーバーのレスポンスのアクションを設定
```users_controller.rb
class UsersController < ApplicationController
.
.
.
  def logout
    @session[:user_id] = nil
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end
.
.
.
end
```
これをすれば良かったかな？
## 試してみる
NoMethodError in UsersController#logout
undefined method `[]=' for nil:NilClass
```users_controller.rb
def logout
    @session[:user_id] = nil # <---error
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end
```
```@session[:user_id] = nil```の部分がダメみたい。
### 解決
```@```がついていた。

# ログイン中とログアウト中の場合にヘッダーの違いを出せ。
## ログイン中
・投稿一覧(/posts/index)
・新規投稿(/posts/new)
・ユーザー一覧(/users/index)
・ログアウト(/logout)

## ログアウト中
・TweetAppとは(/about)
・新規登録(/signup)
・ログイン(/login)

ログインの状態を表すものは```session[user_id]```だ。
これを使って表していこう。

## application.html.erbに条件をつける
```html
.
.
.
<ul class="header-menus">
        <% if session[:user_id] %>
          <li>
            現在ログインしているユーザーのid:
            <%= session[:user_id] %>
          </li>
          <li>
            <%= link_to("投稿一覧", "/posts/index") %>
          </li>
          <li>
            <%= link_to("新規投稿", "/posts/new") %>
          </li>
          <li>
            <%= link_to("ユーザー一覧", "/users/index") %>
          </li>
          <li>
            <%= link_to("ログアウト", "/logout") %>
          </li>
        <% else %>
          <li>
            <%= link_to("TweetAppとは", "/about") %>
          </li>
          <li>
            <%= link_to("新規登録", "/signup") %>
          </li>
          <li>
          <%= link_to("ログイン", "/login") %>
          </li>
        <% end %>
      </ul>
.
.
.
```
前の問題の条件をつなげるだけだった。
これでどうだろうか？
## 「localhost:3000/logout」に対するルーティングがありません
どういうことだろうか？
ログアウトに対するルーティングが設定されていない。
getではなくpostだろうか？
```
 post "logout" => "users#logout"
```
## ログアウト用のリンクのmethodがpostに設定されていません。
リンクをポストにしなければならないのかな？
どのようにすればいいか忘れた。
調べる。
```html
<%= link_to("ログアウト", "/logout", {method: "post"}) %>
```
にするらしい。
なるほど
```get```はページを表示させるためのメソッドだから
```post```を使うのかな。
そして
```link_to```に{method: "post"}をつけることによって```post```のメソッドになるのか。
web3 関連サイトのデザインまとめ


## Marketplace

### OpenSea

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/f964684b-c7b9-5db5-3d59-3da2ebcab10a.png)

### Rarible

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/c87580f3-8a53-ed11-3612-b10c57fcc910.png)

## Media

### mirror

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/f59af2a8-53e8-91a9-a3f2-1571498c9e0e.png)

## Finance

### SushiSwap

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/50c121d3-042c-016e-c815-750e0b6e526a.png)


### coinbase

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/07d97468-5f81-a489-8946-5aa852f8de45.png)



## Learning

### buildspace

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/8ee3cc74-eb70-78e8-2660-67dcab9e0bf8.png)


## Tools

### ENS

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/b721d1dc-9c70-c949-8931-fba08daa18a1.png)

### POAP

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/3e27b590-634c-1416-426f-543eb0b2f6c0.png)


### alchemy

alchemyapi![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/9e994542-b07d-b0d6-796c-8ee689d779cf.png)


### Snapshot

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/a02c0d77-912d-9f56-d3a3-0bd8ff76ec19.png)

### Dework

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/23fb42d9-ec81-d852-b115-86fc8ba6b515.png)


### Guild

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/eb06966a-a7d2-0052-e68b-04fa979d3881.png)



## DAO

### Nouns DAO

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/3244f88b-10f4-796f-d2f2-3f62295dd3ed.png)


## NFT

### BAYC

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/8ccdb5a3-e9cc-0035-8f92-dab7faabb21a.png)

### Clone x

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/c7b5b0c9-589c-e66c-f99e-593385d4de31.png)


### Azuki

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/db99d76c-ace5-4f9a-8a3d-c8ad23169cdb.png)

### CrypotoPunks

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/7894ac73-2eef-0278-7536-6dd8da556599.png)

### Nishikigoi NFT

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/4b28268b-45a8-58ca-cb97-2561038ed107.png)


### pssssd

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29088/305df3a1-249b-4ad9-8740-2e4fc1eb0b07.png)
Vue.js アニメーション機能を使う

## vue.jsに標準で備わっているアニメーション機能

要素の追加や削除などでただ表示を変更するのではなく、スライドや、フェードイン/フェードアウトなどアニメーションを利用しユーザー体験をあげることができる機能がvue.jsには標準で備わっているのでその機能を使ってみる。

## slidedown/upを使い要素を表示する

まずはボタンがクリックされた場合、アニメーションの対象の要素がslidedownで表示され、もう一度ボタンをクリックしたときにslideupで消えていく機能を実装する。

表示側

```html
<div id="app">
  <input type="button" value="表示/非表示" v-on:click="onclick">
  <transition>
    <div id="main" v-show="flag">トランジションを使いアニメーションを実装する</div>
  </transition>
</div>
```

表示側に必要なことは「transition」要素でアニメーションによって表示切り替えをしたい要素を囲うこと。このとき注意しなくてはいけない点は、「transition要素の配下に指定できるのは一つの要素のみ」ということ。divタグが同列に並ぶような構造をtransitionの中に作ってしまうと警告が出ます。

Vue側

```jsx
Vue.createApp({
  data: function() {
    return {
      flag: false
    }
  },
  methods: {
    onclick(){ 
      this.flag = !this.flag
    }
  }
  }).mount('#app')
```

Vue側は至ってシンプルな構造。表示側のtransition要素を表示するかしないかを判定するため「flag」とボタンクリックによって「flag」を切り替えるメソッドを準備するだけです。

CSS

```
#main{
  border: 1px solid #000;
  width: 350px;
  overflow: hidden;
}

.v-enter-active, .v-leave-active{
  transition: height 1s;
}

.v-enter-from, .v-leave-to{
  height: 0px;
}

.v-enter-to, .v-leave-from {
  height: 100px;
}
```

アニメーション機能を実現する部分の多くはこのCSSファイルです。

一番上の「#main」は通常のcssの記述で、アニメーションに必要なのはそれ以外部分です。

- .v-enter-active

  このクラスはアニメーションを付与する要素を表示するときに対象の要素に付与されるクラスです。

- .v-leave-active

  このクラスはアニメーションを付与する要素を非表示するときに対象の要素に付与されるクラスです。

 上記二つのクラスに対して記述されている

```
transition: height 1s;
```

というプロパティは表示/非表示の変化をどのように行うかを定めている部分です。

```
表示側で使用したtransition要素を指定: 変化させる属性 変化させるスピード（秒数指定）;   
```

その他、cssで指定しているクラスの意味

- v-enter-from

  要素を表示し始めた時の状態を指定

- v-enter-to

   要素を表示し終わった時の状態を指定

- v-leave-from

    要素を非表示にし始める時の状態を指定

- v-leave-to

    要素を非表示にし終わったときの状態を指定

 slidedown/upでは表示と非表示は全く逆の動作となるため「v-enter-active, v-leave-from」「v-enter-to, v-leave-to」と一括りにしています。

## keyframesによるアニメーション制御

アニメーションには、「CSS Transition」と「CSS Animation」と二つの種類がある。

「CSS Transition」は先程のslidedown/up の方法で比較的シンプルな実装と表示ができるもの。

「CSS Animation」はもう少し細かい設定ができ表示もよりリッチになる方法。

「CSS Animation」を使用する時は kyeframeを使いCSSファイルで細かい設定を行う。

  先程のslidedown/upで使用した、HTML、Vue.jsをそのまま利用しCSS側だけを変更することによって表示方法に変化をつける。

CSS

```
#main{
  border: 1px solid #000;
  width: 350px;
  overflow: hidden;
}

@keyframes slide-in {
  0%{
    transform: translateX(100%);
  }
  10%{
    transform: translateX(20%);
  }
  100%{
    transform: translateX(0%);
  }
}
.v-enter-active {
  animation: slide-in 1.5s;
}

.v-leave-active {
  animation: slide-in 1.5s reverse;
}
```

@keyframes　slide-inとしているのは変化させる一連の状態に名前をつけています。あとで出てくるv-enter-active、v-leave-activeでここでつけた名前を使用します。

keyframesの中には

```
0% {
  transform: translate
}
```

 という表記がありますが、これは「変化を起こしたている時の途中の状態」を% で表し、その中身として「その％の時にどのような状態であるか」を記述いているものです。今回の場合は、表示する状態になってから、0%,10%と左にスライドしていき100%の状態で本来その要素が表示されるべき場所におさまる、というような実装になっています。

最後に、slidedown/upでも登場したv-enter-active、 v-leavea-ctiveの中身ですが、

```
animation: slide-in 1.5s;

animation: slide-in 1.5s reverse;
```

```
アニメーションを行う: keyframesで作成したslide-inを使う　　変化にかける時間;

アニメーションを行う: keyframesで作成したslide-inを使う　　変化にかける時間 表示する時の変化とは逆の手順で変化される;
```

というようなことを書いています。
Blue Team Level 1を取ったので少し経験をシェア

![148920.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893830/83f2f394-2bf8-e7a6-0225-c03a535aeddd.jpeg)

## 紹介

Blue Team Level 1 という試験についてまったく知らない方が多くいると思います。qiitaで検索しても出てこなくて、googleでもそこまで有名ではなさそうだけど、とてもおもしろいコースと試験だと感じたので応募から証明書をもらうまでの経験をシェアしていきたいと思います。

Blue Team Level 1 （BTL1）は Security Team Training Ltd. というイギリスの機構が行うコースと試験です。オフィシャルサイト ( https://securityblue.team/why-btl1/ ) で見ると、範囲としてはセキュリティ基本（ネットワーク等）、フィッシング分析、脅威インテリジェンス、デジタルフォレンジック、セキュリティ情報とイベントの監視（SIEM）、インシデント対応とのことで、簡単に言うとセキュリティ・防御・対応といったようなレッドチームに対するブルーチームの知識とスキルです。

記事を書く時点でまだ英語だけ実施していますし、開催自体もやく 2 年前なので、知名度まだまだですが、ネットでの評価としてはこのブルーチームの分野で、あまりやすいコース（勉強資料・ラボ）と試験がなくて、さらに試験は実技受験なので暗記というより実際のスキルが得られるかと思います。もちろんこれからサイバーセキュリティの重要性が必ず上がってくるので、セキュリティ業務ではなくても学んだ方が良いと思います。

## 勉強や受験

難易度について、Paul Jerimy さんのロードマップ ( https://pauljerimy.com/security-certification-roadmap/ ) を見るとちょうど真ん中ぐらいです。BTL1 のサイトで見ると特にコースを受ける前提条件がないということです。自分はその前に 1 ヶ月ぐらいで Comptia Security+ を勉強して取って、その後ネット（udemy 等の有料ソースも良い、youtube のような無料ソースもいっぱいあります）でいろいろフォレンジックツールの紹介やペンテスト等の知識を補充して、大体 2 ヶ月弱で BTL1 のコースや試験を完走しました。

さきほど言及したけど、試験は完全に実技試験で、昔は書く部分もあったけど現在はなくなりました。24 時間の中にある環境（侵入されたマシンとか）でフォレンジックツールやコマンドでいろいろ調べて、質問に答えるという試験です。自分は 1 回目の試験で合格したけど 90% 正解にならずシルバーコインしか貰えません（90% 以上だとゴールドコイン）。

ヒントとしては、自分が調査していることをちゃんとタイムラインに整理する、ツールやコマンドの使い方に慣れる、そもそも OS・ネットワークの基礎知識、防御といえども攻撃（レッドチーム）の知識もある程度あった方が良いと思います。Security Team Training Ltd. はオフィシャルラボ Blue Teams Lab Online ( https://blueteamlabs.online/ ) を提供しています。必須ではないけどとても貴重な練習資料だと思いますので活用してください。ランクを見て記事を書く時点で日本で 40 人しかいなくて、難易度低のタスクを潰すだけでも日本 1 位になれます。

## 受験後

試験を受けた後にすぐ結果が見れます。その後 PDF 証明書・バッジなども 2 - 3 日後に通知で届けしまた。紙証明書とコインなどは約 1 - 2 ヶ月で届きました。コロナの影響もあるかと思いますが、特に紙証明書を使うケースもほとんどないので少し待っても問題ないと思います。さきほど紹介していなかったけど今年 3 月からレベル 2 の BTL2 コースと試験も出ました。マルウェア分析・脆弱性管理等のさらに高度な技術と知識に関するコースだそうです。自分はクラウドに関する業務がメインで今のところ BTL2 を受験する予定がないけど、いつかまたチャレンジします。
Vue.jsでnpm run serve をしたときにTypeError: Cannot read property 'version' of undefined at moduleと出た時の対処法

Vue-CLIで環境構築した時に出会ったエラーの解決策を備忘録として残しておきます。
記事内に誤りなどあれば、優しくご指摘いただけると幸いです。

# はじめに
今回使用したバージョンは以下になります。

```
$node -v
v16.14.0
$npm -v
8.3.1
$vue --version
@vue/cli 5.0.3
```

Vue-CLIの公式ホームページはこちらから。

https://cli.vuejs.org/

# エラー内容
```
$npm run serve
TypeError: Cannot read property 'version' of undefined at module...
```
バージョンが読み取れない、、、
うーん、、よくわからない。

# 対処法
調べていくと、eslintがインストールされていないために出ていたエラーだということがわかりました。
ということで、早速eslintをインストールしてみました。

```
$ npm install eslint
```

eslintをインストール後Vueを実行すると、無事エラーが消えていました。
よかった！！
これで問題なくVueで開発をすることができそうです。

今回はここまでです。
これからもVueの学習をどんどん深めていきます。


参考サイト
https://github.com/vuejs/vue-cli/issues/2866
なぜ人は転職をするのか、なぜ私は他テック企業の風土やお金事情に興味があるのか（動画編）

前回記事のこちらの動画版もシェアします。
[なぜ人は退職エントリを書くのか、なぜ私は狂ったようにそれを読むのか](https://qiita.com/hide6974/items/2528521bc6a87593e4a6)に関連して動画もシェアします。
あくまでも個人的な意見となります。

## 初めに
なにげなくYoutubeのサジェスト動画でてて来たのをきっかけに一気見した動画たち。

### ★セールスフォース

https://www.youtube.com/watch?v=Ts-Vp22ZIBk


### 光通信

https://www.youtube.com/watch?v=OcvKCbK0aks

### LINE

https://www.youtube.com/watch?v=hmjhDiX2D88

### Amazon

https://www.youtube.com/watch?v=KEWbUIshvfU

### 大塚商会

https://www.youtube.com/watch?v=d3VKBpyE9uA

### マイクロソフト（入社前に確認した動画たちです）

https://www.youtube.com/watch?v=A8DK43R4joE

https://www.youtube.com/watch?v=b88ekyVYPAg

### マイクロソフト追加

https://www.youtube.com/watch?v=xtX5A6dARUw

https://www.youtube.com/watch?v=kynCUkkl4J8

https://www.youtube.com/watch?v=3iJOhWopZLY

https://www.youtube.com/watch?v=HmGpXyImd2c

https://www.youtube.com/shorts/d3TaHcyAEIo

https://www.youtube.com/watch?v=rkuHlfstC7Q

### Google

https://www.youtube.com/watch?v=jDS8djTcZB4

https://www.youtube.com/watch?v=RtcgqE8uGDk


### 富士通

https://www.youtube.com/watch?v=9Xf_idaAUvQ

### IBM

https://www.youtube.com/watch?v=GSLIF8bw77k

https://www.youtube.com/watch?v=SjeDv3FItWE

以上
IdeaVim の EasyMotion プラグインを導入したが symotion-bd-f) のような文字列が挿入される

# 現象

例えば、 `~/.ideavimrc` に以下の設定を加えているとする。

```:.ideavimrc
set easymotin
map　f <Plug>(easymotion-bd-f)
```

`f` キーを押すと、画面に `symotion-bd-f)` が挿入され、インサートモードになる。
一体なぜ？

# 原因

`set easymotion` をタイポしている。
もしくは `AceJump` と `EasyMotion` のプラグインをインストールしていない。

# 解決策

`set easymotion` のタイポを修正する。

```:.ideavimrc
set easymotion
map <leader>f <Plug>(easymotion-bd-f)
```

もしくは `AceJump` と `EasyMotion` のプラグインをインストールする。

# 最後に

みなさんはこのようなつまらないミスで1時間ほどネットをさまよわないようにしましょう。
ネットワーク接続機器

## パケット
<b><font color =blue>パケット</font> - ネットワーク上を流れるデータを小さく分割したもの。
## データ伝送単位
<b>ネットワーク上を流れるデータは全て、広義の意味でパケットと言われる。
しかし、OSI基本参照モデルなどのプロトコル体系では、階層ごとのデータを<font color =blue>セグメント</font>(トランスポート層)・<font color =blue>パケット</font>(ネットワーク層)・<font color =blue>フレーム</font>(データリング層)と呼んでいる。<br>
送信時、上位層から送り出されたデータが下位層に移るとヘッダ情報が追加され、
受信時、階層が上がるごとにヘッダ情報が削除。
<font color =blue>TCPヘッダ</font> - 送信元と宛先のポート番号など
<font color =blue>IPヘッダ</font> - 送信元と宛先のIPアドレスなど
<font color =blue>MACヘッダ</font> - 送信元と宛先のMACアドレスなど
## ネットワーク接続機器
<b>1層 - リピータ
2層 - ブリッジ・スイッチングハブ・L2スイッチ
3層 - ルータ・L3スイッチ
4~7層 - ゲートウェイ
### リピータ
<b>LANにおいて、1層で中継する装置。伝送路の途中でデータの信号波形を増幅・整形する。
### ブリッジ
<b>2層で中継する装置。フレームの宛先MACアドレスを解析して、適切なネットワークに流す。
### MACアドレス
<b>NICにあらかじめ割り振られた世界で一意の物理アドレス
### スイッチングハブ
<b>LANケーブルを束ねる集線装置。受信したフレームの宛先MACアドレスを解析し、それが存在するLANポートにだけ転送。
### L2スイッチ
<b>スイッチングハブの機能に、仮想的なネットワークを構成する<font color = blue>VLAN</font>機能を加えたもの。
### ルータ
<b>3層で中継する装置。パケットの宛先IPアドレスを解析して、最適な経路を選択(<font color =blue>ルーティング</font>)し中継する。
### L3スイッチ
<b>ルータと同じ
### ゲートウェイ
<b>4層以上が異なるLANシステム相互間でプロトコル変換を行う装置。
### デフォルトゲートウェイ
<b>異なるネットワークを接続する出入り口となる装置
月間売り上げ100万のサイトをWordpress で作ってみたーその０

## プログラムとビジネスって、やっぱり別の脳みそがいるよね
連戦連勝の諸先輩プログラマ方の集う場所で、Wordpressでサイトを作ってみた!　的な記事を投稿するのは恐ろしい事である。
そういうのはアメブロでやるようにお叱りを受けるやも知れませんが、それを承知でアップしてみたのは、**プログラムとビジネスって、やっぱり別の脳みそがいるよねと**。
ビジネス、つまりサービスを立ち上げてお金を稼ぐという事と、バックエンドで動いているすごいプログラムって、パソコン画面見てる人からすると、ほとんど関係無いよねと思うからです。

20代でアクセサリーやジュエリー、インテリアのデザインをしていた時期に、沢山の職人さんと仕事をしていたのですが、技術的にすごい事をやってるものが売れる訳では全くなく、また、この人はこんなに凄いものを作れるのに、**何故凄い技術を持ってしてこんなにダサいものを作ってるんだろうか**と思う事が多々あり、プログラミング界隈でも似ているなあと思う事がよくあります。
日本の伝統工芸系の職人さんは、細部に至るまで色々と凄いのですが、それがファッションのマーケットで売れるどころか、ほとんどの伝統工芸は絶滅危惧種になっています。息子は跡を継がず、儂の代でおしまいや　というぼやきを何度聞いたことか。
ZARAとかユニクロの中国やカンボジア量産品の方が何千万倍も売れてるわけで、創業家も今や大金持ちです。かたや日本の職人さんたちは、自分たちの家を工房に、家庭内手工業的に細々と日夜作業をしています。
エルメスやヴィトンみたいに、伝統工芸的なもの作りを原点にしているブランドも、それが売れている原因はモノ自体というよりも、マーケティングやブランディングなど別の所にあります。

## 個人開発で世界に向けて何かを発信できるというインターネットの夢
元々僕がウェブ開発したいと思ったのは、自分の身一つとパソコン一台で、世界を変えるようなモノを作れるんじゃないかという果てしないネットの世界に広がる夢物語です。就職に有利とかでは有りません。
そういう人多いと思うんだけど、日本で見渡すと、そういう個人というかたちで成功している人殆どいないよね。
2チャンのひろゆき(自称プログラマ)、ZOZOの前澤さん(プログラマでは無い)、オンザエッジの堀江さん(一応当時はプログラマだけど、初期はコード丸パクリしてたとか言ってたね)、孫正義（商売人）、winny の金子さん(凄いプログラマだけど、逮捕される)。くらいがパッと思いつく感じで、**金子さん以外はビジネスマンである**。
**ひろゆきや堀江さんなんか足元にも及ばない様なガチグラマーは沢山居るのに、彼らが生み出したものを越える様なサービスは全然出てこない**。

そういう事をよく考えるので、企業にいるガチグラマーの人と話す機会があると、**どうして自分で何か作ってみないんですか？** という子供のような無垢な質問をするんだけど、一言でいうと、**大概が面倒くさいという返答である**。
バックエンドエンジニア *「そういう事考えるけど、(CSSのスタイリングとかフロントエンドのデザインとか色々考えてやるのが)面倒くさい」*
フロントエンドエンジニア *「そういう事やろうと思うんだけど、(バックエンドは結局他の人に頼まないといけないから)面倒くさい」*
フルスタック *「そういう事考えつくけど、(余分な時間ある時までプログラミングの事考えるのしんどいから)、寝てたほうが良い」*
**組織に入って、プログラミングが仕事になると、プライベートまでやろうとは思わないんだろうね。** レストランのシェフも、家では料理なんかしない的な感覚に似ているなあと。
日本の工芸系職人さん達も、同じような質問をしたときに、**そんなん、何作っていいか分からん**　と言ってたいた事を思い出します。
そう考えると、有名な２０％ルールで、自分の時間で自分の作りたいものを作らせてきたGoogleはやっぱりエンジニアファーストの会社なんだなあと。

## コンテンツかプログラムか
枕が長くなりましたが、サイトやアプリを使っている人の9割8分くらいはプログラミングとは縁のない生活をしているわけで、後ろで誰がどういう言語でプラグラムが書かれている、何何のフレームワークを使っている、どこどこのデータベースを使ってるかなんてどうでも良いし、**コンテンツがおもろいか、提供されてるサービスが便利なのか、それがほぼ全てな訳です**。 HTMLとCSSだけの静的サイトでも、面白い記事や有益な情報が乗っていれば、それは人気になり、そこからマネタイズされていくわけで。
**もちろん、アプリやサービスの操作感や安定性、セキュリティ等は後ろのプログラミングや環境次第なので、その点は全く重要です**。ただ、今お話ししたいのは、初期の小さなアイデアを形にするような、小さなスタートアップのサイトやアプリの話です。
また、Google mapやGoogle Earthなどが登場した時のヤバい未来がやって来たヽ(´▽`)/感は、エンジニアリング無しでは現実不可能ですね。

Qiitaでも、サイトやアプリを個人開発してみた　っていう記事は幾つか読んでみたのですが、APIからデータを抽出してリスト化し、アフィリエイトに繋げるとか、持って来たデータを定量化するといった、とてもプログラマらしいものだったので、もっとリアルビジネスとつながった泥臭いものを、Wordpressで作ってみた　という ど直球な記事を今制作中のサイトの制作記として3回ぐらいで上げていこうかなと思っています。
元々はNode.jsとREACTで一から作ろうと考えてたのですが、自分一人でコストはほぼゼロ、制作期間２週間という目標を立てた時点で、プログラマ的エゴは捨てて裸一貫になり、フレームワークとプラグインをフル活用するという方向性に致しました。
果たして月100万円という目標は達成されたのか？最終回で公表予定です。
ぼちぼち更新予定なので、気長にお付き合い頂ければ、これ幸いです。
WSL 上に Re:dash をインストールするまで

# Re:dash について

簡単な説明がされているので[コチラ](https://seleck.cc/614)をご覧下さい 

WSL 上で Re:dash を動かすのに苦労したのでメモとして残しておきます

WSL で動作する [Windows Manager] が必要なので、用意できない方は
[コチラ](https://github.com/taiseiyo/awesome_wm) を参考に導入お願いします。自動でインストールを行う
 script も作成しています

## 手順

まず前提として、WSL(Windows Subsystem for Linux)を扱っているとします。
その方は

- docker のインストールを行う
- docker 上にコンテナを立ちあげる
- Re:dash を起動させる

という流れで実行を行って下さい


### docker のインストール
https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-containers#install-docker-desktop

この記事の「Docker Desktop のインストール」を参考にして、Docker Desktop
のインストールを行って下さい

インストールが終了したら「Docker Desktop」は起動した状態にしておいて下さい

起動イメージはこんな感じです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666674/88342263-7744-63e0-c678-8b9bd140a95a.png)


### docker 上にコンテナを立ちげる

GitHub 上に、hands on 形式でコンテナの導入の仕方が記載されているので [コチラ](https://github.com/kakakakakku/redash-hands-on) を参考にしてください

### Re:dash を起動させる

以下のコマンドで起動可能です!

```
$ docker-compose run --rm server create_db
$ docker-compose up -d
```

## まとめ
Windows のローカル環境でどのように Re:dash を動作させればいいのかネットを色々調べて
漸く動作させる事ができたので、この記事が少しでも役に立てば幸いです

## 参考文献

> - https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-containers#install-docker-desktop
> - https://qiita.com/ma91n/items/25432b591494501df95d
> - https://github.com/kakakakakku/redash-hands-on
短期間&簡単に実装できる美顔機能 - Tencent Effect SDKについて

# Tencent Cloudについて

Tencent Cloudは2019年に日本市場に参入してから日本のエンタテイメント業界にかなり存在感を示しています。特にコロナ禍でライブ配信をはじめ、オンラインイベント、オンライン教育など音声・ビデオ通信技術を活用できる分野では着々と導入実績が増えています。
- [恋愛・婚活マッチングサービス「with」](https://intl.cloud.tencent.com/jp/customers/detail/682)
- [オンラインカラオケ Pokekara](https://intl.cloud.tencent.com/jp/customers/detail/2105)
- [ライブ配信 .yell Live](https://intl.cloud.tencent.com/jp/customers/detail/824)
- [オンラインイベント eventos](https://intl.cloud.tencent.com/jp/customers/detail/684)


下記、音声・ビデオ通信関連のTencent Cloudのコアサービスになります。
※ プロダクト間はシームレスに連携可能
- [Tencent Real-Time Communication](https://intl.cloud.tencent.com/jp/products/trtc): リアルタイム音声・ビデオ通信
- [Cloud Streaming Services](https://intl.cloud.tencent.com/jp/products/css): ライブ配信管理プラットフォーム
- [Video on Demand](https://intl.cloud.tencent.com/jp/products/vod): オンデマンド配信管理プラットフォーム
- [Instant Messaging](https://intl.cloud.tencent.com/jp/products/im): チャットサービス
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117156/ebe3955c-db5f-0122-6574-5d00213881a0.png" width="90%">

上記４つのサービス以外、例えば簡単にショートビデオ機能を実現できる<strong>User Generated Short Video SDK</strong>や人の顔、目、鼻のサイズを自由に調整できる<strong>Tencent Effect SDK</strong>
など非常に面白いサービスもあります。

今日はTencent Effect SDKについて、簡単に紹介します。

# Tencent Effect SDK

Tencent Effect SDKはTencentのAI研究室[YoutuLab](https://open.youtu.qq.com/)、写真加工アプリ[Pitu](https://apps.apple.com/jp/app/pitu-%E8%87%AA%E6%92%AE%E3%82%8A%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%81%E3%83%A7%E3%82%A4%E3%82%B9/id724295527)から生まれたサービスです。顔のサイズを調整したり、可愛いスタンプをつけたりができて、特に女性のライバーには愛用されています。

<img src="https://qcloudimg.tencent-cloud.cn/raw/8975aa3d9d37e1112f47b24b42ead075.jpg" width="40%">
<img src="https://qcloudimg.tencent-cloud.cn/raw/42af9ba6e804957e9fce763e723db1c9.jpg" width="40%">

今まではアプリで美顔機能しか実現出来なかったですが、ついブラウザーからでも美顔機能を実現できました！！　デモ用のウェブサイド[WebAR](https://demo.webar.qcloud.com/)もあるので、よかったらぜひ試してみてください.

# Tencent Effect SDKの詳細

iOS / Android / NodejsのSDKが用意されています。アプリに取り組んでいれば、簡単に美顔の機能を実装できてしまいます。

下記のような機能が備えています。

- ベーシック機能
    - 明るさ(Sharpness)
    - 美白(Beauty)
    - スキンスムージング(skin smoothing)
    - (Ruddy)
    
- アドバンスド機能（一部）
    - アゴ(Chin)
    - 目元(EyeAngle)
    - 目と目の距離(EyeDistance)
    - 目の明るさ(EyeLighten)
    - 目のサイズの拡大(EyeScale)
    - 顔の形(FaceBeauty)
    - 顔の縮小Ver1(FaceNarrow,FaceShort,FaceSlim)
    - 額(Forehead)
    - 唇(LipsThickness)
    - 鼻(NosePosition,NoseSlim,NoseWing)
    - 涙袋(PounchRemove)
    - スマイルライン(SmileLinesRemove)
    - シワ(WrinkleRemove)

- 2D / 3Dステッカー
- フィルター
- コスメティック
- バーチャル背景

# 最後
今日は美顔のTencent Effect SDKを紹介しました。ライブ配信アプリにはもちろん、たとえばバーチャル背景機能ならビデオ通話時にでも活用できるので、結構便利なSDKです。
Apple Storeに「[TRTC](https://apps.apple.com/jp/app/trtc/id1400663224)」というデモアプリもありますので、美顔機能以外、音声チャットやオンラインカラオケ機能もありますので、よかったらぜひ試してください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117156/6e5556ad-a26b-969c-268f-cc57df638ad9.png" width="50%">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117156/6c42be61-465d-9455-7406-aed8d7e8e74f.png" width="40%">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117156/285391df-f058-b3e8-1723-14fbd778bac8.png" width="40%">
Scalaの勉強はじめました 15 ~Futureとアクターモデル~

## はじめに
N予備校でScalaの「並行処理プログラミング」を受講しています。

## Future
:::note
非同期プログラミングにおいて、終了しているかどうかわからない処理結果を抽象化した型。
非同期に処理される結果が入ったOption型のようなもの。
:::

`Node.js`でいうところの`Promise`に近い。

```scala
import scala.concurrent.Future

val s = "Hello"
val f: Future[String] = Future {
 Thread.sleep(1000)
 s + " future!"
}
```

### implicit メソッド
```scala
import scala.concurrent.ExecutionContext.Implicits.global
```
関数型プログラミングとマルチスレッドの並行処理プログラミングを、暗黙的に結びつけるメソッド。
Javaの`ExecutorService`を自動実行してくれる。
スレッドプールの仕組みを意識せず並行処理を実装していくことができる。

:::note
Future シングルトンは関数を与えるとその関数を非同期に与える Future[+T] を返す
:::

### onComplete
```scala
val random = new Random()
val waitMaxMilliSec = 3000

val futureMilliSec: Future[Int] = Future {
 val waitMilliSec = random.nextInt(waitMaxMilliSec);
 if (waitMilliSec < 1000) throw new RuntimeException(s"waitMilliSec is ${waitMilliSec}")
 Thread.sleep(waitMilliSec)
 waitMilliSec
}

val futureSec: Future[Double] = futureMilliSec.map(i => i.toDouble / 1000)

futureSec onComplete {
 case Success(waitSec) => println(s"Success! ${waitSec} sec")
 case Failure(t) => println(s"Failure: ${t.getMessage}")
}
```

`Success(value)`, `Failure(throwable)`の形でパターンマッチが可能。


## アクターモデル
ユーザー => メッセージ(仕事) => メールボックス => アクター
アクターにはそれぞれメールアドレス(パス)があり、パスに基づいてアクター同士がメッセージを送り合うこともできる。

`Akka Actor` において、すべてのアクターは `ActorSystem` という一番偉いオブジェクトによって管理されている。
また全てのアクターは、`スーパーバイザー`というアクターの動作を監視するオブジェクトでもある。

:::note
通信エラーが発生した場合、スーパーバイザーがアクターの仕事を辞めさせ、接続を作り直して、アクターも作り直す。
:::

```scala
import akka.actor.{Actor, ActorSystem, Props}
import akka.event.Logging

import scala.concurrent.Await
import scala.concurrent.duration._

// メッセージを受け取るアクターを定義
class MyActor extends Actor {
  // Logging インスタンス
  val log = Logging(context.system, this)
  // メッセージを処理する メソッド
  def receive = {
    case "test" => log.info("received test")
    case _ => log.info("received unknown message")
  }

}

object ActorStudy extends App {
  // ActorSystem
  val system = ActorSystem("actorSystem")
  // Actor の作成
  val myActor = system.actorOf(Props[MyActor], "myActor")
  // メッセージ を送信
  // ! は、内部的には tell メソッドへの転送メソッド
  // myActor.tell("text", Actor.noSender) と同義
  myActor ! "test"
  myActor ! "hoge"

  Thread.currentThread().join()
}
```
Qiita 分析利用

自分の統計として次のような表示がある。

![qiitaanalyze.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/37443226-d9c9-7ce3-11ca-83d155c3dae2.png)

今日まで、特に放置していた。

投稿した記事と、LGTMした記事で、初心者が重複している。

投稿した記事の初心者を変更して、新人プログラマ応援か、個別の技術にすることにした。

新人プログラマ応援以外の何に変えたかを記録する。


1 初心者 -> 規格

2 初心者 -> プログラマ

3 初心者 -> 事前準備

4. 初心者 -> 名工大

5. 初心者 -> 検索

6. 初心者 -> 自動車 

7. 初心者 -> 法政大学

ついでに、タグを追加したり、誤植を訂正した。

まだ１０記事しか手をいれていない。
８月の連休には項目が変わるくらいの手を入れる予定。 

# 参考資料

５月病にならないで

https://qiita.com/kaizen_nagoya/items/6b9b1f00937cb8b106c9
netlify-cli を使って Next をデプロイするメモ

# 概要

Netlify はデフォルトでは連携した GitHub のレポジトリにプッシュすると自動でビルドとデプロイが走りますが、何らかの理由でビルドとデプロイを自前で行いたい場合に、 netlify-cli が使える。

Next アプリケーションを netlify-cli でデプロイする際の方法のメモ

# netlify-cli

https://docs.netlify.com/cli/get-started/

```
yarn add -D netlify-cli @netlify/plugin-nextjs
```

## @netlify/plugin-nextjs

https://github.com/netlify/netlify-plugin-nextjs

自前でデプロイする場合、SSRやISR、API Routesなどを適切に Netlify 環境にデプロイするためにこの公式プラグインが必要。

## netlify.toml の用意

```netlify.toml
[[plugins]]
  package = "@netlify/plugin-nextjs"
[build]
  base = "./"
  command = "ビルドコマンド"
  publish = ".next"
```

モノレポの場合、このファイル自体はレポジトリのルートに置き、 `base` はルート（ `./` ）を、 `publish` は `./path/to/.next/` のように該当パッケージへのパスにした。
ドキュメント読む限りファイル自体ルートじゃなくても大丈夫そうだけど、各パッケージのビルドをデプロイ前にする、とか考えるとルートにある方が自然な気はする。

# デプロイコマンド

@netlify/plugin-nextjs を使っている場合、ビルドコマンドとデプロイコマンドは分離できない。

```
# プレビューデプロイ
netlify deploy --build

# 本番デプロイ
netlify deploy --build --prod
```

このコマンドが、netlify.toml を読み込んでビルドとデプロイを実行する。
エックスサーバーでLaravelのartisanコマンドが使えない

# 現象

エックスサーバーにLaravelプロジェクトをアップロード後、SSH接続して「php artisan ~~~」を実行すると、以下のようなエラーが出る。

```
PHP Parse error:  syntax error, unexpected 'class' (T_CLASS), expecting identifier (T_STRING) or variable (T_VARIABLE) or '{' or '$' in /home/rgblog/reallygood-kaitori.com/reallygood-kaitori/artisan on line 33
```

# 解決方法

### 1. 「whereis php」コマンドを実行

下記のようなPHPコマンド一覧が表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532969/55317587-0f9c-db92-a96f-98a88ce9e45e.png)

### 適当なコマンドを選択して「artisan」コマンドを実行

「whereis php」で出てきたPHPコマンド一覧から、現在の環境にあったコマンドを選択
→「artisan」コマンド実行で、上手く機能します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532969/1233fee5-7f62-433b-af1f-587459768657.png)

# なぜエラーが起きたのか

「php -v」コマンドを実行してみましょう。

エックスサーバーのデフォルトのPHPバージョンが古すぎる（下記画像では「5.4.16」）のが原因です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2532969/fab9ee02-5079-c321-34ea-c41ffce353fc.png)
OSI基本参照モデルとTCP/IP

## OSI基本参照モデル
<b>ネットワークアーキテクチャを標準化するために、ISOが7階層にまとめ機能を定めたもの。
![20200314095931.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/3b7abd48-cc4c-fd3e-aa65-a9ae2e91bbe9.gif)
## TCP/IP
<b><font color =blue>プロトコル</font>とは、ネットワーク上で、コンピュータ同士が通信する時に使用する手順や約束事のこと。
OSI基本参照モデルでネットワークアーキテクチャが標準化されているが、実際はTCP/IPがRECで規定され、インターネットなどで広く使われているプロトコル体系ということで多くの利用者を獲得し、
事実上の業界標準(<font color =blue>デファクトスタンダード</font>)となっている。
<font color =blue>TCP/IP</font>とは、TCPとIPという二つのプロトコルを中心として構成されている。

![l_bit202006151641249159.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600460/54b869dc-1aba-511c-99b4-e481f80198ac.jpeg)
### アプリケーション層のプロトコル
<b><font color =blue>HTTP</font> - HTML文書などの送受信
<font color =blue>FTP</font> - ファイル転送
<font color =blue>TELNET</font> - 遠隔地のPCにリモートログイン
<font color =blue>SNMP</font> - ネット上の構成機器や障害時の情報収集を行う
<font color =blue>NTP</font> - タイムサーバの時刻を基に複数のコンピュータの時刻を同期させる
<font color =blue>SMTP</font> - メールを送信するときやメールサーバ間でメールを送受信させる
<font color =blue>POP3</font> - メールサーバのメールボックスからメールを受信する
<font color =blue>IMAP4</font> - メールサーバのメールボックスから必要なものを選択して、メールを受信する
### トランスポート層のプロトコル
<b><font color =blue>TCP</font> - 通信相手と通信できたか確認する。信頼性が高い
<font color =blue>UDP</font> - 信頼性は保証しないが、高速なデータ転送を提供
### インターネット層のプロトコル
<b><font color =blue>IP</font> - IPアドレスを用いて、データを通信相手まで届ける
<font color =blue>ICMP</font> - 通信相手との通信状況をメッセージで返す
<font color =blue>ARP</font> - IPアドレスからMACアドレスを取得

### Ping
<b>ICMPを用いて、IPパケットが通信相手に正しく届いているか確認するためのコマンド
### ネットワークインターフェース層のプロトコル
<b><font color =blue>PPP</font> - 2地点間を接続して通信。
<font color =blue>PPPoE</font> - LAN上でPPPを行い、常時接続。
初心者がロリポップでWebサイトを作成してぶつかった問題集


## erbでアップロードしても反映されない。
#### 拡張子の変更忘れミス・使える環境の確認不足
　あたりまえだが、RubyonRailsは使えないのでerbでなくhtmlに直す。

## scriptタグで関数を実行できない。
#### 

https://web-camp.io/magazine/archives/82490
これにならって

```
<script src="main.js"></script>
```

は問題なく動作したが。

```
<script>header();</script> 
```

は動作しなかった。
javascriptの関数は使えないみたい。PHPは使えそうな記事はちらほらあった。
ヘッダーフッターをインクルードしたのだができなくて、つまずいた。
できる人は教えて欲しい。

## 一部のclassが反映されない。
#### CSSでの1行コメントアウトに「//」が使えない
全てではなく、一部だけ。

なぜ？
![スクリーンショット 2022-05-16 22.31.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655277/accac9eb-e9f4-af6e-a1af-e258807561ee.png)

こちらはサーバにあげる前のcssファイルです。赤くなっている「//(ダブルスラッシュ)」。
これはcssファイルでは使えません。rubyonrailsの拡張子scss,sassファイルで使えるのですが、
cssで使えるものと思ってそのままになっていました。

同じ症状の方が他にもhttps://bukki.hatenablog.com/entry/2016/06/08/201509
[Cloud Functions] FirebaseStorage に保存された画像の幅と高さを取得する

Flutter / Firebase のアプリ開発で実装したことを記事にしました。
誰かのお役に立てれば幸いです。

アプリから、FirebaseStorage に画像を保存したときに、
その画像の width と height を取得する必要があったので、CloudFunctions 内で
画像サイズを取得する関数を作成しました。

## パッケージの導入

画像サイズを取得するパッケージは、

https://www.npmjs.com/package/image-size

こちらを使いました。コードが、とてもシンプルです。

## 画像パスから width , height を取得

まずは、Storage に保存された画像のパスと一時的に保存するディレクトリのパスを
用意する必要があります。
一時保存のディレクトリに画像をダウンロードしてから、サイズを取得する流れです。

```typescript
import * as functions from "firebase-functions";
import * as fs from "fs";
import * as path from "path";
import * as os from "os";
import mkdirp from "mkdirp";
import * as admin from "firebase-admin";

const sizeOf = require('image-size')

export const testFunction = functions
  .region("asia-northeast1")
  .storage.object()
  .onFinalize(async (object) => {
    const fileName = object.name; // ファイル名
    if (fileName === undefined) return;

    // 一時的に保存するディレクトリのパスを作成
    const tmpLocalFilePath = path.join(os.tmpdir(), fileName);
    const tmpLocalDir = path.dirname(tmpLocalFilePath);

    // Storage内の画像を一時保存のディレクトリにダウンロード
    const storage = admin.storage();
    const bucket = storage.bucket(object.bucket);
    const storageFile = bucket.file(fileName);

    await mkdirp(tempLocalDir); // 一時保存のディレクトリを作成
    await storageFile.download({ destination: tmpLocalFilePath });

    const { width, height } = sizeOf(tmpLocalFilePath);  // 画像のサイズを取得
    
    fs.unlinkSync(tmpLocalFilePath);  // 一時保存のディレクトリの削除
    return Promise.resolve();
  });

```

## 参考にしたサイト

https://github.com/firebase/functions-samples/blob/main/generate-thumbnail/functions/index.js
エラーが出ないエラー

本日も宜しくお願いします。

さて今日は「エラーが出ないのにシステムが動かない」案件に遭遇して困っている（現在進行形）というものです。

今回は凄くシンプルで、「フォームを使った送信機能の実装です」

あるテキストを入力し、送信を押したらそのテキストが表示される、というシンプルな物のはずなんですが、、、

書いたコードは以下

index.html.erb
```rails.qiita.rb
<h1 class = "display-4"><%= @title %></h1>
<p><%= @msg %></p>

<form method = "post" action = "/hello/index">
  <input type = "text" class = "form-control"
   name  = "input1" value = " <%= @value %>" >
  <input type = "submit" class = "btn btn-primary" >
</form>
```
hello_controller.rb
```rails.qiita.rb
def index
    if request.post? then
      @title = 'Result'
      @msg = 'you typed: ' + params['input1'] + '.'
      @value = params['input1']
    else
      @title = 'Index'
      @msg = 'type text...'
      @value = ''
    end
  end
```
routes.rb
```rails.qiita.rb
get 'hello/index'
  get 'hello' , to: 'hello#index'
  post 'hello', to: 'hello#index'
  post 'hello/index'
```

[input1]がテキストに入力されて送信（post)を受け取ったら画面がかわるはずなんですが、、、
ターミナル上でもエラーが出ておらず、、、

もし誰かこれを見てわかる方がいたら原因を教えてください。（teterailでも質問投げかけたのですが、解答がもらえず困ってます。）
AWS Systems Managerハンズオンやってみた

# はじめに
AWS Systems Manager(SSM)の勉強をしたいと思っていたら、下記のハンズオン教材がAWS公式であったので、やってみました。

https://catalog.us-east-1.prod.workshops.aws/workshops/7e60f6e3-0c8f-488a-bedc-632aa8d526ea/ja-JP/phase1

# 機能
[AWS Systems Manager とは?](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html)でもあるように６つの機能があります。

・Quick Setup
・Operations Management
・アプリケーション管理
・変更管理
・ノード管理
・共有リソース

SSMはAWS SAAの試験ではほぼ出ないかと思いますが、SOAでは必須の知識となります。その一方で上記のように機能が多岐に渡るので、中々分かりづらいサービスであります。

## ハンズオン
ハンズオン範囲は以下の通りです。

・EC2 インスタンスをマネージドインスタンス (AWS Systems Manager の管理下のインスタンス) にする方法
・AWS Systems Managerを用いてサーバアクセスする方法
・AWS Systems Managerを用いてOSコマンドを一括投入する方法
・AWS Systems Managerを用いてOSパッチ適用を自動化させる方法

WindowsとLinuxの両パターンでの、それぞれのやり方について解説がありました。(クラウドなのでどっちもやろうと思えばすぐにできることが良いところですね。)

## メモ
### RunCommand
下記の記事みたいな感じで、出力とエラーでそれぞれ表示されます。
https://dev.classmethod.jp/articles/run-command-enables-log-downloads-from-ssmconsole/

### パッチ適用
3のパッチスキャンの実行後に5のメンテナンスウィンドウを確認したところ、メンテナンスウィンドウの設定がされていないため、初期画面状態のままでした。当たり前のことですが、4定期実行の設定のパッチ適用を設定でスケジュールを設定しないと、メンテナンスウィンドウが実行されないようです。
Flowのトレイルヘッドエラー



**We can't find a text variable with API name opptyStage**
非アクティブの古いバージョンをすべて消したら問題ない。

+ [Problem in flow control module](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000H20xr)

**A flow called New Contact dosen't exist. Check the flow's label and API name.**
言語設定を英語にする必要があったようです。

+ [the challenge is not specified in "Create a simple flow".](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDHXISA5)

**We can't find a picklist screen component with the API name Account.**

+ [Failing to complete the challenge 'add screen to your flow' in Flow builder module.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000H2LvlSAF)
メモリの種類メモ。buffer, stack, cache, queue, ...

メモリの名前は、歴史的な背景があり、習慣があって、話が噛み合わないことがしばしばある。

OSの動作で、どこかに何かのデータが残っていて、悪さをすることがしばしばある。

# 悪さをする可能性のある事項

1. ファイルキャッシュ
アプリケーションが読み書きするファイル処理を高速化するため、一度読んだファイルは、メモリ上に展開した場所を編集し、一定時間はファイルを保存せずに、メモリとの間の読み書きだけにすることがある。
ここでは、ブラウザの読み込み対象ファイルは、ファイルキャッシュとして考える。

2. アプリキャッシュ
アプリケーションの設定など、アプリケーションの処理対象のファイルではなく、設定などの管理データをメモリ上に展開し、終了時などに保存するようにすることがある。

3. ディスクバッファ
ファイル単位ではなく、ディスクの特定の場所の読み書きを、メモリ上に展開し、読み書きする。
ディスクの索引などの場合もある。

4. 通信バッファ
ファイル単位ではなく、通信のまとまりごとにメモリ上に短径し、読み書きする。

5. ユーザバッファ
ユーザの設定で、ファイル単位であるかどうかに関わらず、メモリ上に展開して読み書きしている。

6. OSバッファ
ディスクバッファ、通信バッファ以外のOSの機能について、ファイル単位であるかどうかに関わらず、メモリ上に展開して読み書きする。



# 解消方法

1. ファイルを保存する。保存したファイルを開く
ファイルキャッシュが悪さをしているかもしれないときは、ファイルを保存する。
保村したファイルを開いたら、おかしな挙動が消えた時は、ファイルキャッシュが悪さをしていた可能性がある。


2. アプリケーションソフトウェアを立ち上げ直す。
アプリキャッシュが悪さをしているかもしれないときは、アプリを終了する。
サイドアプリを立ち上げ直すと、整合性のない設定を切り捨て、アプリの初期値で開始するなど、動作が安定することがある。
場合によっては、アプリケーション起動エラーになるかもしれない。


3. ログインし直す。
ユーザバッファが悪さをしているかもしれないときは、ログアウトしてログインし直す。

4. OSを再起動する。
ディスクキャッシュ、OSバッファが悪さをしている場合には、OSを再起動する。

5. OSを再導入する。
OSの設定の整合性が取れなくなっている場合は、OSを再導入すると解消することがある。

6. ディスクをフォーマットし直して、OSを新規導入する 
再導入で整合が取れない場合は、OSを決して、ディスクをフォーマットしなおして、OSを新規導入する。
ディスクの一部がハードウェア的に故障していても、ソフトウェアがあたかも問題ないかのように処理している場合がある。
ディスクをフォーマットし直すと、ハードウェア的に故障している部分は利用しないようにするかもしれない。

# 種類
stack:山積み。後入れ先出し
queue:待ち行列。先入れ先出し。
buffer:緩衝記憶。ある大きさになるまで、まとめている場合がある。通信ハードウェアが持っている場合とソフトウェアで設定する場合もある。
cache: 緩衝記憶。ハードウェアの緩衝記憶をソフトウェアで利用できる場合がある。CPUの緩衝記憶はcacheと呼ぶことが多い。一次キャッシュ、二次キャッシュ。

## 勘違い。cash（現金）

現金（cash）も預金に比べれば、取引の高速化ができるかもしれない。
現金を運ぶことにくられべば、預金の方が取引の高速化ができるかもしれない。

文字では違うが、発音は同じ。経理システム、金融系のシステム設計、運用の口頭の会話だけだと勘違いしたことがある。

# メモリの種類
メモリの分類は大きくはROMとRAMである。
しかし、RomはRead Only Memoryで、RAM はRadom Access Memoryである。
決死て対立する概念ではない。

当初

| |Sequencial Access|Random Access|
|:----|:----|:----|
|Read Only|ROM|-|
|Read Write|-|RAM|

Flash メモリが登場し、不揮発性メモリの利用方法が変わってきた。
不揮発性メモリであるが、ReadとWriteができる。

| |Sequential Access|Random Access|Non Volatile|Volatile|
|:----|:----|:----|:----|:----|
|Read Only|ROM|-|ROM| |
|Read Write|-|RAM|flash|RAM|

Flashを不揮発性メモリというのではなく、ROMという呼び方をする人たちがいるためにわけわかめになる。
Read OnlyでないものをROMというのは辞めて欲しい。
Flashは、ReadはRamdomにできるが、Writeのうち、消去と書き込みに別れる。消去は一度にまとめてある大きさを消去する。Random AccessよりはSequential Accessに近いかもしれない。書き込みはあるまとまりごとに書き込んだ方が管理がしやすいかもしれない。
Firebase SDKをSwift Package Managerで導入何を導入したのか確認する方法

# はじめに

FirebaseSDKを9.0.0にバージョンアップしようとしたら廃止されたパッケージでエラーになってしまって困り、何を入れたかわかることがわかったので簡単に残します。


# 確認の仕方

1. `HogeHoge.xcodeproj/project.pbxproj`をエディターで開きます。（例はVSCode)

2. **packageProductDependencies**を検索します。
そうすると下記のように何が導入されているか分かります。（赤枠のところ）
![スクリーンショット 2022-05-15 13.38.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/e7339b28-4726-5f20-8aac-4c6678881bce.png)

以上です。
【Linux】cronからスクリプトを実行できない事象の調査手順

こちらの技術ブログへ移行しました。

https://aki-website.tech/cron-script-troubleshooting/

# はじめに
自宅サーバにてcron設定すると良く詰まるので調査手順を纏めました！
自分の見直し用でもあるので今後もエラー対応時に随時更新します！

# 前提情報
OS:ubuntu 20.04 LTS

- 「cron → bash → python」 の順で実行させたい
- bashの手動実行は正常に稼働する
- cronからの定期実行は実行されない

# cronを使用する注意点
- 環境変数を使う場合は配慮
- 実行ユーザを配慮
- スクリプトも含めフルパスで記述
- スペルミス

# cron.log出力
デフォルト設定ではcron.logは出力されないため下記の設定ファイルを編集しログを出力させる。

~~~:ターミナル
$ cd /etc/rsyslog.d
$ sudo vi 50-default.conf
~~~
~~~:50-default.conf
(変更前)
#cron.*                          /var/log/cron.log
(変更後)
cron.*                          /var/log/cron.log
~~~
私の自宅サーバ環境では10行目にcron設定項目がありました。
cron設定の反映は下記コマンドでrsyslogを再起動時に行われます。
~~~:ターミナル
$ sudo systemctl restart rsyslog
~~~
cron.logは下記コマンドにて確認できます。
~~~:ターミナル
(ログ全数出力)
$ cat /var/log/cron.log

(最新10件の出力)
$ tail /var/log/cron.log
~~~

参考サイト

https://www.server-memo.net/ubuntu/ubuntu_cron_log.html
# ログレベルの調整
cron.logを出力させるだけでは、メッセージ全件が出力されません。
そのため、エラーメッセージを出力するように下記の通り設定しログレベルを引き上げます。
~~~:ターミナル
$ sudo vi /etc/default/cron
~~~
~~~:/etc/default/cron
(最終行を追加)
# This file has been deprecated. Please add custom options for cron using
# $ systemctl edit cron.service
# or
# $ systemctl edit --full cron.service
EXTRA_OPTS='-L 15' #追加
~~~
設定反映は下記コマンドでcronを再起動します。
~~~:ターミナル
$ sudo /etc/init.d/cron restart
~~~
エラー時は下記のようにcron.logに表示されます。
2行目のExit Codeが確認できたらExit Codeでググります。
- bashのExit Code一覧

https://qiita.com/Linda_pp/items/1104d2d9a263b60e104b
~~~:/var/log/cron.log (抜粋)
May 14 21:00:01 ubuntu CRON[23196]: (root) CMD ([23197] <<実行コマンド>>)
May 14 21:00:10 ubuntu CRON[23196]: (CRON) error (grandchild #23197 failed with exit status 1)
May 14 21:00:10 ubuntu CRON[23196]: (root) MAIL (mailed 1495 bytes of output but got status 0x004b from MTA#012)
May 14 21:00:10 ubuntu CRON[23196]: (root) END ([23197] <<実行コマンド>>)
~~~
## スクリプトの標準出力
cronに設定しているスクリプトの標準エラーを出力させるように設定します。
~~~:cron
* * * * * sudo sh /src/sample.sh >> /tmp/log/sample.log 2>&1
~~~

# まとめ
何時間もエラー調査して結果的にスペルミスだったこともあるので、今一度スペルを確認すること！！！！！
(自戒の意味を込めて)
manコマンドから抜ける


:::note info
Alfredのワークフローなどで、スクリプトにzshをはじめました。初心者用にメモを残します
:::

manコマンドはオンラインマニュアルを参照することができますが終了のさせ方が不明でした
なんとなく、ターミナルのウィンドウを閉じていましたが、面倒な操作だったので調べてみたら、

マニュアル表示中に<font color='red'>「q」キーを押す</font>とマニュアルが終了してターミナルのプロンプトにも戻ります


## 雑談

マニュアルページの操作もメモしておきます

　「f」  次ページ（SPACEキーでも同じ）
　「b」  前ページ
C言語で素数判定をしよう！

本記事はC言語をfor文くらいまで学習した大学１年生を対象として、プログラミングの魅力とプログラミング的思考力を伝えるための教材です。

``` c:prime1.c
//benngaku c 0515_prime1.c

#include <stdio.h>

int main(void){
    int n;

    printf("n=");
    scanf("%d",&n);
    
    if(n==0){
        printf("?\n");
    }else if(n==1){
        printf("NO\n");
    }else if(n==2){
        printf("PRIME\n");
    }else if(n==3){
        printf("PRIME\n");
    }else if(n==4){
        printf("NO\n");
    }else if(n==5){
        printf("PRIME\n");
    }
    
    return 0;
}
```

``` c:prime2.c
//benngaku c 0515_prime2.c

#include <stdio.h>

int main(void){
    int n,i;

    printf("n=");
    scanf("%d",&n);
    
    if(n==0){
        printf("NO\n");
    }else if(n==1){
        printf("NO\n");
    }else if(n==2){
        printf("PRIME\n");
    }else{
        for(i=2;i<n;i++){
            if(n%i==0){
                printf("NO\n");
                return 0;
            }
        }
        printf("PRIME\n");
    }

    return 0;
}
```

``` c:prime3.c
//benngaku c 0515_prime3.c

#include <stdio.h>

int main(void){
    int n,i;

    printf("n=");
    scanf("%d",&n);
    
    if(n==0){
        printf("NO\n");
    }else if(n==1){
        printf("NO\n");
    }else if(n==2){
        printf("PRIME\n");
    }else if(n==3){
        printf("PRIME\n");
    }else if(n==5){
        printf("PRIME\n");
    }else if(n%2==0){
        printf("NO\n");
    }else if(n%3==0){
        printf("NO\n");
    }else if(n%5==0){
        printf("NO\n");
    }else{
        for(i=2;i<n;i++){
            if(n%i==0){
                printf("NO\n");
                return 0;
            }
        }
        printf("PRIME\n");
    }

    return 0;
}
```

``` c:prime4.c
//benngaku c 0515_prime4.c

#include <stdio.h>

int prime(int n);

int main(void){
    int i;
    for(i=0;i<100000;i++){
        printf("%6d  ",i);
        if(prime(i)){
            printf("True\n");
        }else{
            printf("False\n");
        }
    }
    return 0;
}

int prime(int n){
    int primes[]={2,3,5,7,11};
    int i;
    if(n==0||n==1){
        return 0;
    }
    for(i=0;i<sizeof(primes)/sizeof(int);i++){
        if(n==primes[i]){
            return 1;
        }else if(n%primes[i]==0){
            return 0;
        }
    }
    for(i=13;i<n;i++){
        if(n%i==0){
            return 0;
        }
    }
    return 1;
}
```

``` c:float.c
//benngaku c 0515_float.c

#include <stdio.h>

int main(void){
    float i=16777216;
    printf("%f\n",i+1);
    return 0;
}
```

``` c:float_for.c
//benngaku c 0515_float_for.c

#include <stdio.h>

int main(void){
    for(float i=0;1;i++){
        printf("%f\n",i);
    }
    return 0;
}
```

``` c:while.c
#include <stdio.h>

int main(void){
    int i=0;
    while(i<5){
        printf("for %d\n",i);
        i++;
    }
    printf("%d\n",i);
    return 0;
}
```

```c:for.c
#include <stdio.h>

int main(void){
    int i;
    for(i=0;i<5;i++){
        printf("for %d\n",i);
    }
    printf("%d\n",i);
    return 0;
}
```
Ruby で楽しいルーレット

# この記事は？

ターミナル上で気軽にルーレットを楽しめるスクリプトを Ruby で実装します。

![2022-05-15 11-26-16.2022-05-15 11_26_57.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6697/600266c7-7a24-d8b9-08ab-e98758c0518c.gif)

# 実装

```rb:roulette
#! /usr/bin/env ruby
def clear_line
  print("\e[A\e[K")
end

def blink(item)
  red, yellow = 31, 33
  [red, yellow, red, yellow].each_with_index do |color, i|
    if i > 0
      sleep(0.2)
      clear_line
    end
    puts("\e[#{color}m#{item}\e[0m")
  end
end

# 実行中のスクリプトを Control+C で終了できるようにする。
Signal.trap(:INT) { exit }

items = ARGV
items.cycle.each_with_index do |item, i|
  random_number = rand(items.length)

  puts(item)

  case i
  when 0...20
    sleep(0.1)
  when 20...30
    sleep(0.2)
  when 30...(35 + random_number)
    sleep(0.4)
  else
    sleep(0.4)
    clear_line
    blink(item)
    break
  end

  clear_line
end
```

# 実行

```bash
$ chmod +x roulette
$ ./roulette むね もも ささみ せせり ぼんじり
```

# 参考

- ANSI エスケープコード
  - https://en.wikipedia.org/wiki/ANSI_escape_code
  - [ANSIエスケープシーケンス チートシート - Qiita](https://qiita.com/PruneMazui/items/8a023347772620025ad6)
【React】文字数を制限するカスタムフックの作り方


文字数が多いとき、...とするときに使えるカスタムフックを作りました

```tsx
export const useMakeString = (content: string, maxContentLength: number) => {
  if (content.length > maxContentLength) {
    return content.substring(0, maxContentLength) + '...';
  }
  return content;
};
```

実際の使用方法

```tsx
export const sample = () => {
  const title =
    'これは長めのタイトル文です。表示するときにはみ出てしまいます。';
  const displayTitle = useMakeString(title, 15);
  return <div>{displayTitle}</div>;
};
```

2022/05/19 追記

こんなことしなくても css(tailwind.css)で下のように書けばやりたいことが実現できる

```html
<div className="truncate">一行を超える文章</div>
```
Microsoft アカウントに移行すると Minecraft JAVA 版のマルチプレイができなくなった

# マルチプレイができないとき

「 Minecraft JAVA version を Microsoft アカウントに移行する」
https://qiita.com/nanbuwks/items/27786980dfb3076e200e
において、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f08b8f71-a187-4221-4fcb-86dfb9f4099f.png)

> サーバーへの接続に失敗しました
ログインに失敗しました:null

と出ます。

Microsoft アカウントに移行したのと同時にこの症状が出た場合は、Xboxアカウント設定を確認してみましょう。

# Xbox アカウントの確認

Xboxアカウントにサインインします

![Screenshot from 2022-05-15 09-38-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2fef6431-e293-2d96-326a-d1ac34bbae0a.png)

プライバシー設定を選ぶと、以下のメッセージが出る場合はファミリーグループ機能を用いて設定します。

![Screenshot from 2022-05-15 09-40-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a071a429-565c-169a-bbde-a37e0ee32bb8.png)


## ファミリーホストの作業

minecraft でマルチプレイできないアカウントを「ファミリーメンバー」とし、
親などの管理者を「ファミリーホスト」とします。それぞれ別のPCで作業をすることにします。同じPCの場合はアカウント遷移に注意してください。

「ファミリーホスト」から作業をします。


Xboxアカウントにサインインし、右上から「Xbox Profile」に進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/694f971a-7872-a4b1-2fdd-16013e9905f2.png)

「プライバシー設定」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d9fdc28d-47b3-615d-9922-241c43fd3cbf.png)

から、ファミリーメンバーを選び、ファミリーの設定を進めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a1027d61-fd44-d14d-bd43-ae77255a21dc.png)

もし、ファミリーメンバーに該当のメンバーが表示されない場合は、
「Microsoftファミリ」を押した後、以下の「家族のメンバーを追加」を押して追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a5a6a832-fd5e-0e26-37f9-f70d4b96c42e.png)

## ファミリーメンバーの作業
ファミリーメンバーに登録しているメールアドレスにメールがやってくるので以下の画面を開き、サインイン情報が被追加者であることを確認して「今すぐ登録」を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c252f2c0-8f38-2dba-d1a5-fb1cc57dcf11.png)

登録すると12歳制限がかかっていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4a03e0ff-afdd-2234-91ed-0d5bf630c9c5.png)


## 再びファミリーホストの作業

プライバシー設定を再読込すると、設定できるアカウントが追加されているのでファミリーメンバーを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/decab9c8-6ff5-b94e-063c-db4e1345eb2f.png)
Xbox Series X|S、Xbox One、Windows 10 デバイス オンライン セーフティタブを選び、
「Xbox Live 以外のプレイヤーとプレイできます」「クラブの結成と参加ができます」を「許可」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2320bedb-eac0-faae-0076-c7528f966973.png)
「マルチプレイヤー ゲームへの参加」「フレンドを追加」を「許可」にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0b458c9f-9da2-ffed-5607-042b46746a81.png)