OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】なぜ"private" "protected" "public"に分けるのか

# 概要
あるメソッドを実装するときに「アクセス権をどうするか？」という問題に必ず直面すると思います。
それぞれの特徴を知っておくことで、効率良く設計・開発が可能です。
ちなみにこれは`カプセル化`と言い、、オブジェクト同士の紐付き（関係性）を薄くし独立性を高め、再利用や交換といった保守性を高める効率の考え方です。

## 特徴
### publicメソッド

```
- クラスの主な責任や目的を明らかにする
- 外部から実行されることが想定される
- 思いつくままに変更されたりはしない
- 他者が依存したとしても安全
- テストで完全に文書化されている
```

### privateメソッド

```
- 実装の詳細に関わる部分
- 外部から実行されることは想定されていない
- 変更されやすい
- 他者が依存するのは危険
- 基本的にはテストはしない(個人的な意見です。諸説あり。)
```

### protectedメソッド

```
- 外部からは隠蔽されている
- 仲間(自クラスかサブクラスのレシーバー、親子関係にあるクラスのみ)からは実行可能
```

## 判断のポイント
- なるべく狭い範囲で設定するようにする。
    - 余計なアクセス権は想定外の場所の不具合を生む原因にもなりかねないため。
- privateメソッドを多用しないようにする。
    - 本来そのクラスの責務でないものを抱えてしまうことが可能性があるため。
    - 「別のクラスのpublicメソッドにする」可能性を視野に入れる。
- 最も範囲が狭い`private`をベースとして設計する。
- 継承先、あるいは継承元で呼び出したり上書きしたい場合は`protected`にする。
- 外部からのアクセスを可能にしたい場合は`public`にする。
Sass と CSS変数 を組み合わせて色をラクラク管理する

今まで Sass と CSS変数 を組み合わせた利用はできないと思っていました。

がしかし:exclamation::exclamation:

インターポレーション `#{}` を利用すれば利用できたんですね…:sweat_drops:
もっと早く知りたかった…:sweat:

たとえば、カテゴリーごとに見出しやボタンなど、要素の色を変えることって結構ありますよね？

今までは Sass のマップで色を管理し、 `@each` を使って各セレクタに色を設定していました。
これだと、色を変更する要素が増える度に設定しなければならず、とっても大変…

というわけで、Sass と CSS変数 を組み合わせて色をラクラク管理しちゃいます！

## 準備

Sass のマップを利用して色を管理します。
そして、 `@each` を使って `body` 要素にカテゴリーごとのCSS変数を設定します。

```scss:scss
$category-colors: (
  'primary': #FF0000,
  'secondary': #0000ff,
  'tertiary': #ffff00
);

@each $name, $color in $category-colors {
  body.#{$name} {
    // インターポレーションを利用してCSS変数にSass変数を代入
    --category-color: #{$color};
  }
}
```

## 色を利用する

### CSS

色を利用したい要素にCSS変数を設定します。


```css:style.css
.title {
  color: var(--category-color);
}
.btn {
  background-color: var(--category-color);
}

```

### HTML

利用したい色のカテゴリー名（Sass のマップのキー）を `body` 要素の `class` に設定します。

:::note info
body 要素の class名 を変更するだけで要素の色を変えることが可能です。
:::


```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title></title>
  <link rel="stylesheet" href="style.css">
</head>

<!-- Sass のマップのキーを設定する -->
<body class="primary">
  <h1 class="title">タイトル</h1>
  <button type="button" class="btn">ボタン</button>
</body>
</html>
```
デザイン作る前に思い出すこと

# デザイン作る前に思い出すこと

デザインを作成するときに思い出すことを自分で整理する用にまとめてみました。

### デザイン4原則
1. 『近接』……情報をまとめる
2. 『整列』……整える
3. 『反復』……リズムを作る
4. 『対比』……強調する

### その他気にしておくポイント

* 余白をとっているか
* 装飾が過剰ではないか、適切か
* 色の使い方や配色が適切か


上記を意識して作成すればそこまでひどいデザインにはならないはず…！
なんだかうまくいかないときは基本に戻って思い出しておきます。


##  近接
近接は関連する要素を近づけて情報をまとめる役割を果たします。
余白などの距離関係のみで関連性を強調できるので一瞬で内容を理解できます。
![グループ 18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311874/62a0d2b7-8939-16de-b2ec-0543bdb0c54f.png)




## 整列
要素を整列させることで統一感が生まれて視線の流れがスムーズになります。
左揃えや中央揃えなど読みやすくなるよう全体を見て決めておきます。
![グループ 19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311874/30302274-7975-34ee-29ad-6f82eb27b81d.png)


## 反復
同じ要素を繰り返し利用することで一貫性が生まれて読みやすくなります。
デザインやボタンや繰り返し使うことで統一感や可視性なども良くなります。
![グループ 20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311874/61e34812-60d2-1ab9-23c0-5c3f16838ab1.png)

## 対比
優先順位をつけて強調したいものを目立たせてデザインにメリハリをつける。
例えば文字が全部同じ大きさだとどの部分が重要なのかわからないためタイトルだけ大きくして強調…などです。
![グループ 21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311874/1d887fdd-deeb-508f-70c3-19a52fb7234d.png)

# おわりに
4原則を覚えておくとデザイナーに限らずちょっとした資料とかレポート作る際にもわかりやすくまとめられて役にたつかと思います。
より良いデザインになるように基本を大切に応用していきたいですね。
【備忘録】Reactのprettier設定

```json:.prettierrc.json
{
    "arrowParens": "avoid",　//単一引数時に（）の有無
    "bracketSpacing": true, // 単語間の空白スペース有無
    "htmlWhitespaceSensitivity": "css", //cssの設定
    "insertPragma": false,
    "jsxBracketSameLine": false,
    "jsxSingleQuote": false,
    "printWidth": 80,　//８０文字を超えたら改行する。
    "proseWrap": "preserve",
    "quoteProps": "as-needed",
    "requirePragma": false,
    "semi": false,　//セミコロンなし
    "singleQuote": true, //シングルクオート
    "tabWidth": 2, //tab幅はスペース2
    "trailingComma": "all",
    "useTabs": false
  }
```
画面のコンポーネントを自由自在にサイズ変更・保存

# 概要

ダッシュボードのような画面を作成する際、1つ1つの要素の大きさをグリッドに合わせて変更したり、変更した状態を保存できるようにしました。
その際に実施したことをまとめてみました。


# やったこと

