OmniAICreator/Qiita-1.07M huggingface dataset:
振り回されないEasyな表現との付き合い方

## 概要

* Easyな表現には価値がある一方、情報の消失や例外の隠蔽といったデメリットが存在する
* Easyな表現をそのまま手法にブレイクダウンしていると振り回されることになる
* Easyに表現されたものはあくまでもEasyなものであると認識して、自分で考える癖を身につけよう

## Easyな表現とは

ITに限らず世界には情報がたくさん飛び交っています。
そうした情報過多の世界において **分かりやすく表現された情報** というのはとても価値があります。

この

* 分かりやすい

を `Easy` とこの記事では定義します。

例えば以下のようなものを `Easyな表現`(それがあっているかどうかは別)としてイメージをしてもらうと良いです。

* 「人を殺してはいけない」
* 「テストを先に書こう」
* 「信号が赤のときは進んではいけない」


## Easyな表現におけるメリットとデメリット

こうしたEasyな表現は特に自分がその分野のエキスパートでなければ非常にありがたい情報になります。

難しい用語や前提が一切なく、すっと頭に入ってくる簡素にまとめられた情報は、
自分の消費する時間を最大限減らして、新しい気づきを与えてくれることが多いです。

Easyな表現はこうした大きなメリットがあるといえます。

一方で情報をEasyな表現にしていく過程では

* 情報の消失
* 例外の隠蔽

といったことがよく発生します。

この事象を理解しない上でEasyに表現された情報を鵜呑みにしてしまうのは危険です。

特にその中でも私が **一番危険だと思っているものは、Easyに表現されたもの同士での議論** です。

この情報の消失や例外が隠蔽された表現で議論をしても、
前提がずれていたり重要な情報が伝わっていないことで無駄な時間になってしまうことがあります。

## 情報の消失

Easyな表現をするため過程で「抽象化」というテクニックが使われます。

この抽象化によって具体的な情報が削られることが起きます。

プロジェクトマネジメントの世界で **QCDSを調整してプロジェクトを成功に導く** という表現が出てきたとしても、
ではどの具体的な方法は？ というのは読み取れません。

勘違いしてはいけないのは、別にこの言葉自体が良い・悪い、ということではなく、あくまでも Easyに表現をしているから読み取れないのであり、その具体的な方法を考えてない訳ではないということです。(と信じています)

また当然のように **QCDS** と言葉を略していますが、これが「品質」「費用」「納期」「スコープ」を意味しているというのも、
「わかる人にはわかるだろう」ということで情報を消失させている例です。
さらに「品質」という言葉1つとっても思い浮かべるものは人によって違ってきます。

このようにEasyな表現にするためには言葉を短く略したり、具体的な方法は伝えない(後で伝えるも含む)ということが起きます。

## 例外の隠蔽

情報の消失に近いですが Easyに表現されたものは例外をあえて伝えないということが起きます。

この場合における例外とは、「ただし、xxxのときは〜」と繋がる言葉です。

これも広義の意味では情報の消失なのですが、特に消失される情報であるため抜き出しました。

先の例で言うと「人を殺してはいけない」という表現において「ただしxxxのときは〜」が後ろにくっつく可能性があります。

消失してしまった情報が「法律」の話なのか「倫理」の話なのか、いろいろ推測はあるかと思いますが、
「法律」「倫理」においても例外を思い付けるのではないでしょうか。
※込み入った話になりそうなのでこの例ではこれ以上踏み込みませんが…！

## Easyな表現とはどう付き合っていけば良いか

Easyな表現はとても価値があります。
だからこそ上手に付き合っていくためにデメリットを自分で補う行動を取ることで、
振り回されずに付き合っていくことができると思います。

勉強会やTwitter、ブログ記事でEasyな表現で出会ったときは

* 消えている情報は何かを考える・調べる
* 例外を考える・調べる

という癖を身につけていくのが良いと思います。

そしてEasyな表現をもとに具体的なプロセス・手法を考えていく時は、
この消失された情報や例外も参考にしつつ考えていくのが良いです。

また反対にも、Easyな表現が自分の考えとは異なっていても、いきなり拒否反応を示したりせず、
消えている情報や例外を考えるのも重要です。

* 自動テストを書くと生産性が落ちる
* 自動テストを書くと生産性があがる

このように一見対立している意見であっても、
消失された情報を合わせると同じようなことを言っていることに気付くこともあります。

せっかく同じ考えを持っているにも関わらず、
表面的なEasyに表現されたものだけで意見を衝突し合うのはとてももったいないです。

## まとめ

* Easyに表現された情報は理解しやすく価値が高い
* しかしEasyに表現されたものには情報が失われていたり例外が隠れていたりする
* Easyになった情報は、自分が賛同・反対に関わらず、失われている情報を調べたり考えたりする癖を身につけよう

## Tips

* Easyな表現なのに強い断定の言葉があるときは気をつけた方が良いと多います(正しい・正しくないは別にして)
  * 例
      * **結局**xxxなのはyyyな**だけ**である
      * xxxは**間違えている**。
      * xxxは**ダメ。使うな**
Flutter開発メモ

