OmniAICreator/Qiita-1.07M huggingface dataset:
Androidアプリのtargetsdkversionを変更する

# 背景
[過去の記事](https://qiita.com/silverbox/items/1b514f80a7bbbef8ba9f)で、古いAndroidアプリをKotlinに変更したりした。最近またGoogleからAndroidアプリのtargetsdkversion変更指示が来た。
もう新規機能などは何もしていないプロジェクトだが、継続はしておきたい。
自分の為の備忘録で、手順を記載しておく（その頃には手順が変わるのではないかという可能性も高いが、一応）。

# ソースの設定変更

※以下変更箇所で、json形式の設定情報の表記には、hoge.fuga.foo 形式で階層を表現しています（全体図記入すると他の情報が煩わしいので）。直接的にその表現ではない事をご注意ください。

## targetSdkVersion を変える

1. %プロジェクト%/app/build.gradle を開く
2. android.defaultConfig.targetSdkVersion を変える（今回は29）
3. android.compileSdkVersion を変える（今回は29）

## graleのバージョンを変える

```console:コンソールに出たエラー
Minimum supported Gradle version is 6.1.1. Current version is 5.4.1.

Please fix the project's Gradle settings.
Fix Gradle wrapper and re-import project
Open Gradle wrapper properties
Gradle settings
```

ご親切に最後の３行にはリンクが張ってあり、クリックすると処理が始まる。```Fix Gradle wrapper and re-import project``` をクリックしてしばし待つ。

３つのステップがあるのではなく、3種類の対応の中で１つ選ぶらしい。エラーが無くなった。

## その他

上の設定ファイルを開くと色々更新サジェストされたので、それも更新しておく（リンククリックで自動でやってくれる）。

## 実行

メニューから、Run -> Run 'app' でエミュレータでの実行確認。

## ビルド設定

1. %プロジェクト%/app/src/main/AndroidManifest.xml を開く
2. manifest タグ内、android:versionCode、android:versionName を一つ上に上げる。

## ビルド実行

1. Build -> Generate single bundle / APK
2. キーストア関係のファイルやパスワード入力
3. 出力先に %プロジェクト%/app を選択
4. Build vaiants に release を選択
5. %プロジェクト%/app/release 配下に app-release.apk が出来てる事確認

# 登録

## GooglePlay コンソールでの対応

1. アプリ選択
2. 「リリース管理」
3. 「アプリのリリース」
4. 製品版トラック → 「管理」
5. 「リリースを作成」
6. 先に作成した app-release.apk をアップ
7. 「このリリースの新機能」に「Android OS のセキュリティアップデートに伴う更新」とか書く
8. 「保存」、「確認」
9. 「製品版としてリリース」

# あとがき

ほぼ未来の自分向けの記事ですが、私同様に、昔作ったAndroidアプリを継続したい人の役に立てば幸いです。
しかし、変更の度に色々AndroidStudioにサジェストされますね。従っておくのが得そうです。

全然話は変わって、せっかくKotlinでの開発環境整ったのだから、新規に何かAndroidアプリを開発したいと思う今日この頃でした。
【Laravel】ファイルをアップロードしたい

#アップロードフォームの作成
```php:index.balde.php
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<form method="POST" action="/upload" enctype="multipart/form-data">
		{{ csrf_field() }}
	<input type="file" id="file" name="file" class="form-control">
	<button type="submit">アップロード</button>
	</form>
</body>
</html>
```
引用：[Laravelでファイルをアップロードする方法を詳細解説](https://reffect.co.jp/laravel/how_to_upload_file_in_laravel#i)
##ポイント
ファイルアップロード時は**enctype=”multipart/form-data”**を必ず指定する

##ルート情報
通常表示のために適当にアドレスを書く

```php5
Route::get('/','コントローラ名@index');
```

#アップロードファイルの受け取り
```php
    function store(Request $request)
    {
        print_r($request->all());
    }
```
引用：[Laravelでファイルをアップロードする方法を詳細解説](https://reffect.co.jp/laravel/how_to_upload_file_in_laravel#i)

また以下のように書けばファイルのみを見ることができる

```php5
print_r($request->file('file'));
```
fileメソッドの引数として`file`が入っているのはフォームのinput要素のnameプロパティに設定している値。


##ルート情報
このメソッドを書いたらpost送信されるときに呼ばれるようにルート情報を書く

```php5
Route::post('/','コントローラ名@store');
```

#アップロードされたファイルの保存

```php5
public function store(Request $request){

　　　$request->file('file')->store('');
		
}
```
引用：[Laravelでファイルをアップロードする方法を詳細解説](https://reffect.co.jp/laravel/how_to_upload_file_in_laravel#i)

##名前をつけて保存
パスとファイル名、ディスク名を指定して好きな名前をつけられる

```php5
$request->file('file')->storeAs('','image.jgp');
```
引用：[リクエストの取得](https://readouble.com/laravel/7.x/ja/requests.html)

##複数ファイルのアップロード
input要素を以下に修正

```index.blade.php
<input type="file" id="file" name="file[]" class="form-control" multiple>
```
変更点は以下の2つ

- nameを`"file"`から`"file[]"`に変更
-  `multiple`を追加

##受け取り
前と同じで`$request->file('file')`で受け取れ、配列となっている。

#参考
- [Laravelでファイルをアップロードする方法を詳細解説](https://reffect.co.jp/laravel/how_to_upload_file_in_laravel#i)
29歳で未経験エンジニアの勉強日誌

LPIC101を独学で合格したのち、仕事をし始めて勉強速度落ちたため記事を書くことにしました。

現在の仕事先でもLPICどころかインフラもWeb系の知識も全く使わないのでいつまでも未経験・・・。
早く合格し、次にAWSの勉強をして新しい仕事をしたいので記録することに。
自分の為のメモ

本日の勉強内容
１．シェル、スクリプト、およびデータ管理

.とsource  現在のシェルでスクリプト実行。
           例). ./test
              source ./test

/etc/profile  ユーザーログイン時に読み込まれるファイル。
　　　　　　　　環境変数設定する。

~/.bash_profile Bash起動時。
　　　　　　　　　ユーザー固有の環境変数などを設定。
↓　存在しない場合
~/.bash_login 

↓存在しない場合
~/.profile

~/.bashrc 　~/.bash_profile の次に呼び出される。
　　　　　　　環境変数でない変数の設定。エイリアスの設定。関数の　　　　　　　定義を行う。

/etc/bashrc  ~/.bashrcの次に呼び出される。全ユーザー共通。

~/.bash_logout  ログアウト時に呼び出される。


env  環境変数の表示、変更。

export シェル変数を環境変数にする。

set  すべての変数の表示
     (set -C, set -o noclobber でリダイレクトの禁止)

unset 環境変数、シェル変数の削除をする。

function 関数の作成。

alias コマンドを別の値で定義する。
can't find gem bundler (>= 0.a) with executable bundleの対処法

既存のRailsプロジェクトをcloneし、`% bundle install`をした際にこのエラーが発生。

```
% bundle install

Traceback (most recent call last):
       2: from /Users/trilingual/.rbenv/versions/2.5.1/bin/bundle:23:in `<main>'
       1: from /Users/trilingual/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/Users/triringual/.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
```

### 原因
Gemfile.lock最下部に記載の`BUNDLED WITH2.0.2`の記述と`自身がインストールしたbundlerのバージョン`と異なってしまっていることが原因。

```ruby:Gemfile.lock
<省略>
BUNDLED WITH
2.1.4
```
これと

```
% bundler -v
Bundler version 1.17.1
```
これが違うということです。

### 解決策
①アプリケーションのGemfile.lock最下部に記載の`BUNDLED WITH○○`の記載を確認

```ruby:Gemfile.lock
<省略>
BUNDLED WITH
2.1.4
```
②Gemfile.lockに記載のバージョンをインストールする(今回は`2.1.4`)

```
% gem install bundler -v 2.1.4
```

###まとめ
`アプリケーションで想定している環境`と`自身のPCの環境`
を合わせてあげるようなイメージです。
・PCを買い替えてアプリを開いたとき
・アプリをgit cloneしたとき
・Rubyのバージョンを変更したとき
のようなパターンでこのエラーが頻発しているように感じます。

同じエラーが発生した方へ届きますように！
Android Studioをアップデートした際に「some conflicts were found in the installation area」がでた時の対処法

表題の通り**3.3.1=>4.0.1**にアップデートした際に「some conflicts were found in the installation area」とエラーが出てアップデートが完了しないことがありました。



## 対処法
Android Studioを完全にアンインストールし、最新バーションをインストールすることによって、エラーは対処できた。

[MacでAndroidStudioを完全アンインストール - Qiita](https://qiita.com/nagaoyuriko/items/f310b595ff16061e1186)

### 補足
アンインストールの他にもSDKManagerからエラーが発生しているComponentをアンインストールし、再度インストールすると直る方法もあるようです。
今回は事前にホームディレクトリ名などを変更し時間がかかりそうだったので、完全にアンインストールする方法を選びました。

## 参考
- [MacでAndroidStudioを完全アンインストール - Qiita](https://qiita.com/nagaoyuriko/items/f310b595ff16061e1186)

- [intellij idea - Android Studio Update: Some conflicts found in installation area - Stack Overflow](https://stackoverflow.com/questions/28587234/android-studio-update-some-conflicts-found-in-installation-area)
自作OS事始め 1. 環境構築編

# そうだ、OS作ろう！

というわけで、OSを作ってみたいと思います。
今回はGCCのクロスコンパイラを入手するところまでやっちゃいましょう。


## 用意するもの
* Ubuntu 20.04

## 1. 依存関係のインストール
まずは、依存関係をインストールしていきます。

必要なものは以下の通りです。

* curl
* build-essential, m4
* libgmp3-dev, libmpc-dev, libmpfr-dev
* qemu, qemu-kvm

curlはお好みで、wgetなどでも構いません。

```sh
$ sudo apt update
$ sudo apt -y install curl build-essential m4 libgmp3-dev libmpc-dev libmpfr-dev qemu qemu-kvm
```

## 2. gmp、mpfr、mpc、binutilsのビルド

まずは、gmpをmakeします。`--prefix=/usr/local/cc`にしていますが、ここもお好みで構いません。ただし、この`--prefix`で指定した値はgmp、mpfr、mpc、binutilsで共通とした方が良いと思います。

まずはgmpから。

```sh:gmp
$ curl --output gmp-6.2.0.tar.bz2 https://ftp.gnu.org/gnu/gmp/gmp-6.2.0.tar.bz2
$ tar -xvf gmp-6.2.0.tar.bz2
$ cd gmp-6.2.0
$ ./configure --prefix=/usr/local/cc
$ make check && sudo make install
$ cd ..
```

つづいてmpfr、mpc、binutilsの順番でmakeしていきます。

```sh:mpfr
$ curl --output mpfr-4.1.0.tar.bz2 https://ftp.gnu.org/gnu/mpfr/mpfr-4.1.0.tar.bz2
$ tar -xvf mpfr-4.1.0.tar.bz2
$ cd mpfr-4.1.0
$ ./configure --prefix=/usr/local/cc
$ make check && sudo make install
$ cd ..
```
```sh:mpc
$ curl --output mpc-1.2.0.tar.gz https://ftp.gnu.org/gnu/mpc/mpc-1.2.0.tar.gz
$ tar -xvf mpc-1.2.0.tar.gz
$ cd mpc-1.2.0
$ ./configure --prefix=/usr/local/cc
$ make check && sudo make install
$ cd ..
```

```sh:binutils
$ curl --output binutils-2.35.tar.xz https://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.xz
$ tar -xvf binutils-2.35.tar.xz
$ cd binutils-2.35
$ ./configure --target=x86_64-elf --prefix=/usr/local/cc --disable-nls
$ make
$ make install
$ cd ..
```

## 3. gccのビルド

さて、ついにGCCのmakeです。
ここで、注意点がいくつかあります。
1つ目は、gccのソースコードのディレクトリに入って、**`./configure`としてはいけない**ということです。そのようにしてしまうと、`make all-target-libgcc`でこけます。
2つ目は、configureの引数の`--with-xxx`です。これは、それぞれ前の段階でgmp、mpfr、mpcの`--prefix`で指定したディレクトリを指定してください。
3つ目は、`--with-as`引数です。これは、ほかのものと違い、**実行バイナリのパス**を直接指定する必要があります。

```sh:gccのmake
$ curl --output gcc-10.2.0.tar.xz https://ftp.gnu.org/gnu/gcc/gcc-10.2.0/gcc-10.2.0.tar.xz
$ tar -xvf gcc-10.2.0.tar.xz
$ mkdir gcc-make-tmp
$ cd gcc-make-tmp
$ ../gcc-10.2.0/configure\
    --target=x86_64-elf\
    --prefix=/usr/local/cc\
    --disable-nls\
    --enable-languages=c\
    --without-headers\
    --with-gmp=/usr/local/cc\
    --with-mpfr=/usr/local/cc\
    --with-mpc=/usr/local/cc\
    --with-as=/usr/local/cc/bin/x86_64-elf-as # asコマンドのバイナリのパスを指定する
    # これがないとこけることがある(stdio.h: no such file or directory.)
    # こける場合は追加する
    # --with-headers=/usr/include\
    # --with-headers=/usr/include/x86_64-linux-gnu
$ # 結構な時間がかかるので、このコマンドを実行している間にお茶休憩をしましょう。
$ make all-gcc && make install-gcc
$ make all-target-libgcc && make install-target-libgcc
```

## 4. テスト

```sh
$ export PATH=/usr/local/cc/bin:$PATH
$ x86_64-elf-gcc -v
Using built-in specs.
COLLECT_GCC=x86_64-elf-gcc
COLLECT_LTO_WRAPPER=/mnt/d/usr/local/cc/libexec/gcc/x86_64-elf/10.2.0/lto-wrapper
Target: x86_64-elf
Configured with: (省略)
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (GCC)
```

このような出力がなされれば成功です。お疲れさまでした。

## 5. 感想
情報が少なくて苦労しました。特に、最後のgccのmakeがしんどかった。

**binutilsはソースからビルドしましょう。**
[rails]ネストした関係で親情報を子ビューに表示する方法


#やりたいこと
前提・Itemの情報がないとOrderの情報は成り立たない関係
（Orderにitem_idカラムがある（どのitem情報を指しているのか？））
（親）itemテーブル＞（子）orderテーブルになる。

orderコントローラでindexアクションを起動させ（index.html.erb）に
（親）のitem情報を表示させたかったらどうやって記述するの？
※例えば
itemテーブル　　　　　
id:1
ぬいぐるみ4000円      

orderテーブル
item_id:1
user_id:3
ぬいぐるみ4000円とuser_idが結びつくんだな・・・

#手順

```
config/routes.rbの記述内容
Rails.application.routes.draw do
   devise_for :users
  root  'items#index'
  resources :items do
    resources :orders, only: [:create, :index]
  end
end
```

#1.親items>子ordersの関係をroutes.rbで記述する

```
resources :items do
    resources :orders, only: [:create, :index]
```
これで（親）item>（子）orderの関係を指定することができる。ネストすることができる



#2.ordersコントローラーで@item = Item.find(params[item_id])と記述する

```
def index
     @item = Item.find(params[:item_id])
  end
```
@itemの箱の中にitemテーブルの情報を入れる。
どのitemテーブルの情報を指定するか[:item_id]で指定できる
ユーザーが選択したitem情報を@itemに代入する



#3.@itemをorder#indexのビューファイルに記述する

```
orderコントローラーのindex.html.erbに記述
<%= @item.item_name %>
```
これで（親）itemテーブルからデーターを抜き出して
（子）orderコントローラーのindex.html.erbのビューに表示することができる。



#まとめ
分かりにくいまとめですが
要は親テーブルの情報を抜き出して、子のビューに表示させたかったら
ネストを使って関係を示し、子コントローラーでparams[:親＿id]と記述すれば
親から情報を抜き出して子のビュー表示することができるという内容でした。

うまくまとめることができないのは私の力不足です・・・。
具体的な画像とテーブル情報が添付していると分かりやすくなったかも。
HerokuにてSelenium利用時にChrome has crashedのエラー

わりとレアケースだとおもうけど、[stackoverflowの同様の質問欄](https://stackoverflow.com/questions/50642308/webdriverexception-unknown-error-devtoolsactiveport-file-doesnt-exist-while-t#:~:text=Explanation%20regarding%20the%20issue%3A,its%20reference%20in%20scoped_dirXXXXX%20folder.)みても解決できなかったので念の為投稿


```
  File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 81, in __init__
    desired_capabilities=desired_capabilities)
  File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: crashed.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /app/.apt/usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
```

# 結論: For文内でWebブラウザ取得すると、5回目くらいでおきるよ!!

Before
```
for 商品 in 商品リスト:
    browser = セレニウムからWEBブラウザ取得()
    browser.get('URL')

def セレニウムからWEBブラウザ取得():
    options = Options()
    options.add_argument('--no-sandbox')
    options.add_argument("--headless")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--window-size=1920,1080")
    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)
    return browser
```

After
```
browser = セレニウムからWEBブラウザ取得()
for 商品 in 商品リスト:
    browser.get('URL')
    
def セレニウムからWEBブラウザ取得():
    options = Options()
    options.add_argument('--no-sandbox')
    options.add_argument("--headless")
    options.add_argument("--disable-dev-shm-usage")
    options.add_argument("--window-size=1920,1080")
    browser = webdriver.Chrome(ChromeDriverManager().install(), options=options)
    return browser
```

これだけ。 
まぁAfterのほうが効率的だし。
なんか5回以上Borwserを呼び出したらだめだよ!みたいな制約あるんかな?
ローカルだと起きない。Heroku上だと起きる。
[SwiftUI]NavigationViewでListからNavigationLinkで遷移する方法

#今回の記事で実装できるもの
SwiftUIでNavigationViewを使えば本当に簡単に以下の様なものが作れます。

![スクリーンショット 2020-09-05 22.03.56.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517666/1e71599f-2e49-370e-7eda-77c52514f231.jpeg)


以下ではこの実装の解説をしていきます。


#Code

```swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            List(1..<100) { num in
                NavigationLink(destination: Text("Lesson\(num)")) {
                Text("Lesson\(num)")
                }
            }.navigationBarTitle("SwiftuUI")
        }
    }
}
```
これだけ少ないコードで上記の様な
・タイトル
・リスト
・遷移
を実装する事ができます。
ではどの様に実装しているか少し解説していきたいと思います。

#解説
###NavigationView
・NavigationLink
・navigationBarTitle
はもちろんですが、その他にも
・navigationBarItems
など使用するには必須。

###List
(1..<100)でリストの個数を定義しています。今回は1〜99のリストを作成して数字はnumに返しているのでnumもそのままList内で使う事がきますのでText内などでも（\num）で使用する事ができます。

###NavigationLink
destination以降でリンク先の表示するものを定義する事ができます。今回はテキストですがimageはもちろん、Viewを指定して画面を遷移させる事も可能です。

###navigationBarTitle
("")内に書いたテキストをタイトル位置(画面の上部)に表示させる事ができます。
大きさは
```("SwiftuUI", displayMode: .large)```
displayModeの後に
large
inline
automatic
で指定する事ができます。

以上です。是非参考になれば嬉しいです。

#最後に
普段は個人でSwiftUIでアプリを作っています。ハードも作るの大好きです。
よければ下記もチェックして下さい♪
Twitter
https://twitter.com/oka_yuuji
note
https://note.com/oka_yuuji
railsで先週日曜日からのものを取ってくる

# この記事でやること

- 先週の日曜日を指定
- 範囲指定でcreated_atを先週日曜日からの範囲指定

# 先週の日曜日の指定

```ruby
0.days.ago.prev_week # 先週の月曜日
0.days.ago.prev_week(:sunday) # 先週の日曜日
0.days.ago.prev_week(:friday) # 先週の金曜日
```

https://apidock.com/rails/Date/prev_week

「今週の月曜日、先週の月曜日、来週の月曜日を取得する」
https://qiita.com/14021939/items/b6c13367042b8192936d

# 範囲指定

```ruby
from = Time.now.at_beginning_of_day
to   = from + 1.day

