OmniAICreator/Qiita-1.07M huggingface dataset:
[Python]総和が m になる長さ n の整数列の数

# 概要

[第４回 ドワンゴからの挑戦状 予選 C - Kill/Death](https://atcoder.jp/contests/dwacon2018-prelims/tasks/dwacon2018_prelims_c) を解くために、総和がある値になる（正の）整数列の数と、そのうちの一意な組み合わせの数が必要になった。
どちらも整数列の長さ $n$、総和 $m$ のとき $O(nm)$ で二次元配列上に列挙できる。

# 整数列の数を求める

例として $m=4, n=3$ のとき、`● ● ● ●` を ３ つの区画に区切ることを考えればよく、例えば `● ● | ● | ●` のように表せる。
これは $m+n-1$ 箇所のどこに $n-1$ 個の `|` を配置するかという問題になり、その組み合わせの数は $_{n-1+m} C _{n-1}$ で求められ、この例では $_6 C _2 = 15$ 通りある。
<details><summary> 整数列を列挙すると</summary><div>

```
4 0 0
3 0 1
3 1 0
2 0 2
2 1 1
2 2 0
1 0 3
1 1 2
1 2 1
1 3 0
0 0 4
0 1 3
0 2 2
0 3 1
0 4 0
```
</div></details>
これらの整数列のうち、例えば `4 0 0`、`0 4 0`、`0 0 4` は順序の異なる同じ組み合わせからなる。

# 整数列の数を列挙する

$_n C _r$ は値のとり方によっては計算に時間がかかるので、整数列の数を列挙しておくことで高速化できる場面がある。
ここでは以下の漸化式を使う。 $P(n,m)$ は長さ $n$、総和 $m$ の整数列の数である。

```math
P(n,m)= 
\begin{cases}
1 & (n,m=0)\\

P(n-1,m) & (m=0, 1 \leq n) \\
P(n-1,m)+P(n,m-1) & (1 \leq m, 1 \leq n) \\
0 & (otherwise) 
\end{cases}
```

$i$ 番目の要素までで総和がちょうど $j$ となる整数列の数は、 $i-1$ 番目で総和がちょうど $j$ である整数列の数（つまり $i$ 番目の要素が $0$ のとき）と、 $i$ 番目の要素までで総和がちょうど $j-1$ である整数列の数を足せばよい。
以下のように実装できる。

```python
P = []
cur = [0]*(m+1)
cur[0] = 1
for i in range(1, n+1):
    for j in range(1, m+1):
        cur[j] += cur[j-1]
    P.append(cur.copy())
```

## 漸化式の直感的な理解

$P(2,4)$ の整数列を列挙すると

```
4 0 0
# ここまでが P(1,4)

0 4 0
3 1 0
2 2 0
1 3 0
# ここまでが P(2,4)
```

ここで、長さがちょうど $2$ で表せる整数列の 2 番目のすべての要素から $1$ を引くと

```
0 3
3 0
2 1
1 2
```

となり、 $P(2,3)$ の整数列が得られる。
反対に、$P(2,3)$ の 2 番目のすべての要素に $1$ を足すと、2 番目の要素は $0$ 以上となるため、長さがちょうど $2$ で表せる総和が $4$ の整数列が得られる。

# 組み合わせの数を列挙する

先ほど列挙した整数列のうち、順序の異なる同じ組み合わせを除いた一意な組み合わせの数を求める。
$C(n,m)$ は総和 $m$ となる $n$ 個の整数の組み合わせであり、以下の漸化式で求められる。

```math
C(n,m)= 
\begin{cases}
1 & (n,m=0)\\

C(n-1,m) & (m < n, 1 \leq n) \\
C(n-1,m)+C(n,m-n) & (n \leq m, 1 \leq n) \\
0 & (otherwise) 
\end{cases}
```

$i$ 番目の要素までで総和がちょうど $j$ となる整数列の数は、 $i-1$ 番目で総和がちょうど $j$ である整数列の数（つまり $i$ 番目の要素が $0$ のとき）と、 $i$ 番目の要素までで総和がちょうど $j-i$ である整数列の数を足せばよい。
以下のように実装できる。

```python
C = []
cur = [0]*(m+1)
cur[0] = 1
for i in range(1, n+1):
    for j in range(i, m+1):
        cur[j] += cur[j-i]
    C.append(cur.copy())
```

## 漸化式の直感的な理解

$C(3,4)$ を列挙すると、

```
4 0 0
# ここまでが C(1,4)

2 2 0
3 1 0
# ここまでが C(2,4)

2 1 1
# ここまでが C(3,4)
```

となる。ところで、長さがちょうど $2$ で総和 $4$ となる整数の組み合わせを `*` で表すと

```

2 * *
2 * *
0

3 * * *
1 *
0
```

これを転置して読むと

```
2 2
* *
* *

2 1 1
* * *
*
```

となり、長さがちょうど $2$ で総和が $4$ となる整数の組み合わせは、最大値が $2$ で総和が $4$ となる任意の長さの整数の組み合わせと読みかえることができる。
ここで転置後の整数の組み合わせは必ず $2$ で始まり、以降は $C(2,4-2)=C(2,2)$ の整数の組み合わせで表せることがわかる。


# 参考
[数学ガール★分割数(partition number)の漸化式と戯れる - incognita et cognita](http://incognita.hatenablog.com/entry/20110305/1299344781)
なんだと！CatalinaでDTermが使えるだと！！

# 久しぶりに代替ソフトを探してみた
MacOS Sierra以降で[Dterm](https://github.com/muhqu/dterm)が使えなくなっていたため、色々と歯がゆい思いをしていたのですが、
久しぶりにGitHubのリポジトリを見てみたら、2019年9月末にバグフィックスリリースが提供されているではありませんか！

## 早速入れる
　上のページの[release](https://github.com/muhqu/dterm/releases)リンクに1.7.84 バグフィックスリリースがあるのでダウンロード

### アクセシビリティの設定
　起動前に、システム環境設定のセキュリティ＆プライバシー→アクセシビリティを開き、左下のロックを外して、リスト下の+ボタンまたはアプリケーションのドラッグ＆ドロップで`Dterm`を追加

### 右クリックで開く
　初回起動は「外部サイトからダウンロードしたアプリだが、本当に起動するか？（意訳）」と聞いてくるので、`Applications`フォルダーの中の`Dterm`を右クリックでコンテキストメニューから開くを選択。
続いて出る警告ダイアログで「開く」を押すと起動します。

### ショートカットキーを指定
　自分の使いやすい、他とバッティングしないキーコンビネーションを`Dterm`の一般環境設定で登録します。

### アクセシビリティを確認
　環境設定のアクセシビリティタブを選択し、
Dterm is currently: **trusted**
になっていることを確認します

### ショートカットを叩いて起動を確認

<img width="730" alt="Dterm.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20251/87ef8958-c5cd-9d3a-6652-b0984494a032.png">

こんな感じで懐かしの`Dterm`が`Catalina`でも動くことを確認。良かった、良かった。

### 常駐させたいなら
　Macを起動する度に`Dterm`をいちいち起動するのも面倒なので、使用頻度が高くなってきたと思ったら、システム環境設定、ユーザー＆グループの、自分のアカウントのログイン項目に`Dterm`を追加するとMacが再起動しても、ログインすると`Dterm`も起動してくれます。
起動してすぐアクセスしたいわけではないので、右の非表示にチェックを入れても良いかもしれません。
【Ruby on Rails】RSpecとFactoryBotとShoulda MatchersとCapybaraを導入メモ

## RSpec設定


```ruby:Gemfile
group :test do
  gem 'rspec-rails'
end
```


```
rails g rspec:install
```


```:.rspec
--require spec_helper
--format documentation
```


```ruby:config/application.rb
config.generators do |g|
  g.test_framework :rspec,
                   fixtures: false,
                   controller_specs: false,
                   view_specs: false,
                   helper_specs: false,
                   decorator_specs: false,
                   routing_specs: false
end
```


#### Spring設定
```ruby:Gemfile
group :test do
  gem 'spring-commands-rspec'
end
```


```
spring binstub rspec
```

```ruby:config/environments/test.rb
  config.cache_classes = false
```

## FactoryBot設定


```ruby:Gemfile
group :test do
  gem 'factory_bot_rails'
end
```


```ruby:spec/support/factory_bot.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end
```


```ruby:spec/rails_helper.rb
require "support/factory_bot"

config.before(:all) do
  FactoryBot.reload
end
```


## Shoulda Matcher設定


```ruby:Gemfile
group :test do
  gem 'shoulda-matchers'
end
```


```ruby:spec/support/shoulda_matchers.rb
Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end
```


```ruby:spec/rails_helper.rb
require "support/shoulda_matchers"
```

## FFaker設定

```ruby:Gemfile
group :test do 
  gem 'ffaker'
end
```

## Fuubar設定

```ruby:Gemfile
group :test do
  gem 'fuubar'
end
```

```:.rspec
--format Fuubar
--color
```

## system spec設定

```ruby:Gemfile
group :test do
  gem 'capybara'
  gem 'webdrivers'
end
```

```ruby:spec/rails_helper.rb
require 'capybara/rspec'
require 'support/capybara'
```


```ruby:spec_support/capybara.rb
RSpec.configure do |config|
  # Delete screenshot files before testing
  FileUtils.rm_rf(Dir[Rails.root.join('tmp/screenshots/*')], secure: true)

  # Show screenshot when fail
  ENV['RAILS_SYSTEM_TESTING_SCREENSHOT'] = 'inline'

  # Driver setup
  config.before(:each, type: :system) do
    driven_by :selenium_chrome_headless
  end
end

Capybara.register_driver :selenium_chrome_headless do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  %w[
    headless
    window-size=1600x900
    no-sandbox
    disable-gpu
  ].each { |arg| options.add_argument(arg) }
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
```

## system specでユーザーをログインする

```ruby:Gemfile
group :test 
  gem 'rack_session_access'
end
```

```ruby:config/environments/test.rb
  config.middleware.use RackSessionAccess::Middleware
```

```ruby:spec/rails_helper.rb
  require 'rack_session_access/capybara'
```

**ユーザーIDのセッションを設定する：**

```ruby:xxx_spec.rb
page.set_rack_session(user_id: user.id)

# deviseを使う場合：
page.set_rack_session('warden.user.user.key' => User.serialize_into_session(user))
```
Covid-19のソーシャル分析その2　感情分析

##Covid-19のソーシャル分析その2　感情分析
トランプ大統領のツイートを抽出し、感情分析を実施してみた。
おそらく時系列でみてみると彼の焦りや不満点が見えてきて
かつ、次に実施される政策の方向性がある程度見えてくるんじゃないか
と思うので各で分析を深めてもらいたい。



##Rによる感情分析
```R:emotion_analysis.rb
#ライブラリー
library("twitteR")
library("lubridate")
library("ggplot2")
library("ggmap")
library("stringr")
library("tm")
library("RColorBrewer")
library("wordcloud")
library("syuzhet")
#APIkey入力・認証
#参考：https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/
APIKey <- ""
APISecret <- ""
accessToken <- ""
accessSecret <- ""
options(httr_oauth_cache = TRUE)
setup_twitter_oauth(APIKey, APISecret, accessToken, accessSecret)
#ツイート取得
extractTimelineTweets <- function(username,tweetCount){
  # timeline tweets
  twitterUser <- getUser(username)
  tweets = userTimeline(twitterUser,n=tweetCount)
  tweets.df = twListToDF(tweets)
  tweets.df$text <- sapply(tweets.df$text,function(x) iconv(x,to='UTF-8'))
  
  return(tweets.df)
}

tweetsDF <- extracTimelineTweets("POTUS",1500)

#前処理作業
nohandles <- str_replace_all(tweetsDF$text, "@\\w+","")
wordCorpus <- Corpus(VectorSource(nohandles))
wordCorpus <- tm_map(wordCorpus, removePunctuation)
wordCorpus <- tm_map(wordCorpus, removeWords, stopwords("english"))
wordCorpus <- tm_map(wordCorpus, removeWords, c("amp"))
wordCorpus <- tm_map(wordCorpus, stripWhitespace)
#wordcloud
pal <- brewer.pal(9,"YlGnBu")[-(1:4)]
wordcloud(words = wordCorpus,
          scale =c(5,0.1),
          max.words = 1000,
          random.order = FALSE,
          rot.per =0.35,
          use.r.layout = FALSE,
          colors =pal)

#感情スコアー
TweetSentiments <- get_sentiment(tweetsDF$text,method ="syuzhet")
tweets <- cbind(tweetsDF, TweetSentiments)
#グラフ１
qplot(tweets$TweetSentiments)+
  theme(legend.position ="none")+
  xlab("sentiment score")+
  ylab("Number of Tweets")+
  ggtitle("Tweets by sentiment Score")

#グラフ2感情カテゴリー関数
encodeSentiment <- function(x){
  if (x <= -0.5){
    "very negative"
  }else if (x< 0){
    "negative"
  }else if(x ==0) {
    "neutral"
  }　else if (x <0.5){
    "positive"
  }else{ # x>=0.5
    "very positive"
    }
}


##参考文献
**Package ‘Syuzhet’**
https://cran.r-project.org/web/packages/syuzhet/vignettes/syuzhet-vignette.html
Google Meetで通話するときに「カメラまたはマイクで問題が発生しました」と表示される

# マイクを使って通話ができない！
## 参加する
MeetのURLをもらって参加するものの、**「カメラまたはマイクで問題が発生しました」** とポップアップが表示され、音は聞こえるが話せない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268717/6f186fef-9e9a-4bfd-833e-ae6933877c73.png)

## 設定を見てみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268717/2ceeba5b-83db-6a45-834c-0cf217c95390.png)

※設定の確認の仕方→ 右下の「︙」をクリック→「設定」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268717/918c6d41-74f5-bbd3-1993-798e89033396.png)


# 状況
- マイクがブロックされていて、選択もできない。(らしい)
- Windows 10の最新版ChromeでMeetを開いている
- 他のWindowsアプリではマイクは認識しているし、ちゃんと相手にも聞こえている
- 他のサイトで[マイクをテストするツール](https://online-mic-test.com/)を使用したら認識している
- つまりMeetがおかしい

# 解決策
URL欄左の鍵アイコンをクリックし、サイトごとの設定画面を確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268717/0b3b6620-2bc0-f815-fc8c-67f7dfb45114.png)

「マイク」の項目が「ブロック」となっているのでこれを「**許可**」に変更する。
ブラウザ上部に「再読み込み」ボタンが表示されるので、クリックしてページを開き直す。
設定を確認すると選択できるようになった！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268717/d9eed1b9-1ca8-f9e9-a0ad-b55d6f87ed69.png)
※デバイス名は環境により変わります。私はUSBオーディオデバイスを使用しているので長ったらしい名称になっています。

# 原因の推測
私は普段からページを開いたときに「通知を送っていいですか？」的な確認をされたときは問答無用で「ブロック」を選んでいるのですが、おそらく同じようにマイクの確認をされたときにブロックしたのではないかと思っています。

# おわりに
結構単純な解決方法でしたが、chromeのマイクの設定を見てもデバイスは認識しているし、他のアプリでは普通につかえているので原因がわからないまま2日ほど使えていませんでした。 
最近はテレワークの導入などでMeetを使う人も増えているかと思い、同様の問題が起きた人の参考になればと思い投稿しました。
[Ubuntu 18.04]でvimを使い、快適な日本語入力を行う。

# LinuxでもVimを使った日本語入力を行いたい。

# 記事を書いた目的
## 日本語のテキストファイルを作成する際にもvimを使いたいから。
1. vimを使って日本語入力をする際にネックになるのは**ノーマルモードからinsertモードに変更した際にいちいち半角を全角に戻す**必要があってそれが面倒くさい。
1. 日本語入力協調モードというのを使うとEscをモード切り替え時にうまいこと入力方式を切り替えてくれる。 
1. しかし、Linuxでも日本語入力協調モードを使った快適な日本語入力を行う機能がデフォルトのvimにはない。(私が調べた限りではUbuntu 18.04,Centos-7のgvimにはデフォルトで日本語入力協調モードの機能がありませんでした.)
1. **linuxでも快適な日本語入力をvimを使って行いたい!!!!!!**

# 対象読者
- vimを使って小説を書きたい方。
- vimを使ってレポートや論文の文章を作りたい方。
- vimに興味がある方。

# 動作環境
- 使用OS→ubunt18.04
- vimのバージョン→Vi IMproved 8.0 (2016 Sep 12, compiled Mar 18 2020 18:29:15)
- ibus

# 行ったこと

## 1. プラグインを入れて日本語入力協調モードを使えるようにする。
- 以下の[サイト](https://sites.google.com/site/fudist/Home/vim-nihongo-ban/vim-japanese/ime-control#linux)を参考にして設定を行いました。

### 大まかな作業手順
- プラグインのダウンロード
[日本語入力プラグイン](https://github.com/fuenor/im_control.vim/archive/master.zip)からダウンロードし、ファイルを展開します。

- パスの設定
先程ダウンロードしたディレクトリのうち必要なのは**im_control.vim-master**です。このファイルを配置したパスを通す為にvimrcに以下の文を追加します。私は/home/user/vimjp/im_control.vim-masterのように配置したので以下のように設定しました。

```bash:vimrc
set runtimepath+=/home/user/vimjp/im_control.vim-master
```
- ibus engineを使って入力方式が変更できるようにする。
[同サイト](https://sites.google.com/site/fudist/Home/vim-nihongo-ban/vim-japanese/ime-control/ibus#TOC-IBus-Python-1.5)に詳しく書いてありますが、ざっくりいうとモード切り替え時にibus engineというコマンドを実行して入力方式を変更できるようにvimrcに以下の文を設定します。

```bash:vimrc
" 「日本語入力固定モード」の動作モード
let IM_CtrlMode = 1
" 「日本語入力固定モード」切替キー
inoremap <silent> <C-j> <C-r>=IMState('FixMode')<CR>

" IBus 1.5以降
function! IMCtrl(cmd)
  let cmd = a:cmd
  if cmd == 'On'
    let res = system('ibus engine "mozc-jp"')
  elseif cmd == 'Off'
    let res = system('ibus engine "xkb:jp::jpn"')
  endif
  return ''
endfunction

" <ESC>押下後のIM切替開始までの反応が遅い場合はttimeoutlenを短く設定してみてください。
" IMCtrl()のsystem()コマンド実行時に&を付けて非同期で実行するという方法でも体感速度が上がる場合があります。
set timeout timeoutlen=3000 ttimeoutlen=100 
```

この状態でinsertモードで**Ctrl-j**を実行すると日本語入力協調モードが起動します。
うまく起動しないばあいにはきちんとパスが通っているか確認してみてください。

## 2. vim終了時に入力方式をmozcに戻す。

これで日本語入力協調モードが使えるようになりましたが、面倒なことがあります。
それは、**vim終了時に入力方式がjapanese(アルファベットオンリーしか使えない)**状態になってしまうことです。
これを変更するには、Windowskey-spaceを使ってmozcに切り替える必要があります。**正直これが面倒!!!**
**そこでvimを終了時にmozcに入力方式を戻せるようにしたいと思います。**

### 作業内容

- 環境変数PATHに登録するパスを増やします。bashrcに以下の内容を記述してください。

```bash:bashrc
PATH=$PATH":/home/user/bash"
```
これでPATHにbashというディレクトリのパスが追加されたので/bash内のシェルスクリプトをどのディレクトリからも実行することができるようになりました。

- bashにvimというファイルを作る
 /home/user/bash/vimというファイルを作り以下のように記述します。

```bash:vim
#!/bin/bash↲
/usr/bin/vim "$@"
ibus engine "mozc-jp"
```

- 実行権限を付与
/home/user/bash/vimに実行権限を付与します。

```shell-session
chmod 744 /home/user/bash/vim
```
- エイリアスの追加
vimというコマンドを実行した際にそのままvimがバイナリから起動するのではなく/home/user/bash/vimを通してvimが立ち上がるように設定します。
bashrcに以下の文を追加してください。

```bash:bashrc
alias vim='/home/tomita/bash/vim'
```
これでvimを終了時に入力方式をmozcに戻すことができました。

## よりよい方法がありましたらぜひコメント欄で教えてください！！！
CentOS7でCronが実行されない

cronのサービス起動済み、ファイルに対する実行権限も問題なし。
手動実行で成功するシェルがcronで設定したら全く実行されず、原因解明までの道のり

```
less /var/log/cronで実行ログを確認するもコマンドの実行形跡はある

May  2 16:43:01 localhost CROND[31348]: (root) CMD (backup.sh)
``` 

結論から書くと、以下のように修正したら/tmp/cron.logに原因がlogに記載されました。
例はとりあえず、毎分実行でcrontabに登録

修正前

```
* * * * * backup.sh 
```

修正後

```
* * * * * backup.sh >> /tmp/cron.log 2>&1

2>&1は標準エラー出力(2)を標準出力(1)に入れるという意味
```

参考までに今回の原因


```/tmp/cron.log
less /tmp/cron.logで確認すると下記が表示されてた

/bin/sh: backup.sh: bin/sh: bad interpreter: No such file or directory
```

シェルスクリプトの先頭行に以下のように書くはずがtypoしてました。。。
typoを修正したところ、無事実行されるようになりました。

```
#!/bin/bash
```

備忘録 CentOS7のCrontのStartとStop

```
systemctl start crond
systemctl stop crond
```
備忘録　Flashメッセージを使いこなそう

# Flashメッセージで次のリクエストにデータを伝える

railsのredirect_toメソッドにflashを使うことで次のリクエストにデータを伝えることができる。(同じリクエスト内でもできるが後述)

```ruby
redirect_to リダイレクト先のURL, notice: 'ここのデータを送れるよ！'
```

次のように2行で書いても、同じ。

```ruby
flash[:notice] = 'ここのデータを送れるよ！'
redirect_to リダイレクト先のURL
```

redirect_toのオプションに渡せるflashのキーはデフォルトでは:noticeと:alertのみとなっている。
次のようにflashキーの値にオリジナルのデータをハッシュで渡すことでプチカスタマイズができる。


```ruby
redirect_to リダイレクト先のURL, flash: {hogehoge: 'ここのデータを送れるよ！'}
#=> 次のリクエストではflash.hogehogeで参照できる
```
また、noticeとalertは以下のようにメソッドの形でデータを渡すこともできる。

```ruby
flash.notice = 'ここのデータを送れるよ！'
flash.alert = 'ここのデータを送れるよ！'
```

redirect_toすると次のリクエストに移行するが、
同じリクエスト内にデータを伝えたいこともありますよね！（renderでエラーメッセージを表示するなど）
そんな時は

```ruby
flash.now(:notice) = '今のリクエストが終わるまでデータを保持できるよ！'
flash.now(:alert) = '今のリクエストが終わるまでデータを保持できるよ！'
```

とすることで同リクエスト内でデータを参照できます。

```ruby
flash.keep(:notice) = '次の次までデータを保持できるよ！'
flash.keep(:alert) = '次の次までデータを保持できるよ！'
```
flash.keepはredirectで送ったリクエストの次のリクエストまでデータを保持できます。

flashメッセージの表示期間（現在のリクエストor次回のリクエストorその先）によって上記を使い分けましょう。
ステータスバーに表示させるキッチンタイマーを作ってみた！

#背景

キッチンタイマーが欲しいなあ。
でもアプリとかだとブラウザ開いたりして常に見ることできないしなあ。
じゃあiPhoneで良いじゃんって思ったけど、つい携帯触っちゃうしダメじゃん！！

常に見えるところで場所を取らないキッチンタイマーが欲しい！
あれ？Macの最上部、ステータスバー良いじゃん！作ってみよ！

こういう流れで作ってみました。


#作り方

こちらの記事を参考にしました。
https://qiita.com/hartmann16325/items/8667611fcaf68b9a948b

僕はpythonを使うので調べたところ、rumpsというライブラリを使えばステータスバーでの操作が可能とのこと。

GitHubにあげているのでよかったらどうぞ！
https://github.com/tokky08/Kitchen_timer


```python
@rumps.clicked(u'30分')
def selectTimer(sender):
    global minute
    minute = 30

    global start
    start = time.time()
```

ここでメニューバーの作成です。


```python

@rumps.timer(1)
def dispTimer(sender):
    
    timer_minute = str(minute-1)
    timer_second = str(second - int(time.time() - start) % 60)

    remaining_minute = int(time.time() - start) // 60
    timer_minute = str(int(timer_minute) - remaining_minute)

    if int(timer_minute) < 0:
        app.title = "TIME UP"
        if int(timer_minute) == -1 and int(timer_second) == 58:
            rumps.notification(message="作業をやめてください！！！", title="TIME UP！", subtitle="")


    else:
        if int(timer_second) < 10:
            timer_second = "0" + timer_second

        app.title = "残り時間：" + timer_minute + ":" + timer_second
```

ここでこの関数が1秒ごとに実行されます。
分と秒に分けて考えています。

 
分は、`time.time()-start`はカウントダウンし始めからこの関数が実行された時間を引いた秒数が計算されます。
そして、`second`はここでは59としています。
`second-int(time.time()-start)`で１秒ずつ減っていくことを表しています。
%60しているのはマイナス表示にならないためです。

秒は、`remaining_minute`で経過した分を表しています。
それを選択したタイムから引くことで残りの分を表すことができます。

#まとめ
思い立ってあれこれ調べて6時間かけて完成しました。
簡単そうに見えてもいざ作ろうとなるといくつか試練が出てきますね。
それでもアイデアを具現化することができてプログラミングは面白いな！と思います。

何か誤り等あればご指摘よろしくお願いいたします。
Amazon CloudWatch Syntheticsを試してみた

Amazon CloudWatch SyntheticsがGAになったので試してみました。
https://aws.amazon.com/about-aws/whats-new/2020/04/amazon-cloudwatch-synthetics-generally-available/
https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries.html


## どんなもの

WEBやAPIを監視するサービスです。
TOPページやAPI監視以外にもリンク切れワークフロー監視のBlueprintsが用意されています。
UIのスクリーンショットを保存することも可能です。

## WEB監視

### 準備

##### 1. 時々200以外のステータスを返すLambdaを用意する

```lambda.py
import random

def lambda_handler(event, context):
    status = random.choices((200,400,500), weights = (7,2,1))[0]

    res = {
        "isBase64Encoded": False,
        "statusCode": status,
        "statusDescription": "status: {}".format(status),
        "headers": {
            "Set-cookie": "cookies",
            "Content-Type": "text/html"
        }
    }
    
    res['body'] = """<html>
    <head>
	<title>hello world</title>
	</head>
	<body>
	<h1>Hello World</h1>
	</body>
    </html>"""

    return res
```

##### 2. ALBを作成して、Lambdaをターゲットにする

##### 3. Canaryを作成する

<img width="620" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/3cc858b7-8e2a-31f4-345e-333b9d3d0caa.png">

ALBのDNS名(または作成していればRoute53のALBのエイリアス)をURLに指定します。
残りはデフォルトで作成します。

### 結果

<img width="1449" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/0b8d5cf0-11ed-6f6b-2803-c4f6c878bfb8.png">


<img width="1445" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/6ca1caeb-7380-6681-fb9a-3565cb7f8319.png">

レイテンシや、スクリーンショットが確認できます。

## リンク切れ監視

### 準備

##### 1. 時々リンク切れにする(=リンク先で404ステータスを返す)Lambdaを用意する

```lambda_link.py
import random

def lambda_handler(event, context):
    path = event['path']
    if path == '/':
        status = 200
    else:
        status = random.choices((200,404), weights = (7,3))[0]
    
    res = {
        "isBase64Encoded": False,
        "statusCode": status,
        "statusDescription": "status: {}".format(status),
        "headers": {
            "Set-cookie": "cookies",
            "Content-Type": "text/html"
        }
    }

    top = """<html>
    <head>
	<title>hello world</title>
	</head>
	<body>
	<h1>TOP Page</h1>
    <a href="/linkA">linkA</a>
    <a href="/linkB">linkB</a>
    <a href="/linkC">linkC</a>  
	</body>
    </html>"""

    link = """<html>
    <head>
	<title>hello world</title>
	</head>
	<body>
	<h1>Linked Page</h1>
	</body>
    </html>"""

    if path == '/':
        res['body'] = top
    else:
        res['body'] = link

    return res
```

##### 2. ALBを作成して、Lambdaをターゲットにする

##### 3. Canaryを作成する

<img width="614" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/f90634c5-fcaa-f2d3-798b-578f28ddc76c.png">

ALBのDNS名(または作成していればRoute53のALBのエイリアス)をURLに指定します。
残りはデフォルトで作成します。

### 結果

<img width="1446" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/f1c6257e-2d9e-a2e3-81e7-2228ba22c5bf.png">

リンク先(LinkB)で404エラーになったのを拾って、失敗のステータスになっていることが確認できます。

## 雑感

技術的にはLambda＋αで目立ったところはないですが、手軽に監視できるところが良いと感じました。
vagrant(CentOS7)とローカルPC間のscpを使用したファイル転送

よく使うわりに毎回忘れそうになるのでメモ

どちらもローカルPC側のコンソールからコマンドを打ってます。

ローカルからvagrant側に送信

```

scp [ファイル名] [ユーザ名]@[サーバIPアドレス]:[ファイル名]
入力例　公開鍵のid_rsa.pubをauthorized_keysにリネームして送信してます
scp ~/.ssh/id_rsa.pub vagrant@192.168.33.10:~/.ssh/authorized_keys

実際はssh-copy-idで渡した方が早いかも・・
ssh-copy-id -i [公開鍵パス] vagrant@192.168.33.10:~/.ssh/
```



vagrantからローカルPC側に送信
vagrantではrootユーザでの送信が多いので例もrootでやってます。
（パスワードの入力を求められる場合はデフォルトであればvagrantと入力すればOK）

``` 
scp [ユーザ名]@[サーバアドレス]:[送信したいファイルバス] [送信したいローカルPCパス] 
入力例　rootユーザでsql-dumpファイルをローカルPCに送信
scp root@192.168.33.10:/var/backup/mysql-dump/20200502.sql.gz .
```

おまけでオプション

```
ディレクトリを再帰的に送信したかったら -r
scp -r somethingDirPath 送信先DirPath

sshdで接続ポートを変更している場合は、-Pオプションで指定
scp -P 9999
```
mongodbのよく使いそうな操作メモ


# mongodbのよく使いそうな操作メモ

自分用メモ

## 接続・切断

mongodbの接続
ローカルホストかつユーザー認証を有効化していない場合は↓で接続できる。

```
> mongo
```


mongodbの切断

```
> exit
```


## DBの操作

### DBの一覧の確認

```
> show dbs;
```


### DBの切替

※存在しないDB名を指定した場合はDBが作成される。

```
> use {db名};
```


### コレクションの操作

#### 一覧表示

コレクション＝RDBでいうテーブルみたいなもの

```
> show collections;
```

#### レコード検索(全件取得)

```
>db.{コレクション名}.find();
```

#### レコード検索(単一条件)

```
> db.{コレクション名}.find({ フィールド名:"値" });
```

#### レコード件数の取得(全件)

```
>db.{コレクション名}.find().count();
```

### CSV出力


```
$ mongoexport --db=[データベース名] --collection=["]コレクション名] --type=csv --fields=[フィールド1,]フィールド2...] --out=[ファイル名]].csv
```


### 参考元
https://qiita.com/k-staging/items/a386d272abb2c9b92f1a

https://qiita.com/itosho/items/138c190e34f5b02cb6d2

https://qiita.com/masarufuruya/items/33fbe059229230c8fc0c
Flutterで起動時に白い画面が長時間表示されるのを解消する

Flutterのアプリを起動すると、しばらく白い画面が表示されますよね。
デバッグビルドだけかと思っていたら、そうでもない。
リリースビルドでも、結構最初の画面が出るまで、その白い画面が表示されている時間が長い。

これはなんぞ？ Flutterの諸々初期化に時間がかかってやむを得ない現象なのか？回避方法は無いのか？

と思っていたら、`android`や`ios`の各フォルダに、こんなファイルがあるのに気づきました。

![android_res.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/98bdae8b-e1d3-7e58-5ea9-37516c44cb15.png)]

![ios_launcher.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/aab0db60-f0dc-850b-bbc3-a9e55846ece9.png)

なんぞ？と思ってそれぞれのファイルや、同じフォルダにある`README.md`を読んでみたところ。

どうやら、スプラッシュ画面用のリソースを設定するところのようで、**デフォルトで真っ白なスプラッシュ画面が起動されている**のだと判明しました。

そこで、この画像を差し替えればいいじゃん！と思って作り始めたもののの・・・

解像度別に用意するの面倒くさいorz

となって、

「アプリアイコンも便利なジェネレータ作って下さっている方がいた。スプラッシュだって有るに違いない」

と探す旅に出たら、案外サクッと見つけてサクッと入れられたので、紹介します。

# 環境など

|ツールなど|バージョンなど|
|:--|:--|
| MacBook Air Early2015|macOS Mojave 10.14.5|
|Android Studio |3.6.1|
|Java |1.8.0_131|
|Flutter|1.12.13+hotfix.5|
|Dart |2.7.0|

# 参考サイト
https://yaba-blog.com/flutter-splash-screen/

他にも色々出てきますが、上記の記事が分かりやすかったです。

# スプラッシュ画面設定手順
## 1.パッケージを導入

[flutter_native_splash](https://pub.dev/packages/flutter_native_splash)というパッケージを入れます。
`pubspec.yaml`に追加ですね。アプリの実行には関係ないので、`dev_dependencies`の方に入れます。

```yaml:pubspec.yaml
dev_dependencies:
  flutter_test:
    sdk: flutter

  ...

  # splash
  flutter_native_splash: ^0.1.9
```

依存ライブラリの指定の後に、以下の記述を入れます。

```yaml:pubspec.yaml
# splash generate sources
flutter_native_splash:
  image: "assets/splash/splash.png"
  color: "97d4d9"
```

インデントに注意してください。`flutter_native_splash:`は`dev_dependencies:`等と同じ階層になければなりません。


```yaml:pubspec.yaml
dev_dependencies:
  flutter_test:
    sdk: flutter

  ...

  # splash
  flutter_native_splash: ^0.1.9

flutter_native_splash:
  ...
```

こういう形になっているはずです。

## 2.スプラッシュ画像の用意

スプラッシュは、背景色＋ロゴ画像で表示されます。

`pubspec.yaml`で指定した、`image`のパスに、ロゴ画像を配置します。
`color`に、背景色をRGB形式で指定します。

画像を画面いっぱいに表示するfill指定も可能です。詳しくは、パッケージのページで確認して下さい。

## 3.生成コマンドを実行

コンソールなどで以下のように実行するだけ。

```console
$ flutter pub get
$ flutter pub run flutter_native_splash:create
```

画像がそれぞれ、以下に配置されます。

- Android
  - `app/src/main/drawable-(解像度)/splash.png`
- iOS
  - `Runner/Assets.xcassets/LaunchImage.imageset`

基本的には以上でスプラッシュが白い画面から、自分が作成したロゴ表示に変わります！

## 4.それでも白い画面が表示される場合

端末のキャッシュによるところがあるみたいですので、一度アンインストールして再インストールすると良いようです。
線形代数の基礎 第8回 - 行列式(3)

　本稿は、線形代数を独学でやり直し勉強した時のメモです。せっかくなのでアウトプットしようと思って書き始めました。詳しくは[第１回](http://qiita.com/nognog/items/8279935a96b4ca5dd375)の説明をご参照ください。今回は、行列式の説明の3回目です。前回からとても（３年くらい）間が空いてしまい、以前この投稿を読まれていた方はすでに線形代数はマスターしてしまっているかも知れませんが、まだたまにLGTMや続きのご要望をいただくこともあるので、続きを書いてみることにしました。

　今回ですが、前回の内容を使って、行列式を求める例題を解いてみることにします。また、例題を解くにあたり、前回ご説明しそびれていた行列式の性質をご紹介します。

# 1. 行列式の性質（前回の続き）

## 1.1. 【性質6】転置行列の行列式

転置行列の行列式は、元の行列の行列式と等しくなります。つまり、

$$
|A^t| = |A|
$$

となります。証明は省略しますが、前回までにご説明しました通り、行列による符号付きの拡大率を表したものが行列式なので、なんとなくイメージつくと思います（よね？）。

## 1.2. 【性質7〜9】行の操作に関する行列式の性質

性質6はとても便利で、この性質により、前回列に対してご説明した性質は、すべて行についても成り立つということになります。つまり、

- 【性質7】ある行と別の行を入れ替えた行列式は元の行列式に-1をかけたものになる。（前回の性質1に相当）
- 【性質8】ある行に、他の行の定数倍を書けたものの行列式は、元の行列式と等しい。（前回の性質2に相当）
- 【性質9】前回の性質5は、行に対しても成り立つ。
ということになります。

性質6を用いて元の行列を転置した後に、前回ご紹介した性質を使うことにより、これらの性質が成り立つことは確認することができます。

# 2. 具体的に、行列式を解いてみる

　次に、具体的な例題として、行列式をこれまでご説明した性質を使って、次の行列式$|A|$を解いてみようと思います。

$$
|A|=
\left|
	\begin{matrix}
		2 & -4 & 1 & -2 \\\
	        0 & 2 & 0 & 1 \\\
		1 & 3 & -1 & 0 \\\
		-1 & 1 & 2 & 2
	\end{matrix}
\right|
$$

 まず、２列目から4列目x2を引きます。このとき、性質1より、求めたい行列式と新しい行列式の値は等しくなります。

$$
|A|=
\left|
	\begin{matrix}
		2 & -4-(-2) \times 2 & 1 & -2 \\\
	        0 & 2-1 \times 2 & 0 & 1 \\\
		1 & 3 & -1 & 0 \\\
		-1 & 1-2 \times 2 & 2 & 2
	\end{matrix}
\right| =
\left|
	\begin{matrix}
		2 & 0 & 1 & -2 \\\
	        0 & 0 & 0 & 1 \\\
		1 & 3 & -1 & 0 \\\
		-1 & -3 & 2 & 2
	\end{matrix}
\right|
$$

 次に、１行目と２行目を入れ替えます。この時、性質7より、行列式は負号が反対になります。
$$
|A|= -
\left|
	\begin{matrix}
		0 & 0 & 0 & 1 \\\
	        2 & 0 & 1 & -2 \\\
		1 & 3 & -1 & 0 \\\
		-1 & -3 & 2 & 2
	\end{matrix}
\right|
$$

 さらに、１列目と４列目を入れ替えます。また負号が反転します。
$$
|A|= -
\left|
	\begin{matrix}
		1 & 0 & 0 & 0 \\\
	        -2 & 0 & 1 & 2 \\\
		0 & 3 & -1 & 1 \\\
		0 & -3 & 2 & -1
	\end{matrix}
\right|
$$

 １行目の２〜4列目の値が0なので、性質9が使えて、
$$
|A|= 1 \times
\left|
	\begin{matrix}
	        0 & 1 & 2 \\\
		3 & -1 & 1 \\\
		-3 & 2 & -1
	\end{matrix}
\right|
$$

さらに、3列目から2列目x2を引いても行列式の値は変わらないので、
$$
|A|= 1 \times
\left|
	\begin{matrix}
	        0 & 1 & 2 - 1 \times 2 \\\
		3 & -1 & 1 - (-1) \times 2\\\
		-3 & 2 & -1 - 2 \times 2
	\end{matrix}
\right| = 1 \times
\left|
	\begin{matrix}
	        0 & 1 & 0 \\\
		3 & -1 & 3\\\
		-3 & 2 & -5
	\end{matrix}
\right|
$$

次に1列目と2列目を入れ替えると、負号が反転し、
$$
|A| = -1 \times 
\left|
	\begin{matrix}
	        1 & 0 & 0 \\\
		-1 & 3 & 3\\\
		2 & -3 & -5
	\end{matrix}
\right|
$$

さらに、また性質9を使うと、
$$
|A| = -1 \times 1 \times 
\left|
	\begin{matrix}
		3 & 3\\\
		-3 & -5
	\end{matrix}
\right|
$$

残った行列式は、$2 \times 2$行列の行列式なので、高校で習う行列式の公式$ad-bc$を使って計算すると、めでたく行列式を求めることができます。
$$
|A| = -1 \times 1 \times (3 \times (-5) - (-3) \times 3) = 6
$$

# 3. まとめ
　今回は具体的に行列式の例題を解いてみました。実際の業務では、自分で行列式を解くことが必要な場面はほとんどないと思いますが、前回と今回でご紹介した行列式の性質、さらには、その背景にある、**<Font color="red">「行列式は負号付きの拡大率」</Font>**ということの理解はとても重要だと思います。

　次回は逆行列の説明を考えています。（あまり間が空かないで投稿するようにできればと。。）
WebRTCで顔認識＋バーチャル背景

[**agoraがよくわかる！無料セミナー実施中！>**](https://jp.vcube.com/service/agora#seminar)  

zoomのバーチャル背景がバズっていますが、WebRTCでも顔認識や体の認識ができるOSSがあるので試してみました。
今回は顔だけ認識させて、顔の部分だけ映像として生成するサンプルになります。
ブラウザで顔＋体を認識させるには処理能力的に限界がありそうで、実質顔だけ認識させるのが現実的な実装のように思います。


##利用するライブラリ
今回、顔の認識については[pico.js](https://github.com/tehnokv/picojs)を利用しました。
その他には[clmtrackr](https://github.com/auduno/clmtrackr)もよく知られているようです。

##完成イメージ
<img width="1552" alt="スクリーンショット_0002-05-03_0_28_58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/65ea6db0-918b-780b-c482-5b0d38a27140.png">
canvasの背景として画像をセットし、顔認識できた範囲に対して円でくり抜きをしています。

サンプルコードは[こちら](https://github.com/fu-jimoto/AgoraIO-Virtual-Background-Face-Only)に公開しています。

##コードの説明
主なポイントは4つです。
・Webカメラの映像をcanvasに描画
・カメラ映像を解析
・顔の範囲を円でくり抜き
・配信する映像ソースとして設定

###Webカメラの映像をcanvasに描画
```javascript:index.html

navigator.mediaDevices.getUserMedia({ auduo: false, video: { width: videoSource.width, height: videoSource.height } }).then(stream => {
  videoSource.srcObject = stream;
  videoSource.onloadedmetadata = function () {
    drawLoop();
  };
});
//中略
context.globalCompositeOperation = 'source-over';
context.drawImage(videoSource, 0, 0, videoSource.width, videoSource.height);
```
WebRTCではおなじみのgetUserMediaでカメラ映像を取得し、canvasに描画します。

###カメラ映像を解析

```javascript:index.html
dets = pico.run_cascade(image, facefinder_classify_region, params);
dets = update_memory(dets);
dets = pico.cluster_detections(dets, 0.2);
```
このあたりは本家のコードをそのまま利用しています。

###顔の範囲を円でくり抜き
```javascript:index.html
context.globalCompositeOperation = 'destination-in';

if(dets.length >= 1 && dets[0][3] > qthresh){
  dx = dets[0][1];
  dy = dets[0][0];
  radius = dets[0][2]/2*0.8;//積極的に背景を隠す
  context.beginPath();
  context.arc(dx, dy, radius, 0, Math.PI*2, false);
  context.fill();
}else{
  context.beginPath();
  context.arc(dx, dy, radius, 0, Math.PI*2, false);
  context.fill();
}
```
destination-inは「重なった領域のみが描画される」という設定になります。
又、背景を隠すという意味で円の半径も解析値より0.8倍程度に補正をかけています。


###配信する映像ソースとして設定
```javascript:index.html
rtc.maskedStream = canvas.captureStream(15);
//中略
rtc.localStream = AgoraRTC.createStream({
  streamID: rtc.params.uid,
  audio: true,
  video: true,
  screen: false,
  microphoneId: option.microphoneId,
  videoSource: rtc.maskedStream.getVideoTracks()[0]
  //cameraId: option.cameraId
})
```
こちらはagoa.io SDKのAPI部分になります。canvasのストリームを取得して、videoSourceのパラメータとして設定しています。


##微妙に残った課題
今回の実装方法では背景画像について送信するストリームに乗ってきません。実際、もう少しcanvas部分に手を加えれば可能かもしれません。
その他の方法としては利用している背景画像のURLを相手にも通知してcssで表示させるというやり方になります。


#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=7eb96b46f6f54159c26f)
[**agoraがよくわかる！無料セミナー実施中！**](https://jp.vcube.com/service/agora#seminar)  
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=7eb96b46f6f54159c26f)
【Django】フォームからviews.pyでクエリ結果をフィルタする方法

# 環境
- Django 2.0.2

# 実施内容
- views.pyでformから送信された検索のクエリを受け取る
- 本紹介では、変数名：query

```views.py
 def get_queryset(self):
 q_word = self.request.GET.get('query')
 object_list = ServiceModel.objects.filter(
               Q(service_title__icontains=q_word) or Q(service_catch_copy__icontains=q_word))
```

-formタグでqueryを送信

```html
<form method="get" action="">
　<div class="form-group">
　　<input class="form-control" name="query" value="{{ request.GET.query }}" id="exampleFormControlInput1" type="text" placeholder="例）画像認識など">
　</div>
　<button type="submit" class="btn btn-info btn-block">検索</button>
</form>
```

- 参考サイト
- [Djnagoドキュメント](https://docs.djangoproject.com/ja/2.0/intro/tutorial04/)
Windows上のWireSharkでリモートのLinuxのtcpdumpをリアルタイムで表示する

# 概要
- Windows上でWireSharkを起動し、リモートのLinuxのtcpdumpの結果をリアルタイムで表示する
    - SSHトンネルでリモートのtcpdumpの結果をWireSharkの入力にリダイレクト（？）する

![remote-captya.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/0f8c1e7d-4167-ef62-ca22-11d72c95b3bd.png)


# 方法

## 前提
### 確認環境
- Windows 10 64bit
    - WireShark 3.2.3
- Amazon Linux release 2 (Karoo)
    - tcpdump version 4.9.2

### 条件
- Windowsからコマンドプロンプトで対象のLinuxにsshできる
- 対象のWindowsにWireSharkがインストールされている
    - コマンドプロンプトで `wireshark` が実行できる
- 対象のLinuxにtcpdumpがインストールされている

## コマンド

- コマンドプロンプトで以下のワンライナーでOK。
- tcpdump のパス等は適宜読み替えのこと。
- 一点注意点は普通にSSHでログインする時と通っているパスが異なるようなので、 `ssh [RemoteHost] -i [SSH Key] echo $PATH` 等で通っているパスを確認しておくとハマりポイントを一つ回避できるかも。

```
c:\>ssh [RemoteHost] -i [SSH Key] "sudo /usr/sbin/tcpdump -U -w - -i eth0" | wireshark -k -i -
```

# 参考

Wireshark Tcpdump Remote Capturing - YouTube https://www.youtube.com/watch?v=C7nhdAL9oPg

CaptureSetup/Pipes - The Wireshark Wiki https://wiki.wireshark.org/CaptureSetup/Pipes#Remote_Capture
aspidaでAPIが返す型をexportするファイル置き場おススメ2パターン

[aspida](https://github.com/aspidajs/aspida/tree/master/packages/aspida/docs/ja)のエンドポイントが返すUserとかArticleのような型をReact/Vueのファイルでimportしたい場合のベストプラクティス的なものを2パターン紹介します。
`~`がプロジェクトルートのパスエイリアスとして登録されてる前提で書きます。

## 前提
**Userに関するエンドポイントのファイルが二つ**
1. `/apis/users/index.ts` (GETでUserのリストが得られる)
2. `/apis/users/_userId.ts` (パス変数userIdで特定のUserが得られる)

※`/apis/users.ts`と`/apis/users/_userId.ts`の組み合わせで作ると`/apis`直下に同名ファイルとディレクトリが出来てしまってエンドポイント名の`users`に変更があった際2か所変更が発生するので`/apis/users`ディレクトリにまとめるのが良い

**Userを描画するtsxファイルが一つ**
1. `/pages/example.tsx`

## 1.リストを返すエンドポイントのファイルでexport

リストを返すエンドポイントのファイル`/apis/users/index.ts`で`User`型をexportします。

`/apis/users/index.ts`

```typescript
export type User = {
  id: number
  name: string
}

export type Methods = {
  get: {
    resBody: User[]
  }
}
```

`/apis/users/_userId.ts`

```typescript
import { User } from './'

export type Methods = {
  get: {
    resBody: User
  }
}
```

`/pages/example.tsx`

```tsx
import { FC } from 'react'
import { User } from '~/apis/users'

type UserProps = { user: User }

const App: FC<UserProps > = ({ user }) => <h2>ユーザー名：{user.name}</h2>

export default App
```

### メリット
- エンドポイントと一緒に型を書いていくのでラク
- エンドポイントを削除したときに不要になった型を消し忘れることがない

### デメリット
- エンドポイントが増えるとtsxでimportしたい型を探すのが面倒
- 定義ファイルがバラバラなので型ごとにimportが必要

小～中規模はこの方法が楽だと思います。

# 2.typesファイルにまとめてexport

aspidaが変換対象から無視する`/apis/@types.ts`でまとめてexportも出来ます。

`/apis/@types.ts`

```typescript
export type User = {
  id: number
  name: string
}
```

`/apis/users/index.ts`

```typescript
import { User } from '~/apis/@types'

export type Methods = {
  get: {
    resBody: User[]
  }
}
```

`/apis/users/_userId.ts`

```typescript
import { User } from '~/apis/@types'

export type Methods = {
  get: {
    resBody: User
  }
}
```

`/pages/example.tsx`

```tsx
import { FC } from 'react'
import { User } from '~/apis/@types'

type UserProps = { user: User }

const App: FC<UserProps > = ({ user }) => <h2>ユーザー名：{user.name}</h2>

export default App
```

### メリット
- 複数の型をまとめてimportできる
- さらに増えても`/apis/@types/`ディレクトリに複数ファイルを置いて`/apis/@types/index.ts`でまとめてexportできる

### デメリット
- 使われなくなった型を消し忘れる
- エンドポイントを定義するときにファイルの行き来がちょっと面倒

中～大規模はこの方法がおすすめ。
`/types.ts`ではなく`/apis/@types.ts`が良い理由は、API由来の型であることがわかりやすくなることと、aspidaの隠し機能と相性が良いからです。
[aspidaの隠し機能まとめ - Qiita](https://qiita.com/ibuki2003/items/5b42523e214eb99af95a#%E3%83%91%E3%82%B9%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AE%E5%9E%8B%E3%82%92%E6%8C%87%E5%AE%9A)
GPGPU入門_処理の基本とデメリットをイラスト付きで解説

「プログラマ初心者にもわかりやすい解説」を目標にしています。 分かりやすさとイメージを重視するため、正確じゃないことを書いています。ご理解ください。

#GPGPUとは
リンク：[前回の記事をご覧ください](https://qiita.com/yamataroVoid/items/8c93e487d9048fc8e16f)

#GPGPUの高速の仕組みを一言で説明する
GPGPUは、GPUという機械を使ってforループを早くする仕組みです。
![computer_graphic_card.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597581/a8b2283c-56a0-91be-714a-c1ecb08feb34.png)

#GPGPUの仕組み
パソコンには「CPU」という機械と「GPU」という機械が入っています。
![internet_screenshot_computer小さい.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597581/4e731e5b-b371-3add-d553-c39664c6f2ee.png)![キャプチャ_小さい.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597581/a1026765-23fd-1598-487f-82c4f83d08b4.png)

皆さんが普段プログラムしているソースを実行しているのは
「CPU」という機械が行っています。

GPGPUは「CPU」ではなく、「GPU」を使ったプログラムの事です。
![GPUだよ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597581/e343a827-e9e7-2b54-4d55-24db3ebf7410.png)

GPUって何？という方は、今は知らなくて大丈夫です。
「普段使っているCPUとは違う機械が処理をする」ということだけ何となく覚えてください。

といってもプログラムの言語が違うだけで、
普段みなさんがやってるプログラムと大した違いはありません。

#GPGPUで高速化できる例
GPGPUはAIやビッグデータでよく使われています。

囲碁や将棋のAIも、高段位の棋士にも勝てるようになったのは
GPGPUの恩恵が大きいそうです。

どのくらい高速化されるのかは処理によりますが、イメージとしては
・CPUで数日～数ヶ月⇒GPGPU：数時間～数十時間

#GPGPUの処理フロー
![GPGPUフロー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597581/36044fcf-a105-7086-bab2-24531e362f1a.png)

GPUは1000個のスレッドを使って処理を高速化しています。
リンク：[前回の記事をご覧ください](https://qiita.com/yamataroVoid/items/8c93e487d9048fc8e16f)

GPUはそれ単体で動かすことはできません。
必ずCPUからGPU処理開始の実行命令を出します。

そのため、単純なfor文を高速化するだけでも
CPUとGPUの両方のプログラムを書く必要があります。

#GPGPUで高速化できない例
forループを早くするGPGPUですが、ファイルアクセスができません。
ファイルアクセスができるのはCPUのみだからです。

forループ中にファイルアクセスが必要な場合は、CPUで処理を工夫する必要があります。
・CPUで事前にファイルを読み込んでおく
・GPU処理が終わってから、処理結果をファイルに書きこむ

#GPGPUの対応言語
主に3Dプログラムを扱う言語が対象になります。
・WebGL、Unity、Javaなどで、GPGPU用のライブラリが用意されています
・本気で高速化する場合は、GPU専用言語のCUDA一択らしいが環境制限などがある（2020年現在）
　※CUDAの場合はGPUもNVIDIA製である必要があります

#GPGPUを始める前に
GPGPUは元々、3Dの描画プログラムをAI等に流用したものです。

3Dのプログラムと聞くと、なんとなく敷居が高いイメージがありますね。
おそらく、プログラム初級者や3Dに慣れていない方のイメージよりも、ちょこっと難しいです。
一般的なUnityなどのスキルとはちょっと違い、3Dプログラム経験がある＝GPGPUできる人材という訳でもないです。

難易度が高いので仕事で必要とされていないのであれば、あまり手を出すのはオススメしません。
（趣味ではオススメですよ。それなりに楽しいです！）

なぜかというと
・（業種によるが）できる人材が少ない
・開発期間が普段の開発（CPUの開発）に比べて長くなる（2倍～くらい？）
・頑張ってGPGPU化するよりPC環境やプログラムの見直しをした方が高速化される可能性もある
・というか中途半端にGPGPU化すると逆に遅くなる
からです。

人材と処理内容によりますが、
高速化するために1からGPGPUに手を出して数ヶ月2000万かけてGPGPU化するよりも、
PCのメモリ増設やHDD⇒SSDの変更などで高速化できるなら
その方がコスパが良いのではないでしょうか。

こちらの記事が参考になります。
リンク：[GPGPUに手を出す前に検討すべき事について](https://qiita.com/tmasda/items/affbc423d32a081d384e)
リンク：[プログラムを高速化する話Ⅱ 〜GPGPU編〜]
(https://www.slideshare.net/KMC_JP/gpgpu-91122680)
↑チューニング前は速度が「CPU」よりも55倍遅かったらしい（内容は難しいので全部理解する必要はないです）

#求められる人材と勉強期間
・3Dの「シェーダー」を書ける、理解できる人
・積極的に知識を求められる人（プログラムの勉強に抵抗ない人）
　└参考サイトが少ないのと3Dプログラムの知識が必要なため、
　　１からの独学だと早い人でも数週間～２ヶ月以上かかるイメージ

Qiitaを日常的に見たり、1記事でも書いたことがあるような人は概ね大丈夫じゃないでしょうか。

求められる人材が少ないと書きましたが、業種にもよると思います。

実際ゲーム業界はゴロゴロいましたし、
まあそういう人達向けの記事じゃないからいいかな。

#自分が勉強した時に参考にしたサイト
3DとGPGPUの参考にしたサイト
・元がWebGL(JavaScript)なので理解しやすい
・開発環境が用意しやすい
・3Dの基礎から学べる
・知ってる限り日本で1番WebGLについて分かりやすいサイト
リンク：[wgld.org](https://wgld.org/d/webgl/)
EC-CUBE奮闘記①　～EC CUBE4.0をXAMPPで実行～

#0.自己紹介

これが初記事なので、自己紹介をしたいと思います。地方で情報系の大学生やってるikoma1234と申します。今日からEC-CUBEを使ってECサイトを制作することになりました。

僕は現在、市内のEC業者でデータ入力のアルバイトをしています。（楽天、yahoo、Amazonなどへの商品登録）

データ入力自体は難しい仕事じゃないので、Pythonでソフト作って効率化とかしてました。
画像制作ソフト、メール便くん
→https://github.com/ikoma1234/mail-bin-kun

商品説明文生成ソフト、商品説明くん
→https://github.com/ikoma1234/setsumei-kun

#1.ことの始まり



そんなこんなでまったり働いていたのですが、この度自社製のECサイトを作ろう！という運びとなり、パソコンが詳しいという理由で仕事を任せてもらえました。一介の学生アルバイトの身に余るほどの裁量のある仕事で、とても緊張しています。

このブログは活動記録として残すことにしました。拙いところもあると思いますが、気軽に見ていってほしいです。
#2.今日やったこと

##2.1.いろいろダウンロード

OSはwindows 10、ローカルホストにはXAMPPを使います。

まずはEC-CUBE4.0をダウンロードします。会員登録の際に会社名と自分の役職を入力するのですが、見栄張って「学生」じゃなくて「エンジニア」にしちゃいました。背筋が伸びますねぇ～
https://www.ec-cube.net　

次にXAMPPをダウンロード。EC-CUBEのシステム要件に対応するバージョンを選びます。
https://www.apachefriends.org

次にcomposerもダウンロード。これでPHPのパッケージ管理をします。
すでにXAMPPがインストールされていれば、画面の指示通りに押してインストール完了です。
https://getcomposer.org/download/

ダウンロードが終わったら、先ほどのEC-CUBEをXAMPPのhtdocsに突っ込んで解凍。これで必要ファイルは整いました。

##2.2.EC-CUBE 4.0をインストールしよう！

一通り終わったら、XAMPPディレクトリ直下のxampp-control.exeを起動。ApacheとMySQLをオンにします。

次に（Apacheのポート番号が80ならば）
http://localhost:80/phpMyAdmin
に接続。こんな画面が出るはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630640/0f09e305-da37-fef8-fcc8-7ac2d30a532f.png)
でたら左上のデータベースをクリック。適当な名前でデータベースを入力、デフォルトの照合順序と一緒に作成ボタンを押します。

ここまで来ればあと少しです！
http://localhost/eccube4.x.x
に接続します。4.x.xはバージョンの数字です。

あとは画面の指示に従ってインストールします。ここでいくつか問題があり...

###スタックオーバーフロー

！ローカルホストの応答時間が長すぎて、Error: Maximum execution time of 30 seconds exceededとか表示される場合があります。
この場合は、xampp/php/php.iniファイルを編集、
max_execution_time = 30
を
max_execution_time = 300にしましょう。

！xamppのデータベースで、rootは初めからパスワード設定されていません
パスワード設定したい場合は
http://localhost/phpmyadmin/server_privileges.php?viewing_mode=server
の（特権を編集）ボタンから設定できます。その際、xampp\phpMyAdmin\congig.inc.phpのファイルを書き換えることも忘れずに。

！データベースをフォーマットする際、ERROR The　Symfony\Component\Intl\Locale\Locale::parseLocale() is not implemented. Please install the "intl" extension for full localization capabilities.とか出てきます。
この場合も、xampp/php/php.iniファイルを編集、
;extension=intl.dll
を
extension=intl.dllにしましょう。その後Apacheを再起動すれば治るはずです。

全てが終わったらこんな画面になるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630640/3c852a42-fdfc-4c5e-fb8a-42e5e00a7846.png)
(id、パスはフェイクです。)

この時のURLは管理画面に直結するので、人に教えないようにしましょう。（URL付きでスクショ撮ってから気づいた、あぶねぇ～）お疲れ様でした！

#3.今日の感想
やったことこんだけなのに、めちゃくちゃ疲れました。やり方ググっても古いやつはあてにならないし、MAMPでやろうとしたらintlのインストールで詰まるし...　重要な説明端折ってやり方書かないでくれ～（何様だ）

ともあれコロナ禍にGW、時間はたっぷりあります。頑張ってセキュリティ、UI、UX最強のECサイトを作るぞ！ウオオ
Laravel タイムゾーンを日本に変更する

# 目的

- タイムゾーン変更の方法をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 実施方法

1. 下記コマンドをアプリケーションディレクトリで実行してアプリ設定ファイルを開く。

    ```terminal
    $ vi config/app.php
    ```
1. 70行目付近に記載されている`'timezone' => 'UTC',`をコメントアウトする。
1. コメントアウト直後に下記を追記する。

    ```アプリ名ディレクトリ/config/app.php
    'timezone' => 'Asia/Tokyo',
    ```
1. 82行目付近に記載されている`'locale' => 'en',`をコメントアウトする。
1. コメントうと直後に下記を追記する。

    ```アプリ名ディレクトリ/config/app.php
    'locale' => 'ja',
    ```
1. config/app.phpが下記のように修正された事を確認する。

    ```アプリ名ディレクトリ/config/app.php
    /*
    |--------------------------------------------------------------------------
    | Application Timezone
    |--------------------------------------------------------------------------
    |
    | Here you may specify the default timezone for your application, which
    | will be used by the PHP date and date-time functions. We have gone
    | ahead and set this to a sensible default for you out of the box.
    |
    */

    /*     'timezone' => 'UTC', */
      'timezone' => 'Asia/Tokyo',
    /*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    /*     'locale' => 'en', */
    'locale' => 'ja',
    ```
rails devise インストール

# deviseでユーザ管理機能を実装

ユーザー管理機能を実装に、「devise」を使用します。
最初にインストールを行います。

手順の流れとしては、Gemファイルにインストールをする為、Gemfileに追記します。
Gemfileの一番下に追記をしましょう。

`Gemfile`

```
（前略）
gem 'devise'
（後略）
```

以下のように、group内に記述すると、書き方もあります。
特定の環境でのみ使用する設定になってしまいます。

deviseは開発、テスト、本番いずれの環境でも使用しますので注意しましょう。

<font color="Red">NG例</font> 
`Gemfile`

```
group :development do # developmentは開発
  gem 'devise'
end
```
上記に書いてある通り、deviseは開発、テスト、本番いずれの環境でも使用しますので、
この記述だとdevelopment環境のみなので、development環境から、
テストや本番環境に移行していくので、その際に対応できなくなってしまいます。

#deviseのインストールを行おう

続いてGemおよびdeviseのインストールを行います。deviseの場合は、
bundle installの他にdevise用のインストールコマンドの実行が必要なので注意します。

deviseを使用するためには、Gemのインストールに加えてdevise専用のコマンドを利用して
設定ファイルを作成する必要があります。

`ターミナル`

```
$ bundle install　# gemをインストールするためのコマンドです。
$ rails g devise:install　# deviseの設定ファイルを作成
```

# deviseの機能を持ったUserモデルを作成しよう

deviseを利用する際にはアカウントを作成するためのUserモデルを新しく作成します。
作成には通常のモデルの作成方法ではなく、deviseのモデルの作成用コマンドでUserモデルを作成しましょう。

deviseで使用するモデルは、rails g devise <モデル名>コマンドで作成できます。
Userモデルの作成は、rails g devise user コマンドで作成が出来ます。

`ターミナル`

```
$  rails g devise user # deviseコマンドでモデルを作成
```

* 新規作成されるファイル
* app/models/user.rb
* db/migrate/20XXXXXXXXXXXX_devise_create_users.rb
* test/fixtures/users.yml
* test/models/user_test.rb


また補足として、config/routes.rbに以下の様な記述が自動的に追記されます。

`config/routes.rb`

```
Rails.application.routes.draw do
  devise_for :users
#以下略
```

次にマイグレーションファイルを開き、t.string :name, null: false と add_index :users, :name,
 unique: trueを下記の様に追記しましょう。
これで、マイグレーション実行時にnameカラムがNOT NULL制約・一意性制約付きで作成されます。

`db/migrate/マイグレーションファイル`

```

class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :name,               null: false　# 追記する
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""

      # 〜省略〜
    end

    add_index :users, :name, unique: true　# 追記する

# 〜省略〜

```

NOT NULL制約では空の文字列は保存可能なため、validatesを使用します。
更にuser.rb に validates :name, presence: trueと追記し、空の文字列の場合もエラーが発生する様にしてください。

`app/models/user.rb`

```
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable

  validates :name, presence: true, uniqueness: true # 追記する

end
```

最後にマイグレーションを実行し、データベースに反映をさせましょう。

`ターミナル`

```
$ rails db:migrate　# 作成されたマイグレーションファイルを実行
```

# コマンドを誤った場合の対応方法

誤ったコマンドを実行してしまった場合は、以下を参考に修正を行います。

##rails gコマンドの誤り

rails g model userコマンドでファイルを作ってしまった場合は、
下記のコマンドを実行してファイルの削除を行いましょう。

`ターミナル`

```
rails d model user
```

## マイグレーションファイルの誤り

マイグレーションファイルの記述を誤ったままマイグレートしてしまった場合は、
下記のコマンドを実行してからもう一度やり直します。

`ターミナル`

```
 rails db:rollback 
```
AWS Cloud9で行番号を表示させる


AWS Cloud9で行番号を出力させる方法がわからなかったので備忘録として残します。

1. Cloud9を立ち上げ, 「Preferences」を選択
2. 「USER SETTING」>「Show Line Numbers：」をNormalに選択
3. 「Show Gutter」がオン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483101/3c96acc9-395b-db17-e01d-1224d208dafb.png)
【MongoDB】ObjectId以外のプライマリキーを使う

# MongoDBでは`ObjectId`の代わりに任意の値をプライマリキーとして使うことができる

今回はMongoDBでのプライマリキー（主キー）の扱いの話です。

MongoDBでの主キーフィールドには実は**任意の値を入れることが可能**だったという話です。
調べても意外にもそのことに言及した書き込みが出てこなかったため書くことに。

## まず前提から
MongoDBを使っていた際にプライマリキーにデフォルトのデータ型以外の値を入れたい場合が出てきました。

MongoDBではデフォルトのプライマリキーは`ObjectId`です。

- [MongoDB Manual - ObjectId](https://docs.mongodb.com/manual/reference/method/ObjectId/)

MongoDBの`ObjectId`というのは12バイトの値を持つデータ型で、ドキュメント（RDBMSではレコードに相当）を作成するときにMongoDBによって自動的に生成されます。一意の値を持つように生成されるので、MongoDBではRDBMSにおける自動インクリメントされる整数に代わってプライマリキーとして使われます。

具体的には下のようなデータで、キーは必ず`_id`になります。

```
{ "_id" : ObjectId("507f1f77bcf86cd799439011") }
```

この`_id`にObjectId以外の値を入れたかったのですが、調べたところ次の記事に答えがありました。

- [MongoDB Manual - [Documents] The _id Field](https://docs.mongodb.com/manual/core/document/#the-id-field)

## `_id`フィールドの値はユーザー任意のデータで上書き可能

つまり、**`_id`フィールドの値には文字列、整数（`1`, `2` etc...）や日付（JSのDateオブジェクト）を入れることも可能**ということ。

ただしこの場合、`{_id: 1}`というようにユーザーが明示的に`_id`フィールドの値を書く必要があります[^1]。

[^1]: ちなみに`_id`というフィールド名を変更することはできない。必ず`_id`という名前のフィールドがプライマリキーになるようになっている。

もしも、**入力データに`_id`フィールドがなかった場合はDB側で自動的に`ObjectId`型のプライマリキーが生成される**実装になっているようです。

このように上書き可能な値ですが、ObjectIdを任意の値で上書きするには１つだけ条件があります。それは...

- **`_id`フィールド内で一意な値をもつこと（値が同カラム内で重複しない）**

考えてみればプライマリキーなので値が重複しないことが条件なのは当たり前といえば当たり前です[^2]。

[^2]: ちなみにMongoDBはスキーマレスなNoSQLなので`_id`フィールド内のデータの型は同じである必要はない。例えば同一フィールド内の値に整数と文字列が混ざっていても問題ない。

## UUIDなど一意な値を使うときに利用できるかも
値が一意でないといけないので、実際にObjectId以外だと使う場合が限られそうですが、
UUIDやULIDなどで代替したい場合にいいかも。

- 参考：[ID生成大全](https://qiita.com/kawasima/items/6b0f47a60c9cb5ffb5c4)

また、自動インクリメント整数をプライマリキーにすることも↓のような方法があるので組み合わせて実現できそうです。（こういう場合は素直にRDBMS使った方が楽だと思いますが）

- [MongoDB で 自動インクリメント シーケンス を 作成する 方法](https://garafu.blogspot.com/2018/01/mongodb-collation-restriction.html)
PHP Guzzle HTTP Client Example With PHP 7/Laravel

This tutorial help to Understand PHP Guzzle HTTP Client with Laravel.We will create Rest API access using Guzzle Client with laravel. The Guzzle is the most popular PHP HTTP client that makes it easy to send HTTP requests Using HTTP method GET, POST, PUT and DELETE.

https://www.phpflow.com/php/php-guzzle-http-client-example-with-php-7-laravel5/
Atcoder ABC165 A-DをPythonで

開始が10分遅れるトラブル。

#A. We Love Golf
aからbの値を全探索して、kで割り切れればOK

```ABC165a.py
a=int(input())
b,c=map(int,input().split())

for i in range(b,c+1):
    if i%a==0:
        print("OK")
        exit()
print("NG")
```

#B. 1%
複利を含めた合計額がx円を超えるまでwhile文を回す。毎回floorで切り捨てるのを忘れずに。

```ABC165b.py
import math

x=int(input())
y=100
i=0
while True:
    y=math.floor(y*1.01)
    i+=1
    if y>=x:
        print(i)
        exit()
```
#C. Many Requirements
得られるポイントの上から取っていくのかなとかa,bの重複を削除するのかなとか色々考えてたら時間を大幅にロスした。$N, M, Q$ともに小さいので、想定される数列を全探索しても十分間に合います。
Itertoolsのcombinations_with_replacementを使って想定される数列を全て作成し、得点の最大値を出力します。

```ABC165c.py
from itertools import *

n,m,q=map(int,input().split())

aaa=[]
for i in range(m):
    aaa.append(i+1)

l=[]
for i in range(q):
    a=list(map(int,input().split()))
    l.append(a)

a=list(combinations_with_replacement(aaa,n))
ans=0

for i in a:
    aa=0
    for j in l:
        if i[j[1]-1]-i[j[0]-1]==j[2]:
            aa+=j[3]
    if aa>ans:
        ans=aa
print(ans)
```

#D. Floor function
第二項は$x<B$の時$0$、それ以外の時は正の整数になります。よって$x$$\equiv$$B-1 (modB)$の時$f(x)$は最大になり、その関数は矩形波になります。例として$a=100, b=20$としたときの$f(x)$を以下に示します。
![ABC165.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618614/10d8efdc-8f18-d42e-ebe0-6845289a62da.jpeg)

よって、$n>=B$の時は$x=b-1$、$n<B$の時は$x=n$として$f(x)$を出力すればよいです。

```ABC165d.py
import math

a,b,n=map(int,input().split())

if b<=n:
    print(math.floor(a*(b-1)/b))
else:
    print(math.floor(a*(n)/b))
```

今日もD問題までで時間を使い果たしてしまった・・DPとか探索アルゴリズムとか、勉強したものを早く実践で使いたい。