## 使えそうなURL
[widet一覧](https://qiita.com/matsukatsu/items/e289e30231fffb1e4502)

## 概要

- ウィジェット<br>
表示する部品のようなもの、頭が大文字

- プロパティ<br>
ウィジェットの具体的な設定ができる、頭が小文字

## 細かい言語仕様

- returnで返却できるウィジェットは1つまで
- ファイル名はスネークケースで繋ぐ

## ツール使い方

- importはoptionキーとエンター
- debug起動はcontrol+D

## アーキテクチャ周り

- 画面ごとにクラスを作成する、ファイルを作成する
-
PHPファイルの読み込み方

#ファイルの読み込み方の種類
PHPのファイルの読み込み方には1行ずつ読み込むか一気に読み込むかの2通りあります。
1.1行ずつ読み込む→fgets()
2.一気に読み込む→fread()

具体的に
##fgets()
流れ
1.第二引数にreadの頭文字を取った'r'を設定してファイルを読み込む。
2.fgets()は読み込む行が無くなった場合falseを返すのでfalseが返るまでwhileで1行ずつ取得し表示。
3.ファイルを閉じる。

```php
$fp = fopen("ファイル名", "r");
while (($content = fgets($fp)) !== false){
  echo $content;
}
fclose($fp);
```



##fread()
流れ
1.第二引数にreadの頭文字を取った'r'を設定してファイルを読み込む。
2.fread()で全ての値を変数に格納。
3.ファイルを閉じる。
4.格納されたものを表示。

```php
$fp = fopen("ファイル名", "r");
$contents = fread($fp, filesize("ファイル名"));
fclose($fp);
echo $contents;
```

##fgets() VS fread()
結論から言うとfgets()を使うべきです。
メモリは有限なので限度を超えたファイルを一気に読み込むことができません。
なので大きなファイルを読み込む場合fgets()を使うべきでしょう。
またメモリに収まるサイズだったとしても一気読み込むのはPCの負担になるので動作が不安定になったり最悪の場合はシステムが停止する可能性もあるのでfgets()で慣れておきましょう。
【ABC234】C - Happy New Year!をC++で解説

#はじめに
　皆さんこんにちは！ 競プロの問題の理解を深めるために解説記事を書いていこうと思います！今回は **ABC234 C** です！

 気に入っていただけたら**LGTM**して頂けるとうれしいです！

わからないことなどあれば下の**コメント**や[Twitter](https://twitter.com/python05238919)からお願いいたします!
#[C - Happy New Year!](https://atcoder.jp/contests/abc234/tasks/abc234_c)
####問題概要
 10進法にしたときに0, 2で表される正整数のうち$K$番目の数を求めよ．
####制約
 $1 \leq K \leq 10^{18} $

##考察
####ポイント
 **2進数に変換しよう**
####解説
 0,2からなる正整数を小さいほうから並べてみると

```
1 : 2       ->  1
2 : 20      ->  10  
3 : 22      ->  11
4 : 200     ->  100
5 : 202     ->  101
6 : 220     ->  110
7 : 222     ->  111
8 : 2000    ->  1000
```
となります．
　これの**2を1に置き換える**と `->`のとおり**10進数を2進数で変換したもの**と同じであることがわかります．
　これより$K$を2進数に変換すれば答えがわかります．

#実装
　2進数に変換するのは**while文**で$K$を2で割っていきます．**出力は文字列で2で割り切れたら2を，割り切れなかったら0**を文字列の前に足していきます．
2進数の変換を理論的に述べているサイトを紹介します．

https://manabitimes.jp/math/1084

##正解コード

```C++:
#include <bits/stdc++.h>
using namespace std;

int main()
{
    //入力
    long long K;
    cin >> K;

    //解答は文字列で宣言
    string ans = "";

    //2進数に変換
    while (K > 0)
    {
        int a = K % 2;
        K /= 2;
        ans = (char)('0' + 2 * a) + ans;
    }
     
    //出力
    cout << ans << endl;
}

```
Pythonのheapqをmax heapとして利用する方法

Pythonの優先度付きキューであるheapqはmin heapです。そのため`heappop()`すると、最小値がポップされます。max heapとして、最大値をポップしたい場合には、正負反転したリストを`heapify()`して利用するのが簡単な方法です。

```python
import heapq

def test_heapq_maxheap():
    A = [1, 6, 8, 0, -1]
    A = [-1 * a for a in A]
    heapq.heapify(A)
    v = -1 * heapq.heappop(A)
    assert v == 8
```

これで、min heap（標準）とmax heapを状況に応じて使い分けられます。
Flutter ios実機ビルドができない Could not run build/ios/iphoneos/Runner.app

# 実行
```zsh
% flutter devices
connected devices:
iPhone (mobile) • XXXXX-XXXXXXXXXXX (deviceID) • ios  • iOS 15.1.1

% flutter run -d XXXXX-XXXXXXXXXXX
```

# エラー
```zsh
Xcode build done.
Could not run build/ios/iphoneos/Runner.app on XXXXX-XXXXXXXXXXX
```

# 対応
下記ディレクトリ削除

```
% rm -rf ~/flutter/bin/cache/artifacts/
```

# 参考
[Flutter SDKの仕組み](https://qiita.com/kurun_pan/items/520d91b4f5da6f14345b#artifacts)
railsチュートリアル第十三章 画像のリサイズ 本番環境での画像アップロード

###画像のリサイズ
ユーザーに手元で画像サイズを変更させるのは不便です。
なので、画像を表示させる前にサイズを変更する（リサイズする）ようにしてみましょう。

画像をリサイズするためには、画像を操作するプログラムが必要になります。
開発環境にインストールします。

```
sudo apt-get -y install imagemagick
```
###画像処理用のgemを追加する
Gemfile

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

gem 'rails',                      '6.0.3'
gem 'image_processing',           '1.9.3'
gem 'mini_magick',                '4.9.5'
gem 'active_storage_validations', '0.8.2'
.
.
.
```
```
$ bundle install
```

####表示用のリサイズ済み画像を追加
app/models/micropost.rb

```rb
class Micropost < ApplicationRecord
.
.
.
  # 表示用のリサイズ済み画像を返す
  def display_image
    image.variant(resize_to_limit: [500, 500])
    # variantメソッドで変換済み画像を作成できる
    # resize_to_limitオプションを用いて,
    #   画像の幅や高さが500ピクセルを超えることのないように制約をかけます。
  end
end
```

####リサイズ済みのdisplay_imageを使う
app/views/microposts/_micropost.html.erb

```html
<li id="micropost-<%= micropost.id %>">
  <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
  <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
  <span class="content"><%= micropost.content %></span>
  <span class="content">
    <%= micropost.content %>
    <%= image_tag micropost.display_image if micropost.image.attached? %>
    <!--image_tagヘルパーを用いて、関連付けられたmicropost.imageを
    　　　描画（レンダリング）できるようになります-->
    <!--画像がアタッチされていたら画像を表示させる-->
    <!--image.attached?されたら画像の編集される-->
  </span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %> ago.
    <!--メソッド名の表すとおりですが、「3分前に投稿」といった文字列を出力します。-->
    <% if current_user?(micropost.user) %>
    <!--もし自分の投稿だったら-->
      <%= link_to "delete", micropost, method: :delete,
                                       data: { confirm: "You sure?" } %>
    <% end %>
  </span>
</li>
```

###演習
解像度の高い画像をアップロードし、リサイズされているかどうか確認してみましょう。画像が長方形だった場合、リサイズはうまく行われているでしょうか?

アイコンが出てきた。

###本番環境での画像アップロード
####AWS用のgemを追加する
Gemfile

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

gem 'rails',                   '6.0.3'
gem 'aws-sdk-s3',              '1.46.0', require: false
gem 'image_processing',        '1.9.3'
gem 'mini_magick',             '4.9.5'
.
.
.
```
```
$ bundle install
```
####ストレージオプションにAWSを追加する
config/storage.yml

```yml
test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

amazon:
  service: S3
  access_key_id:     <%= ENV['AWS_ACCESS_KEY'] %>
  secret_access_key: <%= ENV['AWS_SECRET_KEY'] %>
  region:            <%= ENV['AWS_REGION'] %>
  bucket:            <%= ENV['AWS_BUCKET'] %>
```

####本番でAWS S3を使うよう設定する
config/environments/production.rb

```rb
.
.
.
  # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
　
　# アップロードされたファイルをAWSに保存する
  config.active_storage.service = :amazon
end
```
###困ったこと
git push heroku masterをすることができなかった。
Nextjs, Fauna, GraphQLでソート

#目的
こちらのサイトを参考に認証機能を搭載したCRUDアプリを作成しました。


https://ichi.pro/next-js-faunadb-graphql-o-shiyoshita-crud-apuri-62173528464366

https://ichi.pro/next-js-to-graphql-apuri-ni-faunadb-ninsho-o-jissosuru-45813515259286

こちらのアプリにtimeという項目を追加し、timeでソートされた状態で出力できるように改良しようと思います。

##手順１　スキーマ
FaunaのGraphQL　Playgroundからスキーマを変更しましょう。
allTodosSortedByTime: [Todo!]! @resolver(name: "sort_by_time", paginated: true)<br>を追加することによってsort_by_timeという新たなuse-defiend functionを作成します。

```
type Todo {
  task: String!
  owner: User!
  time: String 
}

type User {
  email: String! @unique
  todos: [Todo!] @relation
}

type Query {
  allTodos: [Todo!]
  allTodosSortedByTime: [Todo!]! @resolver(name: "sort_by_time", paginated: true)
}
```

##手順２　インデックス作成
ドキュメントを並び替える用の新たなインデックスを作成します。
FaunaのShellから以下のコードを実行しましょう。


```shell:shell
CreateIndex({
  name: "all_Todos_sorted_by_time",
  source: Collection("Todo"),
  values: [
    { field: ["data", "time"] },
    { field: ["ref"] }
  ]
})
```

#手順３　function更新
手順１で作成したfunctionをアルファベット順に並べる関数を作成します。

```shell:shell
Update(Function("sort_by_time"), {
  body: Query(
    Lambda(
      ["size", "after", "before"],
      Let(
        {
          match: Match(Index("all_Todos_sorted_by_time")),
          page: If(
            Equals(Var("before"), null),
            If(
              Equals(Var("after"), null),
              Paginate(Var("match"), { size: Var("size") }),
              Paginate(Var("match"), { size: Var("size"), after: Var("after") })
            ),
            Paginate(Var("match"), { size: Var("size"), before: Var("before") })
          )
        },
        Map(Var("page"), Lambda("values", Get(Select(1, Var("values")))))
      )
    )
  )
})
```

#手順４　Functionの呼び出し
Auth UserがFunctionを呼び出せるようにします。
SecurityでFunctionのCallを許可するようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2291778/6c97225f-96c0-7e30-ff66-525672dfd0ef.png)

#手順５ index.jsの更新
allTodosが呼び出されていたところをallTodosSortedByTimeに変更しましょう。

```
・・・
const { data, error ,mutate } = useSWR(
  gql`
    {
      allTodosSortedByTime {
        data {
          _id
          task
          completed
          time
        }
      }
    }
  `,
  fetcher
);

・・・

  {data ? (
    <div className={styles.todos}>
      {data.allTodosSortedByTime.data.map((todo) => (
        <div key={todo._id} className={styles.todo}>

・・・
```


##参考


https://ichi.pro/next-js-faunadb-graphql-o-shiyoshita-crud-apuri-62173528464366

https://ichi.pro/next-js-to-graphql-apuri-ni-faunadb-ninsho-o-jissosuru-45813515259286


https://docs.fauna.com/fauna/current/cookbook/graphql/sort?lang=javascript
windows powershellのwingetでvscodeをインストールする

windows powershellのwingetでvscodeをインストールする方法の備忘メモです

```bash:powershellのwingetでvscodeをインストール
winget install vscode
```

```bash:test.pyを開く
code test.py
```

もし上記がうまくいかなそうであればインストーラからインストールする。

> [Visual Studio Codeインストール手順＜Windows向け＞](https://sukkiri.jp/technologies/devtools/vscode_win.html)

# 参考
[VS Code を winget でインストールしてみた](https://dev.classmethod.jp/articles/winget-install-vscode/)
[Microsoft Visual Studio Codev1.56.0](https://winget.run/pkg/Microsoft/VisualStudioCode)
「フィボナッチ数を出力せよ」をRubyで

https://qiita.com/Nabetani/items/2441696a019317173f61

鍋谷さんの課題をやってみた。

#コード

めっちゃ恥ずかしいのだけれど、素朴なやり方しか思いつかなかった。

```ruby:Ruby
b, c = ARGV.map(&:to_i)
tm = Time.now

nxt = 1 + c
b1 = 1
s, t = 0, 1
(0..).each do |n|
  break if Time.now - tm > 1.0
  if nxt == n
    str = s.to_s
    result = "f(#{n})="
    result << if (l = str.length) <= 5
                str
              else
                str[0, 2] + "(ommit #{l - 4} digits)" + str[-2, 2]
              end
    puts result
    b1 *= b
    nxt = b1 + c
  end
  s, t = t, s + t
end
```

#結果

```
$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]

$ ruby fibo.rb 12 12
f(13)=233
f(24)=46368
f(156)=17(ommit 29 digits)92
f(1740)=19(ommit 360 digits)80
f(20748)=53(ommit 4332 digits)76
f(248844)=93(ommit 52001 digits)08

$ ruby fibo.rb 34 25
f(26)=12(ommit 2 digits)93
f(59)=95(ommit 8 digits)41
f(1181)=29(ommit 243 digits)81
f(39329)=84(ommit 8215 digits)29

$ ruby fibo.rb 99 99
f(100)=35(ommit 17 digits)75
f(198)=10(ommit 38 digits)24
f(9900)=42(ommit 2065 digits)00

$ ruby fibo.rb 2 0
f(1)=1
f(2)=1
f(4)=3
f(8)=21
f(16)=987
f(32)=21(ommit 3 digits)09
f(64)=10(ommit 10 digits)23
f(128)=25(ommit 23 digits)61
f(256)=14(ommit 50 digits)67
f(512)=44(ommit 103 digits)69
f(1024)=45(ommit 210 digits)43
f(2048)=45(ommit 424 digits)01
f(4096)=46(ommit 852 digits)47
f(8192)=47(ommit 1708 digits)29
f(16384)=50(ommit 3420 digits)63
f(32768)=57(ommit 6844 digits)41
f(65536)=73(ommit 13692 digits)27
f(131072)=11(ommit 27389 digits)89
```

鍋谷さんの実行例より、一桁以上少ない。

#そもそも

```ruby
tm = Time.now

s, t = 0, 1
1000000.times do
  s, t = t, s + t
end

puts Time.now - tm    #=>10.713040801
```

これで10秒以上かかってしまう。うーむ。
いいやり方、ありますかね。
SQLServerのバックアップをAmazon S3に保存する

#はじめに
こんにちは、山田です。今年の目標として、学んだこと実装したことを記事に書いていきたいと思います。
今回は、現在関わらせていただいている案件でSQLServerのバックアップをS３に保存を実装したので、その手順について記載していこうと思います。
よろしくお願いいたします。

#構成図
今回使用するAWSリソースは下記の通りです。

|AWSリソース|個数|
|---|---|
|VPC|1|
|Subnet|2|
|Internet Gateway(IGW)|1|
|EC2|1|
|RDS(SQLServer)|1|
|S3|1|

全体構成図は下記の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/fe4b60ca-57d6-a93e-3a16-bc9279ebab09.png)
① Internet Gateway(IGW)を介して、PublicSubnetに配置しているEC2にログインする。
②「SQL Server Management Studio」を使用して、EC2からRDSにログインする。
③ S3にバックアップを作成するクエリを実行する。

#手順
下記よりSQLServerからS3にバックアップを取得する手順を記載していきます。

##前提条件
VPC、Subnet、InternetGateway、EC2、RDS、S3に関しては作成済みとする。

##オプショングループの作成
① AWS管理コンソール->RDS->オプショングループの作成->グループを作成をクリックする。
② 以下の設定項目を設定する。
  自分の場合は、「SQL Server Express Edition」を使用したので、エンジンは「sqlserver-ex」を選択しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/935cefe0-23ab-8e97-f921-8714bc568fcb.png)
##オプションの追加
① オプション名は「SQLSERVER_BACKUP_RESTORE」を選択する。
② IAMロールは、既存のロールを選択せずに「新しいロールの作成」を選択する。
③ S3送信先は、SQLServerのデータバックアップ保存用に作成したS3を指定する。
④ スケジューリングは「今すぐ」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/3b8409aa-b421-2b08-f9cb-3f23dd28e0cb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/5ea29466-5726-5e96-12aa-f733a4d326f9.png)

##RDSの設定変更
① AWS管理コンソール->RDS＞データベース->バックアップを保存したいSQLServerを選択->「変更」をクリック
② 追加設定の項目で、オプショングループを新しく作成したオプショングループに変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/0be773d9-e202-dcd0-4ded-6f124875b4c5.png)

##SQLManagementStudioのダウンロード
① EC2にログインする。
② 下記URLより、「SQLManagementStudio」をダウンロードする。

https://www.microsoft.com/en-us/download/details.aspx?id=42299

##RDSにログイン
① 「SQLManagementStudio」を起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/c032a73a-4259-b0e1-7b76-9504e2c4748e.png)
② 以下の画面が表示されるので、それぞれの項目を入力してログインする。