items = Item.where(created_at: from...to).order(created_at: :desc)
```

「ActiveRecordで日付の範囲指定」
https://waka.hatenablog.com/entry/2013/04/05/083349

# まとめ

```ruby
fromdate = 0.days.ago.prev_week(:sunday) + 8.hour
todate = Time.now
Post.where(created_at: fromdate...todate)
```

先週日曜日から現在のものをwhereで取得。現在はTime.nowで現在時刻までの指定をした
【PHP】フラッシュメッセージの実装

PHPについて学習内容を備忘録としてまとめます。
今回はフラッシュメッセージをポートフォリオに実装したので、実装方法を記録します。

#フラッシュメッセージ実装
全体の流れとしては空のフォームがあった場合に該当のエラーメッセージを格納し、
ログイン画面でエラーメッセージを表示するという流れになっております。

まずフォームが空かを確認し処理を行います。
これで該当のフォームが空のとき、エラーメッセージに値を格納することができます。

```php

//login_check.php(ログイン過程のファイルです)

if(empty($staff_code)){
	$error_messages['code'] = "コードを入力してください";
  }

if(empty($staff_pass)) {
	$error_messages['pass'] = "パスワードを入力してください";
  }

```
余談にはなりますが、`md5`などで値をハッシュ化するとフォームは空でも値が入ってしまい`empty`で処理できなくなります。

```php

