OmniAICreator/Qiita-1.07M huggingface dataset:
企業経営と組織

# 問題１
### コーポレートガバナンスを説明したものはどれか？
#### コーポレートガバナンスとは？
```Corporate Governance: 企業統治```の意味。
不正などが発覚すると企業価値は損なわれ、株主などのステークホルダは不利益を被る。
コーポレートガバナンスは、適正な経営がなされているか、主に```社外のステークホルダが監督・監視```する仕組みのこと。

# 問題２
### BCPの説明はどれか？
#### BCPとは？
```Business Continuity Plan: 事業継続計画```の略。
緊急事態に備えるための対応計画。迅速に適切な対処を行い、```損害を最小限```に抑えて、```事業の継続```や```早期復旧```を図ることを目的とする。災害や事故、テロなどの発生時にいつの時点で・どの部署が・どう対処するかを事前に```マニュアル化し、訓練```を行っておく。

# 問題３
### ワークシェアリングの説明はどれか？
#### ワークシェアリングとは？
労働者の勤務時間を短縮したり、複数の労働者で分配するなど業務の配分を見直すことで、より多くの雇用を確保する方法。```雇用の安定と創出```を目的としている。

# 問題４
### 社内カンパニー制を説明したものはどれか？
#### 社内カンパニー制とは？
企業の組織形態のひとつです。```複数の事業を推進している企業```において、その個々の```事業を独立採算の形式```で進めます。その```事業ごとをひとつの会社のように位置```づけて、各事業展開を行っていくのです。
##### 出典
https://www.reloclub.jp/relotimes/article/10664#:~:text=%E4%BC%81%E6%A5%AD%E3%81%AE%E7%B5%84%E7%B9%94%E5%BD%A2%E6%85%8B%E3%81%AE%E3%81%B2%E3%81%A8%E3%81%A4%E3%81%A7%E3%81%99%E3%80%82%E8%A4%87%E6%95%B0%E3%81%AE%E4%BA%8B%E6%A5%AD%E3%82%92%E6%8E%A8%E9%80%B2%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E4%BC%81%E6%A5%AD%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6%E3%80%81%E3%81%9D%E3%81%AE%E5%80%8B%E3%80%85%E3%81%AE%E4%BA%8B%E6%A5%AD%E3%82%92%E7%8B%AC%E7%AB%8B%E6%8E%A1%E7%AE%97%E3%81%AE%E5%BD%A2%E5%BC%8F%E3%81%A7%E9%80%B2%E3%82%81%E3%81%BE%E3%81%99%E3%80%82%E3%81%9D%E3%81%AE%E4%BA%8B%E6%A5%AD%E3%81%94%E3%81%A8%E3%82%92%E3%81%B2%E3%81%A8%E3%81%A4%E3%81%AE%E4%BC%9A%E7%A4%BE%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E4%BD%8D%E7%BD%AE%E3%81%A5%E3%81%91%E3%81%A6%E3%80%81%E5%90%84%E4%BA%8B%E6%A5%AD%E5%B1%95%E9%96%8B%E3%82%92%E8%A1%8C%E3%81%A3%E3%81%A6%E3%81%84%E3%81%8F%E3%81%AE%E3%81%A7%E3%81%99%E3%80%82

#### カンパニー制と事業部制の違い
事業部制は独立型ではない、という点がカンパニー制との大きな違いです。重要な意思決定、経営、人事に関する内容については、```本社や企業全体の承認や意向が、常に絡んできます```。外部（本社や企業全体）の判断を常に仰がなければ進められません。カンパニー制と比較すると、```意思決定や判断スピードが劣る```ことになります。

カンパニー制の場合は、それぞれのカンパニーの裁量の範囲が広がります。たとえば、```投資権、採用や配置などの人事の権限も譲渡```されるのです。資金調達においても、資本金や借入金が事業ごとに発生し、本社から出される資金も区分されます。法的には社内計上扱いとなりますが、```カンパニー制上は別会社扱い```ということです。
##### 出典
https://www.reloclub.jp/relotimes/article/10664#:~:text=%E4%BA%8B%E6%A5%AD%E9%83%A8%E5%88%B6%E3%81%AF,%E3%81%A8%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82

# 問題５
### CIOが経営から求められる役割とは？
#### CIOとは？
```Chief Information Officer: 最高情報統括役員```の略。
```情報システム戦略の策定・実施```について、主導する責任を負っている。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
字幕ファイル(.srt)から単語を切り出してみる

# はじめに

- 字幕ファイルから単語リストを切り出しておきたい。。。
- そうだ、Command の -w 機能で切り出してみよう

# 前提

- 対象のファイルは .srt のフォーマット
- .srt の例
```text
6
00:08:44,033 --> 00:08:46,868
Come in.
please report.
```

# やってみる 

- 単語数

```terminal
$ cat some_subtitle.srt | grep -v -e '^[.,:0-9> \-]\+\r' | grep -v -e '^\r$' | grep -o -E '\w+' | sort | uniq | wc -l
    1233
```

- 単語表示

```terminal
$ cat some_subtitle.srt | grep -v -e '^[.,:0-9> \-]\+\r' | grep -v -e '^\r$' | grep -o -E '\w+' | sort | uniq
000
1
10
10K
12
12th
13th
157
15th
16
 :
 :
wrong
yeah
year
years
yet
yo
you
young
$
```

- ファイルに保存

```terminal
$ cat some_subtitle.srt | grep -v -e '^[.,:0-9> \-]\+\r' | grep -v -e '^\r$' | grep -o -E '\w+' | sort | uniq > wordlist.txt
```

# さいごに

- かんたんでしたね
【Salesforce】ユーザの代理ログインができないときの対処法

システム管理者で他の一般ユーザは代理ログインできるのに
一部のユーザが代理ログインできない！

ってときの対処法を2つ紹介します。
たまにあるのですが毎回忘れるので備忘録( * 'ω' * )

# ユーザのリストビューに「ログイン」が表示されない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/18663138-ec1d-674f-a0c1-79ca184ae8df.png)

代理ログインしたいユーザが「有効」であることを確認しましょう。
無効なユーザには代理ログインができません。

# 方法その１：ログインアクセスを許可する
※この方法は代理ログインしたいユーザで通常ログインできる必要があります。

代理ログインしたいユーザに通常ログインし、右上アイコンで出てくるダイアログで「設定」を押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/d408b864-f9ec-813c-9ed0-9f964f0b6ec0.png)


「アカウントログインアクセスの許可」を開き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/ad7f516d-e201-ea93-ce21-f8a2cc15df56.png)

会社のシステム管理者のアクセス期間を設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/aaedb284-83d7-d7f1-eaa4-52ed8e43f757.png)

以上で完了です。


# 方法その２：ログインアクセスポリシーを設定する
※この方法は一括で設定する方法です。ログインアクセスの許可に関係なくす代理ログインができるようになります。

システム管理者で設定画面を開き、「ログインアクセスポリシー」と検索し画面に遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/8f7dc1cb-69dc-6fc5-c4d9-bc9fa2496acc.png)

「管理者は任意のユーザでログインできる」を有効化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/bb3ad982-5ad0-e0a9-22c5-a40f4a28ed68.png)

以上で完了です。


# ログインが表示されるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/1d6e8ae4-6ae9-6f96-2845-9a82561beefb.png)

ご使用の組織に合う方法で設定ください(^^)/
FlaskをElastic Beanstalkでデプロイに関するヒント

# FlaskをElastic Beanstalkでデプロイに関するヒント

## 紹介

少し自分用のためのノートですが、Github Actionsを使ってPython FlaskをAWSのElastic Beanstalkでデプロイする時、いろいろ設定と注意点を書きたいです。

## やりたいこと

1. CI/CD
2. IPでアクセス制限
3. Flask（Dash）とPlotlyを使いたい
4. 低コスト

## ソースコードテンプレート

https://github.com/leolui2004/flask-deploy

## 手順

### ネットワーク

1. VPCを作成
2. サブネットは一つでも良い
3. セキュリティグループを作成
4. VPC・サブネット・SGのIDを記録

### CI/CD

1. AWSでデプロイ用ユーザーを作成、権限はこちら（少し過剰だけど）
 - AmazonEC2FullAccess
 - AdministratorAccess-AWSElasticBeanstalk
2. キーをGitHub Secretsに入れる（先のネットワークのIDも）
3. ファイルをレポジトリにアップロード
4. GitHub Actionsを追加

これで自動ビルドとデプロイができて、デプロイ後ELBのSGルール変更でIP制御ができます。

### 注意点

- Elastic Beanstalkでデプロイするためにポートを8080にするには必要だそうです。

```python
if __name__ == '__main__':
    application.run_server(port=8080, debug=False)
```

- Dashのインポートのフォーマットはこのようなりました。dash_core_componentsのような書き方はエラーまで行かないけど、警告が出します。

```python
from dash import Dash, callback, dcc, html, dash_table
```

- Flask(Dash)とPlotlyのライブラリはややこしくて、これで多分問題ないです。（必要がないライブラリも入っていると思いますが、一応これで無難）

```
Click>=7.0
dash>=1.6.0
dash-core-components>=1.5.0
dash-html-components>=1.0.1
dash-renderer>=1.2.0
Flask>=1.1.1
Flask-Compress>=1.4.0
future>=0.18.2
itsdangerous>=1.1.0
Jinja2>=2.10.3
MarkupSafe>=1.1.1
numpy>=1.16.5
pandas>=0.24.2
pytz>=2019.3
retrying>=1.3.3
six>=1.15.0
Werkzeug>=0.16.0
gunicorn>=19.5.0
plotly>=5.6.0
```

- Elastic Beanstalkは環境名とアプリ名がある

- ELBの手動作成はいらない

- Elastic Beanstalkのログはかなり助かる

- アプリの名前もapplication.pyが必要だそう
受託アジャイルの契約形態について

# はじめに

アジャイルを始める際によく「請負」か「準委任」かどうすれば良いのか？と聞かれることがあります。
その際の考え方です。

# 最初に読むべき情報

https://www.ipa.go.jp/ikc/reports/20200331_1.html

まずここを読んでください。話はそれからだ！って感じ。
細かいところは読んでもらったであろうとして、個人的な解釈を以下に載せておきます。

# 個人的な解釈

## アジャイルかどうかを論点にせず、「請け負えるかどうか」で決める
**アジャイルかどうかを論点にしない**
そもそも「請負」か「準委任」かについて「アジャイルかどうか」を基準にしない。
「アジャイル」が結構なバズワードになっていて、「アジャイル」が意味するところがかなりブレてます。
特に契約の場面では不明確な言葉を基準にすると痛い目を見ることになると思いますので、確実な表現で会話しましょう。

**請け負えるかどうか**
請け負えるってのは「事前に開発スコープが明確」「作業内容が見積もり可能であり、ブレる範囲が少ない」「ここは任せてくださいよ！問題あったら会社として責任取りますよ！と言い切れる」ケースです。

一般的に「アジャイル開発」は「スコープが不明瞭な案件」に向いていると言われており、「スコープが明確な案件」ではあまり使われません。
こういった背景があって「アジャイル開発は準委任が適している」という話になります。

## 偽装請負に関して

今までは偽装請負と判断される可能性が高いと判断されることが多く、受託アジャイルはなかなか進みませんでした。
そこに対して厚労省が回答したものが2021年に公開され、一定の対処方針が示されています。