|項目名|入力値|
|---|---|
|Server type|Database Engine|
|Server name|RDSエンドポイント名|
|Authentication|SQL Server Authentication|
|Login|RDS作成時に設定したマスターユーザー名|
|Password|RDS作成時に設定したマスターパスワード|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/7152ea49-121f-d369-629c-929d64f9d96e.png)

##クエリの実行
① ログイン後以下の画面が表示されるので、「New Query」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/d2655cc1-8a0e-d1a0-60ce-a04957302ffd.png)
② クエリ文を入力して、「Execute」をクリックしてクエリを実行する。
　基本的な構文は、以下の通りです。

```
exec msdb.dbo.rds_backup_database
　　 @source_db_name='<db 名>',
　　 @s3_arn_to_backup_to='arn:aws:s3:::<バケット名>/<バックアップファイル名>',
     @overwrite_S3_backup_file=1;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/ffffee0b-ef3c-b12c-7107-fd2ae400e6a1.png)
③ 指定したS3にバックアップファイルが保存されていれば完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/6f99dca0-2002-b988-7b64-cfe1b9fd375f.png)
【ABC234】 B - Longest SegmentをC++で解説

#はじめに
　皆さんこんにちは！ 競プロの問題の理解を深めるために解説記事を書いていこうと思います！今回は **ABC234 B** です！

 気に入っていただけたら**LGTM**して頂けるとうれしいです！

何かあれば**コメント**や[Twitter](https://twitter.com/python05238919)からお願いいたします!
#[B - Longest Segment](https://atcoder.jp/contests/abc234/tasks/abc234_b)
####問題概要
 $N$個の座標$(x_i, y_i)$における$2$個の線分の長さの最大値を求めよ．

####制約
・$2 \leq N \leq 100$ 
・$ -1000 \leq x_i, y_i \leq 1000$
・$(x_i, y_i) \not= (x_j, y_j) (i \not= j)$
・入力はすべて整数
##考察
####ポイント
　**全探索しましょう**
####解説
 制約が小さいので，各座標ごとに線分の値を求めます．
　全探索することで最大値を更新していきましょう．
　線分の距離$L$の式は
   $ L = \sqrt{(x_i - x_j)^2 + (y_i - y_j)^2}, (i \not= j) $
　で求められます．
#実装
　答えは**小数を含む**ので`long double`で宣言しましょう．全探索は2重ループで実装できます．

##正解コード

```C++:
#include <bits/stdc++.h>
using namespace std;

int main()
{
    //入力
    int N;
    cin >> N;
    vector<int> x(N), y(N);
    for(int i = 0; i < N; i++){
        cin >> x[i] >> y[i];
    }
    
    //答えの宣言
    long double ans = -1.0;

    //全探索
    for(int i = 0; i < N; i++){
        for(int j = i + 1; j < N; j++){
            long double dis = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
            if(dis > ans) ans = dis; //今までの最大値より線分が大きい場合は値を更新する．
        }
    }

    //出力
    cout << setprecision(10)<< ans << endl;
}

```
【Ruby】処理に名前をつけて使おう② calculate_price_with_taxメソッド

※初心者向け
※アウトプット練習の為

開発環境
rails 6.1.4.1
ruby 2.6.5

##問題内容##
以下のプログラムを実行するとエラーが起きます。
①エラーが起きた原因
②正しいソースコード（引数を用いたコードにしましょう）
をそれぞれ答えてください。
**実行したプログラム**

```ruby
price = 300

def calculate_price_with_tax
  tax = 0.1
  puts price + price * tax
end

calculate_price_with_tax

```

##解答##
**①エラーが起きた原因**
メソッドの外側で定義した変数は、メソッドの内側では使えない。そのため、1行目のpriceはcalculate_price_with_taxメソッドの中では使えずにエラーが起きる。

**②正しいソースコード**

```ruby
price = 300

def calculate_price_with_tax(price)
  tax = 0.1
  puts price + price * tax
end

calculate_price_with_tax(price)

```

##解説##
メソッドの中と外は完全に別の世界となっています。そのため、メソッドの中から外にある変数を使ったり、逆にメソッドの外から中にある値を使うことはできません。

唯一、メソッドの中と外を繋ぐ役割が**「引数」** と **「返り値」**です。

それを踏まえて今回の問題を解説していきます。

**①エラーが起きた原因**
解答の通り、エラーが起きた原因は変数priceです。今回の問題文のソースコードには変数priceが2度出てきます。

メソッドの外にある1行目のprice = 300と、メソッドの中にある5行目のprice + price * taxです。

**問題有のソースコード**

```ruby
price = 300

def calculate_price_with_tax
  tax = 0.1
  puts price + price * tax
end
```

メソッドの中では、メソッドの外の変数を使うことができません（変数の使える範囲をスコープと言います）。

よって今回の問題文のソースコードでは、変数priceの定義はメソッドの外で行なっていたにも関わらず、メソッドの中で変数priceをそのまま使おうとしたことがエラーの原因でした。

**②正しいソースコード**

スコープの問題を解決するのが、メソッドの中と外を繋ぐ役割を持つ**「引数」** と **「返り値」** です。
**①メソッドの外から中に値を渡す役割が「引数」**
**②メソッドの中から外に値を渡す役割が「返り値」**

今回は、メソッドの外から中に変数priceを渡すことで問題は解決します。つまり、解決に必要なのは①の**「引数」** です。

引数の使い方は大きく2ステップです。
**1.メソッドの呼び出しをメソッド名(渡したい値)と書く**
**2.メソッドの定義をdef メソッド名(受け取った値を入れる変数名)と書く**
では今回の問題に当てはめてみましょう。

**1. メソッドの呼び出しをメソッド名(渡したい値)と書く**
今回、calculate_price_with_taxメソッドに渡したい値は変数priceなので、以下のようにメソッドを呼び出します。

```ruby
calculate_price_with_tax(price)
```
**2. メソッドの定義をdef メソッド名(受け取った値を入れる変数名)と書く**
今回は値段の値を受け取りたいので、変数名はpriceにします。今回はメソッドの外の変数名priceと一緒ですが、別の名前にしても大丈夫です。

```ruby
def calculate_price_with_tax(price)
  tax = 0.1
  puts price + price * tax
end
```
よって引数を使って以下のように書き換えれば、問題文のソースコードのエラーは解決します。

```ruby
price = 300

def calculate_price_with_tax(price)
  tax = 0.1
  puts price + price * tax
end

calculate_price_with_tax(price)
```
【VS Code】JavaScriptのconsole.logをコンソール画面に出力する方法

本記事では、JSのconsole.logを、VS Codeのコンソール画面に出力する方法を紹介します。

# 環境情報
OS：Windows 10
VS Codeのバージョン：1.63.2

# 手順

以下の手順を行うことで、コンソール画面にconsole.logの内容を出力できます。
①Live Preview拡張機能インストール
②Live Previewの設定変更

## ①Live Previewインストール

Live Preview拡張機能をインストールします。
以下記事の「インストール」セクションに、インストール方法が記載されているので、そちらを参照ください。
https://creating-homepage.com/archives/8616#sec2


## ②Live Previewの設定変更

Live Previewのインストールが完了した後、Live Previewの設定をいくつか変更します。
・変更する設定
　　Auto Refresh Preview
　　Debug On External Preview
　　Open Preview Target

Ctrl + 「,」キーでVS Codeの設定画面を開き、拡張機能 → Live Previewを開きます。
こちらの画面で、↑に挙げたLive Preview3項目の設定を変更します。
![2022-01-09_14h56_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/c54e99dc-1eaa-b7c9-e92b-dd0e0e3a92fa.png)


・Auto Refresh Preview

Auto Refresh Preview を「Never」に設定します。
※Auto Refresh Previewとは
　プレビューを自動的に更新する頻度を設定する項目
　Neverに設定すると、ブラウザーの自動更新を無効にする（更新ボタンを押さない限り、ブラウザが更新されない）
![2022-01-09_15h04_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/13ab84d4-5dcd-a53e-4fac-f84880fbdd82.png)




・Debug On External Preview
Debug On External Previewにチェックを入れます。
※Debug On External Previewとは
　外部プレビュー起動時にJavaScripitデバッガーを有効化
![2022-01-09_15h07_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/e74e5044-9ec9-4720-9d2f-7326c7ed018b.png)


・Open Preview Target
 Open Preview Targetを External Browserに設定します。
※Open Preview Targetとは
　プレビューを、埋め込みプレビューor外部プレビューにするかを設定
　外部プレビューに設定するので、External Browserを選択します
![2022-01-09_15h10_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/6387023f-4e35-30c4-ef94-c767fb020bcd.png)

# 検証

VS Codeのコンソール画面にconsole.logが出力されるか検証します。
## 使用するhtml、js
検証で使用するhtmlとjsファイルは以下です。
htmlファイルからjsファイルを呼び出します。

```ruby:index.html
<!DOCTYPE html>
<html>

<head>
	<title>Console Test</title>
	<meta charset="UTF-8" />
</head>

<body>
	<script src="consoletest.js">
	</script>
	<p>コンソール出力テスト</p>
</body>
</html>
```

```ruby:consoletest.js
console.log('コンソールに出力されるか確認');
```

使用するhtmlファイルをVS Codeに表示します。
htmlファイルを表示したら、画面右のボタン（下図赤枠）をクリックします。
![2022-01-09_15h16_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/e7fd0cba-ca50-b5d4-7e02-0267bd19fccc.png)


すると、ブラウザが起動し、ブラウザ画面にhtmlファイルが表示されます。
このとき、VS Codeのデバッグコンソール画面に、jsファイルに記載したconsole.logの内容が出力されます。
![2022-01-09_15h17_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485934/8480803e-c007-9d38-9cab-49305b5b7e87.png)


#参考記事

Live Previewインストール：https://creating-homepage.com/archives/8616#sec2
Live Previewでconsole.logをVS Codeのコンソールに出力：https://creating-homepage.com/archives/9003
MacからのSSH接続でWARNING: UNPROTECTED PRIVATE KEY FILE!と表記されてEC2にログインできない！

#エラー内容

AWSで新しくEC2、キーペアを作成。
仮想サーバにSSHでアクセス、ログインしようとするが、

```terminal
ssh -i ~.pem ec2-user@~（EC2のIPアドレス）
```

以下のエラーが表示された。

```terminal
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '~.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "~.pem": bad permissions
ec2-user@~（EC2のIPアドレス）: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

作成したキーファイルは使用できない？
Macからだと権限の問題でエラーになると聞いたような...

#原因
Macでダウンロードしたキーファイルを使い、SSHしようとするとはじかれます。
ファイルの権限が緩すぎるのが原因。
秘密鍵は、他のユーザからアクセスできる権限では使用できないらしい。
つまり、秘密鍵が安全でない場合に発生するエラー。
所有者のみ読み書きできる権限にする必要がある。

#対処方法

#####①lsコマンドでキーファイルの権限（パーミッション）を確認してみる。

```terminal
ls -l
-rw-r--r--@  1 ~  ~     1700  1  9 14:08 ~.pem
```

キーファイルの権限が644になっていることが確認できた。
所有者以外も読み込み可になっている...
そうなると、設定すべき権限は所有者のみ読み書き可能。

#####②権限変更なのでchmodコマンドを使用。

```terminal
chmod 600 ~.pem
```

#####③権限を変更することで、キーファイルを使用し、SSH接続が可能になります。

```terminal
ssh -i ~.pem ec2-user@~（EC2のIPアドレス）
```

#####④これにて接続可能になりました！


       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

#参考

https://umebius.com/dev/permissions-0644-for-xxx-key-are-too-open-%E6%A8%A9%E9%99%90%E3%82%92%E3%81%A9%E3%81%86%E3%81%99%E3%82%8C%E3%81%B0%E3%81%84%E3%81%84%EF%BC%9F/

https://akizora.tech/ec2-pem-too-open-3734
C言語でドット絵を作る・動かす

#はじめに
この記事はC言語初心者の主がVisualStudio2019を使い作ったものです。
文章が下手なところ、初心者でコードがおかしいところもありますが、よろしくお願いします。
#完成品
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2302296/5ab9abc4-0e49-392a-04b2-03e729fa44f2.gif)
少し見づらいですがドット絵のキャラクターを出して横に動かすというコードを作りました。
#解説色付け編
![mario.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2302296/0a4d97d8-103b-bc63-a980-1a74c8c34f55.png)
全体画像はこんな感じで、色がついているところを「■」として色がついていないところを「□」としています。
色付けの方法ですが、