//$staff_passは空

$staff_pass=md5($staff_pass);

//$staff_passに値が入る

if(empty($staff_pass)) {
	$error_messages['pass'] = "パスワードを入力してください";
  }

//上記処理が実行されない
```

`error_masseages`に値が格納されましたら、今度はセッションに値を格納します。
このときにフラッシュメッセージの種類によって色などを変更したい際は`$flash_type`も定義します。

```php

//login_check.php

if( isset($_SESSION['flash']) ){
	$flash_messages = $_SESSION['flash']['message'];
	$flash_type = $_SESSION['flash']['type'];
  }
  unset($_SESSION['flash']);
```
最後にログイン画面にてフラッシュメッセージを表示させます。


```php

//login_form.php

    <?php if (isset($flash_messages)): ?>
      <?php foreach ((array)$flash_messages as $message): ?>
        <p class ="flash_message <?= $flash_type ?>"><?= $message?></p>
      <?php endforeach ?>
    <?php endif ?>
```

##実装画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/8efa8872-3619-4944-9b9f-8d5c8df3cd44.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597913/eaed4ecb-9295-9fda-9373-7434bd5dea4a.png)
C言語ファイル出力

ファイル出力すだけの関数、テストのファイル作る時に使うかも。

```C:test.c
#include <stdio.h>
#define PROC_OK (0)
#define  PROC_NG (-1)

int SaveFileData(char *file_name,int data_cnt)
{
	FILE *fp = NULL;
	
	if ((fp = fopen(file_name, "w")) == NULL) {
		/* エラー */
		return PROC_NG;
	}
	
	for(int cnt=1;cnt<=data_cnt;++cnt)
	{
		fprintf(fp, "%08d", cnt);
		if(cnt > 0 && (cnt % 10 == 0) )
		fprintf(fp, "\n");
	}
	
	fclose(fp);
	return PROC_OK;
}
```
備品購買システムのデータモデルの作成ー午後

応用情報技術者平成30年春期 午後問6


ファイル：2018h30h_ap_pm_qs.pdf

参照：
https://www.ap-siken.com/kakomon/30_haru/pm06.html

この問は簡単と思っておりますので、メモも簡単に記載します。
詳細の分析は、上記リンクをご参照くだいますようよろしくお願いします。


１、ｆに入れる適切な字句を答えよ。
表１　備品購買の処理の流れとシステム化対象によると、「取引先のカタログを使って依頼。。。」という記載があるので、見積依頼明細テーブルには、ある決まっている取引先の情報でしょう。
相見積り機能によると、既に見積依頼テーブルが二つに分けるので、見積依頼明細テーブルも取引先ごとに異なる情報を登録しなければなりません。
なので、ｆが「見積依頼明細」です。


見積 （私の答え）
→
見積依頼明細　（参考答え）

私の考えは、「見積」テーブルに取引先番号もキーにしなかればならないだろうと思った。
実は、「見積番号」はキーとして十分ですね。
取引先ごと、見積番号が異なってあればよいとのこと。



＜＜図１　E-R図＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/0f94c6a3-5775-0b0a-a38d-330635255753.png)


＜＜相見積もり機能の検討＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/940ee640-53d8-44bf-7fa7-73e34ade141c.png)

＜＜表１　備品購買の処理の流れとシステム化対象＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/4cea648d-226f-305b-f807-d1a14541b5c2.png)


＜＜参照答え：修正後＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/f79169dc-e128-19fb-0a9a-14ebc3eb0716.png)


２、〔返品対応〕について，本文中の下線①にある追加したレコードのうち，納品明細表に追加したのはどのようなレコードか。返品に関する情報を記録することを考慮して，30字以内で述べよ。

返品したの商品番号、商品数量情報　（私の答え）
→
返品した商品の数量をマイナスの値に設定したレコード (25文字)　（参考答え）


私は、新規テーブルを追加していたと思ってしまった。
ですが、これは既存テーブル「納品、納品明細」ですね。
なので、数量をマイナス値に設定したレコード　でしょう。実際もそうやるだし、赤黒レコードというものでしょうね。


＜＜返品対応＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/38ef1cd8-52bb-26d8-00f7-9b5d9b6e46d1.png)
M5Stack Core2 のバイブレーションモーターを動かしてみる

[M5Stack Core2](https://www.switch-science.com/catalog/6530/)にはバイブレーションモーターが搭載されていますが、Arduino IDEでどのようにコーディングすればバイブレーションできるようになるのか知りたかったため、[公式リポジトリ](https://github.com/m5stack/M5Core2/)のソースコードを見てちょっとだけ調べたことをメモします。

# とりあえずバイブレーションを試すには

AXP192クラスのSetLDOEnable関数をコールすることで、バイブレーションの開始 or 終了を指定できます。

## サンプルコード

下記のvibration関数のようにバイブレーション開始から終了までをワンセットにした関数を定義しておくと、ボタン押下のタイミングに合わせて振動フィードバックしたいときなどにその関数１つ呼び出すだけで済むようになるので便利です。

```cpp
#include <M5Core2.h>
#include <AXP192.h>