**基本的なポイント**
pptなのでリンクがダウンロードになっちゃっうんですけど、一応上のIPAのページの中にある資料です。
[講演資料：アジャイル開発の外部委託は偽装請負になるのかAgile Japan 2021 Day0講演資料(PowerPoint:160KB)](https://www.ipa.go.jp/files/000094364.pptx)

特に重要なポイントは以下です。

![受託者側の開発担当者が自律的に判断して業務を行なっていると認められるケースは問題ないと厚労省が言っている
資料。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214587/ef77f16c-998d-3eeb-59db-5de3ff5b0bc1.png)

細かいポイントはざっくり以下です。詳細は資料見てね。

- 自律的に作業できている場合は、作業内容についてすり合わせる会議体に管理者が必ずしも参加しなくても良い。（参加した方が偽装請負リスクは低い） 
- 自律的に作業できている場合は、コミュニケーションツールなどで発注側と受注側の配下メンバーが直接会話しても良い。（会話しない方が偽装請負リスクは低い） 

**自律的に作業できているとは？**
![厚労省の回答。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214587/fff00918-0b37-631d-8515-785661c1484c.png)

- 発注者と受注者の関係性が対等であること
    - 受注者側が発注側の提案に従う必要がない関係性であること
- ただし業務の遂行方法や労働時間に関する指示については、指揮命令があるように見えるため、偽装請負と判断される。

# 個人的な補足
## 実際にどうやっているか

- 契約形態：受託アジャイル案件は全部準委任です。（観測範囲内に限る）
- 偽装請負関連：
    - 会議体に関してはなるべく管理者も出るようにしている。（出れない時もある）
        - 発注側・受注側で対等な議論をした結果として、受注側としてじゃあどうしようね？って迷うケースもあって、その時に受注側の判断者がいるとスムーズなので。
    - コミュニケーションツール（チャットやJira）は発注側も受注側も関係者は全員参加して会話している。
    - 「自律的に判断」が必要ってのを随所で伝えている。（折に触れて伝えているとしか言いようがない）


## 瑕疵担保責任
請負から準委任にすることで瑕疵担保責任がなくなることを嫌がるお客さんを見かけたりするのですが、個人的には以下観点でメリットが上回る場合にのみアジャイルをお勧めしています。
というか、上回らないのであれば請負でウォーターフォールでやった方が良いと思う。

**メリット：方向転換の高速化**
私が思うに受託アジャイルで得られるメリットは「開発途中の方向転換のオーバーヘッドコストの低減」です。

請負開発の場合、頻繁な仕様変更は管理の手間が非常に大きくなりやすいです。既存の契約範囲を変更することに同義となるため、都度見積もりを行い、受注側でも発注側でも承認プロセスを回す必要があります。
頻繁な仕様変更はコストもかかりますし、期間もかかってしまうため、請負契約ではビジネスメリットが薄いです。

特に市場の変化は目まぐるしく、タイミングに乗り遅れると他社に市場を取られてしまう事になるため、このビジネスメリットは非常に大きいと思われます。

**デメリット：瑕疵担保責任**
請負契約が基本だった関係性から、準委任契約に変えようとする場合「瑕疵担保責任」が話題に上がるかと思います。（瑕疵担保責任＝リリース後一定期間内の不具合については無償で直します責任）
色々な解決法があるかと思いますが、具体的なやり方まで言及するのはちょっと厳しいので、自社の法務と相談ください。

発注先のベンダーにもよると思いますが、ある程度の品質が期待できるのであれば、瑕疵担保責任で賄えるリスクよりも、タイミングよく市場に投入できるメリットの方が上回るとは思っています。


# 注意事項

- あくまで個人の見解であって、会社を代表するものではないです。
- 法律は素人なので、何かしらを保証するものではありません。
- ちゃんと自社の法務に確認してね。

# 次回予告

社内で、あくまで１現場としてアジャイルを始めるためにどうアプローチすれば良いか、みたいな話を書きます。

# おまけ

https://www.amazon.co.jp/dp/481784843X/

まだ買ってもないけど、こんな本が出たらしいので、こんな記事よりこういうちゃんとした法律家が書いたものを読むのが良いと思うます。
Python  BeautifulSoup aタグ取得について

あるサイトのURLを取得試みたが、出来なかった
```
<a href="/company/cmi0179173001/nx1_rq0023287251/?fr=cp_s00700&amp;list_disp_no=1&amp;leadtc=n_ichiran_cst_n5_ttl" target="_blank" class="rnn-linkText rnn-linkText--black">CADオペ/設計補助エンジニア◆未経験歓迎◆年休122日</a>
```
![スクリーンショット 2022-11-27 14.58.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1816675/bd6d3537-db50-b299-1cdd-c6f26fae0892.png)
欲しいURLは下記だが、

```
/company/cmi0179173001/nx1_rq0023287251/?fr=cp_s00700&amp
```

```
boxs = soup.find_all('ul', attrs={'class': 'rnn-group rnn-group--xm rnn-jobOfferList'})
    for box in boxs:
        links = box.find_all('a', attrs={'class': 'rnn-linkText rnn-linkText--black'})
        for link in links:
            link = link.text
```
textを実施すると、「CADオペ/設計補助エンジニア◆未経験歓迎◆年休122日」が取得できてしまう
解決策はとても簡単で、textではなくget('href')で解決
```
boxs = soup.find_all('ul', attrs={'class': 'rnn-group rnn-group--xm rnn-jobOfferList'})
    for box in boxs:
        links = box.find_all('a', attrs={'class': 'rnn-linkText rnn-linkText--black'})
        for link in links:
            link = link.get('href')
```
Google トレンドをスクレイピングする

# 前提
- [対象サイト](https://trends.google.co.jp/trends/trendingsearches/daily?geo=JP)（2022/11/26 時点）
- macOS 12.3.1
- ruby 2.7.4p191
- capybara (3.35.3)
- selenium-webdriver (3.142.7)
- chromedriver 107.0.5304.62
- nokogiri (1.12.3)

# [毎日の検索トレンド](https://trends.google.co.jp/trends/trendingsearches/daily?geo=JP)
- [RSS](https://trends.google.co.jp/trends/trendingsearches/daily/rss?geo=JP)があるのでそれを使う
- タイトルくらいしか取れないので、それ以上のものが欲しい場合はブラウザ経由で取得する

```ruby
require 'rss'

url = "https://trends.google.co.jp/trends/trendingsearches/daily/rss?geo=JP"
rss = RSS::Parser.parse(url)

rss.items.each do |item|
  puts item.title
  puts item.link
  puts '-' * 10
end

# =>
#
# フランス
# https://trends.google.co.jp/trends/trendingsearches/daily?geo=JP#%E3%83%95%E3%83%A9%E3%83%B3%E3%82%B9
# ----------
# アルゼンチンメキシコ
# https://trends.google.co.jp/trends/trendingsearches/daily?geo=JP#%E3%82%A2%E3%83%AB%E3%82%BC%E3%83%B3%E3%83%81%E3%83%B3%E3%83%A1%E3%82%AD%E3%82%B7%E3%82%B3
# ----------
# ジャパンカップ予想
# https://trends.google.co.jp/trends/trendingsearches/daily?geo=JP#%E3%82%B8%E3%83%A3%E3%83%91%E3%83%B3%E3%82%AB%E3%83%83%E3%83%97%E4%BA%88%E6%83%B3
# ----------
# ...
```

# [リアルタイムの検索トレンド](https://trends.google.co.jp/trends/trendingsearches/realtime?geo=JP&category=all)
- こっちは RSS がないので自前で取得する
    - JS 実行があるのでブラウザ経由で
        - 今回は、`capybara + selenium-webdriver + chromedriver`
            - `$ brew install chromedriver`
- 必須ではないけど、Nokogiri を使ってる
    - Capybara の記法に慣れていないので
- 各フィードを click して、他の情報（関連キーワード等）を取りたかったけど、、
    - `Selenium::WebDriver::Error::ElementClickInterceptedError`

```ruby
require 'selenium-webdriver'
require 'capybara'
require 'capybara/dsl'

# https://www.rubydoc.info/gems/capybara/Capybara.configure
Capybara.configure do |config|
  config.run_server = false

  # https://github.com/teamcapybara/capybara#selenium
  config.default_driver = :selenium_chrome_headless
  config.javascript_driver = :selenium_chrome_headless

  config.app_host   = 'https://trends.google.co.jp'
  config.default_max_wait_time = 30
end

class PageFetcher
  include Capybara::DSL

  def fetch
    visit('/trends/trendingsearches/realtime?geo=JP&category=all')

    # エラーが起きる、、
    # link = page.all('.details-top a')[0]
    # link.click

    page
  end
end

page = PageFetcher.new.fetch
# => #<Capybara::Session>

doc = Nokogiri::HTML.parse(page.html)
# => #<Nokogiri::HTML4::Document>

doc.css('.details-top').each do |ele|
  puts ele.css('a').text.split(/\R/).map(&:strip).reject(&:empty?).join(', ')
  puts '-' * 10
end && nil

# =>
#
# 全日本実業団対抗女子駅伝競走大会, 新谷仁美, 廣中璃梨佳, 資生堂, 一山麻緒
# ----------
# 関口 宏, サンデーモーニング, ジャパン・ニュース・ネットワーク, 松原耕二
# ----------
# 武豊, ジャパンカップ, クロフネ, 日本中央競馬会, リアルスティール, 競走馬の血統, G1
# ----------
# ...
```
StableDiffusion2.0をGoogleColaboratoryで動かしてみる

## 概要
GoogleColaboratoryで流行りの画像生成AIを使う方法をメモしてみました。
公式のdocsを参考に、最終的にGoogleドライブに保存するようにしています
https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion_2

## やり方
以下の番号ごとに実行していきます。
※私の場合は、セルごとに分けて記載して実行しています。

①必要なライブラリのインストール
```
!pip install diffusers transformers scipy ftfy
```

②stableDiffusionを使う準備
```
from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler
import torch

repo_id = "stabilityai/stable-diffusion-2"
pipe = DiffusionPipeline.from_pretrained(repo_id, torch_dtype=torch.float16, revision="fp16")

pipe.scheduler = DPMSolverMultistepScheduler.from_config(pipe.scheduler.config)
pipe = pipe.to("cuda")
```

③文字から画像を作成して保存する

```
from diffusers import DiffusionPipeline, DPMSolverMultistepScheduler
import torch
# reは正規表現を使用するための標準ライブラリ
import re

# 保存先フォルダを初期化
!rm -rf make-img
!mkdir make-img

# 作成したい画像の説明文
prompt = "A photo of woman, a elaborate beautiful background, a well-groomed face, beautiful eyes, the most beautiful body I've ever seen"
# 画像のファイル名
filename = re.sub(r'[\\/:*?"<>|,]+','',prompt).replace(' ','_')

# 作成する画像数
num = 2

for i in range(num):
  image = pipe(prompt, guidance_scale=9, num_inference_steps=20).images[0]
  image.save(f'/content/make-img/{filename}_{i:02}.png')
```

④作成したファイルを自分のドライブフォルダにコピーする
※必要に応じて実行してください
/content/drive/MyDrive/python-imgを自分の保存先に変えてください

```
!cp -r /content/make-img /content/drive/MyDrive/python-img
```

①、②は一度実行すればランタイムの接続が切れるまでは再度実行は不要です。※毎回実行するとエラーにはなりませんが、時間がかかります
もし何度も画像を作成したい場合は③、④を再度実行してください

感覚的に2.0は出たばかりで使う人が多いのか、一枚の画像を作る時間が1.5よりも時間がかかるような気がします。
ただ画像の質はかなり上がったような気がします。
Leetcode 1337. The K Weakest Rows in a Matrix

# 1337. The K Weakest Rows in a Matrix

https://leetcode.com/problems/the-k-weakest-rows-in-a-matrix/

## アプローチ
### Java Hashmap

```java
class Solution {
    public int[] kWeakestRows(int[][] mat, int k) {
        Map<Integer, Integer> map = new TreeMap<>();
        for (int i = 0; i < mat.length; i++) {
            int count = 0;
            for (int j = 0; j < mat[i].length; j++) {
                if (mat[i][j] == 1) count++;
            }
            map.put(i, count);
        }
        return map.entrySet().stream()
                 .sorted(Map.Entry.comparingByValue())
                 .limit(k)
                 .map(Map.Entry::getKey)
                 .mapToInt(it -> it)
                 .toArray();
    }
}
```



### 下記の解説を参考しました
> https://leetcode.com/problems/the-k-weakest-rows-in-a-matrix/discuss/2828853/Java-Memory-usage-less-than-99.71-oror-TreeMap-%2B-Stream-API
【AWS】VSCode Remote-SSH＋EC2な開発環境を安く安全に作る〜1. はじめに〜

# 目的
日常業務においてAWSを使った開発を行なっているが、以下の点で問題を抱えていたため解決したかった。
* 会社支給のPCの性能が低いためビルド等に時間がかかり生産性が下がる
    * ~~そもそもハイスペックなPCを配ってくれればこんなことしなくてもいい~~
* 会社のイントラネット内でAWSSDKを使ったアプリを動かすにはIAMユーザのアクセスキーを発行するためセキュリティ面で気になる


# 開発環境の構成
以下の構成の開発環境を作っていきます。ポイントは以下の3点です。
* スポットインスタンスを使うことで費用削減
* 面倒なスポットインスタンス起動周りをSSMパラメータストアやLambdaを使ってなるべく簡潔に
* プライベートサブネットに配置したマシンにSSM接続を使ってセキュアに接続

![vscode-spot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105456/77f9dec4-d580-5a6b-c4cb-36ae56f32c8b.png)

# 効果
* 同一構成でオンデマンドインスタンスを利用するより3~7割費用削減できる
    * スポットインスタンスの割引率と中断回数によって削減効果は変化します
* 開発用インスタンスがインターネットに面していないので安全に利用できる
* IAMロールを使うのでより安全にAWSサービスの呼び出しができる 

次回から実際の構築手順について説明していきます。
* [【AWS】VSCode Remote-SSH＋EC2な開発環境を安く安全に作る〜2. スポットインスタンス用起動テンプレート作成〜](https://qiita.com/soujiroy/items/7798448fdc71a07005c6)
* [【AWS】VSCode Remote-SSH＋EC2な開発環境を安く安全に作る〜3. スポットリクエスト作成〜](https://qiita.com/soujiroy/items/1005f34c82a01bc8139b)
* [【AWS】VSCode Remote-SSH＋EC2な開発環境を安く安全に作る〜4. VSCodeで接続〜](https://qiita.com/soujiroy/items/f602a4171f056b1cb79c)
コメントコーディングで実装内容を明確化しよう

## 前置き
私は実装が苦手なので、日頃から頭で考えるより紙に書いたり、PCのメモに書いたりして頭の中を整理をするようにしています。
その一環で、時間があるときは実装時にコメントコーディングしてみるということをしています。
実装苦手な人やプログラミング初心者向けの紹介になります。

## コメントコーディングの方法
”**自分が日頃使っている言語でコーディングしてみる**”これが大きな特徴だと思います。
私は日頃から日本語を使っているので日本語で書いてるのですが、注意したいのは「箇条書きをする」というところです。

```php
    public function 東京駅から福岡空港まで行く値段を計算する() 
    {
      //自宅から東京駅まで行く値段を計算
      //東京駅から羽田空港まで行く値段を計算
      //羽田空港から福岡空港まで行く値段を計算
      //福岡空港から博多まで行く値段を計算
    }
```
これほど大雑把でもこのコメント4行をメソッドにしてみようかと考えることができます。
また上記は駅や空港を限定していますが、場所を限定しないで他パターンを考えると細かくなります。
すこし大雑把なのでこのコメント4行を少々細かくしてみよう

```php
    public function 東京駅から福岡空港まで行く値段を計算する() 
    {
      //自宅から東京駅まで行く値段を計算
      //東京駅から羽田空港まで行く値段を計算
      //羽田空港から福岡空港まで行く値段を計算
      //福岡空港から博多まで行く値段を計算
    }

    public function 自宅から東京駅まで行く値段を計算() 
    {
      //車で行く
      //タクシーで行く
      //地下鉄で行く
      //JRで行く
      //バスで行く
      //歩きで行く

      //値段を返す
    }
    .
    .
    .
}
```
「自宅から東京駅まで行く値段を計算」をメソッド化してみました。
東京駅まで行くには様々な手段があるためこのように書いています。
また上記の内容に、使う金額が変動する、行く人の人数が変動する、電車の中でご飯を食べる、などを考慮するとさらにコメントの行数が増えます。この辺の考慮は設計書や要件定義をみて判断するといいと思います。

## まとめ
コメントで箇条書きをするだけでも、どのようなメソッドを作っていったら良いかをあらかじめ把握することができます。
また、設計書や要件定義に記載されていない場合は設計者に考慮が必要か質問をすることができます。
考慮漏れなども発見できる為、とても実装しやすくなります。
参考になれば幸いです。

## 参考文献
コーディングの手助けとなる "コメントコーディング" を紹介
https://qiita.com/tatsuo-iriyama/items/7a00c3191cde70c918c3
SwiftUIのList 下から上にしたいよね、わかります。

SwiftUIのlistは普段は上から下にrowが追加されていき、下の方のrowを見るためにはスクロールダウンする必要がありますよね。
ただ、親指の届きやすい画面下部にviewを集めたいときなど、この仕様を変えたいときがあると思います。
以下のようにすると下から上にrowが追加されていきます。
```
List{
                    ForEach(/*...*/){
                        //...
                    }.rotationEffect(Angle(degrees: 180))
              } .rotationEffect(Angle(degrees: 180))


```
まずはlist全体を上下逆さにして、その後各rowを上下逆さにしていますね。

参考:
https://stackoverflow.com/questions/65384646/swiftui-build-view-from-bottom-alignment-in-scrollview
on-demand-dashboardで気楽にDashboard

# はじめに
Cloudwatch Dashboardを気楽にたくさん使っていたら、いつの間にか料金が無視できないものになった経験はありませんか？ 不要なDashboardを削除した結果、Cloud Watch Insightで同じクエリを何度も何度も作ったりしていませんか？

コストを気にすることなく必要に応じてDashboardをS3に退避、復帰することができる、on-demand-dashboardをCDKスタックとして公開しました。
https://github.com/tomohisaota/on-demand-dashboard

# 基本的な構成
* Dashboard Lambda
    * Cloudwatch Dashboardに表示するカスタムウィジェットで、Dashboard管理を行うUIを提供する
* Redirect Lambda
    * 退避されているCloudwatch Dashboardをストレスなく利用するために、復帰後にリダイレクトを行うLambda Function URLを提供する
* S3
    * CloudWatch DashboardのJSON定義を保存しておくストレージ

![on-demand-dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33513/20ab04e1-f518-91ea-9a40-cf63d713b7dc.png)


# ルール設定
どのDashboardを退避可能にするのか、いつ退避可能にするのか等は、ルールによって詳細に設定することができます。すべて手動で設定することも、すべてCDKから固定で設定することも可能です。
ルールにはプリセットを用意しているので、通常のユースケースであればプリセットで対応可能です。

```
const PresetRules: { [key in PresetRuleName]: TOnDemandDashboardRule[] } = {
    Demo1: [
        {
            ruleName: "Manual",
            archive: "Manual",
            matchByName: [
                "OnDemandDashboardAdmin",
                "Dummy1",
            ],
            allowActivate: true,
            allowDeactivate: true,
            allowDelete: true,
            ttl: Duration.minutes(3).toMilliseconds()
        },
    ],
    Demo2: [
        {
            ruleName: "Enabled without control",
            archive: "Enabled",
            matchByName: [
                "OnDemandDashboardAdmin",
                "Dummy1",
            ],
            allowActivate: false,
            allowDeactivate: false,
            allowDelete: false,
            ttl: Duration.minutes(3).toMilliseconds()
        },
    ],
    AllManualExceptODD: [
        {
            ruleName: "Protect ODD",
            matchODD: true,
            archive: "Disabled",
        },
        {
            ruleName: "All Manual",
            matchAll: true,
            archive: "Manual",
            allowActivate: true,
            allowDeactivate: true,
            allowDelete: true,
            ttl: Duration.days(3).toMilliseconds()
        },
    ],
    AllEnabledExceptODD: [
        {
            ruleName: "Protect ODD",
            matchODD: true,
            archive: "Disabled",
        },
        {
            ruleName: "All Enabled",
            matchAll: true,
            archive: "Enabled",
            allowActivate: true,
            allowDeactivate: true,
            allowDelete: true,
            ttl: Duration.days(3).toMilliseconds()
        },
    ],
    AllEnabled: [
        {
            ruleName: "All Enabled",
            matchAll: true,
            archive: "Enabled",
            allowActivate: true,
            allowDeactivate: true,
            allowDelete: true,
            ttl: Duration.days(3).toMilliseconds()
        },
    ],
    AllDisabled: [], // Default behavior
}
```

# さいごに
感想等コメントでいただけると励みになります。
https://github.com/tomohisaota/on-demand-dashboard
VBAでスクレイピング(Selenium)

参照サイト
https://nkmrdai.com/vba-selenium-reference/#VBA%E3%81%A7Selenium%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97

VBAでスクレイピングをしようと思い調べていたところ
Seleniumがよさそうだったのでインストールしてみる。

# SeleniumBasic
## ダウンロードする
https://github.com/florentbr/SeleniumBasic/releases/tag/v2.0.9.0
SeleniumBasic-2.0.9.0.exe

## インストールする

下記フォルダにインストールされる
C:\Users\%username%\AppData\Local\SeleniumBasic

# ChromeDriver
## Chromeのバージョンを確認する

今回はメジャーバージョンが107である。

<img width="400" alt="chrome-ver1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/0b4893e1-281e-d1b6-4c35-abe1e1d01e0f.png">
<img width="400" alt="chrome-ver2" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/66ff860f-dfc8-1760-502d-eaca342929cf.png">


## ダウンロードする

Chromeのバージョンに対応したChromeDriverをダウンロードする

今回は107である。

https://chromedriver.chromium.org/downloads

<img width="400" alt="chromedriver" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/fb0a8b4e-9e9e-e35d-0cd9-c9a09224f7b8.png">

## SeleniumBasicに保存する

<img width="400" alt="selenium-folder" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/716a2c9c-0b3e-43ae-31b0-53973f2483a4.png">

# Excel
## 参照設定する

<img width="400" alt="vbe" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/9f5af553-2ed6-13af-20b2-9cbaed594b12.png">
<br>
<img width="400" alt="refset" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99234/9d024b43-1d0b-60b7-2372-f1c93292c1eb.png">
Splunk: scheduler.logのsuccessログに出力される情報について

しばしば必要となるのでメモ。

###### 実施環境： Splunk Free 8.2.2

###### scheduler.log

 Splunk の scheduler.log に出力される status="success" のログは、スケジュールジョブが正常に完了した際に出力されるログです。
このログには、実行されたスケジュールジョブについての様々な情報が含まれています。
その中でも、よく使用すると思われる情報をピックアップしていきます。

###### 実行環境に関わる情報

実行環境に関わる情報としては、以下のような情報が出力されます。

* savedsearch_name : ジョブ名
* user : ジョブの実行ユーザ名
* app : ジョブの実行APP名
* sid : ジョブのID

```Splunk:Splunk
index="_internal" sourcetype="scheduler" source="*/scheduler.log" status="success"
| where isnotnull(savedsearch_name)
| table _time, savedsearch_name, user, app
```

![スクリーンショット 2021-12-19 16.55.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/2f1de976-5b50-962b-b3d3-c6a0fe63c21b.png "name")

```Splunk:Splunk
index="_internal" sourcetype="scheduler" source="*/scheduler.log" status="success"
| where isnotnull(savedsearch_name)
| table _time, savedsearch_name, sid
```

![スクリーンショット 2021-12-19 16.56.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/9d9ad70b-4d12-5477-1894-1cc13f620f21.png "sid")

###### 実行結果に関わる情報

実行結果に関わる情報としては、以下のような情報が出力されます。

* result_count : 出力件数(件)

```Splunk:Splunk
index="_internal" sourcetype="scheduler" source="*/scheduler.log" status="success"
| where isnotnull(savedsearch_name)
| table _time, savedsearch_name, result_count
```

![スクリーンショット 2021-12-19 17.02.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/9d5a2b51-b56b-6e07-2d5a-28a59bd95ec9.png "count")

###### 実行時間に関わる情報

実行時間に関わる情報としては、以下のような情報が出力されます。

* scheduled_time : 予定されていたジョブ起動日時(UNIX時間)
* dispatch_time : 実際のジョブ起動日時(UNIX時間)
* run_time : ジョブの実行時間(秒)

```Splunk:Splunk
index="_internal" sourcetype="scheduler" source="*/scheduler.log" status="success"
| where isnotnull(savedsearch_name)
| eval scheduled_time = strftime(scheduled_time, "%Y/%m/%d %H:%M:%S"),
       dispatch_time  = strftime(dispatch_time,  "%Y/%m/%d %H:%M:%S")
| table _time, savedsearch_name, scheduled_time, dispatch_time, run_time
```

![スクリーンショット 2021-12-19 17.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/755e8748-8082-6acc-69fa-021e49408be3.png "time")
AWS Certified Data Analytics - Specialtyに向けた勉強メモ

# はじめに
本記事は、DAS-C01を受けるにあたっての勉強内容をメモするための記事です。

# 簡単なプロフィール
現在、都内の金融系IT会社に勤める28歳男性です。
業務内でAWSを扱っている関係で今年度中にAWS全資格取得を目指して勉強をしています。

### 今まで取得したAWS資格一覧
DBS-C01
SCS-C01
DOP-C01
DVA-C01
SOA-C02
SAP-C01
SAA-C02

# 勉強内容

- [Tech Stock（旧：koiwa lab）](https://techstock.jp/)

# メモ
## データ分析基礎知識
- データカタログとメタデータの違い
    - データカタログ：データ辞書、構造化データから非構造データまでデータ形式は多岐にわたる
    - メタデータ：RDS等の構造化が約束されたデータ群、データカタログを効率的に使用するために使用するデータ
※[ご参考](https://www.ibm.com/jp-ja/topics/data-catalog)

-  列指向データと行指向データについて
    - 列指向データ：大量の行データに対して少数の列を抽出するような集計が得意
    - 行指向データ：少数の行に対して大量の列を抽出するような集計が得意
  
※[ご参考](https://docs.treasuredata.com/pages/releaseview.action?pageId=331325)

- MapReduceとは
    - 大量データを処理するための分散コンピューティング用プログラミングモデル

- Hadoop関連用語整理
    - 参考は[こちら](https://qiita.com/tetsuro731/items/64abce51021c904bb7ab)

## AWSサービスについて
- AWS Glueについて
    - データカタログ作成に特化したサービス
    - データカタログ作成元データについて多岐にわたるサービス（S3, Redshift, RDS etc.）を選択できることが強み
    - 処理済データを追跡する、ブックマーク機能あり
    - バッチ処理に向いており、リアルタイム分析には不向き

- Amazon Redshiftについて
    - 分散スタイル
        - KEY
            - 一行ごとにと特定の列の値に従って分散される
        - All
            - 変更が少ないデータの場合に選択
        - EVEN
        - AUTO
    - 暗号化
        - 既存のデータベースを暗号化するように変更は不可
            - 暗号化したDBに既存DBのデータを移行する必要がある
            - KMSもしくはHSMによる暗号化が可能
    - バックグラウンドで自動的にバキューム処理が実行されている
        - ユーザー側の処理が連続して実行されているとバキューム処理が実行されず処理落ちの原因となる

- Amazon Athenaについて
    - クロスリージョンアクセス非対応
    - S3 Glacierアクセス不可
    - 複雑クエリ実行に不向き
    - 実行タスクはワークグループで定義
        - ワークグループごとにデータ使用量の閾値を設定可能

- Elastic Searchについて
    - 文字列検索が可能

- kinesis Data Streams について
    - 過去にストリームしたデータの順番に沿って再生が可能
    - データボトルネック発生時の観点
        - シャードスが足りているか
        - パーティションキー（データをどのシャードに割り当てるかを決めるルール）の振り方は適当か
    - 最大データは１MBまで
        - それ以上の場合はManeged Streaming for Kafkaを検討
- kinesis Data Analytics
    - 取り込んだデータに応じて追加のカラムを追加可能
        - 追加カラムのデータライブラリをS3に格納

- Lake Formation
    - Data Lakeへのアクセス制御管理を行うためのサービス
    - クロスアカウントのリソースを集約可能

- Amazon Quicksight
    - データ単位でのアクセス制御
        - RLS(Row-Level Security)の設置（Enterprise Editionのみ ） 
- Amazon EMR
    - パフォーマンス向上案
        - マッパーサイズの変更
        - JOB入力サイズの変更
            - JOB完了時間を早くさせる
    - S3バケットとの連携手法
        - Hadoop環境との直接統合する際にS3DistCpを使用する
    - コストは高い（らしい）

- DynamoDB
    - ホットキーの要因になりうるのはLSI（GSIは無関係）
pythonでsocket通信（サンプルプログラム）

# はじめに
Docker上に展開しているコンテナでsocketで受信待ち状態にして、socketで通信を受け取ったら、以降の処理を走らせる形のサンプルプログラム。
別コンテナからのリクエストで、同期して処理を実行させたい場合などに使えるかと。

## 環境
- windows10 pro 
- wsl2(20.04.5 LTS (Focal Fossa))
- Dockerのバージョン
    - Docker version 20.10.18, build b40c2f6
    - docker-compose version 1.29.2, build 5becea4c
※Docker Desktop ではありません
※通信のリクエストは、Windowsからも行っています
- python 3.10.7
- コンテナのポート設定については
```
ports: 
  - 50000:50000
```
　を入れています

## コード(受信側)
```python:receive.py
import socket
import logging

# 受信IP（外部からの接続は127.0.0.1では、多分ＮＧかと、、）
RCV_HOST = "0.0.0.0"
# 受信ポート
RCV_PORT = 50000
# 受信可能数（処理中に同時受信数が指定を超えると、待ちが発生せずに処理終了？？）
BACKLOG = 10
# 一度の通信受信できる最大データバイト数
BUFSIZE = 1024

# ログ出力設定
logging.basicConfig(
    level=logging.DEBUG, filename="recive.log", format="rcv_msg: %(message)s"
)

# ソケット定義
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sct:

    # 再使用設定(３つ目の引数が、考え方間違っているかも)
    sct.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, BUFSIZE)
    # 受信設定
    sct.bind((RCV_HOST, RCV_PORT))
    sct.listen(BACKLOG)

    # 継続受信のため、永久ループ
    while True:

        # コネクション定義(切断処理の判定対策)
        conn = None
        try:
            # 受信の待機
            (conn, addr) = sct.accept()
            # 通信内容を受信
            rcv_msg = conn.recv(BUFSIZE)
            # 受信内容のログ出力
            logging.debug(rcv_msg.decode())
            # 送信側に値を返す
            conn.send(b"recived:" + rcv_msg)

        finally:
            # 受信せずに終わる場合(ctrl+c等)は、処理を抜けさせる
            if conn is None:
                break
            # コネクションを閉じる
            conn.close()
```

## コード(送信側)
```python:send.py
import socket

# 接続IP
CONNETC_HOST = "127.0.0.1"
# 接続ポート
CONNECT_PORT = 50000
# 送信内容
BUFSIZE = 1024
# 送信内容
SEND_DATA = b"send message"

# ソケット定義
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sct:
    # 接続
    sct.connect((CONNETC_HOST, CONNECT_PORT))
    # メッセージ送信
    sct.send(SEND_DATA)
    # 受信内容の取得
    rcv_message = sct.recv(BUFSIZE).decode()
    # 受信内容の確認
    print(rcv_message)

```

## 確認方法（不要でしょうが、、）
- 受信側
```shell:直接実行
python receive.py
```
or
```shell:バックグラウンド実行（nohup.outを出力しない）
nohup python receive.py > /dev/null 2>&1 &
```

- 送信側
```shell
python send.py
```

## おまけ
バックグランド実行を終了させるときは
```shell
ps -ef |grep receive.py
```
でreceive.pyを実行しているPIDをみつけて（下記のような結果のときは90がPID）
```
pyuser      90     7  0 04:43 pts/1    00:00:00 python receive.py
pyuser      92     7  0 04:43 pts/1    00:00:00 grep receive.py
```
`-2`を指定して、killコマンドを実行する(バックグラウンド実行のものを、ctrl+cで終了させるようなイメージ)
```shell
kill -2 {PID}
# 例）kill -2 90
```

## 最後に
一部、引数の解釈が間違っていたりする可能性はありますが、基本的には問題なく動くと思います。
コネクションもwith構成にしたかったのですが、受信待ちのときに終了すると、エラーになってしまい、後続の処理が実行されないみたいなので、try/exceptの形式にしています。（このあたりは、どうするのがベストプラクティスなのか不明です…）
将棋ウォーズの級位者と高段者の棋譜を比較してみた

# はじめに
現在ではインターネット上で将棋を気軽に指すことができ，便利な世の中になったと感じてます．ただ，三級あたりからレートが急に上がらなくなり，初段になかなか到達できなくて世の厳しさを思い知らされた経験があります...
そこで，有難いことに棋譜データの公開によって分析がしやすくなったので，**一級の棋譜と四段以上の棋譜を比較し，昇級につながるヒントが得られるか調査しました．**

# 棋譜データ
- アプリケーション ：将棋ウォーズ
- 対戦カード　　　 ：一級vs一級，四段以上vs四段以上<sup>※</sup>
- 対局モード　　　 ：10分切れ負け，通常，平手
- 取得期間　　　　 ：2022/08/30～2022/10/20
- データ数　　　　 ：約2500対局 ×2

※ボットの判定はしていません m(_ _)m

# 比較する項目
- **終局までの手数**
    終局まで何手かかったかを一級と四段以上で比較します．高段者はうっかりミスをしなさそうなので長手数になるのかも？
- **手筋**
    「垂れ歩」とか「ふんどしの桂」とかです．一対局あたりの出現数とか割合を比較します．手筋の数は高段になるほど増えそうですね．
- **戦型**
    使用された戦型の割合を比較します．高段になるほど角換わりのような定跡が多い戦法が増えそうです．
- **囲い**
    使用された囲いの割合を比較します．個人的には矢倉の使用率が気になります．
    
手筋，戦型，囲いは実は棋譜データから簡単に取れるんです！下の画像のような「〇〇.kif」のファイルによく載ってます．嬉しい．

<img src="https://i.imgur.com/SOSzTKh.jpg" width=300>

# 結果
- ### 終局までの手数
<img src="https://i.imgur.com/yhfSw32.png" width=400>

若干ですが高段者は長手数の対局が多いように見えます．しかし，２群の平均値に有意な差があるとは言えない，と出たので比較の考察は難しそうです...
```python
stats.ttest_ind(tesu_1k, tesu_4d, equal_var=False)
>>>
Ttest_indResult(statistic=-1.435889429397662, pvalue=0.15109683568307125)
```

- ### 手筋
1. 一局あたりの手筋の数：
一級：1.09， 四段以上：1.10
1. 一級・高段，それぞれで使用された手筋の割合：
 <img src="https://i.imgur.com/xw7ni8p.png" width=600>

一局あたりの手数の数は，予想と反して差が見られませんでした．
割合を見ると，**一級は「ふんどしの桂，桂頭銀」が相対的にやや多く，高段は「垂れ歩，継ぎ桂」がやや多く指されていました．** 手筋の難易度と相関があるように思えます．

- ### 戦型
<img src="https://i.imgur.com/a0baFcn.png" width=650>

相対的に，**一級は「四間，右四間，棒銀」が多く，高段は「角換わり，向かい飛車，対振り持久戦」が多かったです．** 右四間と棒銀は受けを知らないと一方的に攻められるので，使用率が高くなるのは納得です．

- ### 囲い
<img src="https://i.imgur.com/0aMAdHl.png" width=600>

相対的に，**一級は「居玉，elmo」が多く，高段は「左美濃，居飛車穴熊」が多かったです．** 居玉が多いということは急戦が多いのでしょう．筆者も居玉で決戦することがよくあるので，高段者を見習って居玉は避けようと思います...

# まとめ
昇級のヒント：
- **居玉は避けよ！**

決定的なのはこれぐらいでした．断言はできませんが，棒銀は高段者に通用しにくいようです．
jit-grunt


# jit-grunt



まだgruntを使っていて、たくさんのloadNpmTasksを実行している環境もある模様。
そこでjit-gruntが有効であったことを残しておきたい。

```bash
module.exports = function(grunt) {

  grunt.initConfig({
    // config類
  });

  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-clean');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-imagemin');
  grunt.loadNpmTasks('grunt-contrib-compress');
  grunt.loadNpmTasks('grunt-contrib-htmlmin');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-concat-css');
  grunt.loadNpmTasks('grunt-strip');
  grunt.loadNpmTasks('grunt-nginx');
  grunt.loadNpmTasks('grunt-autoprefixer');
  grunt.loadNpmTasks('grunt-html');
  grunt.loadNpmTasks('grunt-postcss');
  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.registerTask('default',['htmlmin']);
};

```


#### B


```bash

module.exports = function(grunt){

  require('jit-grunt')(grunt)({
    pluginsRoot: 'node_modules', 
    customTasksDir: 'custom/dir'
  });

  grunt.initConfig({
    // config類
  });

  grunt.registerTask('default',['htmlmin']);
};
```


https://github.com/shootaroo/jit-grunt

https://gruntjs.com/

今日、7年放置したサーバ機能を振り返っていて、jit-gruntがやっぱり最強だったので
今から使おうという人は希少だろうけれどGruntで一番影響力を持っていたパッケージだったなと思って
Terraform(ECS on Fargate作成)

### やってみたコード
```ruby:
############ ECR ############
resource "aws_ecr_repository" "ecr" {
  name = "${var.project}-${var.environment}-ecr"
}

############ ECS クラスター ############
resource "aws_ecs_cluster" "ecs-cluster" {
  name = "ecs-cluster-terraform"

  setting {
    name  = "containerInsights"
    value = "disabled"
  }
}

############ ECS サービス ############
resource "aws_ecs_service" "ecs-service" {
  name            = "ecs-service-front-terraform"
  cluster         = aws_ecs_cluster.ecs-cluster.id
  task_definition = aws_ecs_task_definition.ecs-front-fargate.arn
  desired_count   = 1
  launch_type     = "FARGATE"

  network_configuration {
    subnets          = ["${aws_subnet.public_subnet_1a.id}","${aws_subnet.public_subnet_1c.id}"]
    security_groups  = ["${aws_security_group.front-sg.id}"]
    assign_public_ip = "false"
  }
}

############ ECS タスク定義(フロント) ############
resource "aws_ecs_task_definition" "ecs-front-fargate" {
  family                   = "ecs-task-front-terraform"
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = 1024
  memory                   = 2048
  container_definitions    = <<TASK_DEFINITION
[
  {
    "name": "Nginx",
    "image": "nginx",
    "cpu": 1024,
    "memory": 2048,
    "essential": true
  }
]
TASK_DEFINITION
}
```
### 間違えたところ
考えすぎて、ドキュメント読み込むよりさっさと
terraform plan やってエラー確認している方がいいかな
1-2 仮想環境の構築、プロジェクトの開始、サーバー立ち上げ(スナガクのポートフォリオ作成日記)

こんにちは！
記事をご覧いただきありがとうございます。
スナガクと申します。

転職などのためにポートフォリオを制作させて頂いてます。
言語はPythonで、基本的な文法は、本などで学習した者です。
分からないことだらけで、悪戦苦闘中ですが、頑張ります！
同じ初心者の方の助けになれば、幸いです！

今日は、仮想環境の構築から、プロジェクトの開始、サーバーの立ち上げまで行いました。
特にトラブルはなかったので、写真だけ残します。

![Venv 仮想環境立ち上げ(python -m).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2963171/09f8cde0-aadc-8809-7103-a4c660d2dc3b.png)

![Venv 仮想環境立ち上げ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2963171/86804eea-6a2f-0325-f774-57b4950a9d7e.png)

![プ露ジェクト立ち上げ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2963171/80596fed-f5f7-b01f-191a-722696423951.png)

![プ露ジェクト立ち上げ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2963171/9a36f716-f542-d090-cba4-e6a0c80245c2.png)

![サーバー立ち上げ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2963171/b30e86f3-bcf6-6a5a-bb8b-557f1b9e7b89.png)

![サーバー立ち上がり.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2963171/dce5d21f-53dc-8e6c-9246-3efc2310ee50.png)



次は、スクレイピング用のコードを打ち、
Function-based Viewの元となる関数を作ります！

最後まで、ご覧頂き、ありがとうございました！
次回の記事も、よろしければご確認ください。

下記　作りたいポートフォリオの内容です！

制作するポートフォリオの内容は、
Djangoを使ったWebアプリケーションです！
Webアプリケーションの中身は、
It技術の最新情報・トレンドを確認できる、そんなサイトです。
時間がない、ご多忙なエンジニアの方でも、
意欲があれば、このサイトを見て勉強できる。
また、トレンドの情報を自ら投稿し、周りとも共有できる。
そんなサイトを作れば、周りの方に貢献できるかな？
と思っています！

具体的な方法は、
Webスクレイピング等を用いて、
最新技術や、気になるトピックを一目見て確認できる。
そんなサイトです！
また、機能は順次追加していければ、と思っています！

更新頻度は、1週間に1～2回になると思います！
（2022/11/12　現在）

見守って頂けると幸いです！
ご指導、ご鞭撻のほど、よろしくお願いいたします。
supabaseで簡単なTodoアプリを構築した話 - リアルタイム機能

# はじめに

Baas(Backend As A Service)で何かサービスを構築してみたいと思い、
firebaseを触ってみようと思ったところ、Firebase の代替と謳われているsupabaseを発見。

こちらの方が面白そうだと感じたため、構築してみることに

# 使ったもの

* Vite + Svelte + Typescript
    * @supabase/supabase-js
    * tailwind css

* supabase
    * auth
    * db
    * realtime

# これまで

1. フロント側でsupabaseを呼び出せるところように

    https://qiita.com/doyaseizin/items/8820a095a433d09f300d

1. データ取得・操作

    https://qiita.com/doyaseizin/items/d6e0237b700448cc1826

1. ポリシー設定

    https://qiita.com/doyaseizin/items/2afe8df35e0a7adc7e00

## tasksテーブル

|項目|型|
|----|----|
|id|uuid|
|user_id|uuid|
|content|text|
|is_done|boolean|
|created_at|date|

前回まででこのテーブルから`自分が作成した`、`Todoの取得や操作`ができるようになった。

# 今回

共同作業などを行っているときは、
他の人の操作が即座に自分の画面に表示された方が都合がいい。

今回はsupabaseのリアルタイム機能を使って、DBの操作が行われたときに、
即座に画面に反映されるようにしていく。

### 1. Realtimeを有効化する

1. サイドメニューより、`Table Editor`タブを開く
1. テーブルを選択し、テーブル名横の`∨`をクリックし、`Edit Table`を選択する。
1. `Enable Realtime`にチェックを入れて`Save`する

### 2. リアルタイムリスナーをセットアップ

1. Channelをセット

    ```javascript
      const TaskChannel = supabase.channel('task')
    ```

1. イベントに対してのコールバック関数を設定

    例) `tasks`テーブルに`INSERT`イベントが起きた時に着火させたい場合

    ```javascript
      const TaskChannel = supabase.channel('task')

      TaskChannel
        .on (
          'postgres_changes',
          { event: 'INSERT', schema: 'public', table: 'tasks' },
          (payload) => {
            // こちらに処理を作成
          }
        )
    ```

同様に`UPDATE`や`DELETE`のイベントが起きた時にも処理を作成することで、
DBの状態をリアルタイムに受け取り、ローカルへ反映させることが可能でした。

これでシンプルなToDoアプリの完成です。

次回はsupabaseをdocker-composeで起動し、利用した感想などを書いていきます。

supabase、とってもいい感じですね
JetpackComposeでSnackbarの実装方法



JetpackComposeの知識を深めるために、今回はSnackbarを実装を試してみたいと思います。

# リファレンス

https://foso.github.io/Jetpack-Compose-Playground/material/snackbar/



# 実装方法

```SnackbarView.kt
@Composable
fun SnackbarView() {
    Column {
        val snackbarVisibleState = remember { mutableStateOf(false) }
        Button(modifier = Modifier.padding(16.dp),
            onClick = { snackbarVisibleState.value = true }) {
            Text("スナックバー表示")
        }
        if (snackbarVisibleState.value) {
            Snackbar(
                action = {
                    Text(
                        modifier = Modifier.clickable { snackbarVisibleState.value = false },
                        text = AnnotatedString("閉じる")
                    )
                },
                modifier = Modifier.padding(8.dp), 
                content = { Text(text = "スナックバーの表示メッセージ") }
            )
        }
    }
}
```

Snackbarが用意されているので、contentに表示したいViewをactionに今回は閉じる用のクリックできるテキストを設定してみました。actionはSnackbarの右側の領域に設定されます。

# サンプル動作
![スナックバーサンプル.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/6344c7c9-c7ab-12c9-f040-f9c2ab21aaa3.gif)



シンプルなSnackbarは簡単に作れそうです。
AHC014参加記


[estie プログラミングコンテスト2022 (AHC014)](https://atcoder.jp/contests/ahc014) に参加したので記録しておく。

## 結果

後半をランダムに作り直す方針で取り組み、システムテストで1,836,678,087点、101位だった。
焼きなまししてない勢としてはまあまあの出来だと思う。[前回](https://qiita.com/hotpepsi/items/05aef3830137d3fddf9c)よりちょっと良かった。

## やったこと

まず完全にランダムに生成するソルバーを実装してみた。
時間いっぱいまで作り直すようにしたら27.7M点。制限時間が3秒になっていたので5秒にしたら35.0M。
意外と良さそうな点数だったので、部分的に作り直すようにしてみた。
ランダムで作り、スコアがよかったものを30個取り、それらの先頭の30点だけ残して、残りをランダムで作り直すようにしてみた。37.8M点。
焼きなましの温度管理のように、残す部分をlog(経過時間)にしてみたらだいぶスコアが伸びて43.0M点。
後半あまり良くならないので、全体で2回(つまり2.5秒ずつ)やって良いほうを採用するようにしたら44M点を超えた。
細かい改善で最終的に45.4M点。
密になったら良いのかなと思って近いのを優先させてみたりしたがうまくいかなかった。

## ツールなど

- テストケースを10000件生成し、MとNごとにディレクトリにわけた。(Mは25刻み) 分布を確認できるのと、似た条件で10ケースくらい実行するときに便利。
- 2種類の実行ファイルで数ケース実行して結果を試すスクリプトも用意した。
- NとMの平均も取ってみた。N = 45、K=114

## 工夫・実装内容など

- 縦横と斜め、4方向それぞれで各点をC++のsetに入れて、隣の点と、その距離を取得できるようにした。
- setは遅いので、近い点を総当たりで探すようにするのも書いてみた。近い距離ならこちらのほうが速かった。
- 伸ばせる可能性のある点を集めて、シャッフルして1点ずつ確認するのだが、4方向で伸ばせなくなったらフラグを立てて伸ばせる候補から外すようにした。
- ビームサーチっぽく履歴を持って作り直すようにしたが、NとMごとにパラメータを調整した。

## 取り組み方について

- メモを残し忘れた。
- やはり実装に時間を使いすぎている感。
- 他の方の解説のように、領域ごとに作り直せばよかった。
火事発生：トラブル案件の火の消し方

![4189941_s.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/dafbf561-fe72-390a-686f-328a83cd15a2.jpeg)
システムの世界では、上手く行ってないプロジェクトの事を**火のついたプロジェクト**とか**炎上プロジェクト**という言い方をします。
その火の点いたプロジェクトを沈下するためには、**ファイヤーマン**を投入します。
昔から良く、火の点いたプロジェクトの火消し役・**ファイヤーマン**として、呼ばれてました。
火の点いたプロジェクトというのは、非常に混沌としてます。関わっているプロジェクトメンバー全員が、混沌とし、疲労してます。営業・PM・開発者・クライアント全てのメンバーが同じく疲労している事が多いです。

僕がやってきた火消しの方法です。
## １．現状を把握・分析する
火消し役として、プロジェクトにアサインした時に最初に行うのは、利害関係者の意見をヒヤリングする事から始まります。そして、どこにボトルネックがあるのかを分析・解析します。
火の点いてる期間が長ければ、長いほど、分析・解析が難しそうですが、ボトルネックは、特定の人だったり、特定の機能だったり、意外に難しくないパターンが多いです。

# ２．コミュニケーションの潤滑油となる
火の点いたプロジェクトを鎮火させるのは、簡単ではありません。ファイヤーマンといえども、一人でシステム全体を開発する事はできませんし、プロジェクトの詳細を把握するのは、非常に難しい事です。
とはいえ、大量の人員を投入しても余計に混乱するだけになってしまいます。
プロジェクトメンバーは、疲労しているため、心に余裕がない状態になってます。そのため、新参者に心を開いてる余裕はありません。忙しい所に良く分からない人間がやって来たら、バリヤーを張ってしまいます。
ここが最も重要かもしれません。
小さいプロジェクトであれば、ファイヤーマンが一瞬に全てを解決する場合もありますが、大きいプロジェクトでは、そうは行きません。
愚痴を聞いてあげたり、ガス抜きをしながら、良い方向へ向かってると思ってもらえる様にします。

# ３．タスクを遂行する様に指示だしを行う
コミュニケーションが円滑になってきたら、後は、タスクを整理して実行してもらう事になります。
ここでは、改めて実行可能なスケジュールも作成する事が重要となります。混沌としたメンバーは、明確なタスクと実現可能なスケジュールを見る事によって、冷静さを取り戻す事になります。前提として、残業や休日出勤等はいれては行けません。余裕をもたせて安心させる事が大事です。

# ４．頃合を見て、必要な人員を投入する
最後にタスクに関して、人手が足りない部分やスキル的に足りない部分は、必要な人員の投入をして、全体のスケジュールに合わせて行く事になります。あくまでも、実際のタスクは、現状のメンバーがメインで作業を行ってもらうしか、ありません。そこの補佐の人員の投入になります。
1,2,3を対応せずに人だけを投入するプロジェクトがありますが、上手く機能しません。余計に混沌とするだけです。

# まとめ
以上が、火の点いたプロジェクトの鎮火方法になります。
もちろん火が点かない様にプロジェクトをマネージメントするのが大前提となりますが、火の点いたプロジェクトに投入された場合の対処方法です。銀の弾丸はありません。一つずつ解決してみてください。
# お願い
今後も続けていきますので、フォロー、イイね、シェアお願いします。
下記、説明会もご参加下さい。
[エンジニア年収アップ講習(転職サポート付き！)　無料説開会　12月6日　19時開催](https://cto-can-be.hp.peraichi.com/)
javaでseleniumを使用する方法

# はじめに
自動テストやスクレイピングに使いたくてseleniumを入門しました。

# 環境
Java：8
ブラウザ：Google Chrome 107.0.5304.110
selenium:4.6.0
webdrivermanager:5.3.1

# 環境設定
## ライブラリを依存関係に追加する
build.gradleに必要なライブラリの依存関係を追加します。
seleniumライブラリである「selenium-java」に加えて、
ブラウザをコントロールする「webdrivermanager」を追加します。

```build.gradle
dependencies {
    implementation 'org.seleniumhq.selenium:selenium-java:4.6.0'
    implementation 'io.github.bonigarcia:webdrivermanager:5.3.1'
    // ・・・
}
```

## ブラウザーのドライバーをインストールする
[こちら](https://www.selenium.dev/ja/documentation/webdriver/getting_started/install_drivers/#%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9)から使用したいブラウザのドライバーをダウンロードします。
今回はgoogle chromeを使用するため、「ChromeDriver 107.0.5304.62」のmac版をダウンロードします。
zip形式なので、解凍して適当な場所に配置します。

### 注意（ブラウザとドライバーのバージョンは合わせること）
ドライバーはバージョン別に用意されています。
使用するブラウザのバージョンを確認し、合ったドライバーを選んでください。

（最初、特に気にしていなくて実行時エラーが多発しました。。。）

# サンプルを実装

```Main.java
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.time.Duration;

public class Main {

    public static void main(String args[]) {
        
        // ドライバーをセットアップし、インスタンス化します。
        // 先ほどインストールしたドライバーのパスをここで指定します。
        WebDriverManager.chromedriver().setup();
        System.setProperty("webdriver.chrome.driver","/opt/chromedriver");
        WebDriver driver = new ChromeDriver();

        // googleの検索ページに遷移します。
        driver.get("https://www.google.com/?hl=ja");

        // ブラウザ操作の待ち時間を指定します。
        // seleniumは人が操作するより、ずっと速くブラウザを操作します。
        // 応答に時間がかかるページでは適宜、待ち時間を指定します。
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        // クラス属性で検索し、テキストボックスの要素を取得します。
        WebElement textBox = driver.findElement(By.className("gLFyf"));

        // テキストボックスに「Selenium」と入力し、検索を実行します。
        textBox.sendKeys("Selenium");
        textBox.sendKeys(Keys.ENTER);

        // セッションを終了します。
        // ※コメントアウトしていますが、外すと最後にブラウザを閉じるようになります。
        // driver.quit();
    }
}
```

実装出来たら、サンプルを実行してみます。
chromeが起動し、検索が実行されれば成功です。

# 参考文献
https://www.selenium.dev/ja/documentation/overview/

https://www.selenium.dev/ja/documentation/webdriver/getting_started/install_drivers/#%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9
PDFを画像へ変換するLinuxコマンド

Go言語で『PDFファイル』を『画像ファイル』へ変換しようとして調べていたら、
Linuxコマンドで簡単に変換ができたので、そのコマンドを実行する事にした。

## コマンド
```console
# pdftoppm {オプション} {PDFファイル名} {変換画像ディレクトリ}
$ pdftoppm -png test.pdf tmp/
```

## 参考
[【 pdftoppm 】コマンド――PDFファイルを画像に変換する](https://atmarkit.itmedia.co.jp/ait/articles/1903/08/news039.html)
Rails – ModelのscopeとControllerのメソッドチェーンでAND検索をする例


```rb
class User < ApplicationRecord
  scope :filter_name, ->(name) do
    return self if name.blank?
    where(name: name)
  end

  scope :filter_age, ->(age) do
    return self if age.blank?
    where(age: age)
  end
end
```

```rb
class UserController < ApplicationController
  def search
    users = User
              .all
              .filter_name(user_params[:name])
              .filter_age(user_params[:age])
    
    render json: { users: users }
  end

  private

  def user_params
    params.permit(:name, :age, :keyword)
  end
end
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
SQSハンズオンやってみた

# 初めに
https://aws.amazon.com/jp/getting-started/hands-on/send-messages-distributed-applications/

上記ハンズオンやってみました。
GUIが変わっていたこともあり、備忘録として載せたいと思います。

# キューの作成
名前を入力し、後はデフォルトのままで作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/9c3c6d4c-18b6-c0ab-cedf-3117719b4d79.png)

# メッセージの送信
該当のキューでメッセージを送受信を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/5e31bd5b-4ed5-2f13-b6c2-5905d68aa3c7.png)

メッセージ内容を入力し、送信する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/19ab8ef1-d513-2cf8-124f-bde2a738537e.png)

# メッセージの取得
下側のメッセージをポーリングを押すと、メッセージが取得可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/e5b4b1bd-124f-5405-983a-13c64325dbb6.png)

![Screenshot at Nov 27 12-47-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/1f21a34b-f2db-27bd-1c51-86f2d03b9ef2.png)
Leetcode 79. Word Search

# 79. Word Search

https://leetcode.com/problems/word-search/

## アプローチ
### DFS

```java
class Solution {

    public  boolean[][] isVisited;
    public  int height = 0;
    public  int width = 0;

    public boolean exist(char[][] board, String word) {
        height = board.length;
        width = board[0].length;
        isVisited = new boolean[height][width];

        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                isVisited = new boolean[height][width];
                if (board[i][j] == word.charAt(0)) {

                      boolean result = dfs(board, word,  i, j, 0);if (result) {
                        return true;
                    }
                }
            }
        }

        return false;
    }
        public  boolean dfs(char[][] board, String word, int i, int j, int index) {

        if (index == word.length()) {
            return true;
        }
        if (i < 0 || board.length <= i || j < 0 || board[0].length <= j || isVisited[i][j] || word.charAt(index) != board[i][j]) {
            return false;
        }

        isVisited[i][j] = true;
        if (dfs(board, word, i + 1, j, index + 1) ||
                dfs(board, word, i - 1, j, index + 1) ||
                dfs(board, word, i, j + 1, index + 1) ||
                dfs(board, word, i, j - 1, index + 1)) {
            return true;
        }
        isVisited[i][j] = false;
        return false;

    }
}
```