OmniAICreator/Qiita-1.07M huggingface dataset:
感情を記録するWebアプリケーションを作ってみた

#はじめに
初めてWebアプリケーションを作ってみました。グラフをクリックして現在の感情を記録して、後から振り返れるものです。また、1日ごとにどのような感情が多かったかを解析する機能もあります。
開発にはPythonとFlaskを使っています。

#開発の経緯
ふと今日は楽しかった1日だったのか、疲れた1日だったのか振り返ろうと思ったけど、大体その日の一番大きな出来事に引っ張られている気がする。そもそも1日の感情の動きがどのようなものだったか忘れてるなと思いました。
そこで、忘れてしまうならアプリケーションとして記録できるとよいと思い「Record Emotion」開発をしました。

#Record Emotionの概要
このアプリケーションは自分の感情を記録でき、後から振り返ることができるものです。
画面は下記の３画面から構成されています。

・感情を記録するトップ画面
・記録した感情を表示する表示画面
・日付ごとにポジティブかネガティブのどちらだったかの日付画面

それぞれのページから別の２ページにアクセスするリンクが下部に用意されています。


##トップ画面
トップ画面は、最初にアクセスすると表示される画面です。また、感情を記録する入力項目も下部にあります。
感情の記録は、タイトル、グラフへのプロット、コメントの３つを入力した後に「記録する」ボタンを押すことで記録されます。今回は単純な感情（快、不快）ではなく、複雑な感情を記録したかったため、Plutchikの感情の輪を参考にしました。
８つの基本感情から２つを選び組み合わせることで応用感情になるというものです。
詳しいことは[Plutchikの感情の輪](https://ja.wikipedia.org/wiki/%E6%84%9F%E6%83%85%E3%81%AE%E4%B8%80%E8%A6%A7)を参照してください。

入力をして送信すると、入力された情報はタイトル、グラフの軸と座標位置、コメントが送られます。送信が完了すると、自動的に記録した感情を表示する表示画面に遷移します。

![トップ画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2126675/ca9c7d47-ee52-1820-e9df-35774223578f.png)

##記録画面
記録した感情は、表示画面から確認できます。
上部にタイトルと記録した日時を表示し、その下に記録したグラフを描画し、下部にはその時のコメントも合わせて表示します。
技術的にはGoogleSpreadシートを直接読み込み、時系列順に表示しています。

![記録画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2126675/c0ef005a-edc9-0407-448c-025c466e6b65.png)

##日付画面
日付画面では、1日ごとにその日の感情からポジティブが何件、ネガティブが何件あったのかカウントをしてします。
ポジティブの件数が多い場合には、「今日もよい1日でした！！」と表示します。
ネガティブの件数が多い場合には、「こんな日もある！よく寝よう！」と表示します。
ポジティブとネガティブの件数が同じ場合には、「なんとも言えない日だね」と表示します。

![日付画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2126675/3f30e8c6-24c0-78be-431e-68d938a0fa47.png)

#おわりに
初めてWebアプリケーションを作ってみました。
グラフの描画ができないことや入力したデータをどこに保管しておこうか困ったことが多かったですが、
調べているうちにできるかもと試したものをそのまま使っています。
今後はWebブラウザから入力だけでなく、スマートフォンから入力やLINEからアクセスできないかなと考えています。
また、記録したデータもポジティブかネガティブの２択に分けたものであるため、もっとより詳細な解析（24通りの感情分析、時間ごとの感情の変化）について試したいです。
調査内容まとめ　HTMLタグ一覧　HTMLカテゴリー　リファクタリング

重要なものHTMLタグ一覧

// 文書情報・構造
    <!DOCTYPE><html><head>
    <meta><title><body>
    <h1~h6> 見出し
    <p> 一つの段落（パラグラフ）
// テキストの表現
  <font> フォントの種類・大きさ・色を指定する
  <basefont> テキストの基準サイズ・基準色・基準フォントを指定する
  <>

  ・入れ子のルールはコンテンツモデルで決まる

 HTMLのカテゴリー {
  以下のカテゴリーの中に必ず入っている
  ・フローコンテンツ
      p div table ul ol dl
  ・インタラクティブコンテンツ
      a button iframe img input select textarea
  ・フレージングコンテンツ
      a button cite code iframe img input label select span strong
  ・ヘッディングコンテンツ
      h1 h2 h3 h4 h5 h6 hgroup
  ・セクショコンテンツ
      article aside nav section
  ・メタデータコンテンツ
      meta title style link script
  ・エンべディッドコンテンツ
      iframe img video

      コンテンツモデル {
        ・その要素にはどのカテゴリーのコンテンツをいれていいかを決めているルール
        ・タグの入れ子のmルールはこのコンテンツモデルによって決まっている。
      }
    まとめ {
      ・html5の要素は全て6種のカテゴリーのいずれかに属している
      ・要素ごとにどのカテゴリーの要素を含んでいいか決まっている
      ・それらのルールをコンテンツモデルと呼ぶ
    }

  divタグ： 構造・レイアウト ... 全ての要素を入れ子にできる
  spanタグ： 構造・レイアウト ... フレージングコンテンツを子要素にできる。
  h1~h6タグ：見出し ...フレージングコンテンツを子要素にできる
  p/preタグ：段落 ... フレージングコンテンツを子要素にできる
  strong/emタグ：強調 ... フレージングコンテンツを子要素にできる
  ul/olタグ：リスト定義 ... li template scriptを入れられる
  liタグ：リスト定義（子要素） ... フローコンテンツを入れ子タグにできる
  tableタグ：表の定義 ... tbody thead tfoot caption colgroup
  trタグ：行 ... th td
  th tdタグ：見出しセル データセル th tdはフローコンテンツを含めることができる
 }

 ターゲットブラウザで大きな崩れがない
  リンク漏れや原稿違いなどの、ヒューマンエラーの頻度
  バリデーター・チェックでエラーがでない

  １HTML上の記述順と、情報の順番をきちんと合わせる
  ２タグは本来の使い方をする
  ３bodyラグに固有のclassを設定しておく。
  ４Javascriptのライブラリは乱用しない
  ５CSSの値の指定は極力短縮する
  ６ショートハンドを使用し短いプロパティで定義する
  ７タイプセレクタはできるだけ省略
  ８プロパティは常に同じ順序で記述
  ９インデント、開業などの一定の、ルールで行う。
One message ユーザー情報関係仕様

# API
### ユーザー情報登録API
1. [ユーザー情報登録画面](#ユーザー情報登録画面)からユーザーネーム,email,パスワードを受け取る
2. 受け取ったデータをUserモデルに変換し、ユーザー登録サービスクラスに渡す
3. ユーザー登録サービスクラスは、メールアドレスが既に登録されてないか確認し、登録されていたら、エラーを返し、コントローラーは、そのエラーメッセージを返す
4. メールアドレスが未登録であれば、パスワードをハッシュ化し、DBに登録し、完了したら、コントローラーは201ステータスを返す

# フロント
### ユーザー情報登録画面
1. 「ユーザーネーム」,「メールアドレス」,「パスワード」,「パスワードの確認」を入力
2. それぞれのバリエーションを入力
    - **ユーザーネーム** 32文字まで
    - **メールアドレス** 255文字まで,メールアドレスを満たす文字列であること
    - **パスワード** 8文字以上まで
    - **パスワードの確認** パスワードと同じ文字列であるか？
3. ユーザー情報登録APIにリクエストを送る
4. メールアドレスが登録済みであれば、その趣旨を伝えるメッセージをバリエーションエラーとして表示させる
5. 正常に登録されたら、その入力したユーザー情報で、ログインAPIにリクエストして、JWTトークンを受け取り、状態管理化に置く
6. ホーム画面に遷移させる
【omniauth-google-oauth2+devise】Rspecのリクエストテスト

deviseのみ使用時のリクエストテストでは```sign_in user```でログインできていたが、
omniauth-google-oauth2＋devise使用時のテストの書き方で少し苦戦したので書き残す。

##環境
Ruby 3.0.2
Rails 6.1.4.1


##やり方
- sign_inが使えるようにdeviseでのテストの設定をする
- omniauth-google-oauth2が使用できるように設定


```spec/rails_helper.rb
RSpec.configure do |config|
  config.include Devise::Test::IntegrationHelpers, type: :request
end

OmniAuth.configure do |c|
  c.test_mode = true
  c.mock_auth[:google_oauth2] = OmniAuth::AuthHash.new({
    "provider" => "google_oauth2",
    "uid" => "100000000000000000000",
    "info" => {
      "name" => "test employee",
      "email" => "tester1@example.com",
      "first_name" => "test",
      "last_name" => "employee"
    }
  })
end
```

```spec/requests/XXXXX_spec.rb
RSpec.describe "/XXXXX", type: :request do
  describe 'GET /XXXXX' do
  subject { get '/XXXXX', params: { provider: "google_oauth2" } }

  before do
    Rails.application.env_config["devise.mapping"] = Devise.mappings[:user]
    Rails.application.env_config["omniauth.auth"] = OmniAuth.config.mock_auth[:google_oauth2]
    sign_in user
    subject
  end
  it 'レスポンスが200を返すこと' do
    expect(response).to have_http_status(200)
  end
end
```

##参考

https://github.com/zquestz/omniauth-google-oauth2

https://github.com/omniauth/omniauth/wiki/Integration-Testing

https://qiita.com/ngron/items/88f04a2d864f9f33b389
[簡単爆速]Pythonだけでデプロイ。Streamlit1.0の使い方を紹介


# はじめに
データ分析の結果や研究成果を公開するとき、多くの方に使ってもらえるように、何かしらツール化したほうがいい場面があります。
Pythonですと、DjangoやFlaskなどを活用することが多いとは思いますが、Streamlitとは、Pythonのみでフロントエンドアプリケーションを作成できるフレームワークです。

何度目かのStreamlitですが、ついに1.0でGithubを用いてweb上へのデプロイまで簡単にできるようになりました。


# Streamlit Cloudの利用方法
2021年10月現在、streamlitcloudを利用するにはinviteしてもらう必要があります。

https://streamlit.io/cloud

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/b57d2464-cace-8218-7ee9-1335fdeb436c.png)

Freeのところの（Get an invite）から[このページ](https://forms.streamlit.io/community-sign-up)にいき招待メールを受け取りましょう。
数日でメールが返ってきます。loginできたら以下のような画面になるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/c043f4fc-d894-d6f4-3152-3ff3f60d2627.png)

GithubにpushしたRepository情報を入力します。

環境ファイルは必要なので`requirement.txt`や`pyproject.toml`などをrepositoryに追加しておきましょう。ローカルでもpoetryなどの、ディレクトリごとに仮想環境を構築してくれるパッケージを使用している場合は自然にこういったファイルができているでしょう

あまりデプロイに慣れていない人向けに`requirement.txt`に軽く説明すると、`pip install`する必要があるパッケージを記述しているものになります。ローカルで作業した際にインストールしたパッケージがありますよね。それらを本番環境に反映させる必要があります。

下記は公式ドキュメントですが、使っているパッケージツールによってファイルを作ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/11995c3f-49d4-b943-216b-d3167989700d.png)

## デプロイ
`Main file Path` は`streamlit run`するメインファイルを記述しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/8b108cac-71d5-d270-2fa8-d69a7f412c76.png)

右側にコンソールもあり、非常に使いやすいUIになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571279/9b7743e4-5855-2865-2c88-4cc6003cae7e.png)


私も昔作った東京のコロナ感染者とワクチン接種者の推移の可視化アプリを[こちら](https://share.streamlit.io/natsuki0928/covid19app/main/app.py)に上げてみました。

# 最後に
Streamlitの基礎的な使い方については[過去の記事](https://qiita.com/Nate0928/items/566c2073358b4df3ceec)をご覧ください。

1年前は非常にシンプルなアプリしか作れなかったstreamlitですが、多くのウィジェットが追加され、ついにデプロイまで簡単にできるようになりました。今後もアップデートが楽しみです。
【Rails】 LINE messaging APIを使用してLINEbot通知してみた ブロードキャストメッセージ　プッシュメッセージ

***LINE messaging API***を使用してメッセージを送信する
私は、Twitter APIで取得した内容をLINEで通知したかった!!

# 目標
友達登録している方全員に通知を送信したい

# 結論
・LINE messaging API を使用して通知を送る
・**broadcast通知**を使用する

# LINE messaging API
>Messaging APIを使って、ユーザー個人に合わせた体験をLINE上で提供するボットを作成できます。

>作成したボットは、LINEプラットフォームのチャネルに紐づけます。チャネルを作成すると生成されるLINE公式アカウントをボットモードで運用すると、LINE公式アカウントがボットとして動作します。

https://developers.line.biz/ja/docs/messaging-api/overview/

#使用してみる
メッセージの種類は様々ある
>プッシュメッセージ（1対1）
マルチキャストメッセージ（1対多：ユーザーID指定）
ナローキャストメッセージ（1対多：絞り込み配信）
ブロードキャストメッセージ（1対多：すべての友だち）

https://developers.line.biz/ja/docs/messaging-api/sending-messages/

## ブロードキャストメッセージ
今回はこちらを使用していく。

### 1.LINE for Business を登録する
https://www.linebiz.com/jp/entry/

登録手順とトークン取得はこちらを参考にさせていただきました。

https://www.chuken-engineer.com/entry/2020/12/15/131236

### 2.LINE 通知を送信する
1.で取得した`channel secret`と`channel access token`をセットし、**broadcast**で送信する

```ruby:article.rb
client = Line::Bot::Client.new { |config|
      config.channel_secret = "<channel secret>"
      config.channel_token = "<channel access token>"
}
message = {
  type: 'text',
  text: 'hello'
}
response = client.broadcast(message)
p response
```

### 3.LINEbotから通知が届く
![S__33267716.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2133440/35574fba-6528-c1d1-f2b0-2e13183aebda.jpeg)

## プッシュメッセージ
こちらを最初使用していたが、1対1になってしまうので使用しない。
コードの書き方としては、**ブロードキャストメッセージ**と少しだけ違うところがある。

```ruby:article.rb
client = Line::Bot::Client.new { |config|
      config.channel_secret = "<channel secret>"
      config.channel_token = "<channel access token>"
}
message = {
  type: 'text',
  text: 'hello'
}
# ここに違いがある。 "<to>"に送信先のIDを指定しなければならない。
response = client.push_message("<to>", message)
p response
```
https://developers.line.biz/ja/reference/messaging-api/#send-reply-message
【Rspec】共通処理concernsのテストはStructを使うといい

##環境
Ruby 3.0.2
Rails 6.1.4.1

##Structについて

Rspecで共通処理concernsのメソッドテストを実行する際はStructを使うとテストできる

下記のようなconcernsがあったとする

```concerns/name_arrangeable.rb
module NameArrangeable
  def full_name
    "#{first_name} #{last_name}"
  end
end
```

1.　Structを使ってテスト用のクラスをつくる。moduleをincludeしておく
2.　作ったクラスをnewする
→name_arrangeable.full_nameでメソッドを呼び出して使えるようになる

```spec/models/name_arrangeable_spec.rb
let!(:module_test_class) { Struct.new(:name_arrangeable) { include NameArrangeable } }
let!(:name_arrangeable) { module_test_class.new }

describe '#full_name' do
  name_arrangeable.full_name
  ...
end
```

##参考

https://qiita.com/jnchito/items/8bdf1172e472b3e769b1

https://yasagori-programing.hatenablog.jp/entry/2020/03/20/153714
ABC101 C - Minimization から学んだ

https://atcoder.jp/contests/abc101/tasks/arc099_a

![abc101_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/42508317-3813-1ea1-bda4-fc27dc8875a0.png)
![abc101_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/cc4e2bfb-71af-8780-5d9f-d081a0aaa315.png)
![abc101_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/3209a7c9-5801-567a-3930-ea62a36f59b5.png)
![abc101_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/fa865e81-07f2-6d76-e4cc-d03c6986a69e.png)

WA がどうしても取れない。
解答を見た。

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

なるほど、なるほど。ってわかってるのかな？おれ。
ボーっとした後に思い出しながら書いてみた。
なんとか通った。

```Minimization.py
N,K = map(int,input().split())
A = list(map(int,input().split()))
cnt = 0

if K >= N:
    print(1)
else:
    for i in range(10**6):
        if K+(K-1)*i >= N:
            print(i+1)
            break
```

***

あれから、再チャレンジしたが WA.
再度回答を確認。
今回はちゃんと理解しながら聞き取れた(つもり)

```abc101c.py
N,K = map(int,input().split())
A = list(map(int,input().split()))

num = N-K

if num%(K-1) == 0:
    print(1+num//(K-1))
else:
    print(2+num//(K-1))
```
テスト48

```vb

Sub SellNum_Check()

'値がセル番地のチェック
Dim i As Long

i = 2

With ThisWorkbook.Sheets("セル番地")

    For i = 2 To 10
'----------------------------------------------------------
'こっちの処理だと例えば「1d」という値でも「TRUE」にしてしまう(˘ω˘)ｽﾔｧ…
        On Error Resume Next
        
        If Evaluate("ISREF(" & .Cells(i, 2).Value & ")") = True Then
        
            .Cells(i, 3).Value = True
         
        Else
            
            .Cells(i, 3).Value = False
         
        End If
'----------------------------------------------------------
'こっちの処理だと例えば「1d」は空欄、「AA」や「eee」だと「FALSE」になる
'そのため、セル上でISREF関数を使った方が、セル番地のチェックが正確にできる(*ﾟωﾟ)
        .Cells(i, 4).Formula = "=ISREF(" & .Cells(i, 2).Value & ")"
'----------------------------------------------------------
        On Error GoTo 0
        
    Next i

End With


End Sub

'=========================================================

Sub Mergedcell_Filter_Copy()
'-------------------------------------
'結合セルがたくさんあり、なおかつフィルターがかかった表がある
'この状態で範囲選択→可視セル選択→コピー貼り付けをしたかったがどうしてもできなかったため、
'力技で図としてコピーして貼り付けのコード
'_(:3 」∠)_瀕死・・・
'-------------------------------------
Dim Pic As Shape

With ThisWorkbook.Sheets("結合セル1")

    .Range("C2:P19").CopyPicture Appearance:=xlScreen, Format:=xlPicture
    
End With

With ThisWorkbook.Sheets("図の貼り付け")

    .Cells.Clear
    
    For Each Pic In .Shapes
    
        Pic.Delete
        
    Next
    
    .Range("B10").Select
    .Paste

    .Activate
    ActiveWindow.DisplayGridlines = False

End With

End Sub

'====================================================================

Sub NWTest()

Dim NW As New IWshRuntimeLibrary.WshNetwork
Dim objFS As Object
Dim vD As Variant
Dim flg As Boolean

flg = False

Set objFS = CreateObject("Scripting.FilesystemObject").Drives

For Each vD In objFS

    If Left(vD, 1) = "C" Then
    
        flg = True
        
    End If

Next

With NW

    If flg = False Then

        'ネットワークドライブ接続
        Call NW.MapNetworkDrive("C:", _
                                "\\Users\Public", _
                                False, _
                                NW.UserName, _
                                NW.ComputerName)
    End If

End With

End Sub
ServerlessFrameworkでHot Reload対応する

ServerlessFrameWorkのバグで、ホットリロードがデフォルト設定されていない。
対応方法を記載する。

```typescript:serverless.ts
import type { AWS } from '@serverless/typescript';

import hello from '@functions/hello';

const serverlessConfiguration: AWS = {
  service: 'mock',
  frameworkVersion: '2',
  custom: 
  {
    webpack: {
      webpackConfig: './webpack.config.js',
      includeModules: true,
    },
    useChildProcesses: true // ホットリロードの設定をする。←追加する。
  },
  plugins: ['serverless-webpack', 'serverless-offline'],
  provider: {
    name: 'aws',
    runtime: 'nodejs14.x',
    apiGateway: {
      minimumCompressionSize: 1024,
      shouldStartNameWithService: true,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
    },
    lambdaHashingVersion: '20201221',
  },
  // import the function via paths
  functions: { hello },
};

module.exports = serverlessConfiguration;
```

■参考文献
https://github.com/dherault/serverless-offline/issues/931
SonarQubeを日本語化する

Dockerコンテナで立ち上げたSonarQubeを日本語化していきたいと思います。
Dockerじゃなくても手順は同じハズ・・・。

参考にした記事

- https://mebee.info/2020/04/14/post-9166/

# 環境

- Windows10 Pro<br>
Windows10 へDockerインストールについては [コチラ](https://docs.docker.jp/docker-for-windows/install.html) を参照
- SonarQube<br>
Dockerコンテナ作成については [コチラ](https://qiita.com/beeeegle/items/b662fc97cb697a49f542)  の記事を参照

# SonarQube日本語化

1. SonarQubeへアクセス
ブラウザを開いて、SonarQubeへアクセスします。
`http://{IP or ホスト名}/`
特に設定していなければ`http://localhost:9000/`でアクセスできると思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/776e3d55-ed31-398d-4ed7-37cdcf5271b6.png" width=70%>

1. ログイン
ID：`admin`
Password：`admin`
でログイン可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/51ed6edc-fc55-3ac0-fcd7-872470ad6b6d.png" width=70%>

1. Marketplaceへ遷移
画面上部にある『Administration』＞『Marketplace』をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/4939c4ab-a985-3133-c4ec-32e24254db77.png" width=70%>

1. 日本語化Pulginをインストール
『Plugins』のちょい下にあるテキストボックスに『japan』を入力する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/03b81412-09d0-8910-690a-4a04bbe9fc02.png" width=70%>

1. 検索ができたら、『Install』をクリックします。
インストールが終わると画面上部に『Restart Server』が表示されるので、サーバを再起動します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/a87dfb2d-89ca-0142-6513-f2f2cb898de9.png" width=70%>

1. 日本語化されているか確認
画面を更新すると、ログイン画面に戻されると思うので、再びログインします。
この時点で一応日本語化されているのが確認できます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/8f4fbedd-64b1-e2b0-88e7-846723d02109.png" width=70%>

1. ログインします。
完全ではないものの一部日本語化されています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1588937/a69daf19-8d81-de2d-a316-39c5ffdc1f0a.png" width=70%>



# あとがき
パーッと画面遷移したところだと、リセットとか簡単な単語は翻訳されている印象でした。
手順自体はそんな難しくないと思うので、時間があれば適用する。くらいがいいかもしれませんね。
あとは、日本語化して誤解を生むような文章になってないことを祈るばかりですｗ

# 関連記事
- [SonarQubeをDockerで立ち上げた時の話](https://qiita.com/beeeegle/items/b662fc97cb697a49f542)
- [SonarQube＋WindowsでPHPソースをスキャンする](https://qiita.com/beeeegle/items/ee38f03cdcf99a028692)
enumの値によって遷移先を変えたい

#はじめに
現在プログラミング学習を始めて３ヶ月目の初学者です。
学んだことをqiitaに投稿という形でアウトプットするため、また備忘録として記事を作成しました。

##考えた方法
if文で条件分岐

##if文
パッと思いつくほどif文を使いこなせていないので、とにかく調べる
https://kurose.me/rails-enum-login/
こちらの記事を参考にして
作ったif文がこちら

def create
    @task = Task.new(task_params)

    respond_to do |format|
      if @task.save
        format.html {
          if @task.category(0) == "時間が決まったタスク"
            redirect_to time_path
          elsif @task.category(1) == "よく使うタスク"
            redirect_to every_path
          elsif @task.category(2) == "たまたま行ったタスク"
            redirect_to by_chance_path
          elsif @task.category(3) == "ToDo"
            redirect_to todo_path
          else
            render :root
          end
        }
        format.json { render :time, status: :created, location: @task }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end

※controllerはscaffoldコマンドで作成

わかっていたがエラー
ArgumentError in TasksController#create
wrong number of arguments (given 1, expected 0)
引数の値が0を期待しているが、1つ送られてきてる　

記事をよく確認したら引数入れてなかった！
なのでcategoryの引数を消したら無事遷移できました！



##最後に
qiitaへの投稿に慣れていないので、分かりづらい上に情報が少ないですが、これから欠かさず投稿していこうと思います。
How to use object-position with next/image

Next.js offers many benefits compared to create-react-app, which is why the framework has been growing in popularity for the past few years. 

One of these benefits is next/image. The magic of next/image is that it automatically optimizes images for smaller viewports.  However, if you're like me, you might start to get frustrated with next/image when you start trying to style it with CSS. One challenge I faced was trying to center the image using the `object-position` CSS property. In the following example, I'll be using typescript, but if you prefer to use javascript, just change index.tsx to index.js/index.jsx and you'll be good to go. 


```css:global.css
.next-image{
   object-position: center
} 
```

The code above will not work with next/image. Instead, we have to pass props to Next's Image component. These props will then be passed to different CSS properties. 

---
###Image Size
Next's Image component offers us `width` and a `height` props. However, we won't be using them because we want our width to change according to the screen size. To do that we are going to create a container div and make sure anything outside that div is hidden. Don't forget to set the height and width of the container. Feel free to use media queries if you like. 

```react:index.tsx
import Image from 'next/image';
import someImage from "./public/someImage.png"

const Home = () => {
  return (
    <div className="next-image-container">
      <Image src={officeImg} />
    </div>
  );
};
export default Home;
```

```css:global.css
.next-image-container {
  height: 400px;
  width: 100vw;
  overflow: hidden;
}
```

---
###Setting the Object-Position Property
Next/image comes with `objectFit` and `objectPosition` props. These props get passed to the CSS `object-fit` and `object-position ` properties.  In order to use `objectFit` and `objectPosition`, we also need to set out `layout` prop to `fill` (this will make the image grow to fit our container). Finally, we'll add `position: relative` to our `next-image-container` class. Don't forget this step or your image might just take up your whole page. 

Take a look at the final code below.

```react:index.tsx
import Image from 'next/image';
import someImage from "./public/someImage.png"

const Home = () => {
  return (
    <div className="next-image-container">
      <Image
        src={officeImg}
        layout="fill"
        objectFit="cover"
        objectPosition="center bottom"
      />
    </div>
  );
};
export default Home;
```

```css:global.css
.next-image-container {
  height: 400px;
  width: 100vw;
  overflow: hidden;
  position: relative;
}
```
---
###Troubleshooting

**Problem:** Image is taking up the whole screen.

**Solution**: Make sure the parent div is set to `position: relative`. In situations where the parent div cannot be relative, create a new wrapper div around your image with a single CSS property: `position: relative`.

---

If you'd like to learn more about next/image, you can check out the documentation [here](https://nextjs.org/docs/api-reference/next/image). 

Happy coding!
ラビットチャレンジ　応用数学　レポート

#1.線形代数

**行列**：数値を行と列に配置したもの 

```math
A= 
\begin{pmatrix}
1 & 2 \\
3 & 4
\end{pmatrix}
```

A(行,列) = 数値とすれば

```math 
A(1,2) = 2 \\
A(2,1) = 3
```
<br>

###特徴を持つ行列
**単位行列**：対角成分がすべて1でそのほかの成分が0の行列

```math 
I =
\left(
\begin{array}{ccccc}
1 & 0 &\cdots & \cdots & 0\\
0 & \ddots & & & \vdots \\
\vdots & & 1 & & \vdots \\
\vdots & & & \ddots & 0 \\
0 & \cdots & \cdots & 0 & 1\\
\end{array}
\right)
```
<br>

**逆行列**：元の行列に掛けると単位行列に戻る行列 （n×nの正方行列に存在）


```math
A^{-1}A = I\\
AA^{-1} = I
```

逆行列の求め方-**掃き出し法**
<br>

```math
(A|I) → (I|A^{-1})
```
となるように様に計算を行う。

行列の計算は以下の**行基本変形**に従う。
1. ある行を定数倍する
2. ある行と他の行を入れ替える
3. ある行に他の行の定数倍を加える



###行列を利用して連立方程式を解く

```math
\begin{align}
x+2y &= 5 \\
3x+4y &= 11
\end{align}
```
という連立方程式があるとき、行列に直すと

```math
\begin{pmatrix}
1 & 2 \\
3 & 4
\end{pmatrix}

\begin{pmatrix}
x \\
y
\end{pmatrix}
=
\begin{pmatrix}
5\\
11
\end{pmatrix}
```
と記述できる。

```math
A = 
\begin{pmatrix}
1 & 2 \\
3 & 4
\end{pmatrix}
```

として、両辺に左側から逆行列を掛けると、

```math
A^{-1}
\begin{pmatrix}
1 & 2 \\
3 & 4
\end{pmatrix}

\begin{pmatrix}
x \\
y
\end{pmatrix}
=
A^{-1}
\begin{pmatrix}
5\\
11
\end{pmatrix}
```

と書けて、計算すると

```math
\begin{pmatrix}
1 & 0 \\
0 & 1
\end{pmatrix}

\begin{pmatrix}
x \\
y
\end{pmatrix}
=
\begin{pmatrix}
1\\
2
\end{pmatrix}
```

```math 
x = 1, y = 2
```
が得られる。

<br>


#2.確率
**確率**：物事の「起こりやすさ」を数値で表す。客観確率と主観（ベイズ）確率に分かれる。
<br>
定義

```math 
P(A) = \frac{n(A)}{n(U)} = \frac{事象Aが起こる数}{すべての事象の数},\quad
0 \leqq P(A) \leqq 1
```

###条件付き確率

定義：ある事象Bが与えられた下で、Aとなる確率

```math 
P(A|B) = \frac{P(A \cap B)}{P(B)} = \frac{n(A \cap B)}{n(B)}
```

###ベイズの定理
P(B|A) の逆確率である P(A|B) は、「P(B|A) と P(A) の積を P(B) で割る」と求められる。

```math 
P(A|B) = \frac{P(B|A)P(A)}{P(B)} 
```

P(A) を事前確率、P(B|A) を尤度、P(A|B) を事後確率という

###独立な事象の同時確率
定義：お互いの発生には因果関係のない事象Aと事象Bが同時に発生する確率

```math 
P(A \cap B) = P(A)P(B|A) = P(A)P(B)
```

#3.統計
**記述統計**：集団の性質を要約し記述する
**推測統計**：集団から一部を取り出し元の集団（母集団）の性質を推測する
<br>

###期待値
定義：1回の試行で得られる値の平均値
離散型の場合

```math 
E(f) = \sum_{k=1}^{n} P(X = x_k )f(X = x_k)\\
P(X):確率,f(X):確率変数
```

連続型の場合

```math 
E(f) = \int P(X = x )f(X = x)dx 
```

###分散
データの散らばり具合を表す

```math 
Var(f) = \frac{1}{n}\sum_{i=1}^{n}(x_i - μ)^2\\
n:データの個数,x_i:データの値,μ:平均
```

###共分散
2つのデータの傾向の違い

```math
COV(f,g) > 0　なら似た傾向\\
COV(f,g) = 0　なら無関係\\
COV(f,g) < 0　なら逆の傾向
```

###標準偏差
平均値からのばらつき

```math 
σ = \sqrt{Var(f)}
```

#4.推定
母集団を特徴づける母数を統計学的に推測すること
→標本を使って母集団の特徴を推測する

**点推定**：平均値等を1つの値に推定すること
**区間推定**：平均値等が存在する範囲を推定すること


###標本平均
母集団から取り出した標本の平均値

サンプル数が大きくなれば母集団の値に近づく（一致性）
サンプル数がいくつでも、その期待値は母集団の値と同様（不偏性）

```math 
E(\tilde{\theta} = \theta)
```

###標本分散
母集団の中から一部を抽出して分散を求めたもの
→一致性〇、不偏性×

###不偏分散
分散の式にn/n-1をかけたもの
→一致性〇、不偏性〇

```math 
s^2 = \frac{n}{n-1}×\frac{1}{n}\sum_{i=1}^{n}(x_i - \bar{x})^2= \frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2\\
n:データの個数,x_i:データの値,\bar{x}:標本平均
```

#5.情報理論
情報に含まれる「情報量」を数学的に定義する

情報量とは？
ある事象が起きたと時に、どのくらい珍しい事象かという尺度

###自己情報量
珍しい=情報量が多いと考えて

```math 
自己情報量 = -log\Bigl(P(x)\Bigr)\\
P(x)は確率分布
```
と定義する。

###平均情報量（シャノンエントロピー）
複数の事象が起こった場合の情報量

```math 
平均情報量 = -\sum P(x)log\Bigl(P(x)\Bigr)\\
```
と定義する。
Laravelで突然Localhostに接続できないときの対処

今まで問題なく接続できていたのに

ある日突然

localhostに接続出来なくなりました。

:point_down_tone2:100回くらい見たこの顔！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2139028/8fbc959c-85ff-76b2-262d-95e22b5b6cf7.png" width="450">

今後同じ問題が起こったときのためにこちらに記載しておきます。

## :robot:　環境
:computer:　Windows 10
:ballot_box_with_check:　PHP    ：8.0.8
:ballot_box_with_check:　Laravel：8.55.0
:ballot_box_with_check:　docker + Laravel sail

## 試したこと
- 他のアプリで確認→問題なく接続
- .envファイルのAPP_PORT=でPORT番号変更→接続不可
- セキュリティーソフトのファイヤーウォール設定解除→接続不可
- git commitのバージョンを動作していた時間帯に戻す→接続不可

上記色々試しましたが上手く行かず...

## 解決
### **Composerのキャッシュを消して再インストール**

参考サイト
https://stackoverflow.com/questions/65486205/uwsgi-entered-fatal-state-too-many-start-retries-too-quickly-in-docker-contai

:one:　キャッシュのクリア
``sail composer clearcache``

:two:　再インストール
``sail composer install``

:three: dockerの起動
``sail up -d``

これで問題なく接続しました:blush:
GPUクラスターを作ってみた Part.1

# はじめに

研究室内のPCサーバ内にJupyterHub環境を構築し，メンバーが空いているGPUマシンのリソースを自由に用いることができるようにすることで，作業効率が向上すると考え，今回はGPUマシンを贅沢に4台も使って，作ってみることにした．

しかし，せっかくGPUマシンを4台も用意したところで，複数人で作業する時に上手くリソースを配分できなければ，使われていない領域は無駄になってしまう．
そこで，GPUのリソースを最大限，有効活用するために，複数のGPUをクラスタ化する方法について，色々検証していこうと思う．

# 使用機材について

## PCスペック

**CPU**:Core i9-11900K プロセッサー (3.50-5.30GHz/8コア/16スレッド/16MBキャッシュ/TDP 125W)
**GPU**:NVIDIA GeForce RTX 3070 8GB GDDR6
**メモリ**：DDR4-3200 32GB×4
**ディスク**：2TB SSD / NVMe M.2 [PCIe 4.0×4] + 4T HDD
**水冷**

**計4台**

![PC画像](https://drive.google.com/uc?id=1JSDAyXWU0mqN4tTFHuRHZck1pExvh-0z)

## LANスイッチングハブ

TP-Link TL-SX1008 (8ポート 10G)

![ハブ画像1](https://drive.google.com/uc?id=1MP4KgkDdXE7X138Oi_nAfBfScv3FbjD7)

---

![ハブ画像2](https://drive.google.com/uc?id=1DJ46iow3oIFlNdWh6x6NkcOWrf8aDIEn)  

# Ubuntuインストール

## 1.UbuntuのライブUSBを作成

下記のサイトを参考にして，UbuntuのOSイメージが入ったUSBメモリを作成

[MacでUbuntuのライブUSBを作ってインストールするまでの流れ](https://dezanari.com/mac-ubuntu-usb-install/)

## 2.ライブUSBを用いて，PCにUbuntuをインストール

- USBメモリを挿し，PCを起動する．（ここで筆者たちはHDMIケーブルの不具合で，モニターが映らず１時間ぐらい苦戦しました笑）  
![起動後画面](https://drive.google.com/uc?id=1ZkuOCCESWYaVNgDFH-h2MNkXEVwIrS_K)  

- 起動して待機していると，下記のような画面になる.  
![インストール画面](https://drive.google.com/uc?id=1iLjZHNEAi7SjvGVuwDBBh8JcYDXgl-31)
- 画面の指示に従って，OSのインストールを行う．
![インストール実行画面](https://drive.google.com/uc?id=1EEJX7dR40JWdtx6xQVDuEmryOSu1LYju)


# ssh接続

ubuntuを導入した４台のPCのうち３台をサーバ，１台をクライアントとして１台から残りの３台にアクセスできるようにする．  
これは後にGPU-Clusterとしてジョブを割り当てる際に必要になる設定でもあり，これから先インストールするモジュールなどを４台同時にインストールできるようにして仕事効率を上げるためでもある．  
手順を以下に示す
  
## 1. クライアントとサーバの設定

これは以下のサイトの手順通りに行なった．  
[公開鍵認証でのssh接続](https://www.virment.com/how-to-connect-to-server-by-ssh-with-publickey/)<br>
この通りに作業を行うことで簡単にssh接続することができた.

## 2. サーバでのアクセス可能クライアントの制限

サーバとするPCでAllowUserの設定を行なった．これは，クライアントPC以外からのssh接続を無効にするためである．<br>
[AllowUserまたはGroupの設定方法](https://www.kkaneko.jp/tools/server/pubkey.html)

後に，研究室のPCからGPU-Clusterにアクセスできるよう，クライアントとしているPCにも同様の設定を行う．<br>

### イメージ

![イメージ画像](https://drive.google.com/uc?id=1l4cxKhmge8acYWrkyNxLRv9dXN30XxGZ)

## クライアントPCからサーバPCにssh接続してみた

無事1台のクライアントPCから他3台のサーバPCにssh接続することができました！

![ssh確認画面](https://drive.google.com/uc?id=1-5IWvguMGWYjB7stEG5QOYTn7va49M7V)<br>


# 次にやること

次回は,以下のサイトを参考にしながら，それぞれのGPUにKubernetes，Dockerをインストールしていこうと思う．
[Docker環境構築](https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d)
[Kubernetes環境構築](https://thinkit.co.jp/article/18188)
DataPortal: ツールチップ

![スクリーンショット 2021-10-08 10.44.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/bd47e73c-7a30-0200-cb0e-a08fd785621b.png)
今日は DataPortal の有用なコミュニティビジュアリゼーションをご紹介。

### 困ってた事
DataPortal でレポートを作成していると「テキストを配置するほどではないのだけど、ちょっとした補足を入れたい」と思うことが良くありますよね。
標準のグラフではそういったことができないので、コミュニティビジュアリゼーションを探すと、 `MouseOver Tooltip` というのが目に止まります。
![スクリーンショット 2021-10-08 10.41.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/f23e969f-94d5-b188-081c-66b9cb8fd2a6.png)
一見良さそうなのですが、

- 設定した領域内しかツールチップが表示されない
- 設定した領域は他のグラフの操作ができなくなる

という感じでちょっと使い所が難しいのです。
![Group 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/b1aadb78-e833-a5b0-784d-d89118a858d4.png)

### 今日のご紹介
そこで今日ご紹介したい内容がこちら `Material Design icon`。
![スクリーンショット 2021-10-08 11.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/d031facd-ca65-4cbc-b443-22529979cb27.png)
「ふぅん、アイコンを表示するだけでしょ」と思うなかれ。
なんとこちら、ツールチップも表示できちゃうんです！
![スクリーンショット 2021-10-08 11.09.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/3c0d518e-c36a-48bb-7180-aa18f7e50c2b.png)
![スクリーンショット 2021-10-08 11.14.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/4f9bbd27-b2af-8b08-85a4-433d167afab4.png)
しかもなんと、設定した領域外にもツールチップが表示されるので、設定する領域はアイコンのサイズそのまま！
素敵ですねー
![スクリーンショット 2021-10-08 11.11.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/5bf6acb3-c731-fe6f-bc31-4899b5427fcc.png)
テーブルと重ねてもソートできちゃうんです！
わぁ、すごい！

でも、お高いんでしょう？
こちらのコミュニティビジュアリゼーション、今なら金利・手数料全て無料！
タダで使えちゃうんです！！
えぇ、タダで使えちゃうんですか！？
私もさっそく使っちゃお！

`Material Design icon` みなさんもぜひ、お試しください！！
新しいsshキーをアカウント githubに追加する際に問題が発生しました sourcetree

自分用メモ

# 困っていること
MacのSourceTreeでGithubとアカウント連携しようにも
「新しいsshキーをアカウント githubに追加する際に問題が発生しました」
が出てきて上手く行かない

# 解決方法
- Githubアカウントにプライベートアクセストークンを設定しそれを使う

## レシピ
1. トークンを作る
    1. Githubの Settings / Developer settings / Personal access tokens を開く
    1. Generate new tokenする。権限は困ったら多い方に倒す
1. SourceTreeからアカウントを連携する 
    1. ホスト: `Github`, AuthType: `BASIC`, ユーザー名: `Githubユーザー名`, パスワード: `作成したトークン`, プロトコル: `SSH`
    1. 「キーを作成」ボタンを押すとSourceTreeがいい感じにSSHキーを作ってGithubに登録してくれる

既存の鍵を入れる方法はわかりません。
【Power Automate】「SharePointにHTTP要求を送信する」アクションでメールを送信する

:::note alert
SharepointのSendEmail APIは2025年10月31日で廃止になります。PowerAutomateではOutlookコネクタをつかうしかなくなってしまうようです。

https://devblogs.microsoft.com/microsoft365dev/retirement-of-the-sharepoint-sendemail-api/
:::

SharePoint Onlineコネクタの「SharePointにHTTP要求を送信する」アクションを使ってメールを送信します。
サイトからの通知で、個人のメアドを発信元に使いたくないときに有効です。

※この方法ではSharePoint Onlineでサイトを用意しておく必要があります。
※メーリングリストに送信できるかどうかは未検証です。

### 1件のメールアドレスに送信する

|プロパティ|設定する値|
|---|---|
|サイトのアドレス|候補から用意したSPOサイトを選択、URLで用意したサイトを指定する|
|方法|Post|
|URI|_api/SP.Utilities.Utility.SendEmail|
|ヘッダー|{"Accept": "application/json; odata=nometadata","content-type": "application/json;odata=nometadata"}|
|body|{'properties': {'To': [' 実際のメールアドレスに置き換え '],'Body':' 文面を記述する。改行やリンクのhtmlタグ使えます。 ','Subject': ' 件名を記述します '}}|

### 複数人に送信する

|プロパティ|設定する値|
|---|---|
|サイトのアドレス|候補から用意したSPOサイトを選択、URLで用意したサイトを指定する|
|方法|Post|
|URI|_api/SP.Utilities.Utility.SendEmail|
|ヘッダー|{"Accept": "application/json;odata=verbose","content-type": "application/json;odata=verbose"}|
|body|{'properties': { 'To':{ 'results': [ Ａ ] },'Body':' 文面を記述する。改行やリンクのhtmlタグ使えます。 ','Subject': ' 件名を記述します '}}|
|Ａの箇所|テキスト型の変数を用意し、当該アクションの前に「'e-mail-address1','e-mail-address2'・・・」というように成型しておく|

### 手こずったところ
- Outlookコネクタの利用を当初想定していた為、ダブルクォーテーション→シングルクォーテーション、セミコロン→カンマへの変更が必要だったという初手躓き
- メールの宛先を変数に持たせる際にアレイにしてしまったため、ボディ内で動的なコンテンツの検索をしても変数が表示されなかった。　⇒　文字列変数にするのが正解
- 送信相手が変動する⇒ 設定されていない可能性のあるメールアドレスをnull判定の上、concat関数を利用する


### 参考にしたページ、ブログ

##### 複数の宛先にメールする

https://social.technet.microsoft.com/Forums/ie/ja-JP/642c10cc-bc00-4ff4-a71e-fc915c7cd4ff/rest?forum=Sharepoint2013

##### concat関数

https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference

##### シングルクォート

https://qiita.com/r-wakatsuki/items/69baafaeaed675b39ad9
[haskell] stackとHaskell Language Server双方のご機嫌を取り続けた記録

いくら開発側で便利なIDEやツールが用意されていても手元の環境一発であっさり壊れるんだなという実感があります。こんにちは。

今まで生の.hsファイルとかしか書いてなかったのを、stackを使ってわりとちゃんとしたパッケージの形で開発を始めて行った (行っている) のですが、ちょっと込み入ったことをやろうと思って実行した瞬間にコードと関係ない環境面で不具合が出まくったので、その戦いの記録を残しておきます。

具体的に何が起こったかというと、**stackでのビルドは通るのにvscodeに入れていたプラグインくんが警告を出して止まるため、本当にチェックしたいものがチェックできない**という事案が発生しました。

とはいえ、一番クリティカルな問題点はおそらく、ghc9.0.1にstackageのLTS haskellがまだ対応していないことが根源だろうとは思っています。なので、いろいろこねくり回すのをやめてStackage Nightlyをresolverに使うか、あるいはghc9.0.1をアンインストールして8.10.7を入れるかのどちらかにさっさと割り切ってしまうというのもひとつの手でしたね。

## 環境

2021年10月現在の私の環境ですが、以下のようになっています。

* OS: Windows 10
* ghc, cabal, stack: [Chocolatey](https://chocolatey.org/)経由で導入
* エディタ: [VSCode](https://code.visualstudio.com/)
* プラグイン: [Haskell for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=haskell.haskell)・[Haskell Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=justusadam.language-haskell)

まあWin10+VSCodeでhaskellをやろうと思ったらこうなるんじゃないでしょうか。

## "Could not find module"

ちゃんとstack.yamlやpackage.yamlを書けていれば、stackはビルド時に依存するパッケージを自動で導入してくれるのですが、例えstackでのビルドが通ったとしても、HLSで通ってくれるとは限りません。なんでや。

ghcおよびcabalを別途インストールしていた場合、どうもHLSはそちらのパスを見に行くようで、そちらでインストールされていないパッケージはHLSにとって無いものと見なされます。

結果として、`Could not find module`で始まるエラーメッセージをはいてくれやがります。

対策としては、`cabal install --user <package>`あるいは`cabal install --global <package>`をしてやります。これでHLS側の認識でも対象のパッケージがインストールされた扱いになります。

## hie.yamlを書くとむしろエラー

HLSは内部で[hie-bios](https://github.com/haskell/hie-bios)を使っており、これを使ってghcに渡すべきフラグの管理等を把握します。これはふつう自動で行われますが、hie.yamlというファイルを書くことで明示的にhie-biosの設定を行うことができます。

とりあえず、例えばstackで開発しているなら、以下の内容でも動きます：

```hie.yaml
cradle:
  stack:
```

ただし、stack側でresolverにlts-18.13 (ghc-8.10.7) などを使っている場合、「ghcideのバージョンは9.0.1でこのプロジェクトで使っているのは8.10.7だから、バージョンを揃えて！」とHLSに怒られます。こちとらghcideを導入した記憶がありませんが。

このエラーはhie.yamlを書かなければ起こりません。なら書かなければ問題ないな！(フラグ

## どうしてもhie.yamlが必要になったら

hie.yamlは単純な構成のプロジェクトならわざわざ書く必要がありませんが、単純でない構成になってしまった瞬間に必要が出てきます。例えばプロジェクト内にパッケージを複数用意することになった場合などです。
このような場合、HLS (hie-bios) くんが`Multi Cradle: No prefixes matched`というエラーを吐いてきます。

こうなったらhie.yamlを書かないといけません。hie.yamlを書かなければいけないということは、ghcideとghcのバージョンを揃えないといけません。

今回はghc-9.0.1をアンインストールしてghc-8.10.7を導入することで解決させました。(もちろんサポートされていればですが) 過去のバージョンも導入できるし複数バージョン導入可能なChocolateyつよいですね。

手順：

* ghc, cabal, stack, VSCodeのHaskellプラグインを全てアンインストール
* ghc-8.10.7をインストール (chocolatey経由の場合自動的にcabalもインストール)

```Console
> chocolatey install ghc --version 8.10.7 -my
```

* stackを再インストール
* VSCodeのHaskellプラグインを再インストール、ghc8.10.7用の実行ファイルが導入されたことを「出力」タブで確認。
Amazon Timestream へ過去データを保存するには？

時系列データを扱うのに最適化されている[Amazon Timestream](https://aws.amazon.com/jp/timestream/?nc=sn&loc=0)(以下、Timestream) は [Amazon Managed Grafana](https://aws.amazon.com/jp/grafana/) のデータソースにできるため、データ活用も容易になりました。そのため、Timestreamに移行したいと考える方もいるのではないでしょうか。

移行となると収集済みのデータ、すなわち過去データをTimestreamに書き込む必要があります。ここでは、判明している仕様や検証結果を紹介します。

:::note
2022年7月、Amazon Timestreamが東京リージョンでGAしています。
:::

## 書き込み可能な期間

Amazon Timestream のメモリストアの保持期間、もしくは、マグネティックストレージの書き込みオプションを有効化したマグネティックストアの保持期間で指定している期間が書き込めます。
例えばメモリストアの保持期間を 1day と指定したテーブルには、現時刻から -24 時間の期間を指定したレコードが書き込めます。

~~そして Memory store retention は最大で 12months (= 1年) が指定できるため、移行可能な期間は最大で過去1年分となります。~~
→ AWS re:Invent 2021 で、マグネティックストレージに直接書き込めるようになったため、マグネティックストアの最大 = 過去100年分まで書き込めるようになりました。
ref: [Amazon Timestreamに100年前の過去データを保存できるようになっていた件](https://qiita.com/pltnm78/items/c9002abd2926dfaff707)

### 検証

[AWS CLIから書き込み](https://qiita.com/ma2shita/items/1e1cafc9720dc43b0226)できます。
データのタイムスタンプは `Time` となります。ここは `date` でUNIX時間を指定しました。

`date --date '-365 day'` で365日前を指定 (= 保持期間の期間内)

```console
$ export DB="tsdb1"
$ export TBL="data1"
$ export IID=$(uuidgen)

$ export TS=$(date --date '-365 day' +%s%3N)
$ aws timestream-write write-records --database-name ${DB} --table-name ${TBL} --records "Dimensions=[{Name=iid,Value=${IID}},{Name=d1,Value=example1}],Time=${TS},MeasureName=val1,MeasureValueType=BIGINT,MeasureValue=${RANDOM}"
## => 成功
```

`date --date '-366 day'` で366日前を指定 (= 保持期間よりも過去)

```console
$ export DB="tsdb1"
$ export TBL="data1"
$ export IID=$(uuidgen)

$ export TS=$(date --date '-366 day' +%s%3N)
$ aws timestream-write write-records --database-name ${DB} --table-name ${TBL} --records "Dimensions=[{Name=iid,Value=${IID}},{Name=d1,Value=example1}],Time=${TS},MeasureName=val1,MeasureValueType=BIGINT,MeasureValue=${RANDOM}"

An error occurred (RejectedRecordsException) when calling the WriteRecords operation: One or more records have been rejected. See RejectedRecords for details.
## => 失敗
```

## 実運用に向けて

### 保持期間を "後から短くした場合" はどうなる？

12months に設定した保持期間を、例えば移行が終わったので 1day と短くすることは可能です。変更時に「Memory storeからMagnetic storeに移動される」というダイアログが出ますが、データが消えることはありません。
※ただし、マグネティックストアの保持期限を超えた古いデータがどうなるかは未検証です。

### 保持期間を "後から長くした場合" はどうなる？

例えば保持期間を 1day として運用中のTimestreamテーブルにデータ移行をしたいので、一時的に 12months に変更したいと考えるでしょう。
保持期間の変更自体はできますが、書き込みはできませんでした。仕様は不明ですが、運用中のTimestreamテーブルへのデータ移行を直接行うのは難しそうです。

新規に保持期間を長く設定したTimestreamテーブルを作成し、別データを移行し終わった後に、運用中のTimestreamテーブルから新規Timestreamに移行するという方法が考えられます。

### マグネティックストレージの書き込みは後から有効化できる？

(調査中)

### 費用は期間ではなく保存容量

ストアの費用は retention ではなく格納容量です([Amazon Timestream 料金](https://aws.amazon.com/jp/timestream/pricing/))。そのため、とりあえず12monthsに設定するという考え方も検討できそうです。お財布とご相談ください。

## あとがき

データベースは移行がポイントだな。

EoT
apt-get upgradeでのエラー

# 症状
install-infoがうまく設定できず、エラーを吐いていた。

# 解決策
/var/lib/dpkg/info/の中にあるintall-infoの関連ファイルを削除してインストールし直す。

- 移動  
`cd /var/lib/dpkg/info/`

- install-infoのファイルを見る  
`ls |grep install-info`

- 削除する  
`sudo rm -rf install-info.list install-info.md5sums install-info.postinst install-info.triggers`

-  install-infoのインストール  
`apt-get install install-info`

- upgradeを行う
`sudo apt-get upgrade`
C++/socket


```

#pragma once

class ClientUtil
{
public:
	const int PORT = 9876; //サーバープログラムとポート番号を合わせてください
						   //char* destination = "127.0.0.1";
	char* destination = "192.168.xxx.xxx";

	struct sockaddr_in dstAddr;
	int dstSocket;
	WSADATA data;


	ClientUtil() {}
	int init() {


		// Windows の場合
		WSAStartup( MAKEWORD( 2, 0 ), &data );

		// 相手先アドレスの入力と送る文字の入力
		//printf( "サーバーマシンのIPは？:" );
		//scanf( "%s", destination );

		// sockaddr_in 構造体のセット
		memset( &dstAddr, 0, sizeof( dstAddr ) );
		dstAddr.sin_port = htons( PORT );
		dstAddr.sin_family = AF_INET;
		dstAddr.sin_addr.s_addr = inet_addr( destination );


		// ソケットの生成
		dstSocket = socket( AF_INET, SOCK_STREAM, 0 );

		return 0;
	}

	int connect( bool bReConnnect = false ) {
		//接続
		if ( bReConnnect ) {
			closesocket( dstSocket );

			dstSocket = socket( AF_INET, SOCK_STREAM, 0 );
		}


		int result = ::connect( dstSocket, (struct sockaddr *) &dstAddr, sizeof( dstAddr ) );
		if ( SOCKET_ERROR == result ) {
			//printf( "%s　に接続できませんでした\n", destination );
			return SOCKET_ERROR;
		}

		//printf( "%s に接続しました\n", destination );
		//printf( "適当なアルファベットを入力してください\n" );
		return result;
	}
	int close() {

		// Windows でのソケットの終了
		closesocket( dstSocket );
		WSACleanup();
		return 0;
	}

	class Header {
	public:
		Header(){
			memset( &tmpbuff, 0, sizeof( tmpbuff ) );
		}
		unsigned int magicid = 0xabababab;
		int id = 1;
		int datasize = 0;//ヘッダサイズも含める
		int bzip =1;
		char tmpbuff[128 - 4 * sizeof( int )];

	};

	int update( char* dst, int len ) {
		int flags = 0;
		int ret = 0;

		Header hd;
		hd.datasize = len;//圧縮後のデータサイズ

		if ( sizeof( Header ) != 128 ) {
			return -1;
		}
		memcpy( dst, &hd, HEADER_AREA_SIZE );


		ret = send( dstSocket, dst, len, flags );
		if ( ret == SOCKET_ERROR ) {
			return SOCKET_ERROR;
		}

		char buffer[128];
		memset( buffer, 0, sizeof( buffer ) );
		ret = recv( dstSocket, buffer, 128, 0 );
		if ( ret == SOCKET_ERROR ) {
			return SOCKET_ERROR;
		}
		else {
			printf( "." );
		}

		//WSAGetLastErrorでエラーをGETできる
		return ret;
	}
	int update2() {
		// 各種パラメータ
		char buffer[1024];

		while ( 1 ) {
			scanf( "%s", buffer );
			//パケットの送信
			send( dstSocket, buffer, 1024, 0 );
			//パケットの受信
			recv( dstSocket, buffer, 1024, 0 );
			printf( "→ %s\n\n", buffer );
		}

		return 0;
	}
};

```
NavMesh

〇動的NavMesh機能は正式採用
「Unity 5.6からLow Level APIのような物が公開され、NavMeshを動的にベイクすることが可能になりました。」
http://tsubakit1.hateblo.jp/entry/2018/01/06/003209

昔は機能をAppendしていたが、Unity2019では普通に機能実装されている。た
Unity2018でも多分実装されていると思う。

〇メモ

https://xr-hub.com/archives/7639

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/502ceff6-7547-397e-8fee-efe84cee370b.png)

[Unity2019.4.16 Navigationsample](https://1drv.ms/u/s!ApO4wsxFJBbVvgD-xlUI_spgqYFb?e=CvavTT)
VisualStudioでUnityにアタッチが表示されない問題

「Unityにアタッチ」ボタンが出ない場合は、
[Edit]-[Preferences]ダイアログを開いて[External Script Editor]を確認すること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/0913b34a-514f-1498-1536-b1c62ba60fbf.png)
[RealsenseD435で物体認識1

目的
---
RealseseD435の深度情報をつかって物体を認識する。
T265の位置情報を取り出す。

メモ：
---
https://github.com/IntelRealSense/librealsense/blob/master/examples/pointcloud/rs-pointcloud.cpp

https://github.com/IntelRealSense/librealsense/blob/master/examples/tracking-and-depth/rs-tracking-and-depth.cpp

この二つを参考にする。

■T265の位置情報を取り出す処理
    #tab
	{
		auto rotation = pose_data.rotation;
		double M_PI = 3.14159;
		double w = rotation.w;
		double x = -rotation.z;
		double y = rotation.x;
		double z = -rotation.y;

		double pitch = -asin( 2.0 * (x*z - w*y) ) * 180.0 / M_PI;
		double roll = atan2( 2.0 * (w*x + y*z), w*w - x*x - y*y + z*z ) * 180.0 / M_PI;
		double yaw = atan2( 2.0 * (w*z + x*y), w*w + x*x - y*y - z*z ) * 180.0 / M_PI;
		printf( ": [deg]: Roll: %0.3f, Pitch: %0.3f, Yaw: %0.3f ", roll, pitch, yaw );
	}　　　

■　ZIP圧縮してネットワーク転送する処理

ZipTest::encode()で圧縮
cutil.update()でネットワーク送信

	void PointCloud_ZipSend::pointcloud_zip_send( rs2::points& points, ClientUtil& cutil)
	{
	memset( dstTop, 0, HEADER_AREA_SIZE );
	Byte* dstBody = dstTop + HEADER_AREA_SIZE;

	rs2::vertex* srcBuff = new rs2::vertex[RS_DEPTH_W*RS_DEPTH_H];
	int failcnt = 0;

	{
		//int datsize = points.get_data_size();
		int dsize = points.size();
		const rs2::vertex* src = points.get_vertices();

		uLong srclen = dsize * sizeof( rs2::vertex );
		const rs2::vertex* src2 = src;
		int cnt = 0;

		//! データ量を減らしてネットワーク負荷を下げる試作：この方法だとほとんど変化なし
		for ( int y = 0; y <RS_DEPTH_H; y++ ) {
	#if RS_DEPTH_W==640
			for ( int i = 0; i < RS_DEPTH_W; i += 2 ) {
	#else
			for ( int i = 0; i < RS_DEPTH_W; i++ ) {
	#endif
				int index = y * RS_DEPTH_W + i;
				assert( cnt <= dsize );
				srcBuff[cnt++] = src2[index];
			}
		}

		{
			uLong dstlen = dst_buffer_size;// dstバッファ長をいれたら、zlibが使用した長さを返す

			int result = ZipTest::encode( dstBody, dstlen, (Byte*)srcBuff, cnt * sizeof( rs2::vertex ) );
			if ( result == Z_OK ) {
				result = cutil.update( (char*)dstTop, HEADER_AREA_SIZE + dstlen );
				if ( result == SOCKET_ERROR ) {
					if ( SOCKET_ERROR != cutil.connect( true ) ) {
						printf( "o" );
					}
				}
			}
			else {
				failcnt++;
				printf( "%u", failcnt );
			}
		}
	}
	}
ブック全体で「F!」の記号を検索してみて下さい。>このワークシート内にある1つ以上の式の参照に問題がみつかりました。数式内のセル参照、範囲名、定義名、および他のブックへのリンクがすべて正しいことをご確認ください。

の解決方法
[エクセルで参照に問題があるセルの探し方を教えて下さい。「このワークシ... - Yahoo!知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14217639724)
によると
```web
シート間参照、ブック間参照などの場合でエラーになっている場合があります。
ブック全体で「F!」の記号を検索してみて下さい。
で検索結果の一覧を大きく拡げてみて、検索結果の表示の式に#REF!があるかと思います。
```
との事ですっ

なんかマークダウン記法がうまく行かないので以下もメモります。

[Qiita マークダウン記法 一覧表・チートシート - Qiita ](https://qiita.com/kamorits/items/6f342da395ad57468ae3)
Pythonで任意のアプリケーションを最前面にする

会社ノートPCの狭い画面での業務は非効率極まりないので
とりあえず任意のアプリケーションを最前面にする事でお茶を濁すことにしました
拡張用のモニターが欲しいですね

#はじめに
![setwinpos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675031/68062124-a9b8-4975-7d0f-5da9cf551487.png)
タイトルまんまです。
こんな感じにTkinterでGUIを作って、ウィンドウ名の一部をテキストボックスに入力し、ON/OFFします。

#要点
+ .findを使って部分一致でウィンドウ名を探す
+ SetWindowPosを使う

#先にコード
```Python:SetWinPos.py
import win32gui, win32con
import tkinter as tk
from tkinter import ttk

def foreground_on(hwnd, title):
    name = win32gui.GetWindowText(hwnd)
    if name.find(title) >= 0:
        #最前面ON
        win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
        return

def foreground_off(hwnd, title):
    name = win32gui.GetWindowText(hwnd)
    if name.find(title) >= 0:
        #最前面OFF
        win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
        return

mainWnd = tk.Tk()
mainWnd.title(u"SetWinPos")
mainWnd.geometry("250x100")

def Button_1():
    value = EditBox.get()
    win32gui.EnumWindows(foreground_on, value)

def Button_2():
    value = EditBox.get()
    win32gui.EnumWindows(foreground_off, value)

#エントリー
EditBox = ttk.Entry()
EditBox.insert(tk.END,"メモ帳")
EditBox.pack(expand = True, fill = tk.BOTH, padx = 5, pady = 5)
#ボタン1
Button1 = ttk.Button(text='最前面ON', command=Button_1) 
Button1.pack(expand = True, fill = tk.BOTH, padx = 5)
#ボタン2
Button2 = ttk.Button(text='最前面OFF', command=Button_2) 
Button2.pack(expand = True, fill = tk.BOTH, padx = 5, pady = 5)

mainWnd.mainloop()
```

#解説らしきこと
```Python:SetWinPos.py
import win32gui, win32con
import tkinter as tk
from tkinter import ttk
```
ここで必要なライブラリをインポートします
ttkの行は必須ではないですが、今回は見た目の好みの問題でttkを使いました。

```Python:SetWinPos.py
def foreground_on(hwnd, title):
    name = win32gui.GetWindowText(hwnd)
    if name.find(title) >= 0:
        #最前面ON
        win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE)
        return
```
ここについては[**こちらのQA**](https://teratail.com/questions/188610)のものがベースです。
QAではreturn時にFalseを返していますが、動作はするもののエラーを吐いてしまいますので削除。
SetForegroundWindowでは今回の目的は達成出来ないのでSetWindowPosに変えます。
処理の流れとしては、
GetWindowTextで取得したフォアグラウンドウィンドウの名前から**.find**で検索をかけ
検索で見つかれば、そのウィンドウを**win32con.HWND_TOPMOST**(最前面)に設定。
def foreground_offは、同様に**win32con.HWND_NOTOPMOST**(最前面解除)に設定。

SetWindowPosについては[**こちらの記事**](https://office54.net/python/app/windows-foreground-active)に解説があります。

以降はTKでのGUI構築なので省略します。

#おわりに
pywin32を使わずにctypesで書ければ、追加ライブラリのインストールなしで動作させられそうですね。
こんな小さなコードでもPyinstallerでexe化したら9.5MBほどになってしまいます。
UPXかけても9.4MB…
Swift5 MainMenuのitemがenable状態から変わらない場合の対処法

Xcode: v13.0
Swift: 5.5
## 事象
XcodeでOSX用のMainMenuの各item(NSMenuItem)enable/disable制御を実装しようとした際enable状態から変わらない状態が発生したので、その際の対処法をメモします。

storyboard上ではdisable状態のはずなのに・・
![スクリーンショット 2021-10-07 16.53.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264641/acedd0ea-e403-849c-4d99-505ac1c430a8.png)
RUNするとenable状態になってしまう・・
![スクリーンショット 2021-10-07 16.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264641/7e511d37-8534-7948-3af6-e31326de37cf.png)
立ち上げ段階ではdisable状態であって欲しい！!

## 解決策
AutoEnables Itemsのチェックを外す。
上記にチェックが入っていると自動でmenuitemがenable状態になってしまいます。そのような状態を望まない場合はチェックを外しましょう！
![スクリーンショット 2021-10-07 16.58.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264641/0fa13c75-2ae3-2855-1b65-08a9597396e1.png)
OculusIntegration 2020.10　Switch PlatformでAndroid

# 環境
Unity 2020.2.4f1
VS2019 free
OS windows10 pro
Oculus2

#メモ
開発するときは、SwitchPlatformせずPC版でOculusQuest2と接続。OculusLinkが便利。

# 問題
Oculus Linkを停止させるときにUnityがハングアップする。

# ビルド手順

[Unity]
Vulkanの削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/7a2c97ff-a94f-97e3-1af7-7bf5fe1ab92e.png)

Rendering/Colorをリニア
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/72a30617-e65e-c98a-0c87-bcdb10b0dd10.png)

Android6.0以降をターゲットにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/983bfd45-ef4c-bb70-9096-25ad1457bdc8.png)

Switch Platformする。
<font color="Red">テクスチャをASTCにすると処理が長くなる</font>


#Oculus Integrationのインストール(非常に重たい)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/84eda151-8015-9d9b-31dc-1ca7ee51505c.png)
→リップシンクとAvatorは不要だけど、ビルドエラー出るので残す。
★何度かダイアログでるけど、YES/Update/Restartを選択する。

# XRインタラクションツールキット/XR Interaction Toolkit
★previewも検索対象にする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/c769e6f0-0574-f81a-fd3a-b7a76349da69.png)

https://note.com/npaka/n/n7b99fac6b5fa

# XR Plugin Management

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/8f481e48-18b0-99f1-b386-7813b912578a.png)

a) Install XR Plugin Management
b) Oculusにチェック入れる。
　windows　-> OculusLinkで使う。
　android　-> android buildで使う。


# 以前の記事
https://qiita.com/tangotarou2/items/36e5c5f95ca3af421299
Vue.jsで管理するtextareaをごにょごにょしたかった

# 概要

textareaの中身を外からJSでいろいろする画面をVuetifyで作ろうとするとハマる。
実はVuetifyは関係なくてVue.jsなら（たぶん）ハマる。

## やろうとしたこと

あるボタンを押すとカーソル位置にテキストが差し込まれるよくあるやつ。

## わりとすぐわかったこと

`textarea.setTextRange`はVue.jsで管理しているtextareaでは当然うまく動かない。
`textarea.selectionStart`、`textarea.selectionEnd`でカーソル位置をとってきて、v-modelを直接編集する必要がある。

## ハマったこと

textareaのテキスト編集後のカーソル位置がいい感じにならない。
`textarea.setSelectionRange`がまともに動いていないように見える。

## 解

https://stackoverflow.com/questions/52333594/vuetify-how-to-make-setselectionrangeint-int-work-in-v-textarea-when-its-mo/52333799

```
setTimeout(() => bodyTextArea.setSelectionRange(2, 2))
```

```
this.$nextTick(() => {
   textarea.setSelectionRange(2, 2))
})
```

ふーんなるほどね