AXP192 power;

// バイブレーション実行関数
void vibration() {
  power.SetLDOEnable(3, true);  // 3番をtrueにしてバイブレーション開始
  delay(100);                   // バイブレーションの長さ（ms）はお好みで調整
  power.SetLDOEnable(3, false); // 3番をfalseにしてバイブレーション修了
}

void loop() {
  // vibration();　// バイブレーションしたいときに呼び出すだけ
  delay(1000);
}
```

# 参照しました

[M5Core2公式リポジトリ（GitHub）](https://github.com/m5stack/M5Core2/)

公式リポジトリのReadme（PinMap）を見ると、バイブレーションモーターの電源とAXPのLDO 3番pinとがマッピングされていることが示されています。

![axp_ldo3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2760/595c1e59-e8b7-70ac-9c04-fdafaac50ebb.png)

[AXP192クラスのSetLDOEnable関数の中身](https://github.com/m5stack/M5Core2/blob/master/src/AXP192.cpp)を見ると、第一引数にAXPのLDO番号（2または3）を、第二引数に希望する状態（true/false）を指定することで制御できる作りになっていました。
前述のサンプルコードは、必要なパラメータを指定してこの関数を呼び出しただけに過ぎません。

## 公式リポジトリ（M5Core2ライブラリ）のコード

```cpp:M5Core2/src/AXP192.cpp
void AXP192::SetLDOEnable(uint8_t number, bool state)
{
    uint8_t mark = 0x01;
    if ((number < 2) || (number > 3))
        return;

    mark <<= number;
    if (state)
    {
        Write1Byte(0x12, (Read8bit(0x12) | mark));
    }
    else
    {
        Write1Byte(0x12, (Read8bit(0x12) & (~mark)));
    }
}
```
金魚の自動エサやり機

子供と一緒に工作をしてみたので、備忘録的に記事を書きました。
題材は身の回りの便利グッズということで探すと、金魚のエサやりが忘れがちだったので、それではということで「金魚の自動エサやり機」に決定。

手持ちにサーボモーターがあったので、それをmicro:bitで制御すれば何とかできそうだなっと。
![IMG_6729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696263/0d08183d-daa3-c909-6c3d-8dee2572f522.png)

[材料]
・micro:bit x 1台
・サーボモーター SG90 x 1個
・エッジコネクタ x 1個
・スイッチ付き電池ケース x 1個
・タッパー小 x 1個 (100円ショップで買った残り) 
・配線 少々

まずは全体設計。
段ボールで台座を作り、そこにサーボモーターをはめ込んで、サーボモーターによりタッパを回転させてゆき、タッパの所定の角度に作ったスリットからエサが落ちる構造に決定。
![IMG_6778.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696263/46f4da81-0961-81ef-56d6-136c48c7ee12.png)

実際に作り始めてみると、あとから課題が色々と発覚してしまい。。

(1)サーボモーターの電源
   最初はmicro:bitからの出力で一瞬動いたようだが、
   その後、全く動かなくなり、やむなく単三電池x3で別供給に。

(2)サーボモーターの稼働範囲
   当たり前のことだけれど、サーボモーターの稼働範囲が180度。
   エサ落としに使えるタッパーの範囲が半分に限られてしまう。
   (次回の改良課題へ)

(3)エッジコネクタ
   中華系パーツ店で買ったものだったからか、
   子供がちょっと触っただけで、
   コネクタがずれてしまってショートの原因に。
   エッジコネクタの採用はあきらめ、手持ちのICクリップで自作して対処。

制御プログラムはmicro:bitで作成。
取敢えず、スリットの都合上、２日間で180度回転させてみることに。
![IMG_6780.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696263/15b8f2ef-0d18-78c2-e989-7eb9921f8597.png)

完成！
![IMG_6776.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696263/7177ce9f-1f37-1ba2-d009-a3899d9475f9.png)


以上、まだまだ初級者ですが精進してゆきます。
任意のディレクトリ配下のCSVファイルをすべてDataFrameに落とし込む

DataFrameに落とし込みたいCSVファイルが大量にある場合は
下記コマンドを使うことで『ファイル名_df』という変数名でDataFrameを定義できます。

```python
import os
import pandas as pd

for dirname, _, filenames in os.walk("""任意のディレクトリ名"""):
    for filename in filenames:
        path = os.path.join(dirname, filename)
        # execコマンドを用いてファイル名を変数名として動的に定義していく
        exec("{0}_df = pd.read_csv(path)".format(filename.replace('.csv','')))
```
[Vue/Nuxt] プロパティの値の有無によるエラーハンドリング

VuexのStateのプロパティに**オブジェクトで値が入っている場合**において、
**値の有無による条件処理**でのエラーハンドリング実装方法の一例を紹介します。

今回は、
**プロパティに値が入っていたらdispatchでActionsを発火させる**
という場合のコードとなっております。

```index.vue
<script>
export default {
  async fetch({ store }) {
    if (
      store.state.index.data &&
      Object.keys(store.state.index.data).length > 0
    ) {
      await store.dispatch('index/fetchData')
    }
  }
}
```

`store.state.index.data`
では単にdataプロパティに値があるかの確認。

且つ、
`Object.keys(store.state.index.data).length > 0`
で**オブジェクト数が0より多い**ことを確認しています。
partialの使い方

#きっかけ
[メルカリコンペ1位のコード](https://www.kaggle.com/lopuhin/mercari-golf-0-3875-cv-in-75-loc-1900-s "Qiita")に出てきたpartialが良く分からなかったから。


#まとめ
partial→一部の引数は可変、一部の引数は固定で処理を実行できる。

#使用例

[下記例の参考](https://www.st-hakky-blog.com/entry/2018/02/01/225734 "Qiita")
bを5で固定して、aの引数を0～5で変化させて処理させる。

```ruby:qiita.rb
from functools import partial

def add_func(a, b):
    return a + b

add_list = list(map(partial(add_func, b=5), [0,1,2,3,4,5]))

print(add_list)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/aed53913-bd51-6f01-42e5-399936ea0a39.png)



[メルカリコンペ1位のコード](https://www.kaggle.com/lopuhin/mercari-golf-0-3875-cv-in-75-loc-1900-s "Qiita")での例
y_trainの値は固定して、fit_predictに入るxsの値だけを変えている。

```ruby:qiita.rb

def fit_predict(xs, y_train) -> np.ndarray:
    X_train, X_test = xs
    config = tf.ConfigProto(
        intra_op_parallelism_threads=1, use_per_session_threads=1, inter_op_parallelism_threads=1)
    with tf.Session(graph=tf.Graph(), config=config) as sess, timer('fit_predict'):
        ks.backend.set_session(sess)
        model_in = ks.Input(shape=(X_train.shape[1],), dtype='float32', sparse=True)
        out = ks.layers.Dense(192, activation='relu')(model_in)
        out = ks.layers.Dense(64, activation='relu')(out)
        out = ks.layers.Dense(64, activation='relu')(out)
        out = ks.layers.Dense(1)(out)
        model = ks.Model(model_in, out)
        model.compile(loss='mean_squared_error', optimizer=ks.optimizers.Adam(lr=3e-3))
        for i in range(3):
            with timer(f'epoch {i + 1}'):
                model.fit(x=X_train, y=y_train, batch_size=2**(11 + i), epochs=1, verbose=0)
        return model.predict(X_test)[:, 0]

 with ThreadPool(processes=4) as pool: #4つのスレッドにする
        Xb_train, Xb_valid = [x.astype(np.bool).astype(np.float32) for x in [X_train, X_valid]]
        xs = [[Xb_train, Xb_valid], [X_train, X_valid]] * 2
        y_pred = np.mean(pool.map(partial(fit_predict, y_train=y_train), xs), axis=0)
```
railsのsessionデータ更新でzero-length delimited identifier at or near """"のエラー

開発環境である時見慣れぬエラーが出て、もしも本番で発生したらどうすればいいのか途方に暮れそうなので、復旧手順を試行錯誤したメモです。同じエラーが出た場合にヒントになればと思うのですが、同じ状況とは限らないのでご注意。

環境 rails 5.2.4.3 postgresql 12.2 pg 1.2.2 activerecord-session_store 1.1.3

状況
　ログインするサイトで、ブラウザからアクセスした際に以下のエラーが出て、サイトをまったく利用できない。

```development.log
ActiveRecord::StatementInvalid (PG::SyntaxError: ERROR:  zero-length delimited identifier at or near """"
LINE 1: ... SET "data" = $1, "updated_at" = $2 WHERE "sessions"."" = $3
: UPDATE "sessions" SET "data" = $1, "updated_at" = $2 WHERE "sessions"."" = $3)
:

activerecord (5.2.4.3) lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `exec_params'
activerecord (5.2.4.3) lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `block (2 levels) in exec_no_cache'
...
```
ログに羅列されているファイル名には自分が書いたファイルはなく心当たりなし。昨日何やったっけ。とりあえずこの状態のDBをダンプして保存。

セッションの情報はactiverecord-session_storeでactiverecordに記録していて、ユーザがアクセスするとこの情報を更新する。その際にこのエラーが出ている。
正常に動いている本番データと比べると、whereのところは本来は
 WHERE "sessions"."id" = $3　のはずであることがわかった。

activerecord-5.2.4.3/lib/active_record/connection_adapters/abstract/database_statements.rb
までは追っかけて、発行するsqlを生成する関数の入力値arelでname="id"であるところが、エラーが出るパターンではname=""になっていたところまではわかったが、そこから遡るのは断念。

pg_dumpしてpsqlでloadしても同じエラー。そこで、pg_dumpをデータだけにして、dbは一度初期化、migrateしてデータを流し込んだら復旧できた。復旧後改めてpg_dumpして比較すると、

```
ALTER TABLE ONLY public.sessions
    ADD CONSTRAINT sessions_pkey PRIMARY KEY (id);
```
が欠けていた。どこで／何をしてこれが消えたのか、心当たりなし。

sessionsのテーブルだけであれば、邪道っぽいけど、以下のようにactiverecord-session_store適用でやったのと同じmigrationを一時的に用意し、

```
class ResetSessionTable < ActiveRecord::Migration[5.2]
  def up
    drop_table :sessions
    create_table :sessions do |t|
      t.string :session_id, :null => false
      t.text :data
      t.timestamps
    end

    add_index :sessions, :session_id, :unique => true
    add_index :sessions, :updated_at
  end
  def down
  end
end
```

```
# pg_dump -b DB名 --data-only --table sessions >sessions_bak.sql
# ここで上記をdb:migrateしてすぐにdb:rollbackしてファイルを削除
# cat sessions_bak.sql  |/usr/local/pgsql/bin/psql -e DB名
```
こんな感じで停止もそこそこで復旧できる見通しはついた。もっと良い対応があるかもしれない。

結局発生の原因はわかっていないが、開発環境は初期化とかデータロードを頻繁に行っているため、そこで何らかエラーがあった可能性が高いけど、pgのバージョンの制約とか、他のgemとかの影響の可能性もなくはないので、情報共有で投稿してみました。
Rails+mecab+Herokuでデプロイエラーが発生した場合の対策

# 事象
- Rails（6.0.0）
- Heroku
- Heroku Buildpacksにmecab（https\://github.com/diasks2/heroku-buildpack-mecab.git）を追加

この条件で、Herokuでデプロイを行った場合、エラーが発生するケースがあると思います。

# 調査

デプロイエラーの内容は下記のようです。

```
 !     To update to the latest version installed on your system, run `bundle update --bundler`.
 !     To install the missing version, run `gem install bundler:2.0.2`
```

確かに、Gemfile.lockに下記のようにbundlerのバージョン指定をしています。

```
BUNDLED WITH
   2.0.2
```

そこで、Gemfile.lockのBUNDLED WITH指定を手作業で削除し、再度Herokuでデプロイします。
　⇒正常にデプロイ完了します。

しかし、Heroku Buildpacksからmecabを外し、BUNDLED WITH 2.0.2指定を復活させ、再度Herokuでデプロイしてみたところ…
　⇒正常にデプロイ完了します。解せません。

つまり、下記のような状態です。

|  -  |  mecabあり  |  mecabなし  |
| ---- | ---- | ---- |
|  BUNDLED WITH 2.0.2  |  デプロイNG  |  デプロイOK  |
|  BUNDLED WITH なし  |  デプロイOK  |  デプロイOK  |

mecabとbundler v2.0.2は相性が悪いように読み取れます。

根本解決になっておらず恐縮ですが、
Rails+mecab+Herokuという（マニアックな）組み合わせでアプリケーションを作りたい場合、この事象に遭遇した際は、
手作業でGemfile.lockのBUNDLED WITH指定を削除すると、この事象を突破できると思います。

# 備忘
Config versに`MECAB_PATH=/app/vendor/mecab/lib/libmecab.so`の設定をお忘れなく！
pythonでフォルダ作成・ファイル移動,圧縮,削除の操作



#フォルダ作成makedirs

exist_okでフォルダが存在している場合には作らない。
指定しなければエラー。

```python
import os
dir_path = os.path.join('C:\\Users\\username\\Desktop','00')
os.chdir(dir_path)

os.makedirs('new_made', exist_ok=True)
dir_path_sub_folder = os.path.join(dir_path,'new_made')
```

#一旦操作するファイルを作成

```python
from sklearn.datasets import load_iris
import pandas as pd

iris = load_iris()

irisDF = pd.DataFrame(iris.data)
csv_name='iris.csv'

irisDF.to_csv(csv_name,header=False,index=False)
```

#フォルダ内のファイル名を取得

```python
import glob
files = glob.glob(dir_path+"\\"+csv_name)
```

#ファイルの移動

```python
import shutil
move_csv_path = shutil.move(files[0], dir_path_sub_folder+"\\"+csv_name)
```



#zipに圧縮

```python
import zipfile
zip_name=dir_path_sub_folder+'\\iris.zip'