```
printf("\x1b[31m");
	printf("■ ■ ■ ■ ■");//見やすくするためにスペースを入れてますが本当は入れないです
```
\x1b[31mについては詳しくはこのページを](https://www.serendip.ws/archives/4635)
簡単に言いますと、\x1bはESCの16進表記のことで[31mは色を表しています。
これで色を付けました、次は上から順に表示する方法と動かす方法です。
#解説表示編
表示にはmillisecondとsleep関数を使っています。

```
#include<stdio.h>
#include<Windows.h>
int main()
{
	int millisecond = 1 * 75;
    Sleep(millisecond);//1行目
	printf("□□□□□□□□□□□□□□□□□□□□\n");
```

と書いており、ミリ秒単位で処理を止めることができます。
[「Sleep関数を使ってミリ秒単位で止める方法」を参照](https://www.sejuku.net/blog/48301)
今回は1×75ミリ秒処理を止めて1行表示し、また1×75ミリ秒処理を止めて1行表示してを20行やっています。
キャラクターを移動させる方法です。

```
Sleep(millisecond);
	system("cls");
	printf("□□□□□□□□□□□□□□□□□□□□\n");//1行目
```

Sleep関数で処理を止め、system("cls")で四角をすべて消してprintfでふた四角分動かしたものを表示します。
これの繰り返しであのように横に動いてる感じになります。
#小話
作った感想としては1行ずつ、数四角ずつで色付けをしたりしていたのですごく大変でした。
後はgifには載せきれませんでしたがこの作品はfor文を使い無限ループにしています。
行数としては5000行を超えました。
windowsでiverilog その128

#概要　

windowsでiverilogやってみた。
j1と言うcpuは、gforthのp-codeを実行するらしい、調べてみた。

#cpuの特徴

- スタックマシーン
- 16bit
- メモリー　16k
- データスタック　３２
- リターンスタック　３２



#命令コード

|Opcode|	15|	14|	13|	12|	11|	10|	9|	8|	7|	6|	5|	4|	3|	2|	1|	0|
|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|:--|
|literal|1||||||||||||||
|jump|0|0|0||||||||||||
|cond jump|0|0|1||||||||||||
|call|0|1|0||||||||||||
|T|0|1|1||0|0|0|0|||||||
|N|0|1|1||0|0|0|1|||||||
|T+N|0|1|1||0|0|1|0|||||||
|T&N|0|1|1||0|0|1|1|||||||
|`T	N`|0|1|1||0|1|0|0|||||||
|T^N|0|1|1||0|1|0|1|||||||
|~T|0|1|1||0|1|1|0|||||||
|T==N|0|1|1||0|1|1|1|||||||
|T>N|0|1|1||1|0|0|0|||||||
|N>>T|0|1|1||1|0|0|1|||||||
|N<<T|0|1|1||1|0|1|0|||||||
|R->T|0|1|1||1|0|1|1|||||||
|[T]|0|1|1||1|1|0|0|||||||
|io[T]|0|1|1||1|1|0|1|||||||
|depth|0|1|1||1|1|1|0|||||||
|T>Nu|0|1|1||1|1|1|1|||||||



以上。
【Python】conda list を pip freeze のような出力形式にする

### はじめに
`Python` で Web アプリをデプロイする際に、
`Django` や `Flask` で Web アプリ開発を行い `Heroku` にデプロイしたりすることが多いと思います。

このとき、`conda` でライブラリのインストールをしていることがあると思います。
デプロイのため、`requirements.txt` にライブラリを記載することになりますが、
`pip` の場合は、 `pip freeze > requirements.txt` で簡単にインストール済みのライブラリ一覧を作成できます。
`conda` の場合は、 `conda list -e > requirements.txt` とすると、ライブラリの一覧は作成できますが、`{ライブラリ名}=={バージョン}`の形式に毎回変更しなければならず、少し面倒です。

`bash` であれば `awk` や `sed` コマンドが使えるので、正規表現と組み合わせて、 `pip freeze` の出力形式に近い形で出力できるようにしてみます。

---

### awk, sed を利用した conda ライブラリ一覧の出力
```bash
conda list -e | awk -F'=' '{print $1,"==",$2}' | sed 's/ //g' | sed '/^#/d' > requirements.txt
```

このコマンドは、`bash, zsh` などで動作します。 `powershell` では動作しないので気をつけてください。
おおかた `pip freeze` と同じような出力形式で `conda` のライブラリ一覧を出力できると思いますので、`requirements.txt` の作成が楽になると思います。

---

### さいごに
上記のコマンドよりも良いやり方はあると思います。
正規表現は、さまざまな場面で使えそうだと思いました。
Oracle ADBへアクセス

## はじめに
本記事はADBにアクセスする前提のクライアントインストールから行う

### Oracle SQL Developerインストール
sql plusの方が軽量で、アクセスだけで考えればそちらでもよかったのだが、色々機能があって面白そうだったのでこちらを選択

古いけどチュートリアル付きの記事もあった。
https://blogs.oracle.com/oracle4engineer/post/sql-developerdbsql

#### ダウンロード
https://www.oracle.com/jp/tools/downloads/sqldev-downloads.html

本記事ではOracle SQL Developer 21.2.1のWindows 64-bit with JDK 8 includedをダウンロード
なおダウンロードにはOracle.com のユーザー登録（無料）が必要

#### 実行
ダウンロードしたファイルを解凍してexeを実行
インストールは不要みたいで起動完了

### ADBへアクセス
クライアントの準備が出来たので、ADBにアクセスをしてみる

下記のチュートリアルを参考に実施
https://oracle-japan.github.io/ocitutorials/database/adb104-connect-using-wallet/

#### ウォレットのダウンロード

- インスタンス・ウォレット: 単一データベース専用のウォレット。データベース固有のウォレットを提供します。

- リージョナル・ウォレット: 特定のテナントおよびリージョンのすべてのAutonomous Databaseのウォレット(クラウド・アカウントが所有するすべてのサービス・インスタンスを含む)。

使い分けとしてアプリケーションからのアクセスはインスタンス・ウォレットが推奨されている。
リージョナル・ウォレットは管理目的での使用に絞ったほうがよさそうだ。

特に難しい設定はなく下記を入力するだけでアクセスできた
- Name
- ユーザー名
- パスワード(保存もチェックしておいたほうが楽)
- 接続タイプ：クラウド・ウォレット
- 構成ファイル：ダウンロードしたウォレット


また下記のチュートリアルでatabase Actionsを使用したアクセスが載っている
https://oracle-japan.github.io/ocitutorials/database/adb101-provisioning/#anchor2


よくある質問もありがたい

```
OCPU=1でパラレル処理されるの？？

OCPU=1の場合はパラレル処理されないため、より高い性能を求めたい場合は2以上を選択するようにしてください。
パラレル処理とは、Oracle DatabaseのEnterprise Editionの機能であり、ひとつのDDL/DML/Query文を複数のCPUコアを利用して高速に処理させることです。
特に大量データを扱うようなDWHやバッチ処理には有効です。
尚、Autonomous Database はOCPU数を増やすことでコア数、メモリ数、IO帯域が増えます。
また、OCPU増はコストに跳ね返ってきますが、OCPUはオンラインでスケールアップ・ダウンが可能なので、週末・夜間など使わないタイミングはコア数を減らすことでコストを削減できます。

```

ほかにもCloud Shellを使用しても簡単にアクセスできる。


### AutoMLを触ってみる
【Swift】【Firestore】Firestore.Encoder().encode() で nil の key が消えない様にする

GitHub の [gg-mark/NullCodable](https://github.com/g-mark/NullCodable) にある [NullCodable.swift](https://github.com/g-mark/NullCodable/blob/master/Sources/NullCodable/NullCodable.swift) をコピーしておき、 encode したい構造体の Optional 型のプロパティに ``@NullCodable``という propertyWrapper を付ければ消えない様になります。

**例**

```swift
import FirebaseFirestore

struct Data: Codable {
    var a: Int? = nil
    @NullCodable var b: Int? = nil
}

let data = Data()
let encodedData = Firestore.Encoder().encode(data)
print(encodedData)
```

```
["b": <null>]
```

``NullCodable`` がない ``a`` は消えて、
``NullCodable`` をつけた ``b`` は残っている。

**参考**
[Codableでnullが消えてしまう問題に対応する _ えいむーさんは明日も頑張るよ](https://tkgstrator.work/2021/11/21/nullcodable)
Redux Toolkit の store.ts をちゃんと理解する

 [Redux Toolkit Quick Start](https://redux-toolkit.js.org/tutorials/quick-start)を読みながら、Redux Toolkitを学習しているのですが、最初の store.ts の部分から、わからないところがあったので自分なりに調べてみました。


***
### ReturnTypeとは何なのか？

**app/store.ts**

```react
import { configureStore } from '@reduxjs/toolkit'

export const store = configureStore({
  reducer: {},
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
```

　
ReturnTypesについては、[【TypeScript】Utility TypesのReturnTypeを深く理解する](https://qiita.com/NOMURA_keibyou38/items/fc9d21aee217b4213430) では、以下のように説明されています。
 > ReturnTypeは、関数の戻り値の型から新たな型を生成します。

また、[公式サイト](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype)を読むかぎり、ReturnTypesはTypeScriptの機能の一つのようです（Redux Toolkitの機能ではなかった!）。

<br/>
**ReturnTypesの使用例**

[公式サイト](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype)より

```typescript
declare function f1(): { a: number; b: string };
 
type T0 = ReturnType<() => string>;  
// type T0 = string

type T1 = ReturnType<(s: string) => void>;     
// type T1 = void

type T2 = ReturnType<<T>() => T>;
// type T2 = unknown

type T3 = ReturnType<<T extends U, U extends number[]>() => T>;
// type T3 = number[]

type T4 = ReturnType<typeof f1>;
/*     
type T4 = {
    a: number;
    b: string;
}
*/
```
<br/>
したがって、上記の`export type RootState = ReturnType<typeof store.getState>`は、

「storeコンポーネントに含まれる関数getStateの戻り値の型から、新しい型を作る」といった働きをします。

<br/>

***
### `export type AppDispatch`では何をしているの？



`export type AppDispatch = typeof store.dispatch`では、

 	1. `typeof store.dispatch`の部分で、ストアからDispatchの型を抽出
 	2. 抽出した型に対して`AppDispatch`という名前（エイリアス）をつける
 	3. 他のコンポーネントでも利用できるように`AppDispatch`をエクスポートする

といったことを行なっています。

<br/>

***

### 参考

https://redux-toolkit.js.org/tutorials/quick-start
[【TypeScript】Utility TypesのReturnTypeを深く理解する](https://qiita.com/NOMURA_keibyou38/items/fc9d21aee217b4213430)
https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype
https://redux-toolkit.js.org/usage/usage-with-typescript#using-the-extracted-dispatch-type-with-react-redux
【VScode】マインドマップ

# プラグイン
![【VScode】マインドマップ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/282d985d-2bf1-d27e-059a-bf42d56e42b6.png)

# 参考文献
https://iucstscui.hatenablog.com/entry/2021/04/09/234658
Heroku + MySQL + Rails6.0でstaging環境を用意する。

## 背景
個人アプリを開発していて、現状はローカル環境と本番環境しか用意していなかった。
本来であればstaging環境で確認後、本番環境にデプロイする流れが望ましいため、staging環境を準備することにした。

## 前提
- Herokuで本番環境が用意できている。

## 手順

### staging環境の作成

```
heroku create --remote staging
```

これでstaging環境が作成される。

#### 参考記事

https://devcenter.heroku.com/ja/articles/multiple-environments

### 本番環境の環境変数をインポート + stagingの環境変数にセットする。

```
heroku config -s -a "本番環境のアプリ名" > envvars.txt
cat envvars.txt | tr '\n' ' ' | xargs heroku config:set -a "staging環境のアプリ名"
```

`CLEARDB_DATABASE_URL、DATABASE_URL、DB_NAME、DB_USERNAME、DB_PASSWORD、DB_HOSTNAME`もコピーしてしまっているが、そちらは削除しておく。

#### 参考記事

https://uros-randelovic.medium.com/how-to-copy-environment-variables-from-one-heroku-app-to-another-ac04f390f212

#### `cat envvars.txt | tr '\n' ' ' | xargs`の解説

`cat envvars.txt`でインポートした本番環境の環境変数のファイルを出力する。
`tr '\n' ' '`でennvars.txtの改行部分を空白に置換する。
`xargs`コマンドで`cat envvars.txt | tr '\n' ' '`の結果を受け取って、次のコマンドの引数に渡してくれる。

##### 参考記事

https://techblog.kyamanak.com/entry/2018/02/12/202256

https://atmarkit.itmedia.co.jp/ait/articles/1610/03/news017.html

https://eng-entrance.com/linux_command_cat

### MySQLアドオンを追加する。 + stagingの環境変数の修正

```
heroku addons:create cleardb:ignite --remote staging
```


`CLEARDB_DATABASE_URL`から、
`DATABASE_URL、DB_NAME、DB_USERNAME、DB_PASSWORD、DB_HOSTNAME`の環境変数をセットする。

```
例： heroku config:set DB_NAME=xxxx --remote staging
```

`RAILS_ENV`と`RACK_ENV`をstagingに変更する。

```
heroku config:add RACK_ENV=staging --remote staging
heroku config:add RAILS_ENV=staging --remote staging
```

### staging.rbを用意する。
```
cp config/environments/production.rb config/environments/staging.rb
```

```staging.rb
# 下記のように修正
config.action_mailer.default_url_options = { protocol: 'https', host: 'stagingのアプリ名' }
```


### staging環境にデプロイする。

```
git push staging master
```

### staging環境のDBを作成する。

```
heroku run rake db:migrate --remote staging
```

### staging環境のアプリ名を変更する。

```
heroku apps:rename "変更したいアプリ名" --remote staging
```
#### 参考記事

https://devcenter.heroku.com/articles/renaming-apps#updating-git-remotes

以上で完了。

## 最後に
今回は取り急ぎstaging環境を用意することだけを行ったが、今後は

- プルリクを出したら自動的にstaging環境にデプロイされるようにする。
- 本番環境のデータと1日おきに同期する。

などといったことにも挑戦していきたい。
Wolfram Cloudの結果をコードに貼り付けたい - AtCoder ABC A234  - Weird Function

結論: CFormを使うと楽になる場合が多い

$f(x)=x^2+2x+3$のとき、$f(f(f(t)+t)+f(f(t)))$をもとめよ。の式を展開したいとします。
(この問題では不要ですが)Alphaなどに投げて式を簡略化した後に式をコピペしたいことが稀にあります。
この時に結果をコピペしようとすると一工夫必要です。CFormを使いましょう。

# AlphaではなくWolfram Cloudを使う
Wolfram Alphaは、例えば、f(x) = xのように、よく見る形式で書け、便利です。Wolfram言語だとこれは`f[x_] := x`などになり、覚えるのが面倒です。

dでも、Mathematicaの機能をフルに活用したい場合、(また、Mathematicaの多大なナレッジを使えるという意味で)Wolfram Cloudは便利です。Wolfram Cloudは個人の一般的な範囲でしたら、無償で使うことができます。
https://support.wolfram.com/ja/49795

# Wolfram Cloudのを使う
- https://www.wolframcloud.com/ からログインします。ユーザ登録が必要です
- 計算して結果を表示、はShift+Enterです。
- 言語上は`(`の代わりに`[`が使われると思ってください(式自身を書くときはこの限りではないです)

# 今回の式を解く
- `f[x_]:= x ^2  +2x+3`で式を定義します
- `Expand[f[f[f[t]+t]+f[f[t]]], t]`で式をtについて解きます。この結果、以下のようになり、良さそうに思えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/6c6fc6ba-fdfd-523e-f407-782e4f1aa799.png)
- しかし、コピペすると、 `1371+2960 t+3746 SuperscriptBox["t", "2"]+3060 ...`のように、そのままコピペできない形式になります。ここで、次の関数を使うとやりやすいです。
    - FullSimplify: よく見る式の形にします
    - CForm: C言語の形にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/865416b3-63bd-e3b9-037f-24d0739f02c8.png)
- CFormを見ると、powがPowerになっていて、そのままコンパイルできません。define Power powしてもいいですが、<b>今回は</b>、FullSimplifyを併用するとそのままコピペできます。(%は前に実行した結果を参照する、です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/0bca226c-67c6-6138-953f-3ca20ec57fac.png)

- ただ、FullSimplifyしても、そのままコピペは無理なこともあります。defineしたり、しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30938/1751ce31-f938-98fe-3014-643028fec824.png)
<font color=red>なお、Powerなどは、Mathematicaに付属のmdefs.hをincludeすればそのまま使えます</font>

# 投げる

```Python
t = int(input())
print(1371+t*(40+t*(29+2*t*(5+t)))*(74+t*(40+t*(29+2*t*(5+t)))))
```
[まとめ] MPS法解説シリーズ

# はじめに
　一般的な流体シミュレーションでは空間をグリッドに分割して流体を表現します．これを「格子法」と呼びます．
　一方，流体を粒子で表現しようとするのが「粒子法」です．粒子法はSPH法とMPS法に大別されます．

![スクリーンショット 2022-01-09 143040.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480220/6eb094c1-fa7b-9b4a-23e7-92b74ddc0350.png)

　粒子法にはいろんなメリットがあります（[こちら](https://www.particleworks.com/mps_particlebasedmethod_ja.html)のサイトで詳しく説明されています）．

　このシリーズでは，MPS法の理論を体系的に解説することを目的とします．ターゲットは「流体力学の数値計算について大まかにご存じで，MPS法に興味を持ってる方」です．

# MPS法の基礎理論（一部作成中）
・[重み関数と粒子数密度](2022-01-13_b17de4144fe800d1ae53.md)
・[勾配モデルと発散モデル](2022-01-07_7fc6f0e1f8ac2ec813f1.md)
・[ラプラシアンモデル](2022-01-08_3dfbf0f068a1f4b73ff3.md)
・[計算アルゴリズムと圧力のポアソン方程式](2022-01-09_19c6ffb74522af0a5a1b.md)
・安定性条件
・自由表面境界条件
・壁面境界
・解像度可変型粒子法

# 高精度化手法（作成中）
## 高精度微分演算モデル
・CMPS法（運動量・角運動量保存型）
・HL（数学的一貫型）
・GC，LSMPS法（テイラー級数適合型）
・DS法（引張安定型）
## 高精度ポアソン方程式
・HS
・ECS
## 高精度境界条件
・SPP（自由表面境界条件）
・WPP（壁面境界条件）

#参考文献
・[粒子法（越塚先生）](https://www.maruzen-publishing.co.jp/item/?book_no=293175)
・[粒子法入門](https://www.maruzen-publishing.co.jp/item/b294791.html)
・[粒子法（後藤先生）](https://www.morikita.co.jp/books/mid/092231)

# 数式の表記ルール
　このシリーズで用いる数式の表記法について記しておきます．各記事では述べないつもりなので，気になったらこちらを参照ください．例としてスカラー $\phi$ の勾配モデルを用います．

`math
\langle\boldsymbol{\nabla}\phi\rangle_i=\frac{d}{n^0}\sum_{j\ne i}\frac{\phi_{ij}}{|\boldsymbol{r}_{ij}|^2}\boldsymbol{r}_{ij}w_{ij}
`
|表記|意味|
|:--:|:--|
|$\langle\alpha\rangle$|$\alpha$ を離散化した値|
|$\alpha_i$|粒子 $i$ の位置の $\alpha$|
|$\alpha_{ij}$|粒子 $i$ と粒子 $j$ の位置の $\alpha$ の差分 $\alpha_j-\alpha_i$|
|$\alpha^0$|$\alpha$ の基準値|
|$\alpha^k$|第 $k$ ステップの $\alpha$|
|$d$|空間の次元数|
|$n$|粒子数密度|
|$w$|重み関数|

 なお，このルールに従うと粒子 $i$ と粒子 $j$ の間の重み関数は $w(|\boldsymbol{r}\_{ij}|)$ と表されますが，メンドウなので $w_{ij}$ と表すことにします．すなわち，添え字の $ij$ は「粒子 $i$ と粒子 $j$ の間の」を表すこともあります．
【Xcode de AtCoder】stderrのすすめ

# はじめに

この記事で伝えたいことは、「Xcode環境でAtCoderの解答コードをテストするときに、stderr（標準エラー出力）に出力することによる副次的な効果について」です。


# 1. stderrへの出力方法

ご存知の方が大半でしょうが、まず、Swiftにてstderrへ出力する方法を説明します。
私は普段、下記のメソッドを使用しています。

```swift:
func printErr(_ str: String, terminator: String = "\n") {
    let string = str + terminator
    FileHandle.standardError.write(string.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}
```

引数は文字列と区切り文字です。文字列を一つしか指定できませんので、文字列補間（やString:format:）で一つの文字列にして渡します。区切り文字のデフォルトは`改行`。


# 2. 最初にstderrに出力する

AtCoderのプログラムでは、入力情報を標準入力(stdin)から読み込むことから始めるのが普通だと思いますが、その前にstderrに**Ready!**(例)を出力します。

これによる副次的効果としては、次の2点。

## 2.1 副次的効果（その一）：コンソールが自動的に開く

Xcodeにてプログラムを実行するには`⌘R`(command+R)、実行中のプログラムを中止するには`⌘.`(command+period)のショートカットで操作します（もしくはメニュー操作で）。

実行したプログラムが標準入力からの入力を待っている場合、Xcodeのコンソールを開いて入力を与えるのですが、前回`⌘.`でプログラムを中断した場合、コンソールが閉じてしまっているので、`⇧⌘C`(shift+command+C)で再びコンソールを開いてやる必要があり、これが不便でした。
しかし、最初にstderrに出力することによって、コンソールが自動的に開きstderrの情報が出力されるようになります。
この挙動をつい最近発見して「これまでの無駄は何だったのだろう！」と思うほど便利になりました。

例として、3つの整数A,B,Cを入力し$A+B*C$の結果を出力するプログラムは以下のようなコードになります。

```swift:A+B*C
printErr("Ready!")
let (a, b, c) = listOfInt().toTupple()
let ans = a + b * c
print(ans)
```

> listOfInt()やtoTupple()は、巻末の参考記事をご参照ください。


## 2.2 副次的効果（その二）：入力待ちのタイミングが分かる

最初にstderrに出力することで、ビルドが完了しプログラムが起動され入力待ちになったタイミングが分かるようになりました。こう書くと当然のことなんですが・・・。

コンソールが開いているときにstderrに出力しない場合は、この入力待ちのタイミングが分からず、コンソールに入力情報を`⌘V`(command+V：貼り付け)しても結果が出ずやり直すことがありました（やり直しは`⌘.`して`⌘R`）。つまりプログラムが起動されてもまだ入力待ちになっていないタイミングで`⌘V`してもコンソールには貼り付いてもプログラムの入力には渡っておらず、入力を待ち続けるので結果が出てこない訳です。簡単にいうと`⌘R`後の`⌘V`が早すぎたということです。（コンソールが閉じている場合は、コンソールを`⇧⌘C`で開いてから`⌘V`と操作するのでタイミングのずれは起きにくい）

いまは**Ready!**と出たら`⌘V`すれば良いので、このずれをまったく気にする必要がなくなりました。





# 3. stderrはAtCoderのオンラインジャッジに影響しない

ループ途中の変数情報などをstderrに出力しても[**AC**](https://atcoder.jp/contests/apg4b/tasks/APG4b_al)が取れます。これは、副次的効果ではありませんが、事実としてそういうことです。stderrの内容は関係なく、stdoutの内容だけを判定していると思われます。

もちろん、stderrに大量の情報を出力すると、それは実行時間に影響し**TLE**になる可能性があるので、AtCoderに提出するコードではデバック情報の出力などはコメントアウトしておくのが無難です。


# おわりに

ちょっとしたことですが、AtCoderのコンテスト中は時間との戦いですので、無駄なことは極力省きたいと思うのが普通。今回の記事の内容で、これまで不便だったことが改善され快適な環境になりました。
同じような環境で使われている方の参考になれば幸いです。


## 参考記事

https://qiita.com/nak435/items/4854a10a766a8a289aaf


https://qiita.com/nak435/items/f2e775395e9b85e5ed9c


**以上**
TypeScriptにおけるstringとnull

# TypeScriptではstring型の変数にnullを代入できない
C#等の言語では代入できるnullですが、TypeScriptではできません。
![スクリーンショット 2022-01-09 14.21.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/e32262a0-0392-2429-a561-227efe49b782.png)

明示的にnullを許可してあげると代入できるようになります。
![スクリーンショット 2022-01-09 14.22.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/76051c02-fc50-77f8-7764-8e642f062bf1.png)
Google Cloud Digital Leader 合格体験記

# はじめに
Google Cloud Digital Leaderに合格したので簡単な記録を残しておきます。

# Cloud Digital Leaderとは
https://cloud.google.com/certification/cloud-digital-leader

GCPの一番の入門として位置づけられる資格試験。
内容は以下の構成。

- クラウドに関する一般的な知識(15-25%)
- Google Cloud に関する一般的な知識(25-35%)
- Google Cloud のプロダクトとサービス(45-55%)

# 個人的バックグラウンド
[OCIの記事](https://qiita.com/tkuribayashi/items/f17dc8a321766caa0e4d)で書いた通り、
GCPの実務経験は2年ほどあるが、アプリケーション開発者として関わったのみなので、自分で触った機能は限定的。

# 学習方法
https://cloud.google.com/training/business#cloud-digital-leader-path

ある程度クラウドの一般的な知識があれば、上記公式のトレーニングを一通りやればOK。
一通り動画を流しみて、トレーニング内のクイズで確認しつつ、スライドで知識を補足すれば、とりあえず準備としては十分。

# 試験
[資格のトップページ](https://cloud.google.com/certification/cloud-digital-leader)から、リンクをたどり、Google Cloud Webassessorのアカウントを作成し試験を申し込めばよい。後述するが、Webassessorの登録氏名と試験時に見せる身分証明書の氏名が一致している必要があることに注意。

受験当日は、いつも通り近所のレンタルスペースを利用した。
机の周りさえ綺麗ならば、部屋の後ろや隅の方に物が置いてあっても問題はない。

受験前の諸確認については、[CKAD/CKA](https://qiita.com/tkuribayashi/items/fb9cad6786074c5e09c3)のときと似た感じで、カメラオンの状態でチャットでやりとりをしつつ、身分証明書や机周りの確認を行った。
日本語試験で申し込んだためか、確認チャットの序盤でいきなり日本語の指示が来たが、機械翻訳なのかやや意味が不明瞭だったため英語でのやりとりを希望したところ、その後はすべて英語で済んだ。
また、有効な身分証明書については[公式ガイド](https://support.google.com/cloud-certification/answer/9907450?hl=ja&ref_topic=9433463)に記載の通りだが、Webassessorでの登録氏名と一致している必要があるため、例えば運転免許証を利用するなら日本語氏名、パスポートなら英語氏名で登録しておくこと。

# 結果&所感
90分40問の試験だが、15分で一通り回答、5分の見直し含め20分程度で終了。
内容については、トレーニングの模擬問題がそのまま出るということは当然なく、やや戸惑うような内容も多かった。ただ、Google Cloudのプロダクトとサービスについて一通り理解をしておくという原則に従えば、特に難しいことはないはず。
また、日本語受験の場合、一部問題文に脱字が見られたり、やや不安を覚える面もあった。(また、公式トレーニングは英語だったため、そのギャップもあった。英語に問題がなければ試験も英語で受験する方が安心かもしれない)

結果自体は、最終的な審査を経て7-10日後に通知があるとのことだが、採点自体は合格であることがWebassessorで即時確認できた。採点や試験結果に関するフィードバックは通知されないとのこと。

## 今後
直近実務でGCPを使用していないということもあり、次は[AZ-900](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900)の学習・受験を予定している。
Excel VBA 画像挿入する（繰り返し処理をして画像一覧を作る）

#はじめに
画像一覧を作って共有したい！貼り付け作業をまとめてやりたい！
そんなときの元ネタになればいいなと作成したマクロになります。
ここからのアレンジは様々なのでベースとして利用してください。


#目次
1. 使い方
1. コード
1. コード補足
1. 大量のファイルのフルパスの取得方法

#使い方

ファイルのフルパスを書いたセルを選択してマクロを実行します。

画像のファイルパスを書いたセルを選択して実行すると、左隣のセルに画像を挿入します。
画像挿入後、一つ下のセルを確認して同様に文字列が書いてあれば,下方向へ繰り返し処理をします。

![006.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/0b8b0acd-3a4f-b4ae-5028-bfa29ee6be0f.png)

![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/80116a43-b28f-a332-ffce-485006fd7a42.png)


#コード

```VBScript:VBAマクロ
'＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
'画像を大量に挿入するマクロ
'＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝

Sub PicInsertMacro()
Const PADDING = 6

Dim WorkingCell As Range
Set WorkingCell = ActiveCell

'デバッグ用に行数カウント
'Dim LastRow, WorkingRow As Integer
'WorkingRow = 1
'If WorkingCell.Value <> "" Then LastRow = WorkingCell.End(xlDown).Row - WorkingCell.Row + 1

While WorkingCell.Value <> ""
    'デバッグ用
    'Debug.Print WorkingRow & "/" & LastRow & "|" & WorkingCell.Value
    'WorkingRow = WorkingRow + 1
    
    '画像挿入
    ActiveSheet.Pictures.Insert(WorkingCell.Value).Select
    
    '縦長か横長かでサイズ指定を変える。
    If Selection.Width < Selection.Height Then
        Selection.Height = WorkingCell.Offset(0, -1).Height - PADDING
    Else
        Selection.Width = WorkingCell.Offset(0, -1).Width - PADDING
    End If
    
    'セルの真ん中に移動してきれいに配置する
    Selection.Top = WorkingCell.Offset(0, -1).Top + (WorkingCell.Offset(0, -1).Height - Selection.Height) / 2
    Selection.Left = WorkingCell.Offset(0, -1).Left + (WorkingCell.Offset(0, -1).Width - Selection.Width) / 2
    
    '次のセルに移動する
    Set WorkingCell = WorkingCell.Offset(1, 0)
Wend

'デバッグ用
'Debug.Print "fin"

End Sub
```


# コード補足
基本的には画像一覧を作るためにセルは正方形に近いことを前提に作っています。
PADDINGで余白をつけていて、両サイドの余白の合計を指定する内容になっています。
画像の縦長か横長かを確認して、大きい辺を基準にサイズを決定します
![008.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/9ff4cfe2-7115-06ff-c178-f2f632c8b337.png)
![009.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/def4d1c4-f460-808f-4671-e5010863ca0f.png)



#【参考】大量のファイルのフルパスの取得方法
##1つのフォルダにファイルが入っている場合(同一フォルダ)
ファイルをすべて選択してから、` Shiftキー` を押して右クリックすると、` パスのコピー` が可能です。
![010.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/63a4664a-a4e0-f5a5-7bd1-9eb965b502d6.png)


##サブフォルダがある場合ファイルが入っている場合(サブフォルダあり)
コマンドで取得できます

```.bat(dos):bat
dir /s /b /a-d "対象フォルダ"

REM ファイル数が多い場合には結果をファイルに出力することもできます。
dir /s /b /a-d "対象フォルダ" > "保存したいテキストファイルの保存先"
```

dir ファイル一覧を取得します
/s サブディレクトリも取得します
/b　ファイルのフルパスを取得します（/sと組み合わせない場合はファイル名のみ）
/a-d　ファイルのみ表示します。　AllからDirectory(フォルダ)を除くので、ALL-Directoryです。


![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/086645c0-a6aa-a10c-626c-730e84e6d318.png)
ファイル出力をする場合、画面上に文字は出てこないですが、ファイルに書き込まれています
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2486463/96db8b00-c257-493d-06db-f6c164637757.png)


閲覧ありがとうございました。
Pythonのコメント機能を使って簡単にコードを切り替える

発見しました。
参考になれば幸いです。

# コード
```python
#"""      #ここのコメントアウトを解除する 
VAR = 1
"""
VAR = 0
#"""
```

# VSCodeでの様子
![vscodeで切り替え.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644120/8f8d8f04-8e20-c1c8-ec2b-f13f86743e4a.gif)
windows10環境でgit, python, vscodeをインストールしてpowershell上で使う2

以下の記事を作成したが、実は`winget`でシンプルに代替できるんじゃないかというメモ

> [windows10環境でgit, pythonをインストールしてpowershell上で使う](https://qiita.com/seigot/items/ac2be89c7f3ef2298ef0)

powershellを起動する

```
winget --version
## v1.1.13405 等と出力されればOK
```

gitのインストール

```
winget install Git.Git
```

python3のインストール

```
winget install python.python.3

# この方法だと、pythonが正しくインストールされないことがあった。
# なぜかはよく分からないが、、micro soft store上でpythonと検索してインストールした方が確実かもしれない
```

vscodeのインストール

```
winget install vscode
```

パッケージの検索は`winget search`を使えばOK

```
winget search Git
winget search Python
winget search vscode
```

可能であればこちらの方がシンプル

# 参考
[Windows 10搭載PCを買ったら最初にやっておきたいこと【開発者編】](https://news.mynavi.jp/techplus/article/20210622-1904714/2)
[Windows Package Manager `winget` を使う](https://zenn.dev/rhene/scraps/c4dca9570ca0da)
[wingetを使おう 後編：wingetの詳細設定、Tabキー補完など](https://astherier.com/blog/2021/09/winget-usage-3/)
③PythonAnywhere Google Newsのheadlineをスクレイピングしてメールで毎朝定期的に送る

クラウド上のサーバーでPythonのコードを実行できるPythonAnywhereで無料のアカウントでもメールを送ったり、スクレイピングすることを説明しました。

①PythonAnywhereの無料アカウントからメールを送る
https://qiita.com/Kent-747/items/fa92c51d81cd4f50eadc

➁PythonAnywhereの無料アカウントでGoogle Newsをスクレイピング
https://qiita.com/Kent-747/items/0380de9ec7d6de137afa

今回は、それらを組み合わせて、Google Newsのヘッドラインをスクレイピングした結果をメールで送ってみたいと思います。

基本的には、以前紹介したコードを組み合わせただけです。

```python
import requests
from bs4 import BeautifulSoup
import re
   
import smtplib, ssl
from email.mime.text import MIMEText


# SMTP認証情報
account = "xxxxx@gmail.com"
password = "yyyyy"
 
# 送受信先
to_email = "zzzzz@gmail.com"
from_email = "xxxxx@gmail.com"

######## ここからGooglニュースのトップページ情報を取得する #####
URL = "https://news.google.com/topstories?hl=ja&gl=JP&ceid=JP:ja"
rest = requests.get(URL)

# BeautifulSoupにGoogleニュースのページ内容を読み込ませる
soup = BeautifulSoup(rest.text, "html.parser")

# Googleニュースの見出しとURLの情報を取得して出力する
data_list = soup.find_all('h3')

allHeadlines =''

for data in data_list:
    print(data.text)
    
    allHeadlines += data.text
    allHeadlines += "<br>"


# MIMEの作成
subject = "本日のGoogle News"

msg = MIMEText(allHeadlines, "html")
msg["Subject"] = subject
msg["To"] = to_email
msg["From"] = from_email
    
server = smtplib.SMTP_SSL("smtp.gmail.com", 465, context=ssl.create_default_context())
 
server.login(account, password)
server.send_message(msg)
server.quit()

```

今回、少しはまったところは、ヘッドラインをメッセージとして準備する際に<br>で改行させて連結するところです。

こちらを保存してPythonAnywhere上で実行することは前回の記事を参考にしてください。

それが動くことが確認できたら、次のようにTaskとして毎朝メールが発信できるようすることもできます

UTCでしか時間は設定できなくて、日本時間から+9hとのことです。
私は毎朝7:35に届くようにしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/10c96bfd-1a18-5d0b-9a4d-e2b364302064.png)

このように無事、届きました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/823476/f30f2bf3-064a-c3b1-bc9d-ccdc1240b9b9.png)
GASでGmailの本文から不要な空行を削除する

GASでメールを転送する時に不要な空行を削除したい場合など。

返信部分の空行は引用表示なので「>」が入力されています。
なので空判定と併せて引用符も判定しましょう。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209937/331d114e-5d32-da80-482c-ed84b581b1fe.png)

```
// 連続する空行を削除
function func(mailBody){
  var result = [];
  var strList = mailBody.split(/\r\n|\n/g);
  var prevRow = 'dummy';
  strList.forEach(function(currentRow) {
    var currentRow = currentRow.trim();
    if ((prevRow && prevRow != '>') || (currentRow && currentRow != '>')) {
      result.push(currentRow);
    }
    prevRow = currentRow;
  });
  return result.join("\n");
}
```