- [vue-grid-layout](https://github.com/jbaysolutions/vue-grid-layout)のインストール
- 画面にGridLayoutコンポーネントを配置
- 位置情報や大きさを保存

# 前提

- nuxt.jsのプロジェクト構成で開発
- SSR（mode: 'universal'）


# vue-grid-layoutのインストール

プロジェクトにライブラリをインストールしました。
https://github.com/jbaysolutions/vue-grid-layout

```
yarn add vue-grid-layout
```

# 画面にGridLayoutコンポーネントを配置

pagesに保存したvueファイルで &lt;grid-layout&gt;及び&lt;grid-item&gt;タグを配置しました。
SSRの場合、&lt;grid-layout&gt;タグを配置する際は、&lt;client-only&gt;タグで囲う必要があります。

各グリッドの項目は、ドラッグアンドドロップ、サイズ変更を可能にするため、「is-draggable」「is-resizable」のオプションを"true"に設定しています。

参考にした記事
[https://kubio.dev/nuxt-client-only/](Nuxt.jsでClient側でしか使えないコンポーネントを使う)

```html
        <client-only>
          <div class="mb-5">
            <grid-layout
              v-if="chartList"
              :layout="chartList"
              :col-num="12"
              :row-height="100"
              :is-draggable="true"
              :is-resizable="true"
              :is-mirrored="false"
              :vertical-compact="true"
              :margin="[10, 10]"
              :use-css-transforms="true"
            >
              <grid-item
                v-for="(item, key) in chartList"
                :key="key"
                :x="item.x"
                :y="item.y"
                :w="item.w"
                :h="item.h"
                :i="item.i"
              >
                  <v-card>
                  Vuetifyのカードコンポーネントにグラフのコンポーネントを配置しています。
                  ※記載は省略
                  </v-card>
              </grid-item>
            </grid-layout>
          </div>
        </client-only>

```



# 位置情報や大きさを保存

grid-itemの位置（x, y)、大きさ(w, h）、インデックスとなる値（i）を保存。
復元時に<grid-item>の各値に設定するようにして、レイアウトを復元しました。

保存先はローカルストレージでも良かったのですが、このプロジェクトではサーバーサイドで保存させました。

```json
{
   "i": 1,
   "x": 0,
   "y": 0,
   "w": 8,
   "h": 4
   ・・・（省略）
}
```



# 出来上がった様子

こんな感じでグリッドサイズを変更して表示を制御できます。
![グリッドを動かしてみる.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498107/1e18d560-47a7-45dc-633c-be9ca25a6c75.gif)



# 参考情報

- [Vue Grid Layout(Document)](https://jbaysolutions.github.io/vue-grid-layout/)
【一分理解】スクレイピンングしてみよう

## スクレイピングってなに？
スクレイピングとは、ウェブサイトから情報を抽出することです。
サイト上のデータ(商品、価格、天気などのデータ)を取ってくることが多いです。

## pythonで書いてみよう
#### 必要なもの(pip)
・requests
・BeautifulSoup
・調べたいサイトのURL

#### 流れ
requestsで取得
```python
res = requests.get("URL")
```

BeautifulSoupでサイトデータを抽出
```python
soup = BeautifulSoup(res.text, "html.parser")
```

欲しい部分を決定
ex)クラス名:product_lists aaa の ul の中の liを取得
※商品一覧などの構造はだいたいこんな感じ
```python
found_part = soup.find_all("ul", class_='product_lists aaa')
for ul_tag in found_part:
        for li in ul_tag.find_all('li'):
            print(li.find('span').text)
```

サンプルソース
[MyGitHub](https://github.com/yamuyum/python-Basic/blob/main/src/scraping.py "yamuyum/python-Basic")

# ここ注意
:::note alert
サイトによってはスクレイピングを禁止しているものもあるため、確認する必要がある。
:::
【Git】リモートリポジトリの過去のバージョンを取得

Github等のリモートリポジトリの過去のバージョンを取得する方法


# 1.過去のバージョンを確認

```
git log <オプション>
```

# 2.過去のバージョンに戻す

1に表示された戻したいバージョンのコミットIDを使用する

```
git checkout <コミットID>

#　例
git checkout 838dff8fsdfsdf8sdsdf8sd8fdsf8sdf8dg
```
【AWS Summit 2021】日立がチャレンジするクラウドネイティブな社会イノベーション！②

みなさんこんにちは。子育てしながらクラウド推進！日立のモフママです。
前回に引き続き，AWS Summit Online Japan 2021 での日立セッションについてご紹介していきます。


![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/c6d60a35-8ea8-095a-0a3a-9007f988428c.png)


![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/47339e72-43fb-3e19-f7f9-da898cca8140.png)

https://qiita.com/mofu_mother/items/97eb4701c36c67819984


![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/2b811247-ee75-44ec-f3b7-27ead051881d.png)


![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/6dbf752f-852b-49b0-e12b-23bbb96d6a05.png)


![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/b4aefb3e-c84a-a457-c8a8-2e076a5ac1c0.png)


![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/b4a5b3dd-d16c-cf24-f817-4bbdc138aede.png)


![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/8f6ab84d-084f-542c-7ab5-bef9db45ced2.png)


![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/d1c81054-af62-e1db-09b8-2b8bb38228ac.png)


![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/2c233e2b-44ac-4a30-1901-9f11f7434439.png)


![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/b8cea006-a96e-37cf-9152-f2e3852803c5.png)


![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/8744662e-f2c2-25ef-5bd6-b438da8695f1.png)


![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/f19afd67-445d-fb8f-03e4-27ab87413915.png)


https://aws.amazon.com/jp/builders-flash/202003/chalice-api/



![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358174/864777b0-e8b9-976e-89ac-b1863e9e1ecd.png)



<iframe width="560" height="315" src="https://www.youtube.com/embed/LLi1lzhpoto" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

***

+ AWS は、米国その他の諸国における Amazon.com, Inc. またはその関連会社の商標です。
+ その他、本資料に記述してある会社名、製品名は、各社の登録商品または商標です。
Python 複数スレッドをEvent制御してるときCtrl+Cが効かなくなった時のテクニック

すべてのスレッドでevent.waitしている場合、各スレッドがロックされるためctrl+cが受け取れない。
そのため、event.waitを使わないスレッドを必ず１つ用意しておく。このスレッドでctrl+cを受け取り終了フラグをTrueにして子スレッドの条件に終了フラグを配置していおけばループから抜けることができる。


```python
import time
import threading

e_task1 = threading.Event()
e_task2 = threading.Event()

f_sys_exit = False


# ===============================
# 制御不可能なchildスレッドの処理
# ===============================
def can_not_control_task1():
    while True:
        print(threading.current_thread().name, ' is waitting.')
        e_task1.wait()
        print(threading.current_thread().name, ' end.')


def cant_not_control_task2():
    while True:
        print(threading.current_thread().name, ' is waitting.')
        e_task2.wait()
        print(threading.current_thread().name, ' end.')


# ===============================
# 制御可能なchildスレッドの処理
# ===============================
def can_control_task1():
    while True:
        if f_sys_exit:
            break
        print(threading.current_thread().name, ' is waitting.')
        e_task1.wait()
        print(threading.current_thread().name, ' end.')


def can_control_task2():
    while True:
        if f_sys_exit:
            break
        print(threading.current_thread().name, ' is waitting.')
        e_task2.wait()
        print(threading.current_thread().name, ' end.')


# ===============================
# childスレッドの実行処理
# ===============================
def run_can_not_control_child_thread():
    """コントール不可能"""
    ths = []
    for task in [can_not_control_task1, cant_not_control_task2]:
        th = threading.Thread(target=task, name=task.__name__, daemon=False)
        th.start()
        ths.append(th)
    for th in ths:
        th.join()


def run_can_control_child_thread():
    """コントール可能"""
    ths = []
    for task in [can_control_task1, can_control_task2]:
        th = threading.Thread(target=task, name=task.__name__, daemon=False)
        th.start()
        ths.append(th)
    for th in ths:
        th.join()


# ===============================
# メインスレッドの実行処理
# ===============================
def can_not_control():
    """コントール不可能"""
    global f_sys_exit
    threading.Thread(target=run_can_not_control_child_thread, daemon=True).start()
    while True:
        try:
            time.sleep(1)
            print('parent thread is running.')
        except KeyboardInterrupt:
            print('pressed to Ctrl + C keys.')
            break


def can_control():
    """コントール可能"""
    global f_sys_exit
    threading.Thread(target=run_can_control_child_thread, daemon=True).start()
    while True:
        try:
            time.sleep(1)
            print('parent thread is running.')
        except KeyboardInterrupt:
            print('pressed to Ctrl + C keys.')
            # sys_exitフラグをTrueにしてから　
            f_sys_exit = True
            # すべてのwait中のスレッドをsetする
            set_all_event()
            break


# ===============================
# イベント処理
# ===============================
def set_all_event():
    """すべてのイベントをset"""
    global e_task1, e_task2
    e_task1.set()
    e_task2.set()


if __name__ == '__main__':
    # can_not_control()
    can_control()

```
Xcode13.3でSwiftPM.SPMRepositoryError error 5

# Xcode13.3でSwiftPMがうまく動かない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208579/0b076bbc-56b5-ffaa-2d73-67528e58577e.png)

Developer Forumsで同じ現象に陥っている人もいる模様
[Xcode 13.3 SwiftPM.SPMRepositoryEr… | Apple Developer Forums](https://developer.apple.com/forums/thread/702462)
[swift - What is "SwiftPM.SPMRepositoryError error 5"? - Stack Overflow](https://stackoverflow.com/questions/71506588/what-is-swiftpm-spmrepositoryerror-error-5/71515395#71515395)

# ECDSA鍵を生成・登録
参考：　[ECDSA鍵をGitHubで使う - Qiita](https://qiita.com/darai0512/items/c7b47d1b3fe06c4dea7d)

①鍵を生成

```
ssh-keygen -t ecdsa -b 256 -C <gitに登録しているメールアドレス>
```

②公開鍵の中身をGitHubの設定のSSH keysに登録
https://github.com/settings/ssh

参考：　[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~ - Qiita](https://qiita.com/shizuma/items/2b2f873a0034839e47ce#%E5%85%AC%E9%96%8B%E9%8D%B5%E3%82%92github%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B)

# Xcodeのアカウント設定でSSH Keyを更新

1. [Xcode] > [Preferences (環境設定)] を選択します。
1. ウィンドウの上部にある[アカウント(Accounts)] 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208579/c710e09c-c2ff-53bd-c32a-b4f77884fb99.png)
MiniPupper ROS: WSL2でroscoreが動かない

## 環境
* windows10
* Ubuntu20.04 on WSL2
* ROS noetic
* Raspi4 8GB RAM
* Raspi image: (64bit)v1.0.0.20220219.MiniPupper_V2_ROS&OpenCV_Ubuntu20.04.03.img.zip

## 概要
MiniPupperの公式ドキュメントを参考にしてSLAM & Navigation ページでのroscoreコマンド(Step 3.6)を実行しようとしたら、上手く動かない。

## 解決策
どうやらWSLでUbuntuを使っている場合、ホストPCのipアドレスはWSLに割り振られたipアドレス(windowsPC本体のではない)を使用しなければならないようだ。
ドキュメントの192.168.1.7と書かれている部分をlocalhostと書いたら正常に動いた。
ラズパイのipが起動毎に変わる場合は、ipの代わりにhostnameを書く。

```:Step 2.6 Network setup
export ROS_MASTER_URI=http://localhost:11311
export ROS_HOSTNAME=localhost
```
hostname出力 ↓

```:shell
hostname
```

```:Step 3.3 Network setup
export ROS_MASTER_URI=http://localhost:11311
export ROS_HOSTNAME=ubuntu
```
"ubuntu" ↑は各自のhostnameにする。

## 参考
[Mini Pupper Document](https://mangdang-minipupperdocs.readthedocs-hosted.com/en/latest/index.html)
Outlook VBAで宛先(To)から挨拶文を自動生成する

# はじめに

OutlookでEメールを作成する際、だいたいは決まった挨拶文を書くかと思います。例えば、

```txt
To: ◇◇地域振興局建設部 △△課 ○○班 猪鹿技師 様 <inosika.chouko@pref.cats.lg.jp>
```

に対して、

```txt
◇◇地域振興局 建設部
△△課 ○○班
　猪鹿 技師 様

いつも大変お世話になっております。
```

といった感じに。テンプレートにしている方もいるかと思いますが、多くの人は毎回同じことを手入力したり、以前の送信済メールからコピペしているのではないでしょうか。

連絡先から宛先(To, CC, BCC)に相手のアドレスを入れたときに”挨拶文”を自動で入力できたら便利だと思ったので、これをOutlook VBAで実装してみたいと思います。 (※「自動で」と書きましたが、宛先を入力したときのイベント処理が分からなかったため、ここでは宛先を入れた後にリボンやクィックアクセスツールバーに置いたボタンから起動することとします。)

# 基本的な考え方

## 用語

- メインのウィンドウ : Explorer オブジェクト
- それ以外のウィンドウ : Inspector オブジェクト
- 宛先(To,CC,BCC) : Recipients コレクション
- 個々の宛先 : Recipient オブジェクト
- 連絡先ユーザ : AddressEntry オブジェクト
- 連絡先アイテム : ContactItem オブジェクト

## 前提条件

今回は、基本的な処理の説明ですので、以下の前提条件を付けておきます。

1. 「宛先」(メールアドレスや氏名、勤務先の情報)は、Outlookの「連絡先」に必ず入っているものとする
2. 新規メッセージ作成ウィンドウでの作業とする (Inspectorオブジェクト)
3. メッセージの形式は「テキスト形式」とする (PlainText形式)
4. 対象とする宛先は To に一つのみとする
5. 作成ウィンドウの宛先(To)に対象のメールアドレスを入力しておく

![outlook-vba-recipient-to-headline-01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307310/1ed93c34-2644-cc64-992d-c5145e4c10c6.jpeg)


## 処理の流れ

基本的な処理の流れは以下の通りです。(確認やエラーの処理は省きます)

1. MailItemオブジェクトを取得する
2. 宛先 (Recipientsコレクション) を取得し、.Type が olTo だった場合の Index を取得する
3. 本文の内容 (MailItem.Body) を取得しておく
4. Index に対応する宛先 (Recipientオブジェクト) に対応する連絡先ユーザ (AddressEntryオブジェクト) から 連絡先アイテム (ContactItemオブジェクト) を取得する
5. ContactItem から 勤務先、部署、姓(名字)、役職の各プロパティを取得して挨拶文を生成する
6. 3で取得しておいた本文の先頭に挨拶文をつなげて本文を上書きする

```vb:Outlook VBA
Public Sub SetEMailHeadline()

  '// 変数の定義
  Dim myMailItem    As MailItem
  Dim myRecipient   As Recipient
  Dim myContactItem As ContactItem
  Dim myIndex       As Long
  Dim tempBodyText  As String
  Dim tempHeadline  As String

  '// 1. MailItemの取得
  Set myMailItem = Application.ActiveInspector.CurrentItem

  '// 2. RecipientsコレクションからToを選んでIndexを取得
  For Each myRecipient In myMailItem.Recipients
    If myRecipient.Type = olTo Then
      myIndex = myRecipient.Index
    Exit For
  Next

  '// 3. 本文の内容を取得
  tempBodyText = myMailItem.Body

  '// 4. 宛先に該当する連絡先アイテムを取得
  Set myContactItem = myMailItem.Recipients.Item(myIndex).AddressEntry.GetContact

  '// 5. 各種プロパティを取得
  With myContactItem
    tempHeadline = .CompanyName & vbCrLf & _
                   .Department & vbCrLf & _
                   "  " & .LastName & " " & .JobTitle & " 様" & vbCrLf & _
                   vbCrLf & _
                   "いつも大変お世話になっております。"
  End With

  '// 6. 挨拶文を本文の先頭に追加
  myMailItem.Body = tempHeadline & tempBodyText

  '// オブジェクトの解放
  Set myContactItem = Nothing
  Set myMailItem = Nothing
End Sub
```

# おわりに

上記のコードでは、考えられる条件分岐やエラー処理などをしていません。次回はそこら辺を詰めていきたいと思います。
Datorama 関係のまとめ


[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)


# 表示関係

+ [ドーナツチャートCSS : ラベルの色を変えたい](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000FvVFE)
【Javascript】配列や連想配列をディープコピーして安全な配列を取得する。【JSON.parse, JSON.stringify】

自分用のメモとして残します。

Reactでstateで多次元の連想配列を参照する際は普通の代入ではなくディープコピーしないと、
大元のstateに格納した値（≒要素）がsetStateしてないのに変わってしまいます。
そのため、ディープコピーをしてあげることで安全に作業用の別配列として扱えるようにします。


# やり方
JSON.stringify でjson文字列にしてから JSON.parse でJson文字列をjsで使用できる形式に変換する。
```javascript
//this.state = {hoges : [{hoge1:'hoge2'},{hoge10:'hoge20'}]} //左記の値がhogesに入っているとする。
let orig_hoge = this.state.hoges 
// orig_hoge をこのまま使うと、this.state.hogesの値も変えてしまうため、下記でディープコピーしてあげる。
let clone_hoge = JSON.parse(JSON.stringify(orig_hoge)) 
```

以上です。
[Dart]Stream は便利なもの

# 導入
```Stream```を使うと値が更新された時に自動で知らせてくれるみたい。
以下参考。

https://dart.dev/tutorials/language/streams

>Streams can be created in many ways, which is a topic for another article, but they can all be used in the same way: the asynchronous for loop (commonly just called await for) iterates over the events of a stream like the for loop iterates over an Iterable. For example:
>> Future<int> sumStream(Stream<int> stream) async {
>>  var sum = 0;
>>  await for (final value in stream) {
>>    sum += value;
>>  }
>>  return sum;
>>}
>
> This code simply receives each event of a stream of integer events, adds them up, and returns (a future of) the sum. 

# まとめ
チャット機能などに使うと有効活用できそう。
```Stream```は便利なものだ。
問題解決力 = 問題分析力 + 論理的思考力

# 想定読者
ランタイムエラーやバグが出ても自分で直せない人


# 結論
問題を解決したいときは、まずは問題自体を分析してください😤

その問題は
__なにが__
__どこで__
__なぜ__
__どのような条件で__
起きているのかを具体的にしてください。


# カレー作りを例にすると
「自分で作ったカレーが不味い」とします🤯
「次はおいしく作りたい」とします。

どうしたらよいでしょうか？

水の量を変える
カレー粉の量を変える
カレー粉の味を変える
などが考えられますね。

他にも様々な対策案が出せると思いますが、
「どれが効果的なのか」は分からないと思います。
それに「量を変える」と言っても、減らすのか増やすのかが曖昧です。

でも「不味い」ではなく「薄い(から不味い)」というように、
問題を具体的にしてみるとどうでしょうか？
「水を減らす」または「カレー粉の量を増やす」が効果的であることが分かります😊


# プログラムを例にすると
「エラーが出た」とします🤯
「このエラーを解決したい」とします。

カレーのときと同じようにいろいろな対策案は出せますが、
これも「どれが効果的なのか」は分からないと思います。
方針レベルのことは考えられても、実際に実施するのは難しいでしょう。

しかし「エラーが出た」ではなく
「(ファイル名) の ○○行目 で ○○Exception が出た」であれば、
ある程度対策案を絞り込むことができます。
その原因として「○○ の値が ○○ だから」ぐらいの粒度まで分析できれば、
問題はほとんど解決したようなものです。

# まとめ
エラーなど問題が発生したときは問題自体を分析せよ😤
__問題を分析しない限り解決もできない__

# 補足
「エラーが出ました」と誰かに相談すると、大抵はこんな質問をされると思います。
・「どんな内容のエラーが出たの？」
・「どんな条件でエラーが出るの？」
・「どこでエラーが出たの？」
・「エラーの原因は？」
・「エラーが出る操作をもう1回やってみて」

これらの質問も結局のところ、問題自体を分析しているだけに過ぎません。
これからはこれらの質問を自分自身にしてみて、
問題分析力を上げていけば、問題解決力も自ずと上がっていきます🥰
[Rails] Address already in use が発生してrails sができなかった

## 前提
・Dockerで環境構築をしている
・Rails 6.1.5

## エラーの内容
```
`initialize': Address already in use - bind(2) for "0.0.0.0" port 3000 (Errno::EADDRINUSE)
```

## 原因
既に3000Portが使われているため同じポート番号は使えないよというエラー

## 解決策
3000Portを使用しているプロセスを終了する

### ①3000Portを使用しているプロセスの番号を調べる

```
# 現在、実行しているプロセスを表示するコマンド
$ ps -x

  PID TTY      STAT   TIME COMMAND
    1 pts/0    Ss+    0:00 irb
    8 pts/1    Ss+    0:00 /bin/bash
   15 pts/2    Ss+    0:00 /bin/bash
   32 pts/1    Z+     0:00 [ruby] <defunct>
   64 pts/3    Ss+    0:00 /bin/bash
  919 pts/4    Ss     0:00 /bin/bash
 1559 pts/1    Sl+    0:00 spring server | rails-app | started 72 hours ago
 2288 pts/4    Sl+    0:20 puma 5.6.2 (tcp://0.0.0.0:3000) [rails-app]
 2689 ?        Ssl   13:18 spring app    | rails-app | started 45 hours ago | test mode
 2690 ?        Ssl   13:19 spring app    | rails-app | started 45 hours ago | development mode
 2728 pts/5    Ss     0:00 /bin/bash
 3115 pts/5    R+     0:00 ps -x
```

後から気づいたがプロセス多いと探すの大変だからgrepで検索する方が良さそう
```
$ ps -x | grep 0.0.0.0:3000

 2288 pts/4    Sl+    0:01 puma 3.12.6 (tcp://0.0.0.0:3000) [rails_app]
 3168 pts/5    S+     0:00 grep 0.0.0.0:3000
```

### ②killコマンドでプロセスを終了する
```
# killコマンドにはPIDの番号を渡す
$ kill 2288
```

もう一度ps -xで確認するとプロセスが消えているはずだが、消えていなければ下記のコマンドで強制終了する
```
#-9オプションで強制終了
$ kill -9 2288
```

プロセスが終了していることを確認したらrails sすれば起動できるはず。
【Flutter】アプリアイコンのパッケージ、flutter_launcher_iconsで【FormatException: Invalid number (at character 1)】エラーが発生したときの対処

## この記事を読んだら分かること
Flutterでflutter_launcher_iconsを使ってアイコンを設定するときのエラーの対処ができ、アプリアイコンを設定できる！！
エラー内容
```
FormatException: Invalid number (at character 1)
```


## 解決方法
`pubspec.yml`を下記のようにすればOK
dart 2.8の問題らしくgithubでIssueが立ってます。

https://github.com/fluttercommunity/flutter_launcher_icons/issues/316#issuecomment-1004942356



```pubspec.yml

  flutter_lints: ^1.0.0
  flutter_launcher_icons:
    git:
      url: https://github.com/Davenchy/flutter_launcher_icons.git
      ref: fixMinSdkParseFlutter2.8
  
flutter_icons:
  android: true 
  ios: true
  # 画像ファイルのパスを指定する
  image_path: "lib/assets/icon.png"
```

## 修正確認

ターミナルで、下記のコマンドを実行する
```
$ flutter pub run flutter_launcher_icons:main
```

## 結果（成功）
```
  ════════════════════════════════════════════
     FLUTTER LAUNCHER ICONS (v0.9.1)                               
  ════════════════════════════════════════════
  
• Creating default icons Android
• Overwriting the default Android launcher icon with a new icon

WARNING: Icons with alpha channel are not allowed in the Apple App Store.
Set "remove_alpha_ios: true" to remove it.

• Overwriting default iOS launcher icon with new icon

✓ Successfully generated launcher icons
```

## 結果（失敗例）
```
  ════════════════════════════════════════════
     FLUTTER LAUNCHER ICONS (v0.8.0)                               
  ════════════════════════════════════════════
  

✓ Successfully generated launcher icons
Unhandled exception:
FormatException: Invalid number (at character 1)

^

#0      int._handleFormatError (dart:core-patch/integers_patch.dart:129:7)
#1      int.parse (dart:core-patch/integers_patch.dart:55:14)
#2      minSdk (package:flutter_launcher_icons/android.dart:294:18)
#3      createIconsFromConfig (package:flutter_launcher_icons/main.dart:90:47)
#4      createIconsFromArguments (package:flutter_launcher_icons/main.dart:58:7)
#5      main (file:///Users/cnctrk/develop/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_launcher_icons-0.8.1/bin/main.dart:6:26)
#6      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:32)
#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
pub finished with exit code 255
```

Succesfullyって出るけど失敗してるのが分かりづらかった・・・
ちなみにアイコン画像は1枚だけ用意すればOKです。（正方形比率、劣化しないPNGがいいと思う）
サイズのバリエーションはパッケージ側で勝手にやってくれます。
【rails】DBアクセス時のログにLoadと表示されるメソッドと、表示されないメソッドの違いとは


DBアクセス時に、`モデル名 Load`と表示されるメソッドの例
```
User.all
=> User Load (4.6ms)  SELECT "users".* FROM "users"

User.first
User Load (5.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1

User.find(1)
User Load (1.4ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
```

DBアクセス時に、`モデル名 Load`とログに表示されないメソッドの例
```
User.count
(2.0ms)  SELECT COUNT(*) FROM "users"

User.pluck("email")
(1.7ms)  SELECT "users"."email" FROM "users"
```

上記の違いは単純で、モデルオブジェクトの構築の有無です。
`モデル名 Load`のようにログにでるものは、モデルオブジェクトを作成した上で、メモリにロードしているんですね。

`pluck`などもメモリにデータをロードしてるんですが、モデルオブジェクトではないのでその分高速です。

> pluck必要なフィールドだけを読み込むことで、メモリの使用量も削減できるとの事で
これが圧倒的に早い理由らしい

https://qiita.com/TT-nasu/items/e6971efd1383d7f500dd
Laravelのビューコンポーザ【個人的なお勉強アウトプット】

## 参考図書
https://www.amazon.co.jp/dp/B07CLLW4MX/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

## ビューコンポーザとは
LaravelはMVCアーキテクチャ。
ビューで処理をした内容を表示したい場合、ビューのテンプレートBladeで`@php`ディレクティブを使うやり方や、コントローラーで処理をして値を渡す方法はある。しかし、表示するだけの役割のビューテンプレートで処理をするのは避けたほうがよく、コントローラーで処理をするのも何か違う気がする。という問題がMVCにはあった。
その問題を解決するのがビューコンポーザ。
指定のビューに常に同じ処理をして表示するものがある場合、ビューコンポーザを利用したほうが良い。

## サービスとサービスプロバイダ
ビューコンポーザはLaraveの「サービス」、「サービスプロバイダ」を使う。
サービスはLaravelの機能強化の仕組み。
サービスを登録するために用意するのが「サービスプロバイダ」。
サービスプロバイダにビューコンポーザというサービスを登録しておくと、自動的に実行されるようになる。

## サービスプロバイダのつくりかた
```
php artisan make:provider HelloServiceProvider
```
app/provider/の中にファイルが作成される

## サービスプロバイダの基本形

```app/provider/HelloServiceProvider.php
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class プロバイダクラス extends ServiceProvider{
public function register(){
//コンポーザの設定
}
public function boot(){
//コンポーザの設定
}
}
```
サービスプロバイダはServiceProviderというクラスを継承して作成される。
registerメソッドはサービスプロバイダの登録処理を行う。
bootメソッドはアプリケーションサービスへのブートストラップ処理（アプリケーションが起動する際に割り込んで実行される処理）。
ここにコンポーザを設定する処理を用意することで、設定したビューをレンダリングする際に自動的にコンポーザが呼び出されるようになる。

## サービスプロバイダの登録
HelloServiceProviderクラスをプロバイダとしてアプリケーションに登録
```config/app.php
'providers' => [
...
...
App\Providers\HelloServiceProvider::Class
],
```

## ビューコンポーザの使い方
ビューコンポーザには二通りの使い方がある

- boot内に無名クラスでビューコンポーザの処理を読み込む
- ビューコンポーザのクラスを定義して、bootで設定する

本格的に使うときは「ビューコンポーザのクラスを定義して、bootで設定する」。


### boot内に無名クラスでビューコンポーザの処理を読み込む
```app/Providers/HelloServiceProvider.php
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class プロバイダクラス extends ServiceProvider{
public function register(){
//コンポーザの設定
}
public function boot(){
  View::composer(
    'hello.index', function($view){
      $view->with('view_message','composer message!');
    }
  );
}
}
```
引数の$viewはIlluminate\View名前空間にあるViewクラスのインスタンス。ここにあるメソッドなどを利用してビューを操作することができる。
withメソッドはビューに変数などを追加することができる。
```
$view->with('変数名','値');
```

#### ビューコンポーザを利用
```resources/views/hello/index.blade.php
@section('content')
<p>ViewComposer value:{{$view_message}}</p>
@endsection
```
### ビューコンポーザのクラスを定義して、bootで設定する
ビューコンポーザのクラスは特に配置する場所は用意されていない。Httpフォルダ内であればどこでも利用可能。
```app/Http/Composers/HelloComposer.php
namespace App\Http\Composers;

use Illuminate\View\View;

class HelloComposer{
  public function compose(View $view){
    $view->with('view_message' $view->getname());
  }
}
```
コンポーザクラスで必要になるのはcomposeメソッド。インスタンスを引数として持っていて、サービスプロバイダのbootからView::composerが実行された際に呼び出される。
上記のHelloComposerをビューコンポーザとして利用するため、HelloServiceProviderに記述。

```app/Providers/HelloServiceProvider.php
public funtion boot(){
  View::composer(
    'hello.index', 'App\Http\Composers\HelloComposer'
  );
}
```
第2引数に呼び出すクラス名を指定。
Python/sqlalchemyでテーブルをバージョン管理するalembicで困ったとき

# 前提

使い方、導入の仕方などはこちらの記事がが非常に有用でしたのでご参照ください。

https://qiita.com/penpenta/items/c993243c4ceee3840f30

この記事では使い方ではなく困った時の解決法などをいくつか書いていきます。また、随時更新します。

## 競合が起こった時

gitでもよくあることですがチームでバージョン管理していると競合が起こります。

```java
alembic history --verbose
```
こちらのコマンドでheadリビジョンを確認することができます。

バージョンはRivision IDで管理しているので競合を起こしているリビジョンのpyファイルを退避させましょう。

```java
alembic upgrade head
```

でテーブルが最新リビジョンと相違ない状態になったらsqlalchemyで定義してあるテーブルと退避させたpyファイルの相違している部分を修正し、

```java
alembic revision --autogenerate
```

しましょう。
alter文でつくられたリビジョンが生成されるので再度

```java
alembic upgrade head
```
で目的のリビジョンを反映させることができます。

## headが2つ存在してしまった場合

例えばですが

```java
alembic upgrade head
```
をすることがないまま

```java
alembic revision --autogenerate -m "create tables"
```
を2回してしまった場合、headリビジョンが2つ存在してしまうという状況になります。
もちろんこのように単純なケースであれば古い方のリビジョンのpyファイルを消してしまえば解決するのですが、それぞれのリビジョンから派生して複数のalter_table.pyがつくられてしまった場合、後に

```java
alembic upgrade head
```

すると

`
FAILED: Multiple head revisions are present for given argument 'head'; please specify a specific target revision, '<branchname>@head' to narrow to a specific head, or 'heads' for all heads
`

というエラーメッセージが出ます。headを1つにしてくださいという意味ですね。

じゃあリビジョンを指定してあげて...

```java
alembic revision -m "hogehoge"
```

としたところで

`
FAILED: Multiple heads are present; please specify the head revision on which the new revision should be based, or perform a merge.
`

と出てしまう。

実はheadの管理って

```
revision = 'hoge'
down_revision = None
```

ここでしてるんですよね。


なので

```
revision = 'hoge'
down_revision = 'fuga'
```

と指定してあげましょう。

そうするとhogeがheadに、fugaが1つ前のリビジョンになります。

あとは
```java
alembic upgrade head
```
すればいいだけです。

## autogenerateでカラムの型変更が検出されない時の解決方法

env.pyの
`context.configure`
に、
```java
compare_type=True
```

を追加してあげましょう。
その後
```java
alembic revision --autogenerate
```
すれば検出してくれます。
Azure Data Factory / Synapse Analytics Mapping DataflowでPipeline上で取得した日付時刻を利用する

## はじめに

ちょっとつまったので備忘です。

Data Factory のパイプライン側で取得した日付時刻を使用して、データフロー側で処理される対象のファイルを限定したいという動機がありました。
ここのフィルタですね。このフィルタにpipeline 側で取得した日付時刻を使って処理をするにはどうするかという記事になります。

![2022-03-23-10-59-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f7f85bde-ea37-b52b-8c99-017b420cb4c3.png)



### 注意事項

2022/03時点の情報となります。


## 方法

この例では、パイプライン実行前日（日本時間での前日）までに連携されたファイルを対象にしたいとします。
データフローでタイムスタンプに変換可能な形式の文字列でデータフローパラメータに入力してやる必要があります。


1.データフローに以下のような文字列のパラメータを作成

![2022-03-23-11-09-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/5900d46d-f624-a466-49ca-e1220c03f235.png)


2.ソースのフィルタを以下のように設定

```

toTimestamp($filterTimeStamp,'JST')

```

![2022-03-23-11-27-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/7b74d3f2-5176-0365-52a9-8adf76312d9c.png)


3.パイプラインが実行された日本時間でのその日の開始日付時刻を取得し、フォーマットを調整します。※Azureは基本UTCで物事を考えるためこのあたりの変換はややこしいので注意

```

@startOfDay(convertFromUtc(pipeline().TriggerTime,'Tokyo Standard Time'),'yyyy-MM-dd HH:mm:ss')

```



4.上記の式をデータフローの実行パラメータに設定する

![2022-03-23-11-11-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/b93c7df1-803c-551c-e0a8-5800d4b3fdf6.png)

![2022-03-23-11-14-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d57a39cc-3ce1-5e5d-0755-1333e89f07d3.png)

## 参考情報

以下の差異により、フォーマットを調整してやる必要があったということでした。

### パイプライン側で取得される日付時刻のフォーマット

フォーマットを指定しない場合、ISO 8601 に準拠した[yyyy-MM-ddTHH:mm:ss:fffffffK]のフォーマットで返されます。

[Azure Data Factory および Azure Synapse Analytics の式と関数](https://docs.microsoft.com/ja-jp/azure/data-factory/control-flow-expression-language-functions)

一例としてstartOfDay

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

startOfDay

タイムスタンプの日の開始日時を返します

単一の書式指定子またはカスタム書式パターン。 timestamp の既定の形式は "o" (yyyy-MM-ddTHH:mm :ss : fffffffK) です。これは、ISO 8601 に準拠し、タイム ゾーン情報を保持します

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


### データフロー側のTimestamp変換可能なフォーマット


[マッピング データ フローでのデータ変換式の使用](https://docs.microsoft.com/ja-jp/azure/data-factory/data-flow-expressions-usage)

一例としてtoTimestamp

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

toTimestamp

省略可能なタイムスタンプ形式を指定して、文字列をタイムスタンプに変換します。 タイムスタンプを省略すると、既定のパターンの yyyy-[M]M-[d]d hh: mm:ss[.f...] が使用されます。
省略可能なタイムゾーンを 'GMT'、'PST'、'UTC'、'America/Cayman' の形式で渡せます。 タイムスタンプでサポートされる最大精度は、ミリ秒 (値 999) です。

使用可能な形式については、Java の SimpleDateFormat クラスを参照してください。

---------------------------------
IISとは

### IISとは

「Webサーバのソフト（のひとつ）」

※WebサーバーのソフトをPCに入れることによってPCもその役割を果たす。
IISはマイクロソフトが作ったのでWindowsには対応しているけど、Macでは対応していない。

---

### 同類での他には...

 - Apache（アパッチ）
 - nginx（エンジンエックス）

これらも同じ役割Webサーバーの種類
Webサーバーの2台巨頭といわれているのはIISとApache

---

### 参考
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
 - [エンジンエックス (nginx)](https://wa3.i-3-i.info/word12859.html)
 - [IIS (アイアイエス)](https://wa3.i-3-i.info/word12466.html)


[「Apache」とは？Webサーバソフトの役割から特徴に至るまで詳しく紹介](https://hnavi.co.jp/knowledge/blog/apache/)
FlaskとLINE Loginを使ったメンタル共有アプリ

# webアプリを作りました。
この度、webアプリ「[metnal](https://metnal.stock-stu.com/)」を作ったのでご紹介させていただこうと思います。
[metnalの紹介ページ](https://stock-stu.com/introduce_metnal/)では機能面の紹介が多いので、ここでは技術的な面を多めに書かせていただきます。
## 自己紹介
プログラミングほぼ未経験の文系大学生です。
当然webアプリなんて作ったこともないので、試行錯誤の連続でした。

そんな中で、Flaskで作ったアプリにLINEログインやLINE messaging APIといったLINE関連機能や、PWAといった全く知らない機能を導入したのは、自分でもよくやったな～と思っています。
## アプリの説明
[metnal](https://metnal.stock-stu.com/)は簡単に言えば、「メンタル共有アプリ」です。
### 機能の説明
大きく分けて、ログインページとユーザーページ、ゲスト用ページが存在しています。
#### ログインページ
![ログインページ](https://applishow.com/img/uploads/000000100000/nqlwcLETUdvJ/screenshot_1.png?t=1648001280)
ログインページはシンプルさにこだわり、LINEログイン以外を認めないことにしました。
#### ユーザーページ
![ユーザーページ](https://applishow.com/img/uploads/000000100000/nqlwcLETUdvJ/screenshot_2.jpg?t=1648001280)
ユーザーページでは気分を５段階で入力できます。
気分に基づいて、その時の気分スコアを算出します。

また自分の気分を周囲の人に共有することが出来ます。
#### ゲスト用ページ
![ゲストページ](https://applishow.com/img/uploads/000000100000/nqlwcLETUdvJ/screenshot_3.jpg?t=1648001280)
共有してきた人のスコアを見ることが出来ます。
#### LINE通知
ただ単に共有されたスコアを見れるだけであれば、それほど意義はないと考えました。
なぜならスコアを一々閲覧しに行くのが手間になり、結果的に使われなくなるからです。

そこで気分の共有を受けた人はゲストページで「情報を受け取る」ボタンをタップするだけで、共有した側の気分が落ち込んだ時に、LINEBOTから通知を受けられるようにしました。
これにより気分が落ち込んだ人がいる時に、周囲の人が即座にそれに気づける仕組みとなりました。
### なぜ作ったのか
詳しくは[こちら](https://stock-stu.com/introduce_metnal/#toc1)に書かせていただいたのですが、コロナ禍でのメンタルヘルス事情の悪化に伴い、周囲の人が、ある人のメンタルの落ち込みを即座に発見することが大切になってきていると考えたからです。
# 使用技術等
## 概観
基本はFlaskで作っています。
それに加えて、LINE関連の機能として
- LINEログイン
- LINE messaging API

加えて
- 外観の工場のために**Bootstrap**
- webアプリのアップロード先として**Azureapp**
-  ユーザー情報の保管方法として**PostgreSQL**
-  アプリへのアクセスの容易さの担保のために**PWA**の導入

などが主な使用技術となっています。
## 苦戦した所
これらのアプリの作成方法を体系的に学ぶ方法があまりなかったところです。
WEB APIの利用方法やデータベースの使い方なども恥ずかしながら全く知らなかったので、一からやるなど、コツコツの努力が求められました…
# 宣伝
このように文系の大学生が頑張って作ったアプリですので、一度ご覧になってフィードバック等いただけたら励みになります。
よろしくお願いいたします！
[アプリはこちらから](https://metnal.stock-stu.com/)
本日の基礎練習問題②(22/3/23)

# 問題
西暦の年数および月を入力し、その月の日数を求めるプログラムを書きます。
その場合、閏年について考慮する必要があります。

閏年は以下の判断基準で決まります。
①その西暦が4で割り切れたら閏年である
②ただし、例外として100で割り切れる西暦の場合は閏年ではない
③ただし、その例外として400で割り切れる場合は閏年である

つまり、西暦2000年は閏年であり、西暦2100年は閏年ではありません。
これらに対応できるように、出力例と雛形をもとに実装しましょう。

出力例
1990年2月 =>"1990年2月は28日間あります"
2000年2月 =>"2000年2月は29日間あります"
2100年2月 =>"2100年2月は28日間あります"
2000年3月=>"2000年3月は31日間あります"
```雛形.
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  # ここに処理を書き加えてください
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
# 私の回答
```
時間制限のため回答できず‥
```

# 模範回答
```
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if month == 2
    if year % 4 == 0
      if year % 100 == 0 && year % 400 != 0
        days = 28
      else
        days = 29
      end
    else
      days = 28
    end
  else
    days = month_days[month - 1]
  end

  return days
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
# 模範解説
2月以外は各月の日数が決まっています。したがって、まずは以下のようにコードを記述しましょう。
```
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] # 各月の日数は配列で管理
  return month_days[month - 1]
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
そして、2月の時だけ条件式を用いて出力をします。
```
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if month == 2 # 2月のとき
    # 閏年のときはdaysに29を代入
    # それ以外はdaysに28を代入
  else
    days = month_days[month - 1]
  end

  return days
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```
閏年か判定します。閏年の条件は3つありましたが、以下のようにまとめることができます。

① その年が4で割り切れること
② ただし、年が100で割り切れて400で割り切れない場合は閏年ではない

したがって、以下のような条件分岐を設けることができます。
```
year = 指定の年

if year % 4 == 0  # 年が4で割り切れること
  if year % 100 == 0 && year % 400 != 0  # 年が100で割り切れて400で割り切れない場合
    # 閏年でない
  else
    # 閏年
  end
end
```
上記のロジックを反映しましょう。
```
def get_days(year, month)
  month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if month == 2
    if year % 4 == 0  # 年が4で割り切れること
      if year % 100 == 0 && year % 400 != 0  # 年が100で割り切れて400で割り切れない場合
        days = 28 # 閏年でない
      else
        days = 29 # 閏年
      end
    else
      days = 28   # 閏年でない
    end
  else
    days = month_days[month - 1]
  end

  return days
end

puts "年を入力してください："
year = gets.to_i
puts "月を入力してください："
month = gets.to_i

days = get_days(year, month)
puts "#{year}年#{month}月は#{days}日間あります"
```

# 感じたこと
閏年の場合の処理が少し複雑で回答することができなかった。
if文の入れ子？にまだ慣れていないと感じたのでif文の復習を行い理解を深めていきたい。
また西暦や年度系の問題はよく出てくると思うので処理方法を覚えていきたいと思った。

アドバイスやご指摘等ございましたらぜひお願いします！！！

以上
sudachipyを試してみた

| id | text |
|-:|:-|
|1|メロスは激怒した。|
|2|必ず、かの邪智暴虐の王を除かなければならぬと決意した。|
|3|メロスには政治がわからぬ。|
|4|メロスは、村の牧人である。|
|5|笛を吹き、羊と遊んで暮して来た。|

```python
tokenizer_obj = dictionary.Dictionary(dict="full").create()
mode = tokenizer.Tokenizer.SplitMode.C
doc = []
for row in range(len(df)):
    t = tokenizer_obj.tokenize(df["text"][row], mode)
    d = [m.normalized_form() for m in t if m.part_of_speech()[0] in ["名詞", "動詞"]]
    doc.append(d)
docs = pd.array([" ".join(doc[i]) for i in range(len(doc))])
print(docs)

#<StringArray>
#['メロス 激怒 為る',
#'邪知 暴虐 王 除く 成る 決意 為る',
#'メロス 政治 分かる',
#'メロス 村 牧人 有る',
#'笛 吹く 羊 遊ぶ 暮らす 来る']
#Length: 5, dtype: string
```
【パブリッシャー】作成したレポートは只者ではない

[Sharperlight](https://sharperlight.jp/)**パブリッシャー**を使用して作成したレポート(公開クエリ)は、只のレポートではありません。WEBアプリケーションにデータを供給するデータフィーダーとしても使用できます。

Sharperlightを社内ネット―ワークやクラウド上のアプリケーションサーバーにインストールし、必要なデータが保存されているデータソース（データベース）との接続を設定します。あとはSharperlightサービスを起動。
（ユーザーやセキュリティ等の設定はもちろん必要です。）

Sharperlightパブリッシャーを使用して、公開クエリを作成します。それがそのままSharperlightサービスを利用したデータのエンドポイントとなります。

アプリケーションの開発者はデータアクセス層を一から作成する必要はありません。Sharperlightがインストールされていれば欲しいデータをクエリビルダで設計し、公開クエリとしてパブリッシャーに保存すれば即使用できます。
![2022-03-23 Figure 01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/63daaf3d-4d5c-5b67-e42f-2a2e7cc265c7.png)
公開クエリの[リンク]タブでJSONを返すリンクをコピーします。
![2022-03-23 Figure 02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/2637c195-1f11-d58b-5592-1bdb47b360a8.png)
このようなURLが取得できます。
```
http://{YourServerName}/mdService1Rest/DataSource/?query=QiitaSample.SAPMultiCompany&dfmt=jsonarray&dcat=UseNames
```
早速ブラウザのアドレスバーに貼り付けます。JSONファイルがダウンロードされます。
このような形式のJSONデータが返されます。
![2022-03-23 Figure 03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e69205a8-a959-7660-949c-0f791abc5035.png)

WEBアプリケーションの開発者の皆さんのお役に立てれば幸いです。
Slackのチャンネル名からIDを取得する

## 概要
Slackアプリケーションでチャンネル名からチャンネルIDを取得したい。
しかし、[API一覧](https://api.slack.com/methods?query=channel)では、channel関係はすべてdeprecatedになっている。

![Web API methods](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62253/d5156c9f-3cb7-bf13-6007-be4d359305f6.png)

## 解決策
[conversations.list API](https://api.slack.com/methods/conversations.list)を使うらしい。 
`target_channel`のIDを`target_channel_id`に入れる例:

```py
from slack_bolt import App

app = App(token=bot_token)
channels = app.client.conversations_list()["channels"]

try:
    target_channel_id = next(ch["id"] for ch in channels if ch["name"] == target_channel)
except StopIteration:
    raise ValueError(f"{target_channel} is not found")
```


## 参考
- [How to find a channel id from channel name  using a slack api?](https://github.com/slackapi/bolt-js/issues/1248)
KotlinのDeferredについて

タイトルの通り、Deferredについて学習したことを記事に起こします。
単純に業務の中で出てきたけど、知らなかったのを理由に調べてみました。

Deferredとは「延期」という意味らしいですね。defer「延ばす」の過去形のようです。

どうやらコルーチンと共に使われるようです。でも使い方がよくわからない。
意味からなんとなく直訳して想像すると、処理を延ばしてくれる？待ってくれる？（await的な？）

調べてみると、どうやらasyncで処理しているものはdeferred型として返却されるようです。
それで後続の処理で.awaitしてやると、asyncの処理を待ってから処理してくれるようです。

結論：Deferredはasyncで処理した際に付与される型。asyncの処理を待ってから代入してくれる。
C＃を使用してWord画像の自動番号付け機能を実現する方法

けっこうサイズの大きいドキュメントを作成すると、多数の画像を使用する必要がある場合、通常、人々は画像に番号を付けます。現時点では、手動で画像に番号を付ける方法を使用すると、時間がかかり、手間がかかり、エラーが発生しやすくなります。実際、Wordのキャプション機能を使用すると、写真に自動的に番号を付けることが簡単にできます。この記事では、[Spire.Doc](https://www.e-iceblue.com/Download/download-word-for-net-now.html)コンポーネントとC＃プログラミングを使用して、Word画像の自動番号付け機能を実装する方法を紹介します。

次のコードを使用する前に、Visual StudioでC＃アプリケーションを作成し、Spire.Doc.dllをプロジェクトに参照する必要があります。

## 使用する名前空間：

```
using System.Drawing;
using Spire.Doc;
using Spire.Doc.Documents;
using Spire.Doc.Fields;
```
## コード一覧

```
//Documentオブジェクトをインスタンス化する
Document document = new Document();

//Sectionを追加する
Section s = document.AddSection();

//段落を追加し、その中に画像を追加する
Paragraph par1 = s.AddParagraph();
par1.Format.AfterSpacing = 10;
DocPicture pic1 = par1.AppendPicture(Image.FromFile(@"C:\Users\Administrator\Desktop\1.jpg"));
pic1.Height = 100;
pic1.Width = 120;

//画像にキャプションを追加する
CaptionNumberingFormat format = CaptionNumberingFormat.Number;
pic1.AddCaption("画像", format, CaptionPosition.AfterImage);

//別の段落を追加して同じことを行う
Paragraph par2 = s.AddParagraph();
DocPicture pic2 = par2.AppendPicture(Image.FromFile(@"C:\Users\Administrator\Desktop\2.jpg"));
pic2.Height = 100;
pic2.Width = 120;
pic2.AddCaption("画像", format, CaptionPosition.AfterImage);

//ドメインを更新してドキュメントを保存する
document.IsUpdateFields = true;
document.SaveToFile("AddCaption.docx", FileFormat.Docx);
```

キャプションを追加した結果：
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/0b25a845-3765-7df3-ae56-7ab1a06f9fd4.png)


今回のWord画像の自動番号付け機能を実現する方法は以上でした、最後まで読んでいただきありがとうございます。
Thunderbird設定（全メールが入る統合フォルダー、メールの最新日付順並べ）


前提条件
============
検証日: Mar. 2022
OS: Windows 10


出来たこと
============
Thunderbirdで複数のメールアドレスの送受信フォルダ等をまとめる「統合フォルダーの作成」


手順
============
Thunderbirdを起動して右上の三本線を押す。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603615/ef3fe203-c912-0cba-6d1c-50c52410f9d1.jpeg)

「表示」
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603615/5cde9f2e-8b7e-00a1-25b2-c24099a4b12e.jpeg)

「フォルダー」
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603615/711299bc-f59b-845c-523e-5b7df7e869c4.jpeg)

「統合フォルダー」
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603615/9cd227b0-dfe3-4d94-fc40-c8d1c0b566eb.jpeg)

「統合フォルダー」の受信トレイに各メールアドレスが紐づき1フォルダで全メールが取得できていれば完成。


一言
============
プラグインが多く使いやすいと思っているThundirbirdでしたが、

デフォルトでは全メールアカウント受信フォルダがなく、

各メールアドレスのフォルダをクリックしないとメールが見れない点が不便と感じていました。

「統合フォルダー」機能が見つかりすっきりしました。

☆おすすめ→　[Mozilla Thunderbird](https://www.thunderbird.net/ja/)




***
※商品・サービス名は各社の登録商標、商標であることをご了承くださいませ。
本日の基礎練習問題①(22/3/23)

**問題**
以下の要件を満たすxyz_thereメソッドを実装しましょう。
任意の文字列から連続する文字列"xyz"を探し、その直前にピリオド（.）がない場合はTrueを出力する
任意の文字列から連続する文字列"xyz"を探し、その直前にピリオド（.）がある場合はFalseを出力する
上記2つの条件に当てはまらない場合はFalseを出力する
```雛形.
def xyz_there(str)
  # 処理を記述
end

# 呼び出し例
xyz_there('abcxyz')
```
出力例
xyz_there('abcxyz') → True
xyz_there('abc.xyz') → False
xyz_there('xyz.abc') → True
xyz_there('azbycx') → False
xyz_there('a.zbycx') → False

# 私の回答
```ruby.
def xyz_there(str) 
  if str.include?(".xyz")
    puts "False"
  elsif str.include?("xyz")
    puts "True"
  else
    puts "False"
  end
end

# 呼び出し例
xyz_there('abcxyz')
```

# 解説
まずif文でinclude?メソッドを使い".xyz"がstrに含まれているかどうか判断します。
次に"xyz"を同じように判断します。
判断する順番に気をつけて処理を記述しました。

# 模範回答
```ruby.
def xyz_there(str) 
  if str.include?(".xyz")
    puts "False"
  elsif str.include?("xyz")
    puts "True"
  else
    puts "False"
  end
end

# 呼び出し例
xyz_there('abcxyz')
```
# 模範解説
include?を用いて、対象となる文字列が含まれているかどうかを、各条件式で判別しています。
ポイントとしては、str.include?(".xyz")の条件式をstr.include?("xyz")より前に設置することです。
例えば"abc.xyz"という文字列の場合は、str.include?("xyz")においてもtrueとなってしまうため、先に".xyz"を含むかどうかを判別する必要があります。

# 感じたこと
今回使用したinclude?メソッドは一度学習したことがあったので覚えていた。
文字列判断の順番で処理結果がおかしくなるので、if文設定の場合はしっかりと順番を考えて記述していきたい。

アドバイスやご指摘等ございましたらぜひお願いします！！

以上
Spring bootのプロジェクト作成はSpring Initializrを使おう

昔からある Spring Framework のプロジェクト作成ツールとしては Spring Tool Sweet (STS) が有名ですが、それとは別に Spring 公式ツールとして Spring Initializr があるのでそれを使うと便利です。

# Spring Initializrとは
Spring Initializr (スプリング イニシャライザ、で読み方合ってる？) は Spring boot プロジェクトのひな形を簡単に作ることが出来るサービスです。  
[Spring Initializr](https://start.spring.io/) からアクセスして利用を開始できます。

# Spring Initializrの使い方
[Spring Initializr](https://start.spring.io/) にアクセスすると以下のようなページが表示されます。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2387604/4da126ba-0fa2-fcd1-7e7a-ccb6b17aac65.png)
ページの左側に使用するビルドツール・開発に使用する言語・ Spring boot のバージョンなどプロジェクトの基本となる情報を入力し、ページの右側にはそのプロジェクトで使用するライブラリの選択が出来ます。  
最後に下の GENERATE ボタンを押してひな形の Zip ファイルを作成・ダウンロードして、ローカル環境で展開してビルドする、というのが使い方の基本です。  
簡単ですね。  

# 参考情報
Pleiades のサイトに Spring Initializr を使ったプロジェクトひな形作成から、そのひな形を使って実際に `Hello World!` を表示するまでの流れを説明していますので参考にどうぞ。  
[Spring Initializr クイックスタート - 公式サンプルコード](https://spring.pleiades.io/quickstart)

サイトからだとキーボードやマウスでの入力となり再現性が下がるから嫌だ、という場合は curl で CLI 操作も可能です。  
プロジェクト作成方法もコード管理したいという場合は便利かと。
[curlを通してSpring Initializrを利用する | DevelopersIO](https://dev.classmethod.jp/articles/spring-initializr-with-curl/)
CentOS Stream 8 でのキーボード配列の変更

kusanagi で初期設定をしていたときにキーボードが英字配列のキーボードを使っているので、それに変更したら、英字キーボードだと変な変換というか入力になったので、キーボード配列の変更方法を調べたので、備忘録までに。

# localectl コマンドを使う

キーボード配列の変更には「*localectl*」コマンドを使うそうです。一般的なLinux全般の様です。

## localectl コマンドとは？

「*localectl*」はロケール（locale）設定の確認と変更を行うコマンドです。覚えるときには「locale」（ロカール）＋「ctl」（コントロール）で覚えたら良いかなと。私は忘れっぽいので、すぐにググると思いますが。爆

　言語と地域の設定を「ロケール設定」（locale、ロカールとも表記）と呼びます。
※一般的な外来語では「ローカル」だと思いますが、一応「ロケール」的な発音が英語圏では近いかなと思います。

## 現在のロケール設定を確認する

「*localectl*」または「*localectl status*」で、現在のロケール設定を表示します。

```cmd:command line
[user@*** ]# localectl
    System Locale: LANG=ja_JP.UTF-8
      VC Keymap: us
     X11 Layout: us
      X11 Model: pc105+inet
    X11 Options: terminate:ctrl_alt_bksp
```

上記の現在の設定だと、サーバーは日本語対応しているけどキーボードが英字キーボード（PC105）になっているということです。

## キーボードの配列を変更する

今回はキーボード配列の変更をしたいので、コマンド「*set-keymap*」を説明します。他にもコマンドがありますので、ロケール設定を変更する場合はググって調べてみてください。

「*localectl set-keymap キーボード配列*」で変更できます。使用できる配列は「*localectl list-keymaps*」で確認できます。
※「*localectl list-keymaps*」を実行すると全部出てきて半端ない数表示されますので、日本語配列ならjpなどでフィルターをかけた方が良いです。フィルターのかけ方はjpの場合は「*localectl list-keymaps | grep jp*」となります。

今回は日本語キーボードjp106に変更したかったので以下の様にしました。

```cmd:command line
[user@*** ]# localectl set-keymap jp106
    System Locale: LANG=ja_JP.UTF-8
      VC Keymap: jp106
     X11 Layout: jp
      X11 Model: jp106
    X11 Options: terminate:ctrl_alt_bksp
```

これで変更完了です。
Python GitHubトレンドデイリーランキング!!【自動更新】

GitHub Trending をキャッチアップする習慣をつけて、強強エンジニアになろう。
この記事では、Python のGithubのトレンドデイリーランキングを25位まで紹介します。

# トレンドデイリーランキング

## 【1 位】 ManimCommunity/manim
https://github.com/ManimCommunity/manim

🌟 ***32,719*** star
A community-maintained Python framework for creating mathematical animations. 
    
数学アニメーションを作成するための、コミュニティによって管理されている Python フレームワーク。


## 【2 位】 mikumifa/biliTickerBuy
https://github.com/mikumifa/biliTickerBuy

🌟 ***2,101*** star
b站会员购购票辅助工具
    
Bステーション会員向けチケット購入支援ツール

## 【3 位】 cyclotruc/gitingest
https://github.com/cyclotruc/gitingest

🌟 ***9,874*** star
Replace 'hub' with 'ingest' in any github url to get a prompt-friendly extract of a codebase 
    
GitHub の URL で「hub」を「ingest」に置き換えると、コードベースのプロンプト対応の抜粋を取得できます。


## 【4 位】 donnemartin/awesome-aws
https://github.com/donnemartin/awesome-aws

🌟 ***13,384*** star
A curated list of awesome Amazon Web Services (AWS) libraries, open source repos, guides, blogs, and other resources. Featuring the Fiery Meter of AWSome.
    
厳選されたAmazon Web Services (AWS) ライブラリ、オープンソースリポジトリ、ガイド、ブログ、その他のリソースのリストです。AWSomeのFiery Meterも掲載しています。


## 【5 位】 karpathy/nanoGPT
https://github.com/karpathy/nanoGPT

🌟 ***42,086*** star
The simplest, fastest repository for training/finetuning medium-sized GPTs.
    
中規模サイズの GPT をトレーニング/微調整するための、最もシンプルで高速なリポジトリ。


## 【6 位】 yt-dlp/yt-dlp
https://github.com/yt-dlp/yt-dlp

🌟 ***116,052*** star
A feature-rich command-line audio/video downloader
    
機能豊富なコマンドラインオーディオ/ビデオダウンローダー

## 【7 位】 exo-explore/exo
https://github.com/exo-explore/exo

🌟 ***28,575*** star
Run your own AI cluster at home with everyday devices 📱💻 🖥️⌚
    
普段使っているデバイスを使って、自宅で自分だけの AI クラスターを実行しましょう 📱💻 🖥️⌚


## 【8 位】 AUTOMATIC1111/stable-diffusion-webui
https://github.com/AUTOMATIC1111/stable-diffusion-webui

🌟 ***153,769*** star
Stable Diffusion web UI
    
安定拡散ウェブUI

## 【9 位】 kijai/ComfyUI-WanVideoWrapper
https://github.com/kijai/ComfyUI-WanVideoWrapper

🌟 ***3,011*** star


## 【10 位】 Lightning-AI/litgpt
https://github.com/Lightning-AI/litgpt

🌟 ***12,326*** star
20+ high-performance LLMs with recipes to pretrain, finetune and deploy at scale.
    
事前トレーニング、微調整、大規模なデプロイのためのレシピを備えた 20 以上の高性能 LLM。


## 【11 位】 HKUDS/AutoAgent
https://github.com/HKUDS/AutoAgent

🌟 ***5,019*** star
"AutoAgent: Fully-Automated and Zero-Code LLM Agent Framework"
    
「AutoAgent：完全自動化、ゼロコードLLMエージェントフレームワーク」

## 【12 位】 Cinnamon/kotaemon
https://github.com/Cinnamon/kotaemon

🌟 ***22,618*** star
An open-source RAG-based tool for chatting with your documents.
    
ドキュメントとチャットするためのオープンソースの RAG ベースのツールです。


## 【13 位】 PromtEngineer/localGPT
https://github.com/PromtEngineer/localGPT

🌟 ***20,694*** star
Chat with your documents on your local device using GPT models. No data leaves your device and 100% private. 
    
GPTモデルを使用して、ローカルデバイス上のドキュメントとチャットできます。データはデバイス外に一切送信されず、100%プライベートです。

# 最後に
最後まで見ていただきありがとうございました。
LGTMをもらえるととても励みになりますので、ぜひお願いします :bow: