OmniAICreator/Qiita-1.07M huggingface dataset:
EXCEL

http://mt-soft.sakura.ne.jp/mt/archives/200/210excel/211excel/index.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/ec788af5-bc49-976f-8839-78a014528755.png)
vlookup
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/f9db382e-95eb-1be4-2644-620431d3e499.png)
webpackとは？

webpackという言葉、なんとなくの意味しかわからなかったので
復習してみました。

### webPack
「Webpack」とは、モジュールバンドラーツールのことで、
Webアプリケーションを作成する際に必要な、さまざまなJavaScriptを
ひとまとめに管理するためのツール。
モジュールバンドラとは、複数のファイルを１つにまとめて出力してくれるツールのこと。
もっと詳しく言うと、依存関係を考慮しながら管理するツール。
元々、JavaScriptにはファイルをまとめる機能がなく、読み込む順番などを注意しなければならず、
不便だった。

webpackが行うことは、大きく分けて4つ

■Entry(エントリー)
依存関係を解決するために、どのファイルを基準（エントリーポイント）とするかを決める

■Output(アウトプット)
エントリーポイントにされ、webpackによってまとめられたファイルを、
どこへどのような名前で出力（アウトプット）するのか指定する

■Loaders(ローダー)
JavaScript以外のCSSやHTMLなどのファイルをモジュールに変換する方法を
読み込み（ロード）、指定した処理を行う

■Plugins(プラグイン)
圧縮などの、ファイルをまとめる以外でローダーが実行できないタスクを導入し、拡張（プラグイン）する

webpackを用いることで、JavaScriptのライブラリとJavaScript以外のさまざまな言語を、変換・圧縮した上で、好きな場所に配置することが可能となる。

### Webpacker
Webpackerとは、webpackをRails仕様にし、
専用の設定ファイルやヘルパーメソッドを用意してくれるGem。
Railsバージョン6系以降からは、デフォルトでWebpackerが導入されている。

以上がwebpackの簡単な説明なんとなくの理解はできたが、
実際に導入してみないと理解を深めるのは難しいと感じたので、
次回は導入した記事も書いてみたいと思いました。
作成したWebアプリにGoogle Analytics仕込む方法

# 前提
- Google アカウント作成済み
- Googleアナリティクスのアカウント作成済み

以下のような画面が表示されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450257/117ea82f-e336-8886-0b75-f3a4fcf0f63c.png)

# 方法
1. 左のメニューバーの管理をクリック
2. プロパティを作成をクリック ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450257/c356f281-3dbd-236c-53cd-4c00c95538e3.png)
3.情報を記入して作成を押す![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450257/20c517a6-66a1-6c8d-d79f-717bcaca4459.png)
4.ウェブ ストリームの詳細の中で以下のように`<script>`で始まる白枠内の部分をコピー![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450257/ab0b22f5-7969-ddd7-a971-6fc84937ddad.png)
5.自分の作成したWebアプリケーションの<head>タグの中にペースト

終了！
これでPV等の指標がトラッキングできるようになります。
ChromeOS の Linux コンテナで 58 エラーが出た場合の解決法

# 再現環境

Version 89.0.4389.82 (Official Build) (64-bit)

でも、Linux コンテナに大きめの更新があった場合には、今後も再発しそうな気がする…。

# 症状

ChromeOS の更新に伴い、Terminal アプリ起動時に　Linux コンテナのアップグレードが走る。

```
[=======/  ]
```

おなじみのプログレスバーが動いたあと

```
[=======/  ] Starting the Linux container Error starting penguin container: 58
Launching vmshell failed: Error starting crostini for terminal: 58
```

などいうエラーで失敗する。

# 解決手順

まず、`alt` + `ctrl` + `t` で Crosh を開く。
続いて、termina に入る。


```
crosh> vmc start termina
(termina) chronos@localhost ~ $
```


```
(termina) chronos@localhost ~ $ lxc list
+------------------------+---------+------+------+------------+-----------+
|          NAME          |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
+------------------------+---------+------+------+------------+-----------+
| penguin                | STOPPED |      |      | PERSISTENT | 0         |
+------------------------+---------+------+------+------------+-----------+
| penguin-crostini-remap | STOPPED |      |      | PERSISTENT | 0         |
+------------------------+---------+------+------+------------+-----------+
```

通常は存在しない remap というコンテナが存在している。筆者もよく解っていないのだが、コンテナを移行する際に古いコンテナからファイルシステムの同期を取るための措置らしい。

ここで、penguin コンテナを起動する。

```
(termina) chronos@localhost ~ $ lxc start penguin
```

lxc からは「remap やってるよー」的なメッセージが出るので、ひたすら待つ。

```
Remapping container filesystem
```

途中不安になって `ctrl-c` を押すと

```
This operation can't be cancelled (interrupt two more times to force)
```

など「これは止めてはいけないやつだ」と強く不安を煽るメッセージが出るので、押さないほうが良い。

手元環境では1時間以上かかったが、なんの追加のメッセージもなく、コマンドプロンプトへ帰ってくる。

コンテナの状況を見る。

```
(termina) chronos@localhost ~ $ lxc list
+---------+---------+-----------------------+----------------------------------------------+------------+-----------+
|  NAME   |  STATE  |         IPV4          |                     IPV6                     |    TYPE    | SNAPSHOTS |
+---------+---------+-----------------------+----------------------------------------------+------------+-----------+
| penguin | RUNNING | 172.17.0.1 (docker0)  | 2001:268:c105:412a:216:3eff:fe10:39a2 (eth0) | PERSISTENT | 0         |
|         |         | 100.115.92.206 (eth0) |                                              |            |           |
+---------+---------+-----------------------+----------------------------------------------+------------+-----------+
```

`RUNNING` となったので、remap 処理は終わったのだろう。

Crosh での作業は、ここまで。

Terminal を立ち上げる。

無事にコマンドプロンプトが表示されるのを確認して `ls` なりなんなり叩く。

# 推察

たぶん remap をしようとしてタイムアウトした結果が 58 エラーなのだろうという気がする。手元環境は Docker イメージがゴロゴロしていたり、超弩級サイズの Git リポジトリがあったりするので。
Vue + ECharts でウィンドウサイズの変更に合わせてグラフをリサイズする

ECharts のグラフは要素幅が動的に変更された場合にそれに合わせてリサイズしてくれないため、リサイズしたい場合は都度 `resize` メソッドを実行する必要がある。

ピュアな (？) JavaScript アプリであれば `window` オブジェクトの `'resize'` イベントを監視して `chart.resize()` するだけで十分だが、Vue のような VirtualDOM ライブラリを利用している場合は「ウィンドウサイズ」というグローバルな状態をどう扱うかをちゃんと考えないといけない。

昔は Vuex を使って「ウィンドウサイズをちゃんとした状態として扱う」ことでこれ実現するなどしていたが、Vue 2.6.0 で追加された `Vue.observable` を使えば Vuex を使わずとも簡単に書けることを知ったので方法をまとめておく。

## ウィンドウサイズを監視できるようにする
Vue インスタンスプロパティ `$window` を追加して、Vue コンポーネントからウィンドウサイズを監視できるようにする。

参考: [\[Nuxt.js, Vue.js\] Vue コンポーネントで Window のリサイズ/スクロールを監視するとてもよい方法 - やくだつブログ](https://www.useful-blog.info/vue-resize-scroll/)

``` javascript:plugins/window.js
import Vue from 'vue'

const WindowSizePlugin = {
  install(Vue) {
    const $window = Vue.observable({ width: 0, height: 0 })

    if (process.client) {
      function onResize() {
        $window.width = document.documentElement.clientWidth
        $window.height = document.documentElement.clientHeight
      }
      window.addEventListener('resize', onResize)
      onResize()
    }

    Vue.prototype.$window = $window
  }
}

Vue.use(WindowSizePlugin)
```

Nuxt.js の場合は上記を `plugins/window.js` に配置して、 `nuxt.config.js` の `plugin` に `'@/plugins/window'` を追加する。

## ECharts を利用するコンポーネントからウィンドウサイズを監視する
`watch` プロパティで `$window.width` を監視して、変更されたらグラフをリサイズする処理を実行する。

``` vue:Chart.vue
<template>
  <div></div>
</template>

<script>
import { init } from 'echarts'

export default {
  props: {
    option: {
      type: Object,
    },
  },
  data() {
    return {
      chart: null,
    }
  },
  mounted() {
    this.chart = init(this.$el)
    this.chart.setOption(this.option)
  },
  watch: {
    option() {
      this.chart.setOption(this.option)
    },
    '$window.width'() {
      this.chart.resize()
    },
  },
}
</script>
```
【Swift】キーパスについて

#キーパスとは
オプショナルチェーンのようにさまざまなインスタンスが互いに参照しあう関係にあった時、あるインスタンスを起点として次々に参照をたどって別のインスタンス参照できることがありますが、そのような経路をインスタンスとして保存したり、関数の引数と指定渡したりすることです。

以下は、ある学生sがクラブに所属している場合、そのクラブに顧問の先生がいればその先生の名前を表示するためのオプショナルチェーンによる記述です。

```swift 
if let name = s.club?.teacher?.name {
    print(name)
}
```

この記述は変数sに対してのみ有効ですが、Student型のインスタンスならばどれに対しても同様な参照を行うことができます。ここで、次のような記述が可能です。

```swift 
let teacherNamePath = \Student.club?.teacher?.name 
if let name = s[keyPath: teacherNamePath] {
    print(name)
}
```

この`\Student`から始まる記述がキーパス式です。
####キーパス式の形式
`\型名.パス`

#キーパス式の記述
キーパス式にはプロパティーの名前を「.」で区切って並べるほか、配列の要素を添字として指定したり、タプルの要素を通番名またはラベル名で指定することが可能です。次の例は、冒険者とパーティーのクラス定義です。

```swift 
struct Explorer {
    let name: String
    var items: [String: Int]
    var ability: (cure: Int, magic: Int)?
    init(_ name: String, items: [String: Int]) {
        self.name = name
        self.items = items
    }
}

class Party {
    let name: String
    var members = [Explorer]()
    init(name: String) {
        self.name = name
    }
}
```

この定義を使って次のような設定を行います。

```swift 
var party = Party(name: "LuckyStar")
let fighter1 = Explorer("こなた", items: ["剣": 1, "兜": 1])
let fighter2 = Explorer("つかさ", items: ["槍": 1, "薬草": 3])
var fighter3 = Explorer("かがみ", items: ["薬草": 1, "杖": 1])
fighter3.ability = (cure: 10, magic: 20)
party.members = [fighter1, fighter2, fighter3]
```
ここで、次のようにキーパスを指定して実行することが可能です。

```swift 
let kp1 = \Party.members[1].items["薬草"]
if let n = party[keyPath: kp1] {
    print(n) // 3
}

let kp2 = \Party.members[2].ability?.1
if let a = party[keyPath: kp2] {
    print(a) // 20
}
```

#キーパスによる値の操作
キーパスを使って、対象のプロパティの値を変更することもできます。
ここで、次のようなキーパス式を作成して型を調べてみます。

```swift 
let keypath1 = \Explorer.items["短刀"]
print(type(of: keypath1)) // WritableKeyPath<Explorer, Optional<Int>>
let keypath2 = \Party.members[2].items["薬草"]
print(type(of: keypath2)) // ReferenceWritableKeyPath<Party, Optional<Int>>
let keypath3 = \Party.members[1].name
print(type(of: keypath3)) // KeyPath<Party, String>
```

プロパティの値を更新するにはWritableKeyPath型、またはReferenceWritableKeyPath型のキーパスを使う必要がありますが、実際に値の参照、更新ができるかどうかは具体的な変数や定数の状況によって、異なります。定数keypath1, keypath2格納されたキーパスを使って、値を更新してみます。

```swift 
fighter3[keyPath: keypath1] = 1
print(fighter3.items) // ["薬草": 1, "杖": 1, "短刀": 1]
party[keyPath: keypath2]! = 5
print(party.members[2].items) // ["薬草": 5, "杖": 1]
```

#キーパスを使った表記の意義
キーパスはデータ構造の中のある位置を静的に示し、さらにその値の参照を後から行うことができます。例えば、学生とクラブの例を考えます。クラスのインスタンスは参照のデータのため、クラブ顧問の先生とインスタンスが得られたらそれを何かの変数から直接参照するようにできます。しかしその後、別の先生がクラブ顧問になるとその変数が参照するのは顧問の先生ではなくなってしまいます。一方、情報の位置をキーパスとして指定する方法ならば、データが書き換えられても意図する情報を得ることができます。

```swift 
let newArray = array.sorted { $0[keyPath: k] > $1[keyPath: k] }
```
変数kはキーパスで、例えば\Club.budgetや\Club.members.countを指定すると、予算の多い順、構成員の人数の多い順に並べ替えることができます。
プロパティの参照やオプショナルチェーンの記述は特定のインスタンスを起点とした式としてプログラムの中に書き込まれますが、キーパスは起点に型を指定して抽象化されているため、上記のようにコンパクトで効果的な記述を可能にします。
ASUS TUF Gaming A17 FA706QRでのubuntu20.04 ＋Win10 デュアルブート構成

#はじめに
Linux(ubuntu）についてはほとんど初心者な化学系大学教員です。
オープンソースCFDであるOpenFOAMを使うため、[ASUS TUF Gaming A17 FA706QR](https://jp.store.asus.com/store/asusjp/ja_JP/pd/ThemeID.4850018000/productID.5483222600)を購入。
結構なバケモノPC

`インチ : 17.3型
CPU : AMD Ryzen™ 7 5800H
OS : Windows 10 Home
メモリ : 16GB
ストレージ : SSD : 512GB
グラフィックス : NVIDIA® GeForce RTX™ 3070`

このPCにubuntu 20.04をデュアルブート構成し、OpenFOAMを使いたいと思っているが、備忘録を兼ねて纏める。
なおデュアルブートを構築するため、[こちらのページ](https://linuxfan.info/ubuntu-20-04-install-guide)などを参考にした。

#SSD増設
ubuntuとWindowsの入るSSDは分けておきたかったので、WesternDigitalのSSD 500 GBを増設

#インストールディスク作成
[ubuntu 20.04 LTS](https://jp.ubuntu.com/download)のディスクイメージをダウンロードして[Rufus](https://rufus.ie/ja_JP.html)によってTOSHIBA 64GBのUSBメモリでインストールUSBを作成（手持ちがこれしかなかったが、4GBで足りるはず）
※最初isoをUSBに書き込む他のフリーソフトを使ってしまったがそれではブートができなかった。

#ubuntuインストール開始したかったが。。。
インストールディスクUSBを挿して起動してもWindows10が立ち上がってしまった。
そこでPC起動直後にF12キーを押し、Windowsのスタートアップ修復を開き、
「他のデバイスの使用」によりTOSHIBA USB~~~を選択することで、
ubuntuをUSBから起動。
※ubuntuインストール後にBIOSでSecure bootを無効にする必要があったため、
__F2キー__でBIOSに入ったのだが、そこではUSBからブートできることに気づいた。なぜだろう？

#ubuntuインストール
ubuntuのインストール画面に遷移したが、解像度が800x600になってしまっていた。
途中までTabキーなどを駆使して進めていったが、「インストールの種類」で詰んでしまった。
Googleで様々検索したところ、Powerキー（Winキー）を押しながらマウスをドラッグすることで画面を動かすことができた。
これで増設したSSDにubuntuをインストールすることができた。
Docker Desktopの環境構築


# 1. 目的
　Windows 10 Home上にDockerの環境構築をする。

　Docker DesktopがWindows 10 HomeのWSL2で動く場合、Linuxがネイティブに動く。
そのため、下記の利点がある。

- 起動が速くパフォーマンスが高い。
- 動的メモリにメモリを確保するためリソースを有効活用できる。
- Docker自体の起動が速い。

以上の理由から、WSL2で動くDocker Desktopの環境構築をする。

# 2. WSL2の環境構築

開発環境

- Windows 10 Home

### step1. WSLと仮想マシンプラットフォームの有効化

Windowsの機能を開き、WSLと仮想マシンプラットフォームを有効化する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/7bd946b9-2db7-b3ce-003e-9f2c7f486ffb.png)

### step2. デフォルト設定

WSL 2のデフォルトを設定する。

```
$ wsl --set-default-version 2
```

### step3. Linuxカーネルのインストール

[https://aka.ms/wsl2kernel](https://aka.ms/wsl2kernel) に行き、WSL 2用のLinuxカーネルをインストールする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/5e01498e-0d70-175a-38aa-34c9113f0bbe.png)

### step4. Linuxカーネルの切替

LinuxカーネルのデフォルトバージョンをWSL 2に切り替える。

```
$ wsl --set-default-version 2
```

### step5. Linuxディストリビューションのインストール

MicrosoftストアからLinuxディストリビューションのうちUbuntu 20.04　LTSをインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/effd7926-bf58-94c4-7833-1ba1a5d6d185.png)


## 2.1 参照文献
- [Windowsユーザーに贈るLinux超入門(54) Windows 10でWSL 2を有効化する方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/d365f2d5-55ec-1fd6-a930-41cbf405099c.png)
- [Windows 10＋WSL2環境にDocker Desktopをインストール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/b23a32c8-3780-f7a4-01ec-26591de7698d.png)
- [WSL2 CentOS7のインストール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/28d80d8a-63b9-6511-7db1-f5fdfa3b78c1.png)


# 3 Dockerの環境構築

### step1. Docker Desktopのインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/169b5a76-b738-f35b-2a93-41d5fdc19e9f.png)

### step2. Docker Desktopの環境構築
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/5915cc32-f0dc-0065-0209-0e4f7aa51fcf.png)

## 3.1 参照文献
- [WindowsにGitをインストールする方法](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/23873f88-92a4-0b95-6a2b-ad3536cbfe68.png)
- [Windows 10＋WSL2環境にDocker Desktopをインストール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139678/69d88aa0-a1e6-7f34-7697-5daf96038c2b.png)
Flexboxを使い要素を横並びにする

## 初めに
webページを作成にあたって要素を横並びにする方法が定着しないので記事に残します。
## 要素を横並びにする方法
今回はFlexboxを記事にします。flortもありますがFlexboxの方が応用が効くと思うのでFlexboxを使用します。

前提として、Flexboxとはブロック要素の配置を変えることができます。
ブロック要素とインライン要素については以下を見てください。
[ブロック要素とインライン要素について](http://www.htmq.com/htmlkihon/005.shtml)

## displayプロパティについて
displayプロパティとは要素の種類を変更することができるプロパティです。displayプロパティの種類を何個か書いておきます。

| 種類 　　　　       | 説明　　　　 　　　　　　　　　| 
|:----------------- |--------------------------:|
| display:block     | 指定した要素をブロックレベル要素へ|        
| display:inline    | 指定して要素をインライン要素へ   | 
| display:inline-block| 指定した要素は並びはインライン、中身はブロック要素として表示| 
| display:none | 指定した要素は非表示となる          | 
| display:flex | 指定した要素の子要素は横並びになる   |

上記の表で書いてあるdisplay:flexを使用すると要素を横並びにすることができる。注意としては親要素にdisplay:flexを使用することです。
## 横並びにした要素の詳細を指定する
display:flexを使用し、さらに横並びにした要素を中央に寄せたり間隔を開けて均等に配置したりすることもできます。
### justify-contentプロパティ
justify-contentを使用することによって横並びの配置を指定できます。display: flexを使用した親要素に記載します。何個か種類を書いておきます。

| 種類 　　　　       | 説明　　　　 　　　　　　　　　| 
|:----------------- |--------------------------:|
| justify-content:flex-start | 指定した要素を左寄せにする|        
| justify-content:flex-end   | 右寄せにする| 
|justify-content             | 中央寄せ| 
| justify-content:space-between |両端が左右により、等間隔| 
| justify-content:space-around| 両端が左右により等間隔。両端の余白と要素間の余白が1:2になる|

他にも縦の要素を調整するalign-itemsプロパティやなどがあります。
初心者のため間違いなどありましたらご指摘お願いします。
AWS Outposts

#背景
- 「OpenShift, Tanzu Kubernetes Clusterはオンプレでも使えますよ！」と言われた場合、ECS, EKSがオンプレでどうなのか知りたかった。



#AWS Outposts概要
- HWはレンタル
- HWの構築・運用はAWS（ユーザーがやるのはLEDランプ確認と作業員の入館処理）
- 単一のリージョンにひも付く
- 独立したAZとして見える（Outpostsを複数おいて、両方TokyoのMulti-AZとすることもできる）
- AWSとの接続はDXでもVPNでもOK

#使える機能
###コンピュート
- EC2
（Fargateがない）

###オーケストレーター
- ECS
- EKS
- EMR

###ストレージ・DB
- EBS
- RDS
- S3

###ネットワーク
- VPC


#類似サービス
###Local Zones
- 普通のAZよりローカルなAZを選択して利用する。
- オンプレにOutpostsのように配置しなくて良い。
- "有線接続"でのクライアントに対する低レイテンシを実現。

###Wavelength
- Edge Computingのエッジの置き場。
- 普通のAZよりローカルなAZを選択して利用する。
- オンプレにOutpostsのように配置しなくて良い。
- "無線接続"でのクライアントに対する低レイテンシを実現。



#OutpostsでECSを使う場合
（EKSもだいたい書いてあることは同じ）
- FargateはないのでEC2で作る
- ECR, IAM, ELB, Route53はクラウド側のものを使う（レイテンシーが増える）
- AWSとOutpostsのネットワーク接続が途絶えると、クラスターは動き続けるが、クラスター新規作成・インスタンス置き換えなどができなくなる


#その他QA形式
Q. オンプレのデータを使いたい場合、オンプレAPI GWにECSからどうやってアクセスする？Transit Gateway（クラウド）にわざわざ戻る？
A. No
ローカルゲートウェイを介してOutposts外のローカルリソースにアクセスできる

Q. Outpostsのネットワークはどうなってる？
A. 2つある。
1. AWSとつながるServiceLink
2. ローカルとつながるLocalGateway

https://dev.classmethod.jp/articles/aws-outposts-network-connectivity/

Q. Outpostsへのデプロイはどうする？
A. マネジメントコンソール

Q. AWSとOutpostsの接続が切れたらデプロイできない？



#感想
- コンテナをそもそもオンプレで動かす意味があるのか
    - エッジならOutpostsじゃなくていい
- ロックイン対策だとしたらそもそもECSを選ぶのが間違ってる
    - EKSにして、オンプレにはKubernetesにすればいい
- 結論としてはあまりOutpostsを選ぶ理由が見当たらない




#参考
https://www.slideshare.net/ohashimamoru/aws-outposts

https://www.slideshare.net/ohashimamoru/aws-outpostslocalzoneswavelength-220636544

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-on-outposts.html

https://docs.aws.amazon.com/eks/latest/userguide/eks-on-outposts.html
[Nginx+Rails+Unicorn]ドメイン名でアクセスするとWelcome to nginx on Amazon Linux!が表示される

#課題

AWS上でRailsで制作したアプリをNginxとUnicornを使ってデプロイしようと試みていたとき話です。

お名前.comで購入したドメインをroute53でElasticIPに紐付けて、
いざドメイン名でアプリにアクセスしようとすると

Welcome to nginx on Amazon Linux!

このような文章が含まれた画面が表示され、待てど暮らせど一向にアプリは表示されませんでした。

#解決方法

結論
としては、Nginxの設定がうまく行っていませんでした

Nginxの設定ファイルをviで開きます。
作成していない場合はこちらの記事が参考になるかと思います。

[(デプロイ編②)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで](https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1)

```
$ cd /etc/nginx/conf.d
$ vi [アプリ名].conf
```


```
# log directory
error_log  /var/www/rails/micmatch/log/nginx.error.log; #自分のアプリケーション名に変更
access_log /var/www/rails/micmatch/log/nginx.access.log; #自分のアプリケーション名に変更
# max body size
client_max_body_size 2G;
upstream app_server {
  # for UNIX domain socket setups
  server unix:/var/www/rails/micmatch/tmp/sockets/.unicorn.sock fail_timeout=0; #自分のアプリケーション名に変更
}
server {
  listen 80;
  server_name 54.95.78.130; #アプリのElastic IPに変更してください
  # nginx so increasing this is generally safe...
  keepalive_timeout 5;
  # path for static files
  root /var/www/rails/micmatch/public;
  # page cache loading
  try_files $uri/index.html $uri.html $uri @app;
  location @app {
    # HTTP headers
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }
  # Rails error pages
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /var/www/rails/micmatch/public; #自分のアプリケーション名に変更
  }
}

```
Invoke-WebRequestの日本語文字化け解決策

# 問題点
PowerShellのInvoke-WebRequestでcharsetがutf-8に設定されているページを読込むと日本語部分が文字化けして「????」となるため、正しく日本語の処理ができません。

```PowerShell
$res = Invoke-WebRequest -Uri $uri
$content = $res.Content
# 以降、$contentに対して、文字列検索や、正規表現で部分文字列の取り出し処理など。
$matches = [RegEx]::Matches($content, "href=""(http:\/\/www\.example\.com\/項目[a-z0-9]{20}\.html)""")
```
# 参考にした記事
この問題について、以下の記事を参考にさせて頂きました。

https://qiita.com/zaki-lknr/items/1ae3258d7b77c5e2a2ba

この中にある「本来のエンコードがUTF8の場合」というコードです。あらためて引用させて頂きます。

```PowerShell
[System.Text.Encoding]::UTF8.GetString( [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($resp.Content) )
```

これは ISO-8859-1 ⇒ UTF-8 の変換と理解しています。（間違っていればご指摘ください）

# 改善策
ところが上記のコードでも日本語部分が「????」となるため、以下のように書き換えてみたところ文字化けが解消しました。

```PowerShell
$content = [System.Text.Encoding]::UTF8.GetString( [System.Text.Encoding]::GetEncoding("UTF-8").GetBytes($res.Content) )
```

このコードは UTF-8 ⇒ UTF-8 という意味のない処理をしているように見えるのですが、結果として問題は解決しました。

解消した理由までは理解できていませんが、Tipsとして書いておきます。
Vysorを使ってスマホ画面をパソコン画面に表示

# Vysorを使ってスマホ画面をパソコン画面に表示

タイトルがチープにだが要はミラーリングしたい
スマホ画面をパソコン画面に表示する方法はいくつがあるがVysorを使う方法が一番簡単だった

## ダウンロード

Vysorをダウンロード、Windows、Mac両方で使うことが出来る。
Android、iOS両方に対応している。
https://www.vysor.io/

## Android接続

今回はサンプルとしてAndroid画面をパソコンに転送

先にAndroidのUSBデバッグを許可する。
https://support.vysor.io/technical/notfound/

USBデバッグを許可しAndroidとパソコンをUSB接続

Android Devicesに端末が表示される。
![スクリーンショット 2021-03-14 12.59.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59264/5d1045fa-91cf-4f03-c90d-296b648c511c.png)

実行ボタンを押すとAndroid画面が表示される。
パソコン画面でAndroid操作も出来る。
![AnyConv.com__poker-macro_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59264/3cd60d00-9317-937d-dd42-1a9f808872c4.gif)

---
いいね！と思ったら LGTM お願いします :clap::clap::clap:

【PR】プログラミング新聞リリースしました！ → https://pronichi.com
【PR】週末ハッカソンというイベントやってます！ → https://weekend-hackathon.toyscreation.jp/about/
dataframeの列同士を比較して条件を満たす列ラベルを取り出す

質問しようと思ってあちこちいじってたら上手く行ったので、備忘録がてら登録。

###主題
表1のデータから表2を作りたい。

表1　生データ

| 総額   | 食費   | 光熱費  | 水道費  |   
| ---- | ---- | ---- | ---- | --- | --- | --- |
| 2000 | 2000 | 0    | 0    |     |     |     |
| 1000 | 0    | 1000 | 0    |     |     |     |
| 1500 | 0    | 0    | 1500 |     |     |     |

表2　作りたいデータ

| 総額   | 食費   | 光熱費  | 水道費  | 分類  | 
| ---- | ---- | ---- | ---- | --- | --- | --- |
| 2000 | 2000 | 0    | 0    | 食費  |     |     |
| 1000 | 0    | 1000 | 0    | 光熱費 |     |     |
| 1500 | 0    | 0    | 1500 | 水道費 |     |     |

食費・光熱費・水道費はどれか一つに値が入るようになっている
食費1000＋水道費1000＝総額2000、というようなことはない。

### 自分で試したこと

```python
import pandas as pd
df = pd.DataFrame(
    data=[{'総額': 2000, '食費': 2000,'光熱費': 0,'水道費': 0,},
          {'総額': 1000, '食費': 0,'光熱費': 1000,'水道費': 0,},
          {'総額': 1500, '食費': 0,'光熱費': 0,'水道費': 1500,}])

df_temp= df.drop("総額",axis=1)
df_temp["分類"]=df_temp.idxmax(axis=1)
df=df.merge(df_temp)

```
今回は3列の中の最大値が欲しかったので、idxmaxで一発で列ラベルを拾えた。
idxmax、idxminが使えるならこれが良さそう
カフェでプログラミングしてる風（でも何もやってない）Goコード（プログレスバーバージョン）

# おしゃれなカフェで...

私はエンジニア。
コーヒー片手にWindowsのノートPCでプログラミングしています。

っていうのは置いといて・・・
[カフェでプログラミングしてる風（でも何もやってない）Java（クソ）コード](https://qiita.com/3S_Laboo/items/660883a0184dabaea65b)を見た後に、職場であがった話題を絡めたネタ記事です。


# 唐突ですがCRについて


最近、職場でCRについてのこんな話題があがりました。

> 恥ずかしながら、キャリッジリターンの意味を初めて理解した、ただの改行コードと思ってた。
> これ、カーソルを先頭に戻すコードだったんですね

例えばこんな感じ。

```
opt = 'aaa'
opt += 'bbb\r'
print opt   # aaabbb

opt += 'ccc'
print opt   # cccaaa
```

`\r (キャリッジリターン)` はカーソルを先頭に戻す動きなので、元々の`aaabbb`に対して`ccc`が上書きされます。
カーソルは`ccc`の位置なので、元からある`bbb`は上書きされずに残ります。

改行コードはタイプライターの名残らしいです。

| CR | LF |
|:-:|:-:|
| カーソルを行頭に戻す | カーソルを次の行に移す |

という意味になります。
Windowsの改行コードは`CR+LF`ですが、要は「カーソルを行頭に移動して、次の行に移動しろ！」という２つの動作で改行しているわけです。
みなさん知ってました？**私は知ってました。**

# よくある進捗表示

コマンドラインで進捗表示でるやつあるじゃないですか。
あと、`\-/|`をくるくる回すやつ。
あれって、`CR`使ってたんですね！！
みなさん知ってました？**私は知りませんでした。**

# というわけでネタアプリ

っていう会話から本家様の記事を思い出してしまったので、`\r`使ってプログレスバー対応してみました。
そろそろGoを触ろうかと思って、人生で初めてGoを書きました。

それと、毎回done!だとおもしろくないので、たまーに失敗するようにしてみました。
乱数判定いじれば確率変えられます。あまり大きな値にしすぎると毎回`FAIL`になるので、そこはお好みで調整してください！


``` go:cafeProgress.go
package main

import (
	"fmt"
	"math/rand"
	"strings"
	"time"
)

// 進捗表示の桁数
const MAXDIGITS = 50

func main() {

	// 乱数初期化
	rand.Seed(time.Now().UnixNano())

	for {

		// 0%～100% まで
		for percent := 0; percent <= 100; percent++ {

			// 最大maxDigits桁に対して、いまの進捗分の#桁数
			progress := percent * MAXDIGITS / 100

			// ランダムでエラーを発生させる
			seed := rand.Intn(65535)
			hasError := seed < 64 // 65536÷64で1/1024でエラーになる

			// 進捗バーを作る
			marker := "#"
			if hasError {
				marker = "-"
			}
			done := strings.Repeat(marker, progress)
			notyet := strings.Repeat(".", MAXDIGITS-progress)

			// メッセージの出力
			msg := "\r"
			if hasError {
				msg = "FAIL.\n"
			}
			if percent == 100 {
				msg = "SUCCESS.\n"
			}
			fmt.Printf("%3d%% [%v%v] %v", percent, done, notyet, msg)

			// エラーだったら次のターン
			if hasError {
				break
			}

			// 素敵感の演出
			var osooso = rand.Intn(100)
			time.Sleep(time.Millisecond * time.Duration(osooso))
		}
	}
}
```

# 動かしてみる

![cafeProgress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/28288e7d-650e-a039-1a8a-64a2dcc2e5e4.gif)

おー、これはきっと何かしていますね！！
ちゃんと`#`で上書きされていますし、進捗パーセント表示もいい感じです！！
`FAIL`が表示されたときに「しまった！」とか小声で言えば、さらに何かやってる感がアップすること間違いなしですね！！！

# おわりに
ちょっとやってみたくなっただけなんです。
普段はまじめ（？）な記事を書いてますので、どうか許してください。

## 謝辞

@keiji-kataokaさん、リファクタリングありがとうございます！
Ruby on Rails

# rails (必要ならrailsのバージョンも) new (プロジェクト名) -d mysqlでエラーした・・・

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Installing mysql2 0.5.3 with native extensions

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

current directory: /Users/user_name/Programs/web/foobar-repo/vendor/bundle/ruby/2.5.1/gems/mysql2-0.5.3/ext/mysql2

/Users/user_name/.rbenv/versions/2.5.1/bin/ruby -r

(中略)

An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.3'` succeeds before bundling.

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

👆みたいな・・・

### 解決策👇
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
% bundle config --delete build.mysql2
% bundle config --global build.mysql2 --with-opt-dir="$(brew --prefix openssl)"

% cd ~/projects/(プロジェクト名)
% bundle install

ーーーーーーーーーーーーーーーーーーーーーーーーーー
Vue.js始めてみました⑦(computed)

この度Vue.jsを学び始めました。
その勉強内容をまとめます。


## computedオプション

データを計算して使う時にcomputedオプションを使います。
以下がcomputedを使った算出プロパティの書き方です。
computedはカンマ区切りで複数作ることもできます。

```JavaScript:Vue.js

<script>
  new Vue({
    el: '#ID名',
    data: {
      プロパティ名:値
    },
    computed: {
      computedのプロパティ名: function() {
        処理内容
      },
    computed: {
      computedのプロパティ名: function() {
        処理内容
      }
    }
  })
</script>
```


## 使い方

これだけだと意味が分からないのでちょっと使ってみます。

計算で一番身近なのは消費税ですかね。
と、いうことで数字を入力したら消費税込みの金額を計算するものを作ってみます。

```JavaScript:Vue.js
<div id="app">
  <input v-model.number="price" type="number">円
  <p>税込み{{ taxPrice }}</p>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      price: 0
    },
    computed: {
      taxPrice: function() {
        return this.price * 1.1;
      }
    }
  })
</script>
```

上記では
`el`でHTML要素のどの要素とつなげるかを指定していて、
`data`には初期でどのデータを入れておくか指定して、
`computed`に処理方法を記述しています。
その計算内容を`{{ taxPrice }}`に値を渡して表示するということです。


次に、よくある入力画面の「残りの文字数を表示させる」を作ってみます。
そういうのって大体残り少なくなると文字色が赤くなるのでそれもやってみます。

```JavaScript:Vue.js

//150字を以内の入力画面で残り10文字になったら残り文字数の表示が赤くなる
<div id="app">
  <textarea v-model="text"></textarea>
  <p v-bind:style="{color: wordsColor}">残り{{ words }}文字</p>
</div>

<script>
  new Vue({
    el: '#app',
    data: {
      text: ' '
    },
    computed: {
      words: function() {
        return 150 - this.text.length;
      },
      wordsColor: function() {
        col = "green";
        if (this.words < 20) {
          col = "red";
        }
        return col;
      }
    }
  })
</script>
```

上記では`{{ words }}`に150から今入力している文字数を引いた数を計算して渡しています。
`wordsColor`は`v-bind`で色を指定して、その処理はwordsColorで条件式にして決めています。

以上です。
[AndroidStudio]改行場所がぐちゃぐちゃになっちゃた時

# 意外と、検索で出てこない？
AndroidStudioで、作業していて、結構広めのネストを持つコードを削除した時、コードの改行位置がずれてしまうことがある。例えば、こんな感じ。（例が悪いかもしれない）

```kotlin
hogehoge.setonClickListener {
    fugafuga.setOnClickListener {
      piyopiyo.setOnClickListener {
             Lod.d("debug","hogera")
      }
    }
  }
```
ここで、fuga.setOnClickListenerを削除した時に、piyopiyo.setOnClickListenerのネストの位置が微妙にずれて気持ち悪くなる。手動で、ポチポチすれば治せるのだが、プログラマー三大美徳である怠慢は徹底したいところ。

一度、知り合いの方が秒でネストを整えているのを見たことがあって、どうやっているのだろうと疑問に思っていて、質問できてなかったが聞いてみたところ。

「　Ctrl + Alt + L　」

で、できるみたいだ。こんなの知ってて当たり前なのですかね？
意外とググっても出てこなかったので、人に聞くことによって得られる情報の方が良質なのでは！？

ちなみに、AndroidStudioのタブでもそれが、確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599059/459a4002-3e1b-1032-f299-93a6962fd724.png)

ほら。「　Ctrl + Alt + L　」が確認できるでしょ！

上部のタブから、ショートカットの方法が確認できるので、手動でやるの面倒！という操作があれば、ググる前にここから探すのもありかもしれないと思った今日この頃。
DynamoDb：ローカル環境構築(その２:GUI管理ツール)

aws公式サイトで「NoSQL Workbench」というデータベース管理GUIツールがあるが、テーブル作成・変更、データ登録・更新しづらいので、dynamodb-adminの構築方法を紹介します。

dynamodb-adminの詳しい情報は、以下を参照してください。
https://www.npmjs.com/package/dynamodb-admin


### dynamodb-adminをインストール（グローバルで）
```
  npm install dynamodb-admin -g
※1 もしstrict-ssl問題が発生した場合、下記コマンドで無効にして、再度インストールしてください。
  npm config set strict-ssl false
※2 root権限が持ってなかったら、先頭にsudoを追加してください。
```

### DynamoDBのエンドポイントを環境変数に設定
```
export DYNAMO_ENDPOINT=http://localhost:8000
```

### 起動コマンド
```
  dynamodb-admin
```

### DynamoDBを起動して下記のURLをアクセス。
http://localhost:8001
pi picoでmicropython その8

#概要

picoでmicropythonやってみた。
pwm使ってみた。

#サンプルコード


```
import time
from machine import Pin, PWM
pwm = PWM(Pin(25))
pwm.freq(1000)
duty = 0
direction = 1
while True:
   duty += direction
   if duty > 255:
      duty = 255
      direction = -1
   elif duty < 0:
      duty = 0
      direction = 1
   pwm.duty_u16(duty * duty)
   time.sleep(0.001)


```

以上。
Firestoreの複合インデックスでつまったところまとめ

# 対象読者
複合インデックスを登録しているのに取得できない方

# 解決方法
まず、エラー内容を確認します。firebase Functionsを使っている方はfirebaseのコンソールに入って、Functionsのログからエラーを確認してください。もし使われていない方は、例外処理によってエラー内容を返して確認してみてください。以下のエラー（一部抜粋）が出力されていると思います。

```
"details": "The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/[projectID]/firestore/indexes?create_composite=[文字列]",
```

「クエリを実行するにはインデックスが必要なので作ってくださいね」と書かれており、親切にURLも記載してくれています\:clap:。アクセスすると、Google Cloud PlatFormがブラウザで開き、インデックスを登録するかを聞かれますので、そのままインデックスを登録をしてください。
登録が成功された状態でAPIを実行すると、無事にデータが取得できるようになります。（この解決方法は[公式ドキュメント](https://firebase.google.com/docs/firestore/query-data/index-overview?hl=ja#composite_indexes)にも記載されています。）

# 実際につまったところと原因
以下のような構造をとったデータが保存されているとします。

```typescript:interface
interface Log {
  user_id: string
  message_id: string
  created_at: string
}
```

そのデータを以下の条件で取得したいと仮定します。
①あるユーザーのログをメッセージごとに並び替え、さらに作成日の順に並び替えて取得する
②あるメッセージのログをユーザーごとに並び替え、さらに作成日の順に並び替えて取得する

```javascript:model/index.js
// ①の場合のクエリ
snapshot = await docRef
    .where('user_id', '==', userId)
    .orderBy('message_id')
    .orderBy('created_at')
    .get()

// ②の場合のクエリ
snapshot = await docRef
    .where('message_id', '==', messageId)
    .orderBy('user_id')
    .orderBy('created_at')
    .get()
```

このクエリに対し、以下のインデックスを事前に登録していました。

| コレクションID | 	インデックス登録されるフィールド | クエリのスコープ |
|:-:|:-:|:-:|
| collection_id | 	user_id 昇順 message_id 昇順 created_at 昇順 | コレクション |

※表の列の名前は、それぞれfirebaseのコンソールでFirestoreにアクセスし、インデックスに書かれているものです。Google Cloud PlatFormで見た場合は
　　インデックス登録されるフィールド　→　フィールド
　　クエリのスコープ　→　Query scope
となっています。

この状態で実際にAPIを実行すると、**①は取得できて②ではエラーになります。**
そして、上記の解決方法に記載の通りクエリを作成すると、インデックスが以下のようになります。

| コレクションID | 	インデックス登録されるフィールド | クエリのスコープ |
|:-:|:-:|:-:|
| collection_id | 	user_id 昇順 message_id 昇順 created_at 昇順 | コレクション |
| collection_id | 	message_id 昇順 user_id 昇順 created_at 昇順 | コレクション |

ここで、もう一度APIを実行すると先ほどエラーだった②も取得できるようになります。
つまり、原因は<font color="Red">**クエリで指定している複数のインデックスをその順にインデックスに登録していなかったこと**</font>となります。今回のケースでは、使用したフィールドは同じでしたが、厳密には条件が異なっており、インデックスも別々に定義する必要があったようです。

このように条件が違えばインデックスを新たに定義すればいいと言うことが分かったのですが、やみくもにインデックスを作成していると利用料金（インデックスはストレージの料金として計上されるみたいです）が無駄にかかってしまうので、[インデックス マージ](https://firebase.google.com/docs/firestore/query-data/index-overview?hl=ja#taking_advantage_of_index_merging)を活用して重複するインデックスを削減する、と言ったことも可能みたいです。

---

[公式ドキュメント](https://firebase.google.com/docs/firestore/query-data/index-overview?hl=ja#composite_indexes)を読んでみて「複合インデックスを登録すると複数のフィールドを組み合わせたインデックスを作成でき、それによってデータが取得できるようになる」と自分なりに解釈をしてみたのですが、組み合わせであっても順番を担保しないといけないのは何故なのでしょうか、、詳しい方いらっしゃいましたら教えていただきたいです、、\:pray:
Maven最低限のメモ


Android開発以外でJava使うことがない人間のMavenメモ。SPI開発が目的。

### プロジェクト生成

```bash
mvn archetype:generate \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false \
-DgroupId=com.hoge \
-DartifactId=Hello
```

>どのようなオプションが標準化もよくわからない。

### 実行

こうすると動くらしいが、

```bash
cd Hello
mvn -q compile exec:java -Dexec.mainClass=com.hoge.App
```

エラー。

![スクリーンショット 2021-03-16 9.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/8712fbb3-4795-ab53-fb03-9a16f66bda12.png "スクリーンショット 2021-03-16 9.48.23.png")

### エラー対応

文字コードやターゲット環境などの設定が必要らしい（オプションで設定できないの？）。


```diff_xml:pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.hoge</groupId>
  <artifactId>Hello</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Hello</name>
  <url>http://maven.apache.org</url>

+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
```

>手動で加えなくても-DarchetypeVersion=RELEASE \ を加えるとpropertiesが自動生成されるみたい。

### 再実行

```bash
mvn -q compile exec:java -Dexec.mainClass=com.hoge.App
Hello World!
```

### jar生成

```bash
mvn install
```

### jar中身確認

```bash
jar -tf Hello-1.0-SNAPSHOT.jar 

META-INF/
META-INF/MANIFEST.MF
com/
com/hoge/
com/hoge/App.class
META-INF/maven/
META-INF/maven/com.hoge/
META-INF/maven/com.hoge/Hello/
META-INF/maven/com.hoge/Hello/pom.xml
META-INF/maven/com.hoge/Hello/pom.properties
```

## 追記

とりあえず下記でテンプレートを作成すればいいのかな？

```bash
mvn archetype:generate \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=RELEASE \
-DinteractiveMode=false \
-DgroupId=com.hoge \
-DartifactId=Hello
```

なんかよくわからんけど、とりあえず。
pi picoでmicropython その7

#概要

picoでmicropythonやってみた。
adc読んでみた。

#サンプルコード

```
import utime
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)
while True:
   reading = sensor_temp.read_u16() * conversion_factor
   temperature = 27 - (reading - 0.706) / 0.001721
   print('Temp: {:.1f}'.format(temperature))
   utime.sleep(2)


```


以上。
ソートしたい、ループやりたい、けど参照したいデータが異なる場合

なんかよくわからないタイトルなんですけど、内容はこんな感じ

ループを回したいデータがある
でもその中に別の回したいループがある
しかもソートしたい
でもループの中にループをやると中のループのデータが複数取れてしまう
ただ何かの処理の時にはまた一からどちらもループも走らせたい

結論書くとループした後にまたループをさせるしかなかったです。

ソートがなければ行けたけど、ソートがあるせいでうまくいかずRealmを使ってたんですが、Realmもあまり弄れない状況だったので

結果的に同じような処理を2回書きました。

もしソートしたいけど、参照したいデータが違うとかの場合ループを2回回すしかない

みたいな感じで考える時もくるかもです。

できればループの後にまたループみたいな感じで回すのはコード量も増えるし、やりたくないんですけどね。

データが違うし、他にもやり方があるのかもしれないけどスキルも足りなかったので、それをやるしかなかったです。

うん完全に忘備録になってしまった
脆弱性のキャッチアップメモ

いくつかの脆弱性についてキャッチアップしました。

## SQL injection

APはユーザからの入力を受け付け、その後SQLを実行するとユーザの入力により意図しない結果になる恐れがある。

**例**

このようなSQLがあるとします。

```SQL
select * from user where userid = '{{userid}}' and nm = '{{nm}}';
```

ユーザからの入力は：

- userid: 42' or 1=1--
- nm: nm

変換後のSQL

```SQL
select * from user where userid = '42' or 1=1-- and nm = 'nm';
```
になる。

こうして、42というユーザだけではなく、全てのユーザ情報が抽出されてしまうだ。

## SQL injection (second order)

SQLiと違って、ユーザが入力した情報をその場で利用せず、一回APのほうで保管します。  
また未来のどこかのタイミングで仕込んだ情報が意図しない結果になる恐れがある。

**例**

まずユーザは新しいアカウントを作成します。
useridは`42';update user set passwd=xxx where userid = 'admin'--`だとします。

ユーザ42がログインするときに、下記のSQLが実行されると考えられます。

```SQL
select * from user where userid = '42';update user set passwd=xxx where userid = 'admin'--';
```

これで、adminユーザのパスワードが変更され、攻撃者は次回にフル権限を持つadminユーザでログインできるようになる。

## Sensitive Information Saved Unencrypted

重要な情報がエンクリプトされずに外部に流出してしまった。

## Directory Traversal

ファイルの相対パスを利用して機密情報を取得するなり、破壊するなりのこと。

**例**

例えば画像ファイルの取得ロジックは以下のような場合：

```java
File file =  new File("/application/src/images/" + imgFileName); // imgFileNameは別途から来たパラメータ
return file.getCanonicalPath(); // 画像のフルパスを返す
```

- imgFileName：../../../../etc/passwd 

これで実際に画像を作成する場所は
`/application/tomcat/webapp/../../../../etc/passwd` -> `/etc/passwd`になる。

これでシステムのパスワードを漏洩する恐れがある。

## Directory Traversal (second order)

特に調査できませんでした。

## Denial of Service (DoS) via Blocking Call

APのリソースを枯渇させることが目的である。

**例一**

```java
String rowNum = request.getParameter("rowNum");
int row = Integer.parseInt(rowNum);
Item[] items = new Item[row]; // これでrowNumの数によって一気にメモリを食ってしまう恐れがある
```

**例二**

```java
String[] params = request.getParams("info");
for(String param : params) {
  // paramsはすごく多く、かつ処理が遅い場合にAPの反応が遅くなり、ひどい場合にサービス自体が停止してしまう恐れがあります。
}
```

他にいろいろ例があります。

## Insufficient SSL Enforcement

1. SSLを利用していない
2. SSL認証の設定が不適切
3. APとDBが同じ筐体でない場合に、かつAPとDBの通信はセキュアじゃない場合

## Unrestricted File Upload

アップロードされたファイルの検査が足りない。
【Project Euler】 Problem2 【解いてみた】

# はじめに
【Project Euler】とは、プログラミングで解く数学の問題集です。

本投稿では初学者なりに、Problem2 を解くにあたっての考え方を解説しています。
ちなみに言語はRubyを用いています。


※本投稿は、Project Eulerのガイドラインに従い、解答例としてのコードは載せておりません。
　また、問題に関しては私が翻訳しています。ミスがあればご指摘ください。
　　
【Project Euler】について知りたい方はこちらから↓

 https://projecteuler.net/

# 問題(original ver.)
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

# 問題(翻訳ver.)
フィボナッチ数列の項は、直前の２つの項を足したものになる。最初の二項をそれぞれ1,2だとすると、最初の10項は以下のようになる。

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

フィボナッチ数列の項の値が400万以下である時、偶数の項の総和はいくつになるか計算せよ。


## 問題を解く上でのヒント
①問題にある通り、この数列の項は直前の2つの項の足し算で表されます。ということは、3項目=1項目+2項目 と表現されます。
その次は4項目=2項目+3項目と表現されます。つまり式の構造は変わらず、項の値のみが変わっていきます。したがって、第何項目であろうと、c=a+b(a,b,は任意の連続する自然数とする)と表現できます。

すこし分かりづらくなりましたが、要は、各項を入れる変数を作ってしまえばいいということです。



②①でみたように、文字(=変数)は3種類あればすべての項が表現できます。したがって3つ変数を作りましょう。
あとは、各項の値を、400万になるまで繰り返しスライドしてずらしていくイメージです。具体的な数字で言うと、

3=1+2 → 5=2+3 →8=3+5 ...

と数字が移動していくようにすれば良いです。

同じことの繰り返しなので繰り返し処理です。
あとは繰り返し処理の中で偶数が出てくる度に足し合わせるだけです。

偶数であることは、2で割り切れるということだと考えれば、rubyでどのように判別できるかわかるはずです。

# おわりに
今回は【Project Euler】の問題2を解く上での考え方、流れを解説してきました。
今回の解答は、あくまで複数ある解き方の一種です。余裕があれば様々な角度から解いて見てください。

このほかにも多くの問題が存在しているので、気になる方は最下部のリンクから挑戦して見てください。
また今後、私自身その他の問題にも挑戦し、同じような備忘録を投稿していきます。
私の備忘録が少しでも皆さんの参考になれば幸いです。ありがとうございました❗


https://projecteuler.net/about

P.S. 問題を閲覧するにはアカウント登録が必要です。↑
【API実装・下書き機能】rspec テスト model, requestsの違い

#create, build でテストできることの違い

「下書きが保存可能であること」を確認しようと思い、
下記のコードを記述。

```
  context "下書きのとき" do
    let(:draft) { create(:article, status: 0) }

    fit "下書き記事を保存できる" do
      expect(draft).to be_valid
    end
  end 
```

しかし、これでは、
createした後に、createできるか確認。
という順になってしまうため、<font color="red">保存できるかの確認にはならない。(createは作ってすぐに「保存してしまっている」から。)</font>

なので、create -> build に変えるのが正しい。

```
  context "下書きのとき" do
    let(:draft) { build(:article, status: 0) }

    fit "下書き記事を保存できる" do
      expect(draft).to be_valid
    end
  end 
```

これなら、draftは保存可能なデータなのか？
というテストになる。
pi picoでmicropython その6

#概要

picoでmicropythonやってみた。
ナップザック問題、やってみる。

#問題

|価値|	容量|
|:--|:--|
|6|	3|
|7|	4|
|8|	6|
|1|	1|
|4|	5|

容量のリミットは、12
最も、価値が大きくなった時の価値を答えよ。

#サンプルコード

```
N = 5
W = 12
wt = [3, 4, 6, 1, 5]
va = [6, 7, 8, 1, 4]
dp = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

def snap():
   for i in range(N):
      for k in range(W):
         w = W - k
         if (w - wt[i] >= 0):
            if (dp[w] < dp[w - wt[i]] + va[i]):
               dp[w] = dp[w - wt[i]] + va[i]
   print(dp[W])

snap()


```

以上。
Docker をインストールしてVNCでGUI操作をする

Ubuntu20 に Docker をインストールしてVNCでGUI操作をします。

こんな感じにブラウザから docker 内のファイルにアクセスができるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/327c2925-e05e-b66e-a294-5ba11c19b5e3.png)
####Docker のインストール方法
````bash
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
sudo systemctl status docker
sudo usermod -aG docker ${USER}
su - ${USER}
````
####Docker の Ubuntu vnc のインストール
````bash
docker run -p 6080:80 -v /dev/shm:/dev/shm dorowu/ubuntu-desktop-lxde-vnc
````
ブラウザで http://localhost:6080/ でアクセスができるようになるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/327c2925-e05e-b66e-a294-5ba11c19b5e3.png)
####Docker の Wordpress と MySQL と PhpMyAdmin のインストール
````bash
docker pull mysql:5.7.21
docker pull wordpress
docker run --name test-mysql -e MYSQL_ROOT_PASSWORD=test-pw -d mysql
docker run --name test-wordpress --link test-mysql:mysql -d -p 8080:80 wordpress
docker run --name myadmin2 -d --link test-mysql:db -p 8081:80 phpmyadmin
````
ブラウザで http://localhost:8080/ で Wordpress にアクセスができるようになるかと思います。
ブラウザで http://localhost:8081/ で PhpMyAdmin にアクセスができるようになるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/2bdb2bf3-d6b5-18d1-29eb-bd4747deb466.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/129fbc01-50c1-fb2d-d9e5-f91e877ec63a.png)
####Docker のすこしバージョンが古いですが、ROSのインストール
````bash
docker run -d -p 5901:5901 -p 6901:6901 henry2423/ros-vnc-ubuntu:melodic
````
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/dac72e5b-8f4d-063a-a6d7-48040a0bfacb.png)
####Docker の Kali linux をインストールし、コマンドラインからアクセス
````bash
docker pull booyaabes/kali-linux-full
docker run -itd --rm booyaabes/kali-linux-full
docker exec -it f5ef83073abe9cf5e5cd5da406eb09b871f7735f9963d06a268722644df63921 /bin/bash
````
![Screenshot from 2021-03-15 02-50-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115935/3994a6fc-6968-b16d-2834-7cf4b518ecb1.png)
他にもおもしろそうな Docker Image がありそうです。
データベースや環境を汚さないので Nas にインストールしてみると良いような気がします。

####参考リンク

- [Ubuntu 20.04へのDockerのインストールおよび使用方法 | DigitalOcean ](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04-ja)
- [GitHub - fcwu/docker-ubuntu-vnc-desktop: A Docker image to provide web VNC interface to access Ubuntu LXDE/LxQT desktop environment. ](https://github.com/fcwu/docker-ubuntu-vnc-desktop)
- [今更だけどDockerでWordPress環境を用意してみたら超簡単だった - Qiita ](https://qiita.com/maimax/items/5090fd37f9832fe3c5fd)
- [phpmyadmin/phpmyadmin ](https://hub.docker.com/r/phpmyadmin/phpmyadmin/)
- [booyaabes/kali-linux-full ](https://hub.docker.com/r/booyaabes/kali-linux-full)
pi picoでmicropython その5

#概要

picoでmicropythonやってみた。
tensorflow.jsでxorを学習した、変数を使って、回帰やってみた。

#サンプルコード

```
import math

def tanh(x):
   a = math.exp(x)
   b = math.exp(-x)
   return (a - b) / (a + b)

def sigmoid(x):
   return 1.0 / (1.0 + math.exp(-x))

def main():
   w1 = [[-3.4681022, 0.379121, -1.4711456, 2.2247136, 2.3135107, 2.7624693, -1.83576, -1.1545312], [2.1978209, 0.2895245, 2.0881913, -1.3450832, -1.4154571, 1.9255028, 3.2867477, 1.956522]]
   b1 = [-0.6591252, 0.3864409, 0.4982838, 0.3707547, 0.3982254, -0.3612466, 0.4284867, 0.2701645]
   w2 = [[1.4324994 ], [0.7911373], [-2.3011343],  [-1.7614117], [-2.4442003], [3.9701838], [-1.837263], [-1.3641325]]
   b2 = [0.9285715]
   for i in range(4):
      x = [0.0, 0.0]
      y = [0.0]
      h = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
      if (i == 0):
         x = [1.0, 0.0]
         print("1, 0 => ")
      if (i == 1):
         x = [0.0, 1.0]
         print("0, 1 => ")
      if (i == 2):
         x = [1.0, 1.0]
         print("1, 1 => ")
      if (i == 3):
         x = [0.0, 0.0]
         print("0, 0 => ")
      for k in range(2):
         for l in range(8):
            h[l] += x[k] * w1[k][l]
      for l in range(8):
         h[l] += b1[l]
         h[l] = tanh(h[l])
      for k in range(8):
         for l in range(1):
            y[l] += h[k] * w2[k][l]
      for k in range(1):
         y[k] += b2[k]
         y[k] = sigmoid(y[k])
      print(y[0])

main()


```

以上。
WSL とホスト PC 間の接続

# はじめに

WSL2 を使用しだした。ホスト PC との間でファイルのやりとりなどで接続が必要なので、備忘録として残す。GUI パターン、CUI パターンの両方を残す。 

# GUI
WSL 上で `$ explorer.exe .` を実行すると、WSL のカレントディレクトリのエクスプローラが開く。エクスプローラ上にドラッグ＆ドロップでファイルを移せばコピーできる。コマンドラインでないので、直感的でわかりやすい。

# CUI
コマンドライン上で扱いたい場合には `cd /mnt` 以下に C ドライブがあるので、あとは自由に。
Qiita Daily Survey memo 2021.03.16

# Qiita Daily Survey memo 2021.03.16
Qiita の記事を可能な限り毎日読むために、読んだmemoを公開することでモチベーションを維持しようという試み。

## [【個人開発】これまでになかった席替えアプリ「席替えメーカー」を作りました【3/15大幅追記】](https://qiita.com/krpk1900/items/22963432b62a9004717c)
Terai Shogo(krpk1900)さんの記事。
月に一度のﾄﾞｷﾄﾞｷイベント、席替えをしてくれるアプリを作成しました、という記事になります。
gifで動いている様子が確認でき、使用感がイメージしやすいです。
また、他のアプリとの差別化の要素が列挙されていたり、力を入れたポイントが書かれていたり、ToBeの開発が列挙されていたりと読みやすい構成になっています。
特に、「本気で」とついているようにUI、UXは分かりやすそうだなと感じました。
先生の業務は、こういう「ちょっと大変」がたくさんあるイメージなので、そのあたりをサポートしてくれるツールとしてとても良いと思いました！
また、実際のレビューを受けてアップデートがされており、力が入っている感じがすごいです…。


## [Pythonの音楽情報処理ライブラリmusic21の紹介](https://qiita.com/iNomaG/items/16081daf103a042ea0fe)
iNoma G さんの記事。
MITが作成したmusic21というpythonの音楽情報処理ライブラリのご説明をしてくださっている記事です。
記事にもある通り、非常に少ないコードで楽譜が出力できてしまうのが驚きでした。
音符の分布を出力したり、楽譜の音符のところに音名を出力したりと、いろいろできるようです。
確かに言われてみれば楽譜は音楽の設計書なので、かなり構造がしっかりしていますよね。
OCRなどで楽譜を読み込んだり、音を入れて楽譜を出力したり…といった機能があったりするのでしょうか…？


## [入力チェックエラーをNERV本部警告アラート風にして、サクッと人類を補完しちゃおう！！エヴァ劇場公開記念](https://qiita.com/3S_Laboo/items/ccee511a021c33e5ff2f)
3SLaboo さんの記事。
タイトルの通り、アラートをエヴァ風に表示する、という記事になります。
思ったよりもちゃんと激しいアラートで、声を出して笑ってしまいました。SUGOI。
動きのある、おちゃめ感のあるUIはとても良いですよね。
こういうのを見るたびにUIも勉強しなくちゃ、、、と思います。
参考記事も記載してくださっているので、そこも参考にさせていただきます。
SocketException が出てしまうときには Windows Defender ファイアウォールを見直してみるといいかも


同じプログラムにもかかわらず、Unity のバージョンを変更したときに SocketException が発生してしまう場合、Windows Defender ファイアウォールの設定を見直すことで解消できる可能性があります。
もちろん Unity だけに限った話でありませんが。

# 原因
Windows Defender ファイアウォールの設定の設定が、Unity バージョンごとに設定されている可能性があります。ここでは、Unity 2019.4.10f1 Editor と Unity 2020.1.11f1 Editor があることがわかります。
（私はバージョンアップしたときに嵌りました）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/8c130422-a98e-7b72-75f1-5ce1cc1e0fea.png" width=512>

## もう一つ
ここでは特に紹介していませんが、許可の設定を入れていてもブロックが優先されます。Unityのように自動で設定されると、自身で許可していてもそちらにブロックされている可能性がありまｓ

# Windows Defender ファイアウォールの設定
## とりあえず試すなら
いったん Windows Defender ファイアウォールの設定を無効化して試すのが楽です。

1. 有効無効の設定画面を開く  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/bb1b65c3-114c-f3e4-36fc-d2afe0647b68.png" width=512>  
2. 有効になっているので、無効を選択して OK
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/a5b4d00b-3c76-6553-6a9b-3c13dd089b5a.png" width=512>
3. この状態で実行して Socket Exception が出ないか確認する

## ちゃんと設定する
1. 詳細設定
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/de3f0902-f797-6a47-629e-bfcae5109974.png" width=512>  
2. 受信の規則 → 新しい規則
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/5bd4c5dd-a894-d3f2-92aa-27ab1bada027.png" width=512>
3. 後はダイアログに沿って登録
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/55e4358e-d19c-06eb-1210-b7e4e4381da4.png" width=384>
パス自体は自分の Unity のバージョンに合わせて、許可したい（実行している） exe 本体を設定してください。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/9652c325-b976-33d8-d2ee-33fcab5ecd55.png" width=384>
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/7615a305-dc12-e0fe-c4a2-be62becbcdf4.png" width=384>
3つにチェックを入れず、わかるようであれば制限したほうがよりセキュリティは高いです。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/46dd33e3-2ca9-4248-033a-d842d9365507.png" width=384>
後から見てわかるような名前（exeファイル名やプロダクト名）であればなんでも大丈夫です。
                         <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/96c4e7ca-3aa1-2b8f-6f76-f26ef361f029.png" width=384>
4. この状態で実行して Socket Exception が出ないか確認する

# 参考
## SocketException の内容
```
SocketException: 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。
```
React 入門 (#4) ～Create React App～

#１，Reactの簡単なアプリケーションを作ってみます。
完成品はこちら
![2021-03-15_15h24_29.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/821c834a-7cf6-d587-ea12-1ab08f886bcb.gif)

#２，使う技術
>**Hooks**の導入
**useState**の利用
**props**の利用
**CSS**の利用

#３，ディレクトリ構造
ターミナルもしくはコマンドプロンプトから
**npx create-react-app tutorial** を入力してフォルダを作成しましょう。
そうすると、以下のフォルダがされます。
**srcフォルダ**のindex.js以外はすべて削除してください。

①**componentsフォルダ**と**stylesフォルダ**を準備します。
![2021-03-15_15h08_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/34621538-a2ca-c32b-1919-03cb80e0c8a0.png)
②それぞれのフォルダの中に各ファイルを設置
![2021-03-15_15h08_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/c767abf6-7094-10ab-7de9-839aafc85f78.png)

#４，ソースコード
新しく作成するファイルは全部で５つです。
①index.js
![code11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/5f801f21-83e6-cc16-4858-48ae23eb3a84.png)
②App.js
![code8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/551a6ed4-8bb7-a100-ef8b-b312e8a0658c.png)
③global.css
![code12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/487ec6bf-ed21-5e91-c026-a1342af49c58.png)
④CountButton.css
![code10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/f0ac3f2c-559d-2ae7-b176-d840cb8834f3.png)
⑤CountButton.js
![code9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/813ec8b4-4fba-1297-1efd-1dac1cb7ce8b.png)

#４，参考動画

https://youtu.be/ABQLwlE8MUA
PHP exec  , execute 違い

#プリペアドステートメント使えるかどうか
参考：
https://freelance321.com/exec-query-prepare
https://www.php.net/manual/ja/function.exec.php
https://www.php.net/manual/ja/pdostatement.execute.php

###exec
一方的なINSERT, DELETEで使える


###execute
SELECTは必ずこっち
RubyOnRailsのモデル単体テストでPassword is invalidになったりならなかったりする。

RubyOnRailsのモデル単体テストでPassword is invalidになったりならなかったりしたので原因と対処法をめも。

■状況①
ユーザ情報とクレジットカード情報を入力したら商品を購入できる機能があり、モデルの単体テストを実行している。

■状況②
とあるユーザでログインしていないと商品を購入できないので、ユーザをFactoryBotとFakerで作成してログインさせる。

■状況③
単体テストコードを実行すると、ログイン状態で行われるexampleが成功したりしなかったりする。
失敗の場合、ターミナルにはFactoryBotでユーザ作成時にパスワードがおかしいぜと表示される。（下記スクショ参照）

![035d070d63ce1697e785727aeeb9b38d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1031653/aab0f5bd-2755-886a-bcc5-16d6e01c3d5d.png)

■原因
Fakerにて生成されたパスワードが、ユーザモデルのパスワードのバリデーションを満たしていなかった。

■バリデーション
・半角6文字以上が必須
・英数混合が必須

■修正したこと
password { Internet.password(min_length: 6) }
↓
password { 'T1' + Faker::Internet.password(min_length: 4) }

'T1'の部分で英数混合を担保しつつ、残りの4文字はFakerでランダム生成するようにしました。
6文字すべてをFakerで生成するとすべて英字もしくは全て数字のパスワードが生成され、要件を満たされていなかった、ということでした。
pythonを使ってwordpressの自動投稿する

プログラミング初心者の者です。
運営しているwebサイト（https://gakuseikoujyou.com)の投稿を手動でやっていたものをプログラムで自動投稿できるようしてみました。

自己学習ように記事を書き始めようと思いました。初心者ながらよろしくお願いします。
webサイトの紹介
<a href='https://gakuseikoujyou.com'><h2>明学ナビ</a>
![スクリーンショット 2021-03-16 5.23.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620639/53b5324b-4e64-37d6-2c13-469176f67266.png)

明学ナビとは明治大学のサークル一覧の掲載をメインにしているサイトです。
恥ずかしながら、信頼性確保のためサークル掲載は手動でデータを入力して投稿していました。

###今までのサークル掲載手順
-googleformにてサークル情報を記入してもらう
-googlespreadsheetからコピペしてwordpressにて投稿.

###pythonを使って業務効率化後の手順
-googleformにてサークル情報の記入をしてもらう
-ooglespreadsheet上でgasを使って、htmlを作成
-WordPress APIを用いて記事の自動投稿