with zipfile.ZipFile(zip_name, 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write(move_csv_path, arcname=csv_name)
```


#ファイルの削除

```python
os.remove(move_csv_path)
```


#圧縮ファイルの解凍

```python
zip_file = zipfile.ZipFile(zip_name)
zip_file.extractall()
```

解凍先を指定

```python
os.makedirs('extract_zip', exist_ok=True)
zip_file.extractall('extract_zip')
```





#フォルダやファイルの削除


中身の入ったフォルダはremoveで削除できない

```python
os.remove(dir_path_sub_folder)
```

```
PermissionError: [WinError 5] アクセスが拒否されました。
```

シェルユーティリティー(shutil)を使えば完全に削除できる

```python
shutil.rmtree(dir_path_sub_folder)
```

完全でなく、ゴミ箱に送って復元もできるようにする。

```python
import send2trash
send2trash.send2trash(dir_path_sub_folder)
```




#以上
SQL構文を理解する、使える様にするためのアウトプット

前記事の続きになります。

#検索データーの形成

##データの結合
例えばユーザーのフルネーム一覧を取得したいとします。

```sql:sql
SELECT
first_name,
last_name
FROM users;
```

これで取得はできるのですが、なんだかフルネーム取得なのに分かれているのは違和感...
そこでfirst_nameとlast_nameを結合し一つのカラムに表示しましょう。
使用するのは**CONCAT**関数。

```sql:sql
CONCAT(文字列１, 文字列２, 文字列3)
```

実際に先ほどのfirst_name、last_nameに使用すると...

```sql:sql
SELECT CONCAT(first_name, last_name)
FROM users;
```
この様に書くと一つのカラムの中にこれらを結合して抽出したりすることができるます。

また抽出したデータなどをそのままコピーした際などには、カラム名が関数名になっており、
そのまま上司や先方にデータを提示するのは不親切で好ましくないと思います。

そこで検索結果のカラム名を変更したり、SQL文が長くなったり複数のテーブルから検索する時に便利な
**AS**を紹介します。

```sql:sql
SELECT 取得するデータ AS 別名
```

先ほどの例に当てはめると...

```sql:sql
SELECT CONCAT(first_name, last_name) AS "名前"
FROM users;
```
となります。

またこの**AS**は他にも用途があり、**FROM**の部分でも**AS**を使用すると便利な部分があります。

例えば、usersテーブルとshoppingテーブルがあり、
あるユーザーのIDをもとに購入されたもののデータを検索したいとします。
表示するデータは、**名前**と、**商品名**として...

```sql:sql
SELECT
u.name,
s.product_name
FROM users AS u,
shoppings AS s
WHERE u.id = s.user_id;
```
こうすることで

![スクリーンショット 2020-09-06 19.00.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624989/7c9bd063-189d-7f49-17de-dc2fa86834b3.png)

取得することができました！
この様に複数のテーブルにまたがり検索をする場合などには、ごちゃごちゃになって確認しにくくならない様、
ASを積極的に使用しましょう！

##重複の除外
例えば、とあるオンラインショップにて、とある日付に買い物をした人のidリストが欲しいとします。
すると、この様にすると思います。

```sql:sql
SELECT user_id
FROM shopping_list
WHERE date = "2006-09-22";
```

これで一見いい様にも見えますが実はこれだと、同じ日に二回買い物した人のIDが重複して出てしまうんです。
そこで重複をなくすことができる**DISTINCT**を使用しましょう。

```sql:sql
SELECT DISTINCT カラム
```

先ほどのクエリを書き直すと...

```sql:sql
SELECT  DISTINCT user_id
FROM shopping_list
WHERE date = "2006-09-22";
```

こうすることで重複を省き検索を実行することができます。

##レコードのグループ化
先ほどのDISTINCTに似た、**GROUP BY**を使用します。
これは、指定したカラムが同じ値を持つデータを一つのグループとしてまとめることができます。

```sql:sql
GROUP BY カラム
```

一見挙動はDISTINCTと同じ様に見えがちなのですが、
GROUP BYを使用することで、そのグループ単位で集計した結果を取得できるというメリットがあります。

##レコードの数を取得する
グループ化されたデータのレコード件数を取得できる関数が**COUNT**です。

```sql:sql
SELECT COUNT(カラム)
```

上記の様にカラムを指定することで、そのカラムの値が**NULL**ではないデータを取得することができます。

また、NULLのレコードも含め取得する場合は、カラム指定の部分をワイルドカードに変更するのみです。

```sql:sql
SELECT COUNT(*)
```

#データ検索　応用

##テーブルの結合
**JOIN**を使用します。

```sql:sql
FROM テーブル名１
JOIN テーブル名2 ON テーブル名1.カラム名1 = テーブル名2.カラム名2
```

例えば、上でも出した例の、オンラインショップにて、購入した人のデータを取得するとします。

```sql:sql
FROM shopping_list AS s
JOIN users AS u ON s.user_id = u.id;
```
流れとしては
・shopping_listテーブルにusersテーブルを結合させる。
・shopping_listテーブルの各行には、その行のuser_idがusersテーブルのidと一致する行を結合させる。
といった感じです。

これでクエリを書き直すと

```sql:sql
SELECT 
  user_id,
  s.product_name,
  u.name
FROM shopping_list AS s
JOIN users AS u ON s.user = u.id
GROUP BY user_id;
```

この様に書くことができます。

当方もまだまだ理解が浅い部分がありますので、間違っている点等あれば指摘していただければ嬉しいです。
実務頑張ります👌！
ASUS PRIME H470M-PLUSにWindows Server 2012 R2をインストールする。

#概要
[ASUS PRIME H470M-PLUS](https://www.asus.com/jp/Motherboards/PRIME-H470M-PLUS/)はWindows 10しか公式にサポートしていないが、そのボードを使って最低限利用できそうな[^最低限]Windows Server 2012 R2を入れてみる。

#注意点
このような利用は本来サポート外のため自己責任において実施してください。情報提供はありがたいですが、このサイトをみて実際にインストールしてできなかったからと言って私のせいにはしないようにお願いします。

#前提知識
PCを自作したことがある、またはその知識があってPCを組めそうという方を対象にしている。

デバイスドライバーはWindowsで共通的に使えることが多く（少しハックする場合もあるが）おおよそ以下の関係があると思っている。以下の表を念頭にサーバ用ドライバがないときはクライアントOSのドライバを探すと大体よさげな感じがする。

|クライアントOS|サーバOS|
|:-:|:-:|
|Windows XP|Windows Server 2003|
|Windows Vista|Windows Server 2008|
|Windows 7|Windows Server 2008 R2|
|Windows 8|Windows Server 2012|
|Windows 8.1|Windows Server 2012 R2|
|Windows 10(Ver.1809より前)|Windows Server 2016|
|windows 10(Ver.1809以降)|Windows Server 2019|


#PCを組み立てる必要のある部品のほかに用意するもの

* LANボード（OSをインストールすると一緒に入れてくれるもの、またはOS用のデバイスドライバが提供されているもの）[^LANボード]
* Windows Server 2012 R2のインストールメディア（またはそれを入れたUSBメモリ）、ライセンスキー

#インストール前に
BIOSの設定でRAIDはかけていない[^BIOS設定]。その他基本的にデフォルト設定のままで実施している。（intel Virtualization Technologyだけは事情があり有効化）

#インストール手順
1. OSをインストールする
2. マザーボードに付属のCD（なかったら[インターネットサイト](https://www.asus.com/jp/Motherboards/PRIME-H470M-PLUS/HelpDesk_Download/)からダウンロード）よりChipsetをインストールする。インストールする際にAsusSetup.exeではなく、SetupChipset.exeを実行してインストールする。[^chipset]
写真はWindows Server 2019に入れたときのものだがWindows Server 2012 R2でも同じである。
![chipset-install.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101343/f0b81af5-49f6-7c5b-75bf-0bb407fbbb13.jpeg)
3. 同じくマザーボード付属のCDからAudioをインストールする。インストールする際にAsusSetup.exeではなく、install.batを実行してインストールする。
写真はWindows Server 2019に入れたときのものだがWindows Server 2012 R2でも同じである。
![audio-install.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101343/d27294ff-db64-f625-2258-5a81962ed378.jpeg)
4. LANボードを認識していればLANドライバーをインストールする。
5. Windows Updateを実行する。[^RAID]

#終わりに
最初Windows Server 2019を入れたのだが、いったん初期化してこのバージョンのWindows Serverをインストールした。
この後、別のPCでWindows Server 2008 R2のADドメインコントローラーの機能をこのPCに移動させている。[このサイト](https://newhelptech.wordpress.com/2017/06/26/step-by-step-migrate-active-directory-server-2008-r2-to-server-2012-r2/)を参考にして確実に移動できたと思う。
今度はインプレースアップグレードでWindows Server 2019を入れなおす予定である。

[^最低限]: インターネットが利用できて最新のセキュリティ更新プログラムが適用できる状態で普通にOSの操作が利用できるという意味。

[^LANボード]: 記載した2020/9/6時点ではLANコネクタ（Intel Ethernet Connection I219-V）に対応したWindows Server 2019のドライバが[Intelのサイト](https://downloadcenter.intel.com/download/28410/Adapter-User-Guide-for-Intel-Ethernet-Adapters?product=82186)にあるのは知っているのですが、書いている時点ではうまく当たらなかったので、再度トライする。

[^BIOS設定]: 検証をしていないこともさることながら、Intel Rapid Storage TechnologyのドライバーはOSをインストール後に入った関係でうまくいくか不安だったから（かつ、あとでインプレースアップグレードをかけるときに、これが邪魔する可能性が高いため）

[^chipset]: デバイスマネージャーから不明なデバイスと出ている箇所の多くがこれで埋まる。

[^RAID]: .net Framework 4.6.1以上を入れてから付属CDを使っていれようとしたが認識しなかった・・・
ghq の v1 でなくなった look コマンドをデフォルメして復活させる(zsh版)

## TL,DR

[ghq の v1 でなくなった look コマンドをデフォルメして復活させる](https://tech.515hikaru.net/post/2020-01-28-ghq-look/) の zsh 版+αです

## 変更点

- `command cd` だと動かなかったので `cd` に
- `ghq` は `command ghq` に
- 部分一致した上で peco を起動できるように

## Code

```zsh
ghq() {
    if [[ $1 == "look" ]]; then
        if [[ -n $2 ]]; then
            repo_name="$2"
            exact_matched=$(command ghq list --full-path --exact "$repo_name")
            if [[ -n "$exact_matched" ]]; then
                cd "$exact_matched"
            else
                cd $(command ghq list --full-path "$repo_name" | peco)
            fi
        else
            cd $(command ghq list --full-path | peco)
        fi
    else
        command ghq "$@"
    fi
}
```
AxiosでAPIのエンドポイントを@nuxtjs/proxyを使って省略する

Axiosを使ってAPI実行する時にエンドポイントを全て書くのはめんどくさいですよね。

具体的にどういうことかというと、
こういうことです。

**プロキシ未設定**

```index.js
async fetchData({ commit, state }) {
  try {
    const resp = await this.$axios.$get('http://localhost:8000/api/score')
    commit('setData', resp)
  } catch (error) {
    console.log(error)
  }
}
```

**プロキシ設定済**

```index.js
async fetchData({ commit, state }) {
  try {
    const resp = await this.$axios.$get('/api/score')
    commit('setData', resp)
  } catch (error) {
    console.log(error)
  }
}
```

APIのエンドポイントが短くなっていますね。

このやり方を解説します。

# @nuxtjs/proxyをインストール

```
npm install --save @nuxtjs/proxy
```

# proxyの設定

nuxt.config.jsに下記の設定を追加します。

```nuxt.config.js
modules: [
  '@nuxtjs/proxy'
],
proxy: {
  '/api': 'http://localhost:8000'
}
```

※8000のところは各自のサーバのものを入れてください。
これで設定完了です。

あとはAxios使う時のAPIエンドポイントは
`http://localhost:8000`
以降の部分を記述するだけでよくなります。
Python,AI関連の英語読解力を上げる（意味を逆に感じると心が折れるので。。。注意　例:however,・・・)

#目的
**今生**、英語が身につくかどうかは、非常に、微妙だが。。。
これ以上の英語力の低下は避けたい！！！⇒わずかな抵抗として、記事を書く。
（正しい答えは、多読！！！　たぶん）

ここでは、**英語が逆の意味に読めて、読む気を失う**ことがよくあるので、
そうならない留意点をまとめる（まだ、1件ですが。。。）

#英文が逆の意味に感じられる例
##ケース１、「however」

以下の書籍でのpythonでのprivateについての記載において

　Python Pocket Reference, 5th Edition
　Python In Your Pocket
　By Mark Lutz
　Publisher: O'Reilly Media


引用
>This is not strict privacy, however, as such names can still be accessed with other import statement forms.

Google翻訳（ママ）
>ただし、これは厳密なプライバシーではありません。そのような名前は他のインポートステートメントフォームで引き続きアクセスできます。

誤った意味のとりかた、
howeverの前と後ろを分断して、それを、howeverでつなぐ

「これは厳密なプライベートではない」（前半）
＋
しかしながら(= however)
＋
「このような名前は、別の方法でまだアクセスできる」（後半）

⇒　**これで、？？？？が沢山。何が、しかしながら（however)なの？？？？**

|ポイント(間違わないための留意点！！）|
|:---:|
|**however**は、**文頭でなくて、少し、下がった場所**にくる場合あり。この場合の**however**は、ここ以前の文章に対するもの！！|


##ケース２、「not only」

以下のYoutubeのコメント欄にて。
https://www.youtube.com/watch?v=Uumd2zOOz60

引用
>I think this video does **not only** give a guide to how we can read a paper fast, **but also** how to write a good paper to help readers understand it more efficiently.


誤った意味のとりかた、
give xx すら(only)しない、みたいな感じ。。
⇒　？？？　で、真逆の意味に感じる。

|ポイント(間違わないための留意点！！）|
|:---:|
|**not only A   but also B(AばかりでなくBも)** ぐらい、まず、理解しときましょう。更に、ややこしいことを理解してもいいが。。。|

#まとめ
とくにありません。
全然、英語、詳しくないので、正しい解釈等、コメント頂けると幸甚です。:candy:
ウォーターフォールとアジャイル


#ウォーターフォール開発
ウォーターフォール開発とは開発対象の全ての機能を前もって設計し開発を行う開発体制。
・全ての機能の開発が完了するまでサービスをユーザーが利用できない
・開発期間が長くなる。
・途中で仕様変更等ができない
・製品の開発後に問題が発覚した場合に取り返しがつかない
というデメリットが存在する。

#アジャイル開発
開発対象の機能を細かに分割し、小さな開発を繰り返し行う開発体制。
・開発の方向性がぶれる可能性がある
・品の仕様や設計を綿密に定めておかないと、最終製品の品質を落としかねない

#感想
業務ではアジャイル開発を行うことがほとんどなのですが、個人的にはスピード感を持って開発できる点からやっぱアジャイルが一番向いているなあと感じました。
マークダウンの基本的な書き方

#背景
就職以来少しプログラミングから離れていたが、最近コードを書く機会が増えてきたので、アウトプットを増やそうと思いアカウント作成した次第。
qiitaは基本マークダウン形式での投稿みたいだが、今までそんなに書いてきていないので、まずマークダウンの書き方からまとめてみたいと思います。

#マークダウンとは

>Markdown（マークダウン）は、文書を記述するための軽量マークアップ言語のひとつである。本来はプレーンテキスト形式で手軽に書いた文書からHTMLを生成するために開発されたものである。(wikipediaより)

HTML向けに作成されたものなんですね、web系もいつかはやってみたいと思ってます。（思っているだけ）
ついでに引用は文頭に\>でできる

#基本的な記入方法
##強調
\*\*や\_\_で文字を囲うと強調される
**\*\*強調\*\***
__\_\_強調\_\___

##コード埋め込み
\`で囲むとコードを文中に差し込むことができる、そう`import cv2`こんな感じに。

\`\`\`で分全体を囲むと複数行のコードを挿入できる
```import cv2
```

##リスト
\-や\*、\+、もしくは 数字\. とするとリストにすることができる
上下に空行が必要で、記号の後に空白が必要です。

- こんな感じ
 

* こんな感じ
 

+ こんな感じ


1. こんな感じ

##リンク
\[テキスト\]\(アドレス\"タイトル\"\)　このように書くと次のようなリンクを作ることができる
[マークダウンのwikipedia](https://ja.wikipedia.org/wiki/Markdown"マークダウンのwikipedia")

##エスケープ文字
今回一番使った。\\バックスラッシュを入れることで記号をそのまま使える

#最後に
手始めに自分が使うところのメモを書いていったが、今後はデータサイエンス系や趣味の電子工作について書いていければよいと思っています。
[Swift] Tupleのswitchで条件マトリックスをもれなく分岐させる

今日からでもすぐに取り入れられて、

- コードをよりクリーンにできる、とか
- 工数を削減できる、とか

そんなTipsを紹介していく記事シリーズです。
「知らなかった」「気づかなかった」「忘れていた」そんな誰かの役に立てば幸いです。

# 前提環境

- Xcode 11.3.1
- Swift 5.1.3

# Tupleのswitch

```swift
var isWeekday = false
var isChildlen = false
var isSenior = false

switch (isWeekday, isChildlen, isSenior) {
case (true, true, _):
    print("平日・子ども料金")
case (true, _, true):
    print("平日・シルバー料金")
case (true, _, _):
    print("平日・大人料金")
case (false, true, _):
    print("休日・子ども料金")
case (false, _, true):
    print("休日・シルバー料金")
case (false, _, _):
    print("休日・大人料金")
}
```

- Swiftの`switch`は全ての組み合わせを網羅しないとコンパイルエラーにしてくれます。
- それはTupleを`switch`する場合も同様で、全要素が取りうる全組み合わせを網羅させることが容易になります。
- 可読性はあまりよくないので、「全ての組み合わせを網羅する」ことを最優先にしたい場合以外は避けた方が良い書き方かもしれません。
AtCoderにSwiftで挑む時にPlaygroundを使うための小ワザ

[AtCoder](https://atcoder.jp/)にて、Swift 5（執筆時点では5.2.1）が使えるようになりました。

プログラミング・コンテストのコーディングにはブラウザ上でコードを実行できるWebサービスを使うことが一般的かもしれませんが、、、

Playgroundだと補完機能とかコードスニペットとかいろいろと便利なので、Playgroundを使いたい。
しかし、Playgroundでは、AtCoderの問題の前提になっている標準入力が使えないのです。
（私の認識が間違っていたら教えてください。。。）

そこで、私なりの小ワザを考え、実際にコンテストにSwiftで挑戦して、ちゃんとコードを提出できたので共有します。
結果はイマイチだったので触れません（笑

# サンプルコード

過去問の [ABC 086 A - Product](https://atcoder.jp/contests/abc086/tasks/abc086_a) の回答コードです。
詳細はリンク先をみていただきたいですが、要するに以下のような問題です。

- 標準入力より引数が"a b"という形式で与えられる。
- a × bが奇数なら"Odd"と、 偶数なら"Even"と出力する。

```swift:ATCoder.playground
// for TEST
var inputs = ["3 4"]
func readLine() -> String? {
    guard !inputs.isEmpty else {
        return nil
    }
    return inputs.removeFirst()
}
// for TEST

import Foundation

func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map { Int($0)! }
}

func main() {
    let ab = readInts()
    let isEven = ab[0] * ab[1] % 2 == 0
    print(isEven ? "Even" : "Odd")
}

main()
// Playgroundで実行すると出力コンソールに"Even"と表示される
```

# 解説

- `// for TEST`コメントで囲まれたコードブロックは、Swiftの標準入力読み込み関数`readLine()`を同じ関数名で自作することで、上書きと言いますか、hookしてしまう、という意図のコードです。
- `var inputs = ["3 4"]`は、問題で標準入力から与えられる引数になります。この配列の要素を変えてテストをします。
- 問題によっては標準入力で複数行の引数が与えられるということがあります。その場合は`var inputs = ["2", "3 4", "5 6"]`のように定義します。
- コンテストにコードを提出する時は、`// for TEST`コメントで囲まれたコードブロック以外をコピペすればOKです。

# 参考リンク

[AtCoder に登録したら解くべき精選過去問 10 問を Swift 5 で解いてみた](https://qiita.com/conf8o/items/8f2130510a9deaffa312)

[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)
【Rails6】JavaScriptで画像スライドショー機能

オリジナルアプリの実装で使った機能の一つで自分自身の備忘録の為に投稿しておきます！
初心者のため、間違えている所もあると思います...
画像をスライドショーで切り替える方法はネットで検索するといくつか方法がでてきます。
「slick」や「swiper」など。
僕は上記のやり方だとうまく実装できませんでした。
問題は私の方にある。笑
今回は便利そうなプラグインやGemを使わないでシンプルにJavaScriptだけでスライドショーを実装させました。

<h1>実際のコード</h1>
コードは以下の通り

```html.erb
<img id="mypic data-src="images/image1.jpg" width="400" height="300" class="lazyload">
```
まずはビューファイルのhtml側にimgタグで画像を表示させます。
サイズやcssで修飾させたい方はそれぞれ指定してあげてください。
この時に一つ注意点ですが画像の格納場所によってパスが違います。
私はapp/public/images/に格納させたのでimages/image.jpgとしていますが、
もしapp/assets/images/に画像を格納すると変わってきます。しかし、ここだと画像ファイルがアセットパイプラインの対象となり画像のURLが変わってくるので扱いにくいです。
詳しくはこちらを参考にしてみてください！[Railsガイド：アセットパイプライン]:https://railsguides.jp/asset_pipeline.html


```javascript
const pics_src = ["images/image1.jpg","images/image2.jpg","images/image3.jpg"];
let num = -1;
 
 
function slideshow_timer(){
  if (num === 2){
    num = 0;
  } 
  else {
    num ++;
  }
  document.getElementById("mypic").src = pics_src[num];
}
 
setInterval(slideshow_timer, 5000);
```

そしてJavaScriptのファイルです。
配列pics_srcには、スライドさせたい画像を保存します。
そして、画像が入れ替わる処理をslideshow_timerの関数内に条件式で定義します。
今回は３枚の画像をスライドさせるので、変数numが２（３枚目)になったら0(1枚目)に戻す式を書き。

```
if (num === 2){
    num = 0;
}
```

違う場合は変数numに１を足して次の画像を表示させます。

```
else {
    num ++;
  }
```
そしてgetElementById関数を使用し、先ほど設定したimgタグ内のsrc属性を、次の画像のパス名に変更します。

```
 document.getElementById("mypic").src = pics_src[num];
```

最後にsetInterval関数を使用します。setInterval関数は、第一引数に呼び出したい関数名、第二引数に実行するタイミング（インターバル）を指定します。今回は5000ミリ秒と指定したので(画像をじっくり見てもらいたいから)、5秒後には次の画像に切り替わるという仕組みです。

```
setInterval(slideshow_timer, 5000);
```

<h1>終わり</h1>
以上です！
JavaScriptはコードが短いのに実装させるのが大変で苦手意識が凄いですが、便利なので使いこなしていきたいです。
今回はJavaScriptの中でも初心者用のスライドショー機能に挑戦してみましたが、ほぼネットの力に頼ってしまいました笑
次回は少しは自分の力でJavaScriptを使いこなしたいですね！笑
また間違えている所などがありましたら教えていただけると助かります！
最後まで読んで頂きありがとうございます！
[SwiftUI]EnvironmentObjectをあるViewに入れるとPreviewができない

SwiftUIでPreviewを使っていたところ、
このようなエラーに遭遇しました。

```
Thread 1: Fatal error: No observable object of type DataManager found.
A View.environmentObject(_:)
```

現時点の最新のXcode11.6では、ビルドできるのにプレビューに失敗している時、以下の画像のように表示されます。Diagnosticsを押しても、よくわからないエラーが書かれています。

![スクリーンショット 2020-09-06 18.40.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297014/518beb24-11ee-a321-ac52-7705fc71e64d.png)

## クラッシュログの場所を探す

正確なクラッシュログは

```
~/Library/Logs/DiagnosticReports
```

にあります。このディレクトリの中から該当するアプリのクラッシュログを探します。
中身を見てみると、一番初めのエラーを見つけました。

## 問題のあるコード

Viewの構成は以下のようになっています。
ContentView -> SubView -> ChildView

```ContentView.swift
var body: some View {
   SubView()
}
...
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(DataManager())
    }
}

```

```SubView.swift
var body: some View {
   ChildView()
}
...
struct SubView_Previews: PreviewProvider {
    static var previews: some View {
        SubViewView()
    }
}
```

```ChildView.swift

@ObservableObject var dataManager: DataManager

var body: some View {
   Text(self.manager.message)
}
...
struct ChildView_Previews: PreviewProvider {
    static var previews: some View {
        ChildViewView()
            .environmentObject(DataManager())
    }
}
```

## 原因と解決策

ContentViewにDataManagerを`environmentObject`として追加しているので、アプリ起動の際は問題ありませんでした。
しかし、プレビューができませんでした。
数時間をかけて解決策を探したところ、以下のような原因と解決方法を見つけました。

### 原因

- ContentView_Previews：envirnmentObjectを追加している
- SubView_Previews：__environmentObjectを追加していない__
- ChildView_Previews：environmentObjectを追加している

SubView_PreviewsにenvironmentObjectを追加していなことが原因でした。

### 解決策

```SubView.swift
struct SubView_Previews: PreviewProvider {
    static var previews: some View {
        SubViewView()
            .environmentObject(DataManager()) //←このViewでは使ってないけどここにもenvironmentObjectを書かないといけない
    }
}
```
Bootstrapでcolumnの順番入れ替え

# column順番はorder-*で指定できる

デフォルトの順序をorder-\* (\*=1, 2, 3, ...)で指定し、サイズに依存する順序をorder-md-\*とすれば良い。
下記のように設定すると、サイズがMedium以上のときはorder-md-\*に従うので、
column #1 -> column #2 -> column #3
の表示順となるが、Small以下のときはデフォルトの順序、order-\*に従うので、
column #3 -> column #1 -> column #2
となる。

```html:column-order.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="css/bootstrap.min.css">
    <title>column-order</title>
  </head>
  <body>
    <div class="container">
      <h1 class="text-primary">Mai's Test Code</h1>
      <h2 class="text-info">column-order</h2>
      <h3 class="text-secondary d-sm-none">Extra small</h3>
      <h3 class="text-secondary d-md-none d-none d-sm-block">Small : Smartphone</h3>
      <h3 class="text-secondary d-lg-none d-none d-md-block">Medium : Tablet</h3>
      <h3 class="text-secondary d-xl-none d-none d-lg-block">Large : PC</h3>
      <h3 class="text-secondary d-none d-xl-block">Extra large : Large Display</h3>
      <div class="row border">
        <div class="col border order-2 order-md-1 bg-primary text-white">
          column #1
        </div>
        <div class="col border order-3 order-md-2 bg-success text-white">
          column #2
        </div>
        <div class="col border order-1 order-md-3 bg-info text-white">
          column #3
        </div>
      </div>
    </div>
  </body>
</html>
```

結果は次の通り。

画面サイズ：Medium
![スクリーンショット 2020-09-06 18.41.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704305/7f0e5d74-0337-9c36-cf66-0cb7ae5b7f65.png)

画面サイズ：Small
![スクリーンショット 2020-09-06 18.42.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704305/ca998eb8-dd27-cdea-8738-4a84df2c9588.png)
個人的な疑問だった用語のメモリストを共有する

# window 
jsのブラウザを操作する際に使用するオブジェクト

# document
jsのページ全体を取得したり、操作するために使用するオブジェクト

# パスを通す
phpやnpm、composerだったりの特定のコマンドをパスを通さずに叩こうとするとインストールしたディレクトリまでわざわざ移動しないといけないが、パスを通すことでどこでもそのコマンドが使えるようになる。
# ゲッター
ゲッターはある属性の値を取得するメソッド

# セッター
セッターは属性に値を設定するメソッド

# イミュータブルなオブジェクト
変更不可能なオブジェクト

# ミュータブルなオブジェクト
変更可能なオブジェクト

# スタック
後入れ先出しデータ構造、LIFO（Last In First Out）データ構造、および、スタック（stack）と呼ばれます。スタックは英語で「stack」と表記され、「積み上げ」を意味します

# イメージとコンテナの違い
プログラミングで例えるとイメージがクラスでコンテナがオブジェクト（＝インスタンス）

# docker-composeの役割
複数コンテナをコマンド一つで作成、削除、停止できる。
docker runだとそのコンテナ一つごとにコマンドを叩かなければならない。

## その他
dockerコマンドを叩けるターミナルなどをdockerクライアント、dockerサーバーをdockerDemonと呼ぶ

また追記します。アドバイスや何か間違っている点があればよろしくお